diff -Nru juju-core-2.0~beta6/debian/changelog juju-core-2.0~beta7/debian/changelog --- juju-core-2.0~beta6/debian/changelog 2016-04-26 18:07:45.000000000 +0000 +++ juju-core-2.0~beta7/debian/changelog 2016-05-17 20:14:16.000000000 +0000 @@ -1,4 +1,20 @@ -juju-core (2.0~beta6-0ubuntu1.16.04.1) xenial-proposed; urgency=medium +juju-core (2.0~beta7-0ubuntu1.16.04.1) xenial-proposed; urgency=medium + + * New upstream release 2.0-beta7 (LP: #1581645) + + -- Nicholas Skaggs Fri, 13 May 2016 15:22:03 -0400 + +juju-core (2.0~beta6-0ubuntu2.16.10.1) yakkety; urgency=medium + + [ Martin Packman ] + * Avoid autopkgtest failures from lack of support for 32-bit state servers. + + [ Michael Hudson-Doyle ] + * New script for build setup to fit better with dh-golang expectations. + + -- Martin Packman Mon, 09 May 2016 16:38:25 +0000 + +juju-core (2.0~beta6-0ubuntu1) xenial; urgency=medium * New upstream release 2.0-beta6 (LP: #1573176). * Includes fixes for upstream bugs: diff -Nru juju-core-2.0~beta6/debian/control juju-core-2.0~beta7/debian/control --- juju-core-2.0~beta6/debian/control 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/debian/control 2016-05-17 20:01:14.000000000 +0000 @@ -23,6 +23,7 @@ python Standards-Version: 3.9.7 Homepage: http://launchpad.net/juju-core +Xs-Go-Import-Path: github.com/juju/juju Testsuite: autopkgtest Package: juju-2.0 diff -Nru juju-core-2.0~beta6/debian/copyright juju-core-2.0~beta7/debian/copyright --- juju-core-2.0~beta6/debian/copyright 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/debian/copyright 2016-05-17 20:01:14.000000000 +0000 @@ -26,7 +26,7 @@ Files: src/github.com/Azure/azure-sdk-for-go/* Copyright: 2009-2015 The Go Authors. All rights reserved. License: Apache-2.0 -Comment: Last verified commit 9f40dc1ee704920d20418200ddf6ec382456bb0e +Comment: Last verified commit 3b480eaaf6b4236d43a3c06cba969da6f53c8b66 Files: src/github.com/ajstarks/svgo/* Copyright: 2010 Anthony Starks @@ -191,7 +191,7 @@ Files: src/github.com/juju/gomaasapi/* Copyright: 2012-2016, Canonical Ltd. License: LGPL-3+ -Comment: Last verified commit 9ec917cdad9e610c7573973393b08ca98d6e0886 +Comment: Last verified commit 5bd7212f416a2d801e4a39800b66e1ee4461c42e Files: src/github.com/juju/govmomi/* Copyright: 2014-2015 VMware, Inc. All Rights Reserved. @@ -214,7 +214,7 @@ Files: src/github.com/juju/httprequest/* Copyright: 2015 Canonical Ltd. License: LGPL-3+ -Comment: Last verified commit 89d547093c45e293599088cc63e805c6f1205dc0 +Comment: Last verified commit 796aaafaf712f666df58d31a482c51233038bf9f Files: src/github.com/juju/idmclient/* Copyright: 2014, 2015, 2016 Canonical Ltd. @@ -312,7 +312,7 @@ Files: src/github.com/juju/romulus/* Copyright: 2016 Canonical Ltd. License: AGPL-3 -Comment: Last verified commit df735617fa6a358e42bb71ff74b3c3ba4faf9f5f +Comment: Last verified commit 767a53ef0929d969a3c81c53c6b9f8e94a95dae5 Files: src/github.com/juju/schema/* Copyright: 2011-2016 Canonical Ltd. @@ -322,7 +322,7 @@ Files: src/github.com/juju/testing/* Copyright: 2011-2016 Canonical Ltd. License: LGPL-3 with linking exception -Comment: Last verified commit 162fafccebf20a4207ab93d63b986c230e3f4d2e +Comment: Last verified commit 3ea8417b3125018f678eb9159731917d01121445 Files: src/github.com/juju/testing/checkers/file_test.go src/github.com/juju/testing/mgo_windows.go @@ -351,7 +351,7 @@ Copyright: 2011-2016 Canonical Ltd. 2014, 2015, 2016 Cloudbase Solutions SRL License: LGPL-3 with linking exception -Comment: Last verified commit 951b27b4808bad43b9107412e002576c9d1b18bb +Comment: Last verified commit d5423ca3ec0b0cc8ccf093fab1365b1c9f93eb2d Files: src/github.com/juju/utils/du/diskusage.go src/github.com/juju/utils/du/diskusage_windows.go @@ -468,7 +468,7 @@ 2011 AppsAttic Ltd. 2011 Memeo Inc. License: LGPL-3 with linking exception -Comment: Last verified commit 345e9291dbc9e6dd7b6c6c679b32b6d3366ca851 +Comment: Last verified commit a651c43e72df7778b14ac6b54e5ac119d32b1263 Files: src/gopkg.in/check.v1/* Copyright: 2010-2013 Gustavo Niemeyer @@ -507,7 +507,7 @@ Files: src/gopkg.in/juju/charm.v6-unstable/* Copyright: 2011-2016 Canonical Ltd. License: LGPL-3 with linking exception -Comment: Last verified commit 728a5ea3ff1c1ae8b4c3ac4779c0027f693d1ca5 +Comment: Last verified commit 9857751ba31e81773bbb42557e85054d6b4de4dd Files: src/gopkg.in/juju/charmrepo.v2-unstable/* Copyright: 2012-2016 Canonical Ltd. @@ -532,7 +532,7 @@ Files: src/gopkg.in/macaroon-bakery.v1/* Copyright: 2014, Roger Peppe, Canonical Inc. License: LGPL-3 with linking exception -Comment: Last verified commit fddb3dcd74806133259879d033fdfe92f9e67a8a +Comment: Last verified commit c8e0209b0f4e48e8603ab0ae2477445f9443fbdc Files: src/gopkg.in/macaroon.v1/* Copyright: 2014, Roger Peppe diff -Nru juju-core-2.0~beta6/debian/helpers/setup-build-directory.py juju-core-2.0~beta7/debian/helpers/setup-build-directory.py --- juju-core-2.0~beta6/debian/helpers/setup-build-directory.py 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/debian/helpers/setup-build-directory.py 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,42 @@ +#!/usr/bin/python + +# This script sets up the _build directory to be suitable to have +# GOPATH pointed at it. The output looks much like what: +# +# dh_auto_configure --buildsystem=golang --builddirectory=golang +# +# would produce for a normal package build despite the fact that this +# package is not at all out laid in a fashion dh_golang thinks of as +# normal. +# +# Dependencies installed from .deb packages are used in favour of +# packages from ./src. + +import csv +import errno +import os +import shutil + +def ensure_directory(path): + try: + os.makedirs(path) + except OSError as exception: + if exception.errno != errno.EEXIST: + raise + +reader = csv.reader(open("src/github.com/juju/juju/dependencies.tsv"), delimiter="\t") + +def link_pkg(pkgpath): + target = os.path.join("_build/src", pkgpath) + ensure_directory(os.path.dirname(target)) + for prefix in ['/usr/share/gocode/src', 'src']: + srcpath = os.path.abspath(os.path.join(prefix, pkgpath)) + if os.path.exists(srcpath): + os.symlink(srcpath, target) + return + raise Exception("%s not found", pkgpath) + +for record in reader: + link_pkg(record[0]) + +shutil.copytree("src/github.com/juju/juju", "_build/src/github.com/juju/juju", symlinks=True) diff -Nru juju-core-2.0~beta6/debian/rules juju-core-2.0~beta7/debian/rules --- juju-core-2.0~beta6/debian/rules 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/debian/rules 2016-05-17 20:01:14.000000000 +0000 @@ -1,14 +1,11 @@ #!/usr/bin/make -f # -*- makefile -*- -# Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 -# NOTE: debian/gocode/src will contain symlinks to system provided -# dev packages, which will be used over those in the upstream -# juju-core codebase. -export GOPATH:=$(CURDIR)/debian/gocode:$(CURDIR) -export PATH:=$(CURDIR)/bin:$(PATH) +export DH_GOPKG:=github.com/juju/juju +export GOPATH:=$(CURDIR)/_build +export PATH:=$(CURDIR)/_build/bin:$(PATH) PKGDIR:=debian/juju VERSION:=$(shell sed -n 's/^const version = "\(2\.[0-9]\+\)[\.-].*"/\1/p' $(CURDIR)/src/github.com/juju/juju/version/version.go) @@ -23,9 +20,9 @@ endif %: - dh $@ --with=golang + dh $@ --with=golang --buildsystem=golang --builddirectory=_build -COMMON_FLAGS:= -x -v -work +COMMON_FLAGS:= -x -v golang_archs:= amd64 i386 armhf s390x ppc64el arm64 ifeq (,$(filter $(DEB_HOST_ARCH), $(golang_archs))) # NOTE(james-page) statically link libgo for the jujud binary for gccgo @@ -37,28 +34,32 @@ # NOTE: ensure /usr/share/gocode is use in preference to any # embedded source for dependencies. override_dh_auto_configure: - dh_auto_configure - mkdir -p debian/gocode/src - ln -s /usr/share/gocode/src/* debian/gocode/src + ./debian/helpers/setup-build-directory.py -override_dh_auto_install: - go install $(COMMON_FLAGS) github.com/juju/juju/cmd/juju - go install $(COMMON_FLAGS) github.com/juju/juju/cmd/plugins/juju-metadata - go install $(COMMON_FLAGS) github.com/juju/juju/cmd/plugins/juju-upgrade-mongo +override_dh_auto_build: + dh_auto_build -- $(COMMON_FLAGS) + rm _build/bin/jujud + # re-link jujud with specific options go install $(COMMON_FLAGS) $(JUJUD_FLAGS) github.com/juju/juju/cmd/jujud - echo '#!/bin/sh\nexport PATH=/usr/lib/juju-$(VERSION)/bin:"$$PATH"\nexec juju "$$@"' > bin/juju-$(VERSION) - chmod 755 bin/juju-$(VERSION) + +# Don't run the tests -- the juju unit tests are too heavyweight to run during +# package build. +override_dh_auto_test: + : + +override_dh_auto_install: + echo '#!/bin/sh\nexport PATH=/usr/lib/juju-$(VERSION)/bin:"$$PATH"\nexec juju "$$@"' > _build/bin/juju-$(VERSION) + chmod 755 _build/bin/juju-$(VERSION) mkdir -p debian/home HOME=debian/home $(CURDIR)/src/github.com/juju/juju/scripts/generate-docs.py man -o juju.1 - dh_install bin/juju usr/lib/juju-$(VERSION)/bin - dh_install bin/juju-metadata usr/lib/juju-$(VERSION)/bin - dh_install bin/juju-upgrade-mongo usr/lib/juju-$(VERSION)/bin - dh_install bin/jujud usr/lib/juju-$(VERSION)/bin - dh_install bin/juju-$(VERSION) usr/bin + dh_install _build/bin/juju usr/lib/juju-$(VERSION)/bin + dh_install _build/bin/juju-metadata usr/lib/juju-$(VERSION)/bin + dh_install _build/bin/juju-upgrade-mongo usr/lib/juju-$(VERSION)/bin + dh_install _build/bin/jujud usr/lib/juju-$(VERSION)/bin + dh_install _build/bin/juju-$(VERSION) usr/bin dh_install juju.1 usr/lib/juju-$(VERSION)/man/man1 dh_install src/github.com/juju/juju/etc/bash_completion.d/juju2 \ usr/share/bash-completion/completions - dh_auto_install override_dh_link: dh_link -pjuju-2.0 usr/bin/juju-$(VERSION) usr/bin/juju diff -Nru juju-core-2.0~beta6/debian/tests/current-manual-provider juju-core-2.0~beta7/debian/tests/current-manual-provider --- juju-core-2.0~beta6/debian/tests/current-manual-provider 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/debian/tests/current-manual-provider 2016-05-17 20:01:14.000000000 +0000 @@ -1,4 +1,9 @@ #!/bin/sh set -ex +if ! apt-cache show juju-mongodb3.2 >/dev/null 2>&1; then + echo "SKIP: 32-bit state servers not supported after xenial." + exit 0 +fi + sh debian/tests/normal-user.sh debian/tests/manual-provider diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/authorization/client.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/authorization/client.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/authorization/client.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/authorization/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/authorization/managementlocks.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/authorization/managementlocks.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/authorization/managementlocks.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/authorization/managementlocks.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -47,7 +47,7 @@ // // resourceGroupName is the resource group name. lockName is the lock name. // parameters is the management lock parameters. -func (client ManagementLocksClient) CreateOrUpdateAtResourceGroupLevel(resourceGroupName string, lockName string, parameters ManagementLock) (result ManagementLock, ae error) { +func (client ManagementLocksClient) CreateOrUpdateAtResourceGroupLevel(resourceGroupName string, lockName string, parameters ManagementLockProperties) (result ManagementLockObject, ae error) { req, err := client.CreateOrUpdateAtResourceGroupLevelPreparer(resourceGroupName, lockName, parameters) if err != nil { return result, autorest.NewErrorWithError(err, "authorization/ManagementLocksClient", "CreateOrUpdateAtResourceGroupLevel", "Failure preparing request") @@ -68,7 +68,7 @@ } // CreateOrUpdateAtResourceGroupLevelPreparer prepares the CreateOrUpdateAtResourceGroupLevel request. -func (client ManagementLocksClient) CreateOrUpdateAtResourceGroupLevelPreparer(resourceGroupName string, lockName string, parameters ManagementLock) (*http.Request, error) { +func (client ManagementLocksClient) CreateOrUpdateAtResourceGroupLevelPreparer(resourceGroupName string, lockName string, parameters ManagementLockProperties) (*http.Request, error) { pathParameters := map[string]interface{}{ "lockName": url.QueryEscape(lockName), "resourceGroupName": url.QueryEscape(resourceGroupName), @@ -97,7 +97,7 @@ // CreateOrUpdateAtResourceGroupLevelResponder handles the response to the CreateOrUpdateAtResourceGroupLevel request. The method always // closes the http.Response Body. -func (client ManagementLocksClient) CreateOrUpdateAtResourceGroupLevelResponder(resp *http.Response) (result ManagementLock, err error) { +func (client ManagementLocksClient) CreateOrUpdateAtResourceGroupLevelResponder(resp *http.Response) (result ManagementLockObject, err error) { err = autorest.Respond( resp, client.ByInspecting(), @@ -116,7 +116,7 @@ // resource identity. resourceType is resource identity. resourceName is // resource identity. lockName is the name of lock. parameters is create or // update management lock parameters. -func (client ManagementLocksClient) CreateOrUpdateAtResourceLevel(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, lockName string, parameters ManagementLock) (result ManagementLock, ae error) { +func (client ManagementLocksClient) CreateOrUpdateAtResourceLevel(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, lockName string, parameters ManagementLockProperties) (result ManagementLockObject, ae error) { req, err := client.CreateOrUpdateAtResourceLevelPreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, lockName, parameters) if err != nil { return result, autorest.NewErrorWithError(err, "authorization/ManagementLocksClient", "CreateOrUpdateAtResourceLevel", "Failure preparing request") @@ -137,7 +137,7 @@ } // CreateOrUpdateAtResourceLevelPreparer prepares the CreateOrUpdateAtResourceLevel request. -func (client ManagementLocksClient) CreateOrUpdateAtResourceLevelPreparer(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, lockName string, parameters ManagementLock) (*http.Request, error) { +func (client ManagementLocksClient) CreateOrUpdateAtResourceLevelPreparer(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, lockName string, parameters ManagementLockProperties) (*http.Request, error) { pathParameters := map[string]interface{}{ "lockName": url.QueryEscape(lockName), "parentResourcePath": parentResourcePath, @@ -170,7 +170,7 @@ // CreateOrUpdateAtResourceLevelResponder handles the response to the CreateOrUpdateAtResourceLevel request. The method always // closes the http.Response Body. -func (client ManagementLocksClient) CreateOrUpdateAtResourceLevelResponder(resp *http.Response) (result ManagementLock, err error) { +func (client ManagementLocksClient) CreateOrUpdateAtResourceLevelResponder(resp *http.Response) (result ManagementLockObject, err error) { err = autorest.Respond( resp, client.ByInspecting(), @@ -185,7 +185,7 @@ // subscription level. // // lockName is the name of lock. parameters is the management lock parameters. -func (client ManagementLocksClient) CreateOrUpdateAtSubscriptionLevel(lockName string, parameters ManagementLock) (result ManagementLock, ae error) { +func (client ManagementLocksClient) CreateOrUpdateAtSubscriptionLevel(lockName string, parameters ManagementLockProperties) (result ManagementLockObject, ae error) { req, err := client.CreateOrUpdateAtSubscriptionLevelPreparer(lockName, parameters) if err != nil { return result, autorest.NewErrorWithError(err, "authorization/ManagementLocksClient", "CreateOrUpdateAtSubscriptionLevel", "Failure preparing request") @@ -206,7 +206,7 @@ } // CreateOrUpdateAtSubscriptionLevelPreparer prepares the CreateOrUpdateAtSubscriptionLevel request. -func (client ManagementLocksClient) CreateOrUpdateAtSubscriptionLevelPreparer(lockName string, parameters ManagementLock) (*http.Request, error) { +func (client ManagementLocksClient) CreateOrUpdateAtSubscriptionLevelPreparer(lockName string, parameters ManagementLockProperties) (*http.Request, error) { pathParameters := map[string]interface{}{ "lockName": url.QueryEscape(lockName), "subscriptionId": url.QueryEscape(client.SubscriptionID), @@ -234,7 +234,7 @@ // CreateOrUpdateAtSubscriptionLevelResponder handles the response to the CreateOrUpdateAtSubscriptionLevel request. The method always // closes the http.Response Body. -func (client ManagementLocksClient) CreateOrUpdateAtSubscriptionLevelResponder(resp *http.Response) (result ManagementLock, err error) { +func (client ManagementLocksClient) CreateOrUpdateAtSubscriptionLevelResponder(resp *http.Response) (result ManagementLockObject, err error) { err = autorest.Respond( resp, client.ByInspecting(), @@ -441,7 +441,7 @@ // Get gets the management lock of a scope. // // lockName is name of the management lock. -func (client ManagementLocksClient) Get(lockName string) (result ManagementLock, ae error) { +func (client ManagementLocksClient) Get(lockName string) (result ManagementLockObject, ae error) { req, err := client.GetPreparer(lockName) if err != nil { return result, autorest.NewErrorWithError(err, "authorization/ManagementLocksClient", "Get", "Failure preparing request") @@ -489,7 +489,7 @@ // GetResponder handles the response to the Get request. The method always // closes the http.Response Body. -func (client ManagementLocksClient) GetResponder(resp *http.Response) (result ManagementLock, err error) { +func (client ManagementLocksClient) GetResponder(resp *http.Response) (result ManagementLockObject, err error) { err = autorest.Respond( resp, client.ByInspecting(), @@ -532,9 +532,11 @@ } queryParameters := map[string]interface{}{ - "$filter": filter, "api-version": APIVersion, } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), @@ -628,9 +630,11 @@ } queryParameters := map[string]interface{}{ - "$filter": filter, "api-version": APIVersion, } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), @@ -714,9 +718,11 @@ } queryParameters := map[string]interface{}{ - "$filter": filter, "api-version": APIVersion, } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/authorization/models.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/authorization/models.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/authorization/models.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/authorization/models.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -48,20 +48,11 @@ Tagvalue *string `json:"tagvalue,omitempty"` } -// ManagementLock is management lock information. -type ManagementLock struct { - autorest.Response `json:"-"` - Properties *ManagementLockProperties `json:"properties,omitempty"` - ID *string `json:"id,omitempty"` - Type *string `json:"type,omitempty"` - Name *string `json:"name,omitempty"` -} - // ManagementLockListResult is list of management locks. type ManagementLockListResult struct { autorest.Response `json:"-"` - Value *[]ManagementLock `json:"value,omitempty"` - NextLink *string `json:"nextLink,omitempty"` + Value *[]ManagementLockObject `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` } // ManagementLockListResultPreparer prepares a request to retrieve the next set of results. It returns @@ -76,6 +67,15 @@ autorest.WithBaseURL(to.String(client.NextLink))) } +// ManagementLockObject is management lock information. +type ManagementLockObject struct { + autorest.Response `json:"-"` + Properties *ManagementLockProperties `json:"properties,omitempty"` + ID *string `json:"id,omitempty"` + Type *string `json:"type,omitempty"` + Name *string `json:"name,omitempty"` +} + // ManagementLockProperties is the management lock properties. type ManagementLockProperties struct { Level LockLevel `json:"level,omitempty"` diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/authorization/version.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/authorization/version.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/authorization/version.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/authorization/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,8 @@ const ( major = "0" - minor = "1" - patch = "1" + minor = "3" + patch = "0" // Always begin a "tag" with a dash (as per http://semver.org) tag = "-beta" semVerFormat = "%s.%s.%s%s" diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/CHANGELOG.md juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/CHANGELOG.md --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/CHANGELOG.md 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/CHANGELOG.md 2016-05-17 20:01:14.000000000 +0000 @@ -1,17 +1,41 @@ # CHANGELOG -## v0.1.1-beta ------------------------------------------------------------------------------------- +----- + +## `v0.3.0-beta` + +- Corrected unintentional struct field renaming and client renaming in v0.2.0-beta + +----- + +## `v0.2.0-beta` + +- Added support for DNS, Redis, and Web site services +- Updated Storage service to API version 2015-06-15 +- Updated Network to include routing table support +- Address https://github.com/Azure/azure-sdk-for-go/issues/232 +- Address https://github.com/Azure/azure-sdk-for-go/issues/231 +- Address https://github.com/Azure/azure-sdk-for-go/issues/230 +- Address https://github.com/Azure/azure-sdk-for-go/issues/224 +- Address https://github.com/Azure/azure-sdk-for-go/issues/184 +- Address https://github.com/Azure/azure-sdk-for-go/issues/183 + +------ + +## `v0.1.1-beta` - Improves the UserAgent string to disambiguate arm packages from others in the SDK - Improves setting the http.Response into generated results (reduces likelihood of a nil reference) - Adds gofmt, golint, and govet to Travis CI for the arm packages -### Fixed Issues +##### Fixed Issues - https://github.com/Azure/azure-sdk-for-go/issues/196 - https://github.com/Azure/azure-sdk-for-go/issues/213 -## v0.1.0-beta ------------------------------------------------------------------------------------- +------ + +## v0.1.0-beta This release addresses the issues raised against the alpha release and adds more features. Most notably, to address the challenges of encoding JSON @@ -24,7 +48,7 @@ Additionally, the packages now align with Go coding standards and pass both `golint` and `govet`. Accomplishing this required renaming various fields and parameters (such as changing Url to URL). -### Changes +##### Changes - Changed request / response structures to use pointer fields. - Changed methods to return `error` instead of `autorest.Error`. @@ -35,14 +59,16 @@ - Updated README.md with details on asynchronous requests and paging. - Saved package dependencies through Godep (for the entire SDK). -### Fixed Issues: +##### Fixed Issues: - https://github.com/Azure/azure-sdk-for-go/issues/205 - https://github.com/Azure/azure-sdk-for-go/issues/206 - https://github.com/Azure/azure-sdk-for-go/issues/211 - https://github.com/Azure/azure-sdk-for-go/issues/212 -## v0.1.0-alpha ------------------------------------------------------------------------------------ +----- + +## v0.1.0-alpha This release introduces the Azure Resource Manager packages generated from the corresponding [Swagger API](http://swagger.io) [definitions](https://github.com/Azure/azure-rest-api-specs). diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/availabilitysets.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/availabilitysets.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/availabilitysets.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/availabilitysets.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,7 @@ "net/url" ) -// AvailabilitySetsClient is the client for the AvailabilitySets methods of -// the Compute service. +// AvailabilitySetsClient is the the Compute Management Client. type AvailabilitySetsClient struct { ManagementClient } @@ -156,7 +155,7 @@ // 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 client.Send(req, http.StatusOK, http.StatusNoContent) + return client.Send(req, http.StatusNoContent, http.StatusOK) } // DeleteResponder handles the response to the Delete request. The method always @@ -165,7 +164,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusOK), autorest.ByClosing()) result.Response = resp return diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/client.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/client.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/client.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -30,7 +30,7 @@ DefaultBaseURI = "https://management.azure.com" ) -// ManagementClient is the base client for Compute. +// ManagementClient is the the Compute Management Client. type ManagementClient struct { autorest.Client BaseURI string diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/models.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/models.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/models.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/models.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -72,18 +72,12 @@ type OperationStatus string const ( - // OperationStatusFailed specifies the operation status failed state for - // operation status. - OperationStatusFailed OperationStatus = "Failed" - // OperationStatusInProgress specifies the operation status in progress - // state for operation status. - OperationStatusInProgress OperationStatus = "InProgress" - // OperationStatusPreempted specifies the operation status preempted state - // for operation status. - OperationStatusPreempted OperationStatus = "Preempted" - // OperationStatusSucceeded specifies the operation status succeeded state - // for operation status. - OperationStatusSucceeded OperationStatus = "Succeeded" + // 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" ) // OperationStatusEnum enumerates the values for operation status enum. @@ -96,6 +90,9 @@ // OperationStatusEnumInProgress specifies the operation status enum in // progress state for operation status enum. OperationStatusEnumInProgress OperationStatusEnum = "InProgress" + // OperationStatusEnumPreempted specifies the operation status enum + // preempted state for operation status enum. + OperationStatusEnumPreempted OperationStatusEnum = "Preempted" // OperationStatusEnumSucceeded specifies the operation status enum // succeeded state for operation status enum. OperationStatusEnumSucceeded OperationStatusEnum = "Succeeded" @@ -142,6 +139,16 @@ 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" +) + // UsageUnit enumerates the values for usage unit. type UsageUnit string @@ -150,6 +157,21 @@ Count UsageUnit = "Count" ) +// 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 @@ -171,6 +193,12 @@ // 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" @@ -195,6 +223,81 @@ // 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" + // 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" + // StandardDS12 specifies the standard ds12 state for virtual machine size + // types. + StandardDS12 VirtualMachineSizeTypes = "Standard_DS12" + // StandardDS13 specifies the standard ds13 state for virtual machine size + // types. + StandardDS13 VirtualMachineSizeTypes = "Standard_DS13" + // StandardDS14 specifies the standard ds14 state for virtual machine size + // types. + StandardDS14 VirtualMachineSizeTypes = "Standard_DS14" + // StandardDS2 specifies the standard ds2 state for virtual machine size + // types. + StandardDS2 VirtualMachineSizeTypes = "Standard_DS2" + // StandardDS3 specifies the standard ds3 state for virtual machine size + // types. + StandardDS3 VirtualMachineSizeTypes = "Standard_DS3" + // StandardDS4 specifies the standard ds4 state for virtual machine size + // types. + StandardDS4 VirtualMachineSizeTypes = "Standard_DS4" // StandardG1 specifies the standard g1 state for virtual machine size // types. StandardG1 VirtualMachineSizeTypes = "Standard_G1" @@ -210,6 +313,21 @@ // 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 gets or sets additional XML formatted @@ -223,6 +341,11 @@ 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"` @@ -264,15 +387,28 @@ 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 *int `json:"lun,omitempty"` - DiskSizeGB *int `json:"diskSizeGB,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 *int `json:"diskSizeGB,omitempty"` } // DataDiskImage is contains the data disk images information. @@ -282,11 +418,22 @@ // DeleteOperationResult is the compute long running operation response. type DeleteOperationResult struct { - OperationID *string `json:"operationId,omitempty"` - Status OperationStatusEnum `json:"status,omitempty"` - StartTime *date.Time `json:"startTime,omitempty"` - EndTime *date.Time `json:"endTime,omitempty"` - Error *APIError `json:"error,omitempty"` + OperationID *string `json:"operationId,omitempty"` + Status OperationStatus `json:"status,omitempty"` + StartTime *date.Time `json:"startTime,omitempty"` + EndTime *date.Time `json:"endTime,omitempty"` + Error *APIError `json:"error,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"` } // DiskInstanceView is the instance view of the disk. @@ -323,6 +470,18 @@ 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"` @@ -338,19 +497,18 @@ // LongRunningOperationProperties is compute-specific operation properties, // including output type LongRunningOperationProperties struct { - Output *map[string]*string `json:"output,omitempty"` + Output *map[string]interface{} `json:"output,omitempty"` } // LongRunningOperationResult is the Compute service response for long-running // operations. type LongRunningOperationResult struct { - autorest.Response `json:"-"` - OperationID *string `json:"operationId,omitempty"` - Status OperationStatus `json:"status,omitempty"` - StartTime *date.Time `json:"startTime,omitempty"` - EndTime *date.Time `json:"endTime,omitempty"` - Properties *LongRunningOperationProperties `json:"properties,omitempty"` - Error *APIError `json:"error,omitempty"` + OperationID *string `json:"operationId,omitempty"` + Status OperationStatusEnum `json:"status,omitempty"` + StartTime *date.Time `json:"startTime,omitempty"` + EndTime *date.Time `json:"endTime,omitempty"` + Properties *LongRunningOperationProperties `json:"properties,omitempty"` + Error *APIError `json:"error,omitempty"` } // NetworkInterfaceReference is describes a network interface reference. @@ -372,12 +530,14 @@ // OSDisk is describes an Operating System disk. type OSDisk struct { - OsType OperatingSystemTypes `json:"osType,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"` + 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 *int `json:"diskSizeGB,omitempty"` } // OSDiskImage is contains the os disk image information. @@ -421,6 +581,13 @@ 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 *int32 `json:"capacity,omitempty"` +} + // SSHConfiguration is sSH configuration for Linux based VMs running on Azure type SSHConfiguration struct { PublicKeys *[]SSHPublicKey `json:"publicKeys,omitempty"` @@ -445,6 +612,11 @@ 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 UsageUnit `json:"unit,omitempty"` @@ -506,6 +678,19 @@ 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:"-"` @@ -562,8 +747,8 @@ Type *string `json:"type,omitempty"` TypeHandlerVersion *string `json:"typeHandlerVersion,omitempty"` AutoUpgradeMinorVersion *bool `json:"autoUpgradeMinorVersion,omitempty"` - Settings *map[string]*string `json:"settings,omitempty"` - ProtectedSettings *map[string]*string `json:"protectedSettings,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"` } @@ -608,6 +793,7 @@ 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"` } @@ -632,13 +818,270 @@ // 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"` - AvailabilitySet *SubResource `json:"availabilitySet,omitempty"` - ProvisioningState *string `json:"provisioningState,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"` + InstanceView *VirtualMachineInstanceView `json:"instanceView,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"` + LoadBalancerBackendAddressPools *[]SubResource `json:"loadBalancerBackendAddressPools,omitempty"` +} + +// VirtualMachineScaleSetListResult is the List Virtual Machine operation +// response. +type VirtualMachineScaleSetListResult struct { + autorest.Response `json:"-"` + Value *[]VirtualMachineScaleSet `json:"value,omitempty"` +} + +// VirtualMachineScaleSetListSkusResult is the Virtual Machine Scale Set List +// Skus operation response. +type VirtualMachineScaleSetListSkusResult struct { + autorest.Response `json:"-"` + Value *[]VirtualMachineScaleSetSku `json:"value,omitempty"` +} + +// 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"` +} + +// 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 *int32 `json:"minimum,omitempty"` + Maximum *int32 `json:"maximum,omitempty"` + DefaultCapacity *int32 `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 *int `json:"platformUpdateDomain,omitempty"` + PlatformFaultDomain *int `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"` +} + +// 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"` } // VirtualMachineSize is describes the properties of a VM size. @@ -657,6 +1100,13 @@ 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 *int `json:"count,omitempty"` +} + // WindowsConfiguration is describes Windows Configuration of the OS Profile. type WindowsConfiguration struct { ProvisionVMAgent *bool `json:"provisionVMAgent,omitempty"` diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/usageoperations.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/usageoperations.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/usageoperations.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/usageoperations.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,7 @@ "net/url" ) -// UsageOperationsClient is the client for the UsageOperations methods of the -// Compute service. +// UsageOperationsClient is the the Compute Management Client. type UsageOperationsClient struct { ManagementClient } diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/version.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/version.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/version.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,8 @@ const ( major = "0" - minor = "1" - patch = "1" + minor = "3" + patch = "0" // Always begin a "tag" with a dash (as per http://semver.org) tag = "-beta" semVerFormat = "%s.%s.%s%s" diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineextensionimages.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineextensionimages.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineextensionimages.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineextensionimages.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,7 @@ "net/url" ) -// VirtualMachineExtensionImagesClient is the client for the -// VirtualMachineExtensionImages methods of the Compute service. +// VirtualMachineExtensionImagesClient is the the Compute Management Client. type VirtualMachineExtensionImagesClient struct { ManagementClient } @@ -171,8 +170,8 @@ // 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 int, orderby string) (result VirtualMachineImageResourceList, ae error) { - req, err := client.ListVersionsPreparer(location, publisherName, typeParameter, filter, top, orderby) +func (client VirtualMachineExtensionImagesClient) ListVersions(location string, publisherName string, typeParameter string, filter string, top *int, orderBy string) (result VirtualMachineImageResourceList, ae error) { + req, err := client.ListVersionsPreparer(location, publisherName, typeParameter, filter, top, orderBy) if err != nil { return result, autorest.NewErrorWithError(err, "compute/VirtualMachineExtensionImagesClient", "ListVersions", "Failure preparing request") } @@ -192,7 +191,7 @@ } // ListVersionsPreparer prepares the ListVersions request. -func (client VirtualMachineExtensionImagesClient) ListVersionsPreparer(location string, publisherName string, typeParameter string, filter string, top int, orderby string) (*http.Request, error) { +func (client VirtualMachineExtensionImagesClient) ListVersionsPreparer(location string, publisherName string, typeParameter string, filter string, top *int, orderBy string) (*http.Request, error) { pathParameters := map[string]interface{}{ "location": url.QueryEscape(location), "publisherName": url.QueryEscape(publisherName), @@ -201,11 +200,17 @@ } queryParameters := map[string]interface{}{ - "$filter": filter, - "$orderby": orderby, - "$top": top, "api-version": APIVersion, } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + if top != nil { + queryParameters["$top"] = top + } + if len(orderBy) > 0 { + queryParameters["$orderBy"] = orderBy + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineextensions.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineextensions.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineextensions.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineextensions.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,7 @@ "net/url" ) -// VirtualMachineExtensionsClient is the client for the -// VirtualMachineExtensions methods of the Compute service. +// VirtualMachineExtensionsClient is the the Compute Management Client. type VirtualMachineExtensionsClient struct { ManagementClient } @@ -161,7 +160,7 @@ // 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 client.Send(req, http.StatusOK, http.StatusNoContent, http.StatusAccepted) + return client.Send(req, http.StatusAccepted, http.StatusNoContent, http.StatusOK) } // DeleteResponder handles the response to the Delete request. The method always @@ -170,7 +169,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusAccepted), + autorest.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusNoContent, http.StatusOK), autorest.ByClosing()) result.Response = resp return @@ -180,8 +179,8 @@ // // 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 name of the property to -// expand. Allowed value is null or 'instanceView'. +// 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, ae error) { req, err := client.GetPreparer(resourceGroupName, vmName, vmExtensionName, expand) if err != nil { @@ -212,9 +211,11 @@ } queryParameters := map[string]interface{}{ - "$expand": expand, "api-version": APIVersion, } + if len(expand) > 0 { + queryParameters["$expand"] = expand + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineimages.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineimages.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineimages.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachineimages.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,7 @@ "net/url" ) -// VirtualMachineImagesClient is the client for the VirtualMachineImages -// methods of the Compute service. +// VirtualMachineImagesClient is the the Compute Management Client. type VirtualMachineImagesClient struct { ManagementClient } @@ -110,7 +109,7 @@ // 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 int, orderby string) (result VirtualMachineImageResourceList, ae error) { +func (client VirtualMachineImagesClient) List(location string, publisherName string, offer string, skus string, filter string, top *int, orderby string) (result VirtualMachineImageResourceList, ae error) { req, err := client.ListPreparer(location, publisherName, offer, skus, filter, top, orderby) if err != nil { return result, autorest.NewErrorWithError(err, "compute/VirtualMachineImagesClient", "List", "Failure preparing request") @@ -131,7 +130,7 @@ } // ListPreparer prepares the List request. -func (client VirtualMachineImagesClient) ListPreparer(location string, publisherName string, offer string, skus string, filter string, top int, orderby string) (*http.Request, error) { +func (client VirtualMachineImagesClient) ListPreparer(location string, publisherName string, offer string, skus string, filter string, top *int, orderby string) (*http.Request, error) { pathParameters := map[string]interface{}{ "location": url.QueryEscape(location), "offer": url.QueryEscape(offer), @@ -141,11 +140,17 @@ } queryParameters := map[string]interface{}{ - "$filter": filter, - "$orderby": orderby, - "$top": top, "api-version": APIVersion, } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + if top != nil { + queryParameters["$top"] = top + } + if len(orderby) > 0 { + queryParameters["$orderby"] = orderby + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinescalesets.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinescalesets.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinescalesets.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinescalesets.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,927 @@ +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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// 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 the operation to create or update a virtual machine scale +// set. +// +// 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) (result VirtualMachineScaleSet, ae error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, name, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "CreateOrUpdate", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "CreateOrUpdate", "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "CreateOrUpdate", "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client VirtualMachineScaleSetsClient) CreateOrUpdatePreparer(resourceGroupName string, name string, parameters VirtualMachineScaleSet) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{name}"), + autorest.WithJSON(parameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusCreated, http.StatusOK) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client VirtualMachineScaleSetsClient) CreateOrUpdateResponder(resp *http.Response) (result VirtualMachineScaleSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Deallocate the operation to deallocate virtual machines in a virtual +// machine scale set. +// +// 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) (result autorest.Response, ae error) { + req, err := client.DeallocatePreparer(resourceGroupName, vmScaleSetName, vmInstanceIDs) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "Deallocate", "Failure preparing request") + } + + resp, err := client.DeallocateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "Deallocate", "Failure sending request") + } + + result, err = client.DeallocateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "Deallocate", "Failure responding to request") + } + + return +} + +// DeallocatePreparer prepares the Deallocate request. +func (client VirtualMachineScaleSetsClient) DeallocatePreparer(resourceGroupName string, vmScaleSetName string, vmInstanceIDs *VirtualMachineScaleSetVMInstanceIDs) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/deallocate"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) + if vmInstanceIDs != nil { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithJSON(vmInstanceIDs)) + } + return preparer.Prepare(&http.Request{}) +} + +// 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 client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the operation to delete 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) Delete(resourceGroupName string, vmScaleSetName string) (result autorest.Response, ae error) { + req, err := client.DeletePreparer(resourceGroupName, vmScaleSetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "Delete", "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "Delete", "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "Delete", "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client VirtualMachineScaleSetsClient) DeletePreparer(resourceGroupName string, vmScaleSetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusAccepted, http.StatusOK, http.StatusNoContent) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// DeleteInstances the operation to delete virtual machines in a virtual +// machine scale set. +// +// 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) (result autorest.Response, ae error) { + req, err := client.DeleteInstancesPreparer(resourceGroupName, vmScaleSetName, vmInstanceIDs) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "DeleteInstances", "Failure preparing request") + } + + resp, err := client.DeleteInstancesSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "DeleteInstances", "Failure sending request") + } + + result, err = client.DeleteInstancesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "DeleteInstances", "Failure responding to request") + } + + return +} + +// DeleteInstancesPreparer prepares the DeleteInstances request. +func (client VirtualMachineScaleSetsClient) DeleteInstancesPreparer(resourceGroupName string, vmScaleSetName string, vmInstanceIDs VirtualMachineScaleSetVMInstanceRequiredIDs) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/delete"), + autorest.WithJSON(vmInstanceIDs), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the operation to get 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, ae error) { + req, err := client.GetPreparer(resourceGroupName, vmScaleSetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "Get", "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", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "Get", "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": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetInstanceView the operation to get a virtual machine scale set instance +// view. +// +// 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, ae error) { + req, err := client.GetInstanceViewPreparer(resourceGroupName, vmScaleSetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "GetInstanceView", "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", "Failure sending request") + } + + result, err = client.GetInstanceViewResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "GetInstanceView", "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": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/instanceView"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the operation to list virtual machine scale sets under a resource +// group. +// +// resourceGroupName is the name of the resource group. +func (client VirtualMachineScaleSetsClient) List(resourceGroupName string) (result VirtualMachineScaleSetListResult, ae error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "List", "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", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "List", "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client VirtualMachineScaleSetsClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListAll gets the list of 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, ae error) { + req, err := client.ListAllPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "ListAll", "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", "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "ListAll", "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client VirtualMachineScaleSetsClient) ListAllPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Compute/virtualMachineScaleSets"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := lastResults.VirtualMachineScaleSetListWithLinkResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "ListAll", "Failure preparing next results request 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", "Failure sending next results request request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "ListAll", "Failure responding to next results request request") + } + + return +} + +// ListSkus the operation to list available skus for 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) ListSkus(resourceGroupName string, vmScaleSetName string) (result VirtualMachineScaleSetListSkusResult, ae error) { + req, err := client.ListSkusPreparer(resourceGroupName, vmScaleSetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "ListSkus", "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", "Failure sending request") + } + + result, err = client.ListSkusResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "ListSkus", "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": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/skus"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// PowerOff the operation to power off (stop) virtual machines in a virtual +// machine scale set. +// +// 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) (result autorest.Response, ae error) { + req, err := client.PowerOffPreparer(resourceGroupName, vmScaleSetName, vmInstanceIDs) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "PowerOff", "Failure preparing request") + } + + resp, err := client.PowerOffSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "PowerOff", "Failure sending request") + } + + result, err = client.PowerOffResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "PowerOff", "Failure responding to request") + } + + return +} + +// PowerOffPreparer prepares the PowerOff request. +func (client VirtualMachineScaleSetsClient) PowerOffPreparer(resourceGroupName string, vmScaleSetName string, vmInstanceIDs *VirtualMachineScaleSetVMInstanceIDs) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/poweroff"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) + if vmInstanceIDs != nil { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithJSON(vmInstanceIDs)) + } + return preparer.Prepare(&http.Request{}) +} + +// 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 client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Restart the operation to restart virtual machines in a virtual machine +// scale set. +// +// 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) (result autorest.Response, ae error) { + req, err := client.RestartPreparer(resourceGroupName, vmScaleSetName, vmInstanceIDs) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "Restart", "Failure preparing request") + } + + resp, err := client.RestartSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "Restart", "Failure sending request") + } + + result, err = client.RestartResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "Restart", "Failure responding to request") + } + + return +} + +// RestartPreparer prepares the Restart request. +func (client VirtualMachineScaleSetsClient) RestartPreparer(resourceGroupName string, vmScaleSetName string, vmInstanceIDs *VirtualMachineScaleSetVMInstanceIDs) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/restart"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) + if vmInstanceIDs != nil { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithJSON(vmInstanceIDs)) + } + return preparer.Prepare(&http.Request{}) +} + +// 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 client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Start the operation to start virtual machines in a virtual machine scale +// set. +// +// 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) (result autorest.Response, ae error) { + req, err := client.StartPreparer(resourceGroupName, vmScaleSetName, vmInstanceIDs) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "Start", "Failure preparing request") + } + + resp, err := client.StartSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "Start", "Failure sending request") + } + + result, err = client.StartResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "Start", "Failure responding to request") + } + + return +} + +// StartPreparer prepares the Start request. +func (client VirtualMachineScaleSetsClient) StartPreparer(resourceGroupName string, vmScaleSetName string, vmInstanceIDs *VirtualMachineScaleSetVMInstanceIDs) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/start"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) + if vmInstanceIDs != nil { + preparer = autorest.DecoratePreparer(preparer, + autorest.WithJSON(vmInstanceIDs)) + } + return preparer.Prepare(&http.Request{}) +} + +// 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 client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// UpdateInstances the operation to manually upgrade virtual machines in a +// virtual machine scale set. +// +// 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) (result autorest.Response, ae error) { + req, err := client.UpdateInstancesPreparer(resourceGroupName, vmScaleSetName, vmInstanceIDs) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "UpdateInstances", "Failure preparing request") + } + + resp, err := client.UpdateInstancesSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "UpdateInstances", "Failure sending request") + } + + result, err = client.UpdateInstancesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetsClient", "UpdateInstances", "Failure responding to request") + } + + return +} + +// UpdateInstancesPreparer prepares the UpdateInstances request. +func (client VirtualMachineScaleSetsClient) UpdateInstancesPreparer(resourceGroupName string, vmScaleSetName string, vmInstanceIDs VirtualMachineScaleSetVMInstanceRequiredIDs) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/manualupgrade"), + autorest.WithJSON(vmInstanceIDs), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinescalesetvms.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinescalesetvms.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinescalesetvms.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinescalesetvms.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,576 @@ +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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// 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 the operation to deallocate a virtual machine scale set. +// +// 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) (result autorest.Response, ae error) { + req, err := client.DeallocatePreparer(resourceGroupName, vmScaleSetName, instanceID) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "Deallocate", "Failure preparing request") + } + + resp, err := client.DeallocateSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "Deallocate", "Failure sending request") + } + + result, err = client.DeallocateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "Deallocate", "Failure responding to request") + } + + return +} + +// DeallocatePreparer prepares the Deallocate request. +func (client VirtualMachineScaleSetVMsClient) DeallocatePreparer(resourceGroupName string, vmScaleSetName string, instanceID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instanceId": url.QueryEscape(instanceID), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}/deallocate"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Delete the operation to delete a virtual machine scale set. +// +// 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) (result autorest.Response, ae error) { + req, err := client.DeletePreparer(resourceGroupName, vmScaleSetName, instanceID) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "Delete", "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "Delete", "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "Delete", "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client VirtualMachineScaleSetVMsClient) DeletePreparer(resourceGroupName string, vmScaleSetName string, instanceID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instanceId": url.QueryEscape(instanceID), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK, http.StatusNoContent, http.StatusAccepted) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the operation to get 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, ae error) { + req, err := client.GetPreparer(resourceGroupName, vmScaleSetName, instanceID) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "Get", "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", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "Get", "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": url.QueryEscape(instanceID), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetInstanceView the operation to get 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, ae error) { + req, err := client.GetInstanceViewPreparer(resourceGroupName, vmScaleSetName, instanceID) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "GetInstanceView", "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", "Failure sending request") + } + + result, err = client.GetInstanceViewResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "GetInstanceView", "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": url.QueryEscape(instanceID), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}/instanceView"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the operation to list virtual machine scale sets VMs. +// +// 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, ae error) { + req, err := client.ListPreparer(resourceGroupName, virtualMachineScaleSetName, filter, selectParameter, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "List", "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", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "List", "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": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "virtualMachineScaleSetName": url.QueryEscape(virtualMachineScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + if len(selectParameter) > 0 { + queryParameters["$select"] = selectParameter + } + if len(expand) > 0 { + queryParameters["$expand"] = expand + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{virtualMachineScaleSetName}/virtualMachines"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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 scale set. +// +// 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) (result autorest.Response, ae error) { + req, err := client.PowerOffPreparer(resourceGroupName, vmScaleSetName, instanceID) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "PowerOff", "Failure preparing request") + } + + resp, err := client.PowerOffSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "PowerOff", "Failure sending request") + } + + result, err = client.PowerOffResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "PowerOff", "Failure responding to request") + } + + return +} + +// PowerOffPreparer prepares the PowerOff request. +func (client VirtualMachineScaleSetVMsClient) PowerOffPreparer(resourceGroupName string, vmScaleSetName string, instanceID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instanceId": url.QueryEscape(instanceID), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}/poweroff"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Restart the operation to restart a virtual machine scale set. +// +// 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) (result autorest.Response, ae error) { + req, err := client.RestartPreparer(resourceGroupName, vmScaleSetName, instanceID) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "Restart", "Failure preparing request") + } + + resp, err := client.RestartSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "Restart", "Failure sending request") + } + + result, err = client.RestartResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "Restart", "Failure responding to request") + } + + return +} + +// RestartPreparer prepares the Restart request. +func (client VirtualMachineScaleSetVMsClient) RestartPreparer(resourceGroupName string, vmScaleSetName string, instanceID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instanceId": url.QueryEscape(instanceID), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}/restart"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} + +// Start the operation to start a virtual machine scale set. +// +// 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) (result autorest.Response, ae error) { + req, err := client.StartPreparer(resourceGroupName, vmScaleSetName, instanceID) + if err != nil { + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "Start", "Failure preparing request") + } + + resp, err := client.StartSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "Start", "Failure sending request") + } + + result, err = client.StartResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "compute/VirtualMachineScaleSetVMsClient", "Start", "Failure responding to request") + } + + return +} + +// StartPreparer prepares the Start request. +func (client VirtualMachineScaleSetVMsClient) StartPreparer(resourceGroupName string, vmScaleSetName string, instanceID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instanceId": url.QueryEscape(instanceID), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vmScaleSetName": url.QueryEscape(vmScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachineScaleSets/{vmScaleSetName}/virtualmachines/{instanceId}/start"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByClosing()) + result.Response = resp + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachines.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachines.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachines.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachines.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,7 @@ "net/url" ) -// VirtualMachinesClient is the client for the VirtualMachines methods of the -// Compute service. +// VirtualMachinesClient is the the Compute Management Client. type VirtualMachinesClient struct { ManagementClient } @@ -48,7 +47,7 @@ // 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) (result LongRunningOperationResult, ae error) { +func (client VirtualMachinesClient) Capture(resourceGroupName string, vmName string, parameters VirtualMachineCaptureParameters) (result VirtualMachineCaptureResult, ae error) { req, err := client.CapturePreparer(resourceGroupName, vmName, parameters) if err != nil { return result, autorest.NewErrorWithError(err, "compute/VirtualMachinesClient", "Capture", "Failure preparing request") @@ -98,7 +97,7 @@ // CaptureResponder handles the response to the Capture request. The method always // closes the http.Response Body. -func (client VirtualMachinesClient) CaptureResponder(resp *http.Response) (result LongRunningOperationResult, err error) { +func (client VirtualMachinesClient) CaptureResponder(resp *http.Response) (result VirtualMachineCaptureResult, err error) { err = autorest.Respond( resp, client.ByInspecting(), @@ -225,7 +224,7 @@ // 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 client.Send(req, http.StatusAccepted) + return client.Send(req, http.StatusOK, http.StatusAccepted) } // DeallocateResponder handles the response to the Deallocate request. The method always @@ -234,7 +233,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusAccepted), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), autorest.ByClosing()) result.Response = resp return @@ -288,7 +287,7 @@ // 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 client.Send(req, http.StatusOK, http.StatusNoContent, http.StatusAccepted) + return client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusNoContent) } // DeleteResponder handles the response to the Delete request. The method always @@ -297,7 +296,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusAccepted), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), autorest.ByClosing()) result.Response = resp return @@ -369,8 +368,8 @@ // 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 name of the property to expand. Allowed -// value is null or 'instanceView'. +// the virtual machine. expand is the expand expression to apply on the +// operation. func (client VirtualMachinesClient) Get(resourceGroupName string, vmName string, expand string) (result VirtualMachine, ae error) { req, err := client.GetPreparer(resourceGroupName, vmName, expand) if err != nil { @@ -400,9 +399,11 @@ } queryParameters := map[string]interface{}{ - "$expand": expand, "api-version": APIVersion, } + if len(expand) > 0 { + queryParameters["$expand"] = expand + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), @@ -716,7 +717,7 @@ // 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 client.Send(req, http.StatusAccepted) + return client.Send(req, http.StatusOK, http.StatusAccepted) } // PowerOffResponder handles the response to the PowerOff request. The method always @@ -725,7 +726,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusAccepted), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), autorest.ByClosing()) result.Response = resp return @@ -779,7 +780,7 @@ // 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 client.Send(req, http.StatusAccepted) + return client.Send(req, http.StatusOK, http.StatusAccepted) } // RestartResponder handles the response to the Restart request. The method always @@ -788,7 +789,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusAccepted), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), autorest.ByClosing()) result.Response = resp return @@ -842,7 +843,7 @@ // 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 client.Send(req, http.StatusAccepted) + return client.Send(req, http.StatusOK, http.StatusAccepted) } // StartResponder handles the response to the Start request. The method always @@ -851,7 +852,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusAccepted), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), autorest.ByClosing()) result.Response = resp return diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinesizes.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinesizes.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinesizes.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/compute/virtualmachinesizes.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,7 @@ "net/url" ) -// VirtualMachineSizesClient is the client for the VirtualMachineSizes methods -// of the Compute service. +// VirtualMachineSizesClient is the the Compute Management Client. type VirtualMachineSizesClient struct { ManagementClient } diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/dns/client.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/dns/client.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/dns/client.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/dns/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,52 @@ +package dns + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" +) + +const ( + // APIVersion is the version of the Dns + APIVersion = "2015-11-01" + + // DefaultBaseURI is the default URI used for the service Dns + DefaultBaseURI = "https://management.azure.com" +) + +// ManagementClient is the client for managing DNS zones and record. +type ManagementClient struct { + autorest.Client + BaseURI 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, + SubscriptionID: subscriptionID, + } +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/dns/models.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/dns/models.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/dns/models.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/dns/models.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,187 @@ +package dns + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" +) + +// RecordType enumerates the values for record type. +type RecordType string + +const ( + // A specifies the a state for record type. + A RecordType = "A" + // AAAA specifies the aaaa state for record type. + AAAA RecordType = "AAAA" + // CNAME specifies the cname state for record type. + CNAME RecordType = "CNAME" + // MX specifies the mx state for record type. + MX RecordType = "MX" + // NS specifies the ns state for record type. + NS RecordType = "NS" + // PTR specifies the ptr state for record type. + PTR RecordType = "PTR" + // SOA specifies the soa state for record type. + SOA RecordType = "SOA" + // SRV specifies the srv state for record type. + SRV RecordType = "SRV" + // TXT specifies the txt state for record type. + TXT RecordType = "TXT" +) + +// AaaaRecord is an AAAA record. +type AaaaRecord struct { + Ipv6Address *string `json:"ipv6Address,omitempty"` +} + +// ARecord is an A record. +type ARecord struct { + Ipv4Address *string `json:"ipv4Address,omitempty"` +} + +// CnameRecord is a CNAME record. +type CnameRecord struct { + Cname *string `json:"cname,omitempty"` +} + +// MxRecord is an MX record. +type MxRecord struct { + Preference *int `json:"preference,omitempty"` + Exchange *string `json:"exchange,omitempty"` +} + +// NsRecord is an NS record. +type NsRecord struct { + Nsdname *string `json:"nsdname,omitempty"` +} + +// PtrRecord is a PTR record. +type PtrRecord struct { + Ptrdname *string `json:"ptrdname,omitempty"` +} + +// RecordSet is describes a DNS RecordSet (a set of DNS records with the same +// name and type). +type RecordSet 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"` + Etag *string `json:"etag,omitempty"` + Properties *RecordSetProperties `json:"properties,omitempty"` +} + +// RecordSetCreateOrUpdateParameters is parameters supplied to create or +// update a RecordSet. +type RecordSetCreateOrUpdateParameters struct { + RecordSet *RecordSet `json:"RecordSet,omitempty"` +} + +// RecordSetListResult is the response to a RecordSet List operation. +type RecordSetListResult struct { + autorest.Response `json:"-"` + Value *[]RecordSet `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// RecordSetProperties is represents the properties of the records in the +// RecordSet. +type RecordSetProperties struct { + TTL *int32 `json:"TTL,omitempty"` + ARecords *[]ARecord `json:"ARecords,omitempty"` + AAAARecords *[]AaaaRecord `json:"AAAARecords,omitempty"` + MXRecords *[]MxRecord `json:"MXRecords,omitempty"` + NSRecords *[]NsRecord `json:"NSRecords,omitempty"` + PTRRecords *[]PtrRecord `json:"PTRRecords,omitempty"` + SRVRecords *[]SrvRecord `json:"SRVRecords,omitempty"` + TXTRecords *[]TxtRecord `json:"TXTRecords,omitempty"` + CNAMERecord *CnameRecord `json:"CNAMERecord,omitempty"` + SOARecord *SoaRecord `json:"SOARecord,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"` +} + +// SoaRecord is an SOA record. +type SoaRecord struct { + Host *string `json:"host,omitempty"` + Email *string `json:"email,omitempty"` + SerialNumber *int32 `json:"serialNumber,omitempty"` + RefreshTime *int32 `json:"refreshTime,omitempty"` + RetryTime *int32 `json:"retryTime,omitempty"` + ExpireTime *int32 `json:"expireTime,omitempty"` + MinimumTTL *int32 `json:"minimumTTL,omitempty"` +} + +// SrvRecord is an SRV record. +type SrvRecord struct { + Priority *int `json:"priority,omitempty"` + Weight *int `json:"weight,omitempty"` + Port *int `json:"port,omitempty"` + Target *string `json:"target,omitempty"` +} + +// SubResource is +type SubResource struct { + ID *string `json:"id,omitempty"` +} + +// TxtRecord is a TXT record. +type TxtRecord struct { + Value *[]string `json:"value,omitempty"` +} + +// Zone is describes a DNS zone. +type Zone 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"` + Etag *string `json:"etag,omitempty"` + Properties *ZoneProperties `json:"properties,omitempty"` +} + +// ZoneCreateOrUpdateParameters is parameters supplied to create a zone. +type ZoneCreateOrUpdateParameters struct { + Zone *Zone `json:"Zone,omitempty"` +} + +// ZoneListResult is the response to a Zone List or ListAll operation. +type ZoneListResult struct { + autorest.Response `json:"-"` + Value *[]Zone `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ZoneProperties is represents the properties of the zone. +type ZoneProperties struct { + MaxNumberOfRecordSets *int32 `json:"maxNumberOfRecordSets,omitempty"` + NumberOfRecordSets *int32 `json:"numberOfRecordSets,omitempty"` +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/dns/recordsets.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/dns/recordsets.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/dns/recordsets.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/dns/recordsets.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,400 @@ +package dns + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// RecordSetsClient is the client for managing DNS zones and record. +type RecordSetsClient struct { + ManagementClient +} + +// NewRecordSetsClient creates an instance of the RecordSetsClient client. +func NewRecordSetsClient(subscriptionID string) RecordSetsClient { + return NewRecordSetsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewRecordSetsClientWithBaseURI creates an instance of the RecordSetsClient +// client. +func NewRecordSetsClientWithBaseURI(baseURI string, subscriptionID string) RecordSetsClient { + return RecordSetsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate creates a RecordSet within a DNS zone. +// +// resourceGroupName is the name of the resource group. zoneName is the name +// of the zone without a terminating dot. recordType is the type of DNS +// record. Possible values for this parameter include: 'A', 'AAAA', 'CNAME', +// 'MX', 'NS', 'PTR', 'SOA', 'SRV', 'TXT' relativeRecordSetName is the name +// of the RecordSet, relative to the name of the zone. parameters is +// parameters supplied to the CreateOrUpdate operation. ifMatch is the etag +// of RecordSet. ifNoneMatch is defines the If-None-Match condition. Set to +// '*' to force Create-If-Not-Exist. Other values will be ignored. +func (client RecordSetsClient) CreateOrUpdate(resourceGroupName string, zoneName string, recordType RecordType, relativeRecordSetName string, parameters RecordSetCreateOrUpdateParameters, ifMatch string, ifNoneMatch string) (result RecordSet, ae error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, zoneName, recordType, relativeRecordSetName, parameters, ifMatch, ifNoneMatch) + if err != nil { + return result, autorest.NewErrorWithError(err, "dns/RecordSetsClient", "CreateOrUpdate", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "dns/RecordSetsClient", "CreateOrUpdate", "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "dns/RecordSetsClient", "CreateOrUpdate", "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client RecordSetsClient) CreateOrUpdatePreparer(resourceGroupName string, zoneName string, recordType RecordType, relativeRecordSetName string, parameters RecordSetCreateOrUpdateParameters, ifMatch string, ifNoneMatch string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "recordType": url.QueryEscape(string(recordType)), + "relativeRecordSetName": relativeRecordSetName, + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "zoneName": url.QueryEscape(zoneName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnszones/{zoneName}/{recordType}/{relativeRecordSetName}"), + autorest.WithJSON(parameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client RecordSetsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client RecordSetsClient) CreateOrUpdateResponder(resp *http.Response) (result RecordSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete removes a RecordSet from a DNS zone. +// +// resourceGroupName is the name of the resource group. zoneName is the name +// of the zone without a terminating dot. recordType is the type of DNS +// record. Possible values for this parameter include: 'A', 'AAAA', 'CNAME', +// 'MX', 'NS', 'PTR', 'SOA', 'SRV', 'TXT' relativeRecordSetName is the name +// of the RecordSet, relative to the name of the zone. ifMatch is defines the +// If-Match condition. The delete operation will be performed only if the +// ETag of the zone on the server matches this value. +func (client RecordSetsClient) Delete(resourceGroupName string, zoneName string, recordType RecordType, relativeRecordSetName string, ifMatch string) (result autorest.Response, ae error) { + req, err := client.DeletePreparer(resourceGroupName, zoneName, recordType, relativeRecordSetName, ifMatch) + if err != nil { + return result, autorest.NewErrorWithError(err, "dns/RecordSetsClient", "Delete", "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "dns/RecordSetsClient", "Delete", "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "dns/RecordSetsClient", "Delete", "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client RecordSetsClient) DeletePreparer(resourceGroupName string, zoneName string, recordType RecordType, relativeRecordSetName string, ifMatch string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "recordType": url.QueryEscape(string(recordType)), + "relativeRecordSetName": relativeRecordSetName, + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "zoneName": url.QueryEscape(zoneName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnszones/{zoneName}/{recordType}/{relativeRecordSetName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client RecordSetsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client RecordSetsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get gets a RecordSet. +// +// resourceGroupName is the name of the resource group. zoneName is the name +// of the zone without a terminating dot. recordType is the type of DNS +// record. Possible values for this parameter include: 'A', 'AAAA', 'CNAME', +// 'MX', 'NS', 'PTR', 'SOA', 'SRV', 'TXT' relativeRecordSetName is the name +// of the RecordSet, relative to the name of the zone. +func (client RecordSetsClient) Get(resourceGroupName string, zoneName string, recordType RecordType, relativeRecordSetName string) (result RecordSet, ae error) { + req, err := client.GetPreparer(resourceGroupName, zoneName, recordType, relativeRecordSetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "dns/RecordSetsClient", "Get", "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "dns/RecordSetsClient", "Get", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "dns/RecordSetsClient", "Get", "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client RecordSetsClient) GetPreparer(resourceGroupName string, zoneName string, recordType RecordType, relativeRecordSetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "recordType": url.QueryEscape(string(recordType)), + "relativeRecordSetName": relativeRecordSetName, + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "zoneName": url.QueryEscape(zoneName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnszones/{zoneName}/{recordType}/{relativeRecordSetName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client RecordSetsClient) GetSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client RecordSetsClient) GetResponder(resp *http.Response) (result RecordSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List lists the RecordSets of a specified type in a DNS zone. +// +// resourceGroupName is the name of the resource group that contains the zone. +// zoneName is the name of the zone from which to enumerate RecordsSets. +// recordType is the type of record sets to enumerate. Possible values for +// this parameter include: 'A', 'AAAA', 'CNAME', 'MX', 'NS', 'PTR', 'SOA', +// 'SRV', 'TXT' top is query parameters. If null is passed returns the +// default number of zones. filter is the filter to apply on the operation. +func (client RecordSetsClient) List(resourceGroupName string, zoneName string, recordType RecordType, top string, filter string) (result RecordSetListResult, ae error) { + req, err := client.ListPreparer(resourceGroupName, zoneName, recordType, top, filter) + if err != nil { + return result, autorest.NewErrorWithError(err, "dns/RecordSetsClient", "List", "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "dns/RecordSetsClient", "List", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "dns/RecordSetsClient", "List", "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client RecordSetsClient) ListPreparer(resourceGroupName string, zoneName string, recordType RecordType, top string, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "recordType": url.QueryEscape(string(recordType)), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "zoneName": url.QueryEscape(zoneName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(top) > 0 { + queryParameters["$top"] = top + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnszones/{zoneName}/{recordType}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client RecordSetsClient) ListSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client RecordSetsClient) ListResponder(resp *http.Response) (result RecordSetListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListAll lists all RecordSets in a DNS zone. +// +// resourceGroupName is the name of the resource group that contains the zone. +// zoneName is the name of the zone from which to enumerate RecordSets. top +// is query parameters. If null is passed returns the default number of +// zones. filter is the filter to apply on the operation. +func (client RecordSetsClient) ListAll(resourceGroupName string, zoneName string, top string, filter string) (result RecordSetListResult, ae error) { + req, err := client.ListAllPreparer(resourceGroupName, zoneName, top, filter) + if err != nil { + return result, autorest.NewErrorWithError(err, "dns/RecordSetsClient", "ListAll", "Failure preparing request") + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "dns/RecordSetsClient", "ListAll", "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "dns/RecordSetsClient", "ListAll", "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client RecordSetsClient) ListAllPreparer(resourceGroupName string, zoneName string, top string, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "zoneName": url.QueryEscape(zoneName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(top) > 0 { + queryParameters["$top"] = top + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnszones/{zoneName}/recordsets"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListAllSender sends the ListAll request. The method will close the +// http.Response Body if it receives an error. +func (client RecordSetsClient) ListAllSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListAllResponder handles the response to the ListAll request. The method always +// closes the http.Response Body. +func (client RecordSetsClient) ListAllResponder(resp *http.Response) (result RecordSetListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/dns/version.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/dns/version.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/dns/version.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/dns/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,43 @@ +package dns + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "fmt" +) + +const ( + major = "0" + minor = "3" + 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;Package arm/%s;API %s" +) + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return fmt.Sprintf(userAgentFormat, Version(), "dns", "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 -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/dns/zones.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/dns/zones.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/dns/zones.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/dns/zones.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,375 @@ +package dns + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// ZonesClient is the client for managing DNS zones and record. +type ZonesClient struct { + ManagementClient +} + +// NewZonesClient creates an instance of the ZonesClient client. +func NewZonesClient(subscriptionID string) ZonesClient { + return NewZonesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewZonesClientWithBaseURI creates an instance of the ZonesClient client. +func NewZonesClientWithBaseURI(baseURI string, subscriptionID string) ZonesClient { + return ZonesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate creates a DNS zone within a resource group. +// +// resourceGroupName is the name of the resource group. zoneName is the name +// of the zone without a terminating dot. parameters is parameters supplied +// to the CreateOrUpdate operation. ifMatch is the etag of Zone. ifNoneMatch +// is defines the If-None-Match condition. Set to '*' to force +// Create-If-Not-Exist. Other values will be ignored. +func (client ZonesClient) CreateOrUpdate(resourceGroupName string, zoneName string, parameters ZoneCreateOrUpdateParameters, ifMatch string, ifNoneMatch string) (result Zone, ae error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, zoneName, parameters, ifMatch, ifNoneMatch) + if err != nil { + return result, autorest.NewErrorWithError(err, "dns/ZonesClient", "CreateOrUpdate", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "dns/ZonesClient", "CreateOrUpdate", "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "dns/ZonesClient", "CreateOrUpdate", "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client ZonesClient) CreateOrUpdatePreparer(resourceGroupName string, zoneName string, parameters ZoneCreateOrUpdateParameters, ifMatch string, ifNoneMatch string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "zoneName": url.QueryEscape(zoneName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnszones/{zoneName}"), + autorest.WithJSON(parameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client ZonesClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client ZonesClient) CreateOrUpdateResponder(resp *http.Response) (result Zone, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete removes a DNS zone from a resource group. +// +// resourceGroupName is the name of the resource group. zoneName is the name +// of the zone without a terminating dot. ifMatch is defines the If-Match +// condition. The delete operation will be performed only if the ETag of the +// zone on the server matches this value. +func (client ZonesClient) Delete(resourceGroupName string, zoneName string, ifMatch string) (result autorest.Response, ae error) { + req, err := client.DeletePreparer(resourceGroupName, zoneName, ifMatch) + if err != nil { + return result, autorest.NewErrorWithError(err, "dns/ZonesClient", "Delete", "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "dns/ZonesClient", "Delete", "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "dns/ZonesClient", "Delete", "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ZonesClient) DeletePreparer(resourceGroupName string, zoneName string, ifMatch string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "zoneName": url.QueryEscape(zoneName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnszones/{zoneName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client ZonesClient) DeleteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client ZonesClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get gets a DNS zone. +// +// resourceGroupName is the name of the resource group. zoneName is the name +// of the zone without a terminating dot. +func (client ZonesClient) Get(resourceGroupName string, zoneName string) (result Zone, ae error) { + req, err := client.GetPreparer(resourceGroupName, zoneName) + if err != nil { + return result, autorest.NewErrorWithError(err, "dns/ZonesClient", "Get", "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "dns/ZonesClient", "Get", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "dns/ZonesClient", "Get", "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ZonesClient) GetPreparer(resourceGroupName string, zoneName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "zoneName": url.QueryEscape(zoneName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnszones/{zoneName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client ZonesClient) GetSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client ZonesClient) GetResponder(resp *http.Response) (result Zone, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListZonesInResourceGroup lists the DNS zones within a resource group. +// +// resourceGroupName is the name of the resource group. top is query +// parameters. If null is passed returns the default number of zones. filter +// is the filter to apply on the operation. +func (client ZonesClient) ListZonesInResourceGroup(resourceGroupName string, top string, filter string) (result ZoneListResult, ae error) { + req, err := client.ListZonesInResourceGroupPreparer(resourceGroupName, top, filter) + if err != nil { + return result, autorest.NewErrorWithError(err, "dns/ZonesClient", "ListZonesInResourceGroup", "Failure preparing request") + } + + resp, err := client.ListZonesInResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "dns/ZonesClient", "ListZonesInResourceGroup", "Failure sending request") + } + + result, err = client.ListZonesInResourceGroupResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "dns/ZonesClient", "ListZonesInResourceGroup", "Failure responding to request") + } + + return +} + +// ListZonesInResourceGroupPreparer prepares the ListZonesInResourceGroup request. +func (client ZonesClient) ListZonesInResourceGroupPreparer(resourceGroupName string, top string, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(top) > 0 { + queryParameters["$top"] = top + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/dnszones"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListZonesInResourceGroupSender sends the ListZonesInResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client ZonesClient) ListZonesInResourceGroupSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListZonesInResourceGroupResponder handles the response to the ListZonesInResourceGroup request. The method always +// closes the http.Response Body. +func (client ZonesClient) ListZonesInResourceGroupResponder(resp *http.Response) (result ZoneListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListZonesInSubscription lists the DNS zones within a resource group. +// +// top is query parameters. If null is passed returns the default number of +// zones. filter is the filter to apply on the operation. +func (client ZonesClient) ListZonesInSubscription(top string, filter string) (result ZoneListResult, ae error) { + req, err := client.ListZonesInSubscriptionPreparer(top, filter) + if err != nil { + return result, autorest.NewErrorWithError(err, "dns/ZonesClient", "ListZonesInSubscription", "Failure preparing request") + } + + resp, err := client.ListZonesInSubscriptionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "dns/ZonesClient", "ListZonesInSubscription", "Failure sending request") + } + + result, err = client.ListZonesInSubscriptionResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "dns/ZonesClient", "ListZonesInSubscription", "Failure responding to request") + } + + return +} + +// ListZonesInSubscriptionPreparer prepares the ListZonesInSubscription request. +func (client ZonesClient) ListZonesInSubscriptionPreparer(top string, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(top) > 0 { + queryParameters["$top"] = top + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Network/dnszones"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListZonesInSubscriptionSender sends the ListZonesInSubscription request. The method will close the +// http.Response Body if it receives an error. +func (client ZonesClient) ListZonesInSubscriptionSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListZonesInSubscriptionResponder handles the response to the ListZonesInSubscription request. The method always +// closes the http.Response Body. +func (client ZonesClient) ListZonesInSubscriptionResponder(resp *http.Response) (result ZoneListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/features/client.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/features/client.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/features/client.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/features/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -57,7 +57,7 @@ // // resourceProviderNamespace is namespace of the resource provider. // featureName is previewed feature name in the resource provider. -func (client ManagementClient) Get(resourceProviderNamespace string, featureName string) (result Result, ae error) { +func (client ManagementClient) Get(resourceProviderNamespace string, featureName string) (result FeatureResult, ae error) { req, err := client.GetPreparer(resourceProviderNamespace, featureName) if err != nil { return result, autorest.NewErrorWithError(err, "features/ManagementClient", "Get", "Failure preparing request") @@ -106,7 +106,7 @@ // GetResponder handles the response to the Get request. The method always // closes the http.Response Body. -func (client ManagementClient) GetResponder(resp *http.Response) (result Result, err error) { +func (client ManagementClient) GetResponder(resp *http.Response) (result FeatureResult, err error) { err = autorest.Respond( resp, client.ByInspecting(), @@ -120,7 +120,7 @@ // List gets a list of previewed features of a resource provider. // // resourceProviderNamespace is the namespace of the resource provider. -func (client ManagementClient) List(resourceProviderNamespace string) (result OperationsListResult, ae error) { +func (client ManagementClient) List(resourceProviderNamespace string) (result FeatureOperationsListResult, ae error) { req, err := client.ListPreparer(resourceProviderNamespace) if err != nil { return result, autorest.NewErrorWithError(err, "features/ManagementClient", "List", "Failure preparing request") @@ -168,7 +168,7 @@ // ListResponder handles the response to the List request. The method always // closes the http.Response Body. -func (client ManagementClient) ListResponder(resp *http.Response) (result OperationsListResult, err error) { +func (client ManagementClient) ListResponder(resp *http.Response) (result FeatureOperationsListResult, err error) { err = autorest.Respond( resp, client.ByInspecting(), @@ -180,8 +180,8 @@ } // ListNextResults retrieves the next set of results, if any. -func (client ManagementClient) ListNextResults(lastResults OperationsListResult) (result OperationsListResult, ae error) { - req, err := lastResults.OperationsListResultPreparer() +func (client ManagementClient) ListNextResults(lastResults FeatureOperationsListResult) (result FeatureOperationsListResult, ae error) { + req, err := lastResults.FeatureOperationsListResultPreparer() if err != nil { return result, autorest.NewErrorWithError(err, "features/ManagementClient", "List", "Failure preparing next results request request") } @@ -205,7 +205,7 @@ // ListAll gets a list of previewed features for all the providers in the // current subscription. -func (client ManagementClient) ListAll() (result OperationsListResult, ae error) { +func (client ManagementClient) ListAll() (result FeatureOperationsListResult, ae error) { req, err := client.ListAllPreparer() if err != nil { return result, autorest.NewErrorWithError(err, "features/ManagementClient", "ListAll", "Failure preparing request") @@ -252,7 +252,7 @@ // ListAllResponder handles the response to the ListAll request. The method always // closes the http.Response Body. -func (client ManagementClient) ListAllResponder(resp *http.Response) (result OperationsListResult, err error) { +func (client ManagementClient) ListAllResponder(resp *http.Response) (result FeatureOperationsListResult, err error) { err = autorest.Respond( resp, client.ByInspecting(), @@ -264,8 +264,8 @@ } // ListAllNextResults retrieves the next set of results, if any. -func (client ManagementClient) ListAllNextResults(lastResults OperationsListResult) (result OperationsListResult, ae error) { - req, err := lastResults.OperationsListResultPreparer() +func (client ManagementClient) ListAllNextResults(lastResults FeatureOperationsListResult) (result FeatureOperationsListResult, ae error) { + req, err := lastResults.FeatureOperationsListResultPreparer() if err != nil { return result, autorest.NewErrorWithError(err, "features/ManagementClient", "ListAll", "Failure preparing next results request request") } @@ -291,7 +291,7 @@ // // resourceProviderNamespace is namespace of the resource provider. // featureName is previewed feature name in the resource provider. -func (client ManagementClient) Register(resourceProviderNamespace string, featureName string) (result Result, ae error) { +func (client ManagementClient) Register(resourceProviderNamespace string, featureName string) (result FeatureResult, ae error) { req, err := client.RegisterPreparer(resourceProviderNamespace, featureName) if err != nil { return result, autorest.NewErrorWithError(err, "features/ManagementClient", "Register", "Failure preparing request") @@ -340,7 +340,7 @@ // RegisterResponder handles the response to the Register request. The method always // closes the http.Response Body. -func (client ManagementClient) RegisterResponder(resp *http.Response) (result Result, err error) { +func (client ManagementClient) RegisterResponder(resp *http.Response) (result FeatureResult, err error) { err = autorest.Respond( resp, client.ByInspecting(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/features/features.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/features/features.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/features/features.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/features/features.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,338 @@ +package features + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// Client is the client for the Features methods of the Features 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)} +} + +// Get get all features under the subscription. +// +// resourceProviderNamespace is namespace of the resource provider. +// featureName is previewed feature name in the resource provider. +func (client Client) Get(resourceProviderNamespace string, featureName string) (result FeatureResult, ae error) { + req, err := client.GetPreparer(resourceProviderNamespace, featureName) + if err != nil { + return result, autorest.NewErrorWithError(err, "features/Client", "Get", "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "features/Client", "Get", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "features/Client", "Get", "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client Client) GetPreparer(resourceProviderNamespace string, featureName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "featureName": url.QueryEscape(featureName), + "resourceProviderNamespace": url.QueryEscape(resourceProviderNamespace), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Features/providers/{resourceProviderNamespace}/features/{featureName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client Client) GetResponder(resp *http.Response) (result FeatureResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List gets a list of previewed features of a resource provider. +// +// resourceProviderNamespace is the namespace of the resource provider. +func (client Client) List(resourceProviderNamespace string) (result FeatureOperationsListResult, ae error) { + req, err := client.ListPreparer(resourceProviderNamespace) + if err != nil { + return result, autorest.NewErrorWithError(err, "features/Client", "List", "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "features/Client", "List", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "features/Client", "List", "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client Client) ListPreparer(resourceProviderNamespace string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceProviderNamespace": url.QueryEscape(resourceProviderNamespace), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Features/providers/{resourceProviderNamespace}/features"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client Client) ListResponder(resp *http.Response) (result FeatureOperationsListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.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 FeatureOperationsListResult) (result FeatureOperationsListResult, ae error) { + req, err := lastResults.FeatureOperationsListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "features/Client", "List", "Failure preparing next results request request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "features/Client", "List", "Failure sending next results request request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "features/Client", "List", "Failure responding to next results request request") + } + + return +} + +// ListAll gets a list of previewed features for all the providers in the +// current subscription. +func (client Client) ListAll() (result FeatureOperationsListResult, ae error) { + req, err := client.ListAllPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "features/Client", "ListAll", "Failure preparing request") + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "features/Client", "ListAll", "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "features/Client", "ListAll", "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client Client) ListAllPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Features/features"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListAllSender sends the ListAll request. The method will close the +// http.Response Body if it receives an error. +func (client Client) ListAllSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListAllResponder handles the response to the ListAll request. The method always +// closes the http.Response Body. +func (client Client) ListAllResponder(resp *http.Response) (result FeatureOperationsListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.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 Client) ListAllNextResults(lastResults FeatureOperationsListResult) (result FeatureOperationsListResult, ae error) { + req, err := lastResults.FeatureOperationsListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "features/Client", "ListAll", "Failure preparing next results request request") + } + if req == nil { + return + } + + resp, err := client.ListAllSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "features/Client", "ListAll", "Failure sending next results request request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "features/Client", "ListAll", "Failure responding to next results request request") + } + + return +} + +// Register registers for a previewed feature of a resource provider. +// +// resourceProviderNamespace is namespace of the resource provider. +// featureName is previewed feature name in the resource provider. +func (client Client) Register(resourceProviderNamespace string, featureName string) (result FeatureResult, ae error) { + req, err := client.RegisterPreparer(resourceProviderNamespace, featureName) + if err != nil { + return result, autorest.NewErrorWithError(err, "features/Client", "Register", "Failure preparing request") + } + + resp, err := client.RegisterSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "features/Client", "Register", "Failure sending request") + } + + result, err = client.RegisterResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "features/Client", "Register", "Failure responding to request") + } + + return +} + +// RegisterPreparer prepares the Register request. +func (client Client) RegisterPreparer(resourceProviderNamespace string, featureName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "featureName": url.QueryEscape(featureName), + "resourceProviderNamespace": url.QueryEscape(resourceProviderNamespace), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Features/providers/{resourceProviderNamespace}/features/{featureName}/register"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// RegisterSender sends the Register request. The method will close the +// http.Response Body if it receives an error. +func (client Client) RegisterSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// RegisterResponder handles the response to the Register request. The method always +// closes the http.Response Body. +func (client Client) RegisterResponder(resp *http.Response) (result FeatureResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/features/models.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/features/models.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/features/models.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/features/models.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -29,23 +29,16 @@ ProvisioningState *string `json:"provisioningState,omitempty"` } -// GenericResourceFilter is resource filter. -type GenericResourceFilter struct { - ResourceType *string `json:"resourceType,omitempty"` - Tagname *string `json:"tagname,omitempty"` - Tagvalue *string `json:"tagvalue,omitempty"` -} - -// OperationsListResult is list of previewed features. -type OperationsListResult struct { +// FeatureOperationsListResult is list of previewed features. +type FeatureOperationsListResult struct { autorest.Response `json:"-"` - Value *[]Result `json:"value,omitempty"` - NextLink *string `json:"nextLink,omitempty"` + Value *[]FeatureResult `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` } -// OperationsListResultPreparer prepares a request to retrieve the next set of results. It returns +// FeatureOperationsListResultPreparer prepares a request to retrieve the next set of results. It returns // nil if no more results exist. -func (client OperationsListResult) OperationsListResultPreparer() (*http.Request, error) { +func (client FeatureOperationsListResult) FeatureOperationsListResultPreparer() (*http.Request, error) { if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { return nil, nil } @@ -55,11 +48,27 @@ autorest.WithBaseURL(to.String(client.NextLink))) } -// Properties is previewed feature information. -type Properties struct { +// FeatureProperties is previewed feature information. +type FeatureProperties struct { State *string `json:"state,omitempty"` } +// FeatureResult is previewed feature information. +type FeatureResult struct { + autorest.Response `json:"-"` + Name *string `json:"name,omitempty"` + Properties *FeatureProperties `json:"properties,omitempty"` + ID *string `json:"id,omitempty"` + Type *string `json:"type,omitempty"` +} + +// GenericResourceFilter is resource filter. +type GenericResourceFilter struct { + ResourceType *string `json:"resourceType,omitempty"` + Tagname *string `json:"tagname,omitempty"` + Tagvalue *string `json:"tagvalue,omitempty"` +} + // Resource is type Resource struct { ID *string `json:"id,omitempty"` @@ -75,15 +84,6 @@ TagValue *string `json:"tagValue,omitempty"` } -// Result is previewed feature information. -type Result struct { - autorest.Response `json:"-"` - Name *string `json:"name,omitempty"` - Properties *Properties `json:"properties,omitempty"` - ID *string `json:"id,omitempty"` - Type *string `json:"type,omitempty"` -} - // SubResource is type SubResource struct { ID *string `json:"id,omitempty"` diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/features/version.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/features/version.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/features/version.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/features/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,8 @@ const ( major = "0" - minor = "1" - patch = "1" + minor = "3" + patch = "0" // Always begin a "tag" with a dash (as per http://semver.org) tag = "-beta" semVerFormat = "%s.%s.%s%s" diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/client.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/client.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/client.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/models.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/models.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/models.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/models.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -29,13 +29,12 @@ type KeyType string const ( - // KeyTypeNotSpecified specifies the key type not specified state for key - // type. - KeyTypeNotSpecified KeyType = "NotSpecified" - // KeyTypePrimary specifies the key type primary state for key type. - KeyTypePrimary KeyType = "Primary" - // KeyTypeSecondary specifies the key type secondary state for key type. - KeyTypeSecondary KeyType = "Secondary" + // NotSpecified specifies the not specified state for key type. + NotSpecified KeyType = "NotSpecified" + // Primary specifies the primary state for key type. + Primary KeyType = "Primary" + // Secondary specifies the secondary state for key type. + Secondary KeyType = "Secondary" ) // ParameterType enumerates the values for parameter type. @@ -110,6 +109,22 @@ SkuNameStandard SkuName = "Standard" ) +// WorkflowProvisioningState enumerates the values for workflow provisioning +// state. +type WorkflowProvisioningState string + +const ( + // WorkflowProvisioningStateMoving specifies the workflow provisioning + // state moving state for workflow provisioning state. + WorkflowProvisioningStateMoving WorkflowProvisioningState = "Moving" + // WorkflowProvisioningStateNotSpecified specifies the workflow + // provisioning state not specified state for workflow provisioning state. + WorkflowProvisioningStateNotSpecified WorkflowProvisioningState = "NotSpecified" + // WorkflowProvisioningStateSucceeded specifies the workflow provisioning + // state succeeded state for workflow provisioning state. + WorkflowProvisioningStateSucceeded WorkflowProvisioningState = "Succeeded" +) + // WorkflowState enumerates the values for workflow state. type WorkflowState string @@ -164,6 +179,29 @@ WorkflowStatusWaiting WorkflowStatus = "Waiting" ) +// WorkflowTriggerProvisioningState enumerates the values for workflow trigger +// provisioning state. +type WorkflowTriggerProvisioningState string + +const ( + // WorkflowTriggerProvisioningStateCreating specifies the workflow trigger + // provisioning state creating state for workflow trigger provisioning + // state. + WorkflowTriggerProvisioningStateCreating WorkflowTriggerProvisioningState = "Creating" + // WorkflowTriggerProvisioningStateNotSpecified specifies the workflow + // trigger provisioning state not specified state for workflow trigger + // provisioning state. + WorkflowTriggerProvisioningStateNotSpecified WorkflowTriggerProvisioningState = "NotSpecified" + // WorkflowTriggerProvisioningStateSucceeded specifies the workflow + // trigger provisioning state succeeded state for workflow trigger + // provisioning state. + WorkflowTriggerProvisioningStateSucceeded WorkflowTriggerProvisioningState = "Succeeded" + // WorkflowTriggerProvisioningStateUpdating specifies the workflow trigger + // provisioning state updating state for workflow trigger provisioning + // state. + WorkflowTriggerProvisioningStateUpdating WorkflowTriggerProvisioningState = "Updating" +) + // ContentHash is type ContentHash struct { Algorithm *string `json:"algorithm,omitempty"` @@ -172,11 +210,11 @@ // ContentLink is type ContentLink struct { - URI *string `json:"uri,omitempty"` - ContentVersion *string `json:"contentVersion,omitempty"` - ContentSize *int32 `json:"contentSize,omitempty"` - ContentHash *ContentHash `json:"contentHash,omitempty"` - Metadata *map[string]*string `json:"metadata,omitempty"` + URI *string `json:"uri,omitempty"` + ContentVersion *string `json:"contentVersion,omitempty"` + ContentSize *int32 `json:"contentSize,omitempty"` + ContentHash *ContentHash `json:"contentHash,omitempty"` + Metadata *map[string]interface{} `json:"metadata,omitempty"` } // RegenerateSecretKeyParameters is @@ -202,8 +240,8 @@ // RunWorkflowParameters is type RunWorkflowParameters struct { - Name *string `json:"name,omitempty"` - Outputs *map[string]*string `json:"outputs,omitempty"` + Name *string `json:"name,omitempty"` + Outputs *map[string]interface{} `json:"outputs,omitempty"` } // Sku is @@ -288,31 +326,32 @@ // WorkflowOutputParameter is type WorkflowOutputParameter struct { - Type ParameterType `json:"type,omitempty"` - Value *map[string]*string `json:"value,omitempty"` - Metadata *map[string]*string `json:"metadata,omitempty"` - Error *map[string]*string `json:"error,omitempty"` + Type ParameterType `json:"type,omitempty"` + Value *map[string]interface{} `json:"value,omitempty"` + Metadata *map[string]interface{} `json:"metadata,omitempty"` + Error *map[string]interface{} `json:"error,omitempty"` } // WorkflowParameter is type WorkflowParameter struct { - Type ParameterType `json:"type,omitempty"` - Value *map[string]*string `json:"value,omitempty"` - Metadata *map[string]*string `json:"metadata,omitempty"` + Type ParameterType `json:"type,omitempty"` + Value *map[string]interface{} `json:"value,omitempty"` + Metadata *map[string]interface{} `json:"metadata,omitempty"` } // WorkflowProperties is type WorkflowProperties struct { - CreatedTime *date.Time `json:"createdTime,omitempty"` - ChangedTime *date.Time `json:"changedTime,omitempty"` - State WorkflowState `json:"state,omitempty"` - Version *string `json:"version,omitempty"` - AccessEndpoint *string `json:"accessEndpoint,omitempty"` - Sku *Sku `json:"sku,omitempty"` - DefinitionLink *ContentLink `json:"definitionLink,omitempty"` - Definition *map[string]*string `json:"definition,omitempty"` - ParametersLink *ContentLink `json:"parametersLink,omitempty"` - Parameters *map[string]*WorkflowParameter `json:"parameters,omitempty"` + ProvisioningState WorkflowProvisioningState `json:"provisioningState,omitempty"` + CreatedTime *date.Time `json:"createdTime,omitempty"` + ChangedTime *date.Time `json:"changedTime,omitempty"` + State WorkflowState `json:"state,omitempty"` + Version *string `json:"version,omitempty"` + AccessEndpoint *string `json:"accessEndpoint,omitempty"` + Sku *Sku `json:"sku,omitempty"` + DefinitionLink *ContentLink `json:"definitionLink,omitempty"` + Definition *map[string]interface{} `json:"definition,omitempty"` + ParametersLink *ContentLink `json:"parametersLink,omitempty"` + Parameters *map[string]*WorkflowParameter `json:"parameters,omitempty"` } // WorkflowRun is @@ -359,14 +398,14 @@ // WorkflowRunActionProperties is type WorkflowRunActionProperties struct { - StartTime *date.Time `json:"startTime,omitempty"` - EndTime *date.Time `json:"endTime,omitempty"` - Status WorkflowStatus `json:"status,omitempty"` - Code *string `json:"code,omitempty"` - Error *map[string]*string `json:"error,omitempty"` - TrackingID *string `json:"trackingId,omitempty"` - InputsLink *ContentLink `json:"inputsLink,omitempty"` - OutputsLink *ContentLink `json:"outputsLink,omitempty"` + StartTime *date.Time `json:"startTime,omitempty"` + EndTime *date.Time `json:"endTime,omitempty"` + Status WorkflowStatus `json:"status,omitempty"` + Code *string `json:"code,omitempty"` + Error *map[string]interface{} `json:"error,omitempty"` + TrackingID *string `json:"trackingId,omitempty"` + InputsLink *ContentLink `json:"inputsLink,omitempty"` + OutputsLink *ContentLink `json:"outputsLink,omitempty"` } // WorkflowRunFilter is @@ -399,7 +438,7 @@ EndTime *date.Time `json:"endTime,omitempty"` Status WorkflowStatus `json:"status,omitempty"` Code *string `json:"code,omitempty"` - Error *map[string]*string `json:"error,omitempty"` + Error *map[string]interface{} `json:"error,omitempty"` CorrelationID *string `json:"correlationId,omitempty"` Workflow *ResourceReference `json:"workflow,omitempty"` Trigger *WorkflowRunTrigger `json:"trigger,omitempty"` @@ -408,17 +447,17 @@ // WorkflowRunTrigger is type WorkflowRunTrigger struct { - Name *string `json:"name,omitempty"` - Inputs *map[string]*string `json:"inputs,omitempty"` - InputsLink *ContentLink `json:"inputsLink,omitempty"` - Outputs *map[string]*string `json:"outputs,omitempty"` - OutputsLink *ContentLink `json:"outputsLink,omitempty"` - StartTime *date.Time `json:"startTime,omitempty"` - EndTime *date.Time `json:"endTime,omitempty"` - TrackingID *string `json:"trackingId,omitempty"` - Code *string `json:"code,omitempty"` - Status WorkflowStatus `json:"status,omitempty"` - Error *map[string]*string `json:"error,omitempty"` + Name *string `json:"name,omitempty"` + Inputs *map[string]interface{} `json:"inputs,omitempty"` + InputsLink *ContentLink `json:"inputsLink,omitempty"` + Outputs *map[string]interface{} `json:"outputs,omitempty"` + OutputsLink *ContentLink `json:"outputsLink,omitempty"` + StartTime *date.Time `json:"startTime,omitempty"` + EndTime *date.Time `json:"endTime,omitempty"` + TrackingID *string `json:"trackingId,omitempty"` + Code *string `json:"code,omitempty"` + Status WorkflowStatus `json:"status,omitempty"` + Error *map[string]interface{} `json:"error,omitempty"` } // WorkflowSecretKeys is @@ -472,16 +511,16 @@ // WorkflowTriggerHistoryProperties is type WorkflowTriggerHistoryProperties struct { - StartTime *date.Time `json:"startTime,omitempty"` - EndTime *date.Time `json:"endTime,omitempty"` - Status WorkflowStatus `json:"status,omitempty"` - Code *string `json:"code,omitempty"` - Error *map[string]*string `json:"error,omitempty"` - TrackingID *string `json:"trackingId,omitempty"` - InputsLink *ContentLink `json:"inputsLink,omitempty"` - OutputsLink *ContentLink `json:"outputsLink,omitempty"` - Fired *bool `json:"fired,omitempty"` - Run *ResourceReference `json:"run,omitempty"` + StartTime *date.Time `json:"startTime,omitempty"` + EndTime *date.Time `json:"endTime,omitempty"` + Status WorkflowStatus `json:"status,omitempty"` + Code *string `json:"code,omitempty"` + Error *map[string]interface{} `json:"error,omitempty"` + TrackingID *string `json:"trackingId,omitempty"` + InputsLink *ContentLink `json:"inputsLink,omitempty"` + OutputsLink *ContentLink `json:"outputsLink,omitempty"` + Fired *bool `json:"fired,omitempty"` + Run *ResourceReference `json:"run,omitempty"` } // WorkflowTriggerListResult is @@ -505,14 +544,15 @@ // WorkflowTriggerProperties is type WorkflowTriggerProperties struct { - CreatedTime *date.Time `json:"createdTime,omitempty"` - ChangedTime *date.Time `json:"changedTime,omitempty"` - State WorkflowState `json:"state,omitempty"` - Status WorkflowStatus `json:"status,omitempty"` - LastExecutionTime *date.Time `json:"lastExecutionTime,omitempty"` - NextExecutionTime *date.Time `json:"nextExecutionTime,omitempty"` - Recurrence *WorkflowTriggerRecurrence `json:"recurrence,omitempty"` - Workflow *ResourceReference `json:"workflow,omitempty"` + ProvisioningState WorkflowTriggerProvisioningState `json:"provisioningState,omitempty"` + CreatedTime *date.Time `json:"createdTime,omitempty"` + ChangedTime *date.Time `json:"changedTime,omitempty"` + State WorkflowState `json:"state,omitempty"` + Status WorkflowStatus `json:"status,omitempty"` + LastExecutionTime *date.Time `json:"lastExecutionTime,omitempty"` + NextExecutionTime *date.Time `json:"nextExecutionTime,omitempty"` + Recurrence *WorkflowTriggerRecurrence `json:"recurrence,omitempty"` + Workflow *ResourceReference `json:"workflow,omitempty"` } // WorkflowTriggerRecurrence is @@ -543,7 +583,7 @@ AccessEndpoint *string `json:"accessEndpoint,omitempty"` Sku *Sku `json:"sku,omitempty"` DefinitionLink *ContentLink `json:"definitionLink,omitempty"` - Definition *map[string]*string `json:"definition,omitempty"` + Definition *map[string]interface{} `json:"definition,omitempty"` ParametersLink *ContentLink `json:"parametersLink,omitempty"` Parameters *map[string]*WorkflowParameter `json:"parameters,omitempty"` } diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/version.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/version.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/version.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,8 @@ const ( major = "0" - minor = "1" - patch = "1" + minor = "3" + patch = "0" // Always begin a "tag" with a dash (as per http://semver.org) tag = "-beta" semVerFormat = "%s.%s.%s%s" diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowaccesskeys.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowaccesskeys.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowaccesskeys.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowaccesskeys.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -242,7 +242,7 @@ // // resourceGroupName is the resource group name. workflowName is the workflow // name. top is the number of items to be included in the result. -func (client WorkflowAccessKeysClient) List(resourceGroupName string, workflowName string, top int) (result WorkflowAccessKeyListResult, ae error) { +func (client WorkflowAccessKeysClient) List(resourceGroupName string, workflowName string, top *int) (result WorkflowAccessKeyListResult, ae error) { req, err := client.ListPreparer(resourceGroupName, workflowName, top) if err != nil { return result, autorest.NewErrorWithError(err, "logic/WorkflowAccessKeysClient", "List", "Failure preparing request") @@ -263,7 +263,7 @@ } // ListPreparer prepares the List request. -func (client WorkflowAccessKeysClient) ListPreparer(resourceGroupName string, workflowName string, top int) (*http.Request, error) { +func (client WorkflowAccessKeysClient) ListPreparer(resourceGroupName string, workflowName string, top *int) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": url.QueryEscape(resourceGroupName), "subscriptionId": url.QueryEscape(client.SubscriptionID), @@ -271,9 +271,11 @@ } queryParameters := map[string]interface{}{ - "$top": top, "api-version": APIVersion, } + if top != nil { + queryParameters["$top"] = top + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowrunactions.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowrunactions.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowrunactions.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowrunactions.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -114,7 +114,7 @@ // resourceGroupName is the resource group name. workflowName is the workflow // name. runName is the workflow run name. top is the number of items to be // included in the result. filter is the filter to apply on the operation. -func (client WorkflowRunActionsClient) List(resourceGroupName string, workflowName string, runName string, top int, filter string) (result WorkflowRunActionListResult, ae error) { +func (client WorkflowRunActionsClient) List(resourceGroupName string, workflowName string, runName string, top *int, filter string) (result WorkflowRunActionListResult, ae error) { req, err := client.ListPreparer(resourceGroupName, workflowName, runName, top, filter) if err != nil { return result, autorest.NewErrorWithError(err, "logic/WorkflowRunActionsClient", "List", "Failure preparing request") @@ -135,7 +135,7 @@ } // ListPreparer prepares the List request. -func (client WorkflowRunActionsClient) ListPreparer(resourceGroupName string, workflowName string, runName string, top int, filter string) (*http.Request, error) { +func (client WorkflowRunActionsClient) ListPreparer(resourceGroupName string, workflowName string, runName string, top *int, filter string) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": url.QueryEscape(resourceGroupName), "runName": url.QueryEscape(runName), @@ -144,10 +144,14 @@ } queryParameters := map[string]interface{}{ - "$filter": filter, - "$top": top, "api-version": APIVersion, } + if top != nil { + queryParameters["$top"] = top + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowruns.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowruns.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowruns.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowruns.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -175,7 +175,7 @@ // resourceGroupName is the resource group name. workflowName is the workflow // name. top is the number of items to be included in the result. filter is // the filter to apply on the operation. -func (client WorkflowRunsClient) List(resourceGroupName string, workflowName string, top int, filter string) (result WorkflowRunListResult, ae error) { +func (client WorkflowRunsClient) List(resourceGroupName string, workflowName string, top *int, filter string) (result WorkflowRunListResult, ae error) { req, err := client.ListPreparer(resourceGroupName, workflowName, top, filter) if err != nil { return result, autorest.NewErrorWithError(err, "logic/WorkflowRunsClient", "List", "Failure preparing request") @@ -196,7 +196,7 @@ } // ListPreparer prepares the List request. -func (client WorkflowRunsClient) ListPreparer(resourceGroupName string, workflowName string, top int, filter string) (*http.Request, error) { +func (client WorkflowRunsClient) ListPreparer(resourceGroupName string, workflowName string, top *int, filter string) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": url.QueryEscape(resourceGroupName), "subscriptionId": url.QueryEscape(client.SubscriptionID), @@ -204,10 +204,14 @@ } queryParameters := map[string]interface{}{ - "$filter": filter, - "$top": top, "api-version": APIVersion, } + if top != nil { + queryParameters["$top"] = top + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflows.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflows.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflows.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflows.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -363,7 +363,7 @@ // // resourceGroupName is the resource group name. top is the number of items to // be included in the result. filter is the filter to apply on the operation. -func (client WorkflowsClient) ListByResourceGroup(resourceGroupName string, top int, filter string) (result WorkflowListResult, ae error) { +func (client WorkflowsClient) ListByResourceGroup(resourceGroupName string, top *int, filter string) (result WorkflowListResult, ae error) { req, err := client.ListByResourceGroupPreparer(resourceGroupName, top, filter) if err != nil { return result, autorest.NewErrorWithError(err, "logic/WorkflowsClient", "ListByResourceGroup", "Failure preparing request") @@ -384,17 +384,21 @@ } // ListByResourceGroupPreparer prepares the ListByResourceGroup request. -func (client WorkflowsClient) ListByResourceGroupPreparer(resourceGroupName string, top int, filter string) (*http.Request, error) { +func (client WorkflowsClient) ListByResourceGroupPreparer(resourceGroupName string, top *int, filter string) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": url.QueryEscape(resourceGroupName), "subscriptionId": url.QueryEscape(client.SubscriptionID), } queryParameters := map[string]interface{}{ - "$filter": filter, - "$top": top, "api-version": APIVersion, } + if top != nil { + queryParameters["$top"] = top + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), @@ -452,7 +456,7 @@ // // top is the number of items to be included in the result. filter is the // filter to apply on the operation. -func (client WorkflowsClient) ListBySubscription(top int, filter string) (result WorkflowListResult, ae error) { +func (client WorkflowsClient) ListBySubscription(top *int, filter string) (result WorkflowListResult, ae error) { req, err := client.ListBySubscriptionPreparer(top, filter) if err != nil { return result, autorest.NewErrorWithError(err, "logic/WorkflowsClient", "ListBySubscription", "Failure preparing request") @@ -473,16 +477,20 @@ } // ListBySubscriptionPreparer prepares the ListBySubscription request. -func (client WorkflowsClient) ListBySubscriptionPreparer(top int, filter string) (*http.Request, error) { +func (client WorkflowsClient) ListBySubscriptionPreparer(top *int, filter string) (*http.Request, error) { pathParameters := map[string]interface{}{ "subscriptionId": url.QueryEscape(client.SubscriptionID), } queryParameters := map[string]interface{}{ - "$filter": filter, - "$top": top, "api-version": APIVersion, } + if top != nil { + queryParameters["$top"] = top + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), @@ -585,7 +593,7 @@ // RunSender sends the Run request. The method will close the // http.Response Body if it receives an error. func (client WorkflowsClient) RunSender(req *http.Request) (*http.Response, error) { - return client.Send(req, http.StatusAccepted) + return client.Send(req, http.StatusOK, http.StatusAccepted) } // RunResponder handles the response to the Run request. The method always @@ -594,7 +602,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusAccepted), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), autorest.ByUnmarshallingJSON(&result), autorest.ByClosing()) result.Response = autorest.Response{Response: resp} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowtriggerhistories.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowtriggerhistories.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowtriggerhistories.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowtriggerhistories.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -114,7 +114,7 @@ // resourceGroupName is the resource group name. workflowName is the workflow // name. triggerName is the workflow trigger name. top is the number of items // to be included in the result. -func (client WorkflowTriggerHistoriesClient) List(resourceGroupName string, workflowName string, triggerName string, top int) (result WorkflowTriggerHistoryListResult, ae error) { +func (client WorkflowTriggerHistoriesClient) List(resourceGroupName string, workflowName string, triggerName string, top *int) (result WorkflowTriggerHistoryListResult, ae error) { req, err := client.ListPreparer(resourceGroupName, workflowName, triggerName, top) if err != nil { return result, autorest.NewErrorWithError(err, "logic/WorkflowTriggerHistoriesClient", "List", "Failure preparing request") @@ -135,7 +135,7 @@ } // ListPreparer prepares the List request. -func (client WorkflowTriggerHistoriesClient) ListPreparer(resourceGroupName string, workflowName string, triggerName string, top int) (*http.Request, error) { +func (client WorkflowTriggerHistoriesClient) ListPreparer(resourceGroupName string, workflowName string, triggerName string, top *int) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": url.QueryEscape(resourceGroupName), "subscriptionId": url.QueryEscape(client.SubscriptionID), @@ -144,9 +144,11 @@ } queryParameters := map[string]interface{}{ - "$top": top, "api-version": APIVersion, } + if top != nil { + queryParameters["$top"] = top + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowtriggers.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowtriggers.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowtriggers.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowtriggers.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -112,7 +112,7 @@ // resourceGroupName is the resource group name. workflowName is the workflow // name. top is the number of items to be included in the result. filter is // the filter to apply on the operation. -func (client WorkflowTriggersClient) List(resourceGroupName string, workflowName string, top int, filter string) (result WorkflowTriggerListResult, ae error) { +func (client WorkflowTriggersClient) List(resourceGroupName string, workflowName string, top *int, filter string) (result WorkflowTriggerListResult, ae error) { req, err := client.ListPreparer(resourceGroupName, workflowName, top, filter) if err != nil { return result, autorest.NewErrorWithError(err, "logic/WorkflowTriggersClient", "List", "Failure preparing request") @@ -133,7 +133,7 @@ } // ListPreparer prepares the List request. -func (client WorkflowTriggersClient) ListPreparer(resourceGroupName string, workflowName string, top int, filter string) (*http.Request, error) { +func (client WorkflowTriggersClient) ListPreparer(resourceGroupName string, workflowName string, top *int, filter string) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": url.QueryEscape(resourceGroupName), "subscriptionId": url.QueryEscape(client.SubscriptionID), @@ -141,10 +141,14 @@ } queryParameters := map[string]interface{}{ - "$filter": filter, - "$top": top, "api-version": APIVersion, } + if top != nil { + queryParameters["$top"] = top + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowversions.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowversions.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowversions.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/logic/workflowversions.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/applicationgateways.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/applicationgateways.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/applicationgateways.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/applicationgateways.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,11 @@ "net/url" ) -// ApplicationGatewaysClient is the client for the ApplicationGateways methods -// of the Network service. +// ApplicationGatewaysClient is the the Windows Azure Network management API +// provides a RESTful set of web services that interact with Windows Azure +// Networks service to manage your network resrources. The API has entities +// that capture the relationship between an end user and the Windows Azure +// Networks service. type ApplicationGatewaysClient struct { ManagementClient } @@ -458,7 +461,7 @@ // 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 client.Send(req, http.StatusAccepted) + return client.Send(req, http.StatusOK, http.StatusAccepted) } // StartResponder handles the response to the Start request. The method always @@ -467,7 +470,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusAccepted), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), autorest.ByClosing()) result.Response = resp return diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/client.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/client.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/client.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -32,7 +32,11 @@ DefaultBaseURI = "https://management.azure.com" ) -// ManagementClient is the base client for Network. +// ManagementClient is the the Windows Azure Network management API provides a +// RESTful set of web services that interact with Windows Azure Networks +// service to manage your network resrources. The API has entities that +// capture the relationship between an end user and the Windows Azure +// Networks service. type ManagementClient struct { autorest.Client BaseURI string @@ -87,8 +91,10 @@ } queryParameters := map[string]interface{}{ - "api-version": APIVersion, - "domainNameLabel": domainNameLabel, + "api-version": APIVersion, + } + if len(domainNameLabel) > 0 { + queryParameters["domainNameLabel"] = domainNameLabel } return autorest.Prepare(&http.Request{}, diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuitauthorizations.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuitauthorizations.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuitauthorizations.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuitauthorizations.go 2016-05-17 20:01:14.000000000 +0000 @@ -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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// ExpressRouteCircuitAuthorizationsClient is the the Windows Azure Network +// management API provides a RESTful set of web services that interact with +// Windows Azure Networks service to manage your network resrources. The API +// has entities that capture the relationship between an end user and the +// Windows 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 thespecified ExpressRouteCircuits +// +// 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) (result ExpressRouteCircuitAuthorization, ae error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, circuitName, authorizationName, authorizationParameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitAuthorizationsClient", "CreateOrUpdate", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitAuthorizationsClient", "CreateOrUpdate", "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitAuthorizationsClient", "CreateOrUpdate", "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client ExpressRouteCircuitAuthorizationsClient) CreateOrUpdatePreparer(resourceGroupName string, circuitName string, authorizationName string, authorizationParameters ExpressRouteCircuitAuthorization) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "authorizationName": url.QueryEscape(authorizationName), + "circuitName": url.QueryEscape(circuitName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/authorizations/{authorizationName}"), + autorest.WithJSON(authorizationParameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusCreated, http.StatusOK) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitAuthorizationsClient) CreateOrUpdateResponder(resp *http.Response) (result ExpressRouteCircuitAuthorization, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete the delete authorization operation deletes 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) Delete(resourceGroupName string, circuitName string, authorizationName string) (result autorest.Response, ae error) { + req, err := client.DeletePreparer(resourceGroupName, circuitName, authorizationName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitAuthorizationsClient", "Delete", "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitAuthorizationsClient", "Delete", "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitAuthorizationsClient", "Delete", "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ExpressRouteCircuitAuthorizationsClient) DeletePreparer(resourceGroupName string, circuitName string, authorizationName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "authorizationName": url.QueryEscape(authorizationName), + "circuitName": url.QueryEscape(circuitName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/authorizations/{authorizationName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusNoContent, http.StatusAccepted, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), + 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, ae error) { + req, err := client.GetPreparer(resourceGroupName, circuitName, authorizationName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitAuthorizationsClient", "Get", "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", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitAuthorizationsClient", "Get", "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": url.QueryEscape(authorizationName), + "circuitName": url.QueryEscape(circuitName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/authorizations/{authorizationName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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 curcuit. +func (client ExpressRouteCircuitAuthorizationsClient) List(resourceGroupName string, circuitName string) (result AuthorizationListResult, ae error) { + req, err := client.ListPreparer(resourceGroupName, circuitName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitAuthorizationsClient", "List", "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", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitAuthorizationsClient", "List", "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": url.QueryEscape(circuitName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/authorizations"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := lastResults.AuthorizationListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitAuthorizationsClient", "List", "Failure preparing next results request 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", "Failure sending next results request request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitAuthorizationsClient", "List", "Failure responding to next results request request") + } + + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuitpeerings.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuitpeerings.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuitpeerings.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuitpeerings.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,335 @@ +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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// ExpressRouteCircuitPeeringsClient is the the Windows Azure Network +// management API provides a RESTful set of web services that interact with +// Windows Azure Networks service to manage your network resrources. The API +// has entities that capture the relationship between an end user and the +// Windows 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 Pering operation creates/updates an peering in the +// specified ExpressRouteCircuits +// +// 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) (result ExpressRouteCircuitPeering, ae error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, circuitName, peeringName, peeringParameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitPeeringsClient", "CreateOrUpdate", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitPeeringsClient", "CreateOrUpdate", "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitPeeringsClient", "CreateOrUpdate", "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client ExpressRouteCircuitPeeringsClient) CreateOrUpdatePreparer(resourceGroupName string, circuitName string, peeringName string, peeringParameters ExpressRouteCircuitPeering) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": url.QueryEscape(circuitName), + "peeringName": url.QueryEscape(peeringName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/peerings/{peeringName}"), + autorest.WithJSON(peeringParameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusCreated, http.StatusOK) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitPeeringsClient) CreateOrUpdateResponder(resp *http.Response) (result ExpressRouteCircuitPeering, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete the delete peering operation deletes the specified peering 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) Delete(resourceGroupName string, circuitName string, peeringName string) (result autorest.Response, ae error) { + req, err := client.DeletePreparer(resourceGroupName, circuitName, peeringName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitPeeringsClient", "Delete", "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitPeeringsClient", "Delete", "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitPeeringsClient", "Delete", "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ExpressRouteCircuitPeeringsClient) DeletePreparer(resourceGroupName string, circuitName string, peeringName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": url.QueryEscape(circuitName), + "peeringName": url.QueryEscape(peeringName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/peerings/{peeringName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusNoContent, http.StatusAccepted, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), + 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, ae error) { + req, err := client.GetPreparer(resourceGroupName, circuitName, peeringName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitPeeringsClient", "Get", "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", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitPeeringsClient", "Get", "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": url.QueryEscape(circuitName), + "peeringName": url.QueryEscape(peeringName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/peerings/{peeringName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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 curcuit. +func (client ExpressRouteCircuitPeeringsClient) List(resourceGroupName string, circuitName string) (result ExpressRouteCircuitPeeringListResult, ae error) { + req, err := client.ListPreparer(resourceGroupName, circuitName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitPeeringsClient", "List", "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", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitPeeringsClient", "List", "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": url.QueryEscape(circuitName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/peerings"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := lastResults.ExpressRouteCircuitPeeringListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitPeeringsClient", "List", "Failure preparing next results request 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", "Failure sending next results request request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitPeeringsClient", "List", "Failure responding to next results request request") + } + + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuits.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuits.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuits.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/expressroutecircuits.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,682 @@ +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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// ExpressRouteCircuitsClient is the the Windows Azure Network management API +// provides a RESTful set of web services that interact with Windows Azure +// Networks service to manage your network resrources. The API has entities +// that capture the relationship between an end user and the Windows 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 +// +// 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) (result ExpressRouteCircuit, ae error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, circuitName, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "CreateOrUpdate", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "CreateOrUpdate", "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "CreateOrUpdate", "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client ExpressRouteCircuitsClient) CreateOrUpdatePreparer(resourceGroupName string, circuitName string, parameters ExpressRouteCircuit) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": url.QueryEscape(circuitName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/"), + autorest.WithJSON(parameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusCreated, http.StatusOK) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitsClient) CreateOrUpdateResponder(resp *http.Response) (result ExpressRouteCircuit, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete the delete ExpressRouteCircuit operation deletes the specified +// ExpressRouteCircuit. +// +// 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) (result autorest.Response, ae error) { + req, err := client.DeletePreparer(resourceGroupName, circuitName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "Delete", "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "Delete", "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "Delete", "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ExpressRouteCircuitsClient) DeletePreparer(resourceGroupName string, circuitName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": url.QueryEscape(circuitName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusNoContent, http.StatusAccepted, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get ExpressRouteCircuit operation retreives 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, ae error) { + req, err := client.GetPreparer(resourceGroupName, circuitName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "Get", "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", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "Get", "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": url.QueryEscape(circuitName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}/"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List ExpressRouteCircuit opertion retrieves all the +// ExpressRouteCircuits in a resource group. +// +// resourceGroupName is the name of the resource group. +func (client ExpressRouteCircuitsClient) List(resourceGroupName string) (result ExpressRouteCircuitListResult, ae error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "List", "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", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "List", "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ExpressRouteCircuitsClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := lastResults.ExpressRouteCircuitListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "List", "Failure preparing next results request 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", "Failure sending next results request request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "List", "Failure responding to next results request request") + } + + return +} + +// ListAll the List ExpressRouteCircuit opertion retrieves all the +// ExpressRouteCircuits in a subscription. +func (client ExpressRouteCircuitsClient) ListAll() (result ExpressRouteCircuitListResult, ae error) { + req, err := client.ListAllPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListAll", "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", "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListAll", "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client ExpressRouteCircuitsClient) ListAllPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Network/expressRouteCircuits"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := lastResults.ExpressRouteCircuitListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListAll", "Failure preparing next results request 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", "Failure sending next results request request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListAll", "Failure responding to next results request request") + } + + return +} + +// ListArpTable the ListArpTable from ExpressRouteCircuit opertion retrieves +// the currently advertised arp table associated with the +// ExpressRouteCircuits in a resource group. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the circuit. +func (client ExpressRouteCircuitsClient) ListArpTable(resourceGroupName string, circuitName string) (result ExpressRouteCircuitsArpTableListResult, ae error) { + req, err := client.ListArpTablePreparer(resourceGroupName, circuitName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListArpTable", "Failure preparing request") + } + + resp, err := client.ListArpTableSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListArpTable", "Failure sending request") + } + + result, err = client.ListArpTableResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListArpTable", "Failure responding to request") + } + + return +} + +// ListArpTablePreparer prepares the ListArpTable request. +func (client ExpressRouteCircuitsClient) ListArpTablePreparer(resourceGroupName string, circuitName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": url.QueryEscape(circuitName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}arpTable"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// ListArpTableResponder handles the response to the ListArpTable request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitsClient) ListArpTableResponder(resp *http.Response) (result ExpressRouteCircuitsArpTableListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListArpTableNextResults retrieves the next set of results, if any. +func (client ExpressRouteCircuitsClient) ListArpTableNextResults(lastResults ExpressRouteCircuitsArpTableListResult) (result ExpressRouteCircuitsArpTableListResult, ae error) { + req, err := lastResults.ExpressRouteCircuitsArpTableListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListArpTable", "Failure preparing next results request request") + } + if req == nil { + return + } + + resp, err := client.ListArpTableSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListArpTable", "Failure sending next results request request") + } + + result, err = client.ListArpTableResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListArpTable", "Failure responding to next results request request") + } + + return +} + +// ListRoutesTable the ListRoutesTable from ExpressRouteCircuit opertion +// retrieves the currently advertised routes table associated with the +// ExpressRouteCircuits in a resource group. +// +// resourceGroupName is the name of the resource group. circuitName is the +// name of the circuit. +func (client ExpressRouteCircuitsClient) ListRoutesTable(resourceGroupName string, circuitName string) (result ExpressRouteCircuitsRoutesTableListResult, ae error) { + req, err := client.ListRoutesTablePreparer(resourceGroupName, circuitName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListRoutesTable", "Failure preparing request") + } + + resp, err := client.ListRoutesTableSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListRoutesTable", "Failure sending request") + } + + result, err = client.ListRoutesTableResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListRoutesTable", "Failure responding to request") + } + + return +} + +// ListRoutesTablePreparer prepares the ListRoutesTable request. +func (client ExpressRouteCircuitsClient) ListRoutesTablePreparer(resourceGroupName string, circuitName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": url.QueryEscape(circuitName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}routesTable"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// ListRoutesTableResponder handles the response to the ListRoutesTable request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitsClient) ListRoutesTableResponder(resp *http.Response) (result ExpressRouteCircuitsRoutesTableListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListRoutesTableNextResults retrieves the next set of results, if any. +func (client ExpressRouteCircuitsClient) ListRoutesTableNextResults(lastResults ExpressRouteCircuitsRoutesTableListResult) (result ExpressRouteCircuitsRoutesTableListResult, ae error) { + req, err := lastResults.ExpressRouteCircuitsRoutesTableListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListRoutesTable", "Failure preparing next results request request") + } + if req == nil { + return + } + + resp, err := client.ListRoutesTableSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListRoutesTable", "Failure sending next results request request") + } + + result, err = client.ListRoutesTableResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListRoutesTable", "Failure responding to next results request request") + } + + return +} + +// ListStats the Liststats ExpressRouteCircuit opertion 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 loadBalancer. +func (client ExpressRouteCircuitsClient) ListStats(resourceGroupName string, circuitName string) (result ExpressRouteCircuitsStatsListResult, ae error) { + req, err := client.ListStatsPreparer(resourceGroupName, circuitName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListStats", "Failure preparing request") + } + + resp, err := client.ListStatsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListStats", "Failure sending request") + } + + result, err = client.ListStatsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListStats", "Failure responding to request") + } + + return +} + +// ListStatsPreparer prepares the ListStats request. +func (client ExpressRouteCircuitsClient) ListStatsPreparer(resourceGroupName string, circuitName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "circuitName": url.QueryEscape(circuitName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/expressRouteCircuits/{circuitName}stats"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListStatsSender sends the ListStats request. The method will close the +// http.Response Body if it receives an error. +func (client ExpressRouteCircuitsClient) ListStatsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListStatsResponder handles the response to the ListStats request. The method always +// closes the http.Response Body. +func (client ExpressRouteCircuitsClient) ListStatsResponder(resp *http.Response) (result ExpressRouteCircuitsStatsListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListStatsNextResults retrieves the next set of results, if any. +func (client ExpressRouteCircuitsClient) ListStatsNextResults(lastResults ExpressRouteCircuitsStatsListResult) (result ExpressRouteCircuitsStatsListResult, ae error) { + req, err := lastResults.ExpressRouteCircuitsStatsListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListStats", "Failure preparing next results request request") + } + if req == nil { + return + } + + resp, err := client.ListStatsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListStats", "Failure sending next results request request") + } + + result, err = client.ListStatsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteCircuitsClient", "ListStats", "Failure responding to next results request request") + } + + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/expressrouteserviceproviders.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/expressrouteserviceproviders.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/expressrouteserviceproviders.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/expressrouteserviceproviders.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,130 @@ +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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// ExpressRouteServiceProvidersClient is the the Windows Azure Network +// management API provides a RESTful set of web services that interact with +// Windows Azure Networks service to manage your network resrources. The API +// has entities that capture the relationship between an end user and the +// Windows 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 opertion retrieves all the +// available ExpressRouteServiceProviders. +func (client ExpressRouteServiceProvidersClient) List() (result ExpressRouteServiceProviderListResult, ae error) { + req, err := client.ListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteServiceProvidersClient", "List", "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", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteServiceProvidersClient", "List", "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ExpressRouteServiceProvidersClient) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Network/expressRouteServiceProviders"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := lastResults.ExpressRouteServiceProviderListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/ExpressRouteServiceProvidersClient", "List", "Failure preparing next results request 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", "Failure sending next results request request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/ExpressRouteServiceProvidersClient", "List", "Failure responding to next results request request") + } + + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/interfaces.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/interfaces.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/interfaces.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/interfaces.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,11 @@ "net/url" ) -// InterfacesClient is the client for the Interfaces methods of the Network -// service. +// InterfacesClient is the the Windows Azure Network management API provides a +// RESTful set of web services that interact with Windows Azure Networks +// service to manage your network resrources. The API has entities that +// capture the relationship between an end user and the Windows Azure +// Networks service. type InterfacesClient struct { ManagementClient } @@ -157,7 +160,7 @@ // 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 client.Send(req, http.StatusOK, http.StatusNoContent, http.StatusAccepted) + return client.Send(req, http.StatusNoContent, http.StatusAccepted, http.StatusOK) } // DeleteResponder handles the response to the Delete request. The method always @@ -166,7 +169,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusAccepted), + autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), autorest.ByClosing()) result.Response = resp return @@ -237,6 +240,76 @@ return } +// GetVirtualMachineScaleSetNetworkInterface the Get ntework interface +// operation retreives 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. +func (client InterfacesClient) GetVirtualMachineScaleSetNetworkInterface(resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string) (result Interface, ae error) { + req, err := client.GetVirtualMachineScaleSetNetworkInterfacePreparer(resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex, networkInterfaceName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/InterfacesClient", "GetVirtualMachineScaleSetNetworkInterface", "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", "Failure sending request") + } + + result, err = client.GetVirtualMachineScaleSetNetworkInterfaceResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/InterfacesClient", "GetVirtualMachineScaleSetNetworkInterface", "Failure responding to request") + } + + return +} + +// GetVirtualMachineScaleSetNetworkInterfacePreparer prepares the GetVirtualMachineScaleSetNetworkInterface request. +func (client InterfacesClient) GetVirtualMachineScaleSetNetworkInterfacePreparer(resourceGroupName string, virtualMachineScaleSetName string, virtualmachineIndex string, networkInterfaceName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "networkInterfaceName": url.QueryEscape(networkInterfaceName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "virtualmachineIndex": url.QueryEscape(virtualmachineIndex), + "virtualMachineScaleSetName": url.QueryEscape(virtualMachineScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/microsoft.compute/virtualMachineScaleSets/{virtualMachineScaleSetName}/virtualMachines/{virtualmachineIndex}/networkInterfaces/{networkInterfaceName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + // List the List networkInterfaces opertion retrieves all the // networkInterfaces in a resource group. // @@ -406,4 +479,186 @@ } 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, ae error) { + req, err := client.ListVirtualMachineScaleSetNetworkInterfacesPreparer(resourceGroupName, virtualMachineScaleSetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/InterfacesClient", "ListVirtualMachineScaleSetNetworkInterfaces", "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", "Failure sending request") + } + + result, err = client.ListVirtualMachineScaleSetNetworkInterfacesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/InterfacesClient", "ListVirtualMachineScaleSetNetworkInterfaces", "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": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "virtualMachineScaleSetName": url.QueryEscape(virtualMachineScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/microsoft.compute/virtualMachineScaleSets/{virtualMachineScaleSetName}/networkInterfaces"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := lastResults.InterfaceListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/InterfacesClient", "ListVirtualMachineScaleSetNetworkInterfaces", "Failure preparing next results request 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", "Failure sending next results request request") + } + + result, err = client.ListVirtualMachineScaleSetNetworkInterfacesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/InterfacesClient", "ListVirtualMachineScaleSetNetworkInterfaces", "Failure responding to next results request 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, ae error) { + req, err := client.ListVirtualMachineScaleSetVMNetworkInterfacesPreparer(resourceGroupName, virtualMachineScaleSetName, virtualmachineIndex) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/InterfacesClient", "ListVirtualMachineScaleSetVMNetworkInterfaces", "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", "Failure sending request") + } + + result, err = client.ListVirtualMachineScaleSetVMNetworkInterfacesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/InterfacesClient", "ListVirtualMachineScaleSetVMNetworkInterfaces", "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": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "virtualmachineIndex": url.QueryEscape(virtualmachineIndex), + "virtualMachineScaleSetName": url.QueryEscape(virtualMachineScaleSetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/microsoft.compute/virtualMachineScaleSets/{virtualMachineScaleSetName}/virtualMachines/{virtualmachineIndex}/networkInterfaces"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := lastResults.InterfaceListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/InterfacesClient", "ListVirtualMachineScaleSetVMNetworkInterfaces", "Failure preparing next results request 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", "Failure sending next results request request") + } + + result, err = client.ListVirtualMachineScaleSetVMNetworkInterfacesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/InterfacesClient", "ListVirtualMachineScaleSetVMNetworkInterfaces", "Failure responding to next results request request") + } + + return } diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/loadbalancers.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/loadbalancers.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/loadbalancers.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/loadbalancers.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,11 @@ "net/url" ) -// LoadBalancersClient is the client for the LoadBalancers methods of the -// Network service. +// LoadBalancersClient is the the Windows Azure Network management API +// provides a RESTful set of web services that interact with Windows Azure +// Networks service to manage your network resrources. The API has entities +// that capture the relationship between an end user and the Windows Azure +// Networks service. type LoadBalancersClient struct { ManagementClient } @@ -156,7 +159,7 @@ // 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 client.Send(req, http.StatusOK, http.StatusNoContent, http.StatusAccepted) + return client.Send(req, http.StatusNoContent, http.StatusAccepted, http.StatusOK) } // DeleteResponder handles the response to the Delete request. The method always @@ -165,7 +168,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusAccepted), + autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), autorest.ByClosing()) result.Response = resp return diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/localnetworkgateways.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/localnetworkgateways.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/localnetworkgateways.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/localnetworkgateways.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,11 @@ "net/url" ) -// LocalNetworkGatewaysClient is the client for the LocalNetworkGateways -// methods of the Network service. +// LocalNetworkGatewaysClient is the the Windows Azure Network management API +// provides a RESTful set of web services that interact with Windows Azure +// Networks service to manage your network resrources. The API has entities +// that capture the relationship between an end user and the Windows Azure +// Networks service. type LocalNetworkGatewaysClient struct { ManagementClient } @@ -160,7 +163,7 @@ // 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 client.Send(req, http.StatusAccepted, http.StatusNoContent, http.StatusOK) + return client.Send(req, http.StatusNoContent, http.StatusAccepted, http.StatusOK) } // DeleteResponder handles the response to the Delete request. The method always @@ -169,7 +172,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusNoContent, http.StatusOK), + autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), autorest.ByClosing()) result.Response = resp return diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/models.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/models.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/models.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/models.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -61,12 +61,10 @@ type ApplicationGatewayProtocol string const ( - // ApplicationGatewayProtocolHTTP specifies the application gateway - // protocol http state for application gateway protocol. - ApplicationGatewayProtocolHTTP ApplicationGatewayProtocol = "Http" - // ApplicationGatewayProtocolHTTPS specifies the application gateway - // protocol https state for application gateway protocol. - ApplicationGatewayProtocolHTTPS ApplicationGatewayProtocol = "Https" + // 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 @@ -103,6 +101,92 @@ 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" +) + +// 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 @@ -150,6 +234,27 @@ ProbeProtocolTCP ProbeProtocol = "Tcp" ) +// 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 @@ -174,15 +279,31 @@ type SecurityRuleProtocol string const ( - // SecurityRuleProtocolAsterisk specifies the security rule protocol - // asterisk state for security rule protocol. - SecurityRuleProtocolAsterisk SecurityRuleProtocol = "*" - // SecurityRuleProtocolTCP specifies the security rule protocol tcp state - // for security rule protocol. - SecurityRuleProtocolTCP SecurityRuleProtocol = "Tcp" - // SecurityRuleProtocolUDP specifies the security rule protocol udp state - // for security rule protocol. - SecurityRuleProtocolUDP SecurityRuleProtocol = "Udp" + // 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. @@ -205,6 +326,25 @@ Count UsageUnit = "Count" ) +// 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 @@ -229,8 +369,12 @@ type VirtualNetworkGatewayType string const ( - // Vpn specifies the vpn state for virtual network gateway type. - Vpn VirtualNetworkGatewayType = "Vpn" + // 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" ) // VpnType enumerates the values for vpn type. @@ -279,7 +423,7 @@ // ApplicationGatewayBackendAddressPoolPropertiesFormat is properties of // Backend Address Pool of application gateway type ApplicationGatewayBackendAddressPoolPropertiesFormat struct { - BackendIPConfigurations *[]SubResource `json:"backendIpConfigurations,omitempty"` + BackendIPConfigurations *[]SubResource `json:"backendIPConfigurations,omitempty"` BackendAddresses *[]ApplicationGatewayBackendAddress `json:"backendAddresses,omitempty"` ProvisioningState *string `json:"provisioningState,omitempty"` } @@ -347,7 +491,7 @@ // ApplicationGatewayHTTPListenerPropertiesFormat is properties of Http // listener of application gateway type ApplicationGatewayHTTPListenerPropertiesFormat struct { - FrontendIPConfiguration *SubResource `json:"frontendIpConfiguration,omitempty"` + FrontendIPConfiguration *SubResource `json:"frontendIPConfiguration,omitempty"` FrontendPort *SubResource `json:"frontendPort,omitempty"` Protocol ApplicationGatewayProtocol `json:"protocol,omitempty"` SslCertificate *SubResource `json:"sslCertificate,omitempty"` @@ -393,14 +537,15 @@ type ApplicationGatewayPropertiesFormat struct { Sku *ApplicationGatewaySku `json:"sku,omitempty"` OperationalState ApplicationGatewayOperationalState `json:"operationalState,omitempty"` - GatewayIPConfigurations *[]ApplicationGatewayIPConfiguration `json:"gatewayIpConfigurations,omitempty"` + GatewayIPConfigurations *[]ApplicationGatewayIPConfiguration `json:"gatewayIPConfigurations,omitempty"` SslCertificates *[]ApplicationGatewaySslCertificate `json:"sslCertificates,omitempty"` - FrontendIPConfigurations *[]ApplicationGatewayFrontendIPConfiguration `json:"frontendIpConfigurations,omitempty"` + FrontendIPConfigurations *[]ApplicationGatewayFrontendIPConfiguration `json:"frontendIPConfigurations,omitempty"` FrontendPorts *[]ApplicationGatewayFrontendPort `json:"frontendPorts,omitempty"` BackendAddressPools *[]ApplicationGatewayBackendAddressPool `json:"backendAddressPools,omitempty"` BackendHTTPSettingsCollection *[]ApplicationGatewayBackendHTTPSettings `json:"backendHttpSettingsCollection,omitempty"` HTTPListeners *[]ApplicationGatewayHTTPListener `json:"httpListeners,omitempty"` RequestRoutingRules *[]ApplicationGatewayRequestRoutingRule `json:"requestRoutingRules,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` ProvisioningState *string `json:"provisioningState,omitempty"` } @@ -447,6 +592,33 @@ 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 // inprogress, or has failed. Note that this status is distinct from the HTTP @@ -472,19 +644,14 @@ type BackendAddressPoolPropertiesFormat struct { BackendIPConfigurations *[]SubResource `json:"backendIPConfigurations,omitempty"` LoadBalancingRules *[]SubResource `json:"loadBalancingRules,omitempty"` + OutboundNatRule *SubResource `json:"outboundNatRule,omitempty"` ProvisioningState *string `json:"provisioningState,omitempty"` } // ConnectionResetSharedKey is type ConnectionResetSharedKey struct { autorest.Response `json:"-"` - Properties *ConnectionResetSharedKeyPropertiesFormat `json:"properties,omitempty"` -} - -// ConnectionResetSharedKeyPropertiesFormat is -// virtualNeworkGatewayConnectionResetSharedKey properties -type ConnectionResetSharedKeyPropertiesFormat struct { - KeyLength *int32 `json:"keyLength,omitempty"` + KeyLength *int32 `json:"keyLength,omitempty"` } // ConnectionSharedKey is response for GetConnectionSharedKey Api servive call @@ -523,6 +690,255 @@ 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 { + 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 specfies the peering config +type ExpressRouteCircuitPeeringConfig struct { + AdvertisedPublicPrefixes *[]string `json:"advertisedPublicPrefixes,omitempty"` + AdvertisedPublicPrefixesState ExpressRouteCircuitPeeringAdvertisedPublicPrefixState `json:"advertisedPublicPrefixesState,omitempty"` + CustomerASN *int `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 *int `json:"azureASN,omitempty"` + PeerASN *int `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 *int `json:"vlanId,omitempty"` + MicrosoftPeeringConfig *ExpressRouteCircuitPeeringConfig `json:"microsoftPeeringConfig,omitempty"` + Stats *ExpressRouteCircuitStats `json:"stats,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + +// ExpressRouteCircuitPropertiesFormat is properties of ExpressRouteCircuit +type ExpressRouteCircuitPropertiesFormat struct { + 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"` +} + +// ExpressRouteCircuitRoutesTable is the routes table associated with the +// ExpressRouteCircuit +type ExpressRouteCircuitRoutesTable struct { + AddressPrefix *string `json:"addressPrefix,omitempty"` + NextHopType RouteNextHopType `json:"nextHopType,omitempty"` + NextHopIP *string `json:"nextHopIP,omitempty"` + AsPath *string `json:"asPath,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"` +} + +// ExpressRouteCircuitsArpTableListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ExpressRouteCircuitsArpTableListResult) ExpressRouteCircuitsArpTableListResultPreparer() (*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))) +} + +// ExpressRouteCircuitServiceProviderProperties is contains +// ServiceProviderProperties in an ExpressRouteCircuit +type ExpressRouteCircuitServiceProviderProperties struct { + ServiceProviderName *string `json:"serviceProviderName,omitempty"` + PeeringLocation *string `json:"peeringLocation,omitempty"` + BandwidthInMbps *int `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"` +} + +// ExpressRouteCircuitsRoutesTableListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ExpressRouteCircuitsRoutesTableListResult) ExpressRouteCircuitsRoutesTableListResultPreparer() (*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))) +} + +// ExpressRouteCircuitsStatsListResult is response for ListStats from Express +// Route Circuits Api service call +type ExpressRouteCircuitsStatsListResult struct { + autorest.Response `json:"-"` + Value *[]ExpressRouteCircuitStats `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ExpressRouteCircuitsStatsListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ExpressRouteCircuitsStatsListResult) ExpressRouteCircuitsStatsListResultPreparer() (*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))) +} + +// ExpressRouteCircuitStats is contains Stats associated with the peering +type ExpressRouteCircuitStats struct { + BytesIn *int `json:"bytesIn,omitempty"` + BytesOut *int `json:"bytesOut,omitempty"` +} + +// ExpressRouteServiceProvider is expressRouteResourceProvider object +type ExpressRouteServiceProvider struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Properties *ExpressRouteServiceProviderPropertiesFormat `json:"properties,omitempty"` +} + +// ExpressRouteServiceProviderBandwidthsOffered is contains Bandwidths offered +// in ExpressRouteServiceProviders +type ExpressRouteServiceProviderBandwidthsOffered struct { + OfferName *string `json:"offerName,omitempty"` + ValueInMbps *int `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"` @@ -539,10 +955,30 @@ Subnet *SubResource `json:"subnet,omitempty"` PublicIPAddress *SubResource `json:"publicIPAddress,omitempty"` InboundNatRules *[]SubResource `json:"inboundNatRules,omitempty"` + InboundNatPools *[]SubResource `json:"inboundNatPools,omitempty"` + OutboundNatRules *[]SubResource `json:"outboundNatRules,omitempty"` LoadBalancingRules *[]SubResource `json:"loadBalancingRules,omitempty"` ProvisioningState *string `json:"provisioningState,omitempty"` } +// InboundNatPool is inbound NAT pool of the loadbalancer +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 *int `json:"frontendPortRangeStart,omitempty"` + FrontendPortRangeEnd *int `json:"frontendPortRangeEnd,omitempty"` + BackendPort *int `json:"backendPort,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + // InboundNatRule is inbound NAT rule of the loadbalancer type InboundNatRule struct { ID *string `json:"id,omitempty"` @@ -629,6 +1065,8 @@ DNSSettings *InterfaceDNSSettings `json:"dnsSettings,omitempty"` MacAddress *string `json:"macAddress,omitempty"` Primary *bool `json:"primary,omitempty"` + EnableIPForwarding *bool `json:"enableIPForwarding,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` ProvisioningState *string `json:"provisioningState,omitempty"` } @@ -670,6 +1108,9 @@ 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"` } @@ -731,9 +1172,26 @@ type LocalNetworkGatewayPropertiesFormat struct { LocalNetworkAddressSpace *AddressSpace `json:"localNetworkAddressSpace,omitempty"` GatewayIPAddress *string `json:"gatewayIpAddress,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` ProvisioningState *string `json:"provisioningState,omitempty"` } +// OutboundNatRule is outbound NAT pool of the loadbalancer +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 loadbalancer +type OutboundNatRulePropertiesFormat struct { + AllocatedOutboundPorts *int `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"` @@ -800,6 +1258,7 @@ DNSSettings *PublicIPAddressDNSSettings `json:"dnsSettings,omitempty"` IPAddress *string `json:"ipAddress,omitempty"` IdleTimeoutInMinutes *int `json:"idleTimeoutInMinutes,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` ProvisioningState *string `json:"provisioningState,omitempty"` } @@ -812,6 +1271,80 @@ Tags *map[string]*string `json:"tags,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 servive 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 servive 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 *[]SubResource `json:"subnets,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` +} + // SecurityGroup is networkSecurityGroup resource type SecurityGroup struct { autorest.Response `json:"-"` @@ -850,6 +1383,7 @@ DefaultSecurityRules *[]SecurityRule `json:"defaultSecurityRules,omitempty"` NetworkInterfaces *[]SubResource `json:"networkInterfaces,omitempty"` Subnets *[]SubResource `json:"subnets,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` ProvisioningState *string `json:"provisioningState,omitempty"` } @@ -929,6 +1463,7 @@ type SubnetPropertiesFormat struct { AddressPrefix *string `json:"addressPrefix,omitempty"` NetworkSecurityGroup *SubResource `json:"networkSecurityGroup,omitempty"` + RouteTable *SubResource `json:"routeTable,omitempty"` IPConfigurations *[]SubResource `json:"ipConfigurations,omitempty"` ProvisioningState *string `json:"provisioningState,omitempty"` } @@ -1018,13 +1553,18 @@ // VirtualNetworkGatewayConnectionPropertiesFormat is // virtualNeworkGatewayConnection properties type VirtualNetworkGatewayConnectionPropertiesFormat struct { - VirtualNetworkGateway1 *VirtualNetworkGateway `json:"virtualNetworkGateway1,omitempty"` - VirtualNetworkGateway2 *VirtualNetworkGateway `json:"virtualNetworkGateway2,omitempty"` - LocalNetworkGateway2 *LocalNetworkGateway `json:"localNetworkGateway2,omitempty"` - ConnectionType VirtualNetworkGatewayConnectionType `json:"connectionType,omitempty"` - RoutingWeight *int `json:"routingWeight,omitempty"` - SharedKey *string `json:"sharedKey,omitempty"` - ProvisioningState *string `json:"provisioningState,omitempty"` + VirtualNetworkGateway1 *VirtualNetworkGateway `json:"virtualNetworkGateway1,omitempty"` + VirtualNetworkGateway2 *VirtualNetworkGateway `json:"virtualNetworkGateway2,omitempty"` + LocalNetworkGateway2 *LocalNetworkGateway `json:"localNetworkGateway2,omitempty"` + ConnectionType VirtualNetworkGatewayConnectionType `json:"connectionType,omitempty"` + RoutingWeight *int `json:"routingWeight,omitempty"` + SharedKey *string `json:"sharedKey,omitempty"` + ConnectionStatus VirtualNetworkGatewayConnectionStatus `json:"connectionStatus,omitempty"` + EgressBytesTransferred *int32 `json:"egressBytesTransferred,omitempty"` + IngressBytesTransferred *int32 `json:"ingressBytesTransferred,omitempty"` + Peer *SubResource `json:"peer,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` } // VirtualNetworkGatewayIPConfiguration is ipConfiguration for Virtual network @@ -1068,11 +1608,13 @@ // VirtualNetworkGatewayPropertiesFormat is virtualNeworkGateay properties type VirtualNetworkGatewayPropertiesFormat struct { - IPConfigurations *[]VirtualNetworkGatewayIPConfiguration `json:"ipConfigurations,omitempty"` - GatewayType VirtualNetworkGatewayType `json:"gatewayType,omitempty"` - VpnType VpnType `json:"vpnType,omitempty"` - EnableBgp *bool `json:"enableBgp,omitempty"` - ProvisioningState *string `json:"provisioningState,omitempty"` + IPConfigurations *[]VirtualNetworkGatewayIPConfiguration `json:"ipConfigurations,omitempty"` + GatewayType VirtualNetworkGatewayType `json:"gatewayType,omitempty"` + VpnType VpnType `json:"vpnType,omitempty"` + EnableBgp *bool `json:"enableBgp,omitempty"` + GatewayDefaultSite *SubResource `json:"gatewayDefaultSite,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` } // VirtualNetworkListResult is response for ListVirtualNetworks Api servive @@ -1100,5 +1642,6 @@ AddressSpace *AddressSpace `json:"addressSpace,omitempty"` DhcpOptions *DhcpOptions `json:"dhcpOptions,omitempty"` Subnets *[]Subnet `json:"subnets,omitempty"` + ResourceGUID *string `json:"resourceGuid,omitempty"` ProvisioningState *string `json:"provisioningState,omitempty"` } diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/publicipaddresses.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/publicipaddresses.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/publicipaddresses.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/publicipaddresses.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,11 @@ "net/url" ) -// PublicIPAddressesClient is the client for the PublicIPAddresses methods of -// the Network service. +// PublicIPAddressesClient is the the Windows Azure Network management API +// provides a RESTful set of web services that interact with Windows Azure +// Networks service to manage your network resrources. The API has entities +// that capture the relationship between an end user and the Windows Azure +// Networks service. type PublicIPAddressesClient struct { ManagementClient } @@ -93,7 +96,7 @@ // 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 client.Send(req, http.StatusOK, http.StatusCreated) + return client.Send(req, http.StatusCreated, http.StatusOK) } // CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always @@ -102,7 +105,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), autorest.ByUnmarshallingJSON(&result), autorest.ByClosing()) result.Response = autorest.Response{Response: resp} @@ -158,7 +161,7 @@ // 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 client.Send(req, http.StatusAccepted, http.StatusNoContent, http.StatusOK) + return client.Send(req, http.StatusNoContent, http.StatusAccepted, http.StatusOK) } // DeleteResponder handles the response to the Delete request. The method always @@ -167,7 +170,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusNoContent, http.StatusOK), + autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), autorest.ByClosing()) result.Response = resp return diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/routes.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/routes.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/routes.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/routes.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,332 @@ +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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// RoutesClient is the the Windows Azure Network management API provides a +// RESTful set of web services that interact with Windows Azure Networks +// service to manage your network resrources. The API has entities that +// capture the relationship between an end user and the Windows 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 +// +// 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 routeoperation +func (client RoutesClient) CreateOrUpdate(resourceGroupName string, routeTableName string, routeName string, routeParameters Route) (result Route, ae error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, routeTableName, routeName, routeParameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/RoutesClient", "CreateOrUpdate", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network/RoutesClient", "CreateOrUpdate", "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/RoutesClient", "CreateOrUpdate", "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client RoutesClient) CreateOrUpdatePreparer(resourceGroupName string, routeTableName string, routeName string, routeParameters Route) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "routeName": url.QueryEscape(routeName), + "routeTableName": url.QueryEscape(routeTableName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables/{routeTableName}/routes/{routeName}"), + autorest.WithJSON(routeParameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusCreated, http.StatusOK) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client RoutesClient) CreateOrUpdateResponder(resp *http.Response) (result Route, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete the delete route operation deletes the specified route from a 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) Delete(resourceGroupName string, routeTableName string, routeName string) (result autorest.Response, ae error) { + req, err := client.DeletePreparer(resourceGroupName, routeTableName, routeName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/RoutesClient", "Delete", "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network/RoutesClient", "Delete", "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/RoutesClient", "Delete", "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client RoutesClient) DeletePreparer(resourceGroupName string, routeTableName string, routeName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "routeName": url.QueryEscape(routeName), + "routeTableName": url.QueryEscape(routeTableName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables/{routeTableName}/routes/{routeName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusNoContent, http.StatusAccepted, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get the Get route operation retreives 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, ae error) { + req, err := client.GetPreparer(resourceGroupName, routeTableName, routeName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/RoutesClient", "Get", "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", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/RoutesClient", "Get", "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": url.QueryEscape(resourceGroupName), + "routeName": url.QueryEscape(routeName), + "routeTableName": url.QueryEscape(routeTableName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables/{routeTableName}/routes/{routeName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List network security rule opertion 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, ae error) { + req, err := client.ListPreparer(resourceGroupName, routeTableName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/RoutesClient", "List", "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", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/RoutesClient", "List", "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": url.QueryEscape(resourceGroupName), + "routeTableName": url.QueryEscape(routeTableName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables/{routeTableName}/routes"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := lastResults.RouteListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/RoutesClient", "List", "Failure preparing next results request 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", "Failure sending next results request request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/RoutesClient", "List", "Failure responding to next results request request") + } + + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/routetables.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/routetables.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/routetables.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/routetables.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,409 @@ +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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// RouteTablesClient is the the Windows Azure Network management API provides +// a RESTful set of web services that interact with Windows Azure Networks +// service to manage your network resrources. The API has entities that +// capture the relationship between an end user and the Windows 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 tablein +// the specified resource group. +// +// 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) (result RouteTable, ae error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, routeTableName, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/RouteTablesClient", "CreateOrUpdate", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "network/RouteTablesClient", "CreateOrUpdate", "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/RouteTablesClient", "CreateOrUpdate", "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client RouteTablesClient) CreateOrUpdatePreparer(resourceGroupName string, routeTableName string, parameters RouteTable) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "routeTableName": url.QueryEscape(routeTableName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables/{routeTableName}"), + autorest.WithJSON(parameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusCreated, http.StatusOK) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client RouteTablesClient) CreateOrUpdateResponder(resp *http.Response) (result RouteTable, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete the Delete RouteTable operation deletes the specifed Route Table +// +// resourceGroupName is the name of the resource group. routeTableName is the +// name of the route table. +func (client RouteTablesClient) Delete(resourceGroupName string, routeTableName string) (result autorest.Response, ae error) { + req, err := client.DeletePreparer(resourceGroupName, routeTableName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/RouteTablesClient", "Delete", "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "network/RouteTablesClient", "Delete", "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/RouteTablesClient", "Delete", "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client RouteTablesClient) DeletePreparer(resourceGroupName string, routeTableName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "routeTableName": url.QueryEscape(routeTableName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables/{routeTableName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusNoContent, http.StatusAccepted, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), + 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. +func (client RouteTablesClient) Get(resourceGroupName string, routeTableName string) (result RouteTable, ae error) { + req, err := client.GetPreparer(resourceGroupName, routeTableName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/RouteTablesClient", "Get", "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", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/RouteTablesClient", "Get", "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client RouteTablesClient) GetPreparer(resourceGroupName string, routeTableName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "routeTableName": url.QueryEscape(routeTableName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables/{routeTableName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := client.ListPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "network/RouteTablesClient", "List", "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", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/RouteTablesClient", "List", "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client RouteTablesClient) ListPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/routeTables"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := lastResults.RouteTableListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/RouteTablesClient", "List", "Failure preparing next results request 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", "Failure sending next results request request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/RouteTablesClient", "List", "Failure responding to next results request request") + } + + return +} + +// ListAll the list RouteTables returns all route tables in a subscription +func (client RouteTablesClient) ListAll() (result RouteTableListResult, ae error) { + req, err := client.ListAllPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/RouteTablesClient", "ListAll", "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", "Failure sending request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/RouteTablesClient", "ListAll", "Failure responding to request") + } + + return +} + +// ListAllPreparer prepares the ListAll request. +func (client RouteTablesClient) ListAllPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Network/routeTables"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := lastResults.RouteTableListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "network/RouteTablesClient", "ListAll", "Failure preparing next results request 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", "Failure sending next results request request") + } + + result, err = client.ListAllResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "network/RouteTablesClient", "ListAll", "Failure responding to next results request request") + } + + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/securitygroups.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/securitygroups.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/securitygroups.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/securitygroups.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,11 @@ "net/url" ) -// SecurityGroupsClient is the client for the SecurityGroups methods of the -// Network service. +// SecurityGroupsClient is the the Windows Azure Network management API +// provides a RESTful set of web services that interact with Windows Azure +// Networks service to manage your network resrources. The API has entities +// that capture the relationship between an end user and the Windows Azure +// Networks service. type SecurityGroupsClient struct { ManagementClient } diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/securityrules.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/securityrules.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/securityrules.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/securityrules.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,11 @@ "net/url" ) -// SecurityRulesClient is the client for the SecurityRules methods of the -// Network service. +// SecurityRulesClient is the the Windows Azure Network management API +// provides a RESTful set of web services that interact with Windows Azure +// Networks service to manage your network resrources. The API has entities +// that capture the relationship between an end user and the Windows Azure +// Networks service. type SecurityRulesClient struct { ManagementClient } @@ -96,7 +99,7 @@ // 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 client.Send(req, http.StatusOK, http.StatusCreated) + return client.Send(req, http.StatusCreated, http.StatusOK) } // CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always @@ -105,7 +108,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), autorest.ByUnmarshallingJSON(&result), autorest.ByClosing()) result.Response = autorest.Response{Response: resp} @@ -163,7 +166,7 @@ // 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 client.Send(req, http.StatusAccepted, http.StatusOK, http.StatusNoContent) + return client.Send(req, http.StatusNoContent, http.StatusAccepted, http.StatusOK) } // DeleteResponder handles the response to the Delete request. The method always @@ -172,7 +175,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK, http.StatusNoContent), + autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), autorest.ByClosing()) result.Response = resp return diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/subnets.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/subnets.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/subnets.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/subnets.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,7 +24,11 @@ "net/url" ) -// SubnetsClient is the client for the Subnets methods of the Network service. +// SubnetsClient is the the Windows Azure Network management API provides a +// RESTful set of web services that interact with Windows Azure Networks +// service to manage your network resrources. The API has entities that +// capture the relationship between an end user and the Windows Azure +// Networks service. type SubnetsClient struct { ManagementClient } @@ -92,7 +96,7 @@ // 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 client.Send(req, http.StatusOK, http.StatusCreated) + return client.Send(req, http.StatusCreated, http.StatusOK) } // CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always @@ -101,7 +105,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), autorest.ByUnmarshallingJSON(&result), autorest.ByClosing()) result.Response = autorest.Response{Response: resp} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/usages.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/usages.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/usages.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/usages.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,7 +24,11 @@ "net/url" ) -// UsagesClient is the client for the Usages methods of the Network service. +// UsagesClient is the the Windows Azure Network management API provides a +// RESTful set of web services that interact with Windows Azure Networks +// service to manage your network resrources. The API has entities that +// capture the relationship between an end user and the Windows Azure +// Networks service. type UsagesClient struct { ManagementClient } diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/version.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/version.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/version.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,8 @@ const ( major = "0" - minor = "1" - patch = "1" + minor = "3" + patch = "0" // Always begin a "tag" with a dash (as per http://semver.org) tag = "-beta" semVerFormat = "%s.%s.%s%s" diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkgatewayconnections.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkgatewayconnections.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkgatewayconnections.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkgatewayconnections.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,11 @@ "net/url" ) -// VirtualNetworkGatewayConnectionsClient is the client for the -// VirtualNetworkGatewayConnections methods of the Network service. +// VirtualNetworkGatewayConnectionsClient is the the Windows Azure Network +// management API provides a RESTful set of web services that interact with +// Windows Azure Networks service to manage your network resrources. The API +// has entities that capture the relationship between an end user and the +// Windows Azure Networks service. type VirtualNetworkGatewayConnectionsClient struct { ManagementClient } @@ -96,7 +99,7 @@ // 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 client.Send(req, http.StatusOK, http.StatusCreated) + return client.Send(req, http.StatusCreated, http.StatusOK) } // CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always @@ -105,7 +108,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), autorest.ByUnmarshallingJSON(&result), autorest.ByClosing()) result.Response = autorest.Response{Response: resp} @@ -163,7 +166,7 @@ // 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 client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusNoContent) + return client.Send(req, http.StatusNoContent, http.StatusAccepted, http.StatusOK) } // DeleteResponder handles the response to the Delete request. The method always @@ -172,7 +175,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), autorest.ByClosing()) result.Response = resp return @@ -454,7 +457,7 @@ // 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 client.Send(req, http.StatusOK, http.StatusAccepted) + return client.Send(req, http.StatusAccepted, http.StatusOK) } // ResetSharedKeyResponder handles the response to the ResetSharedKey request. The method always @@ -463,7 +466,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK), autorest.ByUnmarshallingJSON(&result), autorest.ByClosing()) result.Response = autorest.Response{Response: resp} @@ -525,7 +528,7 @@ // 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 client.Send(req, http.StatusOK, http.StatusCreated) + return client.Send(req, http.StatusCreated, http.StatusOK) } // SetSharedKeyResponder handles the response to the SetSharedKey request. The method always @@ -534,7 +537,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), autorest.ByUnmarshallingJSON(&result), autorest.ByClosing()) result.Response = autorest.Response{Response: resp} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkgateways.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkgateways.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkgateways.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworkgateways.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,11 @@ "net/url" ) -// VirtualNetworkGatewaysClient is the client for the VirtualNetworkGateways -// methods of the Network service. +// VirtualNetworkGatewaysClient is the the Windows Azure Network management +// API provides a RESTful set of web services that interact with Windows +// Azure Networks service to manage your network resrources. The API has +// entities that capture the relationship between an end user and the Windows +// Azure Networks service. type VirtualNetworkGatewaysClient struct { ManagementClient } @@ -160,7 +163,7 @@ // 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 client.Send(req, http.StatusAccepted, http.StatusOK, http.StatusNoContent) + return client.Send(req, http.StatusNoContent, http.StatusAccepted, http.StatusOK) } // DeleteResponder handles the response to the Delete request. The method always @@ -169,7 +172,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK, http.StatusNoContent), + autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), autorest.ByClosing()) result.Response = resp return diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworks.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworks.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworks.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/network/virtualnetworks.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,11 @@ "net/url" ) -// VirtualNetworksClient is the client for the VirtualNetworks methods of the -// Network service. +// VirtualNetworksClient is the the Windows Azure Network management API +// provides a RESTful set of web services that interact with Windows Azure +// Networks service to manage your network resrources. The API has entities +// that capture the relationship between an end user and the Windows Azure +// Networks service. type VirtualNetworksClient struct { ManagementClient } @@ -93,7 +96,7 @@ // 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 client.Send(req, http.StatusOK, http.StatusCreated) + return client.Send(req, http.StatusCreated, http.StatusOK) } // CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always @@ -102,7 +105,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), autorest.ByUnmarshallingJSON(&result), autorest.ByClosing()) result.Response = autorest.Response{Response: resp} @@ -158,7 +161,7 @@ // 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 client.Send(req, http.StatusOK, http.StatusNoContent, http.StatusAccepted) + return client.Send(req, http.StatusNoContent, http.StatusAccepted, http.StatusOK) } // DeleteResponder handles the response to the Delete request. The method always @@ -167,7 +170,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusAccepted), + autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusAccepted, http.StatusOK), autorest.ByClosing()) result.Response = resp return diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/README.md juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/README.md --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/README.md 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/README.md 2016-05-17 20:01:14.000000000 +0000 @@ -338,16 +338,19 @@ Install the packages you require as you would any other Go package: ```bash -go get github.com/azure/azure-sdk-for-go/arm/authorization -go get github.com/azure/azure-sdk-for-go/arm/compute -go get github.com/azure/azure-sdk-for-go/arm/features -go get github.com/azure/azure-sdk-for-go/arm/logic -go get github.com/azure/azure-sdk-for-go/arm/network -go get github.com/azure/azure-sdk-for-go/arm/resources -go get github.com/azure/azure-sdk-for-go/arm/scheduler -go get github.com/azure/azure-sdk-for-go/arm/search -go get github.com/azure/azure-sdk-for-go/arm/storage -go get github.com/azure/azure-sdk-for-go/arm/subscriptions +go get github.com/Azure/azure-sdk-for-go/arm/authorization +go get github.com/Azure/azure-sdk-for-go/arm/compute +go get github.com/Azure/azure-sdk-for-go/arm/dns +go get github.com/Azure/azure-sdk-for-go/arm/features +go get github.com/Azure/azure-sdk-for-go/arm/logic +go get github.com/Azure/azure-sdk-for-go/arm/network +go get github.com/Azure/azure-sdk-for-go/arm/redis +go get github.com/Azure/azure-sdk-for-go/arm/resources +go get github.com/Azure/azure-sdk-for-go/arm/scheduler +go get github.com/Azure/azure-sdk-for-go/arm/search +go get github.com/Azure/azure-sdk-for-go/arm/storage +go get github.com/Azure/azure-sdk-for-go/arm/subscriptions +go get github.com/Azure/azure-sdk-for-go/arm/web ``` ## License diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/redis/client.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/redis/client.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/redis/client.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/redis/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,549 @@ +package redis + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +const ( + // APIVersion is the version of the Redis + APIVersion = "2015-08-01" + + // DefaultBaseURI is the default URI used for the service Redis + DefaultBaseURI = "https://management.azure.com" +) + +// ManagementClient is the .Net client wrapper for the REST API for Azure +// Redis Cache Management Service +type ManagementClient struct { + autorest.Client + BaseURI 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, + SubscriptionID: subscriptionID, + } +} + +// CreateOrUpdate create a redis cache, or replace (overwrite/recreate, with +// potential downtime) an existing cache +// +// resourceGroupName is the name of the resource group. name is the name of +// the redis cache. parameters is parameters supplied to the CreateOrUpdate +// redis operation. +func (client ManagementClient) CreateOrUpdate(resourceGroupName string, name string, parameters CreateOrUpdateParameters) (result ResourceWithAccessKey, ae error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, name, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "CreateOrUpdate", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "CreateOrUpdate", "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/ManagementClient", "CreateOrUpdate", "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client ManagementClient) CreateOrUpdatePreparer(resourceGroupName string, name string, parameters CreateOrUpdateParameters) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Cache/Redis/{name}"), + autorest.WithJSON(parameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client ManagementClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusCreated, http.StatusOK) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client ManagementClient) CreateOrUpdateResponder(resp *http.Response) (result ResourceWithAccessKey, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete deletes a redis cache. This operation takes a while to complete. +// +// resourceGroupName is the name of the resource group. name is the name of +// the redis cache. +func (client ManagementClient) Delete(resourceGroupName string, name string) (result autorest.Response, ae error) { + req, err := client.DeletePreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "Delete", "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "Delete", "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/ManagementClient", "Delete", "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ManagementClient) DeletePreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Cache/Redis/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client ManagementClient) DeleteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusNotFound) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client ManagementClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNotFound), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get gets a redis cache (resource description). +// +// resourceGroupName is the name of the resource group. name is the name of +// the redis cache. +func (client ManagementClient) Get(resourceGroupName string, name string) (result ResourceType, ae error) { + req, err := client.GetPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "Get", "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "Get", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/ManagementClient", "Get", "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ManagementClient) GetPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Cache/Redis/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client ManagementClient) GetSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client ManagementClient) GetResponder(resp *http.Response) (result ResourceType, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List gets all redis caches in the specified subscription. +func (client ManagementClient) List() (result ListResult, ae error) { + req, err := client.ListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "List", "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "List", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/ManagementClient", "List", "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ManagementClient) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Cache/Redis/"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ManagementClient) ListSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ManagementClient) ListResponder(resp *http.Response) (result ListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.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 ManagementClient) ListNextResults(lastResults ListResult) (result ListResult, ae error) { + req, err := lastResults.ListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "List", "Failure preparing next results request request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "List", "Failure sending next results request request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/ManagementClient", "List", "Failure responding to next results request request") + } + + return +} + +// ListByResourceGroup gets all redis caches in a resource group. +// +// resourceGroupName is the name of the resource group. +func (client ManagementClient) ListByResourceGroup(resourceGroupName string) (result ListResult, ae error) { + req, err := client.ListByResourceGroupPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "ListByResourceGroup", "Failure preparing request") + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "ListByResourceGroup", "Failure sending request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/ManagementClient", "ListByResourceGroup", "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client ManagementClient) ListByResourceGroupPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Cache/Redis/"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client ManagementClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client ManagementClient) ListByResourceGroupResponder(resp *http.Response) (result ListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByResourceGroupNextResults retrieves the next set of results, if any. +func (client ManagementClient) ListByResourceGroupNextResults(lastResults ListResult) (result ListResult, ae error) { + req, err := lastResults.ListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "ListByResourceGroup", "Failure preparing next results request request") + } + if req == nil { + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "ListByResourceGroup", "Failure sending next results request request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/ManagementClient", "ListByResourceGroup", "Failure responding to next results request request") + } + + return +} + +// ListKeys retrieve a redis cache's access keys. This operation requires +// write permission to the cache resource. +// +// resourceGroupName is the name of the resource group. name is the name of +// the redis cache. +func (client ManagementClient) ListKeys(resourceGroupName string, name string) (result ListKeysResult, ae error) { + req, err := client.ListKeysPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "ListKeys", "Failure preparing request") + } + + resp, err := client.ListKeysSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "ListKeys", "Failure sending request") + } + + result, err = client.ListKeysResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/ManagementClient", "ListKeys", "Failure responding to request") + } + + return +} + +// ListKeysPreparer prepares the ListKeys request. +func (client ManagementClient) ListKeysPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Cache/Redis/{name}/listKeys"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListKeysSender sends the ListKeys request. The method will close the +// http.Response Body if it receives an error. +func (client ManagementClient) ListKeysSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListKeysResponder handles the response to the ListKeys request. The method always +// closes the http.Response Body. +func (client ManagementClient) ListKeysResponder(resp *http.Response) (result ListKeysResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// RegenerateKey regenerate redis cache's access keys. This operation requires +// write permission to the cache resource. +// +// resourceGroupName is the name of the resource group. name is the name of +// the redis cache. parameters is specifies which key to reset. +func (client ManagementClient) RegenerateKey(resourceGroupName string, name string, parameters RegenerateKeyParameters) (result ListKeysResult, ae error) { + req, err := client.RegenerateKeyPreparer(resourceGroupName, name, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "RegenerateKey", "Failure preparing request") + } + + resp, err := client.RegenerateKeySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/ManagementClient", "RegenerateKey", "Failure sending request") + } + + result, err = client.RegenerateKeyResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/ManagementClient", "RegenerateKey", "Failure responding to request") + } + + return +} + +// RegenerateKeyPreparer prepares the RegenerateKey request. +func (client ManagementClient) RegenerateKeyPreparer(resourceGroupName string, name string, parameters RegenerateKeyParameters) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Cache/Redis/{name}/regenerateKey"), + autorest.WithJSON(parameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// RegenerateKeySender sends the RegenerateKey request. The method will close the +// http.Response Body if it receives an error. +func (client ManagementClient) RegenerateKeySender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// RegenerateKeyResponder handles the response to the RegenerateKey request. The method always +// closes the http.Response Body. +func (client ManagementClient) RegenerateKeyResponder(resp *http.Response) (result ListKeysResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/redis/models.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/redis/models.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/redis/models.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/redis/models.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,197 @@ +package redis + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/to" + "net/http" +) + +// KeyType enumerates the values for key type. +type KeyType string + +const ( + // Primary specifies the primary state for key type. + Primary KeyType = "Primary" + // Secondary specifies the secondary state for key type. + Secondary KeyType = "Secondary" +) + +// SkuFamily enumerates the values for sku family. +type SkuFamily string + +const ( + // C specifies the c state for sku family. + C SkuFamily = "C" + // P specifies the p state for sku family. + P SkuFamily = "P" +) + +// SkuName enumerates the values for sku name. +type SkuName string + +const ( + // Basic specifies the basic state for sku name. + Basic SkuName = "Basic" + // Premium specifies the premium state for sku name. + Premium SkuName = "Premium" + // Standard specifies the standard state for sku name. + Standard SkuName = "Standard" +) + +// AccessKeys is redis cache access keys. +type AccessKeys struct { + PrimaryKey *string `json:"primaryKey,omitempty"` + SecondaryKey *string `json:"secondaryKey,omitempty"` +} + +// CreateOrUpdateParameters is parameters supplied to the CreateOrUpdate Redis +// operation. +type CreateOrUpdateParameters 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 *Properties `json:"properties,omitempty"` +} + +// ListKeysResult is the response of redis list keys operation. +type ListKeysResult struct { + autorest.Response `json:"-"` + PrimaryKey *string `json:"primaryKey,omitempty"` + SecondaryKey *string `json:"secondaryKey,omitempty"` +} + +// ListResult is the response of list redis operation. +type ListResult struct { + autorest.Response `json:"-"` + Value *[]ResourceType `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ListResult) ListResultPreparer() (*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))) +} + +// Properties is parameters supplied to CreateOrUpdate redis operation. +type Properties struct { + RedisVersion *string `json:"redisVersion,omitempty"` + Sku *Sku `json:"sku,omitempty"` + RedisConfiguration *map[string]*string `json:"redisConfiguration,omitempty"` + EnableNonSslPort *bool `json:"enableNonSslPort,omitempty"` + TenantSettings *map[string]*string `json:"tenantSettings,omitempty"` + ShardCount *int `json:"shardCount,omitempty"` + VirtualNetwork *string `json:"virtualNetwork,omitempty"` + Subnet *string `json:"subnet,omitempty"` + StaticIP *string `json:"staticIP,omitempty"` +} + +// ReadableProperties is parameters describing a redis instance +type ReadableProperties struct { + ProvisioningState *string `json:"provisioningState,omitempty"` + HostName *string `json:"hostName,omitempty"` + Port *int `json:"port,omitempty"` + SslPort *int `json:"sslPort,omitempty"` + RedisVersion *string `json:"redisVersion,omitempty"` + Sku *Sku `json:"sku,omitempty"` + RedisConfiguration *map[string]*string `json:"redisConfiguration,omitempty"` + EnableNonSslPort *bool `json:"enableNonSslPort,omitempty"` + TenantSettings *map[string]*string `json:"tenantSettings,omitempty"` + ShardCount *int `json:"shardCount,omitempty"` + VirtualNetwork *string `json:"virtualNetwork,omitempty"` + Subnet *string `json:"subnet,omitempty"` + StaticIP *string `json:"staticIP,omitempty"` +} + +// ReadablePropertiesWithAccessKey is properties generated only in response to +// CreateOrUpdate redis operation. +type ReadablePropertiesWithAccessKey struct { + AccessKeys *AccessKeys `json:"accessKeys,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` + HostName *string `json:"hostName,omitempty"` + Port *int `json:"port,omitempty"` + SslPort *int `json:"sslPort,omitempty"` + RedisVersion *string `json:"redisVersion,omitempty"` + Sku *Sku `json:"sku,omitempty"` + RedisConfiguration *map[string]*string `json:"redisConfiguration,omitempty"` + EnableNonSslPort *bool `json:"enableNonSslPort,omitempty"` + TenantSettings *map[string]*string `json:"tenantSettings,omitempty"` + ShardCount *int `json:"shardCount,omitempty"` + VirtualNetwork *string `json:"virtualNetwork,omitempty"` + Subnet *string `json:"subnet,omitempty"` + StaticIP *string `json:"staticIP,omitempty"` +} + +// RegenerateKeyParameters is specifies which redis access keys to reset. +type RegenerateKeyParameters struct { + KeyType KeyType `json:"keyType,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"` +} + +// ResourceType is a single redis item in List or Get Operation. +type ResourceType 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 *ReadableProperties `json:"properties,omitempty"` +} + +// ResourceWithAccessKey is a redis item in CreateOrUpdate Operation response. +type ResourceWithAccessKey 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 *ReadablePropertiesWithAccessKey `json:"properties,omitempty"` +} + +// Sku is sku parameters supplied to the create redis operation. +type Sku struct { + Name SkuName `json:"name,omitempty"` + Family SkuFamily `json:"family,omitempty"` + Capacity *int `json:"capacity,omitempty"` +} + +// SubResource is +type SubResource struct { + ID *string `json:"id,omitempty"` +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/redis/redis.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/redis/redis.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/redis/redis.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/redis/redis.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,535 @@ +package redis + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// Client is the .Net client wrapper for the REST API for Azure Redis Cache +// Management 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)} +} + +// CreateOrUpdate create a redis cache, or replace (overwrite/recreate, with +// potential downtime) an existing cache +// +// resourceGroupName is the name of the resource group. name is the name of +// the redis cache. parameters is parameters supplied to the CreateOrUpdate +// redis operation. +func (client Client) CreateOrUpdate(resourceGroupName string, name string, parameters CreateOrUpdateParameters) (result ResourceWithAccessKey, ae error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, name, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/Client", "CreateOrUpdate", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/Client", "CreateOrUpdate", "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/Client", "CreateOrUpdate", "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client Client) CreateOrUpdatePreparer(resourceGroupName string, name string, parameters CreateOrUpdateParameters) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Cache/Redis/{name}"), + autorest.WithJSON(parameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusCreated, http.StatusOK) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client Client) CreateOrUpdateResponder(resp *http.Response) (result ResourceWithAccessKey, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete deletes a redis cache. This operation takes a while to complete. +// +// resourceGroupName is the name of the resource group. name is the name of +// the redis cache. +func (client Client) Delete(resourceGroupName string, name string) (result autorest.Response, ae error) { + req, err := client.DeletePreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/Client", "Delete", "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "redis/Client", "Delete", "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/Client", "Delete", "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client Client) DeletePreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Cache/Redis/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusNotFound) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNotFound), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get gets a redis cache (resource description). +// +// resourceGroupName is the name of the resource group. name is the name of +// the redis cache. +func (client Client) Get(resourceGroupName string, name string) (result ResourceType, ae error) { + req, err := client.GetPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/Client", "Get", "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/Client", "Get", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/Client", "Get", "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client Client) GetPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Cache/Redis/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client Client) GetResponder(resp *http.Response) (result ResourceType, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List gets all redis caches in the specified subscription. +func (client Client) List() (result ListResult, ae error) { + req, err := client.ListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/Client", "List", "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/Client", "List", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/Client", "List", "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client Client) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Cache/Redis/"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client Client) ListResponder(resp *http.Response) (result ListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.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 ListResult) (result ListResult, ae error) { + req, err := lastResults.ListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/Client", "List", "Failure preparing next results request request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/Client", "List", "Failure sending next results request request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/Client", "List", "Failure responding to next results request request") + } + + return +} + +// ListByResourceGroup gets all redis caches in a resource group. +// +// resourceGroupName is the name of the resource group. +func (client Client) ListByResourceGroup(resourceGroupName string) (result ListResult, ae error) { + req, err := client.ListByResourceGroupPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/Client", "ListByResourceGroup", "Failure preparing request") + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/Client", "ListByResourceGroup", "Failure sending request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/Client", "ListByResourceGroup", "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client Client) ListByResourceGroupPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Cache/Redis/"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client Client) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client Client) ListByResourceGroupResponder(resp *http.Response) (result ListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByResourceGroupNextResults retrieves the next set of results, if any. +func (client Client) ListByResourceGroupNextResults(lastResults ListResult) (result ListResult, ae error) { + req, err := lastResults.ListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/Client", "ListByResourceGroup", "Failure preparing next results request request") + } + if req == nil { + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/Client", "ListByResourceGroup", "Failure sending next results request request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/Client", "ListByResourceGroup", "Failure responding to next results request request") + } + + return +} + +// ListKeys retrieve a redis cache's access keys. This operation requires +// write permission to the cache resource. +// +// resourceGroupName is the name of the resource group. name is the name of +// the redis cache. +func (client Client) ListKeys(resourceGroupName string, name string) (result ListKeysResult, ae error) { + req, err := client.ListKeysPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/Client", "ListKeys", "Failure preparing request") + } + + resp, err := client.ListKeysSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/Client", "ListKeys", "Failure sending request") + } + + result, err = client.ListKeysResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/Client", "ListKeys", "Failure responding to request") + } + + return +} + +// ListKeysPreparer prepares the ListKeys request. +func (client Client) ListKeysPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Cache/Redis/{name}/listKeys"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListKeysSender sends the ListKeys request. The method will close the +// http.Response Body if it receives an error. +func (client Client) ListKeysSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListKeysResponder handles the response to the ListKeys request. The method always +// closes the http.Response Body. +func (client Client) ListKeysResponder(resp *http.Response) (result ListKeysResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// RegenerateKey regenerate redis cache's access keys. This operation requires +// write permission to the cache resource. +// +// resourceGroupName is the name of the resource group. name is the name of +// the redis cache. parameters is specifies which key to reset. +func (client Client) RegenerateKey(resourceGroupName string, name string, parameters RegenerateKeyParameters) (result ListKeysResult, ae error) { + req, err := client.RegenerateKeyPreparer(resourceGroupName, name, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "redis/Client", "RegenerateKey", "Failure preparing request") + } + + resp, err := client.RegenerateKeySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "redis/Client", "RegenerateKey", "Failure sending request") + } + + result, err = client.RegenerateKeyResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "redis/Client", "RegenerateKey", "Failure responding to request") + } + + return +} + +// RegenerateKeyPreparer prepares the RegenerateKey request. +func (client Client) RegenerateKeyPreparer(resourceGroupName string, name string, parameters RegenerateKeyParameters) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Cache/Redis/{name}/regenerateKey"), + autorest.WithJSON(parameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// RegenerateKeySender sends the RegenerateKey request. The method will close the +// http.Response Body if it receives an error. +func (client Client) RegenerateKeySender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// RegenerateKeyResponder handles the response to the RegenerateKey request. The method always +// closes the http.Response Body. +func (client Client) RegenerateKeyResponder(resp *http.Response) (result ListKeysResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/redis/version.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/redis/version.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/redis/version.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/redis/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,43 @@ +package redis + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "fmt" +) + +const ( + major = "0" + minor = "3" + 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;Package arm/%s;API %s" +) + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return fmt.Sprintf(userAgentFormat, Version(), "redis", "2015-08-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 -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/client.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/client.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/client.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -106,7 +106,7 @@ // CheckExistenceSender sends the CheckExistence request. The method will close the // http.Response Body if it receives an error. func (client ManagementClient) CheckExistenceSender(req *http.Request) (*http.Response, error) { - return client.Send(req, http.StatusNoContent, http.StatusNotFound) + return client.Send(req, http.StatusOK, http.StatusNoContent, http.StatusNotFound) } // CheckExistenceResponder handles the response to the CheckExistence request. The method always @@ -115,7 +115,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusNotFound), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusNotFound), autorest.ByClosing()) result.Response = resp return @@ -176,7 +176,7 @@ // CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the // http.Response Body if it receives an error. func (client ManagementClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { - return client.Send(req, http.StatusCreated, http.StatusAccepted, http.StatusOK) + return client.Send(req, http.StatusCreated, http.StatusOK) } // CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always @@ -185,7 +185,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusAccepted, http.StatusOK), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), autorest.ByUnmarshallingJSON(&result), autorest.ByClosing()) result.Response = autorest.Response{Response: resp} @@ -333,7 +333,7 @@ // // filter is the filter to apply on the operation. top is query parameters. If // null is passed returns all resource groups. -func (client ManagementClient) List(filter string, top int) (result ListResult, ae error) { +func (client ManagementClient) List(filter string, top *int) (result ResourceListResult, ae error) { req, err := client.ListPreparer(filter, top) if err != nil { return result, autorest.NewErrorWithError(err, "resources/ManagementClient", "List", "Failure preparing request") @@ -354,16 +354,20 @@ } // ListPreparer prepares the List request. -func (client ManagementClient) ListPreparer(filter string, top int) (*http.Request, error) { +func (client ManagementClient) ListPreparer(filter string, top *int) (*http.Request, error) { pathParameters := map[string]interface{}{ "subscriptionId": url.QueryEscape(client.SubscriptionID), } queryParameters := map[string]interface{}{ - "$filter": filter, - "$top": top, "api-version": APIVersion, } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + if top != nil { + queryParameters["$top"] = top + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), @@ -382,7 +386,7 @@ // ListResponder handles the response to the List request. The method always // closes the http.Response Body. -func (client ManagementClient) ListResponder(resp *http.Response) (result ListResult, err error) { +func (client ManagementClient) ListResponder(resp *http.Response) (result ResourceListResult, err error) { err = autorest.Respond( resp, client.ByInspecting(), @@ -394,8 +398,8 @@ } // ListNextResults retrieves the next set of results, if any. -func (client ManagementClient) ListNextResults(lastResults ListResult) (result ListResult, ae error) { - req, err := lastResults.ListResultPreparer() +func (client ManagementClient) ListNextResults(lastResults ResourceListResult) (result ResourceListResult, ae error) { + req, err := lastResults.ResourceListResultPreparer() if err != nil { return result, autorest.NewErrorWithError(err, "resources/ManagementClient", "List", "Failure preparing next results request request") } @@ -417,7 +421,8 @@ return } -// MoveResources move resources within or across subscriptions. +// MoveResources begin moving resources.To determine whether the operation has +// finished processing the request, call GetLongRunningOperationStatus. // // sourceResourceGroupName is source resource group name. parameters is move // resources' parameters. @@ -465,7 +470,7 @@ // MoveResourcesSender sends the MoveResources request. The method will close the // http.Response Body if it receives an error. func (client ManagementClient) MoveResourcesSender(req *http.Request) (*http.Response, error) { - return client.Send(req, http.StatusAccepted) + return client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusNoContent) } // MoveResourcesResponder handles the response to the MoveResources request. The method always @@ -474,7 +479,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusAccepted), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), autorest.ByClosing()) result.Response = resp return diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/deploymentoperations.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/deploymentoperations.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/deploymentoperations.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/deploymentoperations.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -113,7 +113,7 @@ // 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 int) (result DeploymentOperationsListResult, ae error) { +func (client DeploymentOperationsClient) List(resourceGroupName string, deploymentName string, top *int) (result DeploymentOperationsListResult, ae error) { req, err := client.ListPreparer(resourceGroupName, deploymentName, top) if err != nil { return result, autorest.NewErrorWithError(err, "resources/DeploymentOperationsClient", "List", "Failure preparing request") @@ -134,7 +134,7 @@ } // ListPreparer prepares the List request. -func (client DeploymentOperationsClient) ListPreparer(resourceGroupName string, deploymentName string, top int) (*http.Request, error) { +func (client DeploymentOperationsClient) ListPreparer(resourceGroupName string, deploymentName string, top *int) (*http.Request, error) { pathParameters := map[string]interface{}{ "deploymentName": url.QueryEscape(deploymentName), "resourceGroupName": url.QueryEscape(resourceGroupName), @@ -142,9 +142,11 @@ } queryParameters := map[string]interface{}{ - "$top": top, "api-version": APIVersion, } + if top != nil { + queryParameters["$top"] = top + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/deployments.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/deployments.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/deployments.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/deployments.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -89,7 +89,7 @@ // 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 client.Send(req, http.StatusNoContent) + return client.Send(req, http.StatusOK, http.StatusNoContent) } // CancelResponder handles the response to the Cancel request. The method always @@ -98,7 +98,70 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusNoContent), + autorest.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, ae error) { + req, err := client.CheckExistencePreparer(resourceGroupName, deploymentName) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources/DeploymentsClient", "CheckExistence", "Failure preparing request") + } + + resp, err := client.CheckExistenceSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources/DeploymentsClient", "CheckExistence", "Failure sending request") + } + + result, err = client.CheckExistenceResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "resources/DeploymentsClient", "CheckExistence", "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": url.QueryEscape(deploymentName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsHead(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/deployments/{deploymentName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK, http.StatusNoContent, http.StatusNotFound) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusNotFound), autorest.ByClosing()) result.Response = resp return @@ -170,6 +233,70 @@ return } +// Delete begin deleting deployment.To determine whether the operation has +// finished processing the request, call GetLongRunningOperationStatus. +// +// 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) (result autorest.Response, ae error) { + req, err := client.DeletePreparer(resourceGroupName, deploymentName) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources/DeploymentsClient", "Delete", "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources/DeploymentsClient", "Delete", "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "resources/DeploymentsClient", "Delete", "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client DeploymentsClient) DeletePreparer(resourceGroupName string, deploymentName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "deploymentName": url.QueryEscape(deploymentName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/deployments/{deploymentName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusNoContent) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + // Get get a deployment. // // resourceGroupName is the name of the resource group to get. The name is @@ -239,7 +366,7 @@ // 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 int) (result DeploymentListResult, ae error) { +func (client DeploymentsClient) List(resourceGroupName string, filter string, top *int) (result DeploymentListResult, ae error) { req, err := client.ListPreparer(resourceGroupName, filter, top) if err != nil { return result, autorest.NewErrorWithError(err, "resources/DeploymentsClient", "List", "Failure preparing request") @@ -260,17 +387,21 @@ } // ListPreparer prepares the List request. -func (client DeploymentsClient) ListPreparer(resourceGroupName string, filter string, top int) (*http.Request, error) { +func (client DeploymentsClient) ListPreparer(resourceGroupName string, filter string, top *int) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": url.QueryEscape(resourceGroupName), "subscriptionId": url.QueryEscape(client.SubscriptionID), } queryParameters := map[string]interface{}{ - "$filter": filter, - "$top": top, "api-version": APIVersion, } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + if top != nil { + queryParameters["$top"] = top + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/groups.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/groups.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/groups.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/groups.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -86,7 +86,7 @@ // 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 client.Send(req, http.StatusNoContent, http.StatusNotFound) + return client.Send(req, http.StatusOK, http.StatusNoContent, http.StatusNotFound) } // CheckExistenceResponder handles the response to the CheckExistence request. The method always @@ -95,7 +95,7 @@ err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusNoContent, http.StatusNotFound), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusNotFound), autorest.ByClosing()) result.Response = resp return @@ -106,7 +106,7 @@ // 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 Group) (result Group, ae error) { +func (client GroupsClient) CreateOrUpdate(resourceGroupName string, parameters ResourceGroup) (result ResourceGroup, ae error) { req, err := client.CreateOrUpdatePreparer(resourceGroupName, parameters) if err != nil { return result, autorest.NewErrorWithError(err, "resources/GroupsClient", "CreateOrUpdate", "Failure preparing request") @@ -127,7 +127,7 @@ } // CreateOrUpdatePreparer prepares the CreateOrUpdate request. -func (client GroupsClient) CreateOrUpdatePreparer(resourceGroupName string, parameters Group) (*http.Request, error) { +func (client GroupsClient) CreateOrUpdatePreparer(resourceGroupName string, parameters ResourceGroup) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": url.QueryEscape(resourceGroupName), "subscriptionId": url.QueryEscape(client.SubscriptionID), @@ -150,16 +150,16 @@ // 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 client.Send(req, http.StatusCreated, http.StatusOK, http.StatusAccepted) + return client.Send(req, http.StatusCreated, http.StatusOK) } // CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always // closes the http.Response Body. -func (client GroupsClient) CreateOrUpdateResponder(resp *http.Response) (result Group, err error) { +func (client GroupsClient) CreateOrUpdateResponder(resp *http.Response) (result ResourceGroup, err error) { err = autorest.Respond( resp, client.ByInspecting(), - autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK, http.StatusAccepted), + autorest.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), autorest.ByUnmarshallingJSON(&result), autorest.ByClosing()) result.Response = autorest.Response{Response: resp} @@ -233,7 +233,7 @@ // // resourceGroupName is the name of the resource group to get. The name is // case insensitive. -func (client GroupsClient) Get(resourceGroupName string) (result Group, ae error) { +func (client GroupsClient) Get(resourceGroupName string) (result ResourceGroup, ae error) { req, err := client.GetPreparer(resourceGroupName) if err != nil { return result, autorest.NewErrorWithError(err, "resources/GroupsClient", "Get", "Failure preparing request") @@ -281,7 +281,7 @@ // GetResponder handles the response to the Get request. The method always // closes the http.Response Body. -func (client GroupsClient) GetResponder(resp *http.Response) (result Group, err error) { +func (client GroupsClient) GetResponder(resp *http.Response) (result ResourceGroup, err error) { err = autorest.Respond( resp, client.ByInspecting(), @@ -296,7 +296,7 @@ // // 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 int) (result GroupListResult, ae error) { +func (client GroupsClient) List(filter string, top *int) (result ResourceGroupListResult, ae error) { req, err := client.ListPreparer(filter, top) if err != nil { return result, autorest.NewErrorWithError(err, "resources/GroupsClient", "List", "Failure preparing request") @@ -317,16 +317,20 @@ } // ListPreparer prepares the List request. -func (client GroupsClient) ListPreparer(filter string, top int) (*http.Request, error) { +func (client GroupsClient) ListPreparer(filter string, top *int) (*http.Request, error) { pathParameters := map[string]interface{}{ "subscriptionId": url.QueryEscape(client.SubscriptionID), } queryParameters := map[string]interface{}{ - "$filter": filter, - "$top": top, "api-version": APIVersion, } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + if top != nil { + queryParameters["$top"] = top + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), @@ -345,7 +349,7 @@ // ListResponder handles the response to the List request. The method always // closes the http.Response Body. -func (client GroupsClient) ListResponder(resp *http.Response) (result GroupListResult, err error) { +func (client GroupsClient) ListResponder(resp *http.Response) (result ResourceGroupListResult, err error) { err = autorest.Respond( resp, client.ByInspecting(), @@ -357,8 +361,8 @@ } // ListNextResults retrieves the next set of results, if any. -func (client GroupsClient) ListNextResults(lastResults GroupListResult) (result GroupListResult, ae error) { - req, err := lastResults.GroupListResultPreparer() +func (client GroupsClient) ListNextResults(lastResults ResourceGroupListResult) (result ResourceGroupListResult, ae error) { + req, err := lastResults.ResourceGroupListResultPreparer() if err != nil { return result, autorest.NewErrorWithError(err, "resources/GroupsClient", "List", "Failure preparing next results request request") } @@ -385,7 +389,7 @@ // resourceGroupName is query parameters. If null is passed returns all // 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) ListResources(resourceGroupName string, filter string, top int) (result ListResult, ae error) { +func (client GroupsClient) ListResources(resourceGroupName string, filter string, top *int) (result ResourceListResult, ae error) { req, err := client.ListResourcesPreparer(resourceGroupName, filter, top) if err != nil { return result, autorest.NewErrorWithError(err, "resources/GroupsClient", "ListResources", "Failure preparing request") @@ -406,17 +410,21 @@ } // ListResourcesPreparer prepares the ListResources request. -func (client GroupsClient) ListResourcesPreparer(resourceGroupName string, filter string, top int) (*http.Request, error) { +func (client GroupsClient) ListResourcesPreparer(resourceGroupName string, filter string, top *int) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": url.QueryEscape(resourceGroupName), "subscriptionId": url.QueryEscape(client.SubscriptionID), } queryParameters := map[string]interface{}{ - "$filter": filter, - "$top": top, "api-version": APIVersion, } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + if top != nil { + queryParameters["$top"] = top + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), @@ -435,7 +443,7 @@ // ListResourcesResponder handles the response to the ListResources request. The method always // closes the http.Response Body. -func (client GroupsClient) ListResourcesResponder(resp *http.Response) (result ListResult, err error) { +func (client GroupsClient) ListResourcesResponder(resp *http.Response) (result ResourceListResult, err error) { err = autorest.Respond( resp, client.ByInspecting(), @@ -447,8 +455,8 @@ } // ListResourcesNextResults retrieves the next set of results, if any. -func (client GroupsClient) ListResourcesNextResults(lastResults ListResult) (result ListResult, ae error) { - req, err := lastResults.ListResultPreparer() +func (client GroupsClient) ListResourcesNextResults(lastResults ResourceListResult) (result ResourceListResult, ae error) { + req, err := lastResults.ResourceListResultPreparer() if err != nil { return result, autorest.NewErrorWithError(err, "resources/GroupsClient", "ListResources", "Failure preparing next results request request") } @@ -478,7 +486,7 @@ // 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 Group) (result Group, ae error) { +func (client GroupsClient) Patch(resourceGroupName string, parameters ResourceGroup) (result ResourceGroup, ae error) { req, err := client.PatchPreparer(resourceGroupName, parameters) if err != nil { return result, autorest.NewErrorWithError(err, "resources/GroupsClient", "Patch", "Failure preparing request") @@ -499,7 +507,7 @@ } // PatchPreparer prepares the Patch request. -func (client GroupsClient) PatchPreparer(resourceGroupName string, parameters Group) (*http.Request, error) { +func (client GroupsClient) PatchPreparer(resourceGroupName string, parameters ResourceGroup) (*http.Request, error) { pathParameters := map[string]interface{}{ "resourceGroupName": url.QueryEscape(resourceGroupName), "subscriptionId": url.QueryEscape(client.SubscriptionID), @@ -527,7 +535,7 @@ // PatchResponder handles the response to the Patch request. The method always // closes the http.Response Body. -func (client GroupsClient) PatchResponder(resp *http.Response) (result Group, err error) { +func (client GroupsClient) PatchResponder(resp *http.Response) (result ResourceGroup, err error) { err = autorest.Respond( resp, client.ByInspecting(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/models.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/models.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/models.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/models.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -29,6 +29,8 @@ 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" ) @@ -95,11 +97,11 @@ // DeploymentOperationProperties is deployment operation properties. type DeploymentOperationProperties struct { - ProvisioningState *string `json:"provisioningState,omitempty"` - Timestamp *date.Time `json:"timestamp,omitempty"` - StatusCode *string `json:"statusCode,omitempty"` - StatusMessage *map[string]*string `json:"statusMessage,omitempty"` - TargetResource *TargetResource `json:"targetResource,omitempty"` + ProvisioningState *string `json:"provisioningState,omitempty"` + Timestamp *date.Time `json:"timestamp,omitempty"` + StatusCode *string `json:"statusCode,omitempty"` + StatusMessage *map[string]interface{} `json:"statusMessage,omitempty"` + TargetResource *TargetResource `json:"targetResource,omitempty"` } // DeploymentOperationsListResult is list of deployment operations. @@ -123,47 +125,47 @@ // DeploymentProperties is deployment properties. type DeploymentProperties struct { - Template *map[string]*string `json:"template,omitempty"` - TemplateLink *TemplateLink `json:"templateLink,omitempty"` - Parameters *map[string]*string `json:"parameters,omitempty"` - ParametersLink *ParametersLink `json:"parametersLink,omitempty"` - Mode DeploymentMode `json:"mode,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"` } // 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]*string `json:"outputs,omitempty"` - Providers *[]Provider `json:"providers,omitempty"` - Dependencies *[]Dependency `json:"dependencies,omitempty"` - Template *map[string]*string `json:"template,omitempty"` - TemplateLink *TemplateLink `json:"templateLink,omitempty"` - Parameters *map[string]*string `json:"parameters,omitempty"` - ParametersLink *ParametersLink `json:"parametersLink,omitempty"` - Mode DeploymentMode `json:"mode,omitempty"` + 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"` } // DeploymentValidateResult is information from validate template deployment // response. type DeploymentValidateResult struct { autorest.Response `json:"-"` - Error *ManagementErrorWithDetails `json:"error,omitempty"` - Properties *DeploymentPropertiesExtended `json:"properties,omitempty"` + Error *ResourceManagementErrorWithDetails `json:"error,omitempty"` + Properties *DeploymentPropertiesExtended `json:"properties,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]*string `json:"properties,omitempty"` + 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"` } // GenericResourceFilter is resource filter. @@ -173,86 +175,21 @@ Tagvalue *string `json:"tagvalue,omitempty"` } -// Group is resource group information. -type Group struct { - autorest.Response `json:"-"` - ID *string `json:"id,omitempty"` - Name *string `json:"name,omitempty"` - Properties *GroupProperties `json:"properties,omitempty"` - Location *string `json:"location,omitempty"` - Tags *map[string]*string `json:"tags,omitempty"` -} - -// GroupFilter is resource group filter. -type GroupFilter struct { - TagName *string `json:"tagName,omitempty"` - TagValue *string `json:"tagValue,omitempty"` -} - -// GroupListResult is list of resource groups. -type GroupListResult struct { - autorest.Response `json:"-"` - Value *[]Group `json:"value,omitempty"` - NextLink *string `json:"nextLink,omitempty"` -} - -// GroupListResultPreparer prepares a request to retrieve the next set of results. It returns -// nil if no more results exist. -func (client GroupListResult) GroupListResultPreparer() (*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))) -} - -// GroupProperties is the resource group properties. -type GroupProperties struct { - ProvisioningState *string `json:"provisioningState,omitempty"` -} - -// ListResult is list of resource groups. -type ListResult struct { - autorest.Response `json:"-"` - Value *[]GenericResource `json:"value,omitempty"` - NextLink *string `json:"nextLink,omitempty"` -} - -// ListResultPreparer prepares a request to retrieve the next set of results. It returns -// nil if no more results exist. -func (client ListResult) ListResultPreparer() (*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))) -} - -// ManagementError is -type ManagementError struct { - Code *string `json:"code,omitempty"` - Message *string `json:"message,omitempty"` - Target *string `json:"target,omitempty"` -} - -// ManagementErrorWithDetails is -type ManagementErrorWithDetails struct { - Details *[]ManagementError `json:"details,omitempty"` - Code *string `json:"code,omitempty"` - Message *string `json:"message,omitempty"` - Target *string `json:"target,omitempty"` -} - // MoveInfo is parameters of move resources. type MoveInfo struct { Resources *[]string `json:"resources,omitempty"` TargetResourceGroup *string `json:"targetResourceGroup,omitempty"` } +// Operation is operation +type Operation struct { + Name *string `json:"name,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + Description *string `json:"description,omitempty"` + Origin *string `json:"origin,omitempty"` + Properties *map[string]interface{} `json:"properties,omitempty"` +} + // ParametersLink is entity representing the reference to the deployment // paramaters. type ParametersLink struct { @@ -296,26 +233,21 @@ autorest.WithBaseURL(to.String(client.NextLink))) } -// ProviderOperationDefinition is resource provider operation information. -type ProviderOperationDefinition struct { - Name *string `json:"name,omitempty"` - Display *ProviderOperationDisplayProperties `json:"display,omitempty"` -} - -// ProviderOperationDetailListResult is list of resource provider operations. -type ProviderOperationDetailListResult struct { +// ProviderOperationsMetadata is provider Operations metadata +type ProviderOperationsMetadata struct { autorest.Response `json:"-"` - Value *[]ProviderOperationDefinition `json:"value,omitempty"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + ResourceTypes *[]ResourceType `json:"resourceTypes,omitempty"` + Operations *[]Operation `json:"operations,omitempty"` } -// ProviderOperationDisplayProperties is resource provider operation's display -// properties. -type ProviderOperationDisplayProperties 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"` +// ProviderOperationsMetadataListResult is provider operations metadata list +type ProviderOperationsMetadataListResult struct { + autorest.Response `json:"-"` + Value *[]ProviderOperationsMetadata `json:"value,omitempty"` } // ProviderResourceType is resource type managed by the resource provider. @@ -335,6 +267,111 @@ 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"` +} + +// 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))) +} + +// ResourceManagementError is +type ResourceManagementError struct { + Code *string `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Target *string `json:"target,omitempty"` +} + +// ResourceManagementErrorWithDetails is +type ResourceManagementErrorWithDetails struct { + Details *[]ResourceManagementError `json:"details,omitempty"` + Code *string `json:"code,omitempty"` + Message *string `json:"message,omitempty"` + Target *string `json:"target,omitempty"` +} + +// ResourceProviderOperationDefinition is resource provider operation +// information. +type ResourceProviderOperationDefinition struct { + Name *string `json:"name,omitempty"` + Display *ResourceProviderOperationDisplayProperties `json:"display,omitempty"` +} + +// ResourceProviderOperationDetailListResult is list of resource provider +// operations. +type ResourceProviderOperationDetailListResult struct { + autorest.Response `json:"-"` + Value *[]ResourceProviderOperationDefinition `json:"value,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"` +} + +// ResourceType is resource Type +type ResourceType struct { + Name *string `json:"name,omitempty"` + DisplayName *string `json:"displayName,omitempty"` + Operations *[]Operation `json:"operations,omitempty"` +} + // SubResource is type SubResource struct { ID *string `json:"id,omitempty"` diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/provideroperationdetails.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/provideroperationdetails.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/provideroperationdetails.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/provideroperationdetails.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -45,7 +45,7 @@ // List gets a list of resource providers. // // resourceProviderNamespace is resource identity. -func (client ProviderOperationDetailsClient) List(resourceProviderNamespace string, apiVersion string) (result ProviderOperationDetailListResult, ae error) { +func (client ProviderOperationDetailsClient) List(resourceProviderNamespace string, apiVersion string) (result ResourceProviderOperationDetailListResult, ae error) { req, err := client.ListPreparer(resourceProviderNamespace, apiVersion) if err != nil { return result, autorest.NewErrorWithError(err, "resources/ProviderOperationDetailsClient", "List", "Failure preparing request") @@ -93,7 +93,7 @@ // ListResponder handles the response to the List request. The method always // closes the http.Response Body. -func (client ProviderOperationDetailsClient) ListResponder(resp *http.Response) (result ProviderOperationDetailListResult, err error) { +func (client ProviderOperationDetailsClient) ListResponder(resp *http.Response) (result ResourceProviderOperationDetailListResult, err error) { err = autorest.Respond( resp, client.ByInspecting(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/provideroperationsmetadataoperations.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/provideroperationsmetadataoperations.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/provideroperationsmetadataoperations.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/provideroperationsmetadataoperations.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,171 @@ +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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// ProviderOperationsMetadataOperationsClient is the client for the +// ProviderOperationsMetadataOperations methods of the Resources service. +type ProviderOperationsMetadataOperationsClient struct { + ManagementClient +} + +// NewProviderOperationsMetadataOperationsClient creates an instance of the +// ProviderOperationsMetadataOperationsClient client. +func NewProviderOperationsMetadataOperationsClient(subscriptionID string) ProviderOperationsMetadataOperationsClient { + return NewProviderOperationsMetadataOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewProviderOperationsMetadataOperationsClientWithBaseURI creates an +// instance of the ProviderOperationsMetadataOperationsClient client. +func NewProviderOperationsMetadataOperationsClientWithBaseURI(baseURI string, subscriptionID string) ProviderOperationsMetadataOperationsClient { + return ProviderOperationsMetadataOperationsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// Get gets provider operations metadata +// +// resourceProviderNamespace is namespace of the resource provider. +func (client ProviderOperationsMetadataOperationsClient) Get(resourceProviderNamespace string, apiVersion string, expand string) (result ProviderOperationsMetadata, ae error) { + req, err := client.GetPreparer(resourceProviderNamespace, apiVersion, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources/ProviderOperationsMetadataOperationsClient", "Get", "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources/ProviderOperationsMetadataOperationsClient", "Get", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "resources/ProviderOperationsMetadataOperationsClient", "Get", "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ProviderOperationsMetadataOperationsClient) GetPreparer(resourceProviderNamespace string, apiVersion string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceProviderNamespace": url.QueryEscape(resourceProviderNamespace), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(expand) > 0 { + queryParameters["$expand"] = expand + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/providers/Microsoft.Authorization/providerOperations/{resourceProviderNamespace}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client ProviderOperationsMetadataOperationsClient) GetSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client ProviderOperationsMetadataOperationsClient) GetResponder(resp *http.Response) (result ProviderOperationsMetadata, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List gets provider operations metadata list +// +func (client ProviderOperationsMetadataOperationsClient) List(apiVersion string, expand string) (result ProviderOperationsMetadataListResult, ae error) { + req, err := client.ListPreparer(apiVersion, expand) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources/ProviderOperationsMetadataOperationsClient", "List", "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "resources/ProviderOperationsMetadataOperationsClient", "List", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "resources/ProviderOperationsMetadataOperationsClient", "List", "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ProviderOperationsMetadataOperationsClient) ListPreparer(apiVersion string, expand string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(expand) > 0 { + queryParameters["$expand"] = expand + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/providers/Microsoft.Authorization/providerOperations"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ProviderOperationsMetadataOperationsClient) ListSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ProviderOperationsMetadataOperationsClient) ListResponder(resp *http.Response) (result ProviderOperationsMetadataListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/providers.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/providers.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/providers.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/providers.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -106,7 +106,7 @@ // List gets a list of resource providers. // // top is query parameters. If null is passed returns all deployments. -func (client ProvidersClient) List(top int) (result ProviderListResult, ae error) { +func (client ProvidersClient) List(top *int) (result ProviderListResult, ae error) { req, err := client.ListPreparer(top) if err != nil { return result, autorest.NewErrorWithError(err, "resources/ProvidersClient", "List", "Failure preparing request") @@ -127,15 +127,17 @@ } // ListPreparer prepares the List request. -func (client ProvidersClient) ListPreparer(top int) (*http.Request, error) { +func (client ProvidersClient) ListPreparer(top *int) (*http.Request, error) { pathParameters := map[string]interface{}{ "subscriptionId": url.QueryEscape(client.SubscriptionID), } queryParameters := map[string]interface{}{ - "$top": top, "api-version": APIVersion, } + if top != nil { + queryParameters["$top"] = top + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/resources.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/resources.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/resources.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/resources.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,472 @@ +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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// 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, apiVersion string) (result autorest.Response, ae error) { + req, err := client.CheckExistencePreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources/Client", "CheckExistence", "Failure preparing request") + } + + resp, err := client.CheckExistenceSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources/Client", "CheckExistence", "Failure sending request") + } + + result, err = client.CheckExistenceResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "resources/Client", "CheckExistence", "Failure responding to request") + } + + return +} + +// CheckExistencePreparer prepares the CheckExistence request. +func (client Client) CheckExistencePreparer(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "parentResourcePath": parentResourcePath, + "resourceGroupName": url.QueryEscape(resourceGroupName), + "resourceName": url.QueryEscape(resourceName), + "resourceProviderNamespace": url.QueryEscape(resourceProviderNamespace), + "resourceType": resourceType, + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsHead(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK, http.StatusNoContent, http.StatusNotFound) +} + +// 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(), + autorest.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, apiVersion string, parameters GenericResource) (result GenericResource, ae error) { + req, err := client.CreateOrUpdatePreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources/Client", "CreateOrUpdate", "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", "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "resources/Client", "CreateOrUpdate", "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client Client) CreateOrUpdatePreparer(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string, parameters GenericResource) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "parentResourcePath": parentResourcePath, + "resourceGroupName": url.QueryEscape(resourceGroupName), + "resourceName": url.QueryEscape(resourceName), + "resourceProviderNamespace": url.QueryEscape(resourceProviderNamespace), + "resourceType": resourceType, + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}"), + autorest.WithJSON(parameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusCreated, http.StatusOK) +} + +// 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(), + autorest.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, apiVersion string) (result autorest.Response, ae error) { + req, err := client.DeletePreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources/Client", "Delete", "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources/Client", "Delete", "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "resources/Client", "Delete", "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client Client) DeletePreparer(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "parentResourcePath": parentResourcePath, + "resourceGroupName": url.QueryEscape(resourceGroupName), + "resourceName": url.QueryEscape(resourceName), + "resourceProviderNamespace": url.QueryEscape(resourceProviderNamespace), + "resourceType": resourceType, + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK, http.StatusNoContent, http.StatusAccepted) +} + +// 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(), + autorest.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, apiVersion string) (result GenericResource, ae error) { + req, err := client.GetPreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, apiVersion) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources/Client", "Get", "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", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "resources/Client", "Get", "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client Client) GetPreparer(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, apiVersion string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "parentResourcePath": parentResourcePath, + "resourceGroupName": url.QueryEscape(resourceGroupName), + "resourceName": url.QueryEscape(resourceName), + "resourceProviderNamespace": url.QueryEscape(resourceProviderNamespace), + "resourceType": resourceType, + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK, http.StatusNoContent) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + 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. top is query parameters. If +// null is passed returns all resource groups. +func (client Client) List(filter string, top *int) (result ResourceListResult, ae error) { + req, err := client.ListPreparer(filter, top) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources/Client", "List", "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", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "resources/Client", "List", "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client Client) ListPreparer(filter string, top *int) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + if top != nil { + queryParameters["$top"] = top + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resources"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := lastResults.ResourceListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "resources/Client", "List", "Failure preparing next results request 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", "Failure sending next results request request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "resources/Client", "List", "Failure responding to next results request request") + } + + return +} + +// MoveResources begin moving resources.To determine whether the operation has +// finished processing the request, call GetLongRunningOperationStatus. +// +// sourceResourceGroupName is source resource group name. parameters is move +// resources' parameters. +func (client Client) MoveResources(sourceResourceGroupName string, parameters MoveInfo) (result autorest.Response, ae error) { + req, err := client.MoveResourcesPreparer(sourceResourceGroupName, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "resources/Client", "MoveResources", "Failure preparing request") + } + + resp, err := client.MoveResourcesSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "resources/Client", "MoveResources", "Failure sending request") + } + + result, err = client.MoveResourcesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "resources/Client", "MoveResources", "Failure responding to request") + } + + return +} + +// MoveResourcesPreparer prepares the MoveResources request. +func (client Client) MoveResourcesPreparer(sourceResourceGroupName string, parameters MoveInfo) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "sourceResourceGroupName": url.QueryEscape(sourceResourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{sourceResourceGroupName}/moveResources"), + autorest.WithJSON(parameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusNoContent) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/tags.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/tags.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/tags.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/tags.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/version.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/version.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/resources/version.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/resources/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,8 @@ const ( major = "0" - minor = "1" - patch = "1" + minor = "3" + patch = "0" // Always begin a "tag" with a dash (as per http://semver.org) tag = "-beta" semVerFormat = "%s.%s.%s%s" diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/client.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/client.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/client.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/jobcollections.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/jobcollections.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/jobcollections.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/jobcollections.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/jobs.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/jobs.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/jobs.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/jobs.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -240,7 +240,7 @@ // collection name. top is the number of jobs to request, in the of range // [1..100]. skip is the (0-based) index of the job history list from which // to begin requesting entries. -func (client JobsClient) List(resourceGroupName string, jobCollectionName string, top int, skip int) (result JobListResult, ae error) { +func (client JobsClient) List(resourceGroupName string, jobCollectionName string, top *int, skip *int) (result JobListResult, ae error) { req, err := client.ListPreparer(resourceGroupName, jobCollectionName, top, skip) if err != nil { return result, autorest.NewErrorWithError(err, "scheduler/JobsClient", "List", "Failure preparing request") @@ -261,7 +261,7 @@ } // ListPreparer prepares the List request. -func (client JobsClient) ListPreparer(resourceGroupName string, jobCollectionName string, top int, skip int) (*http.Request, error) { +func (client JobsClient) ListPreparer(resourceGroupName string, jobCollectionName string, top *int, skip *int) (*http.Request, error) { pathParameters := map[string]interface{}{ "jobCollectionName": url.QueryEscape(jobCollectionName), "resourceGroupName": url.QueryEscape(resourceGroupName), @@ -269,10 +269,14 @@ } queryParameters := map[string]interface{}{ - "$skip": skip, - "$top": top, "api-version": APIVersion, } + if top != nil { + queryParameters["$top"] = top + } + if skip != nil { + queryParameters["$skip"] = skip + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), @@ -332,7 +336,7 @@ // collection name. jobName is the job name. top is the number of job history // to request, in the of range [1..100]. skip is the (0-based) index of the // job history list from which to begin requesting entries. -func (client JobsClient) ListJobHistory(resourceGroupName string, jobCollectionName string, jobName string, top int, skip int) (result JobHistoryListResult, ae error) { +func (client JobsClient) ListJobHistory(resourceGroupName string, jobCollectionName string, jobName string, top *int, skip *int) (result JobHistoryListResult, ae error) { req, err := client.ListJobHistoryPreparer(resourceGroupName, jobCollectionName, jobName, top, skip) if err != nil { return result, autorest.NewErrorWithError(err, "scheduler/JobsClient", "ListJobHistory", "Failure preparing request") @@ -353,7 +357,7 @@ } // ListJobHistoryPreparer prepares the ListJobHistory request. -func (client JobsClient) ListJobHistoryPreparer(resourceGroupName string, jobCollectionName string, jobName string, top int, skip int) (*http.Request, error) { +func (client JobsClient) ListJobHistoryPreparer(resourceGroupName string, jobCollectionName string, jobName string, top *int, skip *int) (*http.Request, error) { pathParameters := map[string]interface{}{ "jobCollectionName": url.QueryEscape(jobCollectionName), "jobName": url.QueryEscape(jobName), @@ -362,10 +366,14 @@ } queryParameters := map[string]interface{}{ - "$skip": skip, - "$top": top, "api-version": APIVersion, } + if top != nil { + queryParameters["$top"] = top + } + if skip != nil { + queryParameters["$skip"] = skip + } return autorest.Prepare(&http.Request{}, autorest.AsJSON(), diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/models.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/models.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/models.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/models.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -29,24 +29,20 @@ type DayOfWeek string const ( - // DayOfWeekFriday specifies the day of week friday state for day of week. - DayOfWeekFriday DayOfWeek = "Friday" - // DayOfWeekMonday specifies the day of week monday state for day of week. - DayOfWeekMonday DayOfWeek = "Monday" - // DayOfWeekSaturday specifies the day of week saturday state for day of - // week. - DayOfWeekSaturday DayOfWeek = "Saturday" - // DayOfWeekSunday specifies the day of week sunday state for day of week. - DayOfWeekSunday DayOfWeek = "Sunday" - // DayOfWeekThursday specifies the day of week thursday state for day of - // week. - DayOfWeekThursday DayOfWeek = "Thursday" - // DayOfWeekTuesday specifies the day of week tuesday state for day of - // week. - DayOfWeekTuesday DayOfWeek = "Tuesday" - // DayOfWeekWednesday specifies the day of week wednesday state for day of - // week. - DayOfWeekWednesday DayOfWeek = "Wednesday" + // Friday specifies the friday state for day of week. + Friday DayOfWeek = "Friday" + // Monday specifies the monday state for day of week. + Monday DayOfWeek = "Monday" + // Saturday specifies the saturday state for day of week. + Saturday DayOfWeek = "Saturday" + // Sunday specifies the sunday state for day of week. + Sunday DayOfWeek = "Sunday" + // Thursday specifies the thursday state for day of week. + Thursday DayOfWeek = "Thursday" + // Tuesday specifies the tuesday state for day of week. + Tuesday DayOfWeek = "Tuesday" + // Wednesday specifies the wednesday state for day of week. + Wednesday DayOfWeek = "Wednesday" ) // HTTPAuthenticationType enumerates the values for http authentication type. @@ -74,6 +70,12 @@ HTTP JobActionType = "Http" // HTTPS specifies the https state for job action type. HTTPS JobActionType = "Https" + // ServiceBusQueue specifies the service bus queue state for job action + // type. + ServiceBusQueue JobActionType = "ServiceBusQueue" + // ServiceBusTopic specifies the service bus topic state for job action + // type. + ServiceBusTopic JobActionType = "ServiceBusTopic" // StorageQueue specifies the storage queue state for job action type. StorageQueue JobActionType = "StorageQueue" ) @@ -82,39 +84,31 @@ type JobCollectionState string const ( - // JobCollectionStateDeleted specifies the job collection state deleted - // state for job collection state. - JobCollectionStateDeleted JobCollectionState = "Deleted" - // JobCollectionStateDisabled specifies the job collection state disabled - // state for job collection state. - JobCollectionStateDisabled JobCollectionState = "Disabled" - // JobCollectionStateEnabled specifies the job collection state enabled - // state for job collection state. - JobCollectionStateEnabled JobCollectionState = "Enabled" - // JobCollectionStateSuspended specifies the job collection state - // suspended state for job collection state. - JobCollectionStateSuspended JobCollectionState = "Suspended" + // Deleted specifies the deleted state for job collection state. + Deleted JobCollectionState = "Deleted" + // Disabled specifies the disabled state for job collection state. + Disabled JobCollectionState = "Disabled" + // Enabled specifies the enabled state for job collection state. + Enabled JobCollectionState = "Enabled" + // Suspended specifies the suspended state for job collection state. + Suspended JobCollectionState = "Suspended" ) // JobExecutionStatus enumerates the values for job execution status. type JobExecutionStatus string const ( - // JobExecutionStatusCallbackNotFound specifies the job execution status - // callback not found state for job execution status. - JobExecutionStatusCallbackNotFound JobExecutionStatus = "CallbackNotFound" - // JobExecutionStatusCancelled specifies the job execution status - // cancelled state for job execution status. - JobExecutionStatusCancelled JobExecutionStatus = "Cancelled" - // JobExecutionStatusCompleted specifies the job execution status - // completed state for job execution status. - JobExecutionStatusCompleted JobExecutionStatus = "Completed" - // JobExecutionStatusFailed specifies the job execution status failed - // state for job execution status. - JobExecutionStatusFailed JobExecutionStatus = "Failed" - // JobExecutionStatusPostponed specifies the job execution status - // postponed state for job execution status. - JobExecutionStatusPostponed JobExecutionStatus = "Postponed" + // CallbackNotFound specifies the callback not found state for job + // execution status. + CallbackNotFound JobExecutionStatus = "CallbackNotFound" + // Cancelled specifies the cancelled state for job execution status. + Cancelled JobExecutionStatus = "Cancelled" + // Completed specifies the completed state for job execution status. + Completed JobExecutionStatus = "Completed" + // Failed specifies the failed state for job execution status. + Failed JobExecutionStatus = "Failed" + // Postponed specifies the postponed state for job execution status. + Postponed JobExecutionStatus = "Postponed" ) // JobHistoryActionName enumerates the values for job history action name. @@ -195,6 +189,37 @@ None RetryType = "None" ) +// ServiceBusAuthenticationType enumerates the values for service bus +// authentication type. +type ServiceBusAuthenticationType string + +const ( + // ServiceBusAuthenticationTypeNotSpecified specifies the service bus + // authentication type not specified state for service bus authentication + // type. + ServiceBusAuthenticationTypeNotSpecified ServiceBusAuthenticationType = "NotSpecified" + // ServiceBusAuthenticationTypeSharedAccessKey specifies the service bus + // authentication type shared access key state for service bus + // authentication type. + ServiceBusAuthenticationTypeSharedAccessKey ServiceBusAuthenticationType = "SharedAccessKey" +) + +// ServiceBusTransportType enumerates the values for service bus transport +// type. +type ServiceBusTransportType string + +const ( + // ServiceBusTransportTypeAMQP specifies the service bus transport type + // amqp state for service bus transport type. + ServiceBusTransportTypeAMQP ServiceBusTransportType = "AMQP" + // ServiceBusTransportTypeNetMessaging specifies the service bus transport + // type net messaging state for service bus transport type. + ServiceBusTransportTypeNetMessaging ServiceBusTransportType = "NetMessaging" + // ServiceBusTransportTypeNotSpecified specifies the service bus transport + // type not specified state for service bus transport type. + ServiceBusTransportTypeNotSpecified ServiceBusTransportType = "NotSpecified" +) + // SkuDefinition enumerates the values for sku definition. type SkuDefinition string @@ -240,11 +265,13 @@ // JobAction is type JobAction struct { - Type JobActionType `json:"type,omitempty"` - Request *HTTPRequest `json:"request,omitempty"` - QueueMessage *StorageQueueMessage `json:"queueMessage,omitempty"` - RetryPolicy *RetryPolicy `json:"retryPolicy,omitempty"` - ErrorAction *JobErrorAction `json:"errorAction,omitempty"` + Type JobActionType `json:"type,omitempty"` + Request *HTTPRequest `json:"request,omitempty"` + QueueMessage *StorageQueueMessage `json:"queueMessage,omitempty"` + ServiceBusQueueMessage *ServiceBusQueueMessage `json:"serviceBusQueueMessage,omitempty"` + ServiceBusTopicMessage *ServiceBusTopicMessage `json:"serviceBusTopicMessage,omitempty"` + RetryPolicy *RetryPolicy `json:"retryPolicy,omitempty"` + ErrorAction *JobErrorAction `json:"errorAction,omitempty"` } // JobCollectionDefinition is @@ -302,10 +329,12 @@ // JobErrorAction is type JobErrorAction struct { - Type JobActionType `json:"type,omitempty"` - Request *HTTPRequest `json:"request,omitempty"` - QueueMessage *StorageQueueMessage `json:"queueMessage,omitempty"` - RetryPolicy *RetryPolicy `json:"retryPolicy,omitempty"` + Type JobActionType `json:"type,omitempty"` + Request *HTTPRequest `json:"request,omitempty"` + QueueMessage *StorageQueueMessage `json:"queueMessage,omitempty"` + ServiceBusQueueMessage *ServiceBusQueueMessage `json:"serviceBusQueueMessage,omitempty"` + ServiceBusTopicMessage *ServiceBusTopicMessage `json:"serviceBusTopicMessage,omitempty"` + RetryPolicy *RetryPolicy `json:"retryPolicy,omitempty"` } // JobHistoryDefinition is @@ -426,10 +455,66 @@ // RetryPolicy is type RetryPolicy struct { RetryType RetryType `json:"retryType,omitempty"` - RetryInterval *int `json:"retryInterval,omitempty"` + RetryInterval *string `json:"retryInterval,omitempty"` RetryCount *int `json:"retryCount,omitempty"` } +// ServiceBusAuthentication is +type ServiceBusAuthentication struct { + SasKey *string `json:"sasKey,omitempty"` + SasKeyName *string `json:"sasKeyName,omitempty"` + Type ServiceBusAuthenticationType `json:"type,omitempty"` +} + +// ServiceBusBrokeredMessageProperties is +type ServiceBusBrokeredMessageProperties struct { + ContentType *string `json:"contentType,omitempty"` + CorrelationID *string `json:"correlationId,omitempty"` + ForcePersistence *bool `json:"forcePersistence,omitempty"` + Label *string `json:"label,omitempty"` + MessageID *string `json:"messageId,omitempty"` + PartitionKey *string `json:"partitionKey,omitempty"` + ReplyTo *string `json:"replyTo,omitempty"` + ReplyToSessionID *string `json:"replyToSessionId,omitempty"` + ScheduledEnqueueTimeUtc *date.Time `json:"scheduledEnqueueTimeUtc,omitempty"` + SessionID *string `json:"sessionId,omitempty"` + TimeToLive *date.Time `json:"timeToLive,omitempty"` + To *string `json:"to,omitempty"` + ViaPartitionKey *string `json:"viaPartitionKey,omitempty"` +} + +// ServiceBusMessage is +type ServiceBusMessage struct { + Authentication *ServiceBusAuthentication `json:"authentication,omitempty"` + BrokeredMessageProperties *ServiceBusBrokeredMessageProperties `json:"brokeredMessageProperties,omitempty"` + CustomMessageProperties *map[string]*string `json:"customMessageProperties,omitempty"` + Message *string `json:"message,omitempty"` + Namespace *string `json:"namespace,omitempty"` + TransportType ServiceBusTransportType `json:"transportType,omitempty"` +} + +// ServiceBusQueueMessage is +type ServiceBusQueueMessage struct { + Authentication *ServiceBusAuthentication `json:"authentication,omitempty"` + BrokeredMessageProperties *ServiceBusBrokeredMessageProperties `json:"brokeredMessageProperties,omitempty"` + CustomMessageProperties *map[string]*string `json:"customMessageProperties,omitempty"` + Message *string `json:"message,omitempty"` + Namespace *string `json:"namespace,omitempty"` + TransportType ServiceBusTransportType `json:"transportType,omitempty"` + QueueName *string `json:"queueName,omitempty"` +} + +// ServiceBusTopicMessage is +type ServiceBusTopicMessage struct { + Authentication *ServiceBusAuthentication `json:"authentication,omitempty"` + BrokeredMessageProperties *ServiceBusBrokeredMessageProperties `json:"brokeredMessageProperties,omitempty"` + CustomMessageProperties *map[string]*string `json:"customMessageProperties,omitempty"` + Message *string `json:"message,omitempty"` + Namespace *string `json:"namespace,omitempty"` + TransportType ServiceBusTransportType `json:"transportType,omitempty"` + TopicPath *string `json:"topicPath,omitempty"` +} + // Sku is type Sku struct { Name SkuDefinition `json:"name,omitempty"` diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/version.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/version.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/version.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/scheduler/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,8 @@ const ( major = "0" - minor = "1" - patch = "1" + minor = "3" + patch = "0" // Always begin a "tag" with a dash (as per http://semver.org) tag = "-beta" semVerFormat = "%s.%s.%s%s" diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/search/adminkeys.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/search/adminkeys.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/search/adminkeys.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/search/adminkeys.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/search/client.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/search/client.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/search/client.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/search/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/search/models.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/search/models.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/search/models.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/search/models.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -26,15 +26,12 @@ type ProvisioningState string const ( - // ProvisioningStateFailed specifies the provisioning state failed state - // for provisioning state. - ProvisioningStateFailed ProvisioningState = "failed" - // ProvisioningStateProvisioning specifies the provisioning state - // provisioning state for provisioning state. - ProvisioningStateProvisioning ProvisioningState = "provisioning" - // ProvisioningStateSucceeded specifies the provisioning state succeeded - // state for provisioning state. - ProvisioningStateSucceeded ProvisioningState = "succeeded" + // Failed specifies the failed state for provisioning state. + Failed ProvisioningState = "failed" + // Provisioning specifies the provisioning state for provisioning state. + Provisioning ProvisioningState = "provisioning" + // Succeeded specifies the succeeded state for provisioning state. + Succeeded ProvisioningState = "succeeded" ) // ServiceStatus enumerates the values for service status. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/search/querykeys.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/search/querykeys.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/search/querykeys.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/search/querykeys.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/search/services.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/search/services.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/search/services.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/search/services.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/search/version.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/search/version.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/search/version.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/search/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,8 @@ const ( major = "0" - minor = "1" - patch = "1" + minor = "3" + patch = "0" // Always begin a "tag" with a dash (as per http://semver.org) tag = "-beta" semVerFormat = "%s.%s.%s%s" diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/storage/accounts.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/storage/accounts.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/storage/accounts.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/storage/accounts.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,7 @@ "net/url" ) -// AccountsClient is the client for the Accounts methods of the Storage -// service. +// AccountsClient is the the Storage Management Client. type AccountsClient struct { ManagementClient } @@ -111,7 +110,7 @@ // created and subsequent PUT request is issued with exact same set of // properties, then HTTP 200 would be returned. // -// resourceGroupName is the name of the resource group within the user’s +// 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. @@ -179,7 +178,7 @@ // Delete deletes a storage account in Microsoft Azure. // -// resourceGroupName is the name of the resource group within the user’s +// 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. @@ -246,7 +245,7 @@ // 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 +// 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. @@ -374,7 +373,7 @@ // 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 +// resourceGroupName is the name of the resource group within the user's // subscription. func (client AccountsClient) ListByResourceGroup(resourceGroupName string) (result AccountListResult, ae error) { req, err := client.ListByResourceGroupPreparer(resourceGroupName) @@ -501,11 +500,12 @@ // RegenerateKey regenerates the access keys for the specified storage account. // -// resourceGroupName is the name of the resource group within the user’s +// 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 AccountKeys, ae error) { req, err := client.RegenerateKeyPreparer(resourceGroupName, accountName, regenerateKey) if err != nil { @@ -570,14 +570,17 @@ // Update updates the account type or tags for a storage account. It can also // be used to add a custom domain (note that custom domains cannot be added // via the Create operation). Only one custom domain is supported per storage -// account. This API can only be used to update one of tags, accountType, or -// customDomain per call. To update multiple of these properties, call the -// API multiple times with one change per call. This call does not change the -// storage keys for the account. If you want to change storage account keys, -// use the RegenerateKey operation. The location and name of the storage -// account cannot be changed after creation. +// account. In order to replace a custom domain, the old value must be +// cleared before a new value may be set. To clear a custom domain, simply +// update the custom domain with empty string. Then call update again with +// the new cutsom domain name. The update API can only be used to update one +// of tags, accountType, or customDomain per call. To update multiple of +// these properties, call the API multiple times with one change per call. +// This call does not change the storage keys for the account. If you want to +// change storage account keys, use the RegenerateKey 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 +// 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. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/storage/client.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/storage/client.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/storage/client.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/storage/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,13 +24,13 @@ const ( // APIVersion is the version of the Storage - APIVersion = "2015-05-01-preview" + APIVersion = "2015-06-15" // DefaultBaseURI is the default URI used for the service Storage DefaultBaseURI = "https://management.azure.com" ) -// ManagementClient is the base client for Storage. +// ManagementClient is the the Storage Management Client. type ManagementClient struct { autorest.Client BaseURI string diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/storage/models.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/storage/models.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/storage/models.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/storage/models.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -49,16 +49,6 @@ StandardZRS AccountType = "Standard_ZRS" ) -// KeyName enumerates the values for key name. -type KeyName string - -const ( - // Key1 specifies the key 1 state for key name. - Key1 KeyName = "key1" - // Key2 specifies the key 2 state for key name. - Key2 KeyName = "key2" -) - // ProvisioningState enumerates the values for provisioning state. type ProvisioningState string @@ -66,7 +56,7 @@ // Creating specifies the creating state for provisioning state. Creating ProvisioningState = "Creating" // ResolvingDNS specifies the resolving dns state for provisioning state. - ResolvingDNS ProvisioningState = "ResolvingDns" + ResolvingDNS ProvisioningState = "ResolvingDNS" // Succeeded specifies the succeeded state for provisioning state. Succeeded ProvisioningState = "Succeeded" ) @@ -167,7 +157,7 @@ // AccountRegenerateKeyParameters is type AccountRegenerateKeyParameters struct { - KeyName KeyName `json:"keyName,omitempty"` + KeyName *string `json:"keyName,omitempty"` } // AccountUpdateParameters is the parameters to update on the account. @@ -201,6 +191,7 @@ Blob *string `json:"blob,omitempty"` Queue *string `json:"queue,omitempty"` Table *string `json:"table,omitempty"` + File *string `json:"file,omitempty"` } // Resource is diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/storage/usageoperations.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/storage/usageoperations.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/storage/usageoperations.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/storage/usageoperations.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,7 @@ "net/url" ) -// UsageOperationsClient is the client for the UsageOperations methods of the -// Storage service. +// UsageOperationsClient is the the Storage Management Client. type UsageOperationsClient struct { ManagementClient } @@ -44,8 +43,9 @@ // List gets the current usage count and the limit for the resources under the // subscription. -func (client UsageOperationsClient) List() (result UsageListResult, ae error) { - req, err := client.ListPreparer() +// +func (client UsageOperationsClient) List(apiVersion string) (result UsageListResult, ae error) { + req, err := client.ListPreparer(apiVersion) if err != nil { return result, autorest.NewErrorWithError(err, "storage/UsageOperationsClient", "List", "Failure preparing request") } @@ -65,7 +65,7 @@ } // ListPreparer prepares the List request. -func (client UsageOperationsClient) ListPreparer() (*http.Request, error) { +func (client UsageOperationsClient) ListPreparer(apiVersion string) (*http.Request, error) { pathParameters := map[string]interface{}{ "subscriptionId": url.QueryEscape(client.SubscriptionID), } diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/storage/version.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/storage/version.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/storage/version.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/storage/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,8 @@ const ( major = "0" - minor = "1" - patch = "1" + minor = "3" + patch = "0" // Always begin a "tag" with a dash (as per http://semver.org) tag = "-beta" semVerFormat = "%s.%s.%s%s" @@ -34,7 +34,7 @@ // UserAgent returns the UserAgent string to use when sending http.Requests. func UserAgent() string { - return fmt.Sprintf(userAgentFormat, Version(), "storage", "2015-05-01-preview") + return fmt.Sprintf(userAgentFormat, Version(), "storage", "2015-06-15") } // Version returns the semantic version (see http://semver.org) of the client. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/client.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/client.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/client.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -115,7 +115,7 @@ } // List gets a list of the subscriptionIds. -func (client ManagementClient) List() (result ListResult, ae error) { +func (client ManagementClient) List() (result SubscriptionListResult, ae error) { req, err := client.ListPreparer() if err != nil { return result, autorest.NewErrorWithError(err, "subscriptions/ManagementClient", "List", "Failure preparing request") @@ -162,7 +162,7 @@ // ListResponder handles the response to the List request. The method always // closes the http.Response Body. -func (client ManagementClient) ListResponder(resp *http.Response) (result ListResult, err error) { +func (client ManagementClient) ListResponder(resp *http.Response) (result SubscriptionListResult, err error) { err = autorest.Respond( resp, client.ByInspecting(), @@ -174,8 +174,8 @@ } // ListNextResults retrieves the next set of results, if any. -func (client ManagementClient) ListNextResults(lastResults ListResult) (result ListResult, ae error) { - req, err := lastResults.ListResultPreparer() +func (client ManagementClient) ListNextResults(lastResults SubscriptionListResult) (result SubscriptionListResult, ae error) { + req, err := lastResults.SubscriptionListResultPreparer() if err != nil { return result, autorest.NewErrorWithError(err, "subscriptions/ManagementClient", "List", "Failure preparing next results request request") } @@ -196,3 +196,64 @@ return } + +// ListLocations gets a list of the subscription locations. +// +// subscriptionID is id of the subscription +func (client ManagementClient) ListLocations(subscriptionID string) (result LocationListResult, ae error) { + req, err := client.ListLocationsPreparer(subscriptionID) + if err != nil { + return result, autorest.NewErrorWithError(err, "subscriptions/ManagementClient", "ListLocations", "Failure preparing request") + } + + resp, err := client.ListLocationsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "subscriptions/ManagementClient", "ListLocations", "Failure sending request") + } + + result, err = client.ListLocationsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "subscriptions/ManagementClient", "ListLocations", "Failure responding to request") + } + + return +} + +// ListLocationsPreparer prepares the ListLocations request. +func (client ManagementClient) ListLocationsPreparer(subscriptionID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(subscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/locations"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListLocationsSender sends the ListLocations request. The method will close the +// http.Response Body if it receives an error. +func (client ManagementClient) ListLocationsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListLocationsResponder handles the response to the ListLocations request. The method always +// closes the http.Response Body. +func (client ManagementClient) ListLocationsResponder(resp *http.Response) (result LocationListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/models.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/models.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/models.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/models.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -36,23 +36,20 @@ Tagvalue *string `json:"tagvalue,omitempty"` } -// ListResult is subscription list operation response. -type ListResult struct { - autorest.Response `json:"-"` - Value *[]Subscription `json:"value,omitempty"` - NextLink *string `json:"nextLink,omitempty"` +// 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"` } -// ListResultPreparer prepares a request to retrieve the next set of results. It returns -// nil if no more results exist. -func (client ListResult) ListResultPreparer() (*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))) +// LocationListResult is location list operation response. +type LocationListResult struct { + autorest.Response `json:"-"` + Value *[]Location `json:"value,omitempty"` } // Resource is @@ -84,6 +81,25 @@ State *string `json:"state,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))) +} + // TenantIDDescription is tenant Id information type TenantIDDescription struct { ID *string `json:"id,omitempty"` diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/subscriptions.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/subscriptions.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/subscriptions.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/subscriptions.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,246 @@ +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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// 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(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)} +} + +// Get gets details about particular subscription. +// +// subscriptionID is id of the subscription. +func (client Client) Get(subscriptionID string) (result Subscription, ae error) { + req, err := client.GetPreparer(subscriptionID) + if err != nil { + return result, autorest.NewErrorWithError(err, "subscriptions/Client", "Get", "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", "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "subscriptions/Client", "Get", "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client Client) GetPreparer(subscriptionID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(subscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := client.ListPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "subscriptions/Client", "List", "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", "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "subscriptions/Client", "List", "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client Client) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.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, ae error) { + req, err := lastResults.SubscriptionListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "subscriptions/Client", "List", "Failure preparing next results request 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", "Failure sending next results request request") + } + + result, err = client.ListResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "subscriptions/Client", "List", "Failure responding to next results request request") + } + + return +} + +// ListLocations gets a list of the subscription locations. +// +// subscriptionID is id of the subscription +func (client Client) ListLocations(subscriptionID string) (result LocationListResult, ae error) { + req, err := client.ListLocationsPreparer(subscriptionID) + if err != nil { + return result, autorest.NewErrorWithError(err, "subscriptions/Client", "ListLocations", "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", "Failure sending request") + } + + result, err = client.ListLocationsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "subscriptions/Client", "ListLocations", "Failure responding to request") + } + + return +} + +// ListLocationsPreparer prepares the ListLocations request. +func (client Client) ListLocationsPreparer(subscriptionID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(subscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/locations"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// 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 client.Send(req, http.StatusOK) +} + +// 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(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/tenants.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/tenants.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/tenants.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/tenants.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/version.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/version.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/version.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/subscriptions/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ // See the License for the specific language governing permissions and // limitations under the License. // -// Code generated by Microsoft (R) AutoRest Code Generator 0.11.0.0 +// Code generated by Microsoft (R) AutoRest Code Generator 0.12.0.0 // Changes may cause incorrect behavior and will be lost if the code is // regenerated. @@ -24,8 +24,8 @@ const ( major = "0" - minor = "1" - patch = "1" + minor = "3" + patch = "0" // Always begin a "tag" with a dash (as per http://semver.org) tag = "-beta" semVerFormat = "%s.%s.%s%s" diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/certificateorders.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/certificateorders.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/certificateorders.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/certificateorders.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,698 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// CertificateOrdersClient is the use these APIs to manage Azure Websites +// resources through the Azure Resource Manager. All task operations conform +// to the HTTP/1.1 protocol specification and each operation returns an +// x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type CertificateOrdersClient struct { + ManagementClient +} + +// NewCertificateOrdersClient creates an instance of the +// CertificateOrdersClient client. +func NewCertificateOrdersClient(subscriptionID string) CertificateOrdersClient { + return NewCertificateOrdersClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewCertificateOrdersClientWithBaseURI creates an instance of the +// CertificateOrdersClient client. +func NewCertificateOrdersClientWithBaseURI(baseURI string, subscriptionID string) CertificateOrdersClient { + return CertificateOrdersClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdateCertificate sends the create or update certificate request. +// +// resourceGroupName is azure resource group name certificateOrderName is +// certificate name name is certificate name keyVaultCertificate is key Vault +// secret csm Id +func (client CertificateOrdersClient) CreateOrUpdateCertificate(resourceGroupName string, certificateOrderName string, name string, keyVaultCertificate CertificateOrderCertificate) (result CertificateOrderCertificate, ae error) { + req, err := client.CreateOrUpdateCertificatePreparer(resourceGroupName, certificateOrderName, name, keyVaultCertificate) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "CreateOrUpdateCertificate", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateCertificateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "CreateOrUpdateCertificate", "Failure sending request") + } + + result, err = client.CreateOrUpdateCertificateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "CreateOrUpdateCertificate", "Failure responding to request") + } + + return +} + +// CreateOrUpdateCertificatePreparer prepares the CreateOrUpdateCertificate request. +func (client CertificateOrdersClient) CreateOrUpdateCertificatePreparer(resourceGroupName string, certificateOrderName string, name string, keyVaultCertificate CertificateOrderCertificate) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "certificateOrderName": url.QueryEscape(certificateOrderName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CertificateRegistration/certificateOrders/{certificateOrderName}/certificates/{name}"), + autorest.WithJSON(keyVaultCertificate), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateCertificateSender sends the CreateOrUpdateCertificate request. The method will close the +// http.Response Body if it receives an error. +func (client CertificateOrdersClient) CreateOrUpdateCertificateSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateCertificateResponder handles the response to the CreateOrUpdateCertificate request. The method always +// closes the http.Response Body. +func (client CertificateOrdersClient) CreateOrUpdateCertificateResponder(resp *http.Response) (result CertificateOrderCertificate, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateCertificateOrder sends the create or update certificate order +// request. +// +// resourceGroupName is azure resource group name name is certificate name +// certificateDistinguishedName is distinguished name to be used for +// purchasing certificate +func (client CertificateOrdersClient) CreateOrUpdateCertificateOrder(resourceGroupName string, name string, certificateDistinguishedName CertificateOrder) (result CertificateOrder, ae error) { + req, err := client.CreateOrUpdateCertificateOrderPreparer(resourceGroupName, name, certificateDistinguishedName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "CreateOrUpdateCertificateOrder", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateCertificateOrderSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "CreateOrUpdateCertificateOrder", "Failure sending request") + } + + result, err = client.CreateOrUpdateCertificateOrderResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "CreateOrUpdateCertificateOrder", "Failure responding to request") + } + + return +} + +// CreateOrUpdateCertificateOrderPreparer prepares the CreateOrUpdateCertificateOrder request. +func (client CertificateOrdersClient) CreateOrUpdateCertificateOrderPreparer(resourceGroupName string, name string, certificateDistinguishedName CertificateOrder) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CertificateRegistration/certificateOrders/{name}"), + autorest.WithJSON(certificateDistinguishedName), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateCertificateOrderSender sends the CreateOrUpdateCertificateOrder request. The method will close the +// http.Response Body if it receives an error. +func (client CertificateOrdersClient) CreateOrUpdateCertificateOrderSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateCertificateOrderResponder handles the response to the CreateOrUpdateCertificateOrder request. The method always +// closes the http.Response Body. +func (client CertificateOrdersClient) CreateOrUpdateCertificateOrderResponder(resp *http.Response) (result CertificateOrder, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteCertificate sends the delete certificate request. +// +// resourceGroupName is azure resource group name certificateOrderName is +// certificate name name is certificate name +func (client CertificateOrdersClient) DeleteCertificate(resourceGroupName string, certificateOrderName string, name string) (result ObjectSet, ae error) { + req, err := client.DeleteCertificatePreparer(resourceGroupName, certificateOrderName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "DeleteCertificate", "Failure preparing request") + } + + resp, err := client.DeleteCertificateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "DeleteCertificate", "Failure sending request") + } + + result, err = client.DeleteCertificateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "DeleteCertificate", "Failure responding to request") + } + + return +} + +// DeleteCertificatePreparer prepares the DeleteCertificate request. +func (client CertificateOrdersClient) DeleteCertificatePreparer(resourceGroupName string, certificateOrderName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "certificateOrderName": url.QueryEscape(certificateOrderName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CertificateRegistration/certificateOrders/{certificateOrderName}/certificates/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteCertificateSender sends the DeleteCertificate request. The method will close the +// http.Response Body if it receives an error. +func (client CertificateOrdersClient) DeleteCertificateSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteCertificateResponder handles the response to the DeleteCertificate request. The method always +// closes the http.Response Body. +func (client CertificateOrdersClient) DeleteCertificateResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteCertificateOrder sends the delete certificate order request. +// +// resourceGroupName is azure resource group name name is certificate name +func (client CertificateOrdersClient) DeleteCertificateOrder(resourceGroupName string, name string) (result ObjectSet, ae error) { + req, err := client.DeleteCertificateOrderPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "DeleteCertificateOrder", "Failure preparing request") + } + + resp, err := client.DeleteCertificateOrderSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "DeleteCertificateOrder", "Failure sending request") + } + + result, err = client.DeleteCertificateOrderResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "DeleteCertificateOrder", "Failure responding to request") + } + + return +} + +// DeleteCertificateOrderPreparer prepares the DeleteCertificateOrder request. +func (client CertificateOrdersClient) DeleteCertificateOrderPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CertificateRegistration/certificateOrders/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteCertificateOrderSender sends the DeleteCertificateOrder request. The method will close the +// http.Response Body if it receives an error. +func (client CertificateOrdersClient) DeleteCertificateOrderSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteCertificateOrderResponder handles the response to the DeleteCertificateOrder request. The method always +// closes the http.Response Body. +func (client CertificateOrdersClient) DeleteCertificateOrderResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetCertificate sends the get certificate request. +// +// resourceGroupName is azure resource group name certificateOrderName is +// certificate name name is certificate name +func (client CertificateOrdersClient) GetCertificate(resourceGroupName string, certificateOrderName string, name string) (result CertificateOrderCertificate, ae error) { + req, err := client.GetCertificatePreparer(resourceGroupName, certificateOrderName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "GetCertificate", "Failure preparing request") + } + + resp, err := client.GetCertificateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "GetCertificate", "Failure sending request") + } + + result, err = client.GetCertificateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "GetCertificate", "Failure responding to request") + } + + return +} + +// GetCertificatePreparer prepares the GetCertificate request. +func (client CertificateOrdersClient) GetCertificatePreparer(resourceGroupName string, certificateOrderName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "certificateOrderName": url.QueryEscape(certificateOrderName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CertificateRegistration/certificateOrders/{certificateOrderName}/certificates/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetCertificateSender sends the GetCertificate request. The method will close the +// http.Response Body if it receives an error. +func (client CertificateOrdersClient) GetCertificateSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetCertificateResponder handles the response to the GetCertificate request. The method always +// closes the http.Response Body. +func (client CertificateOrdersClient) GetCertificateResponder(resp *http.Response) (result CertificateOrderCertificate, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetCertificateOrder sends the get certificate order request. +// +// resourceGroupName is azure resource group name name is certificate name +func (client CertificateOrdersClient) GetCertificateOrder(resourceGroupName string, name string) (result CertificateOrder, ae error) { + req, err := client.GetCertificateOrderPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "GetCertificateOrder", "Failure preparing request") + } + + resp, err := client.GetCertificateOrderSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "GetCertificateOrder", "Failure sending request") + } + + result, err = client.GetCertificateOrderResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "GetCertificateOrder", "Failure responding to request") + } + + return +} + +// GetCertificateOrderPreparer prepares the GetCertificateOrder request. +func (client CertificateOrdersClient) GetCertificateOrderPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CertificateRegistration/certificateOrders/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetCertificateOrderSender sends the GetCertificateOrder request. The method will close the +// http.Response Body if it receives an error. +func (client CertificateOrdersClient) GetCertificateOrderSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetCertificateOrderResponder handles the response to the GetCertificateOrder request. The method always +// closes the http.Response Body. +func (client CertificateOrdersClient) GetCertificateOrderResponder(resp *http.Response) (result CertificateOrder, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetCertificateOrders sends the get certificate orders request. +// +// resourceGroupName is azure resource group name +func (client CertificateOrdersClient) GetCertificateOrders(resourceGroupName string) (result CertificateOrderCollection, ae error) { + req, err := client.GetCertificateOrdersPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "GetCertificateOrders", "Failure preparing request") + } + + resp, err := client.GetCertificateOrdersSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "GetCertificateOrders", "Failure sending request") + } + + result, err = client.GetCertificateOrdersResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "GetCertificateOrders", "Failure responding to request") + } + + return +} + +// GetCertificateOrdersPreparer prepares the GetCertificateOrders request. +func (client CertificateOrdersClient) GetCertificateOrdersPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CertificateRegistration/certificateOrders"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetCertificateOrdersSender sends the GetCertificateOrders request. The method will close the +// http.Response Body if it receives an error. +func (client CertificateOrdersClient) GetCertificateOrdersSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetCertificateOrdersResponder handles the response to the GetCertificateOrders request. The method always +// closes the http.Response Body. +func (client CertificateOrdersClient) GetCertificateOrdersResponder(resp *http.Response) (result CertificateOrderCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetCertificates sends the get certificates request. +// +// resourceGroupName is azure resource group name certificateOrderName is +// certificate name +func (client CertificateOrdersClient) GetCertificates(resourceGroupName string, certificateOrderName string) (result CertificateOrderCertificateCollection, ae error) { + req, err := client.GetCertificatesPreparer(resourceGroupName, certificateOrderName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "GetCertificates", "Failure preparing request") + } + + resp, err := client.GetCertificatesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "GetCertificates", "Failure sending request") + } + + result, err = client.GetCertificatesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "GetCertificates", "Failure responding to request") + } + + return +} + +// GetCertificatesPreparer prepares the GetCertificates request. +func (client CertificateOrdersClient) GetCertificatesPreparer(resourceGroupName string, certificateOrderName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "certificateOrderName": url.QueryEscape(certificateOrderName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CertificateRegistration/certificateOrders/{certificateOrderName}/certificates"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetCertificatesSender sends the GetCertificates request. The method will close the +// http.Response Body if it receives an error. +func (client CertificateOrdersClient) GetCertificatesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetCertificatesResponder handles the response to the GetCertificates request. The method always +// closes the http.Response Body. +func (client CertificateOrdersClient) GetCertificatesResponder(resp *http.Response) (result CertificateOrderCertificateCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateCertificate sends the update certificate request. +// +// resourceGroupName is azure resource group name certificateOrderName is +// certificate name name is certificate name keyVaultCertificate is key Vault +// secret csm Id +func (client CertificateOrdersClient) UpdateCertificate(resourceGroupName string, certificateOrderName string, name string, keyVaultCertificate CertificateOrderCertificate) (result CertificateOrderCertificate, ae error) { + req, err := client.UpdateCertificatePreparer(resourceGroupName, certificateOrderName, name, keyVaultCertificate) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "UpdateCertificate", "Failure preparing request") + } + + resp, err := client.UpdateCertificateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "UpdateCertificate", "Failure sending request") + } + + result, err = client.UpdateCertificateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "UpdateCertificate", "Failure responding to request") + } + + return +} + +// UpdateCertificatePreparer prepares the UpdateCertificate request. +func (client CertificateOrdersClient) UpdateCertificatePreparer(resourceGroupName string, certificateOrderName string, name string, keyVaultCertificate CertificateOrderCertificate) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "certificateOrderName": url.QueryEscape(certificateOrderName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CertificateRegistration/certificateOrders/{certificateOrderName}/certificates/{name}"), + autorest.WithJSON(keyVaultCertificate), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateCertificateSender sends the UpdateCertificate request. The method will close the +// http.Response Body if it receives an error. +func (client CertificateOrdersClient) UpdateCertificateSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateCertificateResponder handles the response to the UpdateCertificate request. The method always +// closes the http.Response Body. +func (client CertificateOrdersClient) UpdateCertificateResponder(resp *http.Response) (result CertificateOrderCertificate, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateCertificateOrder sends the update certificate order request. +// +// resourceGroupName is azure resource group name name is certificate name +// certificateDistinguishedName is distinguished name to be used for +// purchasing certificate +func (client CertificateOrdersClient) UpdateCertificateOrder(resourceGroupName string, name string, certificateDistinguishedName CertificateOrder) (result CertificateOrder, ae error) { + req, err := client.UpdateCertificateOrderPreparer(resourceGroupName, name, certificateDistinguishedName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "UpdateCertificateOrder", "Failure preparing request") + } + + resp, err := client.UpdateCertificateOrderSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "UpdateCertificateOrder", "Failure sending request") + } + + result, err = client.UpdateCertificateOrderResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificateOrdersClient", "UpdateCertificateOrder", "Failure responding to request") + } + + return +} + +// UpdateCertificateOrderPreparer prepares the UpdateCertificateOrder request. +func (client CertificateOrdersClient) UpdateCertificateOrderPreparer(resourceGroupName string, name string, certificateDistinguishedName CertificateOrder) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.CertificateRegistration/certificateOrders/{name}"), + autorest.WithJSON(certificateDistinguishedName), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateCertificateOrderSender sends the UpdateCertificateOrder request. The method will close the +// http.Response Body if it receives an error. +func (client CertificateOrdersClient) UpdateCertificateOrderSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateCertificateOrderResponder handles the response to the UpdateCertificateOrder request. The method always +// closes the http.Response Body. +func (client CertificateOrdersClient) UpdateCertificateOrderResponder(resp *http.Response) (result CertificateOrder, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/certificates.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/certificates.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/certificates.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/certificates.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,692 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// CertificatesClient is the use these APIs to manage Azure Websites resources +// through the Azure Resource Manager. All task operations conform to the +// HTTP/1.1 protocol specification and each operation returns an +// x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type CertificatesClient struct { + ManagementClient +} + +// NewCertificatesClient creates an instance of the CertificatesClient client. +func NewCertificatesClient(subscriptionID string) CertificatesClient { + return NewCertificatesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewCertificatesClientWithBaseURI creates an instance of the +// CertificatesClient client. +func NewCertificatesClientWithBaseURI(baseURI string, subscriptionID string) CertificatesClient { + return CertificatesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdateCertificate sends the create or update certificate request. +// +// resourceGroupName is name of the resource group name is name of the +// certificate. certificateEnvelope is details of certificate if it exists +// already. +func (client CertificatesClient) CreateOrUpdateCertificate(resourceGroupName string, name string, certificateEnvelope Certificate) (result Certificate, ae error) { + req, err := client.CreateOrUpdateCertificatePreparer(resourceGroupName, name, certificateEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "CreateOrUpdateCertificate", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateCertificateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "CreateOrUpdateCertificate", "Failure sending request") + } + + result, err = client.CreateOrUpdateCertificateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificatesClient", "CreateOrUpdateCertificate", "Failure responding to request") + } + + return +} + +// CreateOrUpdateCertificatePreparer prepares the CreateOrUpdateCertificate request. +func (client CertificatesClient) CreateOrUpdateCertificatePreparer(resourceGroupName string, name string, certificateEnvelope Certificate) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/certificates/{name}"), + autorest.WithJSON(certificateEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateCertificateSender sends the CreateOrUpdateCertificate request. The method will close the +// http.Response Body if it receives an error. +func (client CertificatesClient) CreateOrUpdateCertificateSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateCertificateResponder handles the response to the CreateOrUpdateCertificate request. The method always +// closes the http.Response Body. +func (client CertificatesClient) CreateOrUpdateCertificateResponder(resp *http.Response) (result Certificate, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateCsr sends the create or update csr request. +// +// resourceGroupName is name of the resource group name is name of the +// certificate. csrEnvelope is details of certificate signing request if it +// exists already. +func (client CertificatesClient) CreateOrUpdateCsr(resourceGroupName string, name string, csrEnvelope Csr) (result Csr, ae error) { + req, err := client.CreateOrUpdateCsrPreparer(resourceGroupName, name, csrEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "CreateOrUpdateCsr", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateCsrSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "CreateOrUpdateCsr", "Failure sending request") + } + + result, err = client.CreateOrUpdateCsrResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificatesClient", "CreateOrUpdateCsr", "Failure responding to request") + } + + return +} + +// CreateOrUpdateCsrPreparer prepares the CreateOrUpdateCsr request. +func (client CertificatesClient) CreateOrUpdateCsrPreparer(resourceGroupName string, name string, csrEnvelope Csr) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/csrs/{name}"), + autorest.WithJSON(csrEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateCsrSender sends the CreateOrUpdateCsr request. The method will close the +// http.Response Body if it receives an error. +func (client CertificatesClient) CreateOrUpdateCsrSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateCsrResponder handles the response to the CreateOrUpdateCsr request. The method always +// closes the http.Response Body. +func (client CertificatesClient) CreateOrUpdateCsrResponder(resp *http.Response) (result Csr, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteCertificate sends the delete certificate request. +// +// resourceGroupName is name of the resource group name is name of the +// certificate to be deleted. +func (client CertificatesClient) DeleteCertificate(resourceGroupName string, name string) (result ObjectSet, ae error) { + req, err := client.DeleteCertificatePreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "DeleteCertificate", "Failure preparing request") + } + + resp, err := client.DeleteCertificateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "DeleteCertificate", "Failure sending request") + } + + result, err = client.DeleteCertificateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificatesClient", "DeleteCertificate", "Failure responding to request") + } + + return +} + +// DeleteCertificatePreparer prepares the DeleteCertificate request. +func (client CertificatesClient) DeleteCertificatePreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/certificates/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteCertificateSender sends the DeleteCertificate request. The method will close the +// http.Response Body if it receives an error. +func (client CertificatesClient) DeleteCertificateSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteCertificateResponder handles the response to the DeleteCertificate request. The method always +// closes the http.Response Body. +func (client CertificatesClient) DeleteCertificateResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteCsr sends the delete csr request. +// +// resourceGroupName is name of the resource group name is name of the +// certificate signing request. +func (client CertificatesClient) DeleteCsr(resourceGroupName string, name string) (result ObjectSet, ae error) { + req, err := client.DeleteCsrPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "DeleteCsr", "Failure preparing request") + } + + resp, err := client.DeleteCsrSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "DeleteCsr", "Failure sending request") + } + + result, err = client.DeleteCsrResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificatesClient", "DeleteCsr", "Failure responding to request") + } + + return +} + +// DeleteCsrPreparer prepares the DeleteCsr request. +func (client CertificatesClient) DeleteCsrPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/csrs/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteCsrSender sends the DeleteCsr request. The method will close the +// http.Response Body if it receives an error. +func (client CertificatesClient) DeleteCsrSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteCsrResponder handles the response to the DeleteCsr request. The method always +// closes the http.Response Body. +func (client CertificatesClient) DeleteCsrResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetCertificate sends the get certificate request. +// +// resourceGroupName is name of the resource group name is name of the +// certificate. +func (client CertificatesClient) GetCertificate(resourceGroupName string, name string) (result Certificate, ae error) { + req, err := client.GetCertificatePreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "GetCertificate", "Failure preparing request") + } + + resp, err := client.GetCertificateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "GetCertificate", "Failure sending request") + } + + result, err = client.GetCertificateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificatesClient", "GetCertificate", "Failure responding to request") + } + + return +} + +// GetCertificatePreparer prepares the GetCertificate request. +func (client CertificatesClient) GetCertificatePreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/certificates/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetCertificateSender sends the GetCertificate request. The method will close the +// http.Response Body if it receives an error. +func (client CertificatesClient) GetCertificateSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetCertificateResponder handles the response to the GetCertificate request. The method always +// closes the http.Response Body. +func (client CertificatesClient) GetCertificateResponder(resp *http.Response) (result Certificate, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetCertificates sends the get certificates request. +// +// resourceGroupName is name of the resource group +func (client CertificatesClient) GetCertificates(resourceGroupName string) (result CertificateCollection, ae error) { + req, err := client.GetCertificatesPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "GetCertificates", "Failure preparing request") + } + + resp, err := client.GetCertificatesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "GetCertificates", "Failure sending request") + } + + result, err = client.GetCertificatesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificatesClient", "GetCertificates", "Failure responding to request") + } + + return +} + +// GetCertificatesPreparer prepares the GetCertificates request. +func (client CertificatesClient) GetCertificatesPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/certificates"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetCertificatesSender sends the GetCertificates request. The method will close the +// http.Response Body if it receives an error. +func (client CertificatesClient) GetCertificatesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetCertificatesResponder handles the response to the GetCertificates request. The method always +// closes the http.Response Body. +func (client CertificatesClient) GetCertificatesResponder(resp *http.Response) (result CertificateCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetCsr sends the get csr request. +// +// resourceGroupName is name of the resource group name is name of the +// certificate. +func (client CertificatesClient) GetCsr(resourceGroupName string, name string) (result Csr, ae error) { + req, err := client.GetCsrPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "GetCsr", "Failure preparing request") + } + + resp, err := client.GetCsrSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "GetCsr", "Failure sending request") + } + + result, err = client.GetCsrResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificatesClient", "GetCsr", "Failure responding to request") + } + + return +} + +// GetCsrPreparer prepares the GetCsr request. +func (client CertificatesClient) GetCsrPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/csrs/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetCsrSender sends the GetCsr request. The method will close the +// http.Response Body if it receives an error. +func (client CertificatesClient) GetCsrSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetCsrResponder handles the response to the GetCsr request. The method always +// closes the http.Response Body. +func (client CertificatesClient) GetCsrResponder(resp *http.Response) (result Csr, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetCsrs sends the get csrs request. +// +// resourceGroupName is name of the resource group +func (client CertificatesClient) GetCsrs(resourceGroupName string) (result CsrList, ae error) { + req, err := client.GetCsrsPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "GetCsrs", "Failure preparing request") + } + + resp, err := client.GetCsrsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "GetCsrs", "Failure sending request") + } + + result, err = client.GetCsrsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificatesClient", "GetCsrs", "Failure responding to request") + } + + return +} + +// GetCsrsPreparer prepares the GetCsrs request. +func (client CertificatesClient) GetCsrsPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/csrs"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetCsrsSender sends the GetCsrs request. The method will close the +// http.Response Body if it receives an error. +func (client CertificatesClient) GetCsrsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetCsrsResponder handles the response to the GetCsrs request. The method always +// closes the http.Response Body. +func (client CertificatesClient) GetCsrsResponder(resp *http.Response) (result CsrList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateCertificate sends the update certificate request. +// +// resourceGroupName is name of the resource group name is name of the +// certificate. certificateEnvelope is details of certificate if it exists +// already. +func (client CertificatesClient) UpdateCertificate(resourceGroupName string, name string, certificateEnvelope Certificate) (result Certificate, ae error) { + req, err := client.UpdateCertificatePreparer(resourceGroupName, name, certificateEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "UpdateCertificate", "Failure preparing request") + } + + resp, err := client.UpdateCertificateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "UpdateCertificate", "Failure sending request") + } + + result, err = client.UpdateCertificateResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificatesClient", "UpdateCertificate", "Failure responding to request") + } + + return +} + +// UpdateCertificatePreparer prepares the UpdateCertificate request. +func (client CertificatesClient) UpdateCertificatePreparer(resourceGroupName string, name string, certificateEnvelope Certificate) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/certificates/{name}"), + autorest.WithJSON(certificateEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateCertificateSender sends the UpdateCertificate request. The method will close the +// http.Response Body if it receives an error. +func (client CertificatesClient) UpdateCertificateSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateCertificateResponder handles the response to the UpdateCertificate request. The method always +// closes the http.Response Body. +func (client CertificatesClient) UpdateCertificateResponder(resp *http.Response) (result Certificate, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateCsr sends the update csr request. +// +// resourceGroupName is name of the resource group name is name of the +// certificate. csrEnvelope is details of certificate signing request if it +// exists already. +func (client CertificatesClient) UpdateCsr(resourceGroupName string, name string, csrEnvelope Csr) (result Csr, ae error) { + req, err := client.UpdateCsrPreparer(resourceGroupName, name, csrEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "UpdateCsr", "Failure preparing request") + } + + resp, err := client.UpdateCsrSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/CertificatesClient", "UpdateCsr", "Failure sending request") + } + + result, err = client.UpdateCsrResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/CertificatesClient", "UpdateCsr", "Failure responding to request") + } + + return +} + +// UpdateCsrPreparer prepares the UpdateCsr request. +func (client CertificatesClient) UpdateCsrPreparer(resourceGroupName string, name string, csrEnvelope Csr) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/csrs/{name}"), + autorest.WithJSON(csrEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateCsrSender sends the UpdateCsr request. The method will close the +// http.Response Body if it receives an error. +func (client CertificatesClient) UpdateCsrSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateCsrResponder handles the response to the UpdateCsr request. The method always +// closes the http.Response Body. +func (client CertificatesClient) UpdateCsrResponder(resp *http.Response) (result Csr, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/classicmobileservices.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/classicmobileservices.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/classicmobileservices.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/classicmobileservices.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,237 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// ClassicMobileServicesClient is the use these APIs to manage Azure Websites +// resources through the Azure Resource Manager. All task operations conform +// to the HTTP/1.1 protocol specification and each operation returns an +// x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type ClassicMobileServicesClient struct { + ManagementClient +} + +// NewClassicMobileServicesClient creates an instance of the +// ClassicMobileServicesClient client. +func NewClassicMobileServicesClient(subscriptionID string) ClassicMobileServicesClient { + return NewClassicMobileServicesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewClassicMobileServicesClientWithBaseURI creates an instance of the +// ClassicMobileServicesClient client. +func NewClassicMobileServicesClientWithBaseURI(baseURI string, subscriptionID string) ClassicMobileServicesClient { + return ClassicMobileServicesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// DeleteClassicMobileService sends the delete classic mobile service request. +// +// resourceGroupName is name of resource group name is name of mobile service +func (client ClassicMobileServicesClient) DeleteClassicMobileService(resourceGroupName string, name string) (result ObjectSet, ae error) { + req, err := client.DeleteClassicMobileServicePreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ClassicMobileServicesClient", "DeleteClassicMobileService", "Failure preparing request") + } + + resp, err := client.DeleteClassicMobileServiceSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ClassicMobileServicesClient", "DeleteClassicMobileService", "Failure sending request") + } + + result, err = client.DeleteClassicMobileServiceResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ClassicMobileServicesClient", "DeleteClassicMobileService", "Failure responding to request") + } + + return +} + +// DeleteClassicMobileServicePreparer prepares the DeleteClassicMobileService request. +func (client ClassicMobileServicesClient) DeleteClassicMobileServicePreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/classicMobileServices/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteClassicMobileServiceSender sends the DeleteClassicMobileService request. The method will close the +// http.Response Body if it receives an error. +func (client ClassicMobileServicesClient) DeleteClassicMobileServiceSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteClassicMobileServiceResponder handles the response to the DeleteClassicMobileService request. The method always +// closes the http.Response Body. +func (client ClassicMobileServicesClient) DeleteClassicMobileServiceResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetClassicMobileService sends the get classic mobile service request. +// +// resourceGroupName is name of resource group name is name of mobile service +func (client ClassicMobileServicesClient) GetClassicMobileService(resourceGroupName string, name string) (result ClassicMobileService, ae error) { + req, err := client.GetClassicMobileServicePreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ClassicMobileServicesClient", "GetClassicMobileService", "Failure preparing request") + } + + resp, err := client.GetClassicMobileServiceSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ClassicMobileServicesClient", "GetClassicMobileService", "Failure sending request") + } + + result, err = client.GetClassicMobileServiceResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ClassicMobileServicesClient", "GetClassicMobileService", "Failure responding to request") + } + + return +} + +// GetClassicMobileServicePreparer prepares the GetClassicMobileService request. +func (client ClassicMobileServicesClient) GetClassicMobileServicePreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/classicMobileServices/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetClassicMobileServiceSender sends the GetClassicMobileService request. The method will close the +// http.Response Body if it receives an error. +func (client ClassicMobileServicesClient) GetClassicMobileServiceSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetClassicMobileServiceResponder handles the response to the GetClassicMobileService request. The method always +// closes the http.Response Body. +func (client ClassicMobileServicesClient) GetClassicMobileServiceResponder(resp *http.Response) (result ClassicMobileService, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetClassicMobileServices sends the get classic mobile services request. +// +// resourceGroupName is name of resource group +func (client ClassicMobileServicesClient) GetClassicMobileServices(resourceGroupName string) (result ClassicMobileServiceCollection, ae error) { + req, err := client.GetClassicMobileServicesPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ClassicMobileServicesClient", "GetClassicMobileServices", "Failure preparing request") + } + + resp, err := client.GetClassicMobileServicesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ClassicMobileServicesClient", "GetClassicMobileServices", "Failure sending request") + } + + result, err = client.GetClassicMobileServicesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ClassicMobileServicesClient", "GetClassicMobileServices", "Failure responding to request") + } + + return +} + +// GetClassicMobileServicesPreparer prepares the GetClassicMobileServices request. +func (client ClassicMobileServicesClient) GetClassicMobileServicesPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/classicMobileServices"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetClassicMobileServicesSender sends the GetClassicMobileServices request. The method will close the +// http.Response Body if it receives an error. +func (client ClassicMobileServicesClient) GetClassicMobileServicesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetClassicMobileServicesResponder handles the response to the GetClassicMobileServices request. The method always +// closes the http.Response Body. +func (client ClassicMobileServicesClient) GetClassicMobileServicesResponder(resp *http.Response) (result ClassicMobileServiceCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/client.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/client.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/client.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,59 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" +) + +const ( + // APIVersion is the version of the Web + APIVersion = "2015-08-01" + + // DefaultBaseURI is the default URI used for the service Web + DefaultBaseURI = "https://management.azure.com" +) + +// ManagementClient is the use these APIs to manage Azure Websites resources +// through the Azure Resource Manager. All task operations conform to the +// HTTP/1.1 protocol specification and each operation returns an +// x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type ManagementClient struct { + autorest.Client + BaseURI 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, + SubscriptionID: subscriptionID, + } +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/domains.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/domains.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/domains.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/domains.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,436 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// DomainsClient is the use these APIs to manage Azure Websites resources +// through the Azure Resource Manager. All task operations conform to the +// HTTP/1.1 protocol specification and each operation returns an +// x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type DomainsClient struct { + ManagementClient +} + +// NewDomainsClient creates an instance of the DomainsClient client. +func NewDomainsClient(subscriptionID string) DomainsClient { + return NewDomainsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewDomainsClientWithBaseURI creates an instance of the DomainsClient client. +func NewDomainsClientWithBaseURI(baseURI string, subscriptionID string) DomainsClient { + return DomainsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdateDomain sends the create or update domain request. +// +// resourceGroupName is >Name of the resource group domainName is name of +// the domain domain is domain registration information +func (client DomainsClient) CreateOrUpdateDomain(resourceGroupName string, domainName string, domain Domain) (result Domain, ae error) { + req, err := client.CreateOrUpdateDomainPreparer(resourceGroupName, domainName, domain) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/DomainsClient", "CreateOrUpdateDomain", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateDomainSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/DomainsClient", "CreateOrUpdateDomain", "Failure sending request") + } + + result, err = client.CreateOrUpdateDomainResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/DomainsClient", "CreateOrUpdateDomain", "Failure responding to request") + } + + return +} + +// CreateOrUpdateDomainPreparer prepares the CreateOrUpdateDomain request. +func (client DomainsClient) CreateOrUpdateDomainPreparer(resourceGroupName string, domainName string, domain Domain) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "domainName": url.QueryEscape(domainName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DomainRegistration/domains/{domainName}"), + autorest.WithJSON(domain), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateDomainSender sends the CreateOrUpdateDomain request. The method will close the +// http.Response Body if it receives an error. +func (client DomainsClient) CreateOrUpdateDomainSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusAccepted, http.StatusOK) +} + +// CreateOrUpdateDomainResponder handles the response to the CreateOrUpdateDomain request. The method always +// closes the http.Response Body. +func (client DomainsClient) CreateOrUpdateDomainResponder(resp *http.Response) (result Domain, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteDomain sends the delete domain request. +// +// resourceGroupName is name of the resource group domainName is name of the +// domain forceHardDeleteDomain is if true then the domain will be deleted +// immediately instead of after 24 hours +func (client DomainsClient) DeleteDomain(resourceGroupName string, domainName string, forceHardDeleteDomain *bool) (result ObjectSet, ae error) { + req, err := client.DeleteDomainPreparer(resourceGroupName, domainName, forceHardDeleteDomain) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/DomainsClient", "DeleteDomain", "Failure preparing request") + } + + resp, err := client.DeleteDomainSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/DomainsClient", "DeleteDomain", "Failure sending request") + } + + result, err = client.DeleteDomainResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/DomainsClient", "DeleteDomain", "Failure responding to request") + } + + return +} + +// DeleteDomainPreparer prepares the DeleteDomain request. +func (client DomainsClient) DeleteDomainPreparer(resourceGroupName string, domainName string, forceHardDeleteDomain *bool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "domainName": url.QueryEscape(domainName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if forceHardDeleteDomain != nil { + queryParameters["forceHardDeleteDomain"] = forceHardDeleteDomain + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DomainRegistration/domains/{domainName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteDomainSender sends the DeleteDomain request. The method will close the +// http.Response Body if it receives an error. +func (client DomainsClient) DeleteDomainSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusNoContent) +} + +// DeleteDomainResponder handles the response to the DeleteDomain request. The method always +// closes the http.Response Body. +func (client DomainsClient) DeleteDomainResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetDomain sends the get domain request. +// +// resourceGroupName is name of the resource group domainName is name of the +// domain +func (client DomainsClient) GetDomain(resourceGroupName string, domainName string) (result Domain, ae error) { + req, err := client.GetDomainPreparer(resourceGroupName, domainName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/DomainsClient", "GetDomain", "Failure preparing request") + } + + resp, err := client.GetDomainSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/DomainsClient", "GetDomain", "Failure sending request") + } + + result, err = client.GetDomainResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/DomainsClient", "GetDomain", "Failure responding to request") + } + + return +} + +// GetDomainPreparer prepares the GetDomain request. +func (client DomainsClient) GetDomainPreparer(resourceGroupName string, domainName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "domainName": url.QueryEscape(domainName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DomainRegistration/domains/{domainName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetDomainSender sends the GetDomain request. The method will close the +// http.Response Body if it receives an error. +func (client DomainsClient) GetDomainSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetDomainResponder handles the response to the GetDomain request. The method always +// closes the http.Response Body. +func (client DomainsClient) GetDomainResponder(resp *http.Response) (result Domain, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetDomainOperation sends the get domain operation request. +// +// resourceGroupName is name of the resource group domainName is name of the +// domain operationID is domain purchase operation Id +func (client DomainsClient) GetDomainOperation(resourceGroupName string, domainName string, operationID string) (result Domain, ae error) { + req, err := client.GetDomainOperationPreparer(resourceGroupName, domainName, operationID) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/DomainsClient", "GetDomainOperation", "Failure preparing request") + } + + resp, err := client.GetDomainOperationSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/DomainsClient", "GetDomainOperation", "Failure sending request") + } + + result, err = client.GetDomainOperationResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/DomainsClient", "GetDomainOperation", "Failure responding to request") + } + + return +} + +// GetDomainOperationPreparer prepares the GetDomainOperation request. +func (client DomainsClient) GetDomainOperationPreparer(resourceGroupName string, domainName string, operationID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "domainName": url.QueryEscape(domainName), + "operationId": url.QueryEscape(operationID), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DomainRegistration/domains/{domainName}/operationresults/{operationId}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetDomainOperationSender sends the GetDomainOperation request. The method will close the +// http.Response Body if it receives an error. +func (client DomainsClient) GetDomainOperationSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusAccepted, http.StatusOK, http.StatusInternalServerError) +} + +// GetDomainOperationResponder handles the response to the GetDomainOperation request. The method always +// closes the http.Response Body. +func (client DomainsClient) GetDomainOperationResponder(resp *http.Response) (result Domain, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK, http.StatusInternalServerError), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetDomains sends the get domains request. +// +// resourceGroupName is name of the resource group +func (client DomainsClient) GetDomains(resourceGroupName string) (result DomainCollection, ae error) { + req, err := client.GetDomainsPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/DomainsClient", "GetDomains", "Failure preparing request") + } + + resp, err := client.GetDomainsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/DomainsClient", "GetDomains", "Failure sending request") + } + + result, err = client.GetDomainsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/DomainsClient", "GetDomains", "Failure responding to request") + } + + return +} + +// GetDomainsPreparer prepares the GetDomains request. +func (client DomainsClient) GetDomainsPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DomainRegistration/domains"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetDomainsSender sends the GetDomains request. The method will close the +// http.Response Body if it receives an error. +func (client DomainsClient) GetDomainsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetDomainsResponder handles the response to the GetDomains request. The method always +// closes the http.Response Body. +func (client DomainsClient) GetDomainsResponder(resp *http.Response) (result DomainCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateDomain sends the update domain request. +// +// resourceGroupName is >Name of the resource group domainName is name of +// the domain domain is domain registration information +func (client DomainsClient) UpdateDomain(resourceGroupName string, domainName string, domain Domain) (result Domain, ae error) { + req, err := client.UpdateDomainPreparer(resourceGroupName, domainName, domain) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/DomainsClient", "UpdateDomain", "Failure preparing request") + } + + resp, err := client.UpdateDomainSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/DomainsClient", "UpdateDomain", "Failure sending request") + } + + result, err = client.UpdateDomainResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/DomainsClient", "UpdateDomain", "Failure responding to request") + } + + return +} + +// UpdateDomainPreparer prepares the UpdateDomain request. +func (client DomainsClient) UpdateDomainPreparer(resourceGroupName string, domainName string, domain Domain) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "domainName": url.QueryEscape(domainName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DomainRegistration/domains/{domainName}"), + autorest.WithJSON(domain), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateDomainSender sends the UpdateDomain request. The method will close the +// http.Response Body if it receives an error. +func (client DomainsClient) UpdateDomainSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusAccepted, http.StatusOK) +} + +// UpdateDomainResponder handles the response to the UpdateDomain request. The method always +// closes the http.Response Body. +func (client DomainsClient) UpdateDomainResponder(resp *http.Response) (result Domain, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/globalcertificateorder.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/globalcertificateorder.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/globalcertificateorder.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/globalcertificateorder.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,108 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// GlobalCertificateOrderClient is the use these APIs to manage Azure Websites +// resources through the Azure Resource Manager. All task operations conform +// to the HTTP/1.1 protocol specification and each operation returns an +// x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type GlobalCertificateOrderClient struct { + ManagementClient +} + +// NewGlobalCertificateOrderClient creates an instance of the +// GlobalCertificateOrderClient client. +func NewGlobalCertificateOrderClient(subscriptionID string) GlobalCertificateOrderClient { + return NewGlobalCertificateOrderClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewGlobalCertificateOrderClientWithBaseURI creates an instance of the +// GlobalCertificateOrderClient client. +func NewGlobalCertificateOrderClientWithBaseURI(baseURI string, subscriptionID string) GlobalCertificateOrderClient { + return GlobalCertificateOrderClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// GetAllCertificateOrders sends the get all certificate orders request. +func (client GlobalCertificateOrderClient) GetAllCertificateOrders() (result CertificateOrderCollection, ae error) { + req, err := client.GetAllCertificateOrdersPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalCertificateOrderClient", "GetAllCertificateOrders", "Failure preparing request") + } + + resp, err := client.GetAllCertificateOrdersSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalCertificateOrderClient", "GetAllCertificateOrders", "Failure sending request") + } + + result, err = client.GetAllCertificateOrdersResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalCertificateOrderClient", "GetAllCertificateOrders", "Failure responding to request") + } + + return +} + +// GetAllCertificateOrdersPreparer prepares the GetAllCertificateOrders request. +func (client GlobalCertificateOrderClient) GetAllCertificateOrdersPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.CertificateRegistration/certificateOrders"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetAllCertificateOrdersSender sends the GetAllCertificateOrders request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalCertificateOrderClient) GetAllCertificateOrdersSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetAllCertificateOrdersResponder handles the response to the GetAllCertificateOrders request. The method always +// closes the http.Response Body. +func (client GlobalCertificateOrderClient) GetAllCertificateOrdersResponder(resp *http.Response) (result CertificateOrderCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/globaldomainregistration.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/globaldomainregistration.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/globaldomainregistration.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/globaldomainregistration.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,355 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// GlobalDomainRegistrationClient is the use these APIs to manage Azure +// Websites resources through the Azure Resource Manager. All task operations +// conform to the HTTP/1.1 protocol specification and each operation returns +// an x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type GlobalDomainRegistrationClient struct { + ManagementClient +} + +// NewGlobalDomainRegistrationClient creates an instance of the +// GlobalDomainRegistrationClient client. +func NewGlobalDomainRegistrationClient(subscriptionID string) GlobalDomainRegistrationClient { + return NewGlobalDomainRegistrationClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewGlobalDomainRegistrationClientWithBaseURI creates an instance of the +// GlobalDomainRegistrationClient client. +func NewGlobalDomainRegistrationClientWithBaseURI(baseURI string, subscriptionID string) GlobalDomainRegistrationClient { + return GlobalDomainRegistrationClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CheckDomainAvailability sends the check domain availability request. +// +// identifier is name of the domain +func (client GlobalDomainRegistrationClient) CheckDomainAvailability(identifier NameIdentifier) (result DomainAvailablilityCheckResult, ae error) { + req, err := client.CheckDomainAvailabilityPreparer(identifier) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "CheckDomainAvailability", "Failure preparing request") + } + + resp, err := client.CheckDomainAvailabilitySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "CheckDomainAvailability", "Failure sending request") + } + + result, err = client.CheckDomainAvailabilityResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "CheckDomainAvailability", "Failure responding to request") + } + + return +} + +// CheckDomainAvailabilityPreparer prepares the CheckDomainAvailability request. +func (client GlobalDomainRegistrationClient) CheckDomainAvailabilityPreparer(identifier NameIdentifier) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.DomainRegistration/checkDomainAvailability"), + autorest.WithJSON(identifier), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CheckDomainAvailabilitySender sends the CheckDomainAvailability request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalDomainRegistrationClient) CheckDomainAvailabilitySender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CheckDomainAvailabilityResponder handles the response to the CheckDomainAvailability request. The method always +// closes the http.Response Body. +func (client GlobalDomainRegistrationClient) CheckDomainAvailabilityResponder(resp *http.Response) (result DomainAvailablilityCheckResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetAllDomains sends the get all domains request. +func (client GlobalDomainRegistrationClient) GetAllDomains() (result DomainCollection, ae error) { + req, err := client.GetAllDomainsPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "GetAllDomains", "Failure preparing request") + } + + resp, err := client.GetAllDomainsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "GetAllDomains", "Failure sending request") + } + + result, err = client.GetAllDomainsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "GetAllDomains", "Failure responding to request") + } + + return +} + +// GetAllDomainsPreparer prepares the GetAllDomains request. +func (client GlobalDomainRegistrationClient) GetAllDomainsPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.DomainRegistration/domains"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetAllDomainsSender sends the GetAllDomains request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalDomainRegistrationClient) GetAllDomainsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetAllDomainsResponder handles the response to the GetAllDomains request. The method always +// closes the http.Response Body. +func (client GlobalDomainRegistrationClient) GetAllDomainsResponder(resp *http.Response) (result DomainCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetDomainControlCenterSsoRequest sends the get domain control center sso +// request request. +func (client GlobalDomainRegistrationClient) GetDomainControlCenterSsoRequest() (result DomainControlCenterSsoRequest, ae error) { + req, err := client.GetDomainControlCenterSsoRequestPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "GetDomainControlCenterSsoRequest", "Failure preparing request") + } + + resp, err := client.GetDomainControlCenterSsoRequestSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "GetDomainControlCenterSsoRequest", "Failure sending request") + } + + result, err = client.GetDomainControlCenterSsoRequestResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "GetDomainControlCenterSsoRequest", "Failure responding to request") + } + + return +} + +// GetDomainControlCenterSsoRequestPreparer prepares the GetDomainControlCenterSsoRequest request. +func (client GlobalDomainRegistrationClient) GetDomainControlCenterSsoRequestPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.DomainRegistration/generateSsoRequest"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetDomainControlCenterSsoRequestSender sends the GetDomainControlCenterSsoRequest request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalDomainRegistrationClient) GetDomainControlCenterSsoRequestSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetDomainControlCenterSsoRequestResponder handles the response to the GetDomainControlCenterSsoRequest request. The method always +// closes the http.Response Body. +func (client GlobalDomainRegistrationClient) GetDomainControlCenterSsoRequestResponder(resp *http.Response) (result DomainControlCenterSsoRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListDomainRecommendations sends the list domain recommendations request. +// +// parameters is domain recommendation search parameters +func (client GlobalDomainRegistrationClient) ListDomainRecommendations(parameters DomainRecommendationSearchParameters) (result NameIdentifierCollection, ae error) { + req, err := client.ListDomainRecommendationsPreparer(parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "ListDomainRecommendations", "Failure preparing request") + } + + resp, err := client.ListDomainRecommendationsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "ListDomainRecommendations", "Failure sending request") + } + + result, err = client.ListDomainRecommendationsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "ListDomainRecommendations", "Failure responding to request") + } + + return +} + +// ListDomainRecommendationsPreparer prepares the ListDomainRecommendations request. +func (client GlobalDomainRegistrationClient) ListDomainRecommendationsPreparer(parameters DomainRecommendationSearchParameters) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.DomainRegistration/listDomainRecommendations"), + autorest.WithJSON(parameters), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListDomainRecommendationsSender sends the ListDomainRecommendations request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalDomainRegistrationClient) ListDomainRecommendationsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListDomainRecommendationsResponder handles the response to the ListDomainRecommendations request. The method always +// closes the http.Response Body. +func (client GlobalDomainRegistrationClient) ListDomainRecommendationsResponder(resp *http.Response) (result NameIdentifierCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ValidateDomainPurchaseInformation sends the validate domain purchase +// information request. +// +// domainRegistrationInput is domain registration information +func (client GlobalDomainRegistrationClient) ValidateDomainPurchaseInformation(domainRegistrationInput DomainRegistrationInput) (result ObjectSet, ae error) { + req, err := client.ValidateDomainPurchaseInformationPreparer(domainRegistrationInput) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "ValidateDomainPurchaseInformation", "Failure preparing request") + } + + resp, err := client.ValidateDomainPurchaseInformationSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "ValidateDomainPurchaseInformation", "Failure sending request") + } + + result, err = client.ValidateDomainPurchaseInformationResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalDomainRegistrationClient", "ValidateDomainPurchaseInformation", "Failure responding to request") + } + + return +} + +// ValidateDomainPurchaseInformationPreparer prepares the ValidateDomainPurchaseInformation request. +func (client GlobalDomainRegistrationClient) ValidateDomainPurchaseInformationPreparer(domainRegistrationInput DomainRegistrationInput) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.DomainRegistration/validateDomainRegistrationInformation"), + autorest.WithJSON(domainRegistrationInput), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ValidateDomainPurchaseInformationSender sends the ValidateDomainPurchaseInformation request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalDomainRegistrationClient) ValidateDomainPurchaseInformationSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ValidateDomainPurchaseInformationResponder handles the response to the ValidateDomainPurchaseInformation request. The method always +// closes the http.Response Body. +func (client GlobalDomainRegistrationClient) ValidateDomainPurchaseInformationResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/global.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/global.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/global.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/global.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,846 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// GlobalClient is the use these APIs to manage Azure Websites resources +// through the Azure Resource Manager. All task operations conform to the +// HTTP/1.1 protocol specification and each operation returns an +// x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type GlobalClient struct { + ManagementClient +} + +// NewGlobalClient creates an instance of the GlobalClient client. +func NewGlobalClient(subscriptionID string) GlobalClient { + return NewGlobalClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewGlobalClientWithBaseURI creates an instance of the GlobalClient client. +func NewGlobalClientWithBaseURI(baseURI string, subscriptionID string) GlobalClient { + return GlobalClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CheckNameAvailability sends the check name availability request. +// +// request is name availability request +func (client GlobalClient) CheckNameAvailability(request ResourceNameAvailabilityRequest) (result ResourceNameAvailability, ae error) { + req, err := client.CheckNameAvailabilityPreparer(request) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "CheckNameAvailability", "Failure preparing request") + } + + resp, err := client.CheckNameAvailabilitySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "CheckNameAvailability", "Failure sending request") + } + + result, err = client.CheckNameAvailabilityResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalClient", "CheckNameAvailability", "Failure responding to request") + } + + return +} + +// CheckNameAvailabilityPreparer prepares the CheckNameAvailability request. +func (client GlobalClient) CheckNameAvailabilityPreparer(request ResourceNameAvailabilityRequest) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Web/checknameavailability"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CheckNameAvailabilitySender sends the CheckNameAvailability request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalClient) CheckNameAvailabilitySender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CheckNameAvailabilityResponder handles the response to the CheckNameAvailability request. The method always +// closes the http.Response Body. +func (client GlobalClient) CheckNameAvailabilityResponder(resp *http.Response) (result ResourceNameAvailability, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetAllClassicMobileServices sends the get all classic mobile services +// request. +func (client GlobalClient) GetAllClassicMobileServices() (result ClassicMobileServiceCollection, ae error) { + req, err := client.GetAllClassicMobileServicesPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllClassicMobileServices", "Failure preparing request") + } + + resp, err := client.GetAllClassicMobileServicesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllClassicMobileServices", "Failure sending request") + } + + result, err = client.GetAllClassicMobileServicesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllClassicMobileServices", "Failure responding to request") + } + + return +} + +// GetAllClassicMobileServicesPreparer prepares the GetAllClassicMobileServices request. +func (client GlobalClient) GetAllClassicMobileServicesPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Web/classicMobileServices"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetAllClassicMobileServicesSender sends the GetAllClassicMobileServices request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalClient) GetAllClassicMobileServicesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetAllClassicMobileServicesResponder handles the response to the GetAllClassicMobileServices request. The method always +// closes the http.Response Body. +func (client GlobalClient) GetAllClassicMobileServicesResponder(resp *http.Response) (result ClassicMobileServiceCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetAllHostingEnvironments sends the get all hosting environments request. +func (client GlobalClient) GetAllHostingEnvironments() (result HostingEnvironmentCollection, ae error) { + req, err := client.GetAllHostingEnvironmentsPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllHostingEnvironments", "Failure preparing request") + } + + resp, err := client.GetAllHostingEnvironmentsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllHostingEnvironments", "Failure sending request") + } + + result, err = client.GetAllHostingEnvironmentsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllHostingEnvironments", "Failure responding to request") + } + + return +} + +// GetAllHostingEnvironmentsPreparer prepares the GetAllHostingEnvironments request. +func (client GlobalClient) GetAllHostingEnvironmentsPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Web/hostingEnvironments"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetAllHostingEnvironmentsSender sends the GetAllHostingEnvironments request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalClient) GetAllHostingEnvironmentsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetAllHostingEnvironmentsResponder handles the response to the GetAllHostingEnvironments request. The method always +// closes the http.Response Body. +func (client GlobalClient) GetAllHostingEnvironmentsResponder(resp *http.Response) (result HostingEnvironmentCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetAllManagedHostingEnvironments sends the get all managed hosting +// environments request. +func (client GlobalClient) GetAllManagedHostingEnvironments() (result ManagedHostingEnvironmentCollection, ae error) { + req, err := client.GetAllManagedHostingEnvironmentsPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllManagedHostingEnvironments", "Failure preparing request") + } + + resp, err := client.GetAllManagedHostingEnvironmentsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllManagedHostingEnvironments", "Failure sending request") + } + + result, err = client.GetAllManagedHostingEnvironmentsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllManagedHostingEnvironments", "Failure responding to request") + } + + return +} + +// GetAllManagedHostingEnvironmentsPreparer prepares the GetAllManagedHostingEnvironments request. +func (client GlobalClient) GetAllManagedHostingEnvironmentsPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Web/managedHostingEnvironments"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetAllManagedHostingEnvironmentsSender sends the GetAllManagedHostingEnvironments request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalClient) GetAllManagedHostingEnvironmentsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetAllManagedHostingEnvironmentsResponder handles the response to the GetAllManagedHostingEnvironments request. The method always +// closes the http.Response Body. +func (client GlobalClient) GetAllManagedHostingEnvironmentsResponder(resp *http.Response) (result ManagedHostingEnvironmentCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetAllServerFarms sends the get all server farms request. +// +// detailed is false to return a subset of App Service Plan properties, true +// to return all of the properties. +// Retrieval of all properties may increase the API latency. +func (client GlobalClient) GetAllServerFarms(detailed *bool) (result ServerFarmCollection, ae error) { + req, err := client.GetAllServerFarmsPreparer(detailed) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllServerFarms", "Failure preparing request") + } + + resp, err := client.GetAllServerFarmsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllServerFarms", "Failure sending request") + } + + result, err = client.GetAllServerFarmsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllServerFarms", "Failure responding to request") + } + + return +} + +// GetAllServerFarmsPreparer prepares the GetAllServerFarms request. +func (client GlobalClient) GetAllServerFarmsPreparer(detailed *bool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if detailed != nil { + queryParameters["detailed"] = detailed + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Web/serverfarms"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetAllServerFarmsSender sends the GetAllServerFarms request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalClient) GetAllServerFarmsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetAllServerFarmsResponder handles the response to the GetAllServerFarms request. The method always +// closes the http.Response Body. +func (client GlobalClient) GetAllServerFarmsResponder(resp *http.Response) (result ServerFarmCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetAllSites sends the get all sites request. +func (client GlobalClient) GetAllSites() (result SiteCollection, ae error) { + req, err := client.GetAllSitesPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllSites", "Failure preparing request") + } + + resp, err := client.GetAllSitesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllSites", "Failure sending request") + } + + result, err = client.GetAllSitesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllSites", "Failure responding to request") + } + + return +} + +// GetAllSitesPreparer prepares the GetAllSites request. +func (client GlobalClient) GetAllSitesPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Web/sites"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetAllSitesSender sends the GetAllSites request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalClient) GetAllSitesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetAllSitesResponder handles the response to the GetAllSites request. The method always +// closes the http.Response Body. +func (client GlobalClient) GetAllSitesResponder(resp *http.Response) (result SiteCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetAllWebHostingPlans sends the get all web hosting plans request. +// +// detailed is false to return a subset of App Service Plan properties, true +// to return all of the properties. +// Retrieval of all properties may increase the API latency. +func (client GlobalClient) GetAllWebHostingPlans(detailed *bool) (result ServerFarmCollection, ae error) { + req, err := client.GetAllWebHostingPlansPreparer(detailed) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllWebHostingPlans", "Failure preparing request") + } + + resp, err := client.GetAllWebHostingPlansSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllWebHostingPlans", "Failure sending request") + } + + result, err = client.GetAllWebHostingPlansResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalClient", "GetAllWebHostingPlans", "Failure responding to request") + } + + return +} + +// GetAllWebHostingPlansPreparer prepares the GetAllWebHostingPlans request. +func (client GlobalClient) GetAllWebHostingPlansPreparer(detailed *bool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if detailed != nil { + queryParameters["detailed"] = detailed + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Web/webhostingplans"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetAllWebHostingPlansSender sends the GetAllWebHostingPlans request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalClient) GetAllWebHostingPlansSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetAllWebHostingPlansResponder handles the response to the GetAllWebHostingPlans request. The method always +// closes the http.Response Body. +func (client GlobalClient) GetAllWebHostingPlansResponder(resp *http.Response) (result ServerFarmCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSubscriptionGeoRegions sends the get subscription geo regions request. +func (client GlobalClient) GetSubscriptionGeoRegions() (result GeoRegionCollection, ae error) { + req, err := client.GetSubscriptionGeoRegionsPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetSubscriptionGeoRegions", "Failure preparing request") + } + + resp, err := client.GetSubscriptionGeoRegionsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetSubscriptionGeoRegions", "Failure sending request") + } + + result, err = client.GetSubscriptionGeoRegionsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalClient", "GetSubscriptionGeoRegions", "Failure responding to request") + } + + return +} + +// GetSubscriptionGeoRegionsPreparer prepares the GetSubscriptionGeoRegions request. +func (client GlobalClient) GetSubscriptionGeoRegionsPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Web/geoRegions"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSubscriptionGeoRegionsSender sends the GetSubscriptionGeoRegions request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalClient) GetSubscriptionGeoRegionsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSubscriptionGeoRegionsResponder handles the response to the GetSubscriptionGeoRegions request. The method always +// closes the http.Response Body. +func (client GlobalClient) GetSubscriptionGeoRegionsResponder(resp *http.Response) (result GeoRegionCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSubscriptionPublishingCredentials sends the get subscription publishing +// credentials request. +func (client GlobalClient) GetSubscriptionPublishingCredentials() (result User, ae error) { + req, err := client.GetSubscriptionPublishingCredentialsPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetSubscriptionPublishingCredentials", "Failure preparing request") + } + + resp, err := client.GetSubscriptionPublishingCredentialsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "GetSubscriptionPublishingCredentials", "Failure sending request") + } + + result, err = client.GetSubscriptionPublishingCredentialsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalClient", "GetSubscriptionPublishingCredentials", "Failure responding to request") + } + + return +} + +// GetSubscriptionPublishingCredentialsPreparer prepares the GetSubscriptionPublishingCredentials request. +func (client GlobalClient) GetSubscriptionPublishingCredentialsPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Web/publishingCredentials"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSubscriptionPublishingCredentialsSender sends the GetSubscriptionPublishingCredentials request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalClient) GetSubscriptionPublishingCredentialsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSubscriptionPublishingCredentialsResponder handles the response to the GetSubscriptionPublishingCredentials request. The method always +// closes the http.Response Body. +func (client GlobalClient) GetSubscriptionPublishingCredentialsResponder(resp *http.Response) (result User, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// IsHostingEnvironmentNameAvailable sends the is hosting environment name +// available request. +// +// name is hosting environment name +func (client GlobalClient) IsHostingEnvironmentNameAvailable(name string) (result ObjectSet, ae error) { + req, err := client.IsHostingEnvironmentNameAvailablePreparer(name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "IsHostingEnvironmentNameAvailable", "Failure preparing request") + } + + resp, err := client.IsHostingEnvironmentNameAvailableSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "IsHostingEnvironmentNameAvailable", "Failure sending request") + } + + result, err = client.IsHostingEnvironmentNameAvailableResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalClient", "IsHostingEnvironmentNameAvailable", "Failure responding to request") + } + + return +} + +// IsHostingEnvironmentNameAvailablePreparer prepares the IsHostingEnvironmentNameAvailable request. +func (client GlobalClient) IsHostingEnvironmentNameAvailablePreparer(name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + "name": name, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Web/ishostingenvironmentnameavailable"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// IsHostingEnvironmentNameAvailableSender sends the IsHostingEnvironmentNameAvailable request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalClient) IsHostingEnvironmentNameAvailableSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// IsHostingEnvironmentNameAvailableResponder handles the response to the IsHostingEnvironmentNameAvailable request. The method always +// closes the http.Response Body. +func (client GlobalClient) IsHostingEnvironmentNameAvailableResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// IsHostingEnvironmentWithLegacyNameAvailable sends the is hosting +// environment with legacy name available request. +// +// name is hosting environment name +func (client GlobalClient) IsHostingEnvironmentWithLegacyNameAvailable(name string) (result ObjectSet, ae error) { + req, err := client.IsHostingEnvironmentWithLegacyNameAvailablePreparer(name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "IsHostingEnvironmentWithLegacyNameAvailable", "Failure preparing request") + } + + resp, err := client.IsHostingEnvironmentWithLegacyNameAvailableSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "IsHostingEnvironmentWithLegacyNameAvailable", "Failure sending request") + } + + result, err = client.IsHostingEnvironmentWithLegacyNameAvailableResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalClient", "IsHostingEnvironmentWithLegacyNameAvailable", "Failure responding to request") + } + + return +} + +// IsHostingEnvironmentWithLegacyNameAvailablePreparer prepares the IsHostingEnvironmentWithLegacyNameAvailable request. +func (client GlobalClient) IsHostingEnvironmentWithLegacyNameAvailablePreparer(name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Web/ishostingenvironmentnameavailable/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// IsHostingEnvironmentWithLegacyNameAvailableSender sends the IsHostingEnvironmentWithLegacyNameAvailable request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalClient) IsHostingEnvironmentWithLegacyNameAvailableSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// IsHostingEnvironmentWithLegacyNameAvailableResponder handles the response to the IsHostingEnvironmentWithLegacyNameAvailable request. The method always +// closes the http.Response Body. +func (client GlobalClient) IsHostingEnvironmentWithLegacyNameAvailableResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListPremierAddOnOffers sends the list premier add on offers request. +func (client GlobalClient) ListPremierAddOnOffers() (result ObjectSet, ae error) { + req, err := client.ListPremierAddOnOffersPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "ListPremierAddOnOffers", "Failure preparing request") + } + + resp, err := client.ListPremierAddOnOffersSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "ListPremierAddOnOffers", "Failure sending request") + } + + result, err = client.ListPremierAddOnOffersResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalClient", "ListPremierAddOnOffers", "Failure responding to request") + } + + return +} + +// ListPremierAddOnOffersPreparer prepares the ListPremierAddOnOffers request. +func (client GlobalClient) ListPremierAddOnOffersPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Web/premieraddonoffers"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListPremierAddOnOffersSender sends the ListPremierAddOnOffers request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalClient) ListPremierAddOnOffersSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListPremierAddOnOffersResponder handles the response to the ListPremierAddOnOffers request. The method always +// closes the http.Response Body. +func (client GlobalClient) ListPremierAddOnOffersResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSubscriptionPublishingCredentials sends the update subscription +// publishing credentials request. +// +// requestMessage is requestMessage with new publishing credentials +func (client GlobalClient) UpdateSubscriptionPublishingCredentials(requestMessage User) (result User, ae error) { + req, err := client.UpdateSubscriptionPublishingCredentialsPreparer(requestMessage) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "UpdateSubscriptionPublishingCredentials", "Failure preparing request") + } + + resp, err := client.UpdateSubscriptionPublishingCredentialsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/GlobalClient", "UpdateSubscriptionPublishingCredentials", "Failure sending request") + } + + result, err = client.UpdateSubscriptionPublishingCredentialsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalClient", "UpdateSubscriptionPublishingCredentials", "Failure responding to request") + } + + return +} + +// UpdateSubscriptionPublishingCredentialsPreparer prepares the UpdateSubscriptionPublishingCredentials request. +func (client GlobalClient) UpdateSubscriptionPublishingCredentialsPreparer(requestMessage User) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.Web/publishingCredentials"), + autorest.WithJSON(requestMessage), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSubscriptionPublishingCredentialsSender sends the UpdateSubscriptionPublishingCredentials request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalClient) UpdateSubscriptionPublishingCredentialsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSubscriptionPublishingCredentialsResponder handles the response to the UpdateSubscriptionPublishingCredentials request. The method always +// closes the http.Response Body. +func (client GlobalClient) UpdateSubscriptionPublishingCredentialsResponder(resp *http.Response) (result User, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/globalresourcegroups.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/globalresourcegroups.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/globalresourcegroups.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/globalresourcegroups.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,110 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// GlobalResourceGroupsClient is the use these APIs to manage Azure Websites +// resources through the Azure Resource Manager. All task operations conform +// to the HTTP/1.1 protocol specification and each operation returns an +// x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type GlobalResourceGroupsClient struct { + ManagementClient +} + +// NewGlobalResourceGroupsClient creates an instance of the +// GlobalResourceGroupsClient client. +func NewGlobalResourceGroupsClient(subscriptionID string) GlobalResourceGroupsClient { + return NewGlobalResourceGroupsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewGlobalResourceGroupsClientWithBaseURI creates an instance of the +// GlobalResourceGroupsClient client. +func NewGlobalResourceGroupsClientWithBaseURI(baseURI string, subscriptionID string) GlobalResourceGroupsClient { + return GlobalResourceGroupsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// MoveResources sends the move resources request. +// +func (client GlobalResourceGroupsClient) MoveResources(resourceGroupName string, moveResourceEnvelope CsmMoveResourceEnvelope) (result autorest.Response, ae error) { + req, err := client.MoveResourcesPreparer(resourceGroupName, moveResourceEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/GlobalResourceGroupsClient", "MoveResources", "Failure preparing request") + } + + resp, err := client.MoveResourcesSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "web/GlobalResourceGroupsClient", "MoveResources", "Failure sending request") + } + + result, err = client.MoveResourcesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/GlobalResourceGroupsClient", "MoveResources", "Failure responding to request") + } + + return +} + +// MoveResourcesPreparer prepares the MoveResources request. +func (client GlobalResourceGroupsClient) MoveResourcesPreparer(resourceGroupName string, moveResourceEnvelope CsmMoveResourceEnvelope) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/moveResources"), + autorest.WithJSON(moveResourceEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// MoveResourcesSender sends the MoveResources request. The method will close the +// http.Response Body if it receives an error. +func (client GlobalResourceGroupsClient) MoveResourcesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusNoContent) +} + +// MoveResourcesResponder handles the response to the MoveResources request. The method always +// closes the http.Response Body. +func (client GlobalResourceGroupsClient) MoveResourcesResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/hostingenvironments.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/hostingenvironments.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/hostingenvironments.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/hostingenvironments.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,2539 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// HostingEnvironmentsClient is the use these APIs to manage Azure Websites +// resources through the Azure Resource Manager. All task operations conform +// to the HTTP/1.1 protocol specification and each operation returns an +// x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type HostingEnvironmentsClient struct { + ManagementClient +} + +// NewHostingEnvironmentsClient creates an instance of the +// HostingEnvironmentsClient client. +func NewHostingEnvironmentsClient(subscriptionID string) HostingEnvironmentsClient { + return NewHostingEnvironmentsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewHostingEnvironmentsClientWithBaseURI creates an instance of the +// HostingEnvironmentsClient client. +func NewHostingEnvironmentsClientWithBaseURI(baseURI string, subscriptionID string) HostingEnvironmentsClient { + return HostingEnvironmentsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdateHostingEnvironment sends the create or update hosting +// environment request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) hostingEnvironmentEnvelope is +// properties of hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) CreateOrUpdateHostingEnvironment(resourceGroupName string, name string, hostingEnvironmentEnvelope HostingEnvironment) (result HostingEnvironment, ae error) { + req, err := client.CreateOrUpdateHostingEnvironmentPreparer(resourceGroupName, name, hostingEnvironmentEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "CreateOrUpdateHostingEnvironment", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateHostingEnvironmentSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "CreateOrUpdateHostingEnvironment", "Failure sending request") + } + + result, err = client.CreateOrUpdateHostingEnvironmentResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "CreateOrUpdateHostingEnvironment", "Failure responding to request") + } + + return +} + +// CreateOrUpdateHostingEnvironmentPreparer prepares the CreateOrUpdateHostingEnvironment request. +func (client HostingEnvironmentsClient) CreateOrUpdateHostingEnvironmentPreparer(resourceGroupName string, name string, hostingEnvironmentEnvelope HostingEnvironment) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}"), + autorest.WithJSON(hostingEnvironmentEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateHostingEnvironmentSender sends the CreateOrUpdateHostingEnvironment request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) CreateOrUpdateHostingEnvironmentSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusBadRequest, http.StatusNotFound, http.StatusConflict) +} + +// CreateOrUpdateHostingEnvironmentResponder handles the response to the CreateOrUpdateHostingEnvironment request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) CreateOrUpdateHostingEnvironmentResponder(resp *http.Response) (result HostingEnvironment, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusBadRequest, http.StatusNotFound, http.StatusConflict), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateMultiRolePool sends the create or update multi role pool +// request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) multiRolePoolEnvelope is +// properties of multiRole pool +func (client HostingEnvironmentsClient) CreateOrUpdateMultiRolePool(resourceGroupName string, name string, multiRolePoolEnvelope WorkerPool) (result WorkerPool, ae error) { + req, err := client.CreateOrUpdateMultiRolePoolPreparer(resourceGroupName, name, multiRolePoolEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "CreateOrUpdateMultiRolePool", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateMultiRolePoolSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "CreateOrUpdateMultiRolePool", "Failure sending request") + } + + result, err = client.CreateOrUpdateMultiRolePoolResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "CreateOrUpdateMultiRolePool", "Failure responding to request") + } + + return +} + +// CreateOrUpdateMultiRolePoolPreparer prepares the CreateOrUpdateMultiRolePool request. +func (client HostingEnvironmentsClient) CreateOrUpdateMultiRolePoolPreparer(resourceGroupName string, name string, multiRolePoolEnvelope WorkerPool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/multiRolePools/default"), + autorest.WithJSON(multiRolePoolEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateMultiRolePoolSender sends the CreateOrUpdateMultiRolePool request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) CreateOrUpdateMultiRolePoolSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusBadRequest, http.StatusNotFound, http.StatusConflict) +} + +// CreateOrUpdateMultiRolePoolResponder handles the response to the CreateOrUpdateMultiRolePool request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) CreateOrUpdateMultiRolePoolResponder(resp *http.Response) (result WorkerPool, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusBadRequest, http.StatusNotFound, http.StatusConflict), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateWorkerPool sends the create or update worker pool request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) workerPoolName is name of +// worker pool workerPoolEnvelope is properties of worker pool +func (client HostingEnvironmentsClient) CreateOrUpdateWorkerPool(resourceGroupName string, name string, workerPoolName string, workerPoolEnvelope WorkerPool) (result WorkerPool, ae error) { + req, err := client.CreateOrUpdateWorkerPoolPreparer(resourceGroupName, name, workerPoolName, workerPoolEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "CreateOrUpdateWorkerPool", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateWorkerPoolSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "CreateOrUpdateWorkerPool", "Failure sending request") + } + + result, err = client.CreateOrUpdateWorkerPoolResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "CreateOrUpdateWorkerPool", "Failure responding to request") + } + + return +} + +// CreateOrUpdateWorkerPoolPreparer prepares the CreateOrUpdateWorkerPool request. +func (client HostingEnvironmentsClient) CreateOrUpdateWorkerPoolPreparer(resourceGroupName string, name string, workerPoolName string, workerPoolEnvelope WorkerPool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "workerPoolName": url.QueryEscape(workerPoolName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/workerPools/{workerPoolName}"), + autorest.WithJSON(workerPoolEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateWorkerPoolSender sends the CreateOrUpdateWorkerPool request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) CreateOrUpdateWorkerPoolSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusBadRequest, http.StatusNotFound, http.StatusConflict) +} + +// CreateOrUpdateWorkerPoolResponder handles the response to the CreateOrUpdateWorkerPool request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) CreateOrUpdateWorkerPoolResponder(resp *http.Response) (result WorkerPool, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusBadRequest, http.StatusNotFound, http.StatusConflict), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteHostingEnvironment sends the delete hosting environment request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) forceDelete is delete even if +// the hostingEnvironment (App Service Environment) contains resources +func (client HostingEnvironmentsClient) DeleteHostingEnvironment(resourceGroupName string, name string, forceDelete *bool) (result ObjectSet, ae error) { + req, err := client.DeleteHostingEnvironmentPreparer(resourceGroupName, name, forceDelete) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "DeleteHostingEnvironment", "Failure preparing request") + } + + resp, err := client.DeleteHostingEnvironmentSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "DeleteHostingEnvironment", "Failure sending request") + } + + result, err = client.DeleteHostingEnvironmentResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "DeleteHostingEnvironment", "Failure responding to request") + } + + return +} + +// DeleteHostingEnvironmentPreparer prepares the DeleteHostingEnvironment request. +func (client HostingEnvironmentsClient) DeleteHostingEnvironmentPreparer(resourceGroupName string, name string, forceDelete *bool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if forceDelete != nil { + queryParameters["forceDelete"] = forceDelete + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteHostingEnvironmentSender sends the DeleteHostingEnvironment request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) DeleteHostingEnvironmentSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusBadRequest, http.StatusNotFound, http.StatusConflict) +} + +// DeleteHostingEnvironmentResponder handles the response to the DeleteHostingEnvironment request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) DeleteHostingEnvironmentResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusBadRequest, http.StatusNotFound, http.StatusConflict), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironment sends the get hosting environment request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) GetHostingEnvironment(resourceGroupName string, name string) (result HostingEnvironment, ae error) { + req, err := client.GetHostingEnvironmentPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironment", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironment", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironment", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentPreparer prepares the GetHostingEnvironment request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentSender sends the GetHostingEnvironment request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentResponder handles the response to the GetHostingEnvironment request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentResponder(resp *http.Response) (result HostingEnvironment, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentCapacities sends the get hosting environment +// capacities request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) GetHostingEnvironmentCapacities(resourceGroupName string, name string) (result StampCapacityCollection, ae error) { + req, err := client.GetHostingEnvironmentCapacitiesPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentCapacities", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentCapacitiesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentCapacities", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentCapacitiesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentCapacities", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentCapacitiesPreparer prepares the GetHostingEnvironmentCapacities request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentCapacitiesPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/capacities/compute"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentCapacitiesSender sends the GetHostingEnvironmentCapacities request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentCapacitiesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentCapacitiesResponder handles the response to the GetHostingEnvironmentCapacities request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentCapacitiesResponder(resp *http.Response) (result StampCapacityCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentDiagnostics sends the get hosting environment +// diagnostics request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) GetHostingEnvironmentDiagnostics(resourceGroupName string, name string) (result HostingEnvironmentDiagnosticsList, ae error) { + req, err := client.GetHostingEnvironmentDiagnosticsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentDiagnostics", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentDiagnosticsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentDiagnostics", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentDiagnosticsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentDiagnostics", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentDiagnosticsPreparer prepares the GetHostingEnvironmentDiagnostics request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentDiagnosticsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/diagnostics"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentDiagnosticsSender sends the GetHostingEnvironmentDiagnostics request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentDiagnosticsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentDiagnosticsResponder handles the response to the GetHostingEnvironmentDiagnostics request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentDiagnosticsResponder(resp *http.Response) (result HostingEnvironmentDiagnosticsList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentDiagnosticsItem sends the get hosting environment +// diagnostics item request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) diagnosticsName is name of +// the diagnostics +func (client HostingEnvironmentsClient) GetHostingEnvironmentDiagnosticsItem(resourceGroupName string, name string, diagnosticsName string) (result HostingEnvironmentDiagnostics, ae error) { + req, err := client.GetHostingEnvironmentDiagnosticsItemPreparer(resourceGroupName, name, diagnosticsName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentDiagnosticsItem", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentDiagnosticsItemSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentDiagnosticsItem", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentDiagnosticsItemResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentDiagnosticsItem", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentDiagnosticsItemPreparer prepares the GetHostingEnvironmentDiagnosticsItem request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentDiagnosticsItemPreparer(resourceGroupName string, name string, diagnosticsName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "diagnosticsName": url.QueryEscape(diagnosticsName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/diagnostics/{diagnosticsName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentDiagnosticsItemSender sends the GetHostingEnvironmentDiagnosticsItem request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentDiagnosticsItemSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentDiagnosticsItemResponder handles the response to the GetHostingEnvironmentDiagnosticsItem request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentDiagnosticsItemResponder(resp *http.Response) (result HostingEnvironmentDiagnostics, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentMetricDefinitions sends the get hosting environment +// metric definitions request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) GetHostingEnvironmentMetricDefinitions(resourceGroupName string, name string) (result MetricDefinition, ae error) { + req, err := client.GetHostingEnvironmentMetricDefinitionsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMetricDefinitions", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentMetricDefinitionsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMetricDefinitions", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentMetricDefinitionsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMetricDefinitions", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentMetricDefinitionsPreparer prepares the GetHostingEnvironmentMetricDefinitions request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMetricDefinitionsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/metricdefinitions"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentMetricDefinitionsSender sends the GetHostingEnvironmentMetricDefinitions request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMetricDefinitionsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentMetricDefinitionsResponder handles the response to the GetHostingEnvironmentMetricDefinitions request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMetricDefinitionsResponder(resp *http.Response) (result MetricDefinition, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentMetrics sends the get hosting environment metrics +// request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) details is include instance +// details filter is return only usages/metrics specified in the filter. +// Filter conforms to odata syntax. Example: $filter=(name.value eq 'Metric1' +// or name.value eq 'Metric2') and startTime eq '2014-01-01T00:00:00Z' and +// endTime eq '2014-12-31T23:59:59Z' and timeGrain eq +// duration'[Hour|Minute|Day]'. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMetrics(resourceGroupName string, name string, details *bool, filter string) (result ResourceMetricCollection, ae error) { + req, err := client.GetHostingEnvironmentMetricsPreparer(resourceGroupName, name, details, filter) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMetrics", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentMetricsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMetrics", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentMetricsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMetrics", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentMetricsPreparer prepares the GetHostingEnvironmentMetrics request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMetricsPreparer(resourceGroupName string, name string, details *bool, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if details != nil { + queryParameters["details"] = details + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/metrics"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentMetricsSender sends the GetHostingEnvironmentMetrics request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMetricsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentMetricsResponder handles the response to the GetHostingEnvironmentMetrics request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMetricsResponder(resp *http.Response) (result ResourceMetricCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentMultiRoleMetricDefinitions sends the get hosting +// environment multi role metric definitions request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) GetHostingEnvironmentMultiRoleMetricDefinitions(resourceGroupName string, name string) (result MetricDefinitionCollection, ae error) { + req, err := client.GetHostingEnvironmentMultiRoleMetricDefinitionsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMultiRoleMetricDefinitions", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentMultiRoleMetricDefinitionsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMultiRoleMetricDefinitions", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentMultiRoleMetricDefinitionsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMultiRoleMetricDefinitions", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentMultiRoleMetricDefinitionsPreparer prepares the GetHostingEnvironmentMultiRoleMetricDefinitions request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMultiRoleMetricDefinitionsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/multiRolePools/default/metricdefinitions"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentMultiRoleMetricDefinitionsSender sends the GetHostingEnvironmentMultiRoleMetricDefinitions request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMultiRoleMetricDefinitionsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentMultiRoleMetricDefinitionsResponder handles the response to the GetHostingEnvironmentMultiRoleMetricDefinitions request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMultiRoleMetricDefinitionsResponder(resp *http.Response) (result MetricDefinitionCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentMultiRoleMetrics sends the get hosting environment +// multi role metrics request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) startTime is beginning time +// of metrics query endTime is end time of metrics query timeGrain is time +// granularity of metrics query details is include instance details filter is +// return only usages/metrics specified in the filter. Filter conforms to +// odata syntax. Example: $filter=(name.value eq 'Metric1' or name.value eq +// 'Metric2') and startTime eq '2014-01-01T00:00:00Z' and endTime eq +// '2014-12-31T23:59:59Z' and timeGrain eq duration'[Hour|Minute|Day]'. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMultiRoleMetrics(resourceGroupName string, name string, startTime string, endTime string, timeGrain string, details *bool, filter string) (result ResourceMetricCollection, ae error) { + req, err := client.GetHostingEnvironmentMultiRoleMetricsPreparer(resourceGroupName, name, startTime, endTime, timeGrain, details, filter) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMultiRoleMetrics", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentMultiRoleMetricsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMultiRoleMetrics", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentMultiRoleMetricsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMultiRoleMetrics", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentMultiRoleMetricsPreparer prepares the GetHostingEnvironmentMultiRoleMetrics request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMultiRoleMetricsPreparer(resourceGroupName string, name string, startTime string, endTime string, timeGrain string, details *bool, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(startTime) > 0 { + queryParameters["startTime"] = startTime + } + if len(endTime) > 0 { + queryParameters["endTime"] = endTime + } + if len(timeGrain) > 0 { + queryParameters["timeGrain"] = timeGrain + } + if details != nil { + queryParameters["details"] = details + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/multiRolePools/default/metrics"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentMultiRoleMetricsSender sends the GetHostingEnvironmentMultiRoleMetrics request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMultiRoleMetricsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentMultiRoleMetricsResponder handles the response to the GetHostingEnvironmentMultiRoleMetrics request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMultiRoleMetricsResponder(resp *http.Response) (result ResourceMetricCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentMultiRoleUsages sends the get hosting environment +// multi role usages request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) GetHostingEnvironmentMultiRoleUsages(resourceGroupName string, name string) (result UsageCollection, ae error) { + req, err := client.GetHostingEnvironmentMultiRoleUsagesPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMultiRoleUsages", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentMultiRoleUsagesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMultiRoleUsages", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentMultiRoleUsagesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentMultiRoleUsages", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentMultiRoleUsagesPreparer prepares the GetHostingEnvironmentMultiRoleUsages request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMultiRoleUsagesPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/multiRolePools/default/usages"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentMultiRoleUsagesSender sends the GetHostingEnvironmentMultiRoleUsages request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMultiRoleUsagesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentMultiRoleUsagesResponder handles the response to the GetHostingEnvironmentMultiRoleUsages request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentMultiRoleUsagesResponder(resp *http.Response) (result UsageCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentOperation sends the get hosting environment operation +// request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) operationID is operation +// identifier GUID +func (client HostingEnvironmentsClient) GetHostingEnvironmentOperation(resourceGroupName string, name string, operationID string) (result ObjectSet, ae error) { + req, err := client.GetHostingEnvironmentOperationPreparer(resourceGroupName, name, operationID) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentOperation", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentOperationSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentOperation", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentOperationResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentOperation", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentOperationPreparer prepares the GetHostingEnvironmentOperation request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentOperationPreparer(resourceGroupName string, name string, operationID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "operationId": url.QueryEscape(operationID), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/operations/{operationId}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentOperationSender sends the GetHostingEnvironmentOperation request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentOperationSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusNotFound, http.StatusInternalServerError) +} + +// GetHostingEnvironmentOperationResponder handles the response to the GetHostingEnvironmentOperation request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentOperationResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNotFound, http.StatusInternalServerError), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentOperations sends the get hosting environment +// operations request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) GetHostingEnvironmentOperations(resourceGroupName string, name string) (result ObjectSet, ae error) { + req, err := client.GetHostingEnvironmentOperationsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentOperations", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentOperationsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentOperations", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentOperationsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentOperations", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentOperationsPreparer prepares the GetHostingEnvironmentOperations request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentOperationsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/operations"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentOperationsSender sends the GetHostingEnvironmentOperations request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentOperationsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentOperationsResponder handles the response to the GetHostingEnvironmentOperations request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentOperationsResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironments sends the get hosting environments request. +// +// resourceGroupName is name of resource group +func (client HostingEnvironmentsClient) GetHostingEnvironments(resourceGroupName string) (result HostingEnvironmentCollection, ae error) { + req, err := client.GetHostingEnvironmentsPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironments", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironments", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironments", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentsPreparer prepares the GetHostingEnvironments request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentsPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentsSender sends the GetHostingEnvironments request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentsResponder handles the response to the GetHostingEnvironments request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentsResponder(resp *http.Response) (result HostingEnvironmentCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentServerFarms sends the get hosting environment server +// farms request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) GetHostingEnvironmentServerFarms(resourceGroupName string, name string) (result ServerFarmCollection, ae error) { + req, err := client.GetHostingEnvironmentServerFarmsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentServerFarms", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentServerFarmsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentServerFarms", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentServerFarmsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentServerFarms", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentServerFarmsPreparer prepares the GetHostingEnvironmentServerFarms request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentServerFarmsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/serverfarms"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentServerFarmsSender sends the GetHostingEnvironmentServerFarms request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentServerFarmsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentServerFarmsResponder handles the response to the GetHostingEnvironmentServerFarms request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentServerFarmsResponder(resp *http.Response) (result ServerFarmCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentSites sends the get hosting environment sites request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) propertiesToInclude is comma +// separated list of site properties to include +func (client HostingEnvironmentsClient) GetHostingEnvironmentSites(resourceGroupName string, name string, propertiesToInclude string) (result SiteCollection, ae error) { + req, err := client.GetHostingEnvironmentSitesPreparer(resourceGroupName, name, propertiesToInclude) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentSites", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentSitesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentSites", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentSitesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentSites", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentSitesPreparer prepares the GetHostingEnvironmentSites request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentSitesPreparer(resourceGroupName string, name string, propertiesToInclude string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(propertiesToInclude) > 0 { + queryParameters["propertiesToInclude"] = propertiesToInclude + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/sites"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentSitesSender sends the GetHostingEnvironmentSites request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentSitesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentSitesResponder handles the response to the GetHostingEnvironmentSites request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentSitesResponder(resp *http.Response) (result SiteCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentUsages sends the get hosting environment usages +// request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) filter is return only +// usages/metrics specified in the filter. Filter conforms to odata syntax. +// Example: $filter=(name.value eq 'Metric1' or name.value eq 'Metric2') and +// startTime eq '2014-01-01T00:00:00Z' and endTime eq '2014-12-31T23:59:59Z' +// and timeGrain eq duration'[Hour|Minute|Day]'. +func (client HostingEnvironmentsClient) GetHostingEnvironmentUsages(resourceGroupName string, name string, filter string) (result CsmUsageQuotaCollection, ae error) { + req, err := client.GetHostingEnvironmentUsagesPreparer(resourceGroupName, name, filter) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentUsages", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentUsagesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentUsages", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentUsagesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentUsages", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentUsagesPreparer prepares the GetHostingEnvironmentUsages request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentUsagesPreparer(resourceGroupName string, name string, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/usages"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentUsagesSender sends the GetHostingEnvironmentUsages request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentUsagesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentUsagesResponder handles the response to the GetHostingEnvironmentUsages request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentUsagesResponder(resp *http.Response) (result CsmUsageQuotaCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentVips sends the get hosting environment vips request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) GetHostingEnvironmentVips(resourceGroupName string, name string) (result AddressResponse, ae error) { + req, err := client.GetHostingEnvironmentVipsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentVips", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentVipsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentVips", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentVipsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentVips", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentVipsPreparer prepares the GetHostingEnvironmentVips request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentVipsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/capacities/virtualip"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentVipsSender sends the GetHostingEnvironmentVips request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentVipsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentVipsResponder handles the response to the GetHostingEnvironmentVips request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentVipsResponder(resp *http.Response) (result AddressResponse, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentWebHostingPlans sends the get hosting environment web +// hosting plans request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebHostingPlans(resourceGroupName string, name string) (result ServerFarmCollection, ae error) { + req, err := client.GetHostingEnvironmentWebHostingPlansPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentWebHostingPlans", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentWebHostingPlansSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentWebHostingPlans", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentWebHostingPlansResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentWebHostingPlans", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentWebHostingPlansPreparer prepares the GetHostingEnvironmentWebHostingPlans request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebHostingPlansPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/webhostingplans"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentWebHostingPlansSender sends the GetHostingEnvironmentWebHostingPlans request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebHostingPlansSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentWebHostingPlansResponder handles the response to the GetHostingEnvironmentWebHostingPlans request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebHostingPlansResponder(resp *http.Response) (result ServerFarmCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentWebWorkerMetricDefinitions sends the get hosting +// environment web worker metric definitions request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) workerPoolName is name of +// worker pool +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebWorkerMetricDefinitions(resourceGroupName string, name string, workerPoolName string) (result MetricDefinitionCollection, ae error) { + req, err := client.GetHostingEnvironmentWebWorkerMetricDefinitionsPreparer(resourceGroupName, name, workerPoolName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentWebWorkerMetricDefinitions", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentWebWorkerMetricDefinitionsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentWebWorkerMetricDefinitions", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentWebWorkerMetricDefinitionsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentWebWorkerMetricDefinitions", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentWebWorkerMetricDefinitionsPreparer prepares the GetHostingEnvironmentWebWorkerMetricDefinitions request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebWorkerMetricDefinitionsPreparer(resourceGroupName string, name string, workerPoolName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "workerPoolName": url.QueryEscape(workerPoolName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/workerPools/{workerPoolName}/metricdefinitions"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentWebWorkerMetricDefinitionsSender sends the GetHostingEnvironmentWebWorkerMetricDefinitions request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebWorkerMetricDefinitionsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentWebWorkerMetricDefinitionsResponder handles the response to the GetHostingEnvironmentWebWorkerMetricDefinitions request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebWorkerMetricDefinitionsResponder(resp *http.Response) (result MetricDefinitionCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentWebWorkerMetrics sends the get hosting environment web +// worker metrics request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) workerPoolName is name of +// worker pool details is include instance details filter is return only +// usages/metrics specified in the filter. Filter conforms to odata syntax. +// Example: $filter=(name.value eq 'Metric1' or name.value eq 'Metric2') and +// startTime eq '2014-01-01T00:00:00Z' and endTime eq '2014-12-31T23:59:59Z' +// and timeGrain eq duration'[Hour|Minute|Day]'. +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebWorkerMetrics(resourceGroupName string, name string, workerPoolName string, details *bool, filter string) (result ResourceMetricCollection, ae error) { + req, err := client.GetHostingEnvironmentWebWorkerMetricsPreparer(resourceGroupName, name, workerPoolName, details, filter) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentWebWorkerMetrics", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentWebWorkerMetricsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentWebWorkerMetrics", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentWebWorkerMetricsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentWebWorkerMetrics", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentWebWorkerMetricsPreparer prepares the GetHostingEnvironmentWebWorkerMetrics request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebWorkerMetricsPreparer(resourceGroupName string, name string, workerPoolName string, details *bool, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "workerPoolName": url.QueryEscape(workerPoolName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if details != nil { + queryParameters["details"] = details + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/workerPools/{workerPoolName}/metrics"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentWebWorkerMetricsSender sends the GetHostingEnvironmentWebWorkerMetrics request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebWorkerMetricsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentWebWorkerMetricsResponder handles the response to the GetHostingEnvironmentWebWorkerMetrics request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebWorkerMetricsResponder(resp *http.Response) (result ResourceMetricCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetHostingEnvironmentWebWorkerUsages sends the get hosting environment web +// worker usages request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) workerPoolName is name of +// worker pool +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebWorkerUsages(resourceGroupName string, name string, workerPoolName string) (result UsageCollection, ae error) { + req, err := client.GetHostingEnvironmentWebWorkerUsagesPreparer(resourceGroupName, name, workerPoolName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentWebWorkerUsages", "Failure preparing request") + } + + resp, err := client.GetHostingEnvironmentWebWorkerUsagesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentWebWorkerUsages", "Failure sending request") + } + + result, err = client.GetHostingEnvironmentWebWorkerUsagesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetHostingEnvironmentWebWorkerUsages", "Failure responding to request") + } + + return +} + +// GetHostingEnvironmentWebWorkerUsagesPreparer prepares the GetHostingEnvironmentWebWorkerUsages request. +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebWorkerUsagesPreparer(resourceGroupName string, name string, workerPoolName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "workerPoolName": url.QueryEscape(workerPoolName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/workerPools/{workerPoolName}/usages"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetHostingEnvironmentWebWorkerUsagesSender sends the GetHostingEnvironmentWebWorkerUsages request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebWorkerUsagesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetHostingEnvironmentWebWorkerUsagesResponder handles the response to the GetHostingEnvironmentWebWorkerUsages request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetHostingEnvironmentWebWorkerUsagesResponder(resp *http.Response) (result UsageCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetMultiRolePool sends the get multi role pool request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) GetMultiRolePool(resourceGroupName string, name string) (result WorkerPool, ae error) { + req, err := client.GetMultiRolePoolPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePool", "Failure preparing request") + } + + resp, err := client.GetMultiRolePoolSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePool", "Failure sending request") + } + + result, err = client.GetMultiRolePoolResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePool", "Failure responding to request") + } + + return +} + +// GetMultiRolePoolPreparer prepares the GetMultiRolePool request. +func (client HostingEnvironmentsClient) GetMultiRolePoolPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/multiRolePools/default"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetMultiRolePoolSender sends the GetMultiRolePool request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetMultiRolePoolSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetMultiRolePoolResponder handles the response to the GetMultiRolePool request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetMultiRolePoolResponder(resp *http.Response) (result WorkerPool, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetMultiRolePoolInstanceMetricDefinitions sends the get multi role pool +// instance metric definitions request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) instance is name of instance +// in the multiRole pool> +func (client HostingEnvironmentsClient) GetMultiRolePoolInstanceMetricDefinitions(resourceGroupName string, name string, instance string) (result ObjectSet, ae error) { + req, err := client.GetMultiRolePoolInstanceMetricDefinitionsPreparer(resourceGroupName, name, instance) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePoolInstanceMetricDefinitions", "Failure preparing request") + } + + resp, err := client.GetMultiRolePoolInstanceMetricDefinitionsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePoolInstanceMetricDefinitions", "Failure sending request") + } + + result, err = client.GetMultiRolePoolInstanceMetricDefinitionsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePoolInstanceMetricDefinitions", "Failure responding to request") + } + + return +} + +// GetMultiRolePoolInstanceMetricDefinitionsPreparer prepares the GetMultiRolePoolInstanceMetricDefinitions request. +func (client HostingEnvironmentsClient) GetMultiRolePoolInstanceMetricDefinitionsPreparer(resourceGroupName string, name string, instance string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instance": url.QueryEscape(instance), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/multiRolePools/default/instances/{instance}/metricdefinitions"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetMultiRolePoolInstanceMetricDefinitionsSender sends the GetMultiRolePoolInstanceMetricDefinitions request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetMultiRolePoolInstanceMetricDefinitionsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetMultiRolePoolInstanceMetricDefinitionsResponder handles the response to the GetMultiRolePoolInstanceMetricDefinitions request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetMultiRolePoolInstanceMetricDefinitionsResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetMultiRolePoolInstanceMetrics sends the get multi role pool instance +// metrics request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) instance is name of instance +// in the multiRole pool details is include instance details +func (client HostingEnvironmentsClient) GetMultiRolePoolInstanceMetrics(resourceGroupName string, name string, instance string, details *bool) (result ObjectSet, ae error) { + req, err := client.GetMultiRolePoolInstanceMetricsPreparer(resourceGroupName, name, instance, details) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePoolInstanceMetrics", "Failure preparing request") + } + + resp, err := client.GetMultiRolePoolInstanceMetricsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePoolInstanceMetrics", "Failure sending request") + } + + result, err = client.GetMultiRolePoolInstanceMetricsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePoolInstanceMetrics", "Failure responding to request") + } + + return +} + +// GetMultiRolePoolInstanceMetricsPreparer prepares the GetMultiRolePoolInstanceMetrics request. +func (client HostingEnvironmentsClient) GetMultiRolePoolInstanceMetricsPreparer(resourceGroupName string, name string, instance string, details *bool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instance": url.QueryEscape(instance), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if details != nil { + queryParameters["details"] = details + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/multiRolePools/default/instances/{instance}/metrics"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetMultiRolePoolInstanceMetricsSender sends the GetMultiRolePoolInstanceMetrics request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetMultiRolePoolInstanceMetricsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetMultiRolePoolInstanceMetricsResponder handles the response to the GetMultiRolePoolInstanceMetrics request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetMultiRolePoolInstanceMetricsResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetMultiRolePools sends the get multi role pools request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) GetMultiRolePools(resourceGroupName string, name string) (result WorkerPoolCollection, ae error) { + req, err := client.GetMultiRolePoolsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePools", "Failure preparing request") + } + + resp, err := client.GetMultiRolePoolsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePools", "Failure sending request") + } + + result, err = client.GetMultiRolePoolsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePools", "Failure responding to request") + } + + return +} + +// GetMultiRolePoolsPreparer prepares the GetMultiRolePools request. +func (client HostingEnvironmentsClient) GetMultiRolePoolsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/multiRolePools"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetMultiRolePoolsSender sends the GetMultiRolePools request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetMultiRolePoolsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetMultiRolePoolsResponder handles the response to the GetMultiRolePools request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetMultiRolePoolsResponder(resp *http.Response) (result WorkerPoolCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetMultiRolePoolSkus sends the get multi role pool skus request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) GetMultiRolePoolSkus(resourceGroupName string, name string) (result SkuInfoCollection, ae error) { + req, err := client.GetMultiRolePoolSkusPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePoolSkus", "Failure preparing request") + } + + resp, err := client.GetMultiRolePoolSkusSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePoolSkus", "Failure sending request") + } + + result, err = client.GetMultiRolePoolSkusResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetMultiRolePoolSkus", "Failure responding to request") + } + + return +} + +// GetMultiRolePoolSkusPreparer prepares the GetMultiRolePoolSkus request. +func (client HostingEnvironmentsClient) GetMultiRolePoolSkusPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/multiRolePools/default/skus"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetMultiRolePoolSkusSender sends the GetMultiRolePoolSkus request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetMultiRolePoolSkusSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetMultiRolePoolSkusResponder handles the response to the GetMultiRolePoolSkus request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetMultiRolePoolSkusResponder(resp *http.Response) (result SkuInfoCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetWorkerPool sends the get worker pool request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) workerPoolName is name of +// worker pool +func (client HostingEnvironmentsClient) GetWorkerPool(resourceGroupName string, name string, workerPoolName string) (result WorkerPool, ae error) { + req, err := client.GetWorkerPoolPreparer(resourceGroupName, name, workerPoolName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPool", "Failure preparing request") + } + + resp, err := client.GetWorkerPoolSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPool", "Failure sending request") + } + + result, err = client.GetWorkerPoolResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPool", "Failure responding to request") + } + + return +} + +// GetWorkerPoolPreparer prepares the GetWorkerPool request. +func (client HostingEnvironmentsClient) GetWorkerPoolPreparer(resourceGroupName string, name string, workerPoolName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "workerPoolName": url.QueryEscape(workerPoolName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/workerPools/{workerPoolName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetWorkerPoolSender sends the GetWorkerPool request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetWorkerPoolSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetWorkerPoolResponder handles the response to the GetWorkerPool request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetWorkerPoolResponder(resp *http.Response) (result WorkerPool, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetWorkerPoolInstanceMetricDefinitions sends the get worker pool instance +// metric definitions request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) workerPoolName is name of +// worker pool instance is name of instance in the worker pool +func (client HostingEnvironmentsClient) GetWorkerPoolInstanceMetricDefinitions(resourceGroupName string, name string, workerPoolName string, instance string) (result ObjectSet, ae error) { + req, err := client.GetWorkerPoolInstanceMetricDefinitionsPreparer(resourceGroupName, name, workerPoolName, instance) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPoolInstanceMetricDefinitions", "Failure preparing request") + } + + resp, err := client.GetWorkerPoolInstanceMetricDefinitionsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPoolInstanceMetricDefinitions", "Failure sending request") + } + + result, err = client.GetWorkerPoolInstanceMetricDefinitionsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPoolInstanceMetricDefinitions", "Failure responding to request") + } + + return +} + +// GetWorkerPoolInstanceMetricDefinitionsPreparer prepares the GetWorkerPoolInstanceMetricDefinitions request. +func (client HostingEnvironmentsClient) GetWorkerPoolInstanceMetricDefinitionsPreparer(resourceGroupName string, name string, workerPoolName string, instance string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instance": url.QueryEscape(instance), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "workerPoolName": url.QueryEscape(workerPoolName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/workerPools/{workerPoolName}/instances/{instance}/metricdefinitions"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetWorkerPoolInstanceMetricDefinitionsSender sends the GetWorkerPoolInstanceMetricDefinitions request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetWorkerPoolInstanceMetricDefinitionsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetWorkerPoolInstanceMetricDefinitionsResponder handles the response to the GetWorkerPoolInstanceMetricDefinitions request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetWorkerPoolInstanceMetricDefinitionsResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetWorkerPoolInstanceMetrics sends the get worker pool instance metrics +// request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) workerPoolName is name of +// worker pool instance is name of instance in the worker pool details is +// include instance details filter is return only usages/metrics specified in +// the filter. Filter conforms to odata syntax. Example: $filter=(name.value +// eq 'Metric1' or name.value eq 'Metric2') and startTime eq +// '2014-01-01T00:00:00Z' and endTime eq '2014-12-31T23:59:59Z' and timeGrain +// eq duration'[Hour|Minute|Day]'. +func (client HostingEnvironmentsClient) GetWorkerPoolInstanceMetrics(resourceGroupName string, name string, workerPoolName string, instance string, details *bool, filter string) (result ObjectSet, ae error) { + req, err := client.GetWorkerPoolInstanceMetricsPreparer(resourceGroupName, name, workerPoolName, instance, details, filter) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPoolInstanceMetrics", "Failure preparing request") + } + + resp, err := client.GetWorkerPoolInstanceMetricsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPoolInstanceMetrics", "Failure sending request") + } + + result, err = client.GetWorkerPoolInstanceMetricsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPoolInstanceMetrics", "Failure responding to request") + } + + return +} + +// GetWorkerPoolInstanceMetricsPreparer prepares the GetWorkerPoolInstanceMetrics request. +func (client HostingEnvironmentsClient) GetWorkerPoolInstanceMetricsPreparer(resourceGroupName string, name string, workerPoolName string, instance string, details *bool, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "instance": url.QueryEscape(instance), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "workerPoolName": url.QueryEscape(workerPoolName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if details != nil { + queryParameters["details"] = details + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/workerPools/{workerPoolName}/instances/{instance}/metrics"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetWorkerPoolInstanceMetricsSender sends the GetWorkerPoolInstanceMetrics request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetWorkerPoolInstanceMetricsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetWorkerPoolInstanceMetricsResponder handles the response to the GetWorkerPoolInstanceMetrics request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetWorkerPoolInstanceMetricsResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetWorkerPools sends the get worker pools request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) GetWorkerPools(resourceGroupName string, name string) (result WorkerPoolCollection, ae error) { + req, err := client.GetWorkerPoolsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPools", "Failure preparing request") + } + + resp, err := client.GetWorkerPoolsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPools", "Failure sending request") + } + + result, err = client.GetWorkerPoolsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPools", "Failure responding to request") + } + + return +} + +// GetWorkerPoolsPreparer prepares the GetWorkerPools request. +func (client HostingEnvironmentsClient) GetWorkerPoolsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/workerPools"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetWorkerPoolsSender sends the GetWorkerPools request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetWorkerPoolsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetWorkerPoolsResponder handles the response to the GetWorkerPools request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetWorkerPoolsResponder(resp *http.Response) (result WorkerPoolCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetWorkerPoolSkus sends the get worker pool skus request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) workerPoolName is name of +// worker pool +func (client HostingEnvironmentsClient) GetWorkerPoolSkus(resourceGroupName string, name string, workerPoolName string) (result SkuInfoCollection, ae error) { + req, err := client.GetWorkerPoolSkusPreparer(resourceGroupName, name, workerPoolName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPoolSkus", "Failure preparing request") + } + + resp, err := client.GetWorkerPoolSkusSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPoolSkus", "Failure sending request") + } + + result, err = client.GetWorkerPoolSkusResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "GetWorkerPoolSkus", "Failure responding to request") + } + + return +} + +// GetWorkerPoolSkusPreparer prepares the GetWorkerPoolSkus request. +func (client HostingEnvironmentsClient) GetWorkerPoolSkusPreparer(resourceGroupName string, name string, workerPoolName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "workerPoolName": url.QueryEscape(workerPoolName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/workerPools/{workerPoolName}/skus"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetWorkerPoolSkusSender sends the GetWorkerPoolSkus request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) GetWorkerPoolSkusSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetWorkerPoolSkusResponder handles the response to the GetWorkerPoolSkus request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) GetWorkerPoolSkusResponder(resp *http.Response) (result SkuInfoCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// RebootHostingEnvironment sends the reboot hosting environment request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) RebootHostingEnvironment(resourceGroupName string, name string) (result ObjectSet, ae error) { + req, err := client.RebootHostingEnvironmentPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "RebootHostingEnvironment", "Failure preparing request") + } + + resp, err := client.RebootHostingEnvironmentSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "RebootHostingEnvironment", "Failure sending request") + } + + result, err = client.RebootHostingEnvironmentResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "RebootHostingEnvironment", "Failure responding to request") + } + + return +} + +// RebootHostingEnvironmentPreparer prepares the RebootHostingEnvironment request. +func (client HostingEnvironmentsClient) RebootHostingEnvironmentPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/reboot"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// RebootHostingEnvironmentSender sends the RebootHostingEnvironment request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) RebootHostingEnvironmentSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusBadRequest, http.StatusNotFound, http.StatusConflict) +} + +// RebootHostingEnvironmentResponder handles the response to the RebootHostingEnvironment request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) RebootHostingEnvironmentResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusBadRequest, http.StatusNotFound, http.StatusConflict), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ResumeHostingEnvironment sends the resume hosting environment request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) ResumeHostingEnvironment(resourceGroupName string, name string) (result SiteCollection, ae error) { + req, err := client.ResumeHostingEnvironmentPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "ResumeHostingEnvironment", "Failure preparing request") + } + + resp, err := client.ResumeHostingEnvironmentSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "ResumeHostingEnvironment", "Failure sending request") + } + + result, err = client.ResumeHostingEnvironmentResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "ResumeHostingEnvironment", "Failure responding to request") + } + + return +} + +// ResumeHostingEnvironmentPreparer prepares the ResumeHostingEnvironment request. +func (client HostingEnvironmentsClient) ResumeHostingEnvironmentPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/resume"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ResumeHostingEnvironmentSender sends the ResumeHostingEnvironment request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) ResumeHostingEnvironmentSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// ResumeHostingEnvironmentResponder handles the response to the ResumeHostingEnvironment request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) ResumeHostingEnvironmentResponder(resp *http.Response) (result SiteCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// SuspendHostingEnvironment sends the suspend hosting environment request. +// +// resourceGroupName is name of resource group name is name of +// hostingEnvironment (App Service Environment) +func (client HostingEnvironmentsClient) SuspendHostingEnvironment(resourceGroupName string, name string) (result SiteCollection, ae error) { + req, err := client.SuspendHostingEnvironmentPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "SuspendHostingEnvironment", "Failure preparing request") + } + + resp, err := client.SuspendHostingEnvironmentSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "SuspendHostingEnvironment", "Failure sending request") + } + + result, err = client.SuspendHostingEnvironmentResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/HostingEnvironmentsClient", "SuspendHostingEnvironment", "Failure responding to request") + } + + return +} + +// SuspendHostingEnvironmentPreparer prepares the SuspendHostingEnvironment request. +func (client HostingEnvironmentsClient) SuspendHostingEnvironmentPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/hostingEnvironments/{name}/suspend"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// SuspendHostingEnvironmentSender sends the SuspendHostingEnvironment request. The method will close the +// http.Response Body if it receives an error. +func (client HostingEnvironmentsClient) SuspendHostingEnvironmentSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// SuspendHostingEnvironmentResponder handles the response to the SuspendHostingEnvironment request. The method always +// closes the http.Response Body. +func (client HostingEnvironmentsClient) SuspendHostingEnvironmentResponder(resp *http.Response) (result SiteCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/managedhostingenvironments.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/managedhostingenvironments.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/managedhostingenvironments.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/managedhostingenvironments.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,643 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// ManagedHostingEnvironmentsClient is the use these APIs to manage Azure +// Websites resources through the Azure Resource Manager. All task operations +// conform to the HTTP/1.1 protocol specification and each operation returns +// an x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type ManagedHostingEnvironmentsClient struct { + ManagementClient +} + +// NewManagedHostingEnvironmentsClient creates an instance of the +// ManagedHostingEnvironmentsClient client. +func NewManagedHostingEnvironmentsClient(subscriptionID string) ManagedHostingEnvironmentsClient { + return NewManagedHostingEnvironmentsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewManagedHostingEnvironmentsClientWithBaseURI creates an instance of the +// ManagedHostingEnvironmentsClient client. +func NewManagedHostingEnvironmentsClientWithBaseURI(baseURI string, subscriptionID string) ManagedHostingEnvironmentsClient { + return ManagedHostingEnvironmentsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdateManagedHostingEnvironment sends the create or update managed +// hosting environment request. +// +// resourceGroupName is name of resource group name is name of managed hosting +// environment managedHostingEnvironmentEnvelope is properties of managed +// hosting environment +func (client ManagedHostingEnvironmentsClient) CreateOrUpdateManagedHostingEnvironment(resourceGroupName string, name string, managedHostingEnvironmentEnvelope HostingEnvironment) (result HostingEnvironment, ae error) { + req, err := client.CreateOrUpdateManagedHostingEnvironmentPreparer(resourceGroupName, name, managedHostingEnvironmentEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "CreateOrUpdateManagedHostingEnvironment", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateManagedHostingEnvironmentSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "CreateOrUpdateManagedHostingEnvironment", "Failure sending request") + } + + result, err = client.CreateOrUpdateManagedHostingEnvironmentResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "CreateOrUpdateManagedHostingEnvironment", "Failure responding to request") + } + + return +} + +// CreateOrUpdateManagedHostingEnvironmentPreparer prepares the CreateOrUpdateManagedHostingEnvironment request. +func (client ManagedHostingEnvironmentsClient) CreateOrUpdateManagedHostingEnvironmentPreparer(resourceGroupName string, name string, managedHostingEnvironmentEnvelope HostingEnvironment) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/managedHostingEnvironments/{name}"), + autorest.WithJSON(managedHostingEnvironmentEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateManagedHostingEnvironmentSender sends the CreateOrUpdateManagedHostingEnvironment request. The method will close the +// http.Response Body if it receives an error. +func (client ManagedHostingEnvironmentsClient) CreateOrUpdateManagedHostingEnvironmentSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusBadRequest, http.StatusNotFound, http.StatusConflict) +} + +// CreateOrUpdateManagedHostingEnvironmentResponder handles the response to the CreateOrUpdateManagedHostingEnvironment request. The method always +// closes the http.Response Body. +func (client ManagedHostingEnvironmentsClient) CreateOrUpdateManagedHostingEnvironmentResponder(resp *http.Response) (result HostingEnvironment, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusBadRequest, http.StatusNotFound, http.StatusConflict), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteManagedHostingEnvironment sends the delete managed hosting +// environment request. +// +// resourceGroupName is name of resource group name is name of managed hosting +// environment forceDelete is delete even if the managed hosting environment +// contains resources +func (client ManagedHostingEnvironmentsClient) DeleteManagedHostingEnvironment(resourceGroupName string, name string, forceDelete *bool) (result ObjectSet, ae error) { + req, err := client.DeleteManagedHostingEnvironmentPreparer(resourceGroupName, name, forceDelete) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "DeleteManagedHostingEnvironment", "Failure preparing request") + } + + resp, err := client.DeleteManagedHostingEnvironmentSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "DeleteManagedHostingEnvironment", "Failure sending request") + } + + result, err = client.DeleteManagedHostingEnvironmentResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "DeleteManagedHostingEnvironment", "Failure responding to request") + } + + return +} + +// DeleteManagedHostingEnvironmentPreparer prepares the DeleteManagedHostingEnvironment request. +func (client ManagedHostingEnvironmentsClient) DeleteManagedHostingEnvironmentPreparer(resourceGroupName string, name string, forceDelete *bool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if forceDelete != nil { + queryParameters["forceDelete"] = forceDelete + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/managedHostingEnvironments/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteManagedHostingEnvironmentSender sends the DeleteManagedHostingEnvironment request. The method will close the +// http.Response Body if it receives an error. +func (client ManagedHostingEnvironmentsClient) DeleteManagedHostingEnvironmentSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusBadRequest, http.StatusNotFound, http.StatusConflict) +} + +// DeleteManagedHostingEnvironmentResponder handles the response to the DeleteManagedHostingEnvironment request. The method always +// closes the http.Response Body. +func (client ManagedHostingEnvironmentsClient) DeleteManagedHostingEnvironmentResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusBadRequest, http.StatusNotFound, http.StatusConflict), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetManagedHostingEnvironment sends the get managed hosting environment +// request. +// +// resourceGroupName is name of resource group name is name of managed hosting +// environment +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironment(resourceGroupName string, name string) (result ManagedHostingEnvironment, ae error) { + req, err := client.GetManagedHostingEnvironmentPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironment", "Failure preparing request") + } + + resp, err := client.GetManagedHostingEnvironmentSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironment", "Failure sending request") + } + + result, err = client.GetManagedHostingEnvironmentResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironment", "Failure responding to request") + } + + return +} + +// GetManagedHostingEnvironmentPreparer prepares the GetManagedHostingEnvironment request. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/managedHostingEnvironments/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetManagedHostingEnvironmentSender sends the GetManagedHostingEnvironment request. The method will close the +// http.Response Body if it receives an error. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetManagedHostingEnvironmentResponder handles the response to the GetManagedHostingEnvironment request. The method always +// closes the http.Response Body. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentResponder(resp *http.Response) (result ManagedHostingEnvironment, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetManagedHostingEnvironmentOperation sends the get managed hosting +// environment operation request. +// +// resourceGroupName is name of resource group name is name of managed hosting +// environment operationID is operation identifier GUID +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentOperation(resourceGroupName string, name string, operationID string) (result ObjectSet, ae error) { + req, err := client.GetManagedHostingEnvironmentOperationPreparer(resourceGroupName, name, operationID) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentOperation", "Failure preparing request") + } + + resp, err := client.GetManagedHostingEnvironmentOperationSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentOperation", "Failure sending request") + } + + result, err = client.GetManagedHostingEnvironmentOperationResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentOperation", "Failure responding to request") + } + + return +} + +// GetManagedHostingEnvironmentOperationPreparer prepares the GetManagedHostingEnvironmentOperation request. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentOperationPreparer(resourceGroupName string, name string, operationID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "operationId": url.QueryEscape(operationID), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/managedHostingEnvironments/{name}/operations/{operationId}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetManagedHostingEnvironmentOperationSender sends the GetManagedHostingEnvironmentOperation request. The method will close the +// http.Response Body if it receives an error. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentOperationSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted, http.StatusNotFound, http.StatusInternalServerError) +} + +// GetManagedHostingEnvironmentOperationResponder handles the response to the GetManagedHostingEnvironmentOperation request. The method always +// closes the http.Response Body. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentOperationResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNotFound, http.StatusInternalServerError), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetManagedHostingEnvironments sends the get managed hosting environments +// request. +// +// resourceGroupName is name of resource group +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironments(resourceGroupName string) (result HostingEnvironmentCollection, ae error) { + req, err := client.GetManagedHostingEnvironmentsPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironments", "Failure preparing request") + } + + resp, err := client.GetManagedHostingEnvironmentsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironments", "Failure sending request") + } + + result, err = client.GetManagedHostingEnvironmentsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironments", "Failure responding to request") + } + + return +} + +// GetManagedHostingEnvironmentsPreparer prepares the GetManagedHostingEnvironments request. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentsPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/managedHostingEnvironments"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetManagedHostingEnvironmentsSender sends the GetManagedHostingEnvironments request. The method will close the +// http.Response Body if it receives an error. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetManagedHostingEnvironmentsResponder handles the response to the GetManagedHostingEnvironments request. The method always +// closes the http.Response Body. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentsResponder(resp *http.Response) (result HostingEnvironmentCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetManagedHostingEnvironmentServerFarms sends the get managed hosting +// environment server farms request. +// +// resourceGroupName is name of resource group name is name of managed hosting +// environment +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentServerFarms(resourceGroupName string, name string) (result ServerFarmCollection, ae error) { + req, err := client.GetManagedHostingEnvironmentServerFarmsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentServerFarms", "Failure preparing request") + } + + resp, err := client.GetManagedHostingEnvironmentServerFarmsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentServerFarms", "Failure sending request") + } + + result, err = client.GetManagedHostingEnvironmentServerFarmsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentServerFarms", "Failure responding to request") + } + + return +} + +// GetManagedHostingEnvironmentServerFarmsPreparer prepares the GetManagedHostingEnvironmentServerFarms request. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentServerFarmsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/managedHostingEnvironments/{name}/serverfarms"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetManagedHostingEnvironmentServerFarmsSender sends the GetManagedHostingEnvironmentServerFarms request. The method will close the +// http.Response Body if it receives an error. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentServerFarmsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetManagedHostingEnvironmentServerFarmsResponder handles the response to the GetManagedHostingEnvironmentServerFarms request. The method always +// closes the http.Response Body. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentServerFarmsResponder(resp *http.Response) (result ServerFarmCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetManagedHostingEnvironmentSites sends the get managed hosting environment +// sites request. +// +// resourceGroupName is name of resource group name is name of managed hosting +// environment propertiesToInclude is comma separated list of site properties +// to include +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentSites(resourceGroupName string, name string, propertiesToInclude string) (result SiteCollection, ae error) { + req, err := client.GetManagedHostingEnvironmentSitesPreparer(resourceGroupName, name, propertiesToInclude) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentSites", "Failure preparing request") + } + + resp, err := client.GetManagedHostingEnvironmentSitesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentSites", "Failure sending request") + } + + result, err = client.GetManagedHostingEnvironmentSitesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentSites", "Failure responding to request") + } + + return +} + +// GetManagedHostingEnvironmentSitesPreparer prepares the GetManagedHostingEnvironmentSites request. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentSitesPreparer(resourceGroupName string, name string, propertiesToInclude string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(propertiesToInclude) > 0 { + queryParameters["propertiesToInclude"] = propertiesToInclude + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/managedHostingEnvironments/{name}/sites"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetManagedHostingEnvironmentSitesSender sends the GetManagedHostingEnvironmentSites request. The method will close the +// http.Response Body if it receives an error. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentSitesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetManagedHostingEnvironmentSitesResponder handles the response to the GetManagedHostingEnvironmentSites request. The method always +// closes the http.Response Body. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentSitesResponder(resp *http.Response) (result SiteCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetManagedHostingEnvironmentVips sends the get managed hosting environment +// vips request. +// +// resourceGroupName is name of resource group name is name of managed hosting +// environment +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentVips(resourceGroupName string, name string) (result AddressResponse, ae error) { + req, err := client.GetManagedHostingEnvironmentVipsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentVips", "Failure preparing request") + } + + resp, err := client.GetManagedHostingEnvironmentVipsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentVips", "Failure sending request") + } + + result, err = client.GetManagedHostingEnvironmentVipsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentVips", "Failure responding to request") + } + + return +} + +// GetManagedHostingEnvironmentVipsPreparer prepares the GetManagedHostingEnvironmentVips request. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentVipsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/managedHostingEnvironments/{name}/capacities/virtualip"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetManagedHostingEnvironmentVipsSender sends the GetManagedHostingEnvironmentVips request. The method will close the +// http.Response Body if it receives an error. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentVipsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetManagedHostingEnvironmentVipsResponder handles the response to the GetManagedHostingEnvironmentVips request. The method always +// closes the http.Response Body. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentVipsResponder(resp *http.Response) (result AddressResponse, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetManagedHostingEnvironmentWebHostingPlans sends the get managed hosting +// environment web hosting plans request. +// +// resourceGroupName is name of resource group name is name of managed hosting +// environment +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentWebHostingPlans(resourceGroupName string, name string) (result ServerFarmCollection, ae error) { + req, err := client.GetManagedHostingEnvironmentWebHostingPlansPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentWebHostingPlans", "Failure preparing request") + } + + resp, err := client.GetManagedHostingEnvironmentWebHostingPlansSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentWebHostingPlans", "Failure sending request") + } + + result, err = client.GetManagedHostingEnvironmentWebHostingPlansResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ManagedHostingEnvironmentsClient", "GetManagedHostingEnvironmentWebHostingPlans", "Failure responding to request") + } + + return +} + +// GetManagedHostingEnvironmentWebHostingPlansPreparer prepares the GetManagedHostingEnvironmentWebHostingPlans request. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentWebHostingPlansPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/managedHostingEnvironments/{name}/webhostingplans"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetManagedHostingEnvironmentWebHostingPlansSender sends the GetManagedHostingEnvironmentWebHostingPlans request. The method will close the +// http.Response Body if it receives an error. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentWebHostingPlansSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetManagedHostingEnvironmentWebHostingPlansResponder handles the response to the GetManagedHostingEnvironmentWebHostingPlans request. The method always +// closes the http.Response Body. +func (client ManagedHostingEnvironmentsClient) GetManagedHostingEnvironmentWebHostingPlansResponder(resp *http.Response) (result ServerFarmCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/models.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/models.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/models.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/models.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,2183 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/date" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/to" + "net/http" +) + +// AccessControlEntryAction enumerates the values for access control entry +// action. +type AccessControlEntryAction string + +const ( + // Deny specifies the deny state for access control entry action. + Deny AccessControlEntryAction = "Deny" + // Permit specifies the permit state for access control entry action. + Permit AccessControlEntryAction = "Permit" +) + +// AutoHealActionType enumerates the values for auto heal action type. +type AutoHealActionType string + +const ( + // CustomAction specifies the custom action state for auto heal action + // type. + CustomAction AutoHealActionType = "CustomAction" + // LogEvent specifies the log event state for auto heal action type. + LogEvent AutoHealActionType = "LogEvent" + // Recycle specifies the recycle state for auto heal action type. + Recycle AutoHealActionType = "Recycle" +) + +// AzureResourceType enumerates the values for azure resource type. +type AzureResourceType string + +const ( + // TrafficManager specifies the traffic manager state for azure resource + // type. + TrafficManager AzureResourceType = "TrafficManager" + // Website specifies the website state for azure resource type. + Website AzureResourceType = "Website" +) + +// BackupItemStatus enumerates the values for backup item status. +type BackupItemStatus string + +const ( + // Created specifies the created state for backup item status. + Created BackupItemStatus = "Created" + // Deleted specifies the deleted state for backup item status. + Deleted BackupItemStatus = "Deleted" + // DeleteFailed specifies the delete failed state for backup item status. + DeleteFailed BackupItemStatus = "DeleteFailed" + // DeleteInProgress specifies the delete in progress state for backup item + // status. + DeleteInProgress BackupItemStatus = "DeleteInProgress" + // Failed specifies the failed state for backup item status. + Failed BackupItemStatus = "Failed" + // InProgress specifies the in progress state for backup item status. + InProgress BackupItemStatus = "InProgress" + // PartiallySucceeded specifies the partially succeeded state for backup + // item status. + PartiallySucceeded BackupItemStatus = "PartiallySucceeded" + // Skipped specifies the skipped state for backup item status. + Skipped BackupItemStatus = "Skipped" + // Succeeded specifies the succeeded state for backup item status. + Succeeded BackupItemStatus = "Succeeded" + // TimedOut specifies the timed out state for backup item status. + TimedOut BackupItemStatus = "TimedOut" +) + +// BackupRestoreOperationType enumerates the values for backup restore +// operation type. +type BackupRestoreOperationType string + +const ( + // Clone specifies the clone state for backup restore operation type. + Clone BackupRestoreOperationType = "Clone" + // Default specifies the default state for backup restore operation type. + Default BackupRestoreOperationType = "Default" + // Relocation specifies the relocation state for backup restore operation + // type. + Relocation BackupRestoreOperationType = "Relocation" +) + +// BuiltInAuthenticationProvider enumerates the values for built in +// authentication provider. +type BuiltInAuthenticationProvider string + +const ( + // AzureActiveDirectory specifies the azure active directory state for + // built in authentication provider. + AzureActiveDirectory BuiltInAuthenticationProvider = "AzureActiveDirectory" + // Facebook specifies the facebook state for built in authentication + // provider. + Facebook BuiltInAuthenticationProvider = "Facebook" + // Google specifies the google state for built in authentication provider. + Google BuiltInAuthenticationProvider = "Google" + // MicrosoftAccount specifies the microsoft account state for built in + // authentication provider. + MicrosoftAccount BuiltInAuthenticationProvider = "MicrosoftAccount" + // Twitter specifies the twitter state for built in authentication + // provider. + Twitter BuiltInAuthenticationProvider = "Twitter" +) + +// CertificateAction enumerates the values for certificate action. +type CertificateAction string + +const ( + // Rekey specifies the rekey state for certificate action. + Rekey CertificateAction = "Rekey" + // Renew specifies the renew state for certificate action. + Renew CertificateAction = "Renew" +) + +// CertificateOrderStatus enumerates the values for certificate order status. +type CertificateOrderStatus string + +const ( + // Canceled specifies the canceled state for certificate order status. + Canceled CertificateOrderStatus = "Canceled" + // Denied specifies the denied state for certificate order status. + Denied CertificateOrderStatus = "Denied" + // Expired specifies the expired state for certificate order status. + Expired CertificateOrderStatus = "Expired" + // Issued specifies the issued state for certificate order status. + Issued CertificateOrderStatus = "Issued" + // NotSubmitted specifies the not submitted state for certificate order + // status. + NotSubmitted CertificateOrderStatus = "NotSubmitted" + // Pendingissuance specifies the pendingissuance state for certificate + // order status. + Pendingissuance CertificateOrderStatus = "Pendingissuance" + // PendingRekey specifies the pending rekey state for certificate order + // status. + PendingRekey CertificateOrderStatus = "PendingRekey" + // Pendingrevocation specifies the pendingrevocation state for certificate + // order status. + Pendingrevocation CertificateOrderStatus = "Pendingrevocation" + // Revoked specifies the revoked state for certificate order status. + Revoked CertificateOrderStatus = "Revoked" + // Unused specifies the unused state for certificate order status. + Unused CertificateOrderStatus = "Unused" +) + +// CertificateProductType enumerates the values for certificate product type. +type CertificateProductType string + +const ( + // StandardDomainValidatedSsl specifies the standard domain validated ssl + // state for certificate product type. + StandardDomainValidatedSsl CertificateProductType = "StandardDomainValidatedSsl" + // StandardDomainValidatedWildCardSsl specifies the standard domain + // validated wild card ssl state for certificate product type. + StandardDomainValidatedWildCardSsl CertificateProductType = "StandardDomainValidatedWildCardSsl" +) + +// ComputeModeOptions enumerates the values for compute mode options. +type ComputeModeOptions string + +const ( + // Dedicated specifies the dedicated state for compute mode options. + Dedicated ComputeModeOptions = "Dedicated" + // Shared specifies the shared state for compute mode options. + Shared ComputeModeOptions = "Shared" +) + +// CustomHostNameDNSRecordType enumerates the values for custom host name dns +// record type. +type CustomHostNameDNSRecordType string + +const ( + // A specifies the a state for custom host name dns record type. + A CustomHostNameDNSRecordType = "A" + // CName specifies the c name state for custom host name dns record type. + CName CustomHostNameDNSRecordType = "CName" +) + +// DatabaseServerType enumerates the values for database server type. +type DatabaseServerType string + +const ( + // Custom specifies the custom state for database server type. + Custom DatabaseServerType = "Custom" + // MySQL specifies the my sql state for database server type. + MySQL DatabaseServerType = "MySql" + // SQLAzure specifies the sql azure state for database server type. + SQLAzure DatabaseServerType = "SQLAzure" + // SQLServer specifies the sql server state for database server type. + SQLServer DatabaseServerType = "SQLServer" +) + +// DomainStatus enumerates the values for domain status. +type DomainStatus string + +const ( + // DomainStatusActive specifies the domain status active state for domain + // status. + DomainStatusActive DomainStatus = "Active" + // DomainStatusAwaiting specifies the domain status awaiting state for + // domain status. + DomainStatusAwaiting DomainStatus = "Awaiting" + // DomainStatusCancelled specifies the domain status cancelled state for + // domain status. + DomainStatusCancelled DomainStatus = "Cancelled" + // DomainStatusConfiscated specifies the domain status confiscated state + // for domain status. + DomainStatusConfiscated DomainStatus = "Confiscated" + // DomainStatusDisabled specifies the domain status disabled state for + // domain status. + DomainStatusDisabled DomainStatus = "Disabled" + // DomainStatusExcluded specifies the domain status excluded state for + // domain status. + DomainStatusExcluded DomainStatus = "Excluded" + // DomainStatusExpired specifies the domain status expired state for + // domain status. + DomainStatusExpired DomainStatus = "Expired" + // DomainStatusFailed specifies the domain status failed state for domain + // status. + DomainStatusFailed DomainStatus = "Failed" + // DomainStatusHeld specifies the domain status held state for domain + // status. + DomainStatusHeld DomainStatus = "Held" + // DomainStatusJSONConverterFailed specifies the domain status json + // converter failed state for domain status. + DomainStatusJSONConverterFailed DomainStatus = "JsonConverterFailed" + // DomainStatusLocked specifies the domain status locked state for domain + // status. + DomainStatusLocked DomainStatus = "Locked" + // DomainStatusParked specifies the domain status parked state for domain + // status. + DomainStatusParked DomainStatus = "Parked" + // DomainStatusPending specifies the domain status pending state for + // domain status. + DomainStatusPending DomainStatus = "Pending" + // DomainStatusReserved specifies the domain status reserved state for + // domain status. + DomainStatusReserved DomainStatus = "Reserved" + // DomainStatusReverted specifies the domain status reverted state for + // domain status. + DomainStatusReverted DomainStatus = "Reverted" + // DomainStatusSuspended specifies the domain status suspended state for + // domain status. + DomainStatusSuspended DomainStatus = "Suspended" + // DomainStatusTransferred specifies the domain status transferred state + // for domain status. + DomainStatusTransferred DomainStatus = "Transferred" + // DomainStatusUnknown specifies the domain status unknown state for + // domain status. + DomainStatusUnknown DomainStatus = "Unknown" + // DomainStatusUnlocked specifies the domain status unlocked state for + // domain status. + DomainStatusUnlocked DomainStatus = "Unlocked" + // DomainStatusUnparked specifies the domain status unparked state for + // domain status. + DomainStatusUnparked DomainStatus = "Unparked" + // DomainStatusUpdated specifies the domain status updated state for + // domain status. + DomainStatusUpdated DomainStatus = "Updated" +) + +// DomainType enumerates the values for domain type. +type DomainType string + +const ( + // Regular specifies the regular state for domain type. + Regular DomainType = "Regular" + // SoftDeleted specifies the soft deleted state for domain type. + SoftDeleted DomainType = "SoftDeleted" +) + +// FrequencyUnit enumerates the values for frequency unit. +type FrequencyUnit string + +const ( + // Day specifies the day state for frequency unit. + Day FrequencyUnit = "Day" + // Hour specifies the hour state for frequency unit. + Hour FrequencyUnit = "Hour" +) + +// HostingEnvironmentStatus enumerates the values for hosting environment +// status. +type HostingEnvironmentStatus string + +const ( + // Deleting specifies the deleting state for hosting environment status. + Deleting HostingEnvironmentStatus = "Deleting" + // Preparing specifies the preparing state for hosting environment status. + Preparing HostingEnvironmentStatus = "Preparing" + // Ready specifies the ready state for hosting environment status. + Ready HostingEnvironmentStatus = "Ready" + // Scaling specifies the scaling state for hosting environment status. + Scaling HostingEnvironmentStatus = "Scaling" +) + +// HostNameType enumerates the values for host name type. +type HostNameType string + +const ( + // Managed specifies the managed state for host name type. + Managed HostNameType = "Managed" + // Verified specifies the verified state for host name type. + Verified HostNameType = "Verified" +) + +// InternalLoadBalancingMode enumerates the values for internal load balancing +// mode. +type InternalLoadBalancingMode string + +const ( + // None specifies the none state for internal load balancing mode. + None InternalLoadBalancingMode = "None" + // Publishing specifies the publishing state for internal load balancing + // mode. + Publishing InternalLoadBalancingMode = "Publishing" + // Web specifies the web state for internal load balancing mode. + Web InternalLoadBalancingMode = "Web" +) + +// KeyVaultSecretStatus enumerates the values for key vault secret status. +type KeyVaultSecretStatus string + +const ( + // KeyVaultSecretStatusAzureServiceUnauthorizedToAccessKeyVault specifies + // the key vault secret status azure service unauthorized to access key + // vault state for key vault secret status. + KeyVaultSecretStatusAzureServiceUnauthorizedToAccessKeyVault KeyVaultSecretStatus = "AzureServiceUnauthorizedToAccessKeyVault" + // KeyVaultSecretStatusCertificateOrderFailed specifies the key vault + // secret status certificate order failed state for key vault secret + // status. + KeyVaultSecretStatusCertificateOrderFailed KeyVaultSecretStatus = "CertificateOrderFailed" + // KeyVaultSecretStatusInitialized specifies the key vault secret status + // initialized state for key vault secret status. + KeyVaultSecretStatusInitialized KeyVaultSecretStatus = "Initialized" + // KeyVaultSecretStatusKeyVaultDoesNotExist specifies the key vault secret + // status key vault does not exist state for key vault secret status. + KeyVaultSecretStatusKeyVaultDoesNotExist KeyVaultSecretStatus = "KeyVaultDoesNotExist" + // KeyVaultSecretStatusKeyVaultSecretDoesNotExist specifies the key vault + // secret status key vault secret does not exist state for key vault + // secret status. + KeyVaultSecretStatusKeyVaultSecretDoesNotExist KeyVaultSecretStatus = "KeyVaultSecretDoesNotExist" + // KeyVaultSecretStatusOperationNotPermittedOnKeyVault specifies the key + // vault secret status operation not permitted on key vault state for key + // vault secret status. + KeyVaultSecretStatusOperationNotPermittedOnKeyVault KeyVaultSecretStatus = "OperationNotPermittedOnKeyVault" + // KeyVaultSecretStatusSucceeded specifies the key vault secret status + // succeeded state for key vault secret status. + KeyVaultSecretStatusSucceeded KeyVaultSecretStatus = "Succeeded" + // KeyVaultSecretStatusUnknown specifies the key vault secret status + // unknown state for key vault secret status. + KeyVaultSecretStatusUnknown KeyVaultSecretStatus = "Unknown" + // KeyVaultSecretStatusUnknownError specifies the key vault secret status + // unknown error state for key vault secret status. + KeyVaultSecretStatusUnknownError KeyVaultSecretStatus = "UnknownError" + // KeyVaultSecretStatusWaitingOnCertificateOrder specifies the key vault + // secret status waiting on certificate order state for key vault secret + // status. + KeyVaultSecretStatusWaitingOnCertificateOrder KeyVaultSecretStatus = "WaitingOnCertificateOrder" +) + +// LogLevel enumerates the values for log level. +type LogLevel string + +const ( + // Error specifies the error state for log level. + Error LogLevel = "Error" + // Information specifies the information state for log level. + Information LogLevel = "Information" + // Off specifies the off state for log level. + Off LogLevel = "Off" + // Verbose specifies the verbose state for log level. + Verbose LogLevel = "Verbose" + // Warning specifies the warning state for log level. + Warning LogLevel = "Warning" +) + +// ManagedHostingEnvironmentStatus enumerates the values for managed hosting +// environment status. +type ManagedHostingEnvironmentStatus string + +const ( + // ManagedHostingEnvironmentStatusDeleting specifies the managed hosting + // environment status deleting state for managed hosting environment + // status. + ManagedHostingEnvironmentStatusDeleting ManagedHostingEnvironmentStatus = "Deleting" + // ManagedHostingEnvironmentStatusPreparing specifies the managed hosting + // environment status preparing state for managed hosting environment + // status. + ManagedHostingEnvironmentStatusPreparing ManagedHostingEnvironmentStatus = "Preparing" + // ManagedHostingEnvironmentStatusReady specifies the managed hosting + // environment status ready state for managed hosting environment status. + ManagedHostingEnvironmentStatusReady ManagedHostingEnvironmentStatus = "Ready" +) + +// ManagedPipelineMode enumerates the values for managed pipeline mode. +type ManagedPipelineMode string + +const ( + // Classic specifies the classic state for managed pipeline mode. + Classic ManagedPipelineMode = "Classic" + // Integrated specifies the integrated state for managed pipeline mode. + Integrated ManagedPipelineMode = "Integrated" +) + +// SiteAvailabilityState enumerates the values for site availability state. +type SiteAvailabilityState string + +const ( + // DisasterRecoveryMode specifies the disaster recovery mode state for + // site availability state. + DisasterRecoveryMode SiteAvailabilityState = "DisasterRecoveryMode" + // Limited specifies the limited state for site availability state. + Limited SiteAvailabilityState = "Limited" + // Normal specifies the normal state for site availability state. + Normal SiteAvailabilityState = "Normal" +) + +// SiteLoadBalancing enumerates the values for site load balancing. +type SiteLoadBalancing string + +const ( + // LeastRequests specifies the least requests state for site load + // balancing. + LeastRequests SiteLoadBalancing = "LeastRequests" + // LeastResponseTime specifies the least response time state for site load + // balancing. + LeastResponseTime SiteLoadBalancing = "LeastResponseTime" + // RequestHash specifies the request hash state for site load balancing. + RequestHash SiteLoadBalancing = "RequestHash" + // WeightedRoundRobin specifies the weighted round robin state for site + // load balancing. + WeightedRoundRobin SiteLoadBalancing = "WeightedRoundRobin" + // WeightedTotalTraffic specifies the weighted total traffic state for + // site load balancing. + WeightedTotalTraffic SiteLoadBalancing = "WeightedTotalTraffic" +) + +// SslState enumerates the values for ssl state. +type SslState string + +const ( + // Disabled specifies the disabled state for ssl state. + Disabled SslState = "Disabled" + // IPBasedEnabled specifies the ip based enabled state for ssl state. + IPBasedEnabled SslState = "IpBasedEnabled" + // SniEnabled specifies the sni enabled state for ssl state. + SniEnabled SslState = "SniEnabled" +) + +// StatusOptions enumerates the values for status options. +type StatusOptions string + +const ( + // StatusOptionsPending specifies the status options pending state for + // status options. + StatusOptionsPending StatusOptions = "Pending" + // StatusOptionsReady specifies the status options ready state for status + // options. + StatusOptionsReady StatusOptions = "Ready" +) + +// UnauthenticatedClientAction enumerates the values for unauthenticated +// client action. +type UnauthenticatedClientAction string + +const ( + // AllowAnonymous specifies the allow anonymous state for unauthenticated + // client action. + AllowAnonymous UnauthenticatedClientAction = "AllowAnonymous" + // RedirectToLoginPage specifies the redirect to login page state for + // unauthenticated client action. + RedirectToLoginPage UnauthenticatedClientAction = "RedirectToLoginPage" +) + +// UsageState enumerates the values for usage state. +type UsageState string + +const ( + // UsageStateExceeded specifies the usage state exceeded state for usage + // state. + UsageStateExceeded UsageState = "Exceeded" + // UsageStateNormal specifies the usage state normal state for usage state. + UsageStateNormal UsageState = "Normal" +) + +// WorkerSizeOptions enumerates the values for worker size options. +type WorkerSizeOptions string + +const ( + // Large specifies the large state for worker size options. + Large WorkerSizeOptions = "Large" + // Medium specifies the medium state for worker size options. + Medium WorkerSizeOptions = "Medium" + // Small specifies the small state for worker size options. + Small WorkerSizeOptions = "Small" +) + +// Address is address information for domain registration +type Address struct { + Address1 *string `json:"address1,omitempty"` + Address2 *string `json:"address2,omitempty"` + City *string `json:"city,omitempty"` + Country *string `json:"country,omitempty"` + PostalCode *string `json:"postalCode,omitempty"` + State *string `json:"state,omitempty"` +} + +// AddressResponse is describes main public ip address and any extra vips +type AddressResponse struct { + autorest.Response `json:"-"` + ServiceIPAddress *string `json:"serviceIpAddress,omitempty"` + InternalIPAddress *string `json:"internalIpAddress,omitempty"` + OutboundIPAddresses *[]string `json:"outboundIpAddresses,omitempty"` + VipMappings *[]VirtualIPMapping `json:"vipMappings,omitempty"` +} + +// ApplicationLogsConfig is application logs configuration +type ApplicationLogsConfig struct { + FileSystem *FileSystemApplicationLogsConfig `json:"fileSystem,omitempty"` + AzureTableStorage *AzureTableStorageApplicationLogsConfig `json:"azureTableStorage,omitempty"` + AzureBlobStorage *AzureBlobStorageApplicationLogsConfig `json:"azureBlobStorage,omitempty"` +} + +// ArmPlan is the plan object in an ARM, represents a marketplace plan +type ArmPlan struct { + Name *string `json:"name,omitempty"` + Publisher *string `json:"publisher,omitempty"` + Product *string `json:"product,omitempty"` + PromotionCode *string `json:"promotionCode,omitempty"` + Version *string `json:"version,omitempty"` +} + +// AutoHealActions is autoHealActions - Describes the actions which can be +// taken by the auto-heal module when a rule is triggered. +type AutoHealActions struct { + ActionType AutoHealActionType `json:"actionType,omitempty"` + CustomAction *AutoHealCustomAction `json:"customAction,omitempty"` +} + +// AutoHealCustomAction is autoHealCustomAction - Describes the custom action +// to be executed +// when an auto heal rule is triggered. +type AutoHealCustomAction struct { + Exe *string `json:"exe,omitempty"` + Parameters *string `json:"parameters,omitempty"` +} + +// AutoHealRules is autoHealRules - describes the rules which can be defined +// for auto-heal +type AutoHealRules struct { + Triggers *AutoHealTriggers `json:"triggers,omitempty"` + Actions *AutoHealActions `json:"actions,omitempty"` +} + +// AutoHealTriggers is autoHealTriggers - describes the triggers for auto-heal. +type AutoHealTriggers struct { + Requests *RequestsBasedTrigger `json:"requests,omitempty"` + PrivateBytesInKB *int `json:"privateBytesInKB,omitempty"` + StatusCodes *[]StatusCodesBasedTrigger `json:"statusCodes,omitempty"` + SlowRequests *SlowRequestsBasedTrigger `json:"slowRequests,omitempty"` +} + +// AzureBlobStorageApplicationLogsConfig is application logs azure blob +// storage configuration +type AzureBlobStorageApplicationLogsConfig struct { + Level LogLevel `json:"level,omitempty"` + SasURL *string `json:"sasUrl,omitempty"` + RetentionInDays *int `json:"retentionInDays,omitempty"` +} + +// AzureBlobStorageHTTPLogsConfig is http logs to azure blob storage +// configuration +type AzureBlobStorageHTTPLogsConfig struct { + SasURL *string `json:"sasUrl,omitempty"` + RetentionInDays *int `json:"retentionInDays,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +// AzureTableStorageApplicationLogsConfig is application logs to azure table +// storage configuration +type AzureTableStorageApplicationLogsConfig struct { + Level LogLevel `json:"level,omitempty"` + SasURL *string `json:"sasUrl,omitempty"` +} + +// BackupItem is backup description +type BackupItem struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *BackupItemProperties `json:"properties,omitempty"` +} + +// BackupItemCollection is collection of Backup Items +type BackupItemCollection struct { + autorest.Response `json:"-"` + Value *[]BackupItem `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// BackupItemProperties is +type BackupItemProperties struct { + StorageAccountURL *string `json:"storageAccountUrl,omitempty"` + BlobName *string `json:"blobName,omitempty"` + Name *string `json:"name,omitempty"` + Status BackupItemStatus `json:"status,omitempty"` + SizeInBytes *int32 `json:"sizeInBytes,omitempty"` + Created *date.Time `json:"created,omitempty"` + Log *string `json:"log,omitempty"` + Databases *[]DatabaseBackupSetting `json:"databases,omitempty"` + Scheduled *bool `json:"scheduled,omitempty"` + LastRestoreTimeStamp *date.Time `json:"lastRestoreTimeStamp,omitempty"` + FinishedTimeStamp *date.Time `json:"finishedTimeStamp,omitempty"` + CorrelationID *string `json:"correlationId,omitempty"` + WebsiteSizeInBytes *int32 `json:"websiteSizeInBytes,omitempty"` +} + +// BackupRequest is description of a backup which will be performed +type BackupRequest struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *BackupRequestProperties `json:"properties,omitempty"` +} + +// BackupRequestProperties is +type BackupRequestProperties struct { + Name *string `json:"name,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + StorageAccountURL *string `json:"storageAccountUrl,omitempty"` + BackupSchedule *BackupSchedule `json:"backupSchedule,omitempty"` + Databases *[]DatabaseBackupSetting `json:"databases,omitempty"` + Type BackupRestoreOperationType `json:"type,omitempty"` +} + +// BackupSchedule is description of a backup schedule. Describes how often +// should be the backup performed and what should be the retention policy. +type BackupSchedule struct { + FrequencyInterval *int `json:"frequencyInterval,omitempty"` + FrequencyUnit FrequencyUnit `json:"frequencyUnit,omitempty"` + KeepAtLeastOneBackup *bool `json:"keepAtLeastOneBackup,omitempty"` + RetentionPeriodInDays *int `json:"retentionPeriodInDays,omitempty"` + StartTime *date.Time `json:"startTime,omitempty"` + LastExecutionTime *date.Time `json:"lastExecutionTime,omitempty"` +} + +// Certificate is app certificate +type Certificate struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *CertificateProperties `json:"properties,omitempty"` +} + +// CertificateCollection is collection of certificates +type CertificateCollection struct { + autorest.Response `json:"-"` + Value *[]Certificate `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// CertificateOrder is certificate purchase order +type CertificateOrder struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *CertificateOrderProperties `json:"properties,omitempty"` +} + +// CertificateOrderCertificate is class representing the Key Vault container +// for certificate purchased through Azure +type CertificateOrderCertificate struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *CertificateOrderCertificateProperties `json:"properties,omitempty"` +} + +// CertificateOrderCertificateCollection is collection of ceritificateorder +// certificates +type CertificateOrderCertificateCollection struct { + autorest.Response `json:"-"` + Value *[]CertificateOrderCertificate `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// CertificateOrderCertificateProperties is +type CertificateOrderCertificateProperties struct { + KeyVaultCsmID *string `json:"keyVaultCsmId,omitempty"` + KeyVaultSecretName *string `json:"keyVaultSecretName,omitempty"` + ProvisioningState KeyVaultSecretStatus `json:"provisioningState,omitempty"` + Thumbprint *string `json:"thumbprint,omitempty"` +} + +// CertificateOrderCollection is collection of ceritificate orders +type CertificateOrderCollection struct { + autorest.Response `json:"-"` + Value *[]CertificateOrder `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// CertificateOrderProperties is +type CertificateOrderProperties struct { + Certificates *map[string]*CertificateOrderCertificate `json:"certificates,omitempty"` + DistinguishedName *string `json:"distinguishedName,omitempty"` + DomainVerificationToken *string `json:"domainVerificationToken,omitempty"` + ValidityInYears *int `json:"validityInYears,omitempty"` + KeySize *int `json:"keySize,omitempty"` + ProductType CertificateProductType `json:"productType,omitempty"` + Status CertificateOrderStatus `json:"status,omitempty"` + SignedCertificate *string `json:"signedCertificate,omitempty"` + Csr *string `json:"csr,omitempty"` + Intermediate *string `json:"intermediate,omitempty"` + Root *string `json:"root,omitempty"` + SerialNumber *string `json:"serialNumber,omitempty"` + Action CertificateAction `json:"action,omitempty"` + KeyVaultCsmID *string `json:"keyVaultCsmId,omitempty"` + DelayExistingRevokeInHours *int `json:"delayExistingRevokeInHours,omitempty"` +} + +// CertificateProperties is +type CertificateProperties struct { + FriendlyName *string `json:"friendlyName,omitempty"` + SubjectName *string `json:"subjectName,omitempty"` + HostNames *[]string `json:"hostNames,omitempty"` + PfxBlob *string `json:"pfxBlob,omitempty"` + SiteName *string `json:"siteName,omitempty"` + SelfLink *string `json:"selfLink,omitempty"` + Issuer *string `json:"issuer,omitempty"` + IssueDate *date.Time `json:"issueDate,omitempty"` + ExpirationDate *date.Time `json:"expirationDate,omitempty"` + Password *string `json:"password,omitempty"` + Thumbprint *string `json:"thumbprint,omitempty"` + Valid *bool `json:"valid,omitempty"` + CerBlob *string `json:"cerBlob,omitempty"` + PublicKeyHash *string `json:"publicKeyHash,omitempty"` + HostingEnvironmentProfile *HostingEnvironmentProfile `json:"hostingEnvironmentProfile,omitempty"` + KeyVaultCsmID *string `json:"keyVaultCsmId,omitempty"` + KeyVaultSecretName *string `json:"keyVaultSecretName,omitempty"` +} + +// ClassicMobileService is a mobile service +type ClassicMobileService struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *ClassicMobileServiceProperties `json:"properties,omitempty"` +} + +// ClassicMobileServiceCollection is collection of Classic Mobile Services +type ClassicMobileServiceCollection struct { + autorest.Response `json:"-"` + Value *[]ClassicMobileService `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ClassicMobileServiceProperties is +type ClassicMobileServiceProperties struct { + Name *string `json:"name,omitempty"` +} + +// CloningInfo is represents information needed for cloning operation +type CloningInfo struct { + CorrelationID *string `json:"correlationId,omitempty"` + Overwrite *bool `json:"overwrite,omitempty"` + CloneCustomHostNames *bool `json:"cloneCustomHostNames,omitempty"` + CloneSourceControl *bool `json:"cloneSourceControl,omitempty"` + SourceWebAppID *string `json:"sourceWebAppId,omitempty"` + HostingEnvironment *string `json:"hostingEnvironment,omitempty"` + AppSettingsOverrides *map[string]*string `json:"appSettingsOverrides,omitempty"` + ConfigureLoadBalancing *bool `json:"configureLoadBalancing,omitempty"` + TrafficManagerProfileID *string `json:"trafficManagerProfileId,omitempty"` + TrafficManagerProfileName *string `json:"trafficManagerProfileName,omitempty"` +} + +// ConnectionStringDictionary is string dictionary resource +type ConnectionStringDictionary struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *map[string]*ConnStringValueTypePair `json:"properties,omitempty"` +} + +// ConnStringInfo is represents database connection string information +type ConnStringInfo struct { + Name *string `json:"name,omitempty"` + ConnectionString *string `json:"connectionString,omitempty"` + Type DatabaseServerType `json:"type,omitempty"` +} + +// ConnStringValueTypePair is database connection string value to type pair +type ConnStringValueTypePair struct { + Value *string `json:"value,omitempty"` + Type DatabaseServerType `json:"type,omitempty"` +} + +// Contact is contact information for domain registration. If 'Domain Privacy' +// option is not selected then the contact information will be be made +// publicly available through the Whois directories as per ICANN requirements. +type Contact struct { + AddressMailing *Address `json:"addressMailing,omitempty"` + Email *string `json:"email,omitempty"` + Fax *string `json:"fax,omitempty"` + JobTitle *string `json:"jobTitle,omitempty"` + NameFirst *string `json:"nameFirst,omitempty"` + NameLast *string `json:"nameLast,omitempty"` + NameMiddle *string `json:"nameMiddle,omitempty"` + Organization *string `json:"organization,omitempty"` + Phone *string `json:"phone,omitempty"` +} + +// CsmMoveResourceEnvelope is class containing a list of the resources that +// need to be moved and the resource group they should be moved to +type CsmMoveResourceEnvelope struct { + TargetResourceGroup *string `json:"targetResourceGroup,omitempty"` + Resources *[]string `json:"resources,omitempty"` +} + +// CsmPublishingProfileOptions is publishing options for requested profile +type CsmPublishingProfileOptions struct { + Format *string `json:"format,omitempty"` +} + +// CsmSiteRecoveryEntity is class containting details about site recovery +// operation. +type CsmSiteRecoveryEntity struct { + SnapshotTime *date.Time `json:"snapshotTime,omitempty"` + SiteName *string `json:"siteName,omitempty"` + SlotName *string `json:"slotName,omitempty"` +} + +// CsmSlotEntity is class containing deployment slot parameters +type CsmSlotEntity struct { + TargetSlot *string `json:"targetSlot,omitempty"` + PreserveVnet *bool `json:"preserveVnet,omitempty"` +} + +// CsmUsageQuota is usage of the quota resource +type CsmUsageQuota struct { + Unit *string `json:"unit,omitempty"` + NextResetTime *date.Time `json:"nextResetTime,omitempty"` + CurrentValue *int32 `json:"currentValue,omitempty"` + Limit *int32 `json:"limit,omitempty"` + Name *LocalizableString `json:"name,omitempty"` +} + +// CsmUsageQuotaCollection is collection of csm usage quotas +type CsmUsageQuotaCollection struct { + autorest.Response `json:"-"` + Value *[]CsmUsageQuota `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// Csr is certificate signing request object +type Csr struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *CsrProperties `json:"properties,omitempty"` +} + +// CsrList is +type CsrList struct { + autorest.Response `json:"-"` + Value *[]Csr `json:"value,omitempty"` +} + +// CsrProperties is +type CsrProperties struct { + Name *string `json:"name,omitempty"` + DistinguishedName *string `json:"distinguishedName,omitempty"` + CsrString *string `json:"csrString,omitempty"` + PfxBlob *string `json:"pfxBlob,omitempty"` + Password *string `json:"password,omitempty"` + PublicKeyHash *string `json:"publicKeyHash,omitempty"` + HostingEnvironment *string `json:"hostingEnvironment,omitempty"` +} + +// DatabaseBackupSetting is note: properties are serialized in JSON format and +// stored in DB. +// if new properties are added they might not be in the previous +// data rows +// so please handle nulls +type DatabaseBackupSetting struct { + DatabaseType *string `json:"databaseType,omitempty"` + Name *string `json:"name,omitempty"` + ConnectionStringName *string `json:"connectionStringName,omitempty"` + ConnectionString *string `json:"connectionString,omitempty"` +} + +// DeletedSite is reports deleted site including the timestamp of operation +type DeletedSite struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *DeletedSiteProperties `json:"properties,omitempty"` +} + +// DeletedSiteCollection is collection of deleted sites +type DeletedSiteCollection struct { + autorest.Response `json:"-"` + Value *[]DeletedSite `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// DeletedSiteProperties is +type DeletedSiteProperties struct { + DeletedTimestamp *date.Time `json:"deletedTimestamp,omitempty"` + Name *string `json:"name,omitempty"` + State *string `json:"state,omitempty"` + HostNames *[]string `json:"hostNames,omitempty"` + RepositorySiteName *string `json:"repositorySiteName,omitempty"` + UsageState UsageState `json:"usageState,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + EnabledHostNames *[]string `json:"enabledHostNames,omitempty"` + AvailabilityState SiteAvailabilityState `json:"availabilityState,omitempty"` + HostNameSslStates *[]HostNameSslState `json:"hostNameSslStates,omitempty"` + ServerFarmID *string `json:"serverFarmId,omitempty"` + LastModifiedTimeUtc *date.Time `json:"lastModifiedTimeUtc,omitempty"` + SiteConfig *SiteConfig `json:"siteConfig,omitempty"` + TrafficManagerHostNames *[]string `json:"trafficManagerHostNames,omitempty"` + PremiumAppDeployed *bool `json:"premiumAppDeployed,omitempty"` + ScmSiteAlsoStopped *bool `json:"scmSiteAlsoStopped,omitempty"` + TargetSwapSlot *string `json:"targetSwapSlot,omitempty"` + HostingEnvironmentProfile *HostingEnvironmentProfile `json:"hostingEnvironmentProfile,omitempty"` + MicroService *string `json:"microService,omitempty"` + GatewaySiteName *string `json:"gatewaySiteName,omitempty"` + ClientAffinityEnabled *bool `json:"clientAffinityEnabled,omitempty"` + ClientCertEnabled *bool `json:"clientCertEnabled,omitempty"` + OutboundIPAddresses *string `json:"outboundIpAddresses,omitempty"` + CloningInfo *CloningInfo `json:"cloningInfo,omitempty"` +} + +// Domain is represents a domain +type Domain struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *DomainProperties `json:"properties,omitempty"` +} + +// DomainAvailablilityCheckResult is domain availablility check result +type DomainAvailablilityCheckResult struct { + autorest.Response `json:"-"` + Name *string `json:"name,omitempty"` + Available *bool `json:"available,omitempty"` + DomainType DomainType `json:"domainType,omitempty"` +} + +// DomainCollection is collection of domains +type DomainCollection struct { + autorest.Response `json:"-"` + Value *[]Domain `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// DomainControlCenterSsoRequest is single sign on request information for +// domain management +type DomainControlCenterSsoRequest struct { + autorest.Response `json:"-"` + URL *string `json:"url,omitempty"` + PostParameterKey *string `json:"postParameterKey,omitempty"` + PostParameterValue *string `json:"postParameterValue,omitempty"` +} + +// DomainProperties is +type DomainProperties struct { + ContactAdmin *Contact `json:"contactAdmin,omitempty"` + ContactBilling *Contact `json:"contactBilling,omitempty"` + ContactRegistrant *Contact `json:"contactRegistrant,omitempty"` + ContactTech *Contact `json:"contactTech,omitempty"` + RegistrationStatus DomainStatus `json:"registrationStatus,omitempty"` + NameServers *[]string `json:"nameServers,omitempty"` + Privacy *bool `json:"privacy,omitempty"` + CreatedTime *date.Time `json:"createdTime,omitempty"` + ExpirationTime *date.Time `json:"expirationTime,omitempty"` + LastRenewedTime *date.Time `json:"lastRenewedTime,omitempty"` + AutoRenew *bool `json:"autoRenew,omitempty"` + ReadyForDNSRecordManagement *bool `json:"readyForDnsRecordManagement,omitempty"` + ManagedHostNames *[]HostName `json:"managedHostNames,omitempty"` + Consent *DomainPurchaseConsent `json:"consent,omitempty"` +} + +// DomainPurchaseConsent is domain purchase consent object representing +// acceptance of applicable legal agreements +type DomainPurchaseConsent struct { + AgreementKeys *[]string `json:"agreementKeys,omitempty"` + AgreedBy *string `json:"agreedBy,omitempty"` + AgreedAt *date.Time `json:"agreedAt,omitempty"` +} + +// DomainRecommendationSearchParameters is domain recommendation search +// parameters +type DomainRecommendationSearchParameters struct { + Keywords *string `json:"keywords,omitempty"` + MaxDomainRecommendations *int `json:"maxDomainRecommendations,omitempty"` +} + +// DomainRegistrationInput is domain registration input for validation Api +type DomainRegistrationInput struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *DomainRegistrationInputProperties `json:"properties,omitempty"` +} + +// DomainRegistrationInputProperties is +type DomainRegistrationInputProperties struct { + Name *string `json:"name,omitempty"` + ContactAdmin *Contact `json:"contactAdmin,omitempty"` + ContactBilling *Contact `json:"contactBilling,omitempty"` + ContactRegistrant *Contact `json:"contactRegistrant,omitempty"` + ContactTech *Contact `json:"contactTech,omitempty"` + RegistrationStatus DomainStatus `json:"registrationStatus,omitempty"` + NameServers *[]string `json:"nameServers,omitempty"` + Privacy *bool `json:"privacy,omitempty"` + CreatedTime *date.Time `json:"createdTime,omitempty"` + ExpirationTime *date.Time `json:"expirationTime,omitempty"` + LastRenewedTime *date.Time `json:"lastRenewedTime,omitempty"` + AutoRenew *bool `json:"autoRenew,omitempty"` + ReadyForDNSRecordManagement *bool `json:"readyForDnsRecordManagement,omitempty"` + ManagedHostNames *[]HostName `json:"managedHostNames,omitempty"` + Consent *DomainPurchaseConsent `json:"consent,omitempty"` +} + +// EnabledConfig is enabled configuration +type EnabledConfig struct { + Enabled *bool `json:"enabled,omitempty"` +} + +// Experiments is class containing Routing in production experiments +type Experiments struct { + RampUpRules *[]RampUpRule `json:"rampUpRules,omitempty"` +} + +// FileSystemApplicationLogsConfig is application logs to file system +// configuration +type FileSystemApplicationLogsConfig struct { + Level LogLevel `json:"level,omitempty"` +} + +// FileSystemHTTPLogsConfig is http logs to file system configuration +type FileSystemHTTPLogsConfig struct { + RetentionInMb *int `json:"retentionInMb,omitempty"` + RetentionInDays *int `json:"retentionInDays,omitempty"` + Enabled *bool `json:"enabled,omitempty"` +} + +// GeoRegion is geographical region +type GeoRegion struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *GeoRegionProperties `json:"properties,omitempty"` +} + +// GeoRegionCollection is collection of geo regions +type GeoRegionCollection struct { + autorest.Response `json:"-"` + Value *[]GeoRegion `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// GeoRegionProperties is +type GeoRegionProperties struct { + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + DisplayName *string `json:"displayName,omitempty"` +} + +// HandlerMapping is the IIS handler mappings used to define which handler +// processes HTTP requests with certain extension. +// For example it is used to configure php-cgi.exe process to +// handle all HTTP requests with *.php extension. +type HandlerMapping struct { + Extension *string `json:"extension,omitempty"` + ScriptProcessor *string `json:"scriptProcessor,omitempty"` + Arguments *string `json:"arguments,omitempty"` +} + +// HostingEnvironment is description of an hostingEnvironment (App Service +// Environment) +type HostingEnvironment struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *HostingEnvironmentProperties `json:"properties,omitempty"` +} + +// HostingEnvironmentCollection is collection of hosting environments (App +// Service Environments) +type HostingEnvironmentCollection struct { + autorest.Response `json:"-"` + Value *[]HostingEnvironment `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// HostingEnvironmentDiagnostics is diagnostics for a hosting environment (App +// Service Environment) +type HostingEnvironmentDiagnostics struct { + autorest.Response `json:"-"` + Name *string `json:"name,omitempty"` + DiagnosicsOutput *string `json:"diagnosicsOutput,omitempty"` +} + +// HostingEnvironmentDiagnosticsList is +type HostingEnvironmentDiagnosticsList struct { + autorest.Response `json:"-"` + Value *[]HostingEnvironmentDiagnostics `json:"value,omitempty"` +} + +// HostingEnvironmentProfile is specification for a hostingEnvironment (App +// Service Environment) to use for this resource +type HostingEnvironmentProfile struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` +} + +// HostingEnvironmentProperties is +type HostingEnvironmentProperties struct { + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Status HostingEnvironmentStatus `json:"status,omitempty"` + VnetName *string `json:"vnetName,omitempty"` + VnetResourceGroupName *string `json:"vnetResourceGroupName,omitempty"` + VnetSubnetName *string `json:"vnetSubnetName,omitempty"` + VirtualNetwork *VirtualNetworkProfile `json:"virtualNetwork,omitempty"` + InternalLoadBalancingMode InternalLoadBalancingMode `json:"internalLoadBalancingMode,omitempty"` + MultiSize *string `json:"multiSize,omitempty"` + MultiRoleCount *int `json:"multiRoleCount,omitempty"` + WorkerPools *[]WorkerPool `json:"workerPools,omitempty"` + IpsslAddressCount *int `json:"ipsslAddressCount,omitempty"` + DatabaseEdition *string `json:"databaseEdition,omitempty"` + DatabaseServiceObjective *string `json:"databaseServiceObjective,omitempty"` + UpgradeDomains *int `json:"upgradeDomains,omitempty"` + SubscriptionID *string `json:"subscriptionId,omitempty"` + DNSSuffix *string `json:"dnsSuffix,omitempty"` + LastAction *string `json:"lastAction,omitempty"` + LastActionResult *string `json:"lastActionResult,omitempty"` + AllowedMultiSizes *string `json:"allowedMultiSizes,omitempty"` + AllowedWorkerSizes *string `json:"allowedWorkerSizes,omitempty"` + MaximumNumberOfMachines *int `json:"maximumNumberOfMachines,omitempty"` + VipMappings *[]VirtualIPMapping `json:"vipMappings,omitempty"` + EnvironmentCapacities *[]StampCapacity `json:"environmentCapacities,omitempty"` + NetworkAccessControlList *[]NetworkAccessControlEntry `json:"networkAccessControlList,omitempty"` + EnvironmentIsHealthy *bool `json:"environmentIsHealthy,omitempty"` + EnvironmentStatus *string `json:"environmentStatus,omitempty"` + ResourceGroup *string `json:"resourceGroup,omitempty"` + APIManagementAccountID *string `json:"apiManagementAccountId,omitempty"` + Suspended *bool `json:"suspended,omitempty"` +} + +// HostName is details of a hostname derived from a domain +type HostName struct { + Name *string `json:"name,omitempty"` + SiteNames *[]string `json:"siteNames,omitempty"` + AzureResourceName *string `json:"azureResourceName,omitempty"` + AzureResourceType AzureResourceType `json:"azureResourceType,omitempty"` + CustomHostNameDNSRecordType CustomHostNameDNSRecordType `json:"customHostNameDnsRecordType,omitempty"` + HostNameType HostNameType `json:"hostNameType,omitempty"` +} + +// HostNameBinding is a host name binding object +type HostNameBinding struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *HostNameBindingProperties `json:"properties,omitempty"` +} + +// HostNameBindingCollection is collection of host name bindings +type HostNameBindingCollection struct { + autorest.Response `json:"-"` + Value *[]HostNameBinding `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// HostNameBindingProperties is +type HostNameBindingProperties struct { + Name *string `json:"name,omitempty"` + SiteName *string `json:"siteName,omitempty"` + DomainID *string `json:"domainId,omitempty"` + AzureResourceName *string `json:"azureResourceName,omitempty"` + AzureResourceType AzureResourceType `json:"azureResourceType,omitempty"` + CustomHostNameDNSRecordType CustomHostNameDNSRecordType `json:"customHostNameDnsRecordType,omitempty"` + HostNameType HostNameType `json:"hostNameType,omitempty"` +} + +// HostNameSslState is object that represents a SSL-enabled host name. +type HostNameSslState struct { + Name *string `json:"name,omitempty"` + SslState SslState `json:"sslState,omitempty"` + VirtualIP *string `json:"virtualIP,omitempty"` + Thumbprint *string `json:"thumbprint,omitempty"` + ToUpdate *bool `json:"toUpdate,omitempty"` + ToUpdateIPBasedSsl *bool `json:"toUpdateIpBasedSsl,omitempty"` +} + +// HTTPLogsConfig is http logs configuration +type HTTPLogsConfig struct { + FileSystem *FileSystemHTTPLogsConfig `json:"fileSystem,omitempty"` + AzureBlobStorage *AzureBlobStorageHTTPLogsConfig `json:"azureBlobStorage,omitempty"` +} + +// KeyValuePairStringString is +type KeyValuePairStringString struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +// LocalizableString is localizableString object containing the name and a +// localized value. +type LocalizableString struct { + Value *string `json:"value,omitempty"` + LocalizedValue *string `json:"localizedValue,omitempty"` +} + +// ManagedHostingEnvironment is description of a managed hosting environment +type ManagedHostingEnvironment struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *ManagedHostingEnvironmentProperties `json:"properties,omitempty"` +} + +// ManagedHostingEnvironmentCollection is collection of managed hosting +// environments +type ManagedHostingEnvironmentCollection struct { + autorest.Response `json:"-"` + Value *[]ManagedHostingEnvironment `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ManagedHostingEnvironmentProperties is +type ManagedHostingEnvironmentProperties struct { + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Status ManagedHostingEnvironmentStatus `json:"status,omitempty"` + VirtualNetwork *VirtualNetworkProfile `json:"virtualNetwork,omitempty"` + IpsslAddressCount *int `json:"ipsslAddressCount,omitempty"` + DNSSuffix *string `json:"dnsSuffix,omitempty"` + SubscriptionID *string `json:"subscriptionId,omitempty"` + ResourceGroup *string `json:"resourceGroup,omitempty"` + EnvironmentIsHealthy *bool `json:"environmentIsHealthy,omitempty"` + EnvironmentStatus *string `json:"environmentStatus,omitempty"` + Suspended *bool `json:"suspended,omitempty"` +} + +// MetricAvailabilily is class repesenting metrics availability and retention +type MetricAvailabilily struct { + TimeGrain *string `json:"timeGrain,omitempty"` + Retention *string `json:"retention,omitempty"` +} + +// MetricDefinition is class repesenting metadata for the metrics +type MetricDefinition struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *MetricDefinitionProperties `json:"properties,omitempty"` +} + +// MetricDefinitionCollection is collection of metric defintions +type MetricDefinitionCollection struct { + autorest.Response `json:"-"` + Value *[]MetricDefinition `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// MetricDefinitionProperties is +type MetricDefinitionProperties struct { + Name *string `json:"name,omitempty"` + Unit *string `json:"unit,omitempty"` + PrimaryAggregationType *string `json:"primaryAggregationType,omitempty"` + MetricAvailabilities *[]MetricAvailabilily `json:"metricAvailabilities,omitempty"` + DisplayName *string `json:"displayName,omitempty"` +} + +// NameIdentifier is identifies an object +type NameIdentifier struct { + Name *string `json:"name,omitempty"` +} + +// NameIdentifierCollection is collection of domain name identifiers +type NameIdentifierCollection struct { + autorest.Response `json:"-"` + Value *[]NameIdentifier `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// NameValuePair is name value pair +type NameValuePair struct { + Name *string `json:"name,omitempty"` + Value *string `json:"value,omitempty"` +} + +// NetworkAccessControlEntry is +type NetworkAccessControlEntry struct { + Action AccessControlEntryAction `json:"action,omitempty"` + Description *string `json:"description,omitempty"` + Order *int `json:"order,omitempty"` + RemoteSubnet *string `json:"remoteSubnet,omitempty"` +} + +// NetworkFeatures is this is an object used to store a full view of network +// features (presently VNET integration and Hybrid Connections) +// for a web app. +type NetworkFeatures struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *NetworkFeaturesProperties `json:"properties,omitempty"` +} + +// NetworkFeaturesProperties is +type NetworkFeaturesProperties struct { + VirtualNetworkName *string `json:"virtualNetworkName,omitempty"` + VirtualNetworkConnection *VnetInfo `json:"virtualNetworkConnection,omitempty"` + HybridConnections *[]RelayServiceConnectionEntity `json:"hybridConnections,omitempty"` +} + +// ObjectSet is +type ObjectSet struct { + autorest.Response `json:"-"` + Value *map[string]interface{} `json:"value,omitempty"` +} + +// PremierAddOnRequest is +type PremierAddOnRequest struct { + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Plan *ArmPlan `json:"plan,omitempty"` + Properties *map[string]interface{} `json:"properties,omitempty"` + Sku *SkuDescription `json:"sku,omitempty"` +} + +// RampUpRule is routing rules for ramp up testing. This rule allows to +// redirect static traffic % to a slot or to gradually change routing % based +// on performance +type RampUpRule struct { + ActionHostName *string `json:"actionHostName,omitempty"` + ReroutePercentage *float64 `json:"reroutePercentage,omitempty"` + ChangeStep *float64 `json:"changeStep,omitempty"` + ChangeIntervalInMinutes *int `json:"changeIntervalInMinutes,omitempty"` + MinReroutePercentage *float64 `json:"minReroutePercentage,omitempty"` + MaxReroutePercentage *float64 `json:"maxReroutePercentage,omitempty"` + ChangeDecisionCallbackURL *string `json:"changeDecisionCallbackUrl,omitempty"` + Name *string `json:"name,omitempty"` +} + +// RelayServiceConnectionEntity is class that represents a Biztalk Hybrid +// Connection +type RelayServiceConnectionEntity struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *RelayServiceConnectionEntityProperties `json:"properties,omitempty"` +} + +// RelayServiceConnectionEntityProperties is +type RelayServiceConnectionEntityProperties struct { + EntityName *string `json:"entityName,omitempty"` + EntityConnectionString *string `json:"entityConnectionString,omitempty"` + ResourceType *string `json:"resourceType,omitempty"` + ResourceConnectionString *string `json:"resourceConnectionString,omitempty"` + Hostname *string `json:"hostname,omitempty"` + Port *int `json:"port,omitempty"` + BiztalkURI *string `json:"biztalkUri,omitempty"` +} + +// RequestsBasedTrigger is requestsBasedTrigger +type RequestsBasedTrigger struct { + Count *int `json:"count,omitempty"` + TimeInterval *string `json:"timeInterval,omitempty"` +} + +// Resource is +type Resource struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` +} + +// ResourceMetric is object representing a metric for any resource +type ResourceMetric struct { + Name *ResourceMetricName `json:"name,omitempty"` + Unit *string `json:"unit,omitempty"` + TimeGrain *string `json:"timeGrain,omitempty"` + StartTime *date.Time `json:"startTime,omitempty"` + EndTime *date.Time `json:"endTime,omitempty"` + ResourceID *string `json:"resourceId,omitempty"` + MetricValues *[]ResourceMetricValue `json:"metricValues,omitempty"` + Properties *[]KeyValuePairStringString `json:"properties,omitempty"` +} + +// ResourceMetricCollection is collection of metric responses +type ResourceMetricCollection struct { + autorest.Response `json:"-"` + Value *[]ResourceMetric `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ResourceMetricName is name of a metric for any resource +type ResourceMetricName struct { + Value *string `json:"value,omitempty"` + LocalizedValue *string `json:"localizedValue,omitempty"` +} + +// ResourceMetricValue is value of resource metric +type ResourceMetricValue struct { + TimeStamp *string `json:"timeStamp,omitempty"` + Average *float64 `json:"average,omitempty"` + Minimum *float64 `json:"minimum,omitempty"` + Maximum *float64 `json:"maximum,omitempty"` + Total *float64 `json:"total,omitempty"` + Count *float64 `json:"count,omitempty"` +} + +// ResourceNameAvailability is describes if a resource name is available +type ResourceNameAvailability struct { + autorest.Response `json:"-"` + NameAvailable *bool `json:"nameAvailable,omitempty"` + Reason *string `json:"reason,omitempty"` + Message *string `json:"message,omitempty"` +} + +// ResourceNameAvailabilityRequest is resource name availability request +// content +type ResourceNameAvailabilityRequest struct { + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + IsFqdn *bool `json:"isFqdn,omitempty"` +} + +// RestoreRequest is description of a restore request +type RestoreRequest struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *RestoreRequestProperties `json:"properties,omitempty"` +} + +// RestoreRequestProperties is +type RestoreRequestProperties struct { + StorageAccountURL *string `json:"storageAccountUrl,omitempty"` + BlobName *string `json:"blobName,omitempty"` + Overwrite *bool `json:"overwrite,omitempty"` + SiteName *string `json:"siteName,omitempty"` + Databases *[]DatabaseBackupSetting `json:"databases,omitempty"` + IgnoreConflictingHostNames *bool `json:"ignoreConflictingHostNames,omitempty"` + OperationType BackupRestoreOperationType `json:"operationType,omitempty"` + AdjustConnectionStrings *bool `json:"adjustConnectionStrings,omitempty"` + HostingEnvironment *string `json:"hostingEnvironment,omitempty"` +} + +// RestoreResponse is response for a restore site request +type RestoreResponse struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *RestoreResponseProperties `json:"properties,omitempty"` +} + +// RestoreResponseProperties is +type RestoreResponseProperties struct { + OperationID *string `json:"operationId,omitempty"` +} + +// RoutingRule is routing rules for TiP +type RoutingRule struct { + Name *string `json:"name,omitempty"` +} + +// ServerFarmCollection is collection of serverfarms +type ServerFarmCollection struct { + autorest.Response `json:"-"` + Value *[]ServerFarmWithRichSku `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ServerFarmWithRichSku is app Service Plan Model +type ServerFarmWithRichSku struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *ServerFarmWithRichSkuProperties `json:"properties,omitempty"` + Sku *SkuDescription `json:"sku,omitempty"` +} + +// ServerFarmWithRichSkuProperties is +type ServerFarmWithRichSkuProperties struct { + Name *string `json:"name,omitempty"` + Status StatusOptions `json:"status,omitempty"` + Subscription *string `json:"subscription,omitempty"` + AdminSiteName *string `json:"adminSiteName,omitempty"` + HostingEnvironmentProfile *HostingEnvironmentProfile `json:"hostingEnvironmentProfile,omitempty"` + MaximumNumberOfWorkers *int `json:"maximumNumberOfWorkers,omitempty"` + GeoRegion *string `json:"geoRegion,omitempty"` + PerSiteScaling *bool `json:"perSiteScaling,omitempty"` + NumberOfSites *int `json:"numberOfSites,omitempty"` + ResourceGroup *string `json:"resourceGroup,omitempty"` +} + +// Site is represents a web app +type Site struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *SiteProperties `json:"properties,omitempty"` +} + +// SiteAuthSettings is configuration settings for the Azure App Service +// Authentication / Authorization feature. +type SiteAuthSettings struct { + autorest.Response `json:"-"` + Enabled *bool `json:"enabled,omitempty"` + HTTPAPIPrefixPath *string `json:"httpApiPrefixPath,omitempty"` + UnauthenticatedClientAction UnauthenticatedClientAction `json:"unauthenticatedClientAction,omitempty"` + TokenStoreEnabled *bool `json:"tokenStoreEnabled,omitempty"` + AllowedExternalRedirectUrls *[]string `json:"allowedExternalRedirectUrls,omitempty"` + DefaultProvider BuiltInAuthenticationProvider `json:"defaultProvider,omitempty"` + ClientID *string `json:"clientId,omitempty"` + ClientSecret *string `json:"clientSecret,omitempty"` + Issuer *string `json:"issuer,omitempty"` + AllowedAudiences *[]string `json:"allowedAudiences,omitempty"` + AadClientID *string `json:"aadClientId,omitempty"` + OpenIDIssuer *string `json:"openIdIssuer,omitempty"` + GoogleClientID *string `json:"googleClientId,omitempty"` + GoogleClientSecret *string `json:"googleClientSecret,omitempty"` + GoogleOAuthScopes *[]string `json:"googleOAuthScopes,omitempty"` + FacebookAppID *string `json:"facebookAppId,omitempty"` + FacebookAppSecret *string `json:"facebookAppSecret,omitempty"` + FacebookOAuthScopes *[]string `json:"facebookOAuthScopes,omitempty"` + TwitterConsumerKey *string `json:"twitterConsumerKey,omitempty"` + TwitterConsumerSecret *string `json:"twitterConsumerSecret,omitempty"` + MicrosoftAccountClientID *string `json:"microsoftAccountClientId,omitempty"` + MicrosoftAccountClientSecret *string `json:"microsoftAccountClientSecret,omitempty"` + MicrosoftAccountOAuthScopes *[]string `json:"microsoftAccountOAuthScopes,omitempty"` +} + +// SiteCollection is collection of sites +type SiteCollection struct { + autorest.Response `json:"-"` + Value *[]Site `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// SiteCollectionPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client SiteCollection) SiteCollectionPreparer() (*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))) +} + +// SiteConfig is configuration of Azure web site +type SiteConfig struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *SiteConfigProperties `json:"properties,omitempty"` +} + +// SiteConfigProperties is +type SiteConfigProperties struct { + NumberOfWorkers *int `json:"numberOfWorkers,omitempty"` + DefaultDocuments *[]string `json:"defaultDocuments,omitempty"` + NetFrameworkVersion *string `json:"netFrameworkVersion,omitempty"` + PhpVersion *string `json:"phpVersion,omitempty"` + PythonVersion *string `json:"pythonVersion,omitempty"` + RequestTracingEnabled *bool `json:"requestTracingEnabled,omitempty"` + RequestTracingExpirationTime *date.Time `json:"requestTracingExpirationTime,omitempty"` + RemoteDebuggingEnabled *bool `json:"remoteDebuggingEnabled,omitempty"` + RemoteDebuggingVersion *string `json:"remoteDebuggingVersion,omitempty"` + HTTPLoggingEnabled *bool `json:"httpLoggingEnabled,omitempty"` + LogsDirectorySizeLimit *int `json:"logsDirectorySizeLimit,omitempty"` + DetailedErrorLoggingEnabled *bool `json:"detailedErrorLoggingEnabled,omitempty"` + PublishingUsername *string `json:"publishingUsername,omitempty"` + PublishingPassword *string `json:"publishingPassword,omitempty"` + AppSettings *[]NameValuePair `json:"appSettings,omitempty"` + Metadata *[]NameValuePair `json:"metadata,omitempty"` + ConnectionStrings *[]ConnStringInfo `json:"connectionStrings,omitempty"` + HandlerMappings *[]HandlerMapping `json:"handlerMappings,omitempty"` + DocumentRoot *string `json:"documentRoot,omitempty"` + ScmType *string `json:"scmType,omitempty"` + Use32BitWorkerProcess *bool `json:"use32BitWorkerProcess,omitempty"` + WebSocketsEnabled *bool `json:"webSocketsEnabled,omitempty"` + AlwaysOn *bool `json:"alwaysOn,omitempty"` + JavaVersion *string `json:"javaVersion,omitempty"` + JavaContainer *string `json:"javaContainer,omitempty"` + JavaContainerVersion *string `json:"javaContainerVersion,omitempty"` + ManagedPipelineMode ManagedPipelineMode `json:"managedPipelineMode,omitempty"` + VirtualApplications *[]VirtualApplication `json:"virtualApplications,omitempty"` + LoadBalancing SiteLoadBalancing `json:"loadBalancing,omitempty"` + Experiments *Experiments `json:"experiments,omitempty"` + Limits *SiteLimits `json:"limits,omitempty"` + AutoHealEnabled *bool `json:"autoHealEnabled,omitempty"` + AutoHealRules *AutoHealRules `json:"autoHealRules,omitempty"` + TracingOptions *string `json:"tracingOptions,omitempty"` + VnetName *string `json:"vnetName,omitempty"` + AutoSwapSlotName *string `json:"autoSwapSlotName,omitempty"` +} + +// SiteInstance is instance of a web app +type SiteInstance struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *SiteInstanceProperties `json:"properties,omitempty"` +} + +// SiteInstanceCollection is collection of site instances +type SiteInstanceCollection struct { + autorest.Response `json:"-"` + Value *[]SiteInstance `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// SiteInstanceProperties is +type SiteInstanceProperties struct { + Name *string `json:"name,omitempty"` +} + +// SiteLimits is represents metric limits set on a web app. +type SiteLimits struct { + MaxPercentageCPU *float64 `json:"maxPercentageCpu,omitempty"` + MaxMemoryInMb *int32 `json:"maxMemoryInMb,omitempty"` + MaxDiskSizeInMb *int32 `json:"maxDiskSizeInMb,omitempty"` +} + +// SiteLogsConfig is configuration of Azure web site +type SiteLogsConfig struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *SiteLogsConfigProperties `json:"properties,omitempty"` +} + +// SiteLogsConfigProperties is +type SiteLogsConfigProperties struct { + ApplicationLogs *ApplicationLogsConfig `json:"applicationLogs,omitempty"` + HTTPLogs *HTTPLogsConfig `json:"httpLogs,omitempty"` + FailedRequestsTracing *EnabledConfig `json:"failedRequestsTracing,omitempty"` + DetailedErrorMessages *EnabledConfig `json:"detailedErrorMessages,omitempty"` +} + +// SiteProperties is +type SiteProperties struct { + Name *string `json:"name,omitempty"` + State *string `json:"state,omitempty"` + HostNames *[]string `json:"hostNames,omitempty"` + RepositorySiteName *string `json:"repositorySiteName,omitempty"` + UsageState UsageState `json:"usageState,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + EnabledHostNames *[]string `json:"enabledHostNames,omitempty"` + AvailabilityState SiteAvailabilityState `json:"availabilityState,omitempty"` + HostNameSslStates *[]HostNameSslState `json:"hostNameSslStates,omitempty"` + ServerFarmID *string `json:"serverFarmId,omitempty"` + LastModifiedTimeUtc *date.Time `json:"lastModifiedTimeUtc,omitempty"` + SiteConfig *SiteConfig `json:"siteConfig,omitempty"` + TrafficManagerHostNames *[]string `json:"trafficManagerHostNames,omitempty"` + PremiumAppDeployed *bool `json:"premiumAppDeployed,omitempty"` + ScmSiteAlsoStopped *bool `json:"scmSiteAlsoStopped,omitempty"` + TargetSwapSlot *string `json:"targetSwapSlot,omitempty"` + HostingEnvironmentProfile *HostingEnvironmentProfile `json:"hostingEnvironmentProfile,omitempty"` + MicroService *string `json:"microService,omitempty"` + GatewaySiteName *string `json:"gatewaySiteName,omitempty"` + ClientAffinityEnabled *bool `json:"clientAffinityEnabled,omitempty"` + ClientCertEnabled *bool `json:"clientCertEnabled,omitempty"` + OutboundIPAddresses *string `json:"outboundIpAddresses,omitempty"` + CloningInfo *CloningInfo `json:"cloningInfo,omitempty"` +} + +// SitePropertiesModel is +type SitePropertiesModel struct { + Metadata *[]NameValuePair `json:"metadata,omitempty"` + Properties *[]NameValuePair `json:"properties,omitempty"` + AppSettings *[]NameValuePair `json:"appSettings,omitempty"` +} + +// SiteSourceControl is describes the source control configuration for web app +type SiteSourceControl struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *SiteSourceControlProperties `json:"properties,omitempty"` +} + +// SiteSourceControlProperties is +type SiteSourceControlProperties struct { + RepoURL *string `json:"repoUrl,omitempty"` + Branch *string `json:"branch,omitempty"` + IsManualIntegration *bool `json:"isManualIntegration,omitempty"` + DeploymentRollbackEnabled *bool `json:"deploymentRollbackEnabled,omitempty"` + IsMercurial *bool `json:"isMercurial,omitempty"` +} + +// SkuCapacity is description of the App Service Plan scale options +type SkuCapacity struct { + Minimum *int `json:"minimum,omitempty"` + Maximum *int `json:"maximum,omitempty"` + Default *int `json:"default,omitempty"` + ScaleType *string `json:"scaleType,omitempty"` +} + +// SkuDescription is describes a sku for a scalable resource +type SkuDescription struct { + Name *string `json:"name,omitempty"` + Tier *string `json:"tier,omitempty"` + Size *string `json:"size,omitempty"` + Family *string `json:"family,omitempty"` + Capacity *int `json:"capacity,omitempty"` +} + +// SkuInfo is sku discovery information +type SkuInfo struct { + ResourceType *string `json:"resourceType,omitempty"` + Sku *SkuDescription `json:"sku,omitempty"` + Capacity *SkuCapacity `json:"capacity,omitempty"` +} + +// SkuInfoCollection is collection of SkuInfos +type SkuInfoCollection struct { + autorest.Response `json:"-"` + Value *[]SkuInfo `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// SlotConfigNames is class containing names for connection strings and +// application settings to be marked as sticky to the slot +// and not moved during swap operation +// This is valid for all deployment slots under the site +type SlotConfigNames struct { + ConnectionStringNames *[]string `json:"connectionStringNames,omitempty"` + AppSettingNames *[]string `json:"appSettingNames,omitempty"` +} + +// SlotConfigNamesResource is slot Config names azure resource +type SlotConfigNamesResource struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *SlotConfigNamesResourceProperties `json:"properties,omitempty"` +} + +// SlotConfigNamesResourceProperties is +type SlotConfigNamesResourceProperties struct { + ConnectionStringNames *[]string `json:"connectionStringNames,omitempty"` + AppSettingNames *[]string `json:"appSettingNames,omitempty"` +} + +// SlotDifference is an object describing the difference in setting values +// between two web app slots +type SlotDifference struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *SlotDifferenceProperties `json:"properties,omitempty"` +} + +// SlotDifferenceCollection is collection of Slot Differences +type SlotDifferenceCollection struct { + autorest.Response `json:"-"` + Value *[]SlotDifference `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// SlotDifferenceProperties is +type SlotDifferenceProperties struct { + Type *string `json:"type,omitempty"` + SettingType *string `json:"settingType,omitempty"` + DiffRule *string `json:"diffRule,omitempty"` + SettingName *string `json:"settingName,omitempty"` + ValueInCurrentSlot *string `json:"valueInCurrentSlot,omitempty"` + ValueInTargetSlot *string `json:"valueInTargetSlot,omitempty"` + Description *string `json:"description,omitempty"` +} + +// SlowRequestsBasedTrigger is slowRequestsBasedTrigger +type SlowRequestsBasedTrigger struct { + TimeTaken *string `json:"timeTaken,omitempty"` + Count *int `json:"count,omitempty"` + TimeInterval *string `json:"timeInterval,omitempty"` +} + +// SourceControl is describes the Source Control OAuth Token +type SourceControl struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *SourceControlProperties `json:"properties,omitempty"` +} + +// SourceControlCollection is collection of soure controls +type SourceControlCollection struct { + autorest.Response `json:"-"` + Value *[]SourceControl `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// SourceControlProperties is +type SourceControlProperties struct { + Name *string `json:"name,omitempty"` + Token *string `json:"token,omitempty"` + TokenSecret *string `json:"tokenSecret,omitempty"` + RefreshToken *string `json:"refreshToken,omitempty"` + ExpirationTime *date.Time `json:"expirationTime,omitempty"` +} + +// StampCapacity is class containing stamp capacity information +type StampCapacity struct { + Name *string `json:"name,omitempty"` + AvailableCapacity *int32 `json:"availableCapacity,omitempty"` + TotalCapacity *int32 `json:"totalCapacity,omitempty"` + Unit *string `json:"unit,omitempty"` + ComputeMode ComputeModeOptions `json:"computeMode,omitempty"` + WorkerSize WorkerSizeOptions `json:"workerSize,omitempty"` + WorkerSizeID *int `json:"workerSizeId,omitempty"` + ExcludeFromCapacityAllocation *bool `json:"excludeFromCapacityAllocation,omitempty"` + IsApplicableForAllComputeModes *bool `json:"isApplicableForAllComputeModes,omitempty"` + SiteMode *string `json:"siteMode,omitempty"` +} + +// StampCapacityCollection is collection of stamp capacities +type StampCapacityCollection struct { + autorest.Response `json:"-"` + Value *[]StampCapacity `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// StatusCodesBasedTrigger is statusCodeBasedTrigger +type StatusCodesBasedTrigger struct { + Status *int `json:"status,omitempty"` + SubStatus *int `json:"subStatus,omitempty"` + Win32Status *int `json:"win32Status,omitempty"` + Count *int `json:"count,omitempty"` + TimeInterval *string `json:"timeInterval,omitempty"` +} + +// StringDictionary is string dictionary resource +type StringDictionary struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *map[string]*string `json:"properties,omitempty"` +} + +// TldLegalAgreement is represents a legal agreement for top level domain +type TldLegalAgreement struct { + AgreementKey *string `json:"agreementKey,omitempty"` + Title *string `json:"title,omitempty"` + Content *string `json:"content,omitempty"` + URL *string `json:"url,omitempty"` +} + +// TldLegalAgreementCollection is collection of Tld Legal Agreements +type TldLegalAgreementCollection struct { + autorest.Response `json:"-"` + Value *[]TldLegalAgreement `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// TopLevelDomain is a top level domain object +type TopLevelDomain struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *TopLevelDomainProperties `json:"properties,omitempty"` +} + +// TopLevelDomainAgreementOption is options for retrieving the list of top +// level domain legal agreements +type TopLevelDomainAgreementOption struct { + IncludePrivacy *bool `json:"includePrivacy,omitempty"` +} + +// TopLevelDomainCollection is collection of Top Level Domains +type TopLevelDomainCollection struct { + autorest.Response `json:"-"` + Value *[]TopLevelDomain `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// TopLevelDomainProperties is +type TopLevelDomainProperties struct { + Name *string `json:"name,omitempty"` + Privacy *bool `json:"privacy,omitempty"` +} + +// Usage is class that represents usage of the quota resource. +type Usage struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *UsageProperties `json:"properties,omitempty"` +} + +// UsageCollection is collection of usages +type UsageCollection struct { + autorest.Response `json:"-"` + Value *[]Usage `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// UsageProperties is +type UsageProperties struct { + DisplayName *string `json:"displayName,omitempty"` + Name *string `json:"name,omitempty"` + ResourceName *string `json:"resourceName,omitempty"` + Unit *string `json:"unit,omitempty"` + CurrentValue *int32 `json:"currentValue,omitempty"` + Limit *int32 `json:"limit,omitempty"` + NextResetTime *date.Time `json:"nextResetTime,omitempty"` + ComputeMode ComputeModeOptions `json:"computeMode,omitempty"` + SiteMode *string `json:"siteMode,omitempty"` +} + +// User is represents user crendentials used for publishing activity +type User struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *UserProperties `json:"properties,omitempty"` +} + +// UserProperties is +type UserProperties struct { + Name *string `json:"name,omitempty"` + PublishingUserName *string `json:"publishingUserName,omitempty"` + PublishingPassword *string `json:"publishingPassword,omitempty"` + LastUpdatedTime *date.Time `json:"lastUpdatedTime,omitempty"` + Metadata *string `json:"metadata,omitempty"` + IsDeleted *bool `json:"isDeleted,omitempty"` + ScmURI *string `json:"scmUri,omitempty"` +} + +// VirtualApplication is +type VirtualApplication struct { + VirtualPath *string `json:"virtualPath,omitempty"` + PhysicalPath *string `json:"physicalPath,omitempty"` + PreloadEnabled *bool `json:"preloadEnabled,omitempty"` + VirtualDirectories *[]VirtualDirectory `json:"virtualDirectories,omitempty"` +} + +// VirtualDirectory is +type VirtualDirectory struct { + VirtualPath *string `json:"virtualPath,omitempty"` + PhysicalPath *string `json:"physicalPath,omitempty"` +} + +// VirtualIPMapping is class that represents a VIP mapping +type VirtualIPMapping struct { + VirtualIP *string `json:"virtualIP,omitempty"` + InternalHTTPPort *int `json:"internalHttpPort,omitempty"` + InternalHTTPSPort *int `json:"internalHttpsPort,omitempty"` + InUse *bool `json:"inUse,omitempty"` +} + +// VirtualNetworkProfile is specification for using a virtual network +type VirtualNetworkProfile struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Subnet *string `json:"subnet,omitempty"` +} + +// VnetGateway is the VnetGateway contract. This is used to give the vnet +// gateway access to the VPN package. +type VnetGateway struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *VnetGatewayProperties `json:"properties,omitempty"` +} + +// VnetGatewayProperties is +type VnetGatewayProperties struct { + VnetName *string `json:"vnetName,omitempty"` + VpnPackageURI *string `json:"vpnPackageUri,omitempty"` +} + +// VnetInfo is vNETInfo contract. This contract is public and is a stripped +// down version of VNETInfoInternal +type VnetInfo struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *VnetInfoProperties `json:"properties,omitempty"` +} + +// VnetInfoList is +type VnetInfoList struct { + autorest.Response `json:"-"` + Value *[]VnetInfo `json:"value,omitempty"` +} + +// VnetInfoProperties is +type VnetInfoProperties struct { + VnetResourceID *string `json:"vnetResourceId,omitempty"` + CertThumbprint *string `json:"certThumbprint,omitempty"` + CertBlob *string `json:"certBlob,omitempty"` + Routes *[]VnetRoute `json:"routes,omitempty"` +} + +// VnetRoute is vnetRoute contract used to pass routing information for a vnet. +type VnetRoute struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *VnetRouteProperties `json:"properties,omitempty"` +} + +// VnetRouteList is +type VnetRouteList struct { + autorest.Response `json:"-"` + Value *[]VnetRoute `json:"value,omitempty"` +} + +// VnetRouteProperties is +type VnetRouteProperties struct { + Name *string `json:"name,omitempty"` + StartAddress *string `json:"startAddress,omitempty"` + EndAddress *string `json:"endAddress,omitempty"` + RouteType *string `json:"routeType,omitempty"` +} + +// WorkerPool is worker pool of a hostingEnvironment (App Service Environment) +type WorkerPool struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Location *string `json:"location,omitempty"` + Type *string `json:"type,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *WorkerPoolProperties `json:"properties,omitempty"` + Sku *SkuDescription `json:"sku,omitempty"` +} + +// WorkerPoolCollection is collection of worker pools +type WorkerPoolCollection struct { + autorest.Response `json:"-"` + Value *[]WorkerPool `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// WorkerPoolProperties is +type WorkerPoolProperties struct { + WorkerSizeID *int `json:"workerSizeId,omitempty"` + ComputeMode ComputeModeOptions `json:"computeMode,omitempty"` + WorkerSize *string `json:"workerSize,omitempty"` + WorkerCount *int `json:"workerCount,omitempty"` + InstanceNames *[]string `json:"instanceNames,omitempty"` +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/provider.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/provider.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/provider.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/provider.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,337 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// ProviderClient is the use these APIs to manage Azure Websites resources +// through the Azure Resource Manager. All task operations conform to the +// HTTP/1.1 protocol specification and each operation returns an +// x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type ProviderClient struct { + ManagementClient +} + +// NewProviderClient creates an instance of the ProviderClient client. +func NewProviderClient(subscriptionID string) ProviderClient { + return NewProviderClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewProviderClientWithBaseURI creates an instance of the ProviderClient +// client. +func NewProviderClientWithBaseURI(baseURI string, subscriptionID string) ProviderClient { + return ProviderClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// GetPublishingUser sends the get publishing user request. +func (client ProviderClient) GetPublishingUser() (result User, ae error) { + req, err := client.GetPublishingUserPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ProviderClient", "GetPublishingUser", "Failure preparing request") + } + + resp, err := client.GetPublishingUserSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ProviderClient", "GetPublishingUser", "Failure sending request") + } + + result, err = client.GetPublishingUserResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ProviderClient", "GetPublishingUser", "Failure responding to request") + } + + return +} + +// GetPublishingUserPreparer prepares the GetPublishingUser request. +func (client ProviderClient) GetPublishingUserPreparer() (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/providers/Microsoft.Web/publishingUsers/web"), + autorest.WithQueryParameters(queryParameters)) +} + +// GetPublishingUserSender sends the GetPublishingUser request. The method will close the +// http.Response Body if it receives an error. +func (client ProviderClient) GetPublishingUserSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetPublishingUserResponder handles the response to the GetPublishingUser request. The method always +// closes the http.Response Body. +func (client ProviderClient) GetPublishingUserResponder(resp *http.Response) (result User, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSourceControl sends the get source control request. +// +// sourceControlType is type of source control +func (client ProviderClient) GetSourceControl(sourceControlType string) (result SourceControl, ae error) { + req, err := client.GetSourceControlPreparer(sourceControlType) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ProviderClient", "GetSourceControl", "Failure preparing request") + } + + resp, err := client.GetSourceControlSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ProviderClient", "GetSourceControl", "Failure sending request") + } + + result, err = client.GetSourceControlResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ProviderClient", "GetSourceControl", "Failure responding to request") + } + + return +} + +// GetSourceControlPreparer prepares the GetSourceControl request. +func (client ProviderClient) GetSourceControlPreparer(sourceControlType string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "sourceControlType": url.QueryEscape(sourceControlType), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/providers/Microsoft.Web/sourcecontrols/{sourceControlType}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSourceControlSender sends the GetSourceControl request. The method will close the +// http.Response Body if it receives an error. +func (client ProviderClient) GetSourceControlSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSourceControlResponder handles the response to the GetSourceControl request. The method always +// closes the http.Response Body. +func (client ProviderClient) GetSourceControlResponder(resp *http.Response) (result SourceControl, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSourceControls sends the get source controls request. +func (client ProviderClient) GetSourceControls() (result SourceControlCollection, ae error) { + req, err := client.GetSourceControlsPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ProviderClient", "GetSourceControls", "Failure preparing request") + } + + resp, err := client.GetSourceControlsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ProviderClient", "GetSourceControls", "Failure sending request") + } + + result, err = client.GetSourceControlsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ProviderClient", "GetSourceControls", "Failure responding to request") + } + + return +} + +// GetSourceControlsPreparer prepares the GetSourceControls request. +func (client ProviderClient) GetSourceControlsPreparer() (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/providers/Microsoft.Web/sourcecontrols"), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSourceControlsSender sends the GetSourceControls request. The method will close the +// http.Response Body if it receives an error. +func (client ProviderClient) GetSourceControlsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSourceControlsResponder handles the response to the GetSourceControls request. The method always +// closes the http.Response Body. +func (client ProviderClient) GetSourceControlsResponder(resp *http.Response) (result SourceControlCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdatePublishingUser sends the update publishing user request. +// +// requestMessage is details of publishing user +func (client ProviderClient) UpdatePublishingUser(requestMessage User) (result User, ae error) { + req, err := client.UpdatePublishingUserPreparer(requestMessage) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ProviderClient", "UpdatePublishingUser", "Failure preparing request") + } + + resp, err := client.UpdatePublishingUserSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ProviderClient", "UpdatePublishingUser", "Failure sending request") + } + + result, err = client.UpdatePublishingUserResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ProviderClient", "UpdatePublishingUser", "Failure responding to request") + } + + return +} + +// UpdatePublishingUserPreparer prepares the UpdatePublishingUser request. +func (client ProviderClient) UpdatePublishingUserPreparer(requestMessage User) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/providers/Microsoft.Web/publishingUsers/web"), + autorest.WithJSON(requestMessage), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdatePublishingUserSender sends the UpdatePublishingUser request. The method will close the +// http.Response Body if it receives an error. +func (client ProviderClient) UpdatePublishingUserSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdatePublishingUserResponder handles the response to the UpdatePublishingUser request. The method always +// closes the http.Response Body. +func (client ProviderClient) UpdatePublishingUserResponder(resp *http.Response) (result User, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSourceControl sends the update source control request. +// +// sourceControlType is type of source control requestMessage is source +// control token information +func (client ProviderClient) UpdateSourceControl(sourceControlType string, requestMessage SourceControl) (result SourceControl, ae error) { + req, err := client.UpdateSourceControlPreparer(sourceControlType, requestMessage) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ProviderClient", "UpdateSourceControl", "Failure preparing request") + } + + resp, err := client.UpdateSourceControlSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ProviderClient", "UpdateSourceControl", "Failure sending request") + } + + result, err = client.UpdateSourceControlResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ProviderClient", "UpdateSourceControl", "Failure responding to request") + } + + return +} + +// UpdateSourceControlPreparer prepares the UpdateSourceControl request. +func (client ProviderClient) UpdateSourceControlPreparer(sourceControlType string, requestMessage SourceControl) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "sourceControlType": url.QueryEscape(sourceControlType), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/providers/Microsoft.Web/sourcecontrols/{sourceControlType}"), + autorest.WithJSON(requestMessage), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSourceControlSender sends the UpdateSourceControl request. The method will close the +// http.Response Body if it receives an error. +func (client ProviderClient) UpdateSourceControlSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSourceControlResponder handles the response to the UpdateSourceControl request. The method always +// closes the http.Response Body. +func (client ProviderClient) UpdateSourceControlResponder(resp *http.Response) (result SourceControl, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/serverfarms.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/serverfarms.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/serverfarms.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/serverfarms.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,1349 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// ServerFarmsClient is the use these APIs to manage Azure Websites resources +// through the Azure Resource Manager. All task operations conform to the +// HTTP/1.1 protocol specification and each operation returns an +// x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type ServerFarmsClient struct { + ManagementClient +} + +// NewServerFarmsClient creates an instance of the ServerFarmsClient client. +func NewServerFarmsClient(subscriptionID string) ServerFarmsClient { + return NewServerFarmsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewServerFarmsClientWithBaseURI creates an instance of the +// ServerFarmsClient client. +func NewServerFarmsClientWithBaseURI(baseURI string, subscriptionID string) ServerFarmsClient { + return ServerFarmsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdateServerFarm sends the create or update server farm request. +// +// resourceGroupName is name of resource group name is name of App Service +// Plan serverFarmEnvelope is details of App Service Plan allowPendingState +// is oBSOLETE: If true, allow pending state for App Service Plan +func (client ServerFarmsClient) CreateOrUpdateServerFarm(resourceGroupName string, name string, serverFarmEnvelope ServerFarmWithRichSku, allowPendingState *bool) (result ServerFarmWithRichSku, ae error) { + req, err := client.CreateOrUpdateServerFarmPreparer(resourceGroupName, name, serverFarmEnvelope, allowPendingState) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "CreateOrUpdateServerFarm", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateServerFarmSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "CreateOrUpdateServerFarm", "Failure sending request") + } + + result, err = client.CreateOrUpdateServerFarmResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "CreateOrUpdateServerFarm", "Failure responding to request") + } + + return +} + +// CreateOrUpdateServerFarmPreparer prepares the CreateOrUpdateServerFarm request. +func (client ServerFarmsClient) CreateOrUpdateServerFarmPreparer(resourceGroupName string, name string, serverFarmEnvelope ServerFarmWithRichSku, allowPendingState *bool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if allowPendingState != nil { + queryParameters["allowPendingState"] = allowPendingState + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}"), + autorest.WithJSON(serverFarmEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateServerFarmSender sends the CreateOrUpdateServerFarm request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) CreateOrUpdateServerFarmSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// CreateOrUpdateServerFarmResponder handles the response to the CreateOrUpdateServerFarm request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) CreateOrUpdateServerFarmResponder(resp *http.Response) (result ServerFarmWithRichSku, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateVnetRoute sends the create or update vnet route request. +// +// resourceGroupName is name of resource group name is name of App Service +// Plan vnetName is name of virtual network routeName is name of the virtual +// network route route is the route object +func (client ServerFarmsClient) CreateOrUpdateVnetRoute(resourceGroupName string, name string, vnetName string, routeName string, route VnetRoute) (result VnetRoute, ae error) { + req, err := client.CreateOrUpdateVnetRoutePreparer(resourceGroupName, name, vnetName, routeName, route) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "CreateOrUpdateVnetRoute", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateVnetRouteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "CreateOrUpdateVnetRoute", "Failure sending request") + } + + result, err = client.CreateOrUpdateVnetRouteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "CreateOrUpdateVnetRoute", "Failure responding to request") + } + + return +} + +// CreateOrUpdateVnetRoutePreparer prepares the CreateOrUpdateVnetRoute request. +func (client ServerFarmsClient) CreateOrUpdateVnetRoutePreparer(resourceGroupName string, name string, vnetName string, routeName string, route VnetRoute) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "routeName": url.QueryEscape(routeName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/virtualNetworkConnections/{vnetName}/routes/{routeName}"), + autorest.WithJSON(route), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateVnetRouteSender sends the CreateOrUpdateVnetRoute request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) CreateOrUpdateVnetRouteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusBadRequest, http.StatusNotFound) +} + +// CreateOrUpdateVnetRouteResponder handles the response to the CreateOrUpdateVnetRoute request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) CreateOrUpdateVnetRouteResponder(resp *http.Response) (result VnetRoute, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusBadRequest, http.StatusNotFound), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteServerFarm sends the delete server farm request. +// +// resourceGroupName is name of resource group name is name of App Service +// Plan +func (client ServerFarmsClient) DeleteServerFarm(resourceGroupName string, name string) (result ObjectSet, ae error) { + req, err := client.DeleteServerFarmPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "DeleteServerFarm", "Failure preparing request") + } + + resp, err := client.DeleteServerFarmSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "DeleteServerFarm", "Failure sending request") + } + + result, err = client.DeleteServerFarmResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "DeleteServerFarm", "Failure responding to request") + } + + return +} + +// DeleteServerFarmPreparer prepares the DeleteServerFarm request. +func (client ServerFarmsClient) DeleteServerFarmPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteServerFarmSender sends the DeleteServerFarm request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) DeleteServerFarmSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteServerFarmResponder handles the response to the DeleteServerFarm request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) DeleteServerFarmResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteVnetRoute sends the delete vnet route request. +// +// resourceGroupName is name of resource group name is name of App Service +// Plan vnetName is name of virtual network routeName is name of the virtual +// network route +func (client ServerFarmsClient) DeleteVnetRoute(resourceGroupName string, name string, vnetName string, routeName string) (result ObjectSet, ae error) { + req, err := client.DeleteVnetRoutePreparer(resourceGroupName, name, vnetName, routeName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "DeleteVnetRoute", "Failure preparing request") + } + + resp, err := client.DeleteVnetRouteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "DeleteVnetRoute", "Failure sending request") + } + + result, err = client.DeleteVnetRouteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "DeleteVnetRoute", "Failure responding to request") + } + + return +} + +// DeleteVnetRoutePreparer prepares the DeleteVnetRoute request. +func (client ServerFarmsClient) DeleteVnetRoutePreparer(resourceGroupName string, name string, vnetName string, routeName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "routeName": url.QueryEscape(routeName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/virtualNetworkConnections/{vnetName}/routes/{routeName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteVnetRouteSender sends the DeleteVnetRoute request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) DeleteVnetRouteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusNotFound) +} + +// DeleteVnetRouteResponder handles the response to the DeleteVnetRoute request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) DeleteVnetRouteResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNotFound), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetRouteForVnet sends the get route for vnet request. +// +// resourceGroupName is name of resource group name is name of App Service +// Plan vnetName is name of virtual network routeName is name of the virtual +// network route +func (client ServerFarmsClient) GetRouteForVnet(resourceGroupName string, name string, vnetName string, routeName string) (result VnetRouteList, ae error) { + req, err := client.GetRouteForVnetPreparer(resourceGroupName, name, vnetName, routeName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetRouteForVnet", "Failure preparing request") + } + + resp, err := client.GetRouteForVnetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetRouteForVnet", "Failure sending request") + } + + result, err = client.GetRouteForVnetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetRouteForVnet", "Failure responding to request") + } + + return +} + +// GetRouteForVnetPreparer prepares the GetRouteForVnet request. +func (client ServerFarmsClient) GetRouteForVnetPreparer(resourceGroupName string, name string, vnetName string, routeName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "routeName": url.QueryEscape(routeName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/virtualNetworkConnections/{vnetName}/routes/{routeName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetRouteForVnetSender sends the GetRouteForVnet request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) GetRouteForVnetSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusNotFound) +} + +// GetRouteForVnetResponder handles the response to the GetRouteForVnet request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) GetRouteForVnetResponder(resp *http.Response) (result VnetRouteList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNotFound), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetRoutesForVnet sends the get routes for vnet request. +// +// resourceGroupName is name of resource group name is name of App Service +// Plan vnetName is name of virtual network +func (client ServerFarmsClient) GetRoutesForVnet(resourceGroupName string, name string, vnetName string) (result VnetRouteList, ae error) { + req, err := client.GetRoutesForVnetPreparer(resourceGroupName, name, vnetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetRoutesForVnet", "Failure preparing request") + } + + resp, err := client.GetRoutesForVnetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetRoutesForVnet", "Failure sending request") + } + + result, err = client.GetRoutesForVnetResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetRoutesForVnet", "Failure responding to request") + } + + return +} + +// GetRoutesForVnetPreparer prepares the GetRoutesForVnet request. +func (client ServerFarmsClient) GetRoutesForVnetPreparer(resourceGroupName string, name string, vnetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/virtualNetworkConnections/{vnetName}/routes"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetRoutesForVnetSender sends the GetRoutesForVnet request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) GetRoutesForVnetSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetRoutesForVnetResponder handles the response to the GetRoutesForVnet request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) GetRoutesForVnetResponder(resp *http.Response) (result VnetRouteList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetServerFarm sends the get server farm request. +// +// resourceGroupName is name of resource group name is name of App Service +// Plan +func (client ServerFarmsClient) GetServerFarm(resourceGroupName string, name string) (result ServerFarmWithRichSku, ae error) { + req, err := client.GetServerFarmPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarm", "Failure preparing request") + } + + resp, err := client.GetServerFarmSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarm", "Failure sending request") + } + + result, err = client.GetServerFarmResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarm", "Failure responding to request") + } + + return +} + +// GetServerFarmPreparer prepares the GetServerFarm request. +func (client ServerFarmsClient) GetServerFarmPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetServerFarmSender sends the GetServerFarm request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) GetServerFarmSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetServerFarmResponder handles the response to the GetServerFarm request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) GetServerFarmResponder(resp *http.Response) (result ServerFarmWithRichSku, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetServerFarmMetricDefintions sends the get server farm metric defintions +// request. +// +// resourceGroupName is name of resource group name is name of App Service +// Plan +func (client ServerFarmsClient) GetServerFarmMetricDefintions(resourceGroupName string, name string) (result MetricDefinitionCollection, ae error) { + req, err := client.GetServerFarmMetricDefintionsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmMetricDefintions", "Failure preparing request") + } + + resp, err := client.GetServerFarmMetricDefintionsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmMetricDefintions", "Failure sending request") + } + + result, err = client.GetServerFarmMetricDefintionsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmMetricDefintions", "Failure responding to request") + } + + return +} + +// GetServerFarmMetricDefintionsPreparer prepares the GetServerFarmMetricDefintions request. +func (client ServerFarmsClient) GetServerFarmMetricDefintionsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/metricdefinitions"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetServerFarmMetricDefintionsSender sends the GetServerFarmMetricDefintions request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) GetServerFarmMetricDefintionsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetServerFarmMetricDefintionsResponder handles the response to the GetServerFarmMetricDefintions request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) GetServerFarmMetricDefintionsResponder(resp *http.Response) (result MetricDefinitionCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetServerFarmMetrics sends the get server farm metrics request. +// +// resourceGroupName is name of resource group name is name of App Service +// Plan details is if true, metrics are broken down per App Service Plan +// instance filter is return only usages/metrics specified in the filter. +// Filter conforms to odata syntax. Example: $filter=(name.value eq 'Metric1' +// or name.value eq 'Metric2') and startTime eq '2014-01-01T00:00:00Z' and +// endTime eq '2014-12-31T23:59:59Z' and timeGrain eq +// duration'[Hour|Minute|Day]'. +func (client ServerFarmsClient) GetServerFarmMetrics(resourceGroupName string, name string, details *bool, filter string) (result ResourceMetricCollection, ae error) { + req, err := client.GetServerFarmMetricsPreparer(resourceGroupName, name, details, filter) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmMetrics", "Failure preparing request") + } + + resp, err := client.GetServerFarmMetricsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmMetrics", "Failure sending request") + } + + result, err = client.GetServerFarmMetricsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmMetrics", "Failure responding to request") + } + + return +} + +// GetServerFarmMetricsPreparer prepares the GetServerFarmMetrics request. +func (client ServerFarmsClient) GetServerFarmMetricsPreparer(resourceGroupName string, name string, details *bool, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if details != nil { + queryParameters["details"] = details + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/metrics"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetServerFarmMetricsSender sends the GetServerFarmMetrics request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) GetServerFarmMetricsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetServerFarmMetricsResponder handles the response to the GetServerFarmMetrics request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) GetServerFarmMetricsResponder(resp *http.Response) (result ResourceMetricCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetServerFarmOperation sends the get server farm operation request. +// +// resourceGroupName is name of resource group name is name of server farm +// operationID is id of Server farm operation"> +func (client ServerFarmsClient) GetServerFarmOperation(resourceGroupName string, name string, operationID string) (result ServerFarmWithRichSku, ae error) { + req, err := client.GetServerFarmOperationPreparer(resourceGroupName, name, operationID) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmOperation", "Failure preparing request") + } + + resp, err := client.GetServerFarmOperationSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmOperation", "Failure sending request") + } + + result, err = client.GetServerFarmOperationResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmOperation", "Failure responding to request") + } + + return +} + +// GetServerFarmOperationPreparer prepares the GetServerFarmOperation request. +func (client ServerFarmsClient) GetServerFarmOperationPreparer(resourceGroupName string, name string, operationID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "operationId": url.QueryEscape(operationID), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/operationresults/{operationId}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetServerFarmOperationSender sends the GetServerFarmOperation request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) GetServerFarmOperationSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetServerFarmOperationResponder handles the response to the GetServerFarmOperation request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) GetServerFarmOperationResponder(resp *http.Response) (result ServerFarmWithRichSku, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetServerFarms sends the get server farms request. +// +// resourceGroupName is name of resource group +func (client ServerFarmsClient) GetServerFarms(resourceGroupName string) (result ServerFarmCollection, ae error) { + req, err := client.GetServerFarmsPreparer(resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarms", "Failure preparing request") + } + + resp, err := client.GetServerFarmsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarms", "Failure sending request") + } + + result, err = client.GetServerFarmsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarms", "Failure responding to request") + } + + return +} + +// GetServerFarmsPreparer prepares the GetServerFarms request. +func (client ServerFarmsClient) GetServerFarmsPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetServerFarmsSender sends the GetServerFarms request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) GetServerFarmsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetServerFarmsResponder handles the response to the GetServerFarms request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) GetServerFarmsResponder(resp *http.Response) (result ServerFarmCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetServerFarmSites sends the get server farm sites request. +// +// resourceGroupName is name of resource group name is name of App Service +// Plan skipToken is skip to of web apps in a list. If specified, the +// resulting list will contain web apps starting from (including) the +// skipToken. Else, the resulting list contains web apps from the start of +// the list filter is supported filter: $filter=state eq running. Returns +// only web apps that are currently running top is list page size. If +// specified, results are paged. +func (client ServerFarmsClient) GetServerFarmSites(resourceGroupName string, name string, skipToken string, filter string, top string) (result SiteCollection, ae error) { + req, err := client.GetServerFarmSitesPreparer(resourceGroupName, name, skipToken, filter, top) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmSites", "Failure preparing request") + } + + resp, err := client.GetServerFarmSitesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmSites", "Failure sending request") + } + + result, err = client.GetServerFarmSitesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmSites", "Failure responding to request") + } + + return +} + +// GetServerFarmSitesPreparer prepares the GetServerFarmSites request. +func (client ServerFarmsClient) GetServerFarmSitesPreparer(resourceGroupName string, name string, skipToken string, filter string, top string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(skipToken) > 0 { + queryParameters["$skipToken"] = skipToken + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + if len(top) > 0 { + queryParameters["$top"] = top + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/sites"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetServerFarmSitesSender sends the GetServerFarmSites request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) GetServerFarmSitesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetServerFarmSitesResponder handles the response to the GetServerFarmSites request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) GetServerFarmSitesResponder(resp *http.Response) (result SiteCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetServerFarmSitesNextResults retrieves the next set of results, if any. +func (client ServerFarmsClient) GetServerFarmSitesNextResults(lastResults SiteCollection) (result SiteCollection, ae error) { + req, err := lastResults.SiteCollectionPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmSites", "Failure preparing next results request request") + } + if req == nil { + return + } + + resp, err := client.GetServerFarmSitesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmSites", "Failure sending next results request request") + } + + result, err = client.GetServerFarmSitesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmSites", "Failure responding to next results request request") + } + + return +} + +// GetServerFarmVnetGateway sends the get server farm vnet gateway request. +// +// resourceGroupName is name of resource group name is name of the App Service +// Plan vnetName is name of the virtual network gatewayName is name of the +// gateway. Only the 'primary' gateway is supported. +func (client ServerFarmsClient) GetServerFarmVnetGateway(resourceGroupName string, name string, vnetName string, gatewayName string) (result VnetGateway, ae error) { + req, err := client.GetServerFarmVnetGatewayPreparer(resourceGroupName, name, vnetName, gatewayName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmVnetGateway", "Failure preparing request") + } + + resp, err := client.GetServerFarmVnetGatewaySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmVnetGateway", "Failure sending request") + } + + result, err = client.GetServerFarmVnetGatewayResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetServerFarmVnetGateway", "Failure responding to request") + } + + return +} + +// GetServerFarmVnetGatewayPreparer prepares the GetServerFarmVnetGateway request. +func (client ServerFarmsClient) GetServerFarmVnetGatewayPreparer(resourceGroupName string, name string, vnetName string, gatewayName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "gatewayName": url.QueryEscape(gatewayName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/virtualNetworkConnections/{vnetName}/gateways/{gatewayName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetServerFarmVnetGatewaySender sends the GetServerFarmVnetGateway request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) GetServerFarmVnetGatewaySender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetServerFarmVnetGatewayResponder handles the response to the GetServerFarmVnetGateway request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) GetServerFarmVnetGatewayResponder(resp *http.Response) (result VnetGateway, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetVnetFromServerFarm sends the get vnet from server farm request. +// +// resourceGroupName is name of resource group name is name of App Service +// Plan vnetName is name of virtual network +func (client ServerFarmsClient) GetVnetFromServerFarm(resourceGroupName string, name string, vnetName string) (result VnetInfo, ae error) { + req, err := client.GetVnetFromServerFarmPreparer(resourceGroupName, name, vnetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetVnetFromServerFarm", "Failure preparing request") + } + + resp, err := client.GetVnetFromServerFarmSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetVnetFromServerFarm", "Failure sending request") + } + + result, err = client.GetVnetFromServerFarmResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetVnetFromServerFarm", "Failure responding to request") + } + + return +} + +// GetVnetFromServerFarmPreparer prepares the GetVnetFromServerFarm request. +func (client ServerFarmsClient) GetVnetFromServerFarmPreparer(resourceGroupName string, name string, vnetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/virtualNetworkConnections/{vnetName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetVnetFromServerFarmSender sends the GetVnetFromServerFarm request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) GetVnetFromServerFarmSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusNotFound) +} + +// GetVnetFromServerFarmResponder handles the response to the GetVnetFromServerFarm request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) GetVnetFromServerFarmResponder(resp *http.Response) (result VnetInfo, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNotFound), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetVnetsForServerFarm sends the get vnets for server farm request. +// +// resourceGroupName is name of resource group name is name of App Service +// Plan +func (client ServerFarmsClient) GetVnetsForServerFarm(resourceGroupName string, name string) (result VnetInfoList, ae error) { + req, err := client.GetVnetsForServerFarmPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetVnetsForServerFarm", "Failure preparing request") + } + + resp, err := client.GetVnetsForServerFarmSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetVnetsForServerFarm", "Failure sending request") + } + + result, err = client.GetVnetsForServerFarmResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "GetVnetsForServerFarm", "Failure responding to request") + } + + return +} + +// GetVnetsForServerFarmPreparer prepares the GetVnetsForServerFarm request. +func (client ServerFarmsClient) GetVnetsForServerFarmPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/virtualNetworkConnections"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetVnetsForServerFarmSender sends the GetVnetsForServerFarm request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) GetVnetsForServerFarmSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetVnetsForServerFarmResponder handles the response to the GetVnetsForServerFarm request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) GetVnetsForServerFarmResponder(resp *http.Response) (result VnetInfoList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// RebootWorkerForServerFarm sends the reboot worker for server farm request. +// +// resourceGroupName is name of resource group name is name of server farm +// workerName is name of worker machine, typically IP address +func (client ServerFarmsClient) RebootWorkerForServerFarm(resourceGroupName string, name string, workerName string) (result ObjectSet, ae error) { + req, err := client.RebootWorkerForServerFarmPreparer(resourceGroupName, name, workerName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "RebootWorkerForServerFarm", "Failure preparing request") + } + + resp, err := client.RebootWorkerForServerFarmSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "RebootWorkerForServerFarm", "Failure sending request") + } + + result, err = client.RebootWorkerForServerFarmResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "RebootWorkerForServerFarm", "Failure responding to request") + } + + return +} + +// RebootWorkerForServerFarmPreparer prepares the RebootWorkerForServerFarm request. +func (client ServerFarmsClient) RebootWorkerForServerFarmPreparer(resourceGroupName string, name string, workerName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "workerName": url.QueryEscape(workerName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/workers/{workerName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// RebootWorkerForServerFarmSender sends the RebootWorkerForServerFarm request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) RebootWorkerForServerFarmSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// RebootWorkerForServerFarmResponder handles the response to the RebootWorkerForServerFarm request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) RebootWorkerForServerFarmResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// RestartSitesForServerFarm sends the restart sites for server farm request. +// +// resourceGroupName is name of resource group name is name of App Service +// Plan softRestart is soft restart applies the configuration settings and +// restarts the apps if necessary. Hard restart always restarts and +// reprovisions the apps +func (client ServerFarmsClient) RestartSitesForServerFarm(resourceGroupName string, name string, softRestart *bool) (result ObjectSet, ae error) { + req, err := client.RestartSitesForServerFarmPreparer(resourceGroupName, name, softRestart) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "RestartSitesForServerFarm", "Failure preparing request") + } + + resp, err := client.RestartSitesForServerFarmSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "RestartSitesForServerFarm", "Failure sending request") + } + + result, err = client.RestartSitesForServerFarmResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "RestartSitesForServerFarm", "Failure responding to request") + } + + return +} + +// RestartSitesForServerFarmPreparer prepares the RestartSitesForServerFarm request. +func (client ServerFarmsClient) RestartSitesForServerFarmPreparer(resourceGroupName string, name string, softRestart *bool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if softRestart != nil { + queryParameters["softRestart"] = softRestart + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/restartSites"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// RestartSitesForServerFarmSender sends the RestartSitesForServerFarm request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) RestartSitesForServerFarmSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// RestartSitesForServerFarmResponder handles the response to the RestartSitesForServerFarm request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) RestartSitesForServerFarmResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateServerFarmVnetGateway sends the update server farm vnet gateway +// request. +// +// resourceGroupName is the resource group name is the name of the App Service +// Plan vnetName is the name of the virtual network gatewayName is the name +// of the gateway. Only 'primary' is supported. connectionEnvelope is the +// gateway entity. +func (client ServerFarmsClient) UpdateServerFarmVnetGateway(resourceGroupName string, name string, vnetName string, gatewayName string, connectionEnvelope VnetGateway) (result VnetGateway, ae error) { + req, err := client.UpdateServerFarmVnetGatewayPreparer(resourceGroupName, name, vnetName, gatewayName, connectionEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "UpdateServerFarmVnetGateway", "Failure preparing request") + } + + resp, err := client.UpdateServerFarmVnetGatewaySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "UpdateServerFarmVnetGateway", "Failure sending request") + } + + result, err = client.UpdateServerFarmVnetGatewayResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "UpdateServerFarmVnetGateway", "Failure responding to request") + } + + return +} + +// UpdateServerFarmVnetGatewayPreparer prepares the UpdateServerFarmVnetGateway request. +func (client ServerFarmsClient) UpdateServerFarmVnetGatewayPreparer(resourceGroupName string, name string, vnetName string, gatewayName string, connectionEnvelope VnetGateway) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "gatewayName": url.QueryEscape(gatewayName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/virtualNetworkConnections/{vnetName}/gateways/{gatewayName}"), + autorest.WithJSON(connectionEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateServerFarmVnetGatewaySender sends the UpdateServerFarmVnetGateway request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) UpdateServerFarmVnetGatewaySender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateServerFarmVnetGatewayResponder handles the response to the UpdateServerFarmVnetGateway request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) UpdateServerFarmVnetGatewayResponder(resp *http.Response) (result VnetGateway, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateVnetRoute sends the update vnet route request. +// +// resourceGroupName is name of resource group name is name of App Service +// Plan vnetName is name of virtual network routeName is name of the virtual +// network route route is the route object +func (client ServerFarmsClient) UpdateVnetRoute(resourceGroupName string, name string, vnetName string, routeName string, route VnetRoute) (result VnetRoute, ae error) { + req, err := client.UpdateVnetRoutePreparer(resourceGroupName, name, vnetName, routeName, route) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "UpdateVnetRoute", "Failure preparing request") + } + + resp, err := client.UpdateVnetRouteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/ServerFarmsClient", "UpdateVnetRoute", "Failure sending request") + } + + result, err = client.UpdateVnetRouteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/ServerFarmsClient", "UpdateVnetRoute", "Failure responding to request") + } + + return +} + +// UpdateVnetRoutePreparer prepares the UpdateVnetRoute request. +func (client ServerFarmsClient) UpdateVnetRoutePreparer(resourceGroupName string, name string, vnetName string, routeName string, route VnetRoute) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "routeName": url.QueryEscape(routeName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/serverfarms/{name}/virtualNetworkConnections/{vnetName}/routes/{routeName}"), + autorest.WithJSON(route), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateVnetRouteSender sends the UpdateVnetRoute request. The method will close the +// http.Response Body if it receives an error. +func (client ServerFarmsClient) UpdateVnetRouteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusBadRequest, http.StatusNotFound) +} + +// UpdateVnetRouteResponder handles the response to the UpdateVnetRoute request. The method always +// closes the http.Response Body. +func (client ServerFarmsClient) UpdateVnetRouteResponder(resp *http.Response) (result VnetRoute, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusBadRequest, http.StatusNotFound), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/sites.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/sites.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/sites.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/sites.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,10559 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// SitesClient is the use these APIs to manage Azure Websites resources +// through the Azure Resource Manager. All task operations conform to the +// HTTP/1.1 protocol specification and each operation returns an +// x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type SitesClient struct { + ManagementClient +} + +// NewSitesClient creates an instance of the SitesClient client. +func NewSitesClient(subscriptionID string) SitesClient { + return NewSitesClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewSitesClientWithBaseURI creates an instance of the SitesClient client. +func NewSitesClientWithBaseURI(baseURI string, subscriptionID string) SitesClient { + return SitesClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// AddSitePremierAddOn sends the add site premier add on request. +// +func (client SitesClient) AddSitePremierAddOn(resourceGroupName string, name string, premierAddOnName string, premierAddOn PremierAddOnRequest) (result ObjectSet, ae error) { + req, err := client.AddSitePremierAddOnPreparer(resourceGroupName, name, premierAddOnName, premierAddOn) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "AddSitePremierAddOn", "Failure preparing request") + } + + resp, err := client.AddSitePremierAddOnSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "AddSitePremierAddOn", "Failure sending request") + } + + result, err = client.AddSitePremierAddOnResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "AddSitePremierAddOn", "Failure responding to request") + } + + return +} + +// AddSitePremierAddOnPreparer prepares the AddSitePremierAddOn request. +func (client SitesClient) AddSitePremierAddOnPreparer(resourceGroupName string, name string, premierAddOnName string, premierAddOn PremierAddOnRequest) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "premierAddOnName": url.QueryEscape(premierAddOnName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/premieraddons/{premierAddOnName}"), + autorest.WithJSON(premierAddOn), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// AddSitePremierAddOnSender sends the AddSitePremierAddOn request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) AddSitePremierAddOnSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// AddSitePremierAddOnResponder handles the response to the AddSitePremierAddOn request. The method always +// closes the http.Response Body. +func (client SitesClient) AddSitePremierAddOnResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// AddSitePremierAddOnSlot sends the add site premier add on slot request. +// +func (client SitesClient) AddSitePremierAddOnSlot(resourceGroupName string, name string, premierAddOnName string, premierAddOn PremierAddOnRequest, slot string) (result ObjectSet, ae error) { + req, err := client.AddSitePremierAddOnSlotPreparer(resourceGroupName, name, premierAddOnName, premierAddOn, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "AddSitePremierAddOnSlot", "Failure preparing request") + } + + resp, err := client.AddSitePremierAddOnSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "AddSitePremierAddOnSlot", "Failure sending request") + } + + result, err = client.AddSitePremierAddOnSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "AddSitePremierAddOnSlot", "Failure responding to request") + } + + return +} + +// AddSitePremierAddOnSlotPreparer prepares the AddSitePremierAddOnSlot request. +func (client SitesClient) AddSitePremierAddOnSlotPreparer(resourceGroupName string, name string, premierAddOnName string, premierAddOn PremierAddOnRequest, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "premierAddOnName": url.QueryEscape(premierAddOnName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/premieraddons/{premierAddOnName}"), + autorest.WithJSON(premierAddOn), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// AddSitePremierAddOnSlotSender sends the AddSitePremierAddOnSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) AddSitePremierAddOnSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// AddSitePremierAddOnSlotResponder handles the response to the AddSitePremierAddOnSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) AddSitePremierAddOnSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ApplySlotConfigSlot sends the apply slot config slot request. +// +// resourceGroupName is name of resource group name is name of web app +// slotSwapEntity is request body that contains the target slot name. +// Settings from that slot will be applied on the source slot slot is name of +// the source slot. Settings from the target slot will be applied onto this +// slot +func (client SitesClient) ApplySlotConfigSlot(resourceGroupName string, name string, slotSwapEntity CsmSlotEntity, slot string) (result ObjectSet, ae error) { + req, err := client.ApplySlotConfigSlotPreparer(resourceGroupName, name, slotSwapEntity, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ApplySlotConfigSlot", "Failure preparing request") + } + + resp, err := client.ApplySlotConfigSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ApplySlotConfigSlot", "Failure sending request") + } + + result, err = client.ApplySlotConfigSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ApplySlotConfigSlot", "Failure responding to request") + } + + return +} + +// ApplySlotConfigSlotPreparer prepares the ApplySlotConfigSlot request. +func (client SitesClient) ApplySlotConfigSlotPreparer(resourceGroupName string, name string, slotSwapEntity CsmSlotEntity, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/applySlotConfig"), + autorest.WithJSON(slotSwapEntity), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ApplySlotConfigSlotSender sends the ApplySlotConfigSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ApplySlotConfigSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ApplySlotConfigSlotResponder handles the response to the ApplySlotConfigSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) ApplySlotConfigSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ApplySlotConfigToProduction sends the apply slot config to production +// request. +// +// resourceGroupName is name of resource group name is name of web app +// slotSwapEntity is request body that contains the target slot name. +// Settings from that slot will be applied on the source slot +func (client SitesClient) ApplySlotConfigToProduction(resourceGroupName string, name string, slotSwapEntity CsmSlotEntity) (result ObjectSet, ae error) { + req, err := client.ApplySlotConfigToProductionPreparer(resourceGroupName, name, slotSwapEntity) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ApplySlotConfigToProduction", "Failure preparing request") + } + + resp, err := client.ApplySlotConfigToProductionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ApplySlotConfigToProduction", "Failure sending request") + } + + result, err = client.ApplySlotConfigToProductionResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ApplySlotConfigToProduction", "Failure responding to request") + } + + return +} + +// ApplySlotConfigToProductionPreparer prepares the ApplySlotConfigToProduction request. +func (client SitesClient) ApplySlotConfigToProductionPreparer(resourceGroupName string, name string, slotSwapEntity CsmSlotEntity) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/applySlotConfig"), + autorest.WithJSON(slotSwapEntity), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ApplySlotConfigToProductionSender sends the ApplySlotConfigToProduction request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ApplySlotConfigToProductionSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ApplySlotConfigToProductionResponder handles the response to the ApplySlotConfigToProduction request. The method always +// closes the http.Response Body. +func (client SitesClient) ApplySlotConfigToProductionResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// BackupSite sends the backup site request. +// +// resourceGroupName is name of resource group name is name of web app request +// is information on backup request +func (client SitesClient) BackupSite(resourceGroupName string, name string, request BackupRequest) (result BackupItem, ae error) { + req, err := client.BackupSitePreparer(resourceGroupName, name, request) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "BackupSite", "Failure preparing request") + } + + resp, err := client.BackupSiteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "BackupSite", "Failure sending request") + } + + result, err = client.BackupSiteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "BackupSite", "Failure responding to request") + } + + return +} + +// BackupSitePreparer prepares the BackupSite request. +func (client SitesClient) BackupSitePreparer(resourceGroupName string, name string, request BackupRequest) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/backup"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// BackupSiteSender sends the BackupSite request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) BackupSiteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// BackupSiteResponder handles the response to the BackupSite request. The method always +// closes the http.Response Body. +func (client SitesClient) BackupSiteResponder(resp *http.Response) (result BackupItem, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// BackupSiteDeprecated sends the backup site deprecated request. +// +// resourceGroupName is name of resource group name is name of web app request +// is information on backup request +func (client SitesClient) BackupSiteDeprecated(resourceGroupName string, name string, request BackupRequest) (result BackupItem, ae error) { + req, err := client.BackupSiteDeprecatedPreparer(resourceGroupName, name, request) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "BackupSiteDeprecated", "Failure preparing request") + } + + resp, err := client.BackupSiteDeprecatedSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "BackupSiteDeprecated", "Failure sending request") + } + + result, err = client.BackupSiteDeprecatedResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "BackupSiteDeprecated", "Failure responding to request") + } + + return +} + +// BackupSiteDeprecatedPreparer prepares the BackupSiteDeprecated request. +func (client SitesClient) BackupSiteDeprecatedPreparer(resourceGroupName string, name string, request BackupRequest) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/backup"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// BackupSiteDeprecatedSender sends the BackupSiteDeprecated request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) BackupSiteDeprecatedSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// BackupSiteDeprecatedResponder handles the response to the BackupSiteDeprecated request. The method always +// closes the http.Response Body. +func (client SitesClient) BackupSiteDeprecatedResponder(resp *http.Response) (result BackupItem, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// BackupSiteDeprecatedSlot sends the backup site deprecated slot request. +// +// resourceGroupName is name of resource group name is name of web app request +// is information on backup request slot is name of web app slot. If not +// specified then will default to production slot. +func (client SitesClient) BackupSiteDeprecatedSlot(resourceGroupName string, name string, request BackupRequest, slot string) (result BackupItem, ae error) { + req, err := client.BackupSiteDeprecatedSlotPreparer(resourceGroupName, name, request, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "BackupSiteDeprecatedSlot", "Failure preparing request") + } + + resp, err := client.BackupSiteDeprecatedSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "BackupSiteDeprecatedSlot", "Failure sending request") + } + + result, err = client.BackupSiteDeprecatedSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "BackupSiteDeprecatedSlot", "Failure responding to request") + } + + return +} + +// BackupSiteDeprecatedSlotPreparer prepares the BackupSiteDeprecatedSlot request. +func (client SitesClient) BackupSiteDeprecatedSlotPreparer(resourceGroupName string, name string, request BackupRequest, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/backup"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// BackupSiteDeprecatedSlotSender sends the BackupSiteDeprecatedSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) BackupSiteDeprecatedSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// BackupSiteDeprecatedSlotResponder handles the response to the BackupSiteDeprecatedSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) BackupSiteDeprecatedSlotResponder(resp *http.Response) (result BackupItem, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// BackupSiteSlot sends the backup site slot request. +// +// resourceGroupName is name of resource group name is name of web app request +// is information on backup request slot is name of web app slot. If not +// specified then will default to production slot. +func (client SitesClient) BackupSiteSlot(resourceGroupName string, name string, request BackupRequest, slot string) (result BackupItem, ae error) { + req, err := client.BackupSiteSlotPreparer(resourceGroupName, name, request, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "BackupSiteSlot", "Failure preparing request") + } + + resp, err := client.BackupSiteSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "BackupSiteSlot", "Failure sending request") + } + + result, err = client.BackupSiteSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "BackupSiteSlot", "Failure responding to request") + } + + return +} + +// BackupSiteSlotPreparer prepares the BackupSiteSlot request. +func (client SitesClient) BackupSiteSlotPreparer(resourceGroupName string, name string, request BackupRequest, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/backup"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// BackupSiteSlotSender sends the BackupSiteSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) BackupSiteSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// BackupSiteSlotResponder handles the response to the BackupSiteSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) BackupSiteSlotResponder(resp *http.Response) (result BackupItem, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateSite sends the create or update site request. +// +// resourceGroupName is name of the resource group name is name of the web app +// siteEnvelope is details of web app if it exists already +// skipDNSRegistration is if true web app hostname is not registered with DNS +// on creation. This parameter is +// only used for app creation skipCustomDomainVerification is if +// true, custom (non *.azurewebsites.net) domains associated with web app are +// not verified. forceDNSRegistration is if true, web app hostname is force +// registered with DNS ttlInSeconds is time to live in seconds for web app's +// default domain name +func (client SitesClient) CreateOrUpdateSite(resourceGroupName string, name string, siteEnvelope Site, skipDNSRegistration string, skipCustomDomainVerification string, forceDNSRegistration string, ttlInSeconds string) (result Site, ae error) { + req, err := client.CreateOrUpdateSitePreparer(resourceGroupName, name, siteEnvelope, skipDNSRegistration, skipCustomDomainVerification, forceDNSRegistration, ttlInSeconds) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSite", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSiteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSite", "Failure sending request") + } + + result, err = client.CreateOrUpdateSiteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSite", "Failure responding to request") + } + + return +} + +// CreateOrUpdateSitePreparer prepares the CreateOrUpdateSite request. +func (client SitesClient) CreateOrUpdateSitePreparer(resourceGroupName string, name string, siteEnvelope Site, skipDNSRegistration string, skipCustomDomainVerification string, forceDNSRegistration string, ttlInSeconds string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(skipDNSRegistration) > 0 { + queryParameters["skipDnsRegistration"] = skipDNSRegistration + } + if len(skipCustomDomainVerification) > 0 { + queryParameters["skipCustomDomainVerification"] = skipCustomDomainVerification + } + if len(forceDNSRegistration) > 0 { + queryParameters["forceDnsRegistration"] = forceDNSRegistration + } + if len(ttlInSeconds) > 0 { + queryParameters["ttlInSeconds"] = ttlInSeconds + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}"), + autorest.WithJSON(siteEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSiteSender sends the CreateOrUpdateSite request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) CreateOrUpdateSiteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// CreateOrUpdateSiteResponder handles the response to the CreateOrUpdateSite request. The method always +// closes the http.Response Body. +func (client SitesClient) CreateOrUpdateSiteResponder(resp *http.Response) (result Site, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateSiteConfig sends the create or update site config request. +// +// resourceGroupName is name of resource group name is name of web app +// siteConfig is request body that contains the configuraiton setting for the +// web app +func (client SitesClient) CreateOrUpdateSiteConfig(resourceGroupName string, name string, siteConfig SiteConfig) (result SiteConfig, ae error) { + req, err := client.CreateOrUpdateSiteConfigPreparer(resourceGroupName, name, siteConfig) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteConfig", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSiteConfigSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteConfig", "Failure sending request") + } + + result, err = client.CreateOrUpdateSiteConfigResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteConfig", "Failure responding to request") + } + + return +} + +// CreateOrUpdateSiteConfigPreparer prepares the CreateOrUpdateSiteConfig request. +func (client SitesClient) CreateOrUpdateSiteConfigPreparer(resourceGroupName string, name string, siteConfig SiteConfig) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/web"), + autorest.WithJSON(siteConfig), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSiteConfigSender sends the CreateOrUpdateSiteConfig request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) CreateOrUpdateSiteConfigSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateSiteConfigResponder handles the response to the CreateOrUpdateSiteConfig request. The method always +// closes the http.Response Body. +func (client SitesClient) CreateOrUpdateSiteConfigResponder(resp *http.Response) (result SiteConfig, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateSiteConfigSlot sends the create or update site config slot +// request. +// +// resourceGroupName is name of resource group name is name of web app +// siteConfig is request body that contains the configuraiton setting for the +// web app slot is name of web app slot. If not specified then will default +// to production slot. +func (client SitesClient) CreateOrUpdateSiteConfigSlot(resourceGroupName string, name string, siteConfig SiteConfig, slot string) (result SiteConfig, ae error) { + req, err := client.CreateOrUpdateSiteConfigSlotPreparer(resourceGroupName, name, siteConfig, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteConfigSlot", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSiteConfigSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteConfigSlot", "Failure sending request") + } + + result, err = client.CreateOrUpdateSiteConfigSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteConfigSlot", "Failure responding to request") + } + + return +} + +// CreateOrUpdateSiteConfigSlotPreparer prepares the CreateOrUpdateSiteConfigSlot request. +func (client SitesClient) CreateOrUpdateSiteConfigSlotPreparer(resourceGroupName string, name string, siteConfig SiteConfig, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/web"), + autorest.WithJSON(siteConfig), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSiteConfigSlotSender sends the CreateOrUpdateSiteConfigSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) CreateOrUpdateSiteConfigSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateSiteConfigSlotResponder handles the response to the CreateOrUpdateSiteConfigSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) CreateOrUpdateSiteConfigSlotResponder(resp *http.Response) (result SiteConfig, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateSiteHostNameBinding sends the create or update site host name +// binding request. +// +// resourceGroupName is name of resource group name is name of web app +// hostName is name of host hostNameBinding is host name binding information +func (client SitesClient) CreateOrUpdateSiteHostNameBinding(resourceGroupName string, name string, hostName string, hostNameBinding HostNameBinding) (result HostNameBinding, ae error) { + req, err := client.CreateOrUpdateSiteHostNameBindingPreparer(resourceGroupName, name, hostName, hostNameBinding) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteHostNameBinding", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSiteHostNameBindingSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteHostNameBinding", "Failure sending request") + } + + result, err = client.CreateOrUpdateSiteHostNameBindingResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteHostNameBinding", "Failure responding to request") + } + + return +} + +// CreateOrUpdateSiteHostNameBindingPreparer prepares the CreateOrUpdateSiteHostNameBinding request. +func (client SitesClient) CreateOrUpdateSiteHostNameBindingPreparer(resourceGroupName string, name string, hostName string, hostNameBinding HostNameBinding) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "hostName": url.QueryEscape(hostName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/hostNameBindings/{hostName}"), + autorest.WithJSON(hostNameBinding), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSiteHostNameBindingSender sends the CreateOrUpdateSiteHostNameBinding request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) CreateOrUpdateSiteHostNameBindingSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateSiteHostNameBindingResponder handles the response to the CreateOrUpdateSiteHostNameBinding request. The method always +// closes the http.Response Body. +func (client SitesClient) CreateOrUpdateSiteHostNameBindingResponder(resp *http.Response) (result HostNameBinding, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateSiteHostNameBindingSlot sends the create or update site host +// name binding slot request. +// +// resourceGroupName is name of resource group name is name of web app +// hostName is name of host hostNameBinding is host name binding information +// slot is name of web app slot. If not specified then will default to +// production slot. +func (client SitesClient) CreateOrUpdateSiteHostNameBindingSlot(resourceGroupName string, name string, hostName string, hostNameBinding HostNameBinding, slot string) (result HostNameBinding, ae error) { + req, err := client.CreateOrUpdateSiteHostNameBindingSlotPreparer(resourceGroupName, name, hostName, hostNameBinding, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteHostNameBindingSlot", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSiteHostNameBindingSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteHostNameBindingSlot", "Failure sending request") + } + + result, err = client.CreateOrUpdateSiteHostNameBindingSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteHostNameBindingSlot", "Failure responding to request") + } + + return +} + +// CreateOrUpdateSiteHostNameBindingSlotPreparer prepares the CreateOrUpdateSiteHostNameBindingSlot request. +func (client SitesClient) CreateOrUpdateSiteHostNameBindingSlotPreparer(resourceGroupName string, name string, hostName string, hostNameBinding HostNameBinding, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "hostName": url.QueryEscape(hostName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/hostNameBindings/{hostName}"), + autorest.WithJSON(hostNameBinding), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSiteHostNameBindingSlotSender sends the CreateOrUpdateSiteHostNameBindingSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) CreateOrUpdateSiteHostNameBindingSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateSiteHostNameBindingSlotResponder handles the response to the CreateOrUpdateSiteHostNameBindingSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) CreateOrUpdateSiteHostNameBindingSlotResponder(resp *http.Response) (result HostNameBinding, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateSiteRelayServiceConnection sends the create or update site +// relay service connection request. +// +// resourceGroupName is the resource group name name is the name of the web +// app entityName is the name by which the Hybrid Connection is identified +// connectionEnvelope is the details of the Hybrid Connection +func (client SitesClient) CreateOrUpdateSiteRelayServiceConnection(resourceGroupName string, name string, entityName string, connectionEnvelope RelayServiceConnectionEntity) (result RelayServiceConnectionEntity, ae error) { + req, err := client.CreateOrUpdateSiteRelayServiceConnectionPreparer(resourceGroupName, name, entityName, connectionEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteRelayServiceConnection", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSiteRelayServiceConnectionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteRelayServiceConnection", "Failure sending request") + } + + result, err = client.CreateOrUpdateSiteRelayServiceConnectionResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteRelayServiceConnection", "Failure responding to request") + } + + return +} + +// CreateOrUpdateSiteRelayServiceConnectionPreparer prepares the CreateOrUpdateSiteRelayServiceConnection request. +func (client SitesClient) CreateOrUpdateSiteRelayServiceConnectionPreparer(resourceGroupName string, name string, entityName string, connectionEnvelope RelayServiceConnectionEntity) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "entityName": url.QueryEscape(entityName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/hybridconnection/{entityName}"), + autorest.WithJSON(connectionEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSiteRelayServiceConnectionSender sends the CreateOrUpdateSiteRelayServiceConnection request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) CreateOrUpdateSiteRelayServiceConnectionSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateSiteRelayServiceConnectionResponder handles the response to the CreateOrUpdateSiteRelayServiceConnection request. The method always +// closes the http.Response Body. +func (client SitesClient) CreateOrUpdateSiteRelayServiceConnectionResponder(resp *http.Response) (result RelayServiceConnectionEntity, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateSiteRelayServiceConnectionSlot sends the create or update +// site relay service connection slot request. +// +// resourceGroupName is the resource group name name is the name of the web +// app entityName is the name by which the Hybrid Connection is identified +// connectionEnvelope is the details of the Hybrid Connection slot is the +// name of the slot for the web app. +func (client SitesClient) CreateOrUpdateSiteRelayServiceConnectionSlot(resourceGroupName string, name string, entityName string, connectionEnvelope RelayServiceConnectionEntity, slot string) (result RelayServiceConnectionEntity, ae error) { + req, err := client.CreateOrUpdateSiteRelayServiceConnectionSlotPreparer(resourceGroupName, name, entityName, connectionEnvelope, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteRelayServiceConnectionSlot", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSiteRelayServiceConnectionSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteRelayServiceConnectionSlot", "Failure sending request") + } + + result, err = client.CreateOrUpdateSiteRelayServiceConnectionSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteRelayServiceConnectionSlot", "Failure responding to request") + } + + return +} + +// CreateOrUpdateSiteRelayServiceConnectionSlotPreparer prepares the CreateOrUpdateSiteRelayServiceConnectionSlot request. +func (client SitesClient) CreateOrUpdateSiteRelayServiceConnectionSlotPreparer(resourceGroupName string, name string, entityName string, connectionEnvelope RelayServiceConnectionEntity, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "entityName": url.QueryEscape(entityName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/hybridconnection/{entityName}"), + autorest.WithJSON(connectionEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSiteRelayServiceConnectionSlotSender sends the CreateOrUpdateSiteRelayServiceConnectionSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) CreateOrUpdateSiteRelayServiceConnectionSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateSiteRelayServiceConnectionSlotResponder handles the response to the CreateOrUpdateSiteRelayServiceConnectionSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) CreateOrUpdateSiteRelayServiceConnectionSlotResponder(resp *http.Response) (result RelayServiceConnectionEntity, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateSiteSlot sends the create or update site slot request. +// +// resourceGroupName is name of the resource group name is name of the web app +// siteEnvelope is details of web app if it exists already slot is name of +// web app slot. If not specified then will default to production slot. +// skipDNSRegistration is if true web app hostname is not registered with DNS +// on creation. This parameter is +// only used for app creation skipCustomDomainVerification is if +// true, custom (non *.azurewebsites.net) domains associated with web app are +// not verified. forceDNSRegistration is if true, web app hostname is force +// registered with DNS ttlInSeconds is time to live in seconds for web app's +// default domain name +func (client SitesClient) CreateOrUpdateSiteSlot(resourceGroupName string, name string, siteEnvelope Site, slot string, skipDNSRegistration string, skipCustomDomainVerification string, forceDNSRegistration string, ttlInSeconds string) (result Site, ae error) { + req, err := client.CreateOrUpdateSiteSlotPreparer(resourceGroupName, name, siteEnvelope, slot, skipDNSRegistration, skipCustomDomainVerification, forceDNSRegistration, ttlInSeconds) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteSlot", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSiteSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteSlot", "Failure sending request") + } + + result, err = client.CreateOrUpdateSiteSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteSlot", "Failure responding to request") + } + + return +} + +// CreateOrUpdateSiteSlotPreparer prepares the CreateOrUpdateSiteSlot request. +func (client SitesClient) CreateOrUpdateSiteSlotPreparer(resourceGroupName string, name string, siteEnvelope Site, slot string, skipDNSRegistration string, skipCustomDomainVerification string, forceDNSRegistration string, ttlInSeconds string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(skipDNSRegistration) > 0 { + queryParameters["skipDnsRegistration"] = skipDNSRegistration + } + if len(skipCustomDomainVerification) > 0 { + queryParameters["skipCustomDomainVerification"] = skipCustomDomainVerification + } + if len(forceDNSRegistration) > 0 { + queryParameters["forceDnsRegistration"] = forceDNSRegistration + } + if len(ttlInSeconds) > 0 { + queryParameters["ttlInSeconds"] = ttlInSeconds + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}"), + autorest.WithJSON(siteEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSiteSlotSender sends the CreateOrUpdateSiteSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) CreateOrUpdateSiteSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// CreateOrUpdateSiteSlotResponder handles the response to the CreateOrUpdateSiteSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) CreateOrUpdateSiteSlotResponder(resp *http.Response) (result Site, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateSiteSourceControl sends the create or update site source +// control request. +// +// resourceGroupName is name of resource group name is name of web app +// siteSourceControl is request body that contains the source control +// parameters +func (client SitesClient) CreateOrUpdateSiteSourceControl(resourceGroupName string, name string, siteSourceControl SiteSourceControl) (result SiteSourceControl, ae error) { + req, err := client.CreateOrUpdateSiteSourceControlPreparer(resourceGroupName, name, siteSourceControl) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteSourceControl", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSiteSourceControlSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteSourceControl", "Failure sending request") + } + + result, err = client.CreateOrUpdateSiteSourceControlResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteSourceControl", "Failure responding to request") + } + + return +} + +// CreateOrUpdateSiteSourceControlPreparer prepares the CreateOrUpdateSiteSourceControl request. +func (client SitesClient) CreateOrUpdateSiteSourceControlPreparer(resourceGroupName string, name string, siteSourceControl SiteSourceControl) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/sourcecontrols/web"), + autorest.WithJSON(siteSourceControl), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSiteSourceControlSender sends the CreateOrUpdateSiteSourceControl request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) CreateOrUpdateSiteSourceControlSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateSiteSourceControlResponder handles the response to the CreateOrUpdateSiteSourceControl request. The method always +// closes the http.Response Body. +func (client SitesClient) CreateOrUpdateSiteSourceControlResponder(resp *http.Response) (result SiteSourceControl, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateSiteSourceControlSlot sends the create or update site source +// control slot request. +// +// resourceGroupName is name of resource group name is name of web app +// siteSourceControl is request body that contains the source control +// parameters slot is name of web app slot. If not specified then will +// default to production slot. +func (client SitesClient) CreateOrUpdateSiteSourceControlSlot(resourceGroupName string, name string, siteSourceControl SiteSourceControl, slot string) (result SiteSourceControl, ae error) { + req, err := client.CreateOrUpdateSiteSourceControlSlotPreparer(resourceGroupName, name, siteSourceControl, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteSourceControlSlot", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSiteSourceControlSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteSourceControlSlot", "Failure sending request") + } + + result, err = client.CreateOrUpdateSiteSourceControlSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteSourceControlSlot", "Failure responding to request") + } + + return +} + +// CreateOrUpdateSiteSourceControlSlotPreparer prepares the CreateOrUpdateSiteSourceControlSlot request. +func (client SitesClient) CreateOrUpdateSiteSourceControlSlotPreparer(resourceGroupName string, name string, siteSourceControl SiteSourceControl, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/sourcecontrols/web"), + autorest.WithJSON(siteSourceControl), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSiteSourceControlSlotSender sends the CreateOrUpdateSiteSourceControlSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) CreateOrUpdateSiteSourceControlSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateSiteSourceControlSlotResponder handles the response to the CreateOrUpdateSiteSourceControlSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) CreateOrUpdateSiteSourceControlSlotResponder(resp *http.Response) (result SiteSourceControl, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateSiteVNETConnection sends the create or update site vnet +// connection request. +// +// resourceGroupName is the resource group name name is the name of the web +// app vnetName is the name of the Virtual Network connectionEnvelope is the +// properties of this Virtual Network Connection +func (client SitesClient) CreateOrUpdateSiteVNETConnection(resourceGroupName string, name string, vnetName string, connectionEnvelope VnetInfo) (result VnetInfo, ae error) { + req, err := client.CreateOrUpdateSiteVNETConnectionPreparer(resourceGroupName, name, vnetName, connectionEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteVNETConnection", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSiteVNETConnectionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteVNETConnection", "Failure sending request") + } + + result, err = client.CreateOrUpdateSiteVNETConnectionResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteVNETConnection", "Failure responding to request") + } + + return +} + +// CreateOrUpdateSiteVNETConnectionPreparer prepares the CreateOrUpdateSiteVNETConnection request. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionPreparer(resourceGroupName string, name string, vnetName string, connectionEnvelope VnetInfo) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/virtualNetworkConnections/{vnetName}"), + autorest.WithJSON(connectionEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSiteVNETConnectionSender sends the CreateOrUpdateSiteVNETConnection request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateSiteVNETConnectionResponder handles the response to the CreateOrUpdateSiteVNETConnection request. The method always +// closes the http.Response Body. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionResponder(resp *http.Response) (result VnetInfo, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateSiteVNETConnectionGateway sends the create or update site +// vnet connection gateway request. +// +// resourceGroupName is the resource group name name is the name of the web +// app vnetName is the name of the Virtual Network gatewayName is the name of +// the gateway. The only gateway that exists presently is "primary" +// connectionEnvelope is the properties to update this gateway with. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionGateway(resourceGroupName string, name string, vnetName string, gatewayName string, connectionEnvelope VnetGateway) (result VnetGateway, ae error) { + req, err := client.CreateOrUpdateSiteVNETConnectionGatewayPreparer(resourceGroupName, name, vnetName, gatewayName, connectionEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteVNETConnectionGateway", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSiteVNETConnectionGatewaySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteVNETConnectionGateway", "Failure sending request") + } + + result, err = client.CreateOrUpdateSiteVNETConnectionGatewayResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteVNETConnectionGateway", "Failure responding to request") + } + + return +} + +// CreateOrUpdateSiteVNETConnectionGatewayPreparer prepares the CreateOrUpdateSiteVNETConnectionGateway request. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionGatewayPreparer(resourceGroupName string, name string, vnetName string, gatewayName string, connectionEnvelope VnetGateway) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "gatewayName": url.QueryEscape(gatewayName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/virtualNetworkConnections/{vnetName}/gateways/{gatewayName}"), + autorest.WithJSON(connectionEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSiteVNETConnectionGatewaySender sends the CreateOrUpdateSiteVNETConnectionGateway request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionGatewaySender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateSiteVNETConnectionGatewayResponder handles the response to the CreateOrUpdateSiteVNETConnectionGateway request. The method always +// closes the http.Response Body. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionGatewayResponder(resp *http.Response) (result VnetGateway, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateSiteVNETConnectionGatewaySlot sends the create or update site +// vnet connection gateway slot request. +// +// resourceGroupName is the resource group name name is the name of the web +// app vnetName is the name of the Virtual Network gatewayName is the name of +// the gateway. The only gateway that exists presently is "primary" +// connectionEnvelope is the properties to update this gateway with. slot is +// the name of the slot for this web app. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionGatewaySlot(resourceGroupName string, name string, vnetName string, gatewayName string, connectionEnvelope VnetGateway, slot string) (result VnetGateway, ae error) { + req, err := client.CreateOrUpdateSiteVNETConnectionGatewaySlotPreparer(resourceGroupName, name, vnetName, gatewayName, connectionEnvelope, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteVNETConnectionGatewaySlot", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSiteVNETConnectionGatewaySlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteVNETConnectionGatewaySlot", "Failure sending request") + } + + result, err = client.CreateOrUpdateSiteVNETConnectionGatewaySlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteVNETConnectionGatewaySlot", "Failure responding to request") + } + + return +} + +// CreateOrUpdateSiteVNETConnectionGatewaySlotPreparer prepares the CreateOrUpdateSiteVNETConnectionGatewaySlot request. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionGatewaySlotPreparer(resourceGroupName string, name string, vnetName string, gatewayName string, connectionEnvelope VnetGateway, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "gatewayName": url.QueryEscape(gatewayName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/virtualNetworkConnections/{vnetName}/gateways/{gatewayName}"), + autorest.WithJSON(connectionEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSiteVNETConnectionGatewaySlotSender sends the CreateOrUpdateSiteVNETConnectionGatewaySlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionGatewaySlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateSiteVNETConnectionGatewaySlotResponder handles the response to the CreateOrUpdateSiteVNETConnectionGatewaySlot request. The method always +// closes the http.Response Body. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionGatewaySlotResponder(resp *http.Response) (result VnetGateway, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// CreateOrUpdateSiteVNETConnectionSlot sends the create or update site vnet +// connection slot request. +// +// resourceGroupName is the resource group name name is the name of the web +// app vnetName is the name of the Virtual Network connectionEnvelope is the +// properties of this Virtual Network Connection slot is the name of the slot +// for this web app. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionSlot(resourceGroupName string, name string, vnetName string, connectionEnvelope VnetInfo, slot string) (result VnetInfo, ae error) { + req, err := client.CreateOrUpdateSiteVNETConnectionSlotPreparer(resourceGroupName, name, vnetName, connectionEnvelope, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteVNETConnectionSlot", "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSiteVNETConnectionSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteVNETConnectionSlot", "Failure sending request") + } + + result, err = client.CreateOrUpdateSiteVNETConnectionSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "CreateOrUpdateSiteVNETConnectionSlot", "Failure responding to request") + } + + return +} + +// CreateOrUpdateSiteVNETConnectionSlotPreparer prepares the CreateOrUpdateSiteVNETConnectionSlot request. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionSlotPreparer(resourceGroupName string, name string, vnetName string, connectionEnvelope VnetInfo, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/virtualNetworkConnections/{vnetName}"), + autorest.WithJSON(connectionEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// CreateOrUpdateSiteVNETConnectionSlotSender sends the CreateOrUpdateSiteVNETConnectionSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// CreateOrUpdateSiteVNETConnectionSlotResponder handles the response to the CreateOrUpdateSiteVNETConnectionSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) CreateOrUpdateSiteVNETConnectionSlotResponder(resp *http.Response) (result VnetInfo, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteBackup sends the delete backup request. +// +// resourceGroupName is name of resource group name is name of web app +// backupID is id of backup +func (client SitesClient) DeleteBackup(resourceGroupName string, name string, backupID string) (result BackupItem, ae error) { + req, err := client.DeleteBackupPreparer(resourceGroupName, name, backupID) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteBackup", "Failure preparing request") + } + + resp, err := client.DeleteBackupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteBackup", "Failure sending request") + } + + result, err = client.DeleteBackupResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DeleteBackup", "Failure responding to request") + } + + return +} + +// DeleteBackupPreparer prepares the DeleteBackup request. +func (client SitesClient) DeleteBackupPreparer(resourceGroupName string, name string, backupID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "backupId": url.QueryEscape(backupID), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/backups/{backupId}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteBackupSender sends the DeleteBackup request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DeleteBackupSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteBackupResponder handles the response to the DeleteBackup request. The method always +// closes the http.Response Body. +func (client SitesClient) DeleteBackupResponder(resp *http.Response) (result BackupItem, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteBackupSlot sends the delete backup slot request. +// +// resourceGroupName is name of resource group name is name of web app +// backupID is id of backup slot is name of web app slot. If not specified +// then will default to production slot. +func (client SitesClient) DeleteBackupSlot(resourceGroupName string, name string, backupID string, slot string) (result BackupItem, ae error) { + req, err := client.DeleteBackupSlotPreparer(resourceGroupName, name, backupID, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteBackupSlot", "Failure preparing request") + } + + resp, err := client.DeleteBackupSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteBackupSlot", "Failure sending request") + } + + result, err = client.DeleteBackupSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DeleteBackupSlot", "Failure responding to request") + } + + return +} + +// DeleteBackupSlotPreparer prepares the DeleteBackupSlot request. +func (client SitesClient) DeleteBackupSlotPreparer(resourceGroupName string, name string, backupID string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "backupId": url.QueryEscape(backupID), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/backups/{backupId}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteBackupSlotSender sends the DeleteBackupSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DeleteBackupSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteBackupSlotResponder handles the response to the DeleteBackupSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) DeleteBackupSlotResponder(resp *http.Response) (result BackupItem, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteSite sends the delete site request. +// +// resourceGroupName is name of resource group name is name of web app +// deleteMetrics is if true, web app metrics are also deleted +// deleteEmptyServerFarm is if true and App Service Plan is empty after web +// app deletion, App Service Plan is also deleted skipDNSRegistration is if +// true, DNS registration is skipped deleteAllSlots is if true, all slots +// associated with web app are also deleted +func (client SitesClient) DeleteSite(resourceGroupName string, name string, deleteMetrics string, deleteEmptyServerFarm string, skipDNSRegistration string, deleteAllSlots string) (result ObjectSet, ae error) { + req, err := client.DeleteSitePreparer(resourceGroupName, name, deleteMetrics, deleteEmptyServerFarm, skipDNSRegistration, deleteAllSlots) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSite", "Failure preparing request") + } + + resp, err := client.DeleteSiteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSite", "Failure sending request") + } + + result, err = client.DeleteSiteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSite", "Failure responding to request") + } + + return +} + +// DeleteSitePreparer prepares the DeleteSite request. +func (client SitesClient) DeleteSitePreparer(resourceGroupName string, name string, deleteMetrics string, deleteEmptyServerFarm string, skipDNSRegistration string, deleteAllSlots string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(deleteMetrics) > 0 { + queryParameters["deleteMetrics"] = deleteMetrics + } + if len(deleteEmptyServerFarm) > 0 { + queryParameters["deleteEmptyServerFarm"] = deleteEmptyServerFarm + } + if len(skipDNSRegistration) > 0 { + queryParameters["skipDnsRegistration"] = skipDNSRegistration + } + if len(deleteAllSlots) > 0 { + queryParameters["deleteAllSlots"] = deleteAllSlots + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSiteSender sends the DeleteSite request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DeleteSiteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteSiteResponder handles the response to the DeleteSite request. The method always +// closes the http.Response Body. +func (client SitesClient) DeleteSiteResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteSiteHostNameBinding sends the delete site host name binding request. +// +// resourceGroupName is name of resource group name is name of web app +// hostName is name of host +func (client SitesClient) DeleteSiteHostNameBinding(resourceGroupName string, name string, hostName string) (result ObjectSet, ae error) { + req, err := client.DeleteSiteHostNameBindingPreparer(resourceGroupName, name, hostName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteHostNameBinding", "Failure preparing request") + } + + resp, err := client.DeleteSiteHostNameBindingSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteHostNameBinding", "Failure sending request") + } + + result, err = client.DeleteSiteHostNameBindingResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteHostNameBinding", "Failure responding to request") + } + + return +} + +// DeleteSiteHostNameBindingPreparer prepares the DeleteSiteHostNameBinding request. +func (client SitesClient) DeleteSiteHostNameBindingPreparer(resourceGroupName string, name string, hostName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "hostName": url.QueryEscape(hostName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/hostNameBindings/{hostName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSiteHostNameBindingSender sends the DeleteSiteHostNameBinding request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DeleteSiteHostNameBindingSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteSiteHostNameBindingResponder handles the response to the DeleteSiteHostNameBinding request. The method always +// closes the http.Response Body. +func (client SitesClient) DeleteSiteHostNameBindingResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteSiteHostNameBindingSlot sends the delete site host name binding slot +// request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. hostName is name of host +func (client SitesClient) DeleteSiteHostNameBindingSlot(resourceGroupName string, name string, slot string, hostName string) (result ObjectSet, ae error) { + req, err := client.DeleteSiteHostNameBindingSlotPreparer(resourceGroupName, name, slot, hostName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteHostNameBindingSlot", "Failure preparing request") + } + + resp, err := client.DeleteSiteHostNameBindingSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteHostNameBindingSlot", "Failure sending request") + } + + result, err = client.DeleteSiteHostNameBindingSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteHostNameBindingSlot", "Failure responding to request") + } + + return +} + +// DeleteSiteHostNameBindingSlotPreparer prepares the DeleteSiteHostNameBindingSlot request. +func (client SitesClient) DeleteSiteHostNameBindingSlotPreparer(resourceGroupName string, name string, slot string, hostName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "hostName": url.QueryEscape(hostName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/hostNameBindings/{hostName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSiteHostNameBindingSlotSender sends the DeleteSiteHostNameBindingSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DeleteSiteHostNameBindingSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteSiteHostNameBindingSlotResponder handles the response to the DeleteSiteHostNameBindingSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) DeleteSiteHostNameBindingSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteSitePremierAddOn sends the delete site premier add on request. +// +func (client SitesClient) DeleteSitePremierAddOn(resourceGroupName string, name string, premierAddOnName string) (result ObjectSet, ae error) { + req, err := client.DeleteSitePremierAddOnPreparer(resourceGroupName, name, premierAddOnName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSitePremierAddOn", "Failure preparing request") + } + + resp, err := client.DeleteSitePremierAddOnSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSitePremierAddOn", "Failure sending request") + } + + result, err = client.DeleteSitePremierAddOnResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSitePremierAddOn", "Failure responding to request") + } + + return +} + +// DeleteSitePremierAddOnPreparer prepares the DeleteSitePremierAddOn request. +func (client SitesClient) DeleteSitePremierAddOnPreparer(resourceGroupName string, name string, premierAddOnName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "premierAddOnName": url.QueryEscape(premierAddOnName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/premieraddons/{premierAddOnName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSitePremierAddOnSender sends the DeleteSitePremierAddOn request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DeleteSitePremierAddOnSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteSitePremierAddOnResponder handles the response to the DeleteSitePremierAddOn request. The method always +// closes the http.Response Body. +func (client SitesClient) DeleteSitePremierAddOnResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteSitePremierAddOnSlot sends the delete site premier add on slot +// request. +// +func (client SitesClient) DeleteSitePremierAddOnSlot(resourceGroupName string, name string, premierAddOnName string, slot string) (result ObjectSet, ae error) { + req, err := client.DeleteSitePremierAddOnSlotPreparer(resourceGroupName, name, premierAddOnName, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSitePremierAddOnSlot", "Failure preparing request") + } + + resp, err := client.DeleteSitePremierAddOnSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSitePremierAddOnSlot", "Failure sending request") + } + + result, err = client.DeleteSitePremierAddOnSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSitePremierAddOnSlot", "Failure responding to request") + } + + return +} + +// DeleteSitePremierAddOnSlotPreparer prepares the DeleteSitePremierAddOnSlot request. +func (client SitesClient) DeleteSitePremierAddOnSlotPreparer(resourceGroupName string, name string, premierAddOnName string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "premierAddOnName": url.QueryEscape(premierAddOnName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/premieraddons/{premierAddOnName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSitePremierAddOnSlotSender sends the DeleteSitePremierAddOnSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DeleteSitePremierAddOnSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteSitePremierAddOnSlotResponder handles the response to the DeleteSitePremierAddOnSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) DeleteSitePremierAddOnSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteSiteRelayServiceConnection sends the delete site relay service +// connection request. +// +// resourceGroupName is the resource group name name is the name of the web +// app entityName is the name by which the Hybrid Connection is identified +func (client SitesClient) DeleteSiteRelayServiceConnection(resourceGroupName string, name string, entityName string) (result ObjectSet, ae error) { + req, err := client.DeleteSiteRelayServiceConnectionPreparer(resourceGroupName, name, entityName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteRelayServiceConnection", "Failure preparing request") + } + + resp, err := client.DeleteSiteRelayServiceConnectionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteRelayServiceConnection", "Failure sending request") + } + + result, err = client.DeleteSiteRelayServiceConnectionResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteRelayServiceConnection", "Failure responding to request") + } + + return +} + +// DeleteSiteRelayServiceConnectionPreparer prepares the DeleteSiteRelayServiceConnection request. +func (client SitesClient) DeleteSiteRelayServiceConnectionPreparer(resourceGroupName string, name string, entityName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "entityName": url.QueryEscape(entityName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/hybridconnection/{entityName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSiteRelayServiceConnectionSender sends the DeleteSiteRelayServiceConnection request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DeleteSiteRelayServiceConnectionSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteSiteRelayServiceConnectionResponder handles the response to the DeleteSiteRelayServiceConnection request. The method always +// closes the http.Response Body. +func (client SitesClient) DeleteSiteRelayServiceConnectionResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteSiteRelayServiceConnectionSlot sends the delete site relay service +// connection slot request. +// +// resourceGroupName is the resource group name name is the name of the web +// app entityName is the name by which the Hybrid Connection is identified +// slot is the name of the slot for the web app. +func (client SitesClient) DeleteSiteRelayServiceConnectionSlot(resourceGroupName string, name string, entityName string, slot string) (result ObjectSet, ae error) { + req, err := client.DeleteSiteRelayServiceConnectionSlotPreparer(resourceGroupName, name, entityName, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteRelayServiceConnectionSlot", "Failure preparing request") + } + + resp, err := client.DeleteSiteRelayServiceConnectionSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteRelayServiceConnectionSlot", "Failure sending request") + } + + result, err = client.DeleteSiteRelayServiceConnectionSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteRelayServiceConnectionSlot", "Failure responding to request") + } + + return +} + +// DeleteSiteRelayServiceConnectionSlotPreparer prepares the DeleteSiteRelayServiceConnectionSlot request. +func (client SitesClient) DeleteSiteRelayServiceConnectionSlotPreparer(resourceGroupName string, name string, entityName string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "entityName": url.QueryEscape(entityName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/hybridconnection/{entityName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSiteRelayServiceConnectionSlotSender sends the DeleteSiteRelayServiceConnectionSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DeleteSiteRelayServiceConnectionSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteSiteRelayServiceConnectionSlotResponder handles the response to the DeleteSiteRelayServiceConnectionSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) DeleteSiteRelayServiceConnectionSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteSiteSlot sends the delete site slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. deleteMetrics is if true, web app metrics are also deleted +// deleteEmptyServerFarm is if true and App Service Plan is empty after web +// app deletion, App Service Plan is also deleted skipDNSRegistration is if +// true, DNS registration is skipped deleteAllSlots is if true, all slots +// associated with web app are also deleted +func (client SitesClient) DeleteSiteSlot(resourceGroupName string, name string, slot string, deleteMetrics string, deleteEmptyServerFarm string, skipDNSRegistration string, deleteAllSlots string) (result ObjectSet, ae error) { + req, err := client.DeleteSiteSlotPreparer(resourceGroupName, name, slot, deleteMetrics, deleteEmptyServerFarm, skipDNSRegistration, deleteAllSlots) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteSlot", "Failure preparing request") + } + + resp, err := client.DeleteSiteSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteSlot", "Failure sending request") + } + + result, err = client.DeleteSiteSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteSlot", "Failure responding to request") + } + + return +} + +// DeleteSiteSlotPreparer prepares the DeleteSiteSlot request. +func (client SitesClient) DeleteSiteSlotPreparer(resourceGroupName string, name string, slot string, deleteMetrics string, deleteEmptyServerFarm string, skipDNSRegistration string, deleteAllSlots string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(deleteMetrics) > 0 { + queryParameters["deleteMetrics"] = deleteMetrics + } + if len(deleteEmptyServerFarm) > 0 { + queryParameters["deleteEmptyServerFarm"] = deleteEmptyServerFarm + } + if len(skipDNSRegistration) > 0 { + queryParameters["skipDnsRegistration"] = skipDNSRegistration + } + if len(deleteAllSlots) > 0 { + queryParameters["deleteAllSlots"] = deleteAllSlots + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSiteSlotSender sends the DeleteSiteSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DeleteSiteSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteSiteSlotResponder handles the response to the DeleteSiteSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) DeleteSiteSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteSiteSourceControl sends the delete site source control request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) DeleteSiteSourceControl(resourceGroupName string, name string) (result ObjectSet, ae error) { + req, err := client.DeleteSiteSourceControlPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteSourceControl", "Failure preparing request") + } + + resp, err := client.DeleteSiteSourceControlSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteSourceControl", "Failure sending request") + } + + result, err = client.DeleteSiteSourceControlResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteSourceControl", "Failure responding to request") + } + + return +} + +// DeleteSiteSourceControlPreparer prepares the DeleteSiteSourceControl request. +func (client SitesClient) DeleteSiteSourceControlPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/sourcecontrols/web"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSiteSourceControlSender sends the DeleteSiteSourceControl request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DeleteSiteSourceControlSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteSiteSourceControlResponder handles the response to the DeleteSiteSourceControl request. The method always +// closes the http.Response Body. +func (client SitesClient) DeleteSiteSourceControlResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteSiteSourceControlSlot sends the delete site source control slot +// request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) DeleteSiteSourceControlSlot(resourceGroupName string, name string, slot string) (result ObjectSet, ae error) { + req, err := client.DeleteSiteSourceControlSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteSourceControlSlot", "Failure preparing request") + } + + resp, err := client.DeleteSiteSourceControlSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteSourceControlSlot", "Failure sending request") + } + + result, err = client.DeleteSiteSourceControlSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteSourceControlSlot", "Failure responding to request") + } + + return +} + +// DeleteSiteSourceControlSlotPreparer prepares the DeleteSiteSourceControlSlot request. +func (client SitesClient) DeleteSiteSourceControlSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/sourcecontrols/web"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSiteSourceControlSlotSender sends the DeleteSiteSourceControlSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DeleteSiteSourceControlSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteSiteSourceControlSlotResponder handles the response to the DeleteSiteSourceControlSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) DeleteSiteSourceControlSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteSiteVNETConnection sends the delete site vnet connection request. +// +// resourceGroupName is the resource group name name is the name of the web +// app vnetName is the name of the Virtual Network +func (client SitesClient) DeleteSiteVNETConnection(resourceGroupName string, name string, vnetName string) (result ObjectSet, ae error) { + req, err := client.DeleteSiteVNETConnectionPreparer(resourceGroupName, name, vnetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteVNETConnection", "Failure preparing request") + } + + resp, err := client.DeleteSiteVNETConnectionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteVNETConnection", "Failure sending request") + } + + result, err = client.DeleteSiteVNETConnectionResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteVNETConnection", "Failure responding to request") + } + + return +} + +// DeleteSiteVNETConnectionPreparer prepares the DeleteSiteVNETConnection request. +func (client SitesClient) DeleteSiteVNETConnectionPreparer(resourceGroupName string, name string, vnetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/virtualNetworkConnections/{vnetName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSiteVNETConnectionSender sends the DeleteSiteVNETConnection request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DeleteSiteVNETConnectionSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteSiteVNETConnectionResponder handles the response to the DeleteSiteVNETConnection request. The method always +// closes the http.Response Body. +func (client SitesClient) DeleteSiteVNETConnectionResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DeleteSiteVNETConnectionSlot sends the delete site vnet connection slot +// request. +// +// resourceGroupName is the resource group name name is the name of the web +// app vnetName is the name of the Virtual Network slot is the name of the +// slot for this web app. +func (client SitesClient) DeleteSiteVNETConnectionSlot(resourceGroupName string, name string, vnetName string, slot string) (result ObjectSet, ae error) { + req, err := client.DeleteSiteVNETConnectionSlotPreparer(resourceGroupName, name, vnetName, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteVNETConnectionSlot", "Failure preparing request") + } + + resp, err := client.DeleteSiteVNETConnectionSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteVNETConnectionSlot", "Failure sending request") + } + + result, err = client.DeleteSiteVNETConnectionSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DeleteSiteVNETConnectionSlot", "Failure responding to request") + } + + return +} + +// DeleteSiteVNETConnectionSlotPreparer prepares the DeleteSiteVNETConnectionSlot request. +func (client SitesClient) DeleteSiteVNETConnectionSlotPreparer(resourceGroupName string, name string, vnetName string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/virtualNetworkConnections/{vnetName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DeleteSiteVNETConnectionSlotSender sends the DeleteSiteVNETConnectionSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DeleteSiteVNETConnectionSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DeleteSiteVNETConnectionSlotResponder handles the response to the DeleteSiteVNETConnectionSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) DeleteSiteVNETConnectionSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DiscoverSiteRestore sends the discover site restore request. +// +// resourceGroupName is name of resource group name is name of web app request +// is information on restore request +func (client SitesClient) DiscoverSiteRestore(resourceGroupName string, name string, request RestoreRequest) (result RestoreRequest, ae error) { + req, err := client.DiscoverSiteRestorePreparer(resourceGroupName, name, request) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DiscoverSiteRestore", "Failure preparing request") + } + + resp, err := client.DiscoverSiteRestoreSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DiscoverSiteRestore", "Failure sending request") + } + + result, err = client.DiscoverSiteRestoreResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DiscoverSiteRestore", "Failure responding to request") + } + + return +} + +// DiscoverSiteRestorePreparer prepares the DiscoverSiteRestore request. +func (client SitesClient) DiscoverSiteRestorePreparer(resourceGroupName string, name string, request RestoreRequest) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/backups/discover"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DiscoverSiteRestoreSender sends the DiscoverSiteRestore request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DiscoverSiteRestoreSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DiscoverSiteRestoreResponder handles the response to the DiscoverSiteRestore request. The method always +// closes the http.Response Body. +func (client SitesClient) DiscoverSiteRestoreResponder(resp *http.Response) (result RestoreRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DiscoverSiteRestoreDeprecated sends the discover site restore deprecated +// request. +// +// resourceGroupName is name of resource group name is name of web app request +// is information on restore request +func (client SitesClient) DiscoverSiteRestoreDeprecated(resourceGroupName string, name string, request RestoreRequest) (result RestoreRequest, ae error) { + req, err := client.DiscoverSiteRestoreDeprecatedPreparer(resourceGroupName, name, request) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DiscoverSiteRestoreDeprecated", "Failure preparing request") + } + + resp, err := client.DiscoverSiteRestoreDeprecatedSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DiscoverSiteRestoreDeprecated", "Failure sending request") + } + + result, err = client.DiscoverSiteRestoreDeprecatedResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DiscoverSiteRestoreDeprecated", "Failure responding to request") + } + + return +} + +// DiscoverSiteRestoreDeprecatedPreparer prepares the DiscoverSiteRestoreDeprecated request. +func (client SitesClient) DiscoverSiteRestoreDeprecatedPreparer(resourceGroupName string, name string, request RestoreRequest) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/restore/discover"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DiscoverSiteRestoreDeprecatedSender sends the DiscoverSiteRestoreDeprecated request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DiscoverSiteRestoreDeprecatedSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DiscoverSiteRestoreDeprecatedResponder handles the response to the DiscoverSiteRestoreDeprecated request. The method always +// closes the http.Response Body. +func (client SitesClient) DiscoverSiteRestoreDeprecatedResponder(resp *http.Response) (result RestoreRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DiscoverSiteRestoreDeprecatedSlot sends the discover site restore +// deprecated slot request. +// +// resourceGroupName is name of resource group name is name of web app request +// is information on restore request slot is name of web app slot. If not +// specified then will default to production slot. +func (client SitesClient) DiscoverSiteRestoreDeprecatedSlot(resourceGroupName string, name string, request RestoreRequest, slot string) (result RestoreRequest, ae error) { + req, err := client.DiscoverSiteRestoreDeprecatedSlotPreparer(resourceGroupName, name, request, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DiscoverSiteRestoreDeprecatedSlot", "Failure preparing request") + } + + resp, err := client.DiscoverSiteRestoreDeprecatedSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DiscoverSiteRestoreDeprecatedSlot", "Failure sending request") + } + + result, err = client.DiscoverSiteRestoreDeprecatedSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DiscoverSiteRestoreDeprecatedSlot", "Failure responding to request") + } + + return +} + +// DiscoverSiteRestoreDeprecatedSlotPreparer prepares the DiscoverSiteRestoreDeprecatedSlot request. +func (client SitesClient) DiscoverSiteRestoreDeprecatedSlotPreparer(resourceGroupName string, name string, request RestoreRequest, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/restore/discover"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DiscoverSiteRestoreDeprecatedSlotSender sends the DiscoverSiteRestoreDeprecatedSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DiscoverSiteRestoreDeprecatedSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DiscoverSiteRestoreDeprecatedSlotResponder handles the response to the DiscoverSiteRestoreDeprecatedSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) DiscoverSiteRestoreDeprecatedSlotResponder(resp *http.Response) (result RestoreRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// DiscoverSiteRestoreSlot sends the discover site restore slot request. +// +// resourceGroupName is name of resource group name is name of web app request +// is information on restore request slot is name of web app slot. If not +// specified then will default to production slot. +func (client SitesClient) DiscoverSiteRestoreSlot(resourceGroupName string, name string, request RestoreRequest, slot string) (result RestoreRequest, ae error) { + req, err := client.DiscoverSiteRestoreSlotPreparer(resourceGroupName, name, request, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DiscoverSiteRestoreSlot", "Failure preparing request") + } + + resp, err := client.DiscoverSiteRestoreSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "DiscoverSiteRestoreSlot", "Failure sending request") + } + + result, err = client.DiscoverSiteRestoreSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "DiscoverSiteRestoreSlot", "Failure responding to request") + } + + return +} + +// DiscoverSiteRestoreSlotPreparer prepares the DiscoverSiteRestoreSlot request. +func (client SitesClient) DiscoverSiteRestoreSlotPreparer(resourceGroupName string, name string, request RestoreRequest, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/backups/discover"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// DiscoverSiteRestoreSlotSender sends the DiscoverSiteRestoreSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) DiscoverSiteRestoreSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// DiscoverSiteRestoreSlotResponder handles the response to the DiscoverSiteRestoreSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) DiscoverSiteRestoreSlotResponder(resp *http.Response) (result RestoreRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GenerateNewSitePublishingPassword sends the generate new site publishing +// password request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) GenerateNewSitePublishingPassword(resourceGroupName string, name string) (result ObjectSet, ae error) { + req, err := client.GenerateNewSitePublishingPasswordPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GenerateNewSitePublishingPassword", "Failure preparing request") + } + + resp, err := client.GenerateNewSitePublishingPasswordSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GenerateNewSitePublishingPassword", "Failure sending request") + } + + result, err = client.GenerateNewSitePublishingPasswordResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GenerateNewSitePublishingPassword", "Failure responding to request") + } + + return +} + +// GenerateNewSitePublishingPasswordPreparer prepares the GenerateNewSitePublishingPassword request. +func (client SitesClient) GenerateNewSitePublishingPasswordPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/newpassword"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GenerateNewSitePublishingPasswordSender sends the GenerateNewSitePublishingPassword request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GenerateNewSitePublishingPasswordSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GenerateNewSitePublishingPasswordResponder handles the response to the GenerateNewSitePublishingPassword request. The method always +// closes the http.Response Body. +func (client SitesClient) GenerateNewSitePublishingPasswordResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GenerateNewSitePublishingPasswordSlot sends the generate new site +// publishing password slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) GenerateNewSitePublishingPasswordSlot(resourceGroupName string, name string, slot string) (result ObjectSet, ae error) { + req, err := client.GenerateNewSitePublishingPasswordSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GenerateNewSitePublishingPasswordSlot", "Failure preparing request") + } + + resp, err := client.GenerateNewSitePublishingPasswordSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GenerateNewSitePublishingPasswordSlot", "Failure sending request") + } + + result, err = client.GenerateNewSitePublishingPasswordSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GenerateNewSitePublishingPasswordSlot", "Failure responding to request") + } + + return +} + +// GenerateNewSitePublishingPasswordSlotPreparer prepares the GenerateNewSitePublishingPasswordSlot request. +func (client SitesClient) GenerateNewSitePublishingPasswordSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/newpassword"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GenerateNewSitePublishingPasswordSlotSender sends the GenerateNewSitePublishingPasswordSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GenerateNewSitePublishingPasswordSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GenerateNewSitePublishingPasswordSlotResponder handles the response to the GenerateNewSitePublishingPasswordSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GenerateNewSitePublishingPasswordSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetDeletedSites sends the get deleted sites request. +// +// resourceGroupName is name of resource group propertiesToInclude is +// additional web app properties included in the response includeSiteTypes is +// types of apps included in the response +func (client SitesClient) GetDeletedSites(resourceGroupName string, propertiesToInclude string, includeSiteTypes string) (result DeletedSiteCollection, ae error) { + req, err := client.GetDeletedSitesPreparer(resourceGroupName, propertiesToInclude, includeSiteTypes) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetDeletedSites", "Failure preparing request") + } + + resp, err := client.GetDeletedSitesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetDeletedSites", "Failure sending request") + } + + result, err = client.GetDeletedSitesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetDeletedSites", "Failure responding to request") + } + + return +} + +// GetDeletedSitesPreparer prepares the GetDeletedSites request. +func (client SitesClient) GetDeletedSitesPreparer(resourceGroupName string, propertiesToInclude string, includeSiteTypes string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(propertiesToInclude) > 0 { + queryParameters["propertiesToInclude"] = propertiesToInclude + } + if len(includeSiteTypes) > 0 { + queryParameters["includeSiteTypes"] = includeSiteTypes + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/deletedSites"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetDeletedSitesSender sends the GetDeletedSites request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetDeletedSitesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetDeletedSitesResponder handles the response to the GetDeletedSites request. The method always +// closes the http.Response Body. +func (client SitesClient) GetDeletedSitesResponder(resp *http.Response) (result DeletedSiteCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSite sends the get site request. +// +// resourceGroupName is name of resource group name is name of web app +// propertiesToInclude is additional web app properties included in the +// response +func (client SitesClient) GetSite(resourceGroupName string, name string, propertiesToInclude string) (result Site, ae error) { + req, err := client.GetSitePreparer(resourceGroupName, name, propertiesToInclude) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSite", "Failure preparing request") + } + + resp, err := client.GetSiteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSite", "Failure sending request") + } + + result, err = client.GetSiteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSite", "Failure responding to request") + } + + return +} + +// GetSitePreparer prepares the GetSite request. +func (client SitesClient) GetSitePreparer(resourceGroupName string, name string, propertiesToInclude string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(propertiesToInclude) > 0 { + queryParameters["propertiesToInclude"] = propertiesToInclude + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteSender sends the GetSite request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteResponder handles the response to the GetSite request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteResponder(resp *http.Response) (result Site, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteBackupConfiguration sends the get site backup configuration request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) GetSiteBackupConfiguration(resourceGroupName string, name string) (result BackupRequest, ae error) { + req, err := client.GetSiteBackupConfigurationPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupConfiguration", "Failure preparing request") + } + + resp, err := client.GetSiteBackupConfigurationSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupConfiguration", "Failure sending request") + } + + result, err = client.GetSiteBackupConfigurationResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupConfiguration", "Failure responding to request") + } + + return +} + +// GetSiteBackupConfigurationPreparer prepares the GetSiteBackupConfiguration request. +func (client SitesClient) GetSiteBackupConfigurationPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/backup/list"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteBackupConfigurationSender sends the GetSiteBackupConfiguration request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteBackupConfigurationSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteBackupConfigurationResponder handles the response to the GetSiteBackupConfiguration request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteBackupConfigurationResponder(resp *http.Response) (result BackupRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteBackupConfigurationDeprecated sends the get site backup +// configuration deprecated request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) GetSiteBackupConfigurationDeprecated(resourceGroupName string, name string) (result BackupRequest, ae error) { + req, err := client.GetSiteBackupConfigurationDeprecatedPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupConfigurationDeprecated", "Failure preparing request") + } + + resp, err := client.GetSiteBackupConfigurationDeprecatedSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupConfigurationDeprecated", "Failure sending request") + } + + result, err = client.GetSiteBackupConfigurationDeprecatedResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupConfigurationDeprecated", "Failure responding to request") + } + + return +} + +// GetSiteBackupConfigurationDeprecatedPreparer prepares the GetSiteBackupConfigurationDeprecated request. +func (client SitesClient) GetSiteBackupConfigurationDeprecatedPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/backup/config"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteBackupConfigurationDeprecatedSender sends the GetSiteBackupConfigurationDeprecated request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteBackupConfigurationDeprecatedSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteBackupConfigurationDeprecatedResponder handles the response to the GetSiteBackupConfigurationDeprecated request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteBackupConfigurationDeprecatedResponder(resp *http.Response) (result BackupRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteBackupConfigurationDeprecatedSlot sends the get site backup +// configuration deprecated slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) GetSiteBackupConfigurationDeprecatedSlot(resourceGroupName string, name string, slot string) (result BackupRequest, ae error) { + req, err := client.GetSiteBackupConfigurationDeprecatedSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupConfigurationDeprecatedSlot", "Failure preparing request") + } + + resp, err := client.GetSiteBackupConfigurationDeprecatedSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupConfigurationDeprecatedSlot", "Failure sending request") + } + + result, err = client.GetSiteBackupConfigurationDeprecatedSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupConfigurationDeprecatedSlot", "Failure responding to request") + } + + return +} + +// GetSiteBackupConfigurationDeprecatedSlotPreparer prepares the GetSiteBackupConfigurationDeprecatedSlot request. +func (client SitesClient) GetSiteBackupConfigurationDeprecatedSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/backup/config"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteBackupConfigurationDeprecatedSlotSender sends the GetSiteBackupConfigurationDeprecatedSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteBackupConfigurationDeprecatedSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteBackupConfigurationDeprecatedSlotResponder handles the response to the GetSiteBackupConfigurationDeprecatedSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteBackupConfigurationDeprecatedSlotResponder(resp *http.Response) (result BackupRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteBackupConfigurationSlot sends the get site backup configuration slot +// request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) GetSiteBackupConfigurationSlot(resourceGroupName string, name string, slot string) (result BackupRequest, ae error) { + req, err := client.GetSiteBackupConfigurationSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupConfigurationSlot", "Failure preparing request") + } + + resp, err := client.GetSiteBackupConfigurationSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupConfigurationSlot", "Failure sending request") + } + + result, err = client.GetSiteBackupConfigurationSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupConfigurationSlot", "Failure responding to request") + } + + return +} + +// GetSiteBackupConfigurationSlotPreparer prepares the GetSiteBackupConfigurationSlot request. +func (client SitesClient) GetSiteBackupConfigurationSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/backup/list"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteBackupConfigurationSlotSender sends the GetSiteBackupConfigurationSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteBackupConfigurationSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteBackupConfigurationSlotResponder handles the response to the GetSiteBackupConfigurationSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteBackupConfigurationSlotResponder(resp *http.Response) (result BackupRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteBackupStatus sends the get site backup status request. +// +// resourceGroupName is name of resource group name is name of web app +// backupID is id of backup +func (client SitesClient) GetSiteBackupStatus(resourceGroupName string, name string, backupID string) (result BackupItem, ae error) { + req, err := client.GetSiteBackupStatusPreparer(resourceGroupName, name, backupID) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupStatus", "Failure preparing request") + } + + resp, err := client.GetSiteBackupStatusSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupStatus", "Failure sending request") + } + + result, err = client.GetSiteBackupStatusResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupStatus", "Failure responding to request") + } + + return +} + +// GetSiteBackupStatusPreparer prepares the GetSiteBackupStatus request. +func (client SitesClient) GetSiteBackupStatusPreparer(resourceGroupName string, name string, backupID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "backupId": url.QueryEscape(backupID), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/backups/{backupId}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteBackupStatusSender sends the GetSiteBackupStatus request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteBackupStatusSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteBackupStatusResponder handles the response to the GetSiteBackupStatus request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteBackupStatusResponder(resp *http.Response) (result BackupItem, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteBackupStatusSecrets sends the get site backup status secrets request. +// +// resourceGroupName is name of resource group name is name of web app +// backupID is id of backup request is information on backup request +func (client SitesClient) GetSiteBackupStatusSecrets(resourceGroupName string, name string, backupID string, request BackupRequest) (result BackupItem, ae error) { + req, err := client.GetSiteBackupStatusSecretsPreparer(resourceGroupName, name, backupID, request) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupStatusSecrets", "Failure preparing request") + } + + resp, err := client.GetSiteBackupStatusSecretsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupStatusSecrets", "Failure sending request") + } + + result, err = client.GetSiteBackupStatusSecretsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupStatusSecrets", "Failure responding to request") + } + + return +} + +// GetSiteBackupStatusSecretsPreparer prepares the GetSiteBackupStatusSecrets request. +func (client SitesClient) GetSiteBackupStatusSecretsPreparer(resourceGroupName string, name string, backupID string, request BackupRequest) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "backupId": url.QueryEscape(backupID), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/backups/{backupId}/list"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteBackupStatusSecretsSender sends the GetSiteBackupStatusSecrets request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteBackupStatusSecretsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteBackupStatusSecretsResponder handles the response to the GetSiteBackupStatusSecrets request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteBackupStatusSecretsResponder(resp *http.Response) (result BackupItem, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteBackupStatusSecretsSlot sends the get site backup status secrets +// slot request. +// +// resourceGroupName is name of resource group name is name of web app +// backupID is id of backup request is information on backup request slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) GetSiteBackupStatusSecretsSlot(resourceGroupName string, name string, backupID string, request BackupRequest, slot string) (result BackupItem, ae error) { + req, err := client.GetSiteBackupStatusSecretsSlotPreparer(resourceGroupName, name, backupID, request, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupStatusSecretsSlot", "Failure preparing request") + } + + resp, err := client.GetSiteBackupStatusSecretsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupStatusSecretsSlot", "Failure sending request") + } + + result, err = client.GetSiteBackupStatusSecretsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupStatusSecretsSlot", "Failure responding to request") + } + + return +} + +// GetSiteBackupStatusSecretsSlotPreparer prepares the GetSiteBackupStatusSecretsSlot request. +func (client SitesClient) GetSiteBackupStatusSecretsSlotPreparer(resourceGroupName string, name string, backupID string, request BackupRequest, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "backupId": url.QueryEscape(backupID), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/backups/{backupId}/list"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteBackupStatusSecretsSlotSender sends the GetSiteBackupStatusSecretsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteBackupStatusSecretsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteBackupStatusSecretsSlotResponder handles the response to the GetSiteBackupStatusSecretsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteBackupStatusSecretsSlotResponder(resp *http.Response) (result BackupItem, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteBackupStatusSlot sends the get site backup status slot request. +// +// resourceGroupName is name of resource group name is name of web app +// backupID is id of backup slot is name of web app slot. If not specified +// then will default to production slot. +func (client SitesClient) GetSiteBackupStatusSlot(resourceGroupName string, name string, backupID string, slot string) (result BackupItem, ae error) { + req, err := client.GetSiteBackupStatusSlotPreparer(resourceGroupName, name, backupID, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupStatusSlot", "Failure preparing request") + } + + resp, err := client.GetSiteBackupStatusSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupStatusSlot", "Failure sending request") + } + + result, err = client.GetSiteBackupStatusSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteBackupStatusSlot", "Failure responding to request") + } + + return +} + +// GetSiteBackupStatusSlotPreparer prepares the GetSiteBackupStatusSlot request. +func (client SitesClient) GetSiteBackupStatusSlotPreparer(resourceGroupName string, name string, backupID string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "backupId": url.QueryEscape(backupID), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/backups/{backupId}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteBackupStatusSlotSender sends the GetSiteBackupStatusSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteBackupStatusSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteBackupStatusSlotResponder handles the response to the GetSiteBackupStatusSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteBackupStatusSlotResponder(resp *http.Response) (result BackupItem, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteConfig sends the get site config request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) GetSiteConfig(resourceGroupName string, name string) (result SiteConfig, ae error) { + req, err := client.GetSiteConfigPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteConfig", "Failure preparing request") + } + + resp, err := client.GetSiteConfigSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteConfig", "Failure sending request") + } + + result, err = client.GetSiteConfigResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteConfig", "Failure responding to request") + } + + return +} + +// GetSiteConfigPreparer prepares the GetSiteConfig request. +func (client SitesClient) GetSiteConfigPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/web"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteConfigSender sends the GetSiteConfig request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteConfigSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteConfigResponder handles the response to the GetSiteConfig request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteConfigResponder(resp *http.Response) (result SiteConfig, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteConfigSlot sends the get site config slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) GetSiteConfigSlot(resourceGroupName string, name string, slot string) (result SiteConfig, ae error) { + req, err := client.GetSiteConfigSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteConfigSlot", "Failure preparing request") + } + + resp, err := client.GetSiteConfigSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteConfigSlot", "Failure sending request") + } + + result, err = client.GetSiteConfigSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteConfigSlot", "Failure responding to request") + } + + return +} + +// GetSiteConfigSlotPreparer prepares the GetSiteConfigSlot request. +func (client SitesClient) GetSiteConfigSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/web"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteConfigSlotSender sends the GetSiteConfigSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteConfigSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteConfigSlotResponder handles the response to the GetSiteConfigSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteConfigSlotResponder(resp *http.Response) (result SiteConfig, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteHostNameBinding sends the get site host name binding request. +// +// resourceGroupName is name of resource group name is name of web app +// hostName is name of host +func (client SitesClient) GetSiteHostNameBinding(resourceGroupName string, name string, hostName string) (result HostNameBinding, ae error) { + req, err := client.GetSiteHostNameBindingPreparer(resourceGroupName, name, hostName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteHostNameBinding", "Failure preparing request") + } + + resp, err := client.GetSiteHostNameBindingSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteHostNameBinding", "Failure sending request") + } + + result, err = client.GetSiteHostNameBindingResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteHostNameBinding", "Failure responding to request") + } + + return +} + +// GetSiteHostNameBindingPreparer prepares the GetSiteHostNameBinding request. +func (client SitesClient) GetSiteHostNameBindingPreparer(resourceGroupName string, name string, hostName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "hostName": url.QueryEscape(hostName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/hostNameBindings/{hostName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteHostNameBindingSender sends the GetSiteHostNameBinding request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteHostNameBindingSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteHostNameBindingResponder handles the response to the GetSiteHostNameBinding request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteHostNameBindingResponder(resp *http.Response) (result HostNameBinding, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteHostNameBindings sends the get site host name bindings request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) GetSiteHostNameBindings(resourceGroupName string, name string) (result HostNameBindingCollection, ae error) { + req, err := client.GetSiteHostNameBindingsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteHostNameBindings", "Failure preparing request") + } + + resp, err := client.GetSiteHostNameBindingsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteHostNameBindings", "Failure sending request") + } + + result, err = client.GetSiteHostNameBindingsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteHostNameBindings", "Failure responding to request") + } + + return +} + +// GetSiteHostNameBindingsPreparer prepares the GetSiteHostNameBindings request. +func (client SitesClient) GetSiteHostNameBindingsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/hostNameBindings"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteHostNameBindingsSender sends the GetSiteHostNameBindings request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteHostNameBindingsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteHostNameBindingsResponder handles the response to the GetSiteHostNameBindings request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteHostNameBindingsResponder(resp *http.Response) (result HostNameBindingCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteHostNameBindingSlot sends the get site host name binding slot +// request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. hostName is name of host +func (client SitesClient) GetSiteHostNameBindingSlot(resourceGroupName string, name string, slot string, hostName string) (result HostNameBinding, ae error) { + req, err := client.GetSiteHostNameBindingSlotPreparer(resourceGroupName, name, slot, hostName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteHostNameBindingSlot", "Failure preparing request") + } + + resp, err := client.GetSiteHostNameBindingSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteHostNameBindingSlot", "Failure sending request") + } + + result, err = client.GetSiteHostNameBindingSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteHostNameBindingSlot", "Failure responding to request") + } + + return +} + +// GetSiteHostNameBindingSlotPreparer prepares the GetSiteHostNameBindingSlot request. +func (client SitesClient) GetSiteHostNameBindingSlotPreparer(resourceGroupName string, name string, slot string, hostName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "hostName": url.QueryEscape(hostName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/hostNameBindings/{hostName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteHostNameBindingSlotSender sends the GetSiteHostNameBindingSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteHostNameBindingSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteHostNameBindingSlotResponder handles the response to the GetSiteHostNameBindingSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteHostNameBindingSlotResponder(resp *http.Response) (result HostNameBinding, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteHostNameBindingsSlot sends the get site host name bindings slot +// request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) GetSiteHostNameBindingsSlot(resourceGroupName string, name string, slot string) (result HostNameBindingCollection, ae error) { + req, err := client.GetSiteHostNameBindingsSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteHostNameBindingsSlot", "Failure preparing request") + } + + resp, err := client.GetSiteHostNameBindingsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteHostNameBindingsSlot", "Failure sending request") + } + + result, err = client.GetSiteHostNameBindingsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteHostNameBindingsSlot", "Failure responding to request") + } + + return +} + +// GetSiteHostNameBindingsSlotPreparer prepares the GetSiteHostNameBindingsSlot request. +func (client SitesClient) GetSiteHostNameBindingsSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/hostNameBindings"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteHostNameBindingsSlotSender sends the GetSiteHostNameBindingsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteHostNameBindingsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteHostNameBindingsSlotResponder handles the response to the GetSiteHostNameBindingsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteHostNameBindingsSlotResponder(resp *http.Response) (result HostNameBindingCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteInstanceIdentifiers sends the get site instance identifiers request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) GetSiteInstanceIdentifiers(resourceGroupName string, name string) (result SiteInstanceCollection, ae error) { + req, err := client.GetSiteInstanceIdentifiersPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteInstanceIdentifiers", "Failure preparing request") + } + + resp, err := client.GetSiteInstanceIdentifiersSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteInstanceIdentifiers", "Failure sending request") + } + + result, err = client.GetSiteInstanceIdentifiersResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteInstanceIdentifiers", "Failure responding to request") + } + + return +} + +// GetSiteInstanceIdentifiersPreparer prepares the GetSiteInstanceIdentifiers request. +func (client SitesClient) GetSiteInstanceIdentifiersPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/instances"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteInstanceIdentifiersSender sends the GetSiteInstanceIdentifiers request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteInstanceIdentifiersSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteInstanceIdentifiersResponder handles the response to the GetSiteInstanceIdentifiers request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteInstanceIdentifiersResponder(resp *http.Response) (result SiteInstanceCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteInstanceIdentifiersSlot sends the get site instance identifiers slot +// request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) GetSiteInstanceIdentifiersSlot(resourceGroupName string, name string, slot string) (result SiteInstanceCollection, ae error) { + req, err := client.GetSiteInstanceIdentifiersSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteInstanceIdentifiersSlot", "Failure preparing request") + } + + resp, err := client.GetSiteInstanceIdentifiersSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteInstanceIdentifiersSlot", "Failure sending request") + } + + result, err = client.GetSiteInstanceIdentifiersSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteInstanceIdentifiersSlot", "Failure responding to request") + } + + return +} + +// GetSiteInstanceIdentifiersSlotPreparer prepares the GetSiteInstanceIdentifiersSlot request. +func (client SitesClient) GetSiteInstanceIdentifiersSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/instances"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteInstanceIdentifiersSlotSender sends the GetSiteInstanceIdentifiersSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteInstanceIdentifiersSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteInstanceIdentifiersSlotResponder handles the response to the GetSiteInstanceIdentifiersSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteInstanceIdentifiersSlotResponder(resp *http.Response) (result SiteInstanceCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteLogsConfig sends the get site logs config request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) GetSiteLogsConfig(resourceGroupName string, name string) (result SiteLogsConfig, ae error) { + req, err := client.GetSiteLogsConfigPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteLogsConfig", "Failure preparing request") + } + + resp, err := client.GetSiteLogsConfigSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteLogsConfig", "Failure sending request") + } + + result, err = client.GetSiteLogsConfigResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteLogsConfig", "Failure responding to request") + } + + return +} + +// GetSiteLogsConfigPreparer prepares the GetSiteLogsConfig request. +func (client SitesClient) GetSiteLogsConfigPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/logs"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteLogsConfigSender sends the GetSiteLogsConfig request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteLogsConfigSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteLogsConfigResponder handles the response to the GetSiteLogsConfig request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteLogsConfigResponder(resp *http.Response) (result SiteLogsConfig, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteLogsConfigSlot sends the get site logs config slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) GetSiteLogsConfigSlot(resourceGroupName string, name string, slot string) (result SiteLogsConfig, ae error) { + req, err := client.GetSiteLogsConfigSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteLogsConfigSlot", "Failure preparing request") + } + + resp, err := client.GetSiteLogsConfigSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteLogsConfigSlot", "Failure sending request") + } + + result, err = client.GetSiteLogsConfigSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteLogsConfigSlot", "Failure responding to request") + } + + return +} + +// GetSiteLogsConfigSlotPreparer prepares the GetSiteLogsConfigSlot request. +func (client SitesClient) GetSiteLogsConfigSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/logs"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteLogsConfigSlotSender sends the GetSiteLogsConfigSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteLogsConfigSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteLogsConfigSlotResponder handles the response to the GetSiteLogsConfigSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteLogsConfigSlotResponder(resp *http.Response) (result SiteLogsConfig, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteMetricDefinitions sends the get site metric definitions request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) GetSiteMetricDefinitions(resourceGroupName string, name string) (result MetricDefinitionCollection, ae error) { + req, err := client.GetSiteMetricDefinitionsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteMetricDefinitions", "Failure preparing request") + } + + resp, err := client.GetSiteMetricDefinitionsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteMetricDefinitions", "Failure sending request") + } + + result, err = client.GetSiteMetricDefinitionsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteMetricDefinitions", "Failure responding to request") + } + + return +} + +// GetSiteMetricDefinitionsPreparer prepares the GetSiteMetricDefinitions request. +func (client SitesClient) GetSiteMetricDefinitionsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/metricdefinitions"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteMetricDefinitionsSender sends the GetSiteMetricDefinitions request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteMetricDefinitionsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteMetricDefinitionsResponder handles the response to the GetSiteMetricDefinitions request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteMetricDefinitionsResponder(resp *http.Response) (result MetricDefinitionCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteMetricDefinitionsSlot sends the get site metric definitions slot +// request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) GetSiteMetricDefinitionsSlot(resourceGroupName string, name string, slot string) (result MetricDefinitionCollection, ae error) { + req, err := client.GetSiteMetricDefinitionsSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteMetricDefinitionsSlot", "Failure preparing request") + } + + resp, err := client.GetSiteMetricDefinitionsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteMetricDefinitionsSlot", "Failure sending request") + } + + result, err = client.GetSiteMetricDefinitionsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteMetricDefinitionsSlot", "Failure responding to request") + } + + return +} + +// GetSiteMetricDefinitionsSlotPreparer prepares the GetSiteMetricDefinitionsSlot request. +func (client SitesClient) GetSiteMetricDefinitionsSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/metricdefinitions"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteMetricDefinitionsSlotSender sends the GetSiteMetricDefinitionsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteMetricDefinitionsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteMetricDefinitionsSlotResponder handles the response to the GetSiteMetricDefinitionsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteMetricDefinitionsSlotResponder(resp *http.Response) (result MetricDefinitionCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteMetrics sends the get site metrics request. +// +// resourceGroupName is name of resource group name is name of web app details +// is if true, metric details are included in response filter is return only +// usages/metrics specified in the filter. Filter conforms to odata syntax. +// Example: $filter=(name.value eq 'Metric1' or name.value eq 'Metric2') and +// startTime eq '2014-01-01T00:00:00Z' and endTime eq '2014-12-31T23:59:59Z' +// and timeGrain eq duration'[Hour|Minute|Day]'. +func (client SitesClient) GetSiteMetrics(resourceGroupName string, name string, details *bool, filter string) (result ResourceMetricCollection, ae error) { + req, err := client.GetSiteMetricsPreparer(resourceGroupName, name, details, filter) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteMetrics", "Failure preparing request") + } + + resp, err := client.GetSiteMetricsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteMetrics", "Failure sending request") + } + + result, err = client.GetSiteMetricsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteMetrics", "Failure responding to request") + } + + return +} + +// GetSiteMetricsPreparer prepares the GetSiteMetrics request. +func (client SitesClient) GetSiteMetricsPreparer(resourceGroupName string, name string, details *bool, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if details != nil { + queryParameters["details"] = details + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/metrics"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteMetricsSender sends the GetSiteMetrics request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteMetricsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteMetricsResponder handles the response to the GetSiteMetrics request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteMetricsResponder(resp *http.Response) (result ResourceMetricCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteMetricsSlot sends the get site metrics slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. details is if true, metric details are included in response filter +// is return only usages/metrics specified in the filter. Filter conforms to +// odata syntax. Example: $filter=(name.value eq 'Metric1' or name.value eq +// 'Metric2') and startTime eq '2014-01-01T00:00:00Z' and endTime eq +// '2014-12-31T23:59:59Z' and timeGrain eq duration'[Hour|Minute|Day]'. +func (client SitesClient) GetSiteMetricsSlot(resourceGroupName string, name string, slot string, details *bool, filter string) (result ResourceMetricCollection, ae error) { + req, err := client.GetSiteMetricsSlotPreparer(resourceGroupName, name, slot, details, filter) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteMetricsSlot", "Failure preparing request") + } + + resp, err := client.GetSiteMetricsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteMetricsSlot", "Failure sending request") + } + + result, err = client.GetSiteMetricsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteMetricsSlot", "Failure responding to request") + } + + return +} + +// GetSiteMetricsSlotPreparer prepares the GetSiteMetricsSlot request. +func (client SitesClient) GetSiteMetricsSlotPreparer(resourceGroupName string, name string, slot string, details *bool, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if details != nil { + queryParameters["details"] = details + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/metrics"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteMetricsSlotSender sends the GetSiteMetricsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteMetricsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteMetricsSlotResponder handles the response to the GetSiteMetricsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteMetricsSlotResponder(resp *http.Response) (result ResourceMetricCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteNetworkFeatures sends the get site network features request. +// +// resourceGroupName is the resource group name name is the name of the web +// app view is the type of view. This can either be "summary" or "detailed". +func (client SitesClient) GetSiteNetworkFeatures(resourceGroupName string, name string, view string) (result NetworkFeatures, ae error) { + req, err := client.GetSiteNetworkFeaturesPreparer(resourceGroupName, name, view) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteNetworkFeatures", "Failure preparing request") + } + + resp, err := client.GetSiteNetworkFeaturesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteNetworkFeatures", "Failure sending request") + } + + result, err = client.GetSiteNetworkFeaturesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteNetworkFeatures", "Failure responding to request") + } + + return +} + +// GetSiteNetworkFeaturesPreparer prepares the GetSiteNetworkFeatures request. +func (client SitesClient) GetSiteNetworkFeaturesPreparer(resourceGroupName string, name string, view string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "view": url.QueryEscape(view), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/networkFeatures/{view}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteNetworkFeaturesSender sends the GetSiteNetworkFeatures request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteNetworkFeaturesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusNotFound) +} + +// GetSiteNetworkFeaturesResponder handles the response to the GetSiteNetworkFeatures request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteNetworkFeaturesResponder(resp *http.Response) (result NetworkFeatures, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNotFound), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteNetworkFeaturesSlot sends the get site network features slot request. +// +// resourceGroupName is the resource group name name is the name of the web +// app view is the type of view. This can either be "summary" or "detailed". +// slot is the name of the slot for this web app. +func (client SitesClient) GetSiteNetworkFeaturesSlot(resourceGroupName string, name string, view string, slot string) (result NetworkFeatures, ae error) { + req, err := client.GetSiteNetworkFeaturesSlotPreparer(resourceGroupName, name, view, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteNetworkFeaturesSlot", "Failure preparing request") + } + + resp, err := client.GetSiteNetworkFeaturesSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteNetworkFeaturesSlot", "Failure sending request") + } + + result, err = client.GetSiteNetworkFeaturesSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteNetworkFeaturesSlot", "Failure responding to request") + } + + return +} + +// GetSiteNetworkFeaturesSlotPreparer prepares the GetSiteNetworkFeaturesSlot request. +func (client SitesClient) GetSiteNetworkFeaturesSlotPreparer(resourceGroupName string, name string, view string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "view": url.QueryEscape(view), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/networkFeatures/{view}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteNetworkFeaturesSlotSender sends the GetSiteNetworkFeaturesSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteNetworkFeaturesSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusNotFound) +} + +// GetSiteNetworkFeaturesSlotResponder handles the response to the GetSiteNetworkFeaturesSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteNetworkFeaturesSlotResponder(resp *http.Response) (result NetworkFeatures, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNotFound), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteOperation sends the get site operation request. +// +// resourceGroupName is name of resource group name is name of web app +// operationID is id of an operation +func (client SitesClient) GetSiteOperation(resourceGroupName string, name string, operationID string) (result ObjectSet, ae error) { + req, err := client.GetSiteOperationPreparer(resourceGroupName, name, operationID) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteOperation", "Failure preparing request") + } + + resp, err := client.GetSiteOperationSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteOperation", "Failure sending request") + } + + result, err = client.GetSiteOperationResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteOperation", "Failure responding to request") + } + + return +} + +// GetSiteOperationPreparer prepares the GetSiteOperation request. +func (client SitesClient) GetSiteOperationPreparer(resourceGroupName string, name string, operationID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "operationId": url.QueryEscape(operationID), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/operationresults/{operationId}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteOperationSender sends the GetSiteOperation request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteOperationSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteOperationResponder handles the response to the GetSiteOperation request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteOperationResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteOperationSlot sends the get site operation slot request. +// +// resourceGroupName is name of resource group name is name of web app +// operationID is id of an operation slot is name of web app slot. If not +// specified then will default to production slot. +func (client SitesClient) GetSiteOperationSlot(resourceGroupName string, name string, operationID string, slot string) (result ObjectSet, ae error) { + req, err := client.GetSiteOperationSlotPreparer(resourceGroupName, name, operationID, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteOperationSlot", "Failure preparing request") + } + + resp, err := client.GetSiteOperationSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteOperationSlot", "Failure sending request") + } + + result, err = client.GetSiteOperationSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteOperationSlot", "Failure responding to request") + } + + return +} + +// GetSiteOperationSlotPreparer prepares the GetSiteOperationSlot request. +func (client SitesClient) GetSiteOperationSlotPreparer(resourceGroupName string, name string, operationID string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "operationId": url.QueryEscape(operationID), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/operationresults/{operationId}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteOperationSlotSender sends the GetSiteOperationSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteOperationSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteOperationSlotResponder handles the response to the GetSiteOperationSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteOperationSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSitePremierAddOn sends the get site premier add on request. +// +func (client SitesClient) GetSitePremierAddOn(resourceGroupName string, name string, premierAddOnName string) (result ObjectSet, ae error) { + req, err := client.GetSitePremierAddOnPreparer(resourceGroupName, name, premierAddOnName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSitePremierAddOn", "Failure preparing request") + } + + resp, err := client.GetSitePremierAddOnSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSitePremierAddOn", "Failure sending request") + } + + result, err = client.GetSitePremierAddOnResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSitePremierAddOn", "Failure responding to request") + } + + return +} + +// GetSitePremierAddOnPreparer prepares the GetSitePremierAddOn request. +func (client SitesClient) GetSitePremierAddOnPreparer(resourceGroupName string, name string, premierAddOnName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "premierAddOnName": url.QueryEscape(premierAddOnName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/premieraddons/{premierAddOnName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSitePremierAddOnSender sends the GetSitePremierAddOn request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSitePremierAddOnSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSitePremierAddOnResponder handles the response to the GetSitePremierAddOn request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSitePremierAddOnResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSitePremierAddOnSlot sends the get site premier add on slot request. +// +func (client SitesClient) GetSitePremierAddOnSlot(resourceGroupName string, name string, premierAddOnName string, slot string) (result ObjectSet, ae error) { + req, err := client.GetSitePremierAddOnSlotPreparer(resourceGroupName, name, premierAddOnName, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSitePremierAddOnSlot", "Failure preparing request") + } + + resp, err := client.GetSitePremierAddOnSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSitePremierAddOnSlot", "Failure sending request") + } + + result, err = client.GetSitePremierAddOnSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSitePremierAddOnSlot", "Failure responding to request") + } + + return +} + +// GetSitePremierAddOnSlotPreparer prepares the GetSitePremierAddOnSlot request. +func (client SitesClient) GetSitePremierAddOnSlotPreparer(resourceGroupName string, name string, premierAddOnName string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "premierAddOnName": url.QueryEscape(premierAddOnName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/premieraddons/{premierAddOnName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSitePremierAddOnSlotSender sends the GetSitePremierAddOnSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSitePremierAddOnSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSitePremierAddOnSlotResponder handles the response to the GetSitePremierAddOnSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSitePremierAddOnSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteRelayServiceConnection sends the get site relay service connection +// request. +// +// resourceGroupName is the resource group name name is the name of the web +// app entityName is the name by which the Hybrid Connection is identified +func (client SitesClient) GetSiteRelayServiceConnection(resourceGroupName string, name string, entityName string) (result RelayServiceConnectionEntity, ae error) { + req, err := client.GetSiteRelayServiceConnectionPreparer(resourceGroupName, name, entityName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteRelayServiceConnection", "Failure preparing request") + } + + resp, err := client.GetSiteRelayServiceConnectionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteRelayServiceConnection", "Failure sending request") + } + + result, err = client.GetSiteRelayServiceConnectionResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteRelayServiceConnection", "Failure responding to request") + } + + return +} + +// GetSiteRelayServiceConnectionPreparer prepares the GetSiteRelayServiceConnection request. +func (client SitesClient) GetSiteRelayServiceConnectionPreparer(resourceGroupName string, name string, entityName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "entityName": url.QueryEscape(entityName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/hybridconnection/{entityName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteRelayServiceConnectionSender sends the GetSiteRelayServiceConnection request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteRelayServiceConnectionSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteRelayServiceConnectionResponder handles the response to the GetSiteRelayServiceConnection request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteRelayServiceConnectionResponder(resp *http.Response) (result RelayServiceConnectionEntity, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteRelayServiceConnectionSlot sends the get site relay service +// connection slot request. +// +// resourceGroupName is the resource group name name is the name of the web +// app entityName is the name by which the Hybrid Connection is identified +// slot is the name of the slot for the web app. +func (client SitesClient) GetSiteRelayServiceConnectionSlot(resourceGroupName string, name string, entityName string, slot string) (result RelayServiceConnectionEntity, ae error) { + req, err := client.GetSiteRelayServiceConnectionSlotPreparer(resourceGroupName, name, entityName, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteRelayServiceConnectionSlot", "Failure preparing request") + } + + resp, err := client.GetSiteRelayServiceConnectionSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteRelayServiceConnectionSlot", "Failure sending request") + } + + result, err = client.GetSiteRelayServiceConnectionSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteRelayServiceConnectionSlot", "Failure responding to request") + } + + return +} + +// GetSiteRelayServiceConnectionSlotPreparer prepares the GetSiteRelayServiceConnectionSlot request. +func (client SitesClient) GetSiteRelayServiceConnectionSlotPreparer(resourceGroupName string, name string, entityName string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "entityName": url.QueryEscape(entityName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/hybridconnection/{entityName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteRelayServiceConnectionSlotSender sends the GetSiteRelayServiceConnectionSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteRelayServiceConnectionSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteRelayServiceConnectionSlotResponder handles the response to the GetSiteRelayServiceConnectionSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteRelayServiceConnectionSlotResponder(resp *http.Response) (result RelayServiceConnectionEntity, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSites sends the get sites request. +// +// resourceGroupName is name of resource group propertiesToInclude is +// additional web app properties included in the response includeSiteTypes is +// types of apps included in the response includeSlots is whether or not to +// include deployments slots in results +func (client SitesClient) GetSites(resourceGroupName string, propertiesToInclude string, includeSiteTypes string, includeSlots *bool) (result SiteCollection, ae error) { + req, err := client.GetSitesPreparer(resourceGroupName, propertiesToInclude, includeSiteTypes, includeSlots) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSites", "Failure preparing request") + } + + resp, err := client.GetSitesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSites", "Failure sending request") + } + + result, err = client.GetSitesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSites", "Failure responding to request") + } + + return +} + +// GetSitesPreparer prepares the GetSites request. +func (client SitesClient) GetSitesPreparer(resourceGroupName string, propertiesToInclude string, includeSiteTypes string, includeSlots *bool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(propertiesToInclude) > 0 { + queryParameters["propertiesToInclude"] = propertiesToInclude + } + if len(includeSiteTypes) > 0 { + queryParameters["includeSiteTypes"] = includeSiteTypes + } + if includeSlots != nil { + queryParameters["includeSlots"] = includeSlots + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSitesSender sends the GetSites request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSitesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSitesResponder handles the response to the GetSites request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSitesResponder(resp *http.Response) (result SiteCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteSlot sends the get site slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. propertiesToInclude is additional web app properties included in the +// response +func (client SitesClient) GetSiteSlot(resourceGroupName string, name string, slot string, propertiesToInclude string) (result Site, ae error) { + req, err := client.GetSiteSlotPreparer(resourceGroupName, name, slot, propertiesToInclude) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSlot", "Failure preparing request") + } + + resp, err := client.GetSiteSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSlot", "Failure sending request") + } + + result, err = client.GetSiteSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSlot", "Failure responding to request") + } + + return +} + +// GetSiteSlotPreparer prepares the GetSiteSlot request. +func (client SitesClient) GetSiteSlotPreparer(resourceGroupName string, name string, slot string, propertiesToInclude string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(propertiesToInclude) > 0 { + queryParameters["propertiesToInclude"] = propertiesToInclude + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteSlotSender sends the GetSiteSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteSlotResponder handles the response to the GetSiteSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteSlotResponder(resp *http.Response) (result Site, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteSlots sends the get site slots request. +// +// resourceGroupName is name of resource group name is name of web app +// propertiesToInclude is list of app properties to include in the response +func (client SitesClient) GetSiteSlots(resourceGroupName string, name string, propertiesToInclude string) (result SiteCollection, ae error) { + req, err := client.GetSiteSlotsPreparer(resourceGroupName, name, propertiesToInclude) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSlots", "Failure preparing request") + } + + resp, err := client.GetSiteSlotsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSlots", "Failure sending request") + } + + result, err = client.GetSiteSlotsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSlots", "Failure responding to request") + } + + return +} + +// GetSiteSlotsPreparer prepares the GetSiteSlots request. +func (client SitesClient) GetSiteSlotsPreparer(resourceGroupName string, name string, propertiesToInclude string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(propertiesToInclude) > 0 { + queryParameters["propertiesToInclude"] = propertiesToInclude + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteSlotsSender sends the GetSiteSlots request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteSlotsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteSlotsResponder handles the response to the GetSiteSlots request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteSlotsResponder(resp *http.Response) (result SiteCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteSnapshots sends the get site snapshots request. +// +// subscriptionName is azure subscription webspaceName is webspace name is +// website Name +func (client SitesClient) GetSiteSnapshots(subscriptionName string, webspaceName string, name string, resourceGroupName string) (result ObjectSet, ae error) { + req, err := client.GetSiteSnapshotsPreparer(subscriptionName, webspaceName, name, resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSnapshots", "Failure preparing request") + } + + resp, err := client.GetSiteSnapshotsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSnapshots", "Failure sending request") + } + + result, err = client.GetSiteSnapshotsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSnapshots", "Failure responding to request") + } + + return +} + +// GetSiteSnapshotsPreparer prepares the GetSiteSnapshots request. +func (client SitesClient) GetSiteSnapshotsPreparer(subscriptionName string, webspaceName string, name string, resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + "subscriptionName": subscriptionName, + "webspaceName": webspaceName, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/snapshots"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteSnapshotsSender sends the GetSiteSnapshots request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteSnapshotsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteSnapshotsResponder handles the response to the GetSiteSnapshots request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteSnapshotsResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteSnapshotsOnSku sends the get site snapshots on sku request. +// +// subscriptionName is azure subscription webspaceName is webspace name is +// website Name +func (client SitesClient) GetSiteSnapshotsOnSku(subscriptionName string, webspaceName string, name string, resourceGroupName string) (result ObjectSet, ae error) { + req, err := client.GetSiteSnapshotsOnSkuPreparer(subscriptionName, webspaceName, name, resourceGroupName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSnapshotsOnSku", "Failure preparing request") + } + + resp, err := client.GetSiteSnapshotsOnSkuSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSnapshotsOnSku", "Failure sending request") + } + + result, err = client.GetSiteSnapshotsOnSkuResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSnapshotsOnSku", "Failure responding to request") + } + + return +} + +// GetSiteSnapshotsOnSkuPreparer prepares the GetSiteSnapshotsOnSku request. +func (client SitesClient) GetSiteSnapshotsOnSkuPreparer(subscriptionName string, webspaceName string, name string, resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + "subscriptionName": subscriptionName, + "webspaceName": webspaceName, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/restorableSnapshots"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteSnapshotsOnSkuSender sends the GetSiteSnapshotsOnSku request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteSnapshotsOnSkuSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteSnapshotsOnSkuResponder handles the response to the GetSiteSnapshotsOnSku request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteSnapshotsOnSkuResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteSnapshotsOnSkuSlot sends the get site snapshots on sku slot request. +// +// subscriptionName is azure subscription webspaceName is webspace name is +// website Name +func (client SitesClient) GetSiteSnapshotsOnSkuSlot(subscriptionName string, webspaceName string, name string, resourceGroupName string, slot string) (result ObjectSet, ae error) { + req, err := client.GetSiteSnapshotsOnSkuSlotPreparer(subscriptionName, webspaceName, name, resourceGroupName, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSnapshotsOnSkuSlot", "Failure preparing request") + } + + resp, err := client.GetSiteSnapshotsOnSkuSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSnapshotsOnSkuSlot", "Failure sending request") + } + + result, err = client.GetSiteSnapshotsOnSkuSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSnapshotsOnSkuSlot", "Failure responding to request") + } + + return +} + +// GetSiteSnapshotsOnSkuSlotPreparer prepares the GetSiteSnapshotsOnSkuSlot request. +func (client SitesClient) GetSiteSnapshotsOnSkuSlotPreparer(subscriptionName string, webspaceName string, name string, resourceGroupName string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + "subscriptionName": subscriptionName, + "webspaceName": webspaceName, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/restorableSnapshots"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteSnapshotsOnSkuSlotSender sends the GetSiteSnapshotsOnSkuSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteSnapshotsOnSkuSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteSnapshotsOnSkuSlotResponder handles the response to the GetSiteSnapshotsOnSkuSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteSnapshotsOnSkuSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteSnapshotsSlot sends the get site snapshots slot request. +// +// subscriptionName is azure subscription webspaceName is webspace name is +// website Name +func (client SitesClient) GetSiteSnapshotsSlot(subscriptionName string, webspaceName string, name string, resourceGroupName string, slot string) (result ObjectSet, ae error) { + req, err := client.GetSiteSnapshotsSlotPreparer(subscriptionName, webspaceName, name, resourceGroupName, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSnapshotsSlot", "Failure preparing request") + } + + resp, err := client.GetSiteSnapshotsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSnapshotsSlot", "Failure sending request") + } + + result, err = client.GetSiteSnapshotsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSnapshotsSlot", "Failure responding to request") + } + + return +} + +// GetSiteSnapshotsSlotPreparer prepares the GetSiteSnapshotsSlot request. +func (client SitesClient) GetSiteSnapshotsSlotPreparer(subscriptionName string, webspaceName string, name string, resourceGroupName string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + "subscriptionName": subscriptionName, + "webspaceName": webspaceName, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/snapshots"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteSnapshotsSlotSender sends the GetSiteSnapshotsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteSnapshotsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteSnapshotsSlotResponder handles the response to the GetSiteSnapshotsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteSnapshotsSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteSourceControl sends the get site source control request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) GetSiteSourceControl(resourceGroupName string, name string) (result SiteSourceControl, ae error) { + req, err := client.GetSiteSourceControlPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSourceControl", "Failure preparing request") + } + + resp, err := client.GetSiteSourceControlSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSourceControl", "Failure sending request") + } + + result, err = client.GetSiteSourceControlResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSourceControl", "Failure responding to request") + } + + return +} + +// GetSiteSourceControlPreparer prepares the GetSiteSourceControl request. +func (client SitesClient) GetSiteSourceControlPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/sourcecontrols/web"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteSourceControlSender sends the GetSiteSourceControl request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteSourceControlSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteSourceControlResponder handles the response to the GetSiteSourceControl request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteSourceControlResponder(resp *http.Response) (result SiteSourceControl, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteSourceControlSlot sends the get site source control slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) GetSiteSourceControlSlot(resourceGroupName string, name string, slot string) (result SiteSourceControl, ae error) { + req, err := client.GetSiteSourceControlSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSourceControlSlot", "Failure preparing request") + } + + resp, err := client.GetSiteSourceControlSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSourceControlSlot", "Failure sending request") + } + + result, err = client.GetSiteSourceControlSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteSourceControlSlot", "Failure responding to request") + } + + return +} + +// GetSiteSourceControlSlotPreparer prepares the GetSiteSourceControlSlot request. +func (client SitesClient) GetSiteSourceControlSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/sourcecontrols/web"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteSourceControlSlotSender sends the GetSiteSourceControlSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteSourceControlSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteSourceControlSlotResponder handles the response to the GetSiteSourceControlSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteSourceControlSlotResponder(resp *http.Response) (result SiteSourceControl, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteUsages sends the get site usages request. +// +// resourceGroupName is name of resource group name is name of web app filter +// is return only usages specified in the filter. Filter is specified by +// using OData syntax. Example: $filter=(name.value eq 'Metric1' or +// name.value eq 'Metric2') and startTime eq '2014-01-01T00:00:00Z' and +// endTime eq '2014-12-31T23:59:59Z' and timeGrain eq +// duration'[Hour|Minute|Day]'. +func (client SitesClient) GetSiteUsages(resourceGroupName string, name string, filter string) (result CsmUsageQuotaCollection, ae error) { + req, err := client.GetSiteUsagesPreparer(resourceGroupName, name, filter) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteUsages", "Failure preparing request") + } + + resp, err := client.GetSiteUsagesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteUsages", "Failure sending request") + } + + result, err = client.GetSiteUsagesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteUsages", "Failure responding to request") + } + + return +} + +// GetSiteUsagesPreparer prepares the GetSiteUsages request. +func (client SitesClient) GetSiteUsagesPreparer(resourceGroupName string, name string, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/usages"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteUsagesSender sends the GetSiteUsages request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteUsagesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteUsagesResponder handles the response to the GetSiteUsages request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteUsagesResponder(resp *http.Response) (result CsmUsageQuotaCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteUsagesSlot sends the get site usages slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. filter is return only usages specified in the filter. Filter is +// specified by using OData syntax. Example: $filter=(name.value eq 'Metric1' +// or name.value eq 'Metric2') and startTime eq '2014-01-01T00:00:00Z' and +// endTime eq '2014-12-31T23:59:59Z' and timeGrain eq +// duration'[Hour|Minute|Day]'. +func (client SitesClient) GetSiteUsagesSlot(resourceGroupName string, name string, slot string, filter string) (result CsmUsageQuotaCollection, ae error) { + req, err := client.GetSiteUsagesSlotPreparer(resourceGroupName, name, slot, filter) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteUsagesSlot", "Failure preparing request") + } + + resp, err := client.GetSiteUsagesSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteUsagesSlot", "Failure sending request") + } + + result, err = client.GetSiteUsagesSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteUsagesSlot", "Failure responding to request") + } + + return +} + +// GetSiteUsagesSlotPreparer prepares the GetSiteUsagesSlot request. +func (client SitesClient) GetSiteUsagesSlotPreparer(resourceGroupName string, name string, slot string, filter string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if len(filter) > 0 { + queryParameters["$filter"] = filter + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/usages"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteUsagesSlotSender sends the GetSiteUsagesSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteUsagesSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteUsagesSlotResponder handles the response to the GetSiteUsagesSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteUsagesSlotResponder(resp *http.Response) (result CsmUsageQuotaCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteVNETConnection sends the get site vnet connection request. +// +// resourceGroupName is the resource group name name is the name of the web +// app vnetName is the name of the Virtual Network +func (client SitesClient) GetSiteVNETConnection(resourceGroupName string, name string, vnetName string) (result VnetInfo, ae error) { + req, err := client.GetSiteVNETConnectionPreparer(resourceGroupName, name, vnetName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVNETConnection", "Failure preparing request") + } + + resp, err := client.GetSiteVNETConnectionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVNETConnection", "Failure sending request") + } + + result, err = client.GetSiteVNETConnectionResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVNETConnection", "Failure responding to request") + } + + return +} + +// GetSiteVNETConnectionPreparer prepares the GetSiteVNETConnection request. +func (client SitesClient) GetSiteVNETConnectionPreparer(resourceGroupName string, name string, vnetName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/virtualNetworkConnections/{vnetName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteVNETConnectionSender sends the GetSiteVNETConnection request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteVNETConnectionSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteVNETConnectionResponder handles the response to the GetSiteVNETConnection request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteVNETConnectionResponder(resp *http.Response) (result VnetInfo, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteVNETConnections sends the get site vnet connections request. +// +// resourceGroupName is the resource group name name is the name of the web +// app +func (client SitesClient) GetSiteVNETConnections(resourceGroupName string, name string) (result VnetInfoList, ae error) { + req, err := client.GetSiteVNETConnectionsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVNETConnections", "Failure preparing request") + } + + resp, err := client.GetSiteVNETConnectionsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVNETConnections", "Failure sending request") + } + + result, err = client.GetSiteVNETConnectionsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVNETConnections", "Failure responding to request") + } + + return +} + +// GetSiteVNETConnectionsPreparer prepares the GetSiteVNETConnections request. +func (client SitesClient) GetSiteVNETConnectionsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/virtualNetworkConnections"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteVNETConnectionsSender sends the GetSiteVNETConnections request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteVNETConnectionsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteVNETConnectionsResponder handles the response to the GetSiteVNETConnections request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteVNETConnectionsResponder(resp *http.Response) (result VnetInfoList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteVNETConnectionSlot sends the get site vnet connection slot request. +// +// resourceGroupName is the resource group name name is the name of the web +// app vnetName is the name of the Virtual Network slot is the name of the +// slot for this web app. +func (client SitesClient) GetSiteVNETConnectionSlot(resourceGroupName string, name string, vnetName string, slot string) (result VnetInfo, ae error) { + req, err := client.GetSiteVNETConnectionSlotPreparer(resourceGroupName, name, vnetName, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVNETConnectionSlot", "Failure preparing request") + } + + resp, err := client.GetSiteVNETConnectionSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVNETConnectionSlot", "Failure sending request") + } + + result, err = client.GetSiteVNETConnectionSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVNETConnectionSlot", "Failure responding to request") + } + + return +} + +// GetSiteVNETConnectionSlotPreparer prepares the GetSiteVNETConnectionSlot request. +func (client SitesClient) GetSiteVNETConnectionSlotPreparer(resourceGroupName string, name string, vnetName string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/virtualNetworkConnections/{vnetName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteVNETConnectionSlotSender sends the GetSiteVNETConnectionSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteVNETConnectionSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteVNETConnectionSlotResponder handles the response to the GetSiteVNETConnectionSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteVNETConnectionSlotResponder(resp *http.Response) (result VnetInfo, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteVNETConnectionsSlot sends the get site vnet connections slot request. +// +// resourceGroupName is the resource group name name is the name of the web +// app slot is the name of the slot for this web app. +func (client SitesClient) GetSiteVNETConnectionsSlot(resourceGroupName string, name string, slot string) (result VnetInfoList, ae error) { + req, err := client.GetSiteVNETConnectionsSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVNETConnectionsSlot", "Failure preparing request") + } + + resp, err := client.GetSiteVNETConnectionsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVNETConnectionsSlot", "Failure sending request") + } + + result, err = client.GetSiteVNETConnectionsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVNETConnectionsSlot", "Failure responding to request") + } + + return +} + +// GetSiteVNETConnectionsSlotPreparer prepares the GetSiteVNETConnectionsSlot request. +func (client SitesClient) GetSiteVNETConnectionsSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/virtualNetworkConnections"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteVNETConnectionsSlotSender sends the GetSiteVNETConnectionsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteVNETConnectionsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSiteVNETConnectionsSlotResponder handles the response to the GetSiteVNETConnectionsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteVNETConnectionsSlotResponder(resp *http.Response) (result VnetInfoList, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteVnetGateway sends the get site vnet gateway request. +// +// resourceGroupName is the resource group name name is the name of the web +// app vnetName is the name of the Virtual Network gatewayName is the name of +// the gateway. The only gateway that exists presently is "primary" +func (client SitesClient) GetSiteVnetGateway(resourceGroupName string, name string, vnetName string, gatewayName string) (result ObjectSet, ae error) { + req, err := client.GetSiteVnetGatewayPreparer(resourceGroupName, name, vnetName, gatewayName) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVnetGateway", "Failure preparing request") + } + + resp, err := client.GetSiteVnetGatewaySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVnetGateway", "Failure sending request") + } + + result, err = client.GetSiteVnetGatewayResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVnetGateway", "Failure responding to request") + } + + return +} + +// GetSiteVnetGatewayPreparer prepares the GetSiteVnetGateway request. +func (client SitesClient) GetSiteVnetGatewayPreparer(resourceGroupName string, name string, vnetName string, gatewayName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "gatewayName": url.QueryEscape(gatewayName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/virtualNetworkConnections/{vnetName}/gateways/{gatewayName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteVnetGatewaySender sends the GetSiteVnetGateway request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteVnetGatewaySender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusNotFound) +} + +// GetSiteVnetGatewayResponder handles the response to the GetSiteVnetGateway request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteVnetGatewayResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNotFound), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSiteVnetGatewaySlot sends the get site vnet gateway slot request. +// +// resourceGroupName is the resource group name name is the name of the web +// app vnetName is the name of the Virtual Network gatewayName is the name of +// the gateway. The only gateway that exists presently is "primary" slot is +// the name of the slot for this web app. +func (client SitesClient) GetSiteVnetGatewaySlot(resourceGroupName string, name string, vnetName string, gatewayName string, slot string) (result ObjectSet, ae error) { + req, err := client.GetSiteVnetGatewaySlotPreparer(resourceGroupName, name, vnetName, gatewayName, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVnetGatewaySlot", "Failure preparing request") + } + + resp, err := client.GetSiteVnetGatewaySlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVnetGatewaySlot", "Failure sending request") + } + + result, err = client.GetSiteVnetGatewaySlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSiteVnetGatewaySlot", "Failure responding to request") + } + + return +} + +// GetSiteVnetGatewaySlotPreparer prepares the GetSiteVnetGatewaySlot request. +func (client SitesClient) GetSiteVnetGatewaySlotPreparer(resourceGroupName string, name string, vnetName string, gatewayName string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "gatewayName": url.QueryEscape(gatewayName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/virtualNetworkConnections/{vnetName}/gateways/{gatewayName}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSiteVnetGatewaySlotSender sends the GetSiteVnetGatewaySlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSiteVnetGatewaySlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusNotFound) +} + +// GetSiteVnetGatewaySlotResponder handles the response to the GetSiteVnetGatewaySlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSiteVnetGatewaySlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNotFound), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSlotConfigNames sends the get slot config names request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) GetSlotConfigNames(resourceGroupName string, name string) (result SlotConfigNamesResource, ae error) { + req, err := client.GetSlotConfigNamesPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSlotConfigNames", "Failure preparing request") + } + + resp, err := client.GetSlotConfigNamesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSlotConfigNames", "Failure sending request") + } + + result, err = client.GetSlotConfigNamesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSlotConfigNames", "Failure responding to request") + } + + return +} + +// GetSlotConfigNamesPreparer prepares the GetSlotConfigNames request. +func (client SitesClient) GetSlotConfigNamesPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/slotConfigNames"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSlotConfigNamesSender sends the GetSlotConfigNames request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSlotConfigNamesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSlotConfigNamesResponder handles the response to the GetSlotConfigNames request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSlotConfigNamesResponder(resp *http.Response) (result SlotConfigNamesResource, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSlotsDifferencesFromProduction sends the get slots differences from +// production request. +// +// resourceGroupName is name of resource group name is name of web app +// slotSwapEntity is request body that contains the target slot name +func (client SitesClient) GetSlotsDifferencesFromProduction(resourceGroupName string, name string, slotSwapEntity CsmSlotEntity) (result SlotDifferenceCollection, ae error) { + req, err := client.GetSlotsDifferencesFromProductionPreparer(resourceGroupName, name, slotSwapEntity) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSlotsDifferencesFromProduction", "Failure preparing request") + } + + resp, err := client.GetSlotsDifferencesFromProductionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSlotsDifferencesFromProduction", "Failure sending request") + } + + result, err = client.GetSlotsDifferencesFromProductionResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSlotsDifferencesFromProduction", "Failure responding to request") + } + + return +} + +// GetSlotsDifferencesFromProductionPreparer prepares the GetSlotsDifferencesFromProduction request. +func (client SitesClient) GetSlotsDifferencesFromProductionPreparer(resourceGroupName string, name string, slotSwapEntity CsmSlotEntity) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slotsdiffs"), + autorest.WithJSON(slotSwapEntity), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSlotsDifferencesFromProductionSender sends the GetSlotsDifferencesFromProduction request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSlotsDifferencesFromProductionSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSlotsDifferencesFromProductionResponder handles the response to the GetSlotsDifferencesFromProduction request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSlotsDifferencesFromProductionResponder(resp *http.Response) (result SlotDifferenceCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetSlotsDifferencesSlot sends the get slots differences slot request. +// +// resourceGroupName is name of resource group name is name of web app +// slotSwapEntity is request body that contains the target slot name slot is +// name of the source slot +func (client SitesClient) GetSlotsDifferencesSlot(resourceGroupName string, name string, slotSwapEntity CsmSlotEntity, slot string) (result SlotDifferenceCollection, ae error) { + req, err := client.GetSlotsDifferencesSlotPreparer(resourceGroupName, name, slotSwapEntity, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSlotsDifferencesSlot", "Failure preparing request") + } + + resp, err := client.GetSlotsDifferencesSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "GetSlotsDifferencesSlot", "Failure sending request") + } + + result, err = client.GetSlotsDifferencesSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "GetSlotsDifferencesSlot", "Failure responding to request") + } + + return +} + +// GetSlotsDifferencesSlotPreparer prepares the GetSlotsDifferencesSlot request. +func (client SitesClient) GetSlotsDifferencesSlotPreparer(resourceGroupName string, name string, slotSwapEntity CsmSlotEntity, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/slotsdiffs"), + autorest.WithJSON(slotSwapEntity), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetSlotsDifferencesSlotSender sends the GetSlotsDifferencesSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) GetSlotsDifferencesSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetSlotsDifferencesSlotResponder handles the response to the GetSlotsDifferencesSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) GetSlotsDifferencesSlotResponder(resp *http.Response) (result SlotDifferenceCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteAppSettings sends the list site app settings request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) ListSiteAppSettings(resourceGroupName string, name string) (result StringDictionary, ae error) { + req, err := client.ListSiteAppSettingsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteAppSettings", "Failure preparing request") + } + + resp, err := client.ListSiteAppSettingsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteAppSettings", "Failure sending request") + } + + result, err = client.ListSiteAppSettingsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteAppSettings", "Failure responding to request") + } + + return +} + +// ListSiteAppSettingsPreparer prepares the ListSiteAppSettings request. +func (client SitesClient) ListSiteAppSettingsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/appsettings/list"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteAppSettingsSender sends the ListSiteAppSettings request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteAppSettingsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteAppSettingsResponder handles the response to the ListSiteAppSettings request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteAppSettingsResponder(resp *http.Response) (result StringDictionary, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteAppSettingsSlot sends the list site app settings slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) ListSiteAppSettingsSlot(resourceGroupName string, name string, slot string) (result StringDictionary, ae error) { + req, err := client.ListSiteAppSettingsSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteAppSettingsSlot", "Failure preparing request") + } + + resp, err := client.ListSiteAppSettingsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteAppSettingsSlot", "Failure sending request") + } + + result, err = client.ListSiteAppSettingsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteAppSettingsSlot", "Failure responding to request") + } + + return +} + +// ListSiteAppSettingsSlotPreparer prepares the ListSiteAppSettingsSlot request. +func (client SitesClient) ListSiteAppSettingsSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/appsettings/list"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteAppSettingsSlotSender sends the ListSiteAppSettingsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteAppSettingsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteAppSettingsSlotResponder handles the response to the ListSiteAppSettingsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteAppSettingsSlotResponder(resp *http.Response) (result StringDictionary, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteAuthSettings sends the list site auth settings request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) ListSiteAuthSettings(resourceGroupName string, name string) (result SiteAuthSettings, ae error) { + req, err := client.ListSiteAuthSettingsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteAuthSettings", "Failure preparing request") + } + + resp, err := client.ListSiteAuthSettingsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteAuthSettings", "Failure sending request") + } + + result, err = client.ListSiteAuthSettingsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteAuthSettings", "Failure responding to request") + } + + return +} + +// ListSiteAuthSettingsPreparer prepares the ListSiteAuthSettings request. +func (client SitesClient) ListSiteAuthSettingsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/authsettings/list"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteAuthSettingsSender sends the ListSiteAuthSettings request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteAuthSettingsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteAuthSettingsResponder handles the response to the ListSiteAuthSettings request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteAuthSettingsResponder(resp *http.Response) (result SiteAuthSettings, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteAuthSettingsSlot sends the list site auth settings slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) ListSiteAuthSettingsSlot(resourceGroupName string, name string, slot string) (result SiteAuthSettings, ae error) { + req, err := client.ListSiteAuthSettingsSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteAuthSettingsSlot", "Failure preparing request") + } + + resp, err := client.ListSiteAuthSettingsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteAuthSettingsSlot", "Failure sending request") + } + + result, err = client.ListSiteAuthSettingsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteAuthSettingsSlot", "Failure responding to request") + } + + return +} + +// ListSiteAuthSettingsSlotPreparer prepares the ListSiteAuthSettingsSlot request. +func (client SitesClient) ListSiteAuthSettingsSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/authsettings/list"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteAuthSettingsSlotSender sends the ListSiteAuthSettingsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteAuthSettingsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteAuthSettingsSlotResponder handles the response to the ListSiteAuthSettingsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteAuthSettingsSlotResponder(resp *http.Response) (result SiteAuthSettings, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteBackupConfigurationDeprecated sends the list site backup +// configuration deprecated request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) ListSiteBackupConfigurationDeprecated(resourceGroupName string, name string) (result BackupRequest, ae error) { + req, err := client.ListSiteBackupConfigurationDeprecatedPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupConfigurationDeprecated", "Failure preparing request") + } + + resp, err := client.ListSiteBackupConfigurationDeprecatedSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupConfigurationDeprecated", "Failure sending request") + } + + result, err = client.ListSiteBackupConfigurationDeprecatedResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupConfigurationDeprecated", "Failure responding to request") + } + + return +} + +// ListSiteBackupConfigurationDeprecatedPreparer prepares the ListSiteBackupConfigurationDeprecated request. +func (client SitesClient) ListSiteBackupConfigurationDeprecatedPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/backup/config"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteBackupConfigurationDeprecatedSender sends the ListSiteBackupConfigurationDeprecated request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteBackupConfigurationDeprecatedSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteBackupConfigurationDeprecatedResponder handles the response to the ListSiteBackupConfigurationDeprecated request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteBackupConfigurationDeprecatedResponder(resp *http.Response) (result BackupRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteBackupConfigurationDeprecatedSlot sends the list site backup +// configuration deprecated slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) ListSiteBackupConfigurationDeprecatedSlot(resourceGroupName string, name string, slot string) (result BackupRequest, ae error) { + req, err := client.ListSiteBackupConfigurationDeprecatedSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupConfigurationDeprecatedSlot", "Failure preparing request") + } + + resp, err := client.ListSiteBackupConfigurationDeprecatedSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupConfigurationDeprecatedSlot", "Failure sending request") + } + + result, err = client.ListSiteBackupConfigurationDeprecatedSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupConfigurationDeprecatedSlot", "Failure responding to request") + } + + return +} + +// ListSiteBackupConfigurationDeprecatedSlotPreparer prepares the ListSiteBackupConfigurationDeprecatedSlot request. +func (client SitesClient) ListSiteBackupConfigurationDeprecatedSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/backup/config"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteBackupConfigurationDeprecatedSlotSender sends the ListSiteBackupConfigurationDeprecatedSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteBackupConfigurationDeprecatedSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteBackupConfigurationDeprecatedSlotResponder handles the response to the ListSiteBackupConfigurationDeprecatedSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteBackupConfigurationDeprecatedSlotResponder(resp *http.Response) (result BackupRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteBackups sends the list site backups request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) ListSiteBackups(resourceGroupName string, name string) (result BackupItemCollection, ae error) { + req, err := client.ListSiteBackupsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackups", "Failure preparing request") + } + + resp, err := client.ListSiteBackupsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackups", "Failure sending request") + } + + result, err = client.ListSiteBackupsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackups", "Failure responding to request") + } + + return +} + +// ListSiteBackupsPreparer prepares the ListSiteBackups request. +func (client SitesClient) ListSiteBackupsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/backups"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteBackupsSender sends the ListSiteBackups request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteBackupsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteBackupsResponder handles the response to the ListSiteBackups request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteBackupsResponder(resp *http.Response) (result BackupItemCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteBackupsDeprecated sends the list site backups deprecated request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) ListSiteBackupsDeprecated(resourceGroupName string, name string) (result BackupItemCollection, ae error) { + req, err := client.ListSiteBackupsDeprecatedPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupsDeprecated", "Failure preparing request") + } + + resp, err := client.ListSiteBackupsDeprecatedSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupsDeprecated", "Failure sending request") + } + + result, err = client.ListSiteBackupsDeprecatedResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupsDeprecated", "Failure responding to request") + } + + return +} + +// ListSiteBackupsDeprecatedPreparer prepares the ListSiteBackupsDeprecated request. +func (client SitesClient) ListSiteBackupsDeprecatedPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/restore"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteBackupsDeprecatedSender sends the ListSiteBackupsDeprecated request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteBackupsDeprecatedSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteBackupsDeprecatedResponder handles the response to the ListSiteBackupsDeprecated request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteBackupsDeprecatedResponder(resp *http.Response) (result BackupItemCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteBackupsDeprecatedSlot sends the list site backups deprecated slot +// request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) ListSiteBackupsDeprecatedSlot(resourceGroupName string, name string, slot string) (result BackupItemCollection, ae error) { + req, err := client.ListSiteBackupsDeprecatedSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupsDeprecatedSlot", "Failure preparing request") + } + + resp, err := client.ListSiteBackupsDeprecatedSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupsDeprecatedSlot", "Failure sending request") + } + + result, err = client.ListSiteBackupsDeprecatedSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupsDeprecatedSlot", "Failure responding to request") + } + + return +} + +// ListSiteBackupsDeprecatedSlotPreparer prepares the ListSiteBackupsDeprecatedSlot request. +func (client SitesClient) ListSiteBackupsDeprecatedSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/restore"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteBackupsDeprecatedSlotSender sends the ListSiteBackupsDeprecatedSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteBackupsDeprecatedSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteBackupsDeprecatedSlotResponder handles the response to the ListSiteBackupsDeprecatedSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteBackupsDeprecatedSlotResponder(resp *http.Response) (result BackupItemCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteBackupsSlot sends the list site backups slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) ListSiteBackupsSlot(resourceGroupName string, name string, slot string) (result BackupItemCollection, ae error) { + req, err := client.ListSiteBackupsSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupsSlot", "Failure preparing request") + } + + resp, err := client.ListSiteBackupsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupsSlot", "Failure sending request") + } + + result, err = client.ListSiteBackupsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteBackupsSlot", "Failure responding to request") + } + + return +} + +// ListSiteBackupsSlotPreparer prepares the ListSiteBackupsSlot request. +func (client SitesClient) ListSiteBackupsSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/backups"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteBackupsSlotSender sends the ListSiteBackupsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteBackupsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteBackupsSlotResponder handles the response to the ListSiteBackupsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteBackupsSlotResponder(resp *http.Response) (result BackupItemCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteConnectionStrings sends the list site connection strings request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) ListSiteConnectionStrings(resourceGroupName string, name string) (result ConnectionStringDictionary, ae error) { + req, err := client.ListSiteConnectionStringsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteConnectionStrings", "Failure preparing request") + } + + resp, err := client.ListSiteConnectionStringsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteConnectionStrings", "Failure sending request") + } + + result, err = client.ListSiteConnectionStringsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteConnectionStrings", "Failure responding to request") + } + + return +} + +// ListSiteConnectionStringsPreparer prepares the ListSiteConnectionStrings request. +func (client SitesClient) ListSiteConnectionStringsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/connectionstrings/list"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteConnectionStringsSender sends the ListSiteConnectionStrings request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteConnectionStringsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteConnectionStringsResponder handles the response to the ListSiteConnectionStrings request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteConnectionStringsResponder(resp *http.Response) (result ConnectionStringDictionary, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteConnectionStringsSlot sends the list site connection strings slot +// request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) ListSiteConnectionStringsSlot(resourceGroupName string, name string, slot string) (result ConnectionStringDictionary, ae error) { + req, err := client.ListSiteConnectionStringsSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteConnectionStringsSlot", "Failure preparing request") + } + + resp, err := client.ListSiteConnectionStringsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteConnectionStringsSlot", "Failure sending request") + } + + result, err = client.ListSiteConnectionStringsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteConnectionStringsSlot", "Failure responding to request") + } + + return +} + +// ListSiteConnectionStringsSlotPreparer prepares the ListSiteConnectionStringsSlot request. +func (client SitesClient) ListSiteConnectionStringsSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/connectionstrings/list"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteConnectionStringsSlotSender sends the ListSiteConnectionStringsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteConnectionStringsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteConnectionStringsSlotResponder handles the response to the ListSiteConnectionStringsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteConnectionStringsSlotResponder(resp *http.Response) (result ConnectionStringDictionary, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteMetadata sends the list site metadata request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) ListSiteMetadata(resourceGroupName string, name string) (result StringDictionary, ae error) { + req, err := client.ListSiteMetadataPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteMetadata", "Failure preparing request") + } + + resp, err := client.ListSiteMetadataSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteMetadata", "Failure sending request") + } + + result, err = client.ListSiteMetadataResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteMetadata", "Failure responding to request") + } + + return +} + +// ListSiteMetadataPreparer prepares the ListSiteMetadata request. +func (client SitesClient) ListSiteMetadataPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/metadata/list"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteMetadataSender sends the ListSiteMetadata request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteMetadataSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteMetadataResponder handles the response to the ListSiteMetadata request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteMetadataResponder(resp *http.Response) (result StringDictionary, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteMetadataSlot sends the list site metadata slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) ListSiteMetadataSlot(resourceGroupName string, name string, slot string) (result StringDictionary, ae error) { + req, err := client.ListSiteMetadataSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteMetadataSlot", "Failure preparing request") + } + + resp, err := client.ListSiteMetadataSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteMetadataSlot", "Failure sending request") + } + + result, err = client.ListSiteMetadataSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteMetadataSlot", "Failure responding to request") + } + + return +} + +// ListSiteMetadataSlotPreparer prepares the ListSiteMetadataSlot request. +func (client SitesClient) ListSiteMetadataSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/metadata/list"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteMetadataSlotSender sends the ListSiteMetadataSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteMetadataSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteMetadataSlotResponder handles the response to the ListSiteMetadataSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteMetadataSlotResponder(resp *http.Response) (result StringDictionary, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSitePremierAddOns sends the list site premier add ons request. +// +func (client SitesClient) ListSitePremierAddOns(resourceGroupName string, name string) (result ObjectSet, ae error) { + req, err := client.ListSitePremierAddOnsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePremierAddOns", "Failure preparing request") + } + + resp, err := client.ListSitePremierAddOnsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePremierAddOns", "Failure sending request") + } + + result, err = client.ListSitePremierAddOnsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePremierAddOns", "Failure responding to request") + } + + return +} + +// ListSitePremierAddOnsPreparer prepares the ListSitePremierAddOns request. +func (client SitesClient) ListSitePremierAddOnsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/premieraddons"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSitePremierAddOnsSender sends the ListSitePremierAddOns request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSitePremierAddOnsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSitePremierAddOnsResponder handles the response to the ListSitePremierAddOns request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSitePremierAddOnsResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSitePremierAddOnsSlot sends the list site premier add ons slot request. +// +func (client SitesClient) ListSitePremierAddOnsSlot(resourceGroupName string, name string, slot string) (result ObjectSet, ae error) { + req, err := client.ListSitePremierAddOnsSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePremierAddOnsSlot", "Failure preparing request") + } + + resp, err := client.ListSitePremierAddOnsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePremierAddOnsSlot", "Failure sending request") + } + + result, err = client.ListSitePremierAddOnsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePremierAddOnsSlot", "Failure responding to request") + } + + return +} + +// ListSitePremierAddOnsSlotPreparer prepares the ListSitePremierAddOnsSlot request. +func (client SitesClient) ListSitePremierAddOnsSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/premieraddons"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSitePremierAddOnsSlotSender sends the ListSitePremierAddOnsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSitePremierAddOnsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSitePremierAddOnsSlotResponder handles the response to the ListSitePremierAddOnsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSitePremierAddOnsSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSitePublishingCredentials sends the list site publishing credentials +// request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) ListSitePublishingCredentials(resourceGroupName string, name string) (result User, ae error) { + req, err := client.ListSitePublishingCredentialsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePublishingCredentials", "Failure preparing request") + } + + resp, err := client.ListSitePublishingCredentialsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePublishingCredentials", "Failure sending request") + } + + result, err = client.ListSitePublishingCredentialsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePublishingCredentials", "Failure responding to request") + } + + return +} + +// ListSitePublishingCredentialsPreparer prepares the ListSitePublishingCredentials request. +func (client SitesClient) ListSitePublishingCredentialsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/publishingcredentials/list"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSitePublishingCredentialsSender sends the ListSitePublishingCredentials request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSitePublishingCredentialsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSitePublishingCredentialsResponder handles the response to the ListSitePublishingCredentials request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSitePublishingCredentialsResponder(resp *http.Response) (result User, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSitePublishingCredentialsSlot sends the list site publishing +// credentials slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) ListSitePublishingCredentialsSlot(resourceGroupName string, name string, slot string) (result User, ae error) { + req, err := client.ListSitePublishingCredentialsSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePublishingCredentialsSlot", "Failure preparing request") + } + + resp, err := client.ListSitePublishingCredentialsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePublishingCredentialsSlot", "Failure sending request") + } + + result, err = client.ListSitePublishingCredentialsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePublishingCredentialsSlot", "Failure responding to request") + } + + return +} + +// ListSitePublishingCredentialsSlotPreparer prepares the ListSitePublishingCredentialsSlot request. +func (client SitesClient) ListSitePublishingCredentialsSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/publishingcredentials/list"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSitePublishingCredentialsSlotSender sends the ListSitePublishingCredentialsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSitePublishingCredentialsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSitePublishingCredentialsSlotResponder handles the response to the ListSitePublishingCredentialsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSitePublishingCredentialsSlotResponder(resp *http.Response) (result User, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSitePublishingProfileXML sends the list site publishing profile xml +// request. +// +// resourceGroupName is name of resource group name is name of web app options +// is specifies options for publishing profile. Pass +// CsmPublishingProfileOptions.Format=FileZilla3 for FileZilla FTP format. +func (client SitesClient) ListSitePublishingProfileXML(resourceGroupName string, name string, options CsmPublishingProfileOptions) (result autorest.Response, ae error) { + req, err := client.ListSitePublishingProfileXMLPreparer(resourceGroupName, name, options) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePublishingProfileXML", "Failure preparing request") + } + + resp, err := client.ListSitePublishingProfileXMLSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePublishingProfileXML", "Failure sending request") + } + + result, err = client.ListSitePublishingProfileXMLResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePublishingProfileXML", "Failure responding to request") + } + + return +} + +// ListSitePublishingProfileXMLPreparer prepares the ListSitePublishingProfileXML request. +func (client SitesClient) ListSitePublishingProfileXMLPreparer(resourceGroupName string, name string, options CsmPublishingProfileOptions) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/publishxml"), + autorest.WithJSON(options), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSitePublishingProfileXMLSender sends the ListSitePublishingProfileXML request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSitePublishingProfileXMLSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSitePublishingProfileXMLResponder handles the response to the ListSitePublishingProfileXML request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSitePublishingProfileXMLResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK)) + result.Response = resp + return +} + +// ListSitePublishingProfileXMLSlot sends the list site publishing profile xml +// slot request. +// +// resourceGroupName is name of resource group name is name of web app options +// is specifies options for publishing profile. Pass +// CsmPublishingProfileOptions.Format=FileZilla3 for FileZilla FTP format. +// slot is name of web app slot. If not specified then will default to +// production slot. +func (client SitesClient) ListSitePublishingProfileXMLSlot(resourceGroupName string, name string, options CsmPublishingProfileOptions, slot string) (result autorest.Response, ae error) { + req, err := client.ListSitePublishingProfileXMLSlotPreparer(resourceGroupName, name, options, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePublishingProfileXMLSlot", "Failure preparing request") + } + + resp, err := client.ListSitePublishingProfileXMLSlotSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePublishingProfileXMLSlot", "Failure sending request") + } + + result, err = client.ListSitePublishingProfileXMLSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSitePublishingProfileXMLSlot", "Failure responding to request") + } + + return +} + +// ListSitePublishingProfileXMLSlotPreparer prepares the ListSitePublishingProfileXMLSlot request. +func (client SitesClient) ListSitePublishingProfileXMLSlotPreparer(resourceGroupName string, name string, options CsmPublishingProfileOptions, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/publishxml"), + autorest.WithJSON(options), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSitePublishingProfileXMLSlotSender sends the ListSitePublishingProfileXMLSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSitePublishingProfileXMLSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSitePublishingProfileXMLSlotResponder handles the response to the ListSitePublishingProfileXMLSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSitePublishingProfileXMLSlotResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK)) + result.Response = resp + return +} + +// ListSiteRelayServiceConnections sends the list site relay service +// connections request. +// +// resourceGroupName is the resource group name name is the name of the web +// app +func (client SitesClient) ListSiteRelayServiceConnections(resourceGroupName string, name string) (result RelayServiceConnectionEntity, ae error) { + req, err := client.ListSiteRelayServiceConnectionsPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteRelayServiceConnections", "Failure preparing request") + } + + resp, err := client.ListSiteRelayServiceConnectionsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteRelayServiceConnections", "Failure sending request") + } + + result, err = client.ListSiteRelayServiceConnectionsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteRelayServiceConnections", "Failure responding to request") + } + + return +} + +// ListSiteRelayServiceConnectionsPreparer prepares the ListSiteRelayServiceConnections request. +func (client SitesClient) ListSiteRelayServiceConnectionsPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/hybridconnection"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteRelayServiceConnectionsSender sends the ListSiteRelayServiceConnections request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteRelayServiceConnectionsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteRelayServiceConnectionsResponder handles the response to the ListSiteRelayServiceConnections request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteRelayServiceConnectionsResponder(resp *http.Response) (result RelayServiceConnectionEntity, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListSiteRelayServiceConnectionsSlot sends the list site relay service +// connections slot request. +// +// resourceGroupName is the resource group name name is the name of the web +// app slot is the name of the slot for the web app. +func (client SitesClient) ListSiteRelayServiceConnectionsSlot(resourceGroupName string, name string, slot string) (result RelayServiceConnectionEntity, ae error) { + req, err := client.ListSiteRelayServiceConnectionsSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteRelayServiceConnectionsSlot", "Failure preparing request") + } + + resp, err := client.ListSiteRelayServiceConnectionsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteRelayServiceConnectionsSlot", "Failure sending request") + } + + result, err = client.ListSiteRelayServiceConnectionsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ListSiteRelayServiceConnectionsSlot", "Failure responding to request") + } + + return +} + +// ListSiteRelayServiceConnectionsSlotPreparer prepares the ListSiteRelayServiceConnectionsSlot request. +func (client SitesClient) ListSiteRelayServiceConnectionsSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/hybridconnection"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListSiteRelayServiceConnectionsSlotSender sends the ListSiteRelayServiceConnectionsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ListSiteRelayServiceConnectionsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListSiteRelayServiceConnectionsSlotResponder handles the response to the ListSiteRelayServiceConnectionsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) ListSiteRelayServiceConnectionsSlotResponder(resp *http.Response) (result RelayServiceConnectionEntity, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// RecoverSite sends the recover site request. +// +// resourceGroupName is name of resource group name is name of web app +// snapshot is snapshot data used for web app recovery. Snapshot information +// can be obtained by call GetDeletedSites API. +func (client SitesClient) RecoverSite(resourceGroupName string, name string, snapshot CsmSiteRecoveryEntity) (result ObjectSet, ae error) { + req, err := client.RecoverSitePreparer(resourceGroupName, name, snapshot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "RecoverSite", "Failure preparing request") + } + + resp, err := client.RecoverSiteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "RecoverSite", "Failure sending request") + } + + result, err = client.RecoverSiteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "RecoverSite", "Failure responding to request") + } + + return +} + +// RecoverSitePreparer prepares the RecoverSite request. +func (client SitesClient) RecoverSitePreparer(resourceGroupName string, name string, snapshot CsmSiteRecoveryEntity) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/recover"), + autorest.WithJSON(snapshot), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// RecoverSiteSender sends the RecoverSite request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) RecoverSiteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// RecoverSiteResponder handles the response to the RecoverSite request. The method always +// closes the http.Response Body. +func (client SitesClient) RecoverSiteResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// RecoverSiteSlot sends the recover site slot request. +// +// resourceGroupName is name of resource group name is name of web app +// snapshot is snapshot data used for web app recovery. Snapshot information +// can be obtained by call GetDeletedSites API. slot is name of web app slot. +// If not specified then will default to production slot. +func (client SitesClient) RecoverSiteSlot(resourceGroupName string, name string, snapshot CsmSiteRecoveryEntity, slot string) (result ObjectSet, ae error) { + req, err := client.RecoverSiteSlotPreparer(resourceGroupName, name, snapshot, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "RecoverSiteSlot", "Failure preparing request") + } + + resp, err := client.RecoverSiteSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "RecoverSiteSlot", "Failure sending request") + } + + result, err = client.RecoverSiteSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "RecoverSiteSlot", "Failure responding to request") + } + + return +} + +// RecoverSiteSlotPreparer prepares the RecoverSiteSlot request. +func (client SitesClient) RecoverSiteSlotPreparer(resourceGroupName string, name string, snapshot CsmSiteRecoveryEntity, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/recover"), + autorest.WithJSON(snapshot), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// RecoverSiteSlotSender sends the RecoverSiteSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) RecoverSiteSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// RecoverSiteSlotResponder handles the response to the RecoverSiteSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) RecoverSiteSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ResetProductionSlotConfig sends the reset production slot config request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) ResetProductionSlotConfig(resourceGroupName string, name string) (result ObjectSet, ae error) { + req, err := client.ResetProductionSlotConfigPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ResetProductionSlotConfig", "Failure preparing request") + } + + resp, err := client.ResetProductionSlotConfigSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ResetProductionSlotConfig", "Failure sending request") + } + + result, err = client.ResetProductionSlotConfigResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ResetProductionSlotConfig", "Failure responding to request") + } + + return +} + +// ResetProductionSlotConfigPreparer prepares the ResetProductionSlotConfig request. +func (client SitesClient) ResetProductionSlotConfigPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/resetSlotConfig"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ResetProductionSlotConfigSender sends the ResetProductionSlotConfig request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ResetProductionSlotConfigSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ResetProductionSlotConfigResponder handles the response to the ResetProductionSlotConfig request. The method always +// closes the http.Response Body. +func (client SitesClient) ResetProductionSlotConfigResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ResetSlotConfigSlot sends the reset slot config slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) ResetSlotConfigSlot(resourceGroupName string, name string, slot string) (result ObjectSet, ae error) { + req, err := client.ResetSlotConfigSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ResetSlotConfigSlot", "Failure preparing request") + } + + resp, err := client.ResetSlotConfigSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "ResetSlotConfigSlot", "Failure sending request") + } + + result, err = client.ResetSlotConfigSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "ResetSlotConfigSlot", "Failure responding to request") + } + + return +} + +// ResetSlotConfigSlotPreparer prepares the ResetSlotConfigSlot request. +func (client SitesClient) ResetSlotConfigSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/resetSlotConfig"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ResetSlotConfigSlotSender sends the ResetSlotConfigSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) ResetSlotConfigSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ResetSlotConfigSlotResponder handles the response to the ResetSlotConfigSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) ResetSlotConfigSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// RestartSite sends the restart site request. +// +// resourceGroupName is name of resource group name is name of web app +// softRestart is soft restart applies the configuration settings and +// restarts the app if necessary. Hard restart always restarts and +// reprovisions the app synchronous is if true then the API will block until +// the app has been restarted +func (client SitesClient) RestartSite(resourceGroupName string, name string, softRestart *bool, synchronous *bool) (result ObjectSet, ae error) { + req, err := client.RestartSitePreparer(resourceGroupName, name, softRestart, synchronous) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "RestartSite", "Failure preparing request") + } + + resp, err := client.RestartSiteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "RestartSite", "Failure sending request") + } + + result, err = client.RestartSiteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "RestartSite", "Failure responding to request") + } + + return +} + +// RestartSitePreparer prepares the RestartSite request. +func (client SitesClient) RestartSitePreparer(resourceGroupName string, name string, softRestart *bool, synchronous *bool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if softRestart != nil { + queryParameters["softRestart"] = softRestart + } + if synchronous != nil { + queryParameters["synchronous"] = synchronous + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/restart"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// RestartSiteSender sends the RestartSite request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) RestartSiteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// RestartSiteResponder handles the response to the RestartSite request. The method always +// closes the http.Response Body. +func (client SitesClient) RestartSiteResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// RestartSiteSlot sends the restart site slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. softRestart is soft restart applies the configuration settings and +// restarts the app if necessary. Hard restart always restarts and +// reprovisions the app synchronous is if true then the API will block until +// the app has been restarted +func (client SitesClient) RestartSiteSlot(resourceGroupName string, name string, slot string, softRestart *bool, synchronous *bool) (result ObjectSet, ae error) { + req, err := client.RestartSiteSlotPreparer(resourceGroupName, name, slot, softRestart, synchronous) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "RestartSiteSlot", "Failure preparing request") + } + + resp, err := client.RestartSiteSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "RestartSiteSlot", "Failure sending request") + } + + result, err = client.RestartSiteSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "RestartSiteSlot", "Failure responding to request") + } + + return +} + +// RestartSiteSlotPreparer prepares the RestartSiteSlot request. +func (client SitesClient) RestartSiteSlotPreparer(resourceGroupName string, name string, slot string, softRestart *bool, synchronous *bool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if softRestart != nil { + queryParameters["softRestart"] = softRestart + } + if synchronous != nil { + queryParameters["synchronous"] = synchronous + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/restart"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// RestartSiteSlotSender sends the RestartSiteSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) RestartSiteSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// RestartSiteSlotResponder handles the response to the RestartSiteSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) RestartSiteSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// RestoreSite sends the restore site request. +// +// resourceGroupName is name of resource group name is name of web app +// backupID is id of backup to restore request is information on restore +// request +func (client SitesClient) RestoreSite(resourceGroupName string, name string, backupID string, request RestoreRequest) (result RestoreResponse, ae error) { + req, err := client.RestoreSitePreparer(resourceGroupName, name, backupID, request) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "RestoreSite", "Failure preparing request") + } + + resp, err := client.RestoreSiteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "RestoreSite", "Failure sending request") + } + + result, err = client.RestoreSiteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "RestoreSite", "Failure responding to request") + } + + return +} + +// RestoreSitePreparer prepares the RestoreSite request. +func (client SitesClient) RestoreSitePreparer(resourceGroupName string, name string, backupID string, request RestoreRequest) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "backupId": url.QueryEscape(backupID), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/backups/{backupId}/restore"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// RestoreSiteSender sends the RestoreSite request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) RestoreSiteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// RestoreSiteResponder handles the response to the RestoreSite request. The method always +// closes the http.Response Body. +func (client SitesClient) RestoreSiteResponder(resp *http.Response) (result RestoreResponse, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// RestoreSiteSlot sends the restore site slot request. +// +// resourceGroupName is name of resource group name is name of web app +// backupID is id of backup to restore request is information on restore +// request slot is name of web app slot. If not specified then will default +// to production slot. +func (client SitesClient) RestoreSiteSlot(resourceGroupName string, name string, backupID string, request RestoreRequest, slot string) (result RestoreResponse, ae error) { + req, err := client.RestoreSiteSlotPreparer(resourceGroupName, name, backupID, request, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "RestoreSiteSlot", "Failure preparing request") + } + + resp, err := client.RestoreSiteSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "RestoreSiteSlot", "Failure sending request") + } + + result, err = client.RestoreSiteSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "RestoreSiteSlot", "Failure responding to request") + } + + return +} + +// RestoreSiteSlotPreparer prepares the RestoreSiteSlot request. +func (client SitesClient) RestoreSiteSlotPreparer(resourceGroupName string, name string, backupID string, request RestoreRequest, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "backupId": url.QueryEscape(backupID), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/backups/{backupId}/restore"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// RestoreSiteSlotSender sends the RestoreSiteSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) RestoreSiteSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// RestoreSiteSlotResponder handles the response to the RestoreSiteSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) RestoreSiteSlotResponder(resp *http.Response) (result RestoreResponse, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// StartSite sends the start site request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) StartSite(resourceGroupName string, name string) (result ObjectSet, ae error) { + req, err := client.StartSitePreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "StartSite", "Failure preparing request") + } + + resp, err := client.StartSiteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "StartSite", "Failure sending request") + } + + result, err = client.StartSiteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "StartSite", "Failure responding to request") + } + + return +} + +// StartSitePreparer prepares the StartSite request. +func (client SitesClient) StartSitePreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/start"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// StartSiteSender sends the StartSite request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) StartSiteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// StartSiteResponder handles the response to the StartSite request. The method always +// closes the http.Response Body. +func (client SitesClient) StartSiteResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// StartSiteSlot sends the start site slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) StartSiteSlot(resourceGroupName string, name string, slot string) (result ObjectSet, ae error) { + req, err := client.StartSiteSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "StartSiteSlot", "Failure preparing request") + } + + resp, err := client.StartSiteSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "StartSiteSlot", "Failure sending request") + } + + result, err = client.StartSiteSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "StartSiteSlot", "Failure responding to request") + } + + return +} + +// StartSiteSlotPreparer prepares the StartSiteSlot request. +func (client SitesClient) StartSiteSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/start"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// StartSiteSlotSender sends the StartSiteSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) StartSiteSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// StartSiteSlotResponder handles the response to the StartSiteSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) StartSiteSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// StopSite sends the stop site request. +// +// resourceGroupName is name of resource group name is name of web app +func (client SitesClient) StopSite(resourceGroupName string, name string) (result ObjectSet, ae error) { + req, err := client.StopSitePreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "StopSite", "Failure preparing request") + } + + resp, err := client.StopSiteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "StopSite", "Failure sending request") + } + + result, err = client.StopSiteResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "StopSite", "Failure responding to request") + } + + return +} + +// StopSitePreparer prepares the StopSite request. +func (client SitesClient) StopSitePreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/stop"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// StopSiteSender sends the StopSite request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) StopSiteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// StopSiteResponder handles the response to the StopSite request. The method always +// closes the http.Response Body. +func (client SitesClient) StopSiteResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// StopSiteSlot sends the stop site slot request. +// +// resourceGroupName is name of resource group name is name of web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) StopSiteSlot(resourceGroupName string, name string, slot string) (result ObjectSet, ae error) { + req, err := client.StopSiteSlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "StopSiteSlot", "Failure preparing request") + } + + resp, err := client.StopSiteSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "StopSiteSlot", "Failure sending request") + } + + result, err = client.StopSiteSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "StopSiteSlot", "Failure responding to request") + } + + return +} + +// StopSiteSlotPreparer prepares the StopSiteSlot request. +func (client SitesClient) StopSiteSlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/stop"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// StopSiteSlotSender sends the StopSiteSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) StopSiteSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// StopSiteSlotResponder handles the response to the StopSiteSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) StopSiteSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// SwapSlotsSlot sends the swap slots slot request. +// +// resourceGroupName is name of resource group name is name of web app +// slotSwapEntity is request body that contains the target slot name slot is +// name of source slot for the swap +func (client SitesClient) SwapSlotsSlot(resourceGroupName string, name string, slotSwapEntity CsmSlotEntity, slot string) (result ObjectSet, ae error) { + req, err := client.SwapSlotsSlotPreparer(resourceGroupName, name, slotSwapEntity, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "SwapSlotsSlot", "Failure preparing request") + } + + resp, err := client.SwapSlotsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "SwapSlotsSlot", "Failure sending request") + } + + result, err = client.SwapSlotsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "SwapSlotsSlot", "Failure responding to request") + } + + return +} + +// SwapSlotsSlotPreparer prepares the SwapSlotsSlot request. +func (client SitesClient) SwapSlotsSlotPreparer(resourceGroupName string, name string, slotSwapEntity CsmSlotEntity, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/slotsswap"), + autorest.WithJSON(slotSwapEntity), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// SwapSlotsSlotSender sends the SwapSlotsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) SwapSlotsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// SwapSlotsSlotResponder handles the response to the SwapSlotsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) SwapSlotsSlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// SwapSlotWithProduction sends the swap slot with production request. +// +// resourceGroupName is name of resource group name is name of web app +// slotSwapEntity is request body that contains the target slot name +func (client SitesClient) SwapSlotWithProduction(resourceGroupName string, name string, slotSwapEntity CsmSlotEntity) (result ObjectSet, ae error) { + req, err := client.SwapSlotWithProductionPreparer(resourceGroupName, name, slotSwapEntity) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "SwapSlotWithProduction", "Failure preparing request") + } + + resp, err := client.SwapSlotWithProductionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "SwapSlotWithProduction", "Failure sending request") + } + + result, err = client.SwapSlotWithProductionResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "SwapSlotWithProduction", "Failure responding to request") + } + + return +} + +// SwapSlotWithProductionPreparer prepares the SwapSlotWithProduction request. +func (client SitesClient) SwapSlotWithProductionPreparer(resourceGroupName string, name string, slotSwapEntity CsmSlotEntity) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slotsswap"), + autorest.WithJSON(slotSwapEntity), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// SwapSlotWithProductionSender sends the SwapSlotWithProduction request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) SwapSlotWithProductionSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK, http.StatusAccepted) +} + +// SwapSlotWithProductionResponder handles the response to the SwapSlotWithProduction request. The method always +// closes the http.Response Body. +func (client SitesClient) SwapSlotWithProductionResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// SyncSiteRepository sends the sync site repository request. +// +func (client SitesClient) SyncSiteRepository(resourceGroupName string, name string) (result ObjectSet, ae error) { + req, err := client.SyncSiteRepositoryPreparer(resourceGroupName, name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "SyncSiteRepository", "Failure preparing request") + } + + resp, err := client.SyncSiteRepositorySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "SyncSiteRepository", "Failure sending request") + } + + result, err = client.SyncSiteRepositoryResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "SyncSiteRepository", "Failure responding to request") + } + + return +} + +// SyncSiteRepositoryPreparer prepares the SyncSiteRepository request. +func (client SitesClient) SyncSiteRepositoryPreparer(resourceGroupName string, name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/sync"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// SyncSiteRepositorySender sends the SyncSiteRepository request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) SyncSiteRepositorySender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// SyncSiteRepositoryResponder handles the response to the SyncSiteRepository request. The method always +// closes the http.Response Body. +func (client SitesClient) SyncSiteRepositoryResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// SyncSiteRepositorySlot sends the sync site repository slot request. +// +func (client SitesClient) SyncSiteRepositorySlot(resourceGroupName string, name string, slot string) (result ObjectSet, ae error) { + req, err := client.SyncSiteRepositorySlotPreparer(resourceGroupName, name, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "SyncSiteRepositorySlot", "Failure preparing request") + } + + resp, err := client.SyncSiteRepositorySlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "SyncSiteRepositorySlot", "Failure sending request") + } + + result, err = client.SyncSiteRepositorySlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "SyncSiteRepositorySlot", "Failure responding to request") + } + + return +} + +// SyncSiteRepositorySlotPreparer prepares the SyncSiteRepositorySlot request. +func (client SitesClient) SyncSiteRepositorySlotPreparer(resourceGroupName string, name string, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/sync"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// SyncSiteRepositorySlotSender sends the SyncSiteRepositorySlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) SyncSiteRepositorySlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// SyncSiteRepositorySlotResponder handles the response to the SyncSiteRepositorySlot request. The method always +// closes the http.Response Body. +func (client SitesClient) SyncSiteRepositorySlotResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteAppSettings sends the update site app settings request. +// +// resourceGroupName is name of resource group name is name of web app +// appSettings is application settings of web app +func (client SitesClient) UpdateSiteAppSettings(resourceGroupName string, name string, appSettings StringDictionary) (result StringDictionary, ae error) { + req, err := client.UpdateSiteAppSettingsPreparer(resourceGroupName, name, appSettings) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteAppSettings", "Failure preparing request") + } + + resp, err := client.UpdateSiteAppSettingsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteAppSettings", "Failure sending request") + } + + result, err = client.UpdateSiteAppSettingsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteAppSettings", "Failure responding to request") + } + + return +} + +// UpdateSiteAppSettingsPreparer prepares the UpdateSiteAppSettings request. +func (client SitesClient) UpdateSiteAppSettingsPreparer(resourceGroupName string, name string, appSettings StringDictionary) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/appsettings"), + autorest.WithJSON(appSettings), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteAppSettingsSender sends the UpdateSiteAppSettings request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteAppSettingsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteAppSettingsResponder handles the response to the UpdateSiteAppSettings request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteAppSettingsResponder(resp *http.Response) (result StringDictionary, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteAppSettingsSlot sends the update site app settings slot request. +// +// resourceGroupName is name of resource group name is name of web app +// appSettings is application settings of web app slot is name of web app +// slot. If not specified then will default to production slot. +func (client SitesClient) UpdateSiteAppSettingsSlot(resourceGroupName string, name string, appSettings StringDictionary, slot string) (result StringDictionary, ae error) { + req, err := client.UpdateSiteAppSettingsSlotPreparer(resourceGroupName, name, appSettings, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteAppSettingsSlot", "Failure preparing request") + } + + resp, err := client.UpdateSiteAppSettingsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteAppSettingsSlot", "Failure sending request") + } + + result, err = client.UpdateSiteAppSettingsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteAppSettingsSlot", "Failure responding to request") + } + + return +} + +// UpdateSiteAppSettingsSlotPreparer prepares the UpdateSiteAppSettingsSlot request. +func (client SitesClient) UpdateSiteAppSettingsSlotPreparer(resourceGroupName string, name string, appSettings StringDictionary, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/appsettings"), + autorest.WithJSON(appSettings), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteAppSettingsSlotSender sends the UpdateSiteAppSettingsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteAppSettingsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteAppSettingsSlotResponder handles the response to the UpdateSiteAppSettingsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteAppSettingsSlotResponder(resp *http.Response) (result StringDictionary, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteAuthSettings sends the update site auth settings request. +// +// resourceGroupName is name of resource group name is name of web app +// siteAuthSettings is auth settings associated with web app +func (client SitesClient) UpdateSiteAuthSettings(resourceGroupName string, name string, siteAuthSettings SiteAuthSettings) (result SiteAuthSettings, ae error) { + req, err := client.UpdateSiteAuthSettingsPreparer(resourceGroupName, name, siteAuthSettings) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteAuthSettings", "Failure preparing request") + } + + resp, err := client.UpdateSiteAuthSettingsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteAuthSettings", "Failure sending request") + } + + result, err = client.UpdateSiteAuthSettingsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteAuthSettings", "Failure responding to request") + } + + return +} + +// UpdateSiteAuthSettingsPreparer prepares the UpdateSiteAuthSettings request. +func (client SitesClient) UpdateSiteAuthSettingsPreparer(resourceGroupName string, name string, siteAuthSettings SiteAuthSettings) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/authsettings"), + autorest.WithJSON(siteAuthSettings), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteAuthSettingsSender sends the UpdateSiteAuthSettings request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteAuthSettingsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteAuthSettingsResponder handles the response to the UpdateSiteAuthSettings request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteAuthSettingsResponder(resp *http.Response) (result SiteAuthSettings, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteAuthSettingsSlot sends the update site auth settings slot request. +// +// resourceGroupName is name of resource group name is name of web app +// siteAuthSettings is auth settings associated with web app slot is name of +// web app slot. If not specified then will default to production slot. +func (client SitesClient) UpdateSiteAuthSettingsSlot(resourceGroupName string, name string, siteAuthSettings SiteAuthSettings, slot string) (result SiteAuthSettings, ae error) { + req, err := client.UpdateSiteAuthSettingsSlotPreparer(resourceGroupName, name, siteAuthSettings, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteAuthSettingsSlot", "Failure preparing request") + } + + resp, err := client.UpdateSiteAuthSettingsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteAuthSettingsSlot", "Failure sending request") + } + + result, err = client.UpdateSiteAuthSettingsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteAuthSettingsSlot", "Failure responding to request") + } + + return +} + +// UpdateSiteAuthSettingsSlotPreparer prepares the UpdateSiteAuthSettingsSlot request. +func (client SitesClient) UpdateSiteAuthSettingsSlotPreparer(resourceGroupName string, name string, siteAuthSettings SiteAuthSettings, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/authsettings"), + autorest.WithJSON(siteAuthSettings), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteAuthSettingsSlotSender sends the UpdateSiteAuthSettingsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteAuthSettingsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteAuthSettingsSlotResponder handles the response to the UpdateSiteAuthSettingsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteAuthSettingsSlotResponder(resp *http.Response) (result SiteAuthSettings, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteBackupConfiguration sends the update site backup configuration +// request. +// +// resourceGroupName is name of resource group name is name of web app request +// is information on backup request +func (client SitesClient) UpdateSiteBackupConfiguration(resourceGroupName string, name string, request BackupRequest) (result BackupRequest, ae error) { + req, err := client.UpdateSiteBackupConfigurationPreparer(resourceGroupName, name, request) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteBackupConfiguration", "Failure preparing request") + } + + resp, err := client.UpdateSiteBackupConfigurationSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteBackupConfiguration", "Failure sending request") + } + + result, err = client.UpdateSiteBackupConfigurationResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteBackupConfiguration", "Failure responding to request") + } + + return +} + +// UpdateSiteBackupConfigurationPreparer prepares the UpdateSiteBackupConfiguration request. +func (client SitesClient) UpdateSiteBackupConfigurationPreparer(resourceGroupName string, name string, request BackupRequest) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/backup"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteBackupConfigurationSender sends the UpdateSiteBackupConfiguration request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteBackupConfigurationSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteBackupConfigurationResponder handles the response to the UpdateSiteBackupConfiguration request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteBackupConfigurationResponder(resp *http.Response) (result BackupRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteBackupConfigurationDeprecated sends the update site backup +// configuration deprecated request. +// +// resourceGroupName is name of resource group name is name of web app request +// is information on backup request +func (client SitesClient) UpdateSiteBackupConfigurationDeprecated(resourceGroupName string, name string, request BackupRequest) (result BackupRequest, ae error) { + req, err := client.UpdateSiteBackupConfigurationDeprecatedPreparer(resourceGroupName, name, request) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteBackupConfigurationDeprecated", "Failure preparing request") + } + + resp, err := client.UpdateSiteBackupConfigurationDeprecatedSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteBackupConfigurationDeprecated", "Failure sending request") + } + + result, err = client.UpdateSiteBackupConfigurationDeprecatedResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteBackupConfigurationDeprecated", "Failure responding to request") + } + + return +} + +// UpdateSiteBackupConfigurationDeprecatedPreparer prepares the UpdateSiteBackupConfigurationDeprecated request. +func (client SitesClient) UpdateSiteBackupConfigurationDeprecatedPreparer(resourceGroupName string, name string, request BackupRequest) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/backup/config"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteBackupConfigurationDeprecatedSender sends the UpdateSiteBackupConfigurationDeprecated request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteBackupConfigurationDeprecatedSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteBackupConfigurationDeprecatedResponder handles the response to the UpdateSiteBackupConfigurationDeprecated request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteBackupConfigurationDeprecatedResponder(resp *http.Response) (result BackupRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteBackupConfigurationDeprecatedSlot sends the update site backup +// configuration deprecated slot request. +// +// resourceGroupName is name of resource group name is name of web app request +// is information on backup request slot is name of web app slot. If not +// specified then will default to production slot. +func (client SitesClient) UpdateSiteBackupConfigurationDeprecatedSlot(resourceGroupName string, name string, request BackupRequest, slot string) (result BackupRequest, ae error) { + req, err := client.UpdateSiteBackupConfigurationDeprecatedSlotPreparer(resourceGroupName, name, request, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteBackupConfigurationDeprecatedSlot", "Failure preparing request") + } + + resp, err := client.UpdateSiteBackupConfigurationDeprecatedSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteBackupConfigurationDeprecatedSlot", "Failure sending request") + } + + result, err = client.UpdateSiteBackupConfigurationDeprecatedSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteBackupConfigurationDeprecatedSlot", "Failure responding to request") + } + + return +} + +// UpdateSiteBackupConfigurationDeprecatedSlotPreparer prepares the UpdateSiteBackupConfigurationDeprecatedSlot request. +func (client SitesClient) UpdateSiteBackupConfigurationDeprecatedSlotPreparer(resourceGroupName string, name string, request BackupRequest, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/backup/config"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteBackupConfigurationDeprecatedSlotSender sends the UpdateSiteBackupConfigurationDeprecatedSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteBackupConfigurationDeprecatedSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteBackupConfigurationDeprecatedSlotResponder handles the response to the UpdateSiteBackupConfigurationDeprecatedSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteBackupConfigurationDeprecatedSlotResponder(resp *http.Response) (result BackupRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteBackupConfigurationSlot sends the update site backup +// configuration slot request. +// +// resourceGroupName is name of resource group name is name of web app request +// is information on backup request slot is name of web app slot. If not +// specified then will default to production slot. +func (client SitesClient) UpdateSiteBackupConfigurationSlot(resourceGroupName string, name string, request BackupRequest, slot string) (result BackupRequest, ae error) { + req, err := client.UpdateSiteBackupConfigurationSlotPreparer(resourceGroupName, name, request, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteBackupConfigurationSlot", "Failure preparing request") + } + + resp, err := client.UpdateSiteBackupConfigurationSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteBackupConfigurationSlot", "Failure sending request") + } + + result, err = client.UpdateSiteBackupConfigurationSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteBackupConfigurationSlot", "Failure responding to request") + } + + return +} + +// UpdateSiteBackupConfigurationSlotPreparer prepares the UpdateSiteBackupConfigurationSlot request. +func (client SitesClient) UpdateSiteBackupConfigurationSlotPreparer(resourceGroupName string, name string, request BackupRequest, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/backup"), + autorest.WithJSON(request), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteBackupConfigurationSlotSender sends the UpdateSiteBackupConfigurationSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteBackupConfigurationSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteBackupConfigurationSlotResponder handles the response to the UpdateSiteBackupConfigurationSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteBackupConfigurationSlotResponder(resp *http.Response) (result BackupRequest, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteConfig sends the update site config request. +// +// resourceGroupName is name of resource group name is name of web app +// siteConfig is request body that contains the configuraiton setting for the +// web app +func (client SitesClient) UpdateSiteConfig(resourceGroupName string, name string, siteConfig SiteConfig) (result SiteConfig, ae error) { + req, err := client.UpdateSiteConfigPreparer(resourceGroupName, name, siteConfig) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteConfig", "Failure preparing request") + } + + resp, err := client.UpdateSiteConfigSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteConfig", "Failure sending request") + } + + result, err = client.UpdateSiteConfigResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteConfig", "Failure responding to request") + } + + return +} + +// UpdateSiteConfigPreparer prepares the UpdateSiteConfig request. +func (client SitesClient) UpdateSiteConfigPreparer(resourceGroupName string, name string, siteConfig SiteConfig) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/web"), + autorest.WithJSON(siteConfig), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteConfigSender sends the UpdateSiteConfig request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteConfigSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteConfigResponder handles the response to the UpdateSiteConfig request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteConfigResponder(resp *http.Response) (result SiteConfig, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteConfigSlot sends the update site config slot request. +// +// resourceGroupName is name of resource group name is name of web app +// siteConfig is request body that contains the configuraiton setting for the +// web app slot is name of web app slot. If not specified then will default +// to production slot. +func (client SitesClient) UpdateSiteConfigSlot(resourceGroupName string, name string, siteConfig SiteConfig, slot string) (result SiteConfig, ae error) { + req, err := client.UpdateSiteConfigSlotPreparer(resourceGroupName, name, siteConfig, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteConfigSlot", "Failure preparing request") + } + + resp, err := client.UpdateSiteConfigSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteConfigSlot", "Failure sending request") + } + + result, err = client.UpdateSiteConfigSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteConfigSlot", "Failure responding to request") + } + + return +} + +// UpdateSiteConfigSlotPreparer prepares the UpdateSiteConfigSlot request. +func (client SitesClient) UpdateSiteConfigSlotPreparer(resourceGroupName string, name string, siteConfig SiteConfig, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/web"), + autorest.WithJSON(siteConfig), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteConfigSlotSender sends the UpdateSiteConfigSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteConfigSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteConfigSlotResponder handles the response to the UpdateSiteConfigSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteConfigSlotResponder(resp *http.Response) (result SiteConfig, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteConnectionStrings sends the update site connection strings +// request. +// +// resourceGroupName is name of resource group name is name of web app +// connectionStrings is connection strings associated with web app +func (client SitesClient) UpdateSiteConnectionStrings(resourceGroupName string, name string, connectionStrings ConnectionStringDictionary) (result ConnectionStringDictionary, ae error) { + req, err := client.UpdateSiteConnectionStringsPreparer(resourceGroupName, name, connectionStrings) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteConnectionStrings", "Failure preparing request") + } + + resp, err := client.UpdateSiteConnectionStringsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteConnectionStrings", "Failure sending request") + } + + result, err = client.UpdateSiteConnectionStringsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteConnectionStrings", "Failure responding to request") + } + + return +} + +// UpdateSiteConnectionStringsPreparer prepares the UpdateSiteConnectionStrings request. +func (client SitesClient) UpdateSiteConnectionStringsPreparer(resourceGroupName string, name string, connectionStrings ConnectionStringDictionary) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/connectionstrings"), + autorest.WithJSON(connectionStrings), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteConnectionStringsSender sends the UpdateSiteConnectionStrings request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteConnectionStringsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteConnectionStringsResponder handles the response to the UpdateSiteConnectionStrings request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteConnectionStringsResponder(resp *http.Response) (result ConnectionStringDictionary, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteConnectionStringsSlot sends the update site connection strings +// slot request. +// +// resourceGroupName is name of resource group name is name of web app +// connectionStrings is connection strings associated with web app slot is +// name of web app slot. If not specified then will default to production +// slot. +func (client SitesClient) UpdateSiteConnectionStringsSlot(resourceGroupName string, name string, connectionStrings ConnectionStringDictionary, slot string) (result ConnectionStringDictionary, ae error) { + req, err := client.UpdateSiteConnectionStringsSlotPreparer(resourceGroupName, name, connectionStrings, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteConnectionStringsSlot", "Failure preparing request") + } + + resp, err := client.UpdateSiteConnectionStringsSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteConnectionStringsSlot", "Failure sending request") + } + + result, err = client.UpdateSiteConnectionStringsSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteConnectionStringsSlot", "Failure responding to request") + } + + return +} + +// UpdateSiteConnectionStringsSlotPreparer prepares the UpdateSiteConnectionStringsSlot request. +func (client SitesClient) UpdateSiteConnectionStringsSlotPreparer(resourceGroupName string, name string, connectionStrings ConnectionStringDictionary, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/connectionstrings"), + autorest.WithJSON(connectionStrings), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteConnectionStringsSlotSender sends the UpdateSiteConnectionStringsSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteConnectionStringsSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteConnectionStringsSlotResponder handles the response to the UpdateSiteConnectionStringsSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteConnectionStringsSlotResponder(resp *http.Response) (result ConnectionStringDictionary, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteLogsConfig sends the update site logs config request. +// +// resourceGroupName is name of resource group name is name of web app +// siteLogsConfig is site logs configuration +func (client SitesClient) UpdateSiteLogsConfig(resourceGroupName string, name string, siteLogsConfig SiteLogsConfig) (result SiteLogsConfig, ae error) { + req, err := client.UpdateSiteLogsConfigPreparer(resourceGroupName, name, siteLogsConfig) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteLogsConfig", "Failure preparing request") + } + + resp, err := client.UpdateSiteLogsConfigSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteLogsConfig", "Failure sending request") + } + + result, err = client.UpdateSiteLogsConfigResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteLogsConfig", "Failure responding to request") + } + + return +} + +// UpdateSiteLogsConfigPreparer prepares the UpdateSiteLogsConfig request. +func (client SitesClient) UpdateSiteLogsConfigPreparer(resourceGroupName string, name string, siteLogsConfig SiteLogsConfig) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/logs"), + autorest.WithJSON(siteLogsConfig), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteLogsConfigSender sends the UpdateSiteLogsConfig request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteLogsConfigSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteLogsConfigResponder handles the response to the UpdateSiteLogsConfig request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteLogsConfigResponder(resp *http.Response) (result SiteLogsConfig, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteLogsConfigSlot sends the update site logs config slot request. +// +// resourceGroupName is name of resource group name is name of web app +// siteLogsConfig is site logs configuration slot is name of web app slot. If +// not specified then will default to production slot. +func (client SitesClient) UpdateSiteLogsConfigSlot(resourceGroupName string, name string, siteLogsConfig SiteLogsConfig, slot string) (result SiteLogsConfig, ae error) { + req, err := client.UpdateSiteLogsConfigSlotPreparer(resourceGroupName, name, siteLogsConfig, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteLogsConfigSlot", "Failure preparing request") + } + + resp, err := client.UpdateSiteLogsConfigSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteLogsConfigSlot", "Failure sending request") + } + + result, err = client.UpdateSiteLogsConfigSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteLogsConfigSlot", "Failure responding to request") + } + + return +} + +// UpdateSiteLogsConfigSlotPreparer prepares the UpdateSiteLogsConfigSlot request. +func (client SitesClient) UpdateSiteLogsConfigSlotPreparer(resourceGroupName string, name string, siteLogsConfig SiteLogsConfig, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/logs"), + autorest.WithJSON(siteLogsConfig), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteLogsConfigSlotSender sends the UpdateSiteLogsConfigSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteLogsConfigSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteLogsConfigSlotResponder handles the response to the UpdateSiteLogsConfigSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteLogsConfigSlotResponder(resp *http.Response) (result SiteLogsConfig, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteMetadata sends the update site metadata request. +// +// resourceGroupName is name of resource group name is name of web app +// metadata is meta data of web app +func (client SitesClient) UpdateSiteMetadata(resourceGroupName string, name string, metadata StringDictionary) (result StringDictionary, ae error) { + req, err := client.UpdateSiteMetadataPreparer(resourceGroupName, name, metadata) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteMetadata", "Failure preparing request") + } + + resp, err := client.UpdateSiteMetadataSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteMetadata", "Failure sending request") + } + + result, err = client.UpdateSiteMetadataResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteMetadata", "Failure responding to request") + } + + return +} + +// UpdateSiteMetadataPreparer prepares the UpdateSiteMetadata request. +func (client SitesClient) UpdateSiteMetadataPreparer(resourceGroupName string, name string, metadata StringDictionary) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/metadata"), + autorest.WithJSON(metadata), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteMetadataSender sends the UpdateSiteMetadata request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteMetadataSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteMetadataResponder handles the response to the UpdateSiteMetadata request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteMetadataResponder(resp *http.Response) (result StringDictionary, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteMetadataSlot sends the update site metadata slot request. +// +// resourceGroupName is name of resource group name is name of web app +// metadata is meta data of web app slot is name of web app slot. If not +// specified then will default to production slot. +func (client SitesClient) UpdateSiteMetadataSlot(resourceGroupName string, name string, metadata StringDictionary, slot string) (result StringDictionary, ae error) { + req, err := client.UpdateSiteMetadataSlotPreparer(resourceGroupName, name, metadata, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteMetadataSlot", "Failure preparing request") + } + + resp, err := client.UpdateSiteMetadataSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteMetadataSlot", "Failure sending request") + } + + result, err = client.UpdateSiteMetadataSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteMetadataSlot", "Failure responding to request") + } + + return +} + +// UpdateSiteMetadataSlotPreparer prepares the UpdateSiteMetadataSlot request. +func (client SitesClient) UpdateSiteMetadataSlotPreparer(resourceGroupName string, name string, metadata StringDictionary, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/config/metadata"), + autorest.WithJSON(metadata), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteMetadataSlotSender sends the UpdateSiteMetadataSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteMetadataSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteMetadataSlotResponder handles the response to the UpdateSiteMetadataSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteMetadataSlotResponder(resp *http.Response) (result StringDictionary, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteRelayServiceConnection sends the update site relay service +// connection request. +// +// resourceGroupName is the resource group name name is the name of the web +// app entityName is the name by which the Hybrid Connection is identified +// connectionEnvelope is the details of the Hybrid Connection +func (client SitesClient) UpdateSiteRelayServiceConnection(resourceGroupName string, name string, entityName string, connectionEnvelope RelayServiceConnectionEntity) (result RelayServiceConnectionEntity, ae error) { + req, err := client.UpdateSiteRelayServiceConnectionPreparer(resourceGroupName, name, entityName, connectionEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteRelayServiceConnection", "Failure preparing request") + } + + resp, err := client.UpdateSiteRelayServiceConnectionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteRelayServiceConnection", "Failure sending request") + } + + result, err = client.UpdateSiteRelayServiceConnectionResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteRelayServiceConnection", "Failure responding to request") + } + + return +} + +// UpdateSiteRelayServiceConnectionPreparer prepares the UpdateSiteRelayServiceConnection request. +func (client SitesClient) UpdateSiteRelayServiceConnectionPreparer(resourceGroupName string, name string, entityName string, connectionEnvelope RelayServiceConnectionEntity) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "entityName": url.QueryEscape(entityName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/hybridconnection/{entityName}"), + autorest.WithJSON(connectionEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteRelayServiceConnectionSender sends the UpdateSiteRelayServiceConnection request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteRelayServiceConnectionSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteRelayServiceConnectionResponder handles the response to the UpdateSiteRelayServiceConnection request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteRelayServiceConnectionResponder(resp *http.Response) (result RelayServiceConnectionEntity, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteRelayServiceConnectionSlot sends the update site relay service +// connection slot request. +// +// resourceGroupName is the resource group name name is the name of the web +// app entityName is the name by which the Hybrid Connection is identified +// connectionEnvelope is the details of the Hybrid Connection slot is the +// name of the slot for the web app. +func (client SitesClient) UpdateSiteRelayServiceConnectionSlot(resourceGroupName string, name string, entityName string, connectionEnvelope RelayServiceConnectionEntity, slot string) (result RelayServiceConnectionEntity, ae error) { + req, err := client.UpdateSiteRelayServiceConnectionSlotPreparer(resourceGroupName, name, entityName, connectionEnvelope, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteRelayServiceConnectionSlot", "Failure preparing request") + } + + resp, err := client.UpdateSiteRelayServiceConnectionSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteRelayServiceConnectionSlot", "Failure sending request") + } + + result, err = client.UpdateSiteRelayServiceConnectionSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteRelayServiceConnectionSlot", "Failure responding to request") + } + + return +} + +// UpdateSiteRelayServiceConnectionSlotPreparer prepares the UpdateSiteRelayServiceConnectionSlot request. +func (client SitesClient) UpdateSiteRelayServiceConnectionSlotPreparer(resourceGroupName string, name string, entityName string, connectionEnvelope RelayServiceConnectionEntity, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "entityName": url.QueryEscape(entityName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/hybridconnection/{entityName}"), + autorest.WithJSON(connectionEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteRelayServiceConnectionSlotSender sends the UpdateSiteRelayServiceConnectionSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteRelayServiceConnectionSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteRelayServiceConnectionSlotResponder handles the response to the UpdateSiteRelayServiceConnectionSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteRelayServiceConnectionSlotResponder(resp *http.Response) (result RelayServiceConnectionEntity, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteSourceControl sends the update site source control request. +// +// resourceGroupName is name of resource group name is name of web app +// siteSourceControl is request body that contains the source control +// parameters +func (client SitesClient) UpdateSiteSourceControl(resourceGroupName string, name string, siteSourceControl SiteSourceControl) (result SiteSourceControl, ae error) { + req, err := client.UpdateSiteSourceControlPreparer(resourceGroupName, name, siteSourceControl) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteSourceControl", "Failure preparing request") + } + + resp, err := client.UpdateSiteSourceControlSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteSourceControl", "Failure sending request") + } + + result, err = client.UpdateSiteSourceControlResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteSourceControl", "Failure responding to request") + } + + return +} + +// UpdateSiteSourceControlPreparer prepares the UpdateSiteSourceControl request. +func (client SitesClient) UpdateSiteSourceControlPreparer(resourceGroupName string, name string, siteSourceControl SiteSourceControl) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/sourcecontrols/web"), + autorest.WithJSON(siteSourceControl), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteSourceControlSender sends the UpdateSiteSourceControl request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteSourceControlSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteSourceControlResponder handles the response to the UpdateSiteSourceControl request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteSourceControlResponder(resp *http.Response) (result SiteSourceControl, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteSourceControlSlot sends the update site source control slot +// request. +// +// resourceGroupName is name of resource group name is name of web app +// siteSourceControl is request body that contains the source control +// parameters slot is name of web app slot. If not specified then will +// default to production slot. +func (client SitesClient) UpdateSiteSourceControlSlot(resourceGroupName string, name string, siteSourceControl SiteSourceControl, slot string) (result SiteSourceControl, ae error) { + req, err := client.UpdateSiteSourceControlSlotPreparer(resourceGroupName, name, siteSourceControl, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteSourceControlSlot", "Failure preparing request") + } + + resp, err := client.UpdateSiteSourceControlSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteSourceControlSlot", "Failure sending request") + } + + result, err = client.UpdateSiteSourceControlSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteSourceControlSlot", "Failure responding to request") + } + + return +} + +// UpdateSiteSourceControlSlotPreparer prepares the UpdateSiteSourceControlSlot request. +func (client SitesClient) UpdateSiteSourceControlSlotPreparer(resourceGroupName string, name string, siteSourceControl SiteSourceControl, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/sourcecontrols/web"), + autorest.WithJSON(siteSourceControl), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteSourceControlSlotSender sends the UpdateSiteSourceControlSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteSourceControlSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteSourceControlSlotResponder handles the response to the UpdateSiteSourceControlSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteSourceControlSlotResponder(resp *http.Response) (result SiteSourceControl, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteVNETConnection sends the update site vnet connection request. +// +// resourceGroupName is the resource group name name is the name of the web +// app vnetName is the name of the Virtual Network connectionEnvelope is the +// properties of this Virtual Network Connection +func (client SitesClient) UpdateSiteVNETConnection(resourceGroupName string, name string, vnetName string, connectionEnvelope VnetInfo) (result VnetInfo, ae error) { + req, err := client.UpdateSiteVNETConnectionPreparer(resourceGroupName, name, vnetName, connectionEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteVNETConnection", "Failure preparing request") + } + + resp, err := client.UpdateSiteVNETConnectionSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteVNETConnection", "Failure sending request") + } + + result, err = client.UpdateSiteVNETConnectionResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteVNETConnection", "Failure responding to request") + } + + return +} + +// UpdateSiteVNETConnectionPreparer prepares the UpdateSiteVNETConnection request. +func (client SitesClient) UpdateSiteVNETConnectionPreparer(resourceGroupName string, name string, vnetName string, connectionEnvelope VnetInfo) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/virtualNetworkConnections/{vnetName}"), + autorest.WithJSON(connectionEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteVNETConnectionSender sends the UpdateSiteVNETConnection request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteVNETConnectionSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteVNETConnectionResponder handles the response to the UpdateSiteVNETConnection request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteVNETConnectionResponder(resp *http.Response) (result VnetInfo, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteVNETConnectionGateway sends the update site vnet connection +// gateway request. +// +// resourceGroupName is the resource group name name is the name of the web +// app vnetName is the name of the Virtual Network gatewayName is the name of +// the gateway. The only gateway that exists presently is "primary" +// connectionEnvelope is the properties to update this gateway with. +func (client SitesClient) UpdateSiteVNETConnectionGateway(resourceGroupName string, name string, vnetName string, gatewayName string, connectionEnvelope VnetGateway) (result VnetGateway, ae error) { + req, err := client.UpdateSiteVNETConnectionGatewayPreparer(resourceGroupName, name, vnetName, gatewayName, connectionEnvelope) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteVNETConnectionGateway", "Failure preparing request") + } + + resp, err := client.UpdateSiteVNETConnectionGatewaySender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteVNETConnectionGateway", "Failure sending request") + } + + result, err = client.UpdateSiteVNETConnectionGatewayResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteVNETConnectionGateway", "Failure responding to request") + } + + return +} + +// UpdateSiteVNETConnectionGatewayPreparer prepares the UpdateSiteVNETConnectionGateway request. +func (client SitesClient) UpdateSiteVNETConnectionGatewayPreparer(resourceGroupName string, name string, vnetName string, gatewayName string, connectionEnvelope VnetGateway) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "gatewayName": url.QueryEscape(gatewayName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/virtualNetworkConnections/{vnetName}/gateways/{gatewayName}"), + autorest.WithJSON(connectionEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteVNETConnectionGatewaySender sends the UpdateSiteVNETConnectionGateway request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteVNETConnectionGatewaySender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteVNETConnectionGatewayResponder handles the response to the UpdateSiteVNETConnectionGateway request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteVNETConnectionGatewayResponder(resp *http.Response) (result VnetGateway, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteVNETConnectionGatewaySlot sends the update site vnet connection +// gateway slot request. +// +// resourceGroupName is the resource group name name is the name of the web +// app vnetName is the name of the Virtual Network gatewayName is the name of +// the gateway. The only gateway that exists presently is "primary" +// connectionEnvelope is the properties to update this gateway with. slot is +// the name of the slot for this web app. +func (client SitesClient) UpdateSiteVNETConnectionGatewaySlot(resourceGroupName string, name string, vnetName string, gatewayName string, connectionEnvelope VnetGateway, slot string) (result VnetGateway, ae error) { + req, err := client.UpdateSiteVNETConnectionGatewaySlotPreparer(resourceGroupName, name, vnetName, gatewayName, connectionEnvelope, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteVNETConnectionGatewaySlot", "Failure preparing request") + } + + resp, err := client.UpdateSiteVNETConnectionGatewaySlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteVNETConnectionGatewaySlot", "Failure sending request") + } + + result, err = client.UpdateSiteVNETConnectionGatewaySlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteVNETConnectionGatewaySlot", "Failure responding to request") + } + + return +} + +// UpdateSiteVNETConnectionGatewaySlotPreparer prepares the UpdateSiteVNETConnectionGatewaySlot request. +func (client SitesClient) UpdateSiteVNETConnectionGatewaySlotPreparer(resourceGroupName string, name string, vnetName string, gatewayName string, connectionEnvelope VnetGateway, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "gatewayName": url.QueryEscape(gatewayName), + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/virtualNetworkConnections/{vnetName}/gateways/{gatewayName}"), + autorest.WithJSON(connectionEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteVNETConnectionGatewaySlotSender sends the UpdateSiteVNETConnectionGatewaySlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteVNETConnectionGatewaySlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteVNETConnectionGatewaySlotResponder handles the response to the UpdateSiteVNETConnectionGatewaySlot request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteVNETConnectionGatewaySlotResponder(resp *http.Response) (result VnetGateway, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSiteVNETConnectionSlot sends the update site vnet connection slot +// request. +// +// resourceGroupName is the resource group name name is the name of the web +// app vnetName is the name of the Virtual Network connectionEnvelope is the +// properties of this Virtual Network Connection slot is the name of the slot +// for this web app. +func (client SitesClient) UpdateSiteVNETConnectionSlot(resourceGroupName string, name string, vnetName string, connectionEnvelope VnetInfo, slot string) (result VnetInfo, ae error) { + req, err := client.UpdateSiteVNETConnectionSlotPreparer(resourceGroupName, name, vnetName, connectionEnvelope, slot) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteVNETConnectionSlot", "Failure preparing request") + } + + resp, err := client.UpdateSiteVNETConnectionSlotSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteVNETConnectionSlot", "Failure sending request") + } + + result, err = client.UpdateSiteVNETConnectionSlotResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSiteVNETConnectionSlot", "Failure responding to request") + } + + return +} + +// UpdateSiteVNETConnectionSlotPreparer prepares the UpdateSiteVNETConnectionSlot request. +func (client SitesClient) UpdateSiteVNETConnectionSlotPreparer(resourceGroupName string, name string, vnetName string, connectionEnvelope VnetInfo, slot string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "slot": url.QueryEscape(slot), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + "vnetName": url.QueryEscape(vnetName), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPatch(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/slots/{slot}/virtualNetworkConnections/{vnetName}"), + autorest.WithJSON(connectionEnvelope), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSiteVNETConnectionSlotSender sends the UpdateSiteVNETConnectionSlot request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSiteVNETConnectionSlotSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSiteVNETConnectionSlotResponder handles the response to the UpdateSiteVNETConnectionSlot request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSiteVNETConnectionSlotResponder(resp *http.Response) (result VnetInfo, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// UpdateSlotConfigNames sends the update slot config names request. +// +// resourceGroupName is name of resource group name is name of web app +// slotConfigNames is request body containing the names of application +// settings and connection strings +func (client SitesClient) UpdateSlotConfigNames(resourceGroupName string, name string, slotConfigNames SlotConfigNamesResource) (result SlotConfigNamesResource, ae error) { + req, err := client.UpdateSlotConfigNamesPreparer(resourceGroupName, name, slotConfigNames) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSlotConfigNames", "Failure preparing request") + } + + resp, err := client.UpdateSlotConfigNamesSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSlotConfigNames", "Failure sending request") + } + + result, err = client.UpdateSlotConfigNamesResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/SitesClient", "UpdateSlotConfigNames", "Failure responding to request") + } + + return +} + +// UpdateSlotConfigNamesPreparer prepares the UpdateSlotConfigNames request. +func (client SitesClient) UpdateSlotConfigNamesPreparer(resourceGroupName string, name string, slotConfigNames SlotConfigNamesResource) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/config/slotConfigNames"), + autorest.WithJSON(slotConfigNames), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// UpdateSlotConfigNamesSender sends the UpdateSlotConfigNames request. The method will close the +// http.Response Body if it receives an error. +func (client SitesClient) UpdateSlotConfigNamesSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// UpdateSlotConfigNamesResponder handles the response to the UpdateSlotConfigNames request. The method always +// closes the http.Response Body. +func (client SitesClient) UpdateSlotConfigNamesResponder(resp *http.Response) (result SlotConfigNamesResource, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/topleveldomains.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/topleveldomains.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/topleveldomains.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/topleveldomains.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,235 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// TopLevelDomainsClient is the use these APIs to manage Azure Websites +// resources through the Azure Resource Manager. All task operations conform +// to the HTTP/1.1 protocol specification and each operation returns an +// x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +type TopLevelDomainsClient struct { + ManagementClient +} + +// NewTopLevelDomainsClient creates an instance of the TopLevelDomainsClient +// client. +func NewTopLevelDomainsClient(subscriptionID string) TopLevelDomainsClient { + return NewTopLevelDomainsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewTopLevelDomainsClientWithBaseURI creates an instance of the +// TopLevelDomainsClient client. +func NewTopLevelDomainsClientWithBaseURI(baseURI string, subscriptionID string) TopLevelDomainsClient { + return TopLevelDomainsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// GetGetTopLevelDomains sends the get get top level domains request. +func (client TopLevelDomainsClient) GetGetTopLevelDomains() (result TopLevelDomainCollection, ae error) { + req, err := client.GetGetTopLevelDomainsPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "web/TopLevelDomainsClient", "GetGetTopLevelDomains", "Failure preparing request") + } + + resp, err := client.GetGetTopLevelDomainsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/TopLevelDomainsClient", "GetGetTopLevelDomains", "Failure sending request") + } + + result, err = client.GetGetTopLevelDomainsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/TopLevelDomainsClient", "GetGetTopLevelDomains", "Failure responding to request") + } + + return +} + +// GetGetTopLevelDomainsPreparer prepares the GetGetTopLevelDomains request. +func (client TopLevelDomainsClient) GetGetTopLevelDomainsPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.DomainRegistration/topLevelDomains"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetGetTopLevelDomainsSender sends the GetGetTopLevelDomains request. The method will close the +// http.Response Body if it receives an error. +func (client TopLevelDomainsClient) GetGetTopLevelDomainsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetGetTopLevelDomainsResponder handles the response to the GetGetTopLevelDomains request. The method always +// closes the http.Response Body. +func (client TopLevelDomainsClient) GetGetTopLevelDomainsResponder(resp *http.Response) (result TopLevelDomainCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// GetTopLevelDomain sends the get top level domain request. +// +// name is name of the top level domain +func (client TopLevelDomainsClient) GetTopLevelDomain(name string) (result TopLevelDomain, ae error) { + req, err := client.GetTopLevelDomainPreparer(name) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/TopLevelDomainsClient", "GetTopLevelDomain", "Failure preparing request") + } + + resp, err := client.GetTopLevelDomainSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/TopLevelDomainsClient", "GetTopLevelDomain", "Failure sending request") + } + + result, err = client.GetTopLevelDomainResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/TopLevelDomainsClient", "GetTopLevelDomain", "Failure responding to request") + } + + return +} + +// GetTopLevelDomainPreparer prepares the GetTopLevelDomain request. +func (client TopLevelDomainsClient) GetTopLevelDomainPreparer(name string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.DomainRegistration/topLevelDomains/{name}"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetTopLevelDomainSender sends the GetTopLevelDomain request. The method will close the +// http.Response Body if it receives an error. +func (client TopLevelDomainsClient) GetTopLevelDomainSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetTopLevelDomainResponder handles the response to the GetTopLevelDomain request. The method always +// closes the http.Response Body. +func (client TopLevelDomainsClient) GetTopLevelDomainResponder(resp *http.Response) (result TopLevelDomain, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListTopLevelDomainAgreements sends the list top level domain agreements +// request. +// +// name is name of the top level domain agreementOption is domain agreement +// options +func (client TopLevelDomainsClient) ListTopLevelDomainAgreements(name string, agreementOption TopLevelDomainAgreementOption) (result TldLegalAgreementCollection, ae error) { + req, err := client.ListTopLevelDomainAgreementsPreparer(name, agreementOption) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/TopLevelDomainsClient", "ListTopLevelDomainAgreements", "Failure preparing request") + } + + resp, err := client.ListTopLevelDomainAgreementsSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/TopLevelDomainsClient", "ListTopLevelDomainAgreements", "Failure sending request") + } + + result, err = client.ListTopLevelDomainAgreementsResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/TopLevelDomainsClient", "ListTopLevelDomainAgreements", "Failure responding to request") + } + + return +} + +// ListTopLevelDomainAgreementsPreparer prepares the ListTopLevelDomainAgreements request. +func (client TopLevelDomainsClient) ListTopLevelDomainAgreementsPreparer(name string, agreementOption TopLevelDomainAgreementOption) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "name": url.QueryEscape(name), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsPost(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/providers/Microsoft.DomainRegistration/topLevelDomains/{name}/listAgreements"), + autorest.WithJSON(agreementOption), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// ListTopLevelDomainAgreementsSender sends the ListTopLevelDomainAgreements request. The method will close the +// http.Response Body if it receives an error. +func (client TopLevelDomainsClient) ListTopLevelDomainAgreementsSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// ListTopLevelDomainAgreementsResponder handles the response to the ListTopLevelDomainAgreements request. The method always +// closes the http.Response Body. +func (client TopLevelDomainsClient) ListTopLevelDomainAgreementsResponder(resp *http.Response) (result TldLegalAgreementCollection, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/usageoperations.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/usageoperations.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/usageoperations.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/usageoperations.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,116 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "net/http" + "net/url" +) + +// UsageOperationsClient is the use these APIs to manage Azure Websites +// resources through the Azure Resource Manager. All task operations conform +// to the HTTP/1.1 protocol specification and each operation returns an +// x-ms-request-id header that can be used to obtain information about the +// request. You must make sure that requests made to these resources are +// secure. For more information, see Authenticating +// Azure Resource Manager requests. +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)} +} + +// GetUsage sends the get usage request. +// +// resourceGroupName is name of resource group environmentName is environment +// name lastID is last marker that was returned from the batch batchSize is +// size of the batch to be returned. +func (client UsageOperationsClient) GetUsage(resourceGroupName string, environmentName string, lastID string, batchSize int) (result ObjectSet, ae error) { + req, err := client.GetUsagePreparer(resourceGroupName, environmentName, lastID, batchSize) + if err != nil { + return result, autorest.NewErrorWithError(err, "web/UsageOperationsClient", "GetUsage", "Failure preparing request") + } + + resp, err := client.GetUsageSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "web/UsageOperationsClient", "GetUsage", "Failure sending request") + } + + result, err = client.GetUsageResponder(resp) + if err != nil { + ae = autorest.NewErrorWithError(err, "web/UsageOperationsClient", "GetUsage", "Failure responding to request") + } + + return +} + +// GetUsagePreparer prepares the GetUsage request. +func (client UsageOperationsClient) GetUsagePreparer(resourceGroupName string, environmentName string, lastID string, batchSize int) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "environmentName": url.QueryEscape(environmentName), + "resourceGroupName": url.QueryEscape(resourceGroupName), + "subscriptionId": url.QueryEscape(client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + "batchSize": batchSize, + "lastId": lastID, + } + + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web.Admin/environments/{environmentName}/usage"), + autorest.WithPathParameters(pathParameters), + autorest.WithQueryParameters(queryParameters)) +} + +// GetUsageSender sends the GetUsage request. The method will close the +// http.Response Body if it receives an error. +func (client UsageOperationsClient) GetUsageSender(req *http.Request) (*http.Response, error) { + return client.Send(req, http.StatusOK) +} + +// GetUsageResponder handles the response to the GetUsage request. The method always +// closes the http.Response Body. +func (client UsageOperationsClient) GetUsageResponder(resp *http.Response) (result ObjectSet, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + autorest.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Value), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/version.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/version.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/arm/web/version.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/arm/web/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,43 @@ +package web + +// 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.12.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "fmt" +) + +const ( + major = "0" + minor = "3" + 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;Package arm/%s;API %s" +) + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return fmt.Sprintf(userAgentFormat, Version(), "web", "2015-08-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 -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/Godeps.json juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/Godeps.json --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/Godeps.json 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/Godeps.json 2016-05-17 20:01:14.000000000 +0000 @@ -2,18 +2,26 @@ "ImportPath": "github.com/Azure/azure-sdk-for-go", "GoVersion": "go1.5.1", "Packages": [ - "./management/...", - "./arm/..." + "./..." ], "Deps": [ { "ImportPath": "github.com/Azure/go-autorest/autorest", - "Comment": "v1.0.1", - "Rev": "1cebd0377050996f91857917c73f00a377e64262" + "Comment": "v1.1.0-6-ga3998c5", + "Rev": "a3998c5cde825491a61b5dfdb92a098e6155fef0" + }, + { + "ImportPath": "github.com/dgrijalva/jwt-go", + "Comment": "v2.4.0", + "Rev": "f164e17f59b82642a3895ba065c385db6c547344" }, { "ImportPath": "golang.org/x/crypto/pkcs12", - "Rev": "c8b9e6388ef638d5a8a9d865c634befdc46a6784" + "Rev": "346896d57731cb5670b36c6178fc5519f3225980" + }, + { + "ImportPath": "gopkg.in/check.v1", + "Rev": "11d3bc7aa68e238947792f30573146a3231fc0f1" } ] } diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/azure/example/main.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/azure/example/main.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/azure/example/main.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/azure/example/main.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,107 @@ +package main + +import ( + "flag" + "io/ioutil" + "log" + "net/http" + "strings" + + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/azure" +) + +const resourceGroupURLTemplate = "https://management.azure.com/subscriptions/{subscription-id}/resourcegroups" +const apiVersion = "2015-01-01" + +var ( + certificatePath string + applicationID string + tenantID string + subscriptionID string +) + +func init() { + flag.StringVar(&certificatePath, "certificatePath", "", "path to pk12/pfx certificate") + flag.StringVar(&applicationID, "applicationId", "", "application id") + flag.StringVar(&tenantID, "tenantId", "", "tenant id") + flag.StringVar(&subscriptionID, "subscriptionId", "", "subscription id") + flag.Parse() + + log.Println("Using these settings:") + log.Println("* certificatePath:", certificatePath) + log.Println("* applicationID:", applicationID) + log.Println("* tenantID:", tenantID) + log.Println("* subscriptionID:", subscriptionID) + + if strings.Trim(certificatePath, " ") == "" || + strings.Trim(applicationID, " ") == "" || + strings.Trim(tenantID, " ") == "" || + strings.Trim(subscriptionID, " ") == "" { + log.Fatalln("Bad usage. Please specify all four parameters") + } +} + +func main() { + log.Println("loading certificate... ") + certData, err := ioutil.ReadFile(certificatePath) + if err != nil { + log.Fatalln("failed", err) + } + + log.Println("retrieve oauth token... ") + spt, err := azure.NewServicePrincipalTokenFromCertificate( + applicationID, + certData, + "", + tenantID, + azure.AzureResourceManagerScope) + if err != nil { + log.Fatalln("failed", err) + panic(err) + } + + client := &autorest.Client{} + client.Authorizer = spt + + log.Println("querying the list of resource groups... ") + groupsAsString, err := getResourceGroups(client) + if err != nil { + log.Fatalln("failed", err) + } + + log.Println("") + log.Println("Groups:", *groupsAsString) +} + +func getResourceGroups(client *autorest.Client) (*string, error) { + var p map[string]interface{} + var req *http.Request + p = map[string]interface{}{ + "subscription-id": subscriptionID, + } + q := map[string]interface{}{ + "api-version": apiVersion, + } + + req, _ = autorest.Prepare(&http.Request{}, + autorest.AsGet(), + autorest.WithBaseURL(resourceGroupURLTemplate), + autorest.WithPathParameters(p), + autorest.WithQueryParameters(q)) + + resp, err := client.Send(req, http.StatusOK) + if err != nil { + return nil, err + } + + defer resp.Body.Close() + contents, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + + contentsString := string(contents) + + return &contentsString, nil +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/azure/example/README.md juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/azure/example/README.md --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/azure/example/README.md 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/azure/example/README.md 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,115 @@ +# autorest azure example + +## Usage + +This example covers how to make an authenticated call to the Azure Resource Manager APIs, using certificate-based authentication. + +0. Export some required variables + + ``` + export SUBSCRIPTION_ID="aff271ee-e9be-4441-b9bb-42f5af4cbaeb" + export TENANT_ID="13de0a15-b5db-44b9-b682-b4ba82afbd29" + export RESOURCE_GROUP="someresourcegroup" + ``` + + * replace both values with your own + +1. Create a private key + + ``` + openssl genrsa -out "example.key" 2048 + ``` + + + +2. Create the certificate + + ``` + openssl req -new -key "example.key" -subj "/CN=example" -out "example.csr" + + openssl x509 -req -in "example.csr" -signkey "example.key" -out "example.crt" -days 10000 + ``` + + + +3. Create the PKCS12 version of the certificate (with no password) + + ``` + openssl pkcs12 -export -out "example.pfx" -inkey "example.key" -in "example.crt" -passout pass: + ``` + + + +4. Register a new Azure AD Application with the certificate contents + + ``` + certificateContents="$(tail -n+2 "example.key" | head -n-1)" + + azure ad app create \ + --name "example-azuread-app" \ + --home-page="http://example-azuread-app/home" \ + --identifier-uris "http://example-azuread-app/app" \ + --key-usage "Verify" \ + --end-date "2020-01-01" \ + --key-value "${certificateContents}" + ``` + + + +5. Create a new service principal using the "Application Id" from the previous step + + ``` + azure ad sp create "APPLICATION_ID" + ``` + + * Replace APPLICATION_ID with the "Application Id" returned in step 4 + + + +6. Grant your service principal necessary permissions + + ``` + azure role assignment create \ + --resource-group "${RESOURCE_GROUP}" \ + --roleName "Contributor" \ + --subscription "${SUBSCRIPTION_ID}" \ + --spn "http://example-azuread-app/app" + ``` + + * Replace SUBSCRIPTION_ID with your subscription id + * Replace RESOURCE_GROUP with the resource group for the assignment + * Ensure that the `spn` parameter matches an `identifier-url` from Step 4 + + + +7. Run this example app to see your resource groups + + ``` + go run main.go \ + --tenantId="${TENANT_ID}" \ + --subscriptionId="${SUBSCRIPTION_ID}" \ + --applicationId="http://example-azuread-app/app" \ + --certificatePath="certificate.pfx" + ``` + + +You should see something like this as output: + +``` +2015/11/08 18:28:39 Using these settings: +2015/11/08 18:28:39 * certificatePath: certificate.pfx +2015/11/08 18:28:39 * applicationID: http://example-azuread-app/app +2015/11/08 18:28:39 * tenantID: 13de0a15-b5db-44b9-b682-b4ba82afbd29 +2015/11/08 18:28:39 * subscriptionID: aff271ee-e9be-4441-b9bb-42f5af4cbaeb +2015/11/08 18:28:39 loading certificate... +2015/11/08 18:28:39 retrieve oauth token... +2015/11/08 18:28:39 querying the list of resource groups... +2015/11/08 18:28:50 +2015/11/08 18:28:50 Groups: {"value":[{"id":"/subscriptions/aff271ee-e9be-4441-b9bb-42f5af4cbaeb/resourceGroups/kube-66f30810","name":"kube-66f30810","location":"westus","tags":{},"properties":{"provisioningState":"Succeeded"}}]} +``` + + + +## Notes + +You may need to wait sometime between executing step 4, step 5 and step 6. If you issue those requests too quickly, you might hit an AD server that is not consistent with the server where the resource was created. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/azure/token.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/azure/token.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/azure/token.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/azure/token.go 2016-05-17 20:01:14.000000000 +0000 @@ -1,12 +1,19 @@ package azure import ( + "crypto/rand" + "crypto/rsa" + "crypto/sha1" + "encoding/base64" + "fmt" "net/http" "net/url" "strconv" "time" "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12" ) const ( @@ -14,6 +21,8 @@ oauthURL = "https://login.microsoftonline.com/{tenantID}/oauth2/{requestType}?api-version=1.0" tokenBaseDate = "1970-01-01T00:00:00Z" + jwtAudienceTemplate = "https://login.microsoftonline.com/%s/oauth2/token" + // AzureResourceManagerScope is the OAuth scope for the Azure Resource Manager. AzureResourceManagerScope = "https://management.azure.com/" ) @@ -66,33 +75,138 @@ } } +// 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 ServicePrincipalTokenSecret. +// 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 certificate auth with signed JWTs. +type ServicePrincipalCertificateSecret struct { + Pkcs12 []byte + Password string +} + +// SignJwt returns the JWT signed with the certificate's private key. +func (secret *ServicePrincipalCertificateSecret) SignJwt(spt *ServicePrincipalToken) (string, error) { + privateKey, cert, err := pkcs12.Decode(secret.Pkcs12, secret.Password) + if err != nil { + return "", err + } + + rsaPrivateKey, isRsaKey := privateKey.(*rsa.PrivateKey) + if !isRsaKey { + return "", fmt.Errorf("PKCS12 certificate must contain an RSA private key") + } + + hasher := sha1.New() + _, err = hasher.Write(cert.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 = map[string]interface{}{ + "aud": fmt.Sprintf(jwtAudienceTemplate, spt.tenantID), + "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(rsaPrivateKey) + return signedString, nil +} + +// SetAuthenticationValues is a method of the interface ServicePrincipalTokenSecret. +// 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 clientID string - clientSecret string - resource string tenantID string + resource string autoRefresh bool refreshWithin time.Duration sender autorest.Sender } -// NewServicePrincipalToken creates a ServicePrincipalToken from the supplied Service Principal -// credentials scoped to the named resource. -func NewServicePrincipalToken(id string, secret string, tenantID string, resource string) (*ServicePrincipalToken, error) { +// NewServicePrincipalTokenWithSecret create a ServicePrincipalToken using the supplied ServicePrincipalSecret implementation. +func NewServicePrincipalTokenWithSecret(id string, tenantID string, resource string, secret ServicePrincipalSecret) (*ServicePrincipalToken, error) { spt := &ServicePrincipalToken{ + secret: secret, clientID: id, - clientSecret: secret, resource: resource, tenantID: tenantID, autoRefresh: true, refreshWithin: defaultRefresh, - sender: &http.Client{}} + sender: &http.Client{}, + } return spt, nil } +// NewServicePrincipalToken creates a ServicePrincipalToken from the supplied Service Principal +// credentials scoped to the named resource. +func NewServicePrincipalToken(id string, secret string, tenantID string, resource string) (*ServicePrincipalToken, error) { + return NewServicePrincipalTokenWithSecret( + id, + tenantID, + resource, + &ServicePrincipalTokenSecret{ + ClientSecret: secret, + }, + ) +} + +// NewServicePrincipalTokenFromCertificate create a ServicePrincipalToken from the supplied pkcs12 bytes. +func NewServicePrincipalTokenFromCertificate(id string, pkcs12 []byte, password string, tenantID string, resource string) (*ServicePrincipalToken, error) { + return NewServicePrincipalTokenWithSecret( + id, + tenantID, + resource, + &ServicePrincipalCertificateSecret{ + Pkcs12: pkcs12, + Password: password, + }, + ) +} + // EnsureFresh will refresh the token if it will expire within the refresh window (as set by // RefreshWithin). func (spt *ServicePrincipalToken) EnsureFresh() error { @@ -111,16 +225,23 @@ v := url.Values{} v.Set("client_id", spt.clientID) - v.Set("client_secret", spt.clientSecret) v.Set("grant_type", "client_credentials") v.Set("resource", spt.resource) - req, _ := autorest.Prepare(&http.Request{}, + err := spt.secret.SetAuthenticationValues(spt, &v) + if err != nil { + return err + } + + req, err := autorest.Prepare(&http.Request{}, autorest.AsPost(), autorest.AsFormURLEncoded(), autorest.WithBaseURL(oauthURL), autorest.WithPathParameters(p), autorest.WithFormData(v)) + if err != nil { + return err + } resp, err := autorest.SendWithSender(spt.sender, req) if err != nil { @@ -129,9 +250,11 @@ spt.clientID) } + var newToken Token + err = autorest.Respond(resp, autorest.WithErrorUnlessOK(), - autorest.ByUnmarshallingJSON(spt), + autorest.ByUnmarshallingJSON(&newToken), autorest.ByClosing()) if err != nil { return autorest.NewErrorWithError(err, @@ -139,6 +262,8 @@ spt.clientID) } + spt.Token = newToken + return nil } diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/version.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/version.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/version.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -6,7 +6,7 @@ const ( major = "1" - minor = "0" + minor = "1" patch = "1" tag = "" semVerFormat = "%s.%s.%s%s" diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/version_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/version_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/version_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/version_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -5,7 +5,7 @@ ) func TestVersion(t *testing.T) { - v := "1.0.1" + v := "1.1.1" if Version() != v { t.Errorf("autorest: Version failed to return the expected version -- expected %s, received %s", v, Version()) diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/LICENSE juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/LICENSE --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/LICENSE 2016-05-17 20:01:14.000000000 +0000 @@ -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 -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/cmd/jwt/app.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/cmd/jwt/app.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/cmd/jwt/app.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/cmd/jwt/app.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,210 @@ +// A useful example app. You can use this to debug your tokens on the command line. +// This is also a great place to look at how you might use this library. +// +// Example usage: +// The following will create and sign a token, then verify it and output the original claims. +// echo {\"foo\":\"bar\"} | bin/jwt -key test/sample_key -alg RS256 -sign - | bin/jwt -key test/sample_key.pub -verify - +package main + +import ( + "encoding/json" + "flag" + "fmt" + "io" + "io/ioutil" + "os" + "regexp" + "strings" + + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go" +) + +var ( + // Options + flagAlg = flag.String("alg", "", "signing algorithm identifier") + flagKey = flag.String("key", "", "path to key file or '-' to read from stdin") + flagCompact = flag.Bool("compact", false, "output compact JSON") + flagDebug = flag.Bool("debug", false, "print out all kinds of debug data") + + // Modes - exactly one of these is required + flagSign = flag.String("sign", "", "path to claims object to sign or '-' to read from stdin") + flagVerify = flag.String("verify", "", "path to JWT token to verify or '-' to read from stdin") +) + +func main() { + // Usage message if you ask for -help or if you mess up inputs. + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0]) + fmt.Fprintf(os.Stderr, " One of the following flags is required: sign, verify\n") + flag.PrintDefaults() + } + + // Parse command line options + flag.Parse() + + // Do the thing. If something goes wrong, print error to stderr + // and exit with a non-zero status code + if err := start(); err != nil { + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) + } +} + +// Figure out which thing to do and then do that +func start() error { + if *flagSign != "" { + return signToken() + } else if *flagVerify != "" { + return verifyToken() + } else { + flag.Usage() + return fmt.Errorf("None of the required flags are present. What do you want me to do?") + } +} + +// Helper func: Read input from specified file or stdin +func loadData(p string) ([]byte, error) { + if p == "" { + return nil, fmt.Errorf("No path specified") + } + + var rdr io.Reader + if p == "-" { + rdr = os.Stdin + } else { + if f, err := os.Open(p); err == nil { + rdr = f + defer f.Close() + } else { + return nil, err + } + } + return ioutil.ReadAll(rdr) +} + +// Print a json object in accordance with the prophecy (or the command line options) +func printJSON(j interface{}) error { + var out []byte + var err error + + if *flagCompact == false { + out, err = json.MarshalIndent(j, "", " ") + } else { + out, err = json.Marshal(j) + } + + if err == nil { + fmt.Println(string(out)) + } + + return err +} + +// Verify a token and output the claims. This is a great example +// of how to verify and view a token. +func verifyToken() error { + // get the token + tokData, err := loadData(*flagVerify) + if err != nil { + return fmt.Errorf("Couldn't read token: %v", err) + } + + // trim possible whitespace from token + tokData = regexp.MustCompile(`\s*$`).ReplaceAll(tokData, []byte{}) + if *flagDebug { + fmt.Fprintf(os.Stderr, "Token len: %v bytes\n", len(tokData)) + } + + // Parse the token. Load the key from command line option + token, err := jwt.Parse(string(tokData), func(t *jwt.Token) (interface{}, error) { + data, err := loadData(*flagKey) + if err != nil { + return nil, err + } + if isEs() { + return jwt.ParseECPublicKeyFromPEM(data) + } + return data, nil + }) + + // Print some debug data + if *flagDebug && token != nil { + fmt.Fprintf(os.Stderr, "Header:\n%v\n", token.Header) + fmt.Fprintf(os.Stderr, "Claims:\n%v\n", token.Claims) + } + + // Print an error if we can't parse for some reason + if err != nil { + return fmt.Errorf("Couldn't parse token: %v", err) + } + + // Is token invalid? + if !token.Valid { + return fmt.Errorf("Token is invalid") + } + + // Print the token details + if err := printJSON(token.Claims); err != nil { + return fmt.Errorf("Failed to output claims: %v", err) + } + + return nil +} + +// Create, sign, and output a token. This is a great, simple example of +// how to use this library to create and sign a token. +func signToken() error { + // get the token data from command line arguments + tokData, err := loadData(*flagSign) + if err != nil { + return fmt.Errorf("Couldn't read token: %v", err) + } else if *flagDebug { + fmt.Fprintf(os.Stderr, "Token: %v bytes", len(tokData)) + } + + // parse the JSON of the claims + var claims map[string]interface{} + if err := json.Unmarshal(tokData, &claims); err != nil { + return fmt.Errorf("Couldn't parse claims JSON: %v", err) + } + + // get the key + var key interface{} + key, err = loadData(*flagKey) + if err != nil { + return fmt.Errorf("Couldn't read key: %v", err) + } + + // get the signing alg + alg := jwt.GetSigningMethod(*flagAlg) + if alg == nil { + return fmt.Errorf("Couldn't find signing method: %v", *flagAlg) + } + + // create a new token + token := jwt.New(alg) + token.Claims = claims + + if isEs() { + if k, ok := key.([]byte); !ok { + return fmt.Errorf("Couldn't convert key data to key") + } else { + key, err = jwt.ParseECPrivateKeyFromPEM(k) + if err != nil { + return err + } + } + } + + if out, err := token.SignedString(key); err == nil { + fmt.Println(out) + } else { + return fmt.Errorf("Error signing token: %v", err) + } + + return nil +} + +func isEs() bool { + return strings.HasPrefix(*flagAlg, "ES") +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/doc.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/doc.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/doc.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/doc.go 2016-05-17 20:01:14.000000000 +0000 @@ -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 -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/ecdsa.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/ecdsa.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/ecdsa.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/ecdsa.go 2016-05-17 20:01:14.000000000 +0000 @@ -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 ErrInvalidKey + } + + 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 "", ErrInvalidKey + } + + // 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 -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/ecdsa_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/ecdsa_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/ecdsa_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/ecdsa_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,100 @@ +package jwt_test + +import ( + "crypto/ecdsa" + "io/ioutil" + "strings" + "testing" + + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go" +) + +var ecdsaTestData = []struct { + name string + keys map[string]string + tokenString string + alg string + claims map[string]interface{} + valid bool +}{ + { + "Basic ES256", + map[string]string{"private": "test/ec256-private.pem", "public": "test/ec256-public.pem"}, + "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJmb28iOiJiYXIifQ.feG39E-bn8HXAKhzDZq7yEAPWYDhZlwTn3sePJnU9VrGMmwdXAIEyoOnrjreYlVM_Z4N13eK9-TmMTWyfKJtHQ", + "ES256", + map[string]interface{}{"foo": "bar"}, + true, + }, + { + "Basic ES384", + map[string]string{"private": "test/ec384-private.pem", "public": "test/ec384-public.pem"}, + "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzM4NCJ9.eyJmb28iOiJiYXIifQ.ngAfKMbJUh0WWubSIYe5GMsA-aHNKwFbJk_wq3lq23aPp8H2anb1rRILIzVR0gUf4a8WzDtrzmiikuPWyCS6CN4-PwdgTk-5nehC7JXqlaBZU05p3toM3nWCwm_LXcld", + "ES384", + map[string]interface{}{"foo": "bar"}, + true, + }, + { + "Basic ES512", + map[string]string{"private": "test/ec512-private.pem", "public": "test/ec512-public.pem"}, + "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzUxMiJ9.eyJmb28iOiJiYXIifQ.AAU0TvGQOcdg2OvrwY73NHKgfk26UDekh9Prz-L_iWuTBIBqOFCWwwLsRiHB1JOddfKAls5do1W0jR_F30JpVd-6AJeTjGKA4C1A1H6gIKwRY0o_tFDIydZCl_lMBMeG5VNFAjO86-WCSKwc3hqaGkq1MugPRq_qrF9AVbuEB4JPLyL5", + "ES512", + map[string]interface{}{"foo": "bar"}, + true, + }, + { + "basic ES256 invalid: foo => bar", + map[string]string{"private": "test/ec256-private.pem", "public": "test/ec256-public.pem"}, + "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.MEQCIHoSJnmGlPaVQDqacx_2XlXEhhqtWceVopjomc2PJLtdAiAUTeGPoNYxZw0z8mgOnnIcjoxRuNDVZvybRZF3wR1l8W", + "ES256", + map[string]interface{}{"foo": "bar"}, + false, + }, +} + +func TestECDSAVerify(t *testing.T) { + for _, data := range ecdsaTestData { + var err error + + key, _ := ioutil.ReadFile(data.keys["public"]) + + var ecdsaKey *ecdsa.PublicKey + if ecdsaKey, err = jwt.ParseECPublicKeyFromPEM(key); err != nil { + t.Errorf("Unable to parse ECDSA public key: %v", err) + } + + parts := strings.Split(data.tokenString, ".") + + method := jwt.GetSigningMethod(data.alg) + err = method.Verify(strings.Join(parts[0:2], "."), parts[2], ecdsaKey) + if data.valid && err != nil { + t.Errorf("[%v] Error while verifying key: %v", data.name, err) + } + if !data.valid && err == nil { + t.Errorf("[%v] Invalid key passed validation", data.name) + } + } +} + +func TestECDSASign(t *testing.T) { + for _, data := range ecdsaTestData { + var err error + key, _ := ioutil.ReadFile(data.keys["private"]) + + var ecdsaKey *ecdsa.PrivateKey + if ecdsaKey, err = jwt.ParseECPrivateKeyFromPEM(key); err != nil { + t.Errorf("Unable to parse ECDSA private key: %v", err) + } + + if data.valid { + parts := strings.Split(data.tokenString, ".") + method := jwt.GetSigningMethod(data.alg) + sig, err := method.Sign(strings.Join(parts[0:2], "."), ecdsaKey) + if err != nil { + t.Errorf("[%v] Error signing token: %v", data.name, err) + } + if sig == parts[2] { + t.Errorf("[%v] Identical signatures\nbefore:\n%v\nafter:\n%v", data.name, parts[2], sig) + } + } + } +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/ecdsa_utils.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/ecdsa_utils.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/ecdsa_utils.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/ecdsa_utils.go 2016-05-17 20:01:14.000000000 +0000 @@ -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 -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/errors.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/errors.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/errors.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/errors.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,43 @@ +package jwt + +import ( + "errors" +) + +// Error constants +var ( + ErrInvalidKey = errors.New("key is invalid or of invalid type") + ErrHashUnavailable = errors.New("the requested hash function is unavailable") + ErrNoTokenInRequest = errors.New("no token present in request") +) + +// 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 + ValidationErrorExpired // Exp validation failed + ValidationErrorNotValidYet // NBF validation failed +) + +// The error from Parse if token is not valid +type ValidationError struct { + err string + Errors uint32 // bitfield. see ValidationError... constants +} + +// Validation error is an error type +func (e ValidationError) Error() string { + if e.err == "" { + return "token is invalid" + } + return e.err +} + +// No errors +func (e *ValidationError) valid() bool { + if e.Errors > 0 { + return false + } + return true +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/example_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/example_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/example_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/example_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,52 @@ +package jwt_test + +import ( + "fmt" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go" + "time" +) + +func ExampleParse(myToken string, myLookupKey func(interface{}) (interface{}, error)) { + token, err := jwt.Parse(myToken, func(token *jwt.Token) (interface{}, error) { + return myLookupKey(token.Header["kid"]) + }) + + if err == nil && token.Valid { + fmt.Println("Your token is valid. I like your style.") + } else { + fmt.Println("This token is terrible! I cannot accept this.") + } +} + +func ExampleNew(mySigningKey []byte) (string, error) { + // Create the token + token := jwt.New(jwt.SigningMethodHS256) + // Set some claims + token.Claims["foo"] = "bar" + token.Claims["exp"] = time.Now().Add(time.Hour * 72).Unix() + // Sign and get the complete encoded token as a string + tokenString, err := token.SignedString(mySigningKey) + return tokenString, err +} + +func ExampleParse_errorChecking(myToken string, myLookupKey func(interface{}) (interface{}, error)) { + token, err := jwt.Parse(myToken, func(token *jwt.Token) (interface{}, error) { + return myLookupKey(token.Header["kid"]) + }) + + if token.Valid { + fmt.Println("You look nice today") + } else if ve, ok := err.(*jwt.ValidationError); ok { + if ve.Errors&jwt.ValidationErrorMalformed != 0 { + fmt.Println("That's not even a token") + } else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 { + // Token is either expired or not active yet + fmt.Println("Timing is everything") + } else { + fmt.Println("Couldn't handle this token:", err) + } + } else { + fmt.Println("Couldn't handle this token:", err) + } + +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/hmac.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/hmac.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/hmac.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/hmac.go 2016-05-17 20:01:14.000000000 +0000 @@ -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 ErrInvalidKey + } + + // 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 -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/hmac_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/hmac_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/hmac_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/hmac_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,91 @@ +package jwt_test + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go" + "io/ioutil" + "strings" + "testing" +) + +var hmacTestData = []struct { + name string + tokenString string + alg string + claims map[string]interface{} + valid bool +}{ + { + "web sample", + "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", + "HS256", + map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true}, + true, + }, + { + "HS384", + "eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJleHAiOjEuMzAwODE5MzhlKzA5LCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiam9lIn0.KWZEuOD5lbBxZ34g7F-SlVLAQ_r5KApWNWlZIIMyQVz5Zs58a7XdNzj5_0EcNoOy", + "HS384", + map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true}, + true, + }, + { + "HS512", + "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjEuMzAwODE5MzhlKzA5LCJodHRwOi8vZXhhbXBsZS5jb20vaXNfcm9vdCI6dHJ1ZSwiaXNzIjoiam9lIn0.CN7YijRX6Aw1n2jyI2Id1w90ja-DEMYiWixhYCyHnrZ1VfJRaFQz1bEbjjA5Fn4CLYaUG432dEYmSbS4Saokmw", + "HS512", + map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true}, + true, + }, + { + "web sample: invalid", + "eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXo", + "HS256", + map[string]interface{}{"iss": "joe", "exp": 1300819380, "http://example.com/is_root": true}, + false, + }, +} + +// Sample data from http://tools.ietf.org/html/draft-jones-json-web-signature-04#appendix-A.1 +var hmacTestKey, _ = ioutil.ReadFile("test/hmacTestKey") + +func TestHMACVerify(t *testing.T) { + for _, data := range hmacTestData { + parts := strings.Split(data.tokenString, ".") + + method := jwt.GetSigningMethod(data.alg) + err := method.Verify(strings.Join(parts[0:2], "."), parts[2], hmacTestKey) + if data.valid && err != nil { + t.Errorf("[%v] Error while verifying key: %v", data.name, err) + } + if !data.valid && err == nil { + t.Errorf("[%v] Invalid key passed validation", data.name) + } + } +} + +func TestHMACSign(t *testing.T) { + for _, data := range hmacTestData { + if data.valid { + parts := strings.Split(data.tokenString, ".") + method := jwt.GetSigningMethod(data.alg) + sig, err := method.Sign(strings.Join(parts[0:2], "."), hmacTestKey) + if err != nil { + t.Errorf("[%v] Error signing token: %v", data.name, err) + } + if sig != parts[2] { + t.Errorf("[%v] Incorrect signature.\nwas:\n%v\nexpecting:\n%v", data.name, sig, parts[2]) + } + } + } +} + +func BenchmarkHS256Signing(b *testing.B) { + benchmarkSigning(b, jwt.SigningMethodHS256, hmacTestKey) +} + +func BenchmarkHS384Signing(b *testing.B) { + benchmarkSigning(b, jwt.SigningMethodHS384, hmacTestKey) +} + +func BenchmarkHS512Signing(b *testing.B) { + benchmarkSigning(b, jwt.SigningMethodHS512, hmacTestKey) +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/LICENSE juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/LICENSE --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/LICENSE 2016-05-17 20:01:14.000000000 +0000 @@ -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 -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/parser.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/parser.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/parser.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/parser.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,113 @@ +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 +} + +// 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) { + parts := strings.Split(tokenString, ".") + if len(parts) != 3 { + return nil, &ValidationError{err: "token contains an invalid number of segments", Errors: ValidationErrorMalformed} + } + + var err error + token := &Token{Raw: tokenString} + // parse Header + var headerBytes []byte + if headerBytes, err = DecodeSegment(parts[0]); err != nil { + return token, &ValidationError{err: err.Error(), Errors: ValidationErrorMalformed} + } + if err = json.Unmarshal(headerBytes, &token.Header); err != nil { + return token, &ValidationError{err: err.Error(), Errors: ValidationErrorMalformed} + } + + // parse Claims + var claimBytes []byte + if claimBytes, err = DecodeSegment(parts[1]); err != nil { + return token, &ValidationError{err: err.Error(), Errors: ValidationErrorMalformed} + } + dec := json.NewDecoder(bytes.NewBuffer(claimBytes)) + if p.UseJSONNumber { + dec.UseNumber() + } + if err = dec.Decode(&token.Claims); err != nil { + return token, &ValidationError{err: err.Error(), Errors: ValidationErrorMalformed} + } + + // Lookup signature method + if method, ok := token.Header["alg"].(string); ok { + if token.Method = GetSigningMethod(method); token.Method == nil { + return token, &ValidationError{err: "signing method (alg) is unavailable.", Errors: ValidationErrorUnverifiable} + } + } else { + return token, &ValidationError{err: "signing method (alg) is unspecified.", Errors: 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, &ValidationError{err: fmt.Sprintf("signing method %v is invalid", alg), Errors: ValidationErrorSignatureInvalid} + } + } + + // Lookup key + var key interface{} + if keyFunc == nil { + // keyFunc was not provided. short circuiting validation + return token, &ValidationError{err: "no Keyfunc was provided.", Errors: ValidationErrorUnverifiable} + } + if key, err = keyFunc(token); err != nil { + // keyFunc returned an error + return token, &ValidationError{err: err.Error(), Errors: ValidationErrorUnverifiable} + } + + // Check expiration times + vErr := &ValidationError{} + now := TimeFunc().Unix() + if exp, ok := token.Claims["exp"].(float64); ok { + if now > int64(exp) { + vErr.err = "token is expired" + vErr.Errors |= ValidationErrorExpired + } + } + if nbf, ok := token.Claims["nbf"].(float64); ok { + if now < int64(nbf) { + vErr.err = "token is not valid yet" + vErr.Errors |= ValidationErrorNotValidYet + } + } + + // Perform validation + token.Signature = parts[2] + if err = token.Method.Verify(strings.Join(parts[0:2], "."), token.Signature, key); err != nil { + vErr.err = err.Error() + vErr.Errors |= ValidationErrorSignatureInvalid + } + + if vErr.valid() { + token.Valid = true + return token, nil + } + + return token, vErr +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/parser_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/parser_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/parser_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/parser_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,239 @@ +package jwt_test + +import ( + "encoding/json" + "fmt" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go" + "io/ioutil" + "net/http" + "reflect" + "testing" + "time" +) + +var ( + jwtTestDefaultKey []byte + defaultKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return jwtTestDefaultKey, nil } + emptyKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, nil } + errorKeyFunc jwt.Keyfunc = func(t *jwt.Token) (interface{}, error) { return nil, fmt.Errorf("error loading key") } + nilKeyFunc jwt.Keyfunc = nil +) + +var jwtTestData = []struct { + name string + tokenString string + keyfunc jwt.Keyfunc + claims map[string]interface{} + valid bool + errors uint32 + parser *jwt.Parser +}{ + { + "basic", + "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg", + defaultKeyFunc, + map[string]interface{}{"foo": "bar"}, + true, + 0, + nil, + }, + { + "basic expired", + "", // autogen + defaultKeyFunc, + map[string]interface{}{"foo": "bar", "exp": float64(time.Now().Unix() - 100)}, + false, + jwt.ValidationErrorExpired, + nil, + }, + { + "basic nbf", + "", // autogen + defaultKeyFunc, + map[string]interface{}{"foo": "bar", "nbf": float64(time.Now().Unix() + 100)}, + false, + jwt.ValidationErrorNotValidYet, + nil, + }, + { + "expired and nbf", + "", // autogen + defaultKeyFunc, + map[string]interface{}{"foo": "bar", "nbf": float64(time.Now().Unix() + 100), "exp": float64(time.Now().Unix() - 100)}, + false, + jwt.ValidationErrorNotValidYet | jwt.ValidationErrorExpired, + nil, + }, + { + "basic invalid", + "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.EhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg", + defaultKeyFunc, + map[string]interface{}{"foo": "bar"}, + false, + jwt.ValidationErrorSignatureInvalid, + nil, + }, + { + "basic nokeyfunc", + "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg", + nilKeyFunc, + map[string]interface{}{"foo": "bar"}, + false, + jwt.ValidationErrorUnverifiable, + nil, + }, + { + "basic nokey", + "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg", + emptyKeyFunc, + map[string]interface{}{"foo": "bar"}, + false, + jwt.ValidationErrorSignatureInvalid, + nil, + }, + { + "basic errorkey", + "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg", + errorKeyFunc, + map[string]interface{}{"foo": "bar"}, + false, + jwt.ValidationErrorUnverifiable, + nil, + }, + { + "invalid signing method", + "", + defaultKeyFunc, + map[string]interface{}{"foo": "bar"}, + false, + jwt.ValidationErrorSignatureInvalid, + &jwt.Parser{ValidMethods: []string{"HS256"}}, + }, + { + "valid signing method", + "", + defaultKeyFunc, + map[string]interface{}{"foo": "bar"}, + true, + 0, + &jwt.Parser{ValidMethods: []string{"RS256", "HS256"}}, + }, + { + "JSON Number", + "", + defaultKeyFunc, + map[string]interface{}{"foo": json.Number("123.4")}, + true, + 0, + &jwt.Parser{UseJSONNumber: true}, + }, +} + +func init() { + var e error + if jwtTestDefaultKey, e = ioutil.ReadFile("test/sample_key.pub"); e != nil { + panic(e) + } +} + +func makeSample(c map[string]interface{}) string { + key, e := ioutil.ReadFile("test/sample_key") + if e != nil { + panic(e.Error()) + } + + token := jwt.New(jwt.SigningMethodRS256) + token.Claims = c + s, e := token.SignedString(key) + + if e != nil { + panic(e.Error()) + } + + return s +} + +func TestParser_Parse(t *testing.T) { + for _, data := range jwtTestData { + if data.tokenString == "" { + data.tokenString = makeSample(data.claims) + } + + var token *jwt.Token + var err error + if data.parser != nil { + token, err = data.parser.Parse(data.tokenString, data.keyfunc) + } else { + token, err = jwt.Parse(data.tokenString, data.keyfunc) + } + + if !reflect.DeepEqual(data.claims, token.Claims) { + t.Errorf("[%v] Claims mismatch. Expecting: %v Got: %v", data.name, data.claims, token.Claims) + } + if data.valid && err != nil { + t.Errorf("[%v] Error while verifying token: %T:%v", data.name, err, err) + } + if !data.valid && err == nil { + t.Errorf("[%v] Invalid token passed validation", data.name) + } + if data.errors != 0 { + if err == nil { + t.Errorf("[%v] Expecting error. Didn't get one.", data.name) + } else { + // compare the bitfield part of the error + if e := err.(*jwt.ValidationError).Errors; e != data.errors { + t.Errorf("[%v] Errors don't match expectation. %v != %v", data.name, e, data.errors) + } + } + } + if data.valid && token.Signature == "" { + t.Errorf("[%v] Signature is left unpopulated after parsing", data.name) + } + } +} + +func TestParseRequest(t *testing.T) { + // Bearer token request + for _, data := range jwtTestData { + // FIXME: custom parsers are not supported by this helper. skip tests that require them + if data.parser != nil { + t.Logf("Skipping [%v]. Custom parsers are not supported by ParseRequest", data.name) + continue + } + + if data.tokenString == "" { + data.tokenString = makeSample(data.claims) + } + + r, _ := http.NewRequest("GET", "/", nil) + r.Header.Set("Authorization", fmt.Sprintf("Bearer %v", data.tokenString)) + token, err := jwt.ParseFromRequest(r, data.keyfunc) + + if token == nil { + t.Errorf("[%v] Token was not found: %v", data.name, err) + continue + } + if !reflect.DeepEqual(data.claims, token.Claims) { + t.Errorf("[%v] Claims mismatch. Expecting: %v Got: %v", data.name, data.claims, token.Claims) + } + if data.valid && err != nil { + t.Errorf("[%v] Error while verifying token: %v", data.name, err) + } + if !data.valid && err == nil { + t.Errorf("[%v] Invalid token passed validation", data.name) + } + } +} + +// Helper method for benchmarking various methods +func benchmarkSigning(b *testing.B, method jwt.SigningMethod, key interface{}) { + t := jwt.New(method) + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + if _, err := t.SignedString(key); err != nil { + b.Fatal(err) + } + } + }) + +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/README.md juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/README.md --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/README.md 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/README.md 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,69 @@ +A [go](http://www.golang.org) (or 'golang' for search engine friendliness) implementation of [JSON Web Tokens](http://self-issued.info/docs/draft-jones-json-web-token.html) + +[![Build Status](https://travis-ci.org/dgrijalva/jwt-go.svg?branch=master)](https://travis-ci.org/dgrijalva/jwt-go) + +**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? + +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 RSA256 and HMAC SHA256, though hooks are present for adding your own. + +## Parse and Verify + +Parsing and verifying tokens is pretty straight forward. You pass in the token and a function for looking up the key. This is done as a callback since you may need to parse the token to find out what signing method and key was used. + +```go + token, err := jwt.Parse(myToken, func(token *jwt.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"]) + } + return myLookupKey(token.Header["kid"]) + }) + + if err == nil && token.Valid { + deliverGoodness("!") + } else { + deliverUtterRejection(":(") + } +``` + +## Create a token + +```go + // Create the token + token := jwt.New(jwt.SigningMethodHS256) + // Set some claims + token.Claims["foo"] = "bar" + token.Claims["exp"] = time.Now().Add(time.Hour * 72).Unix() + // Sign and get the complete encoded token as a string + tokenString, err := token.SignedString(mySigningKey) +``` + +## 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 + +## 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. + +## 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. For a more http centric example, see [this gist](https://gist.github.com/cryptix/45c33ecf0ae54828e63b). diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,114 @@ +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 either a PEM encoded PKCS1 or PKCS8 RSA public key as +// []byte, or 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 + + switch k := key.(type) { + case []byte: + if rsaKey, err = ParseRSAPublicKeyFromPEM(k); err != nil { + return err + } + case *rsa.PublicKey: + rsaKey = k + default: + return ErrInvalidKey + } + + // 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 either a PEM encoded PKCS1 or PKCS8 RSA private key as +// []byte, or an rsa.PrivateKey structure. +func (m *SigningMethodRSA) Sign(signingString string, key interface{}) (string, error) { + var err error + var rsaKey *rsa.PrivateKey + + switch k := key.(type) { + case []byte: + if rsaKey, err = ParseRSAPrivateKeyFromPEM(k); err != nil { + return "", err + } + case *rsa.PrivateKey: + rsaKey = k + default: + 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 -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_pss.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_pss.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_pss.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_pss.go 2016-05-17 20:01:14.000000000 +0000 @@ -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 "", 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.SignPSS(rand.Reader, rsaKey, m.Hash, hasher.Sum(nil), m.Options); err == nil { + return EncodeSegment(sigBytes), nil + } else { + return "", err + } +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_pss_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_pss_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_pss_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_pss_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,96 @@ +// +build go1.4 + +package jwt_test + +import ( + "crypto/rsa" + "io/ioutil" + "strings" + "testing" + + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go" +) + +var rsaPSSTestData = []struct { + name string + tokenString string + alg string + claims map[string]interface{} + valid bool +}{ + { + "Basic PS256", + "eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.PPG4xyDVY8ffp4CcxofNmsTDXsrVG2npdQuibLhJbv4ClyPTUtR5giNSvuxo03kB6I8VXVr0Y9X7UxhJVEoJOmULAwRWaUsDnIewQa101cVhMa6iR8X37kfFoiZ6NkS-c7henVkkQWu2HtotkEtQvN5hFlk8IevXXPmvZlhQhwzB1sGzGYnoi1zOfuL98d3BIjUjtlwii5w6gYG2AEEzp7HnHCsb3jIwUPdq86Oe6hIFjtBwduIK90ca4UqzARpcfwxHwVLMpatKask00AgGVI0ysdk0BLMjmLutquD03XbThHScC2C2_Pp4cHWgMzvbgLU2RYYZcZRKr46QeNgz9w", + "PS256", + map[string]interface{}{"foo": "bar"}, + true, + }, + { + "Basic PS384", + "eyJhbGciOiJQUzM4NCIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.w7-qqgj97gK4fJsq_DCqdYQiylJjzWONvD0qWWWhqEOFk2P1eDULPnqHRnjgTXoO4HAw4YIWCsZPet7nR3Xxq4ZhMqvKW8b7KlfRTb9cH8zqFvzMmybQ4jv2hKc3bXYqVow3AoR7hN_CWXI3Dv6Kd2X5xhtxRHI6IL39oTVDUQ74LACe-9t4c3QRPuj6Pq1H4FAT2E2kW_0KOc6EQhCLWEhm2Z2__OZskDC8AiPpP8Kv4k2vB7l0IKQu8Pr4RcNBlqJdq8dA5D3hk5TLxP8V5nG1Ib80MOMMqoS3FQvSLyolFX-R_jZ3-zfq6Ebsqr0yEb0AH2CfsECF7935Pa0FKQ", + "PS384", + map[string]interface{}{"foo": "bar"}, + true, + }, + { + "Basic PS512", + "eyJhbGciOiJQUzUxMiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.GX1HWGzFaJevuSLavqqFYaW8_TpvcjQ8KfC5fXiSDzSiT9UD9nB_ikSmDNyDILNdtjZLSvVKfXxZJqCfefxAtiozEDDdJthZ-F0uO4SPFHlGiXszvKeodh7BuTWRI2wL9-ZO4mFa8nq3GMeQAfo9cx11i7nfN8n2YNQ9SHGovG7_T_AvaMZB_jT6jkDHpwGR9mz7x1sycckEo6teLdHRnH_ZdlHlxqknmyTu8Odr5Xh0sJFOL8BepWbbvIIn-P161rRHHiDWFv6nhlHwZnVzjx7HQrWSGb6-s2cdLie9QL_8XaMcUpjLkfOMKkDOfHo6AvpL7Jbwi83Z2ZTHjJWB-A", + "PS512", + map[string]interface{}{"foo": "bar"}, + true, + }, + { + "basic PS256 invalid: foo => bar", + "eyJhbGciOiJQUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.PPG4xyDVY8ffp4CcxofNmsTDXsrVG2npdQuibLhJbv4ClyPTUtR5giNSvuxo03kB6I8VXVr0Y9X7UxhJVEoJOmULAwRWaUsDnIewQa101cVhMa6iR8X37kfFoiZ6NkS-c7henVkkQWu2HtotkEtQvN5hFlk8IevXXPmvZlhQhwzB1sGzGYnoi1zOfuL98d3BIjUjtlwii5w6gYG2AEEzp7HnHCsb3jIwUPdq86Oe6hIFjtBwduIK90ca4UqzARpcfwxHwVLMpatKask00AgGVI0ysdk0BLMjmLutquD03XbThHScC2C2_Pp4cHWgMzvbgLU2RYYZcZRKr46QeNgz9W", + "PS256", + map[string]interface{}{"foo": "bar"}, + false, + }, +} + +func TestRSAPSSVerify(t *testing.T) { + var err error + + key, _ := ioutil.ReadFile("test/sample_key.pub") + var rsaPSSKey *rsa.PublicKey + if rsaPSSKey, err = jwt.ParseRSAPublicKeyFromPEM(key); err != nil { + t.Errorf("Unable to parse RSA public key: %v", err) + } + + for _, data := range rsaPSSTestData { + parts := strings.Split(data.tokenString, ".") + + method := jwt.GetSigningMethod(data.alg) + err := method.Verify(strings.Join(parts[0:2], "."), parts[2], rsaPSSKey) + if data.valid && err != nil { + t.Errorf("[%v] Error while verifying key: %v", data.name, err) + } + if !data.valid && err == nil { + t.Errorf("[%v] Invalid key passed validation", data.name) + } + } +} + +func TestRSAPSSSign(t *testing.T) { + var err error + + key, _ := ioutil.ReadFile("test/sample_key") + var rsaPSSKey *rsa.PrivateKey + if rsaPSSKey, err = jwt.ParseRSAPrivateKeyFromPEM(key); err != nil { + t.Errorf("Unable to parse RSA private key: %v", err) + } + + for _, data := range rsaPSSTestData { + if data.valid { + parts := strings.Split(data.tokenString, ".") + method := jwt.GetSigningMethod(data.alg) + sig, err := method.Sign(strings.Join(parts[0:2], "."), rsaPSSKey) + if err != nil { + t.Errorf("[%v] Error signing token: %v", data.name, err) + } + if sig == parts[2] { + t.Errorf("[%v] Signatures shouldn't match\nnew:\n%v\noriginal:\n%v", data.name, sig, parts[2]) + } + } + } +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,174 @@ +package jwt_test + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go" + "io/ioutil" + "strings" + "testing" +) + +var rsaTestData = []struct { + name string + tokenString string + alg string + claims map[string]interface{} + valid bool +}{ + { + "Basic RS256", + "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.FhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg", + "RS256", + map[string]interface{}{"foo": "bar"}, + true, + }, + { + "Basic RS384", + "eyJhbGciOiJSUzM4NCIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.W-jEzRfBigtCWsinvVVuldiuilzVdU5ty0MvpLaSaqK9PlAWWlDQ1VIQ_qSKzwL5IXaZkvZFJXT3yL3n7OUVu7zCNJzdwznbC8Z-b0z2lYvcklJYi2VOFRcGbJtXUqgjk2oGsiqUMUMOLP70TTefkpsgqDxbRh9CDUfpOJgW-dU7cmgaoswe3wjUAUi6B6G2YEaiuXC0XScQYSYVKIzgKXJV8Zw-7AN_DBUI4GkTpsvQ9fVVjZM9csQiEXhYekyrKu1nu_POpQonGd8yqkIyXPECNmmqH5jH4sFiF67XhD7_JpkvLziBpI-uh86evBUadmHhb9Otqw3uV3NTaXLzJw", + "RS384", + map[string]interface{}{"foo": "bar"}, + true, + }, + { + "Basic RS512", + "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJmb28iOiJiYXIifQ.zBlLlmRrUxx4SJPUbV37Q1joRcI9EW13grnKduK3wtYKmDXbgDpF1cZ6B-2Jsm5RB8REmMiLpGms-EjXhgnyh2TSHE-9W2gA_jvshegLWtwRVDX40ODSkTb7OVuaWgiy9y7llvcknFBTIg-FnVPVpXMmeV_pvwQyhaz1SSwSPrDyxEmksz1hq7YONXhXPpGaNbMMeDTNP_1oj8DZaqTIL9TwV8_1wb2Odt_Fy58Ke2RVFijsOLdnyEAjt2n9Mxihu9i3PhNBkkxa2GbnXBfq3kzvZ_xxGGopLdHhJjcGWXO-NiwI9_tiu14NRv4L2xC0ItD9Yz68v2ZIZEp_DuzwRQ", + "RS512", + map[string]interface{}{"foo": "bar"}, + true, + }, + { + "basic invalid: foo => bar", + "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.EhkiHkoESI_cG3NPigFrxEk9Z60_oXrOT2vGm9Pn6RDgYNovYORQmmA0zs1AoAOf09ly2Nx2YAg6ABqAYga1AcMFkJljwxTT5fYphTuqpWdy4BELeSYJx5Ty2gmr8e7RonuUztrdD5WfPqLKMm1Ozp_T6zALpRmwTIW0QPnaBXaQD90FplAg46Iy1UlDKr-Eupy0i5SLch5Q-p2ZpaL_5fnTIUDlxC3pWhJTyx_71qDI-mAA_5lE_VdroOeflG56sSmDxopPEG3bFlSu1eowyBfxtu0_CuVd-M42RU75Zc4Gsj6uV77MBtbMrf4_7M_NUTSgoIF3fRqxrj0NzihIBg", + "RS256", + map[string]interface{}{"foo": "bar"}, + false, + }, +} + +func TestRSAVerify(t *testing.T) { + key, _ := ioutil.ReadFile("test/sample_key.pub") + + for _, data := range rsaTestData { + parts := strings.Split(data.tokenString, ".") + + method := jwt.GetSigningMethod(data.alg) + err := method.Verify(strings.Join(parts[0:2], "."), parts[2], key) + if data.valid && err != nil { + t.Errorf("[%v] Error while verifying key: %v", data.name, err) + } + if !data.valid && err == nil { + t.Errorf("[%v] Invalid key passed validation", data.name) + } + } +} + +func TestRSASign(t *testing.T) { + key, _ := ioutil.ReadFile("test/sample_key") + + for _, data := range rsaTestData { + if data.valid { + parts := strings.Split(data.tokenString, ".") + method := jwt.GetSigningMethod(data.alg) + sig, err := method.Sign(strings.Join(parts[0:2], "."), key) + if err != nil { + t.Errorf("[%v] Error signing token: %v", data.name, err) + } + if sig != parts[2] { + t.Errorf("[%v] Incorrect signature.\nwas:\n%v\nexpecting:\n%v", data.name, sig, parts[2]) + } + } + } +} + +func TestRSAVerifyWithPreParsedPrivateKey(t *testing.T) { + key, _ := ioutil.ReadFile("test/sample_key.pub") + parsedKey, err := jwt.ParseRSAPublicKeyFromPEM(key) + if err != nil { + t.Fatal(err) + } + testData := rsaTestData[0] + parts := strings.Split(testData.tokenString, ".") + err = jwt.SigningMethodRS256.Verify(strings.Join(parts[0:2], "."), parts[2], parsedKey) + if err != nil { + t.Errorf("[%v] Error while verifying key: %v", testData.name, err) + } +} + +func TestRSAWithPreParsedPrivateKey(t *testing.T) { + key, _ := ioutil.ReadFile("test/sample_key") + parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key) + if err != nil { + t.Fatal(err) + } + testData := rsaTestData[0] + parts := strings.Split(testData.tokenString, ".") + sig, err := jwt.SigningMethodRS256.Sign(strings.Join(parts[0:2], "."), parsedKey) + if err != nil { + t.Errorf("[%v] Error signing token: %v", testData.name, err) + } + if sig != parts[2] { + t.Errorf("[%v] Incorrect signature.\nwas:\n%v\nexpecting:\n%v", testData.name, sig, parts[2]) + } +} + +func TestRSAKeyParsing(t *testing.T) { + key, _ := ioutil.ReadFile("test/sample_key") + pubKey, _ := ioutil.ReadFile("test/sample_key.pub") + badKey := []byte("All your base are belong to key") + + // Test parsePrivateKey + if _, e := jwt.ParseRSAPrivateKeyFromPEM(key); e != nil { + t.Errorf("Failed to parse valid private key: %v", e) + } + + if k, e := jwt.ParseRSAPrivateKeyFromPEM(pubKey); e == nil { + t.Errorf("Parsed public key as valid private key: %v", k) + } + + if k, e := jwt.ParseRSAPrivateKeyFromPEM(badKey); e == nil { + t.Errorf("Parsed invalid key as valid private key: %v", k) + } + + // Test parsePublicKey + if _, e := jwt.ParseRSAPublicKeyFromPEM(pubKey); e != nil { + t.Errorf("Failed to parse valid public key: %v", e) + } + + if k, e := jwt.ParseRSAPublicKeyFromPEM(key); e == nil { + t.Errorf("Parsed private key as valid public key: %v", k) + } + + if k, e := jwt.ParseRSAPublicKeyFromPEM(badKey); e == nil { + t.Errorf("Parsed invalid key as valid private key: %v", k) + } + +} + +func BenchmarkRS256Signing(b *testing.B) { + key, _ := ioutil.ReadFile("test/sample_key") + parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key) + if err != nil { + b.Fatal(err) + } + + benchmarkSigning(b, jwt.SigningMethodRS256, parsedKey) +} + +func BenchmarkRS384Signing(b *testing.B) { + key, _ := ioutil.ReadFile("test/sample_key") + parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key) + if err != nil { + b.Fatal(err) + } + + benchmarkSigning(b, jwt.SigningMethodRS384, parsedKey) +} + +func BenchmarkRS512Signing(b *testing.B) { + key, _ := ioutil.ReadFile("test/sample_key") + parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key) + if err != nil { + b.Fatal(err) + } + + benchmarkSigning(b, jwt.SigningMethodRS512, parsedKey) +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_utils.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_utils.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_utils.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/rsa_utils.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,68 @@ +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") +) + +// 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, ErrNotRSAPrivateKey + } + + return pkey, nil +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/signing_method.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/signing_method.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/signing_method.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/signing_method.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,24 @@ +package jwt + +var signingMethods = map[string]func() SigningMethod{} + +// 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) { + signingMethods[alg] = f +} + +// Get a signing method from an "alg" string +func GetSigningMethod(alg string) (method SigningMethod) { + if methodF, ok := signingMethods[alg]; ok { + method = methodF() + } + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec256-private.pem juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec256-private.pem --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec256-private.pem 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec256-private.pem 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIAh5qA3rmqQQuu0vbKV/+zouz/y/Iy2pLpIcWUSyImSwoAoGCCqGSM49 +AwEHoUQDQgAEYD54V/vp+54P9DXarYqx4MPcm+HKRIQzNasYSoRQHQ/6S6Ps8tpM +cT+KvIIC8W/e9k0W7Cm72M1P9jU7SLf/vg== +-----END EC PRIVATE KEY----- diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec256-public.pem juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec256-public.pem --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec256-public.pem 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec256-public.pem 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYD54V/vp+54P9DXarYqx4MPcm+HK +RIQzNasYSoRQHQ/6S6Ps8tpMcT+KvIIC8W/e9k0W7Cm72M1P9jU7SLf/vg== +-----END PUBLIC KEY----- diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec384-private.pem juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec384-private.pem --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec384-private.pem 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec384-private.pem 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDCaCvMHKhcG/qT7xsNLYnDT7sE/D+TtWIol1ROdaK1a564vx5pHbsRy +SEKcIxISi1igBwYFK4EEACKhZANiAATYa7rJaU7feLMqrAx6adZFNQOpaUH/Uylb +ZLriOLON5YFVwtVUpO1FfEXZUIQpptRPtc5ixIPY658yhBSb6irfIJUSP9aYTflJ +GKk/mDkK4t8mWBzhiD5B6jg9cEGhGgA= +-----END EC PRIVATE KEY----- diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec384-public.pem juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec384-public.pem --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec384-public.pem 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec384-public.pem 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE2Gu6yWlO33izKqwMemnWRTUDqWlB/1Mp +W2S64jizjeWBVcLVVKTtRXxF2VCEKabUT7XOYsSD2OufMoQUm+oq3yCVEj/WmE35 +SRipP5g5CuLfJlgc4Yg+Qeo4PXBBoRoA +-----END PUBLIC KEY----- diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec512-private.pem juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec512-private.pem --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec512-private.pem 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec512-private.pem 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,7 @@ +-----BEGIN EC PRIVATE KEY----- +MIHcAgEBBEIB0pE4uFaWRx7t03BsYlYvF1YvKaBGyvoakxnodm9ou0R9wC+sJAjH +QZZJikOg4SwNqgQ/hyrOuDK2oAVHhgVGcYmgBwYFK4EEACOhgYkDgYYABAAJXIuw +12MUzpHggia9POBFYXSxaOGKGbMjIyDI+6q7wi7LMw3HgbaOmgIqFG72o8JBQwYN +4IbXHf+f86CRY1AA2wHzbHvt6IhkCXTNxBEffa1yMUgu8n9cKKF2iLgyQKcKqW33 +8fGOw/n3Rm2Yd/EB56u2rnD29qS+nOM9eGS+gy39OQ== +-----END EC PRIVATE KEY----- diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec512-public.pem juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec512-public.pem --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec512-public.pem 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/ec512-public.pem 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQACVyLsNdjFM6R4IImvTzgRWF0sWjh +ihmzIyMgyPuqu8IuyzMNx4G2jpoCKhRu9qPCQUMGDeCG1x3/n/OgkWNQANsB82x7 +7eiIZAl0zcQRH32tcjFILvJ/XCihdoi4MkCnCqlt9/HxjsP590ZtmHfxAeertq5w +9vakvpzjPXhkvoMt/Tk= +-----END PUBLIC KEY----- diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/hmacTestKey juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/hmacTestKey --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/hmacTestKey 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/hmacTestKey 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1 @@ +#5K+¥¼ƒ~ew{¦Z³(æðTÉ(©„²ÒP.¿ÓûZ’ÒGï–Š´Ãwb="=.!r.OÀÍšõgЀ£ \ No newline at end of file diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/sample_key juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/sample_key --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/sample_key 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/sample_key 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA4f5wg5l2hKsTeNem/V41fGnJm6gOdrj8ym3rFkEU/wT8RDtn +SgFEZOQpHEgQ7JL38xUfU0Y3g6aYw9QT0hJ7mCpz9Er5qLaMXJwZxzHzAahlfA0i +cqabvJOMvQtzD6uQv6wPEyZtDTWiQi9AXwBpHssPnpYGIn20ZZuNlX2BrClciHhC +PUIIZOQn/MmqTD31jSyjoQoV7MhhMTATKJx2XrHhR+1DcKJzQBSTAGnpYVaqpsAR +ap+nwRipr3nUTuxyGohBTSmjJ2usSeQXHI3bODIRe1AuTyHceAbewn8b462yEWKA +Rdpd9AjQW5SIVPfdsz5B6GlYQ5LdYKtznTuy7wIDAQABAoIBAQCwia1k7+2oZ2d3 +n6agCAbqIE1QXfCmh41ZqJHbOY3oRQG3X1wpcGH4Gk+O+zDVTV2JszdcOt7E5dAy +MaomETAhRxB7hlIOnEN7WKm+dGNrKRvV0wDU5ReFMRHg31/Lnu8c+5BvGjZX+ky9 +POIhFFYJqwCRlopGSUIxmVj5rSgtzk3iWOQXr+ah1bjEXvlxDOWkHN6YfpV5ThdE +KdBIPGEVqa63r9n2h+qazKrtiRqJqGnOrHzOECYbRFYhexsNFz7YT02xdfSHn7gM +IvabDDP/Qp0PjE1jdouiMaFHYnLBbgvlnZW9yuVf/rpXTUq/njxIXMmvmEyyvSDn +FcFikB8pAoGBAPF77hK4m3/rdGT7X8a/gwvZ2R121aBcdPwEaUhvj/36dx596zvY +mEOjrWfZhF083/nYWE2kVquj2wjs+otCLfifEEgXcVPTnEOPO9Zg3uNSL0nNQghj +FuD3iGLTUBCtM66oTe0jLSslHe8gLGEQqyMzHOzYxNqibxcOZIe8Qt0NAoGBAO+U +I5+XWjWEgDmvyC3TrOSf/KCGjtu0TSv30ipv27bDLMrpvPmD/5lpptTFwcxvVhCs +2b+chCjlghFSWFbBULBrfci2FtliClOVMYrlNBdUSJhf3aYSG2Doe6Bgt1n2CpNn +/iu37Y3NfemZBJA7hNl4dYe+f+uzM87cdQ214+jrAoGAXA0XxX8ll2+ToOLJsaNT +OvNB9h9Uc5qK5X5w+7G7O998BN2PC/MWp8H+2fVqpXgNENpNXttkRm1hk1dych86 +EunfdPuqsX+as44oCyJGFHVBnWpm33eWQw9YqANRI+pCJzP08I5WK3osnPiwshd+ +hR54yjgfYhBFNI7B95PmEQkCgYBzFSz7h1+s34Ycr8SvxsOBWxymG5zaCsUbPsL0 +4aCgLScCHb9J+E86aVbbVFdglYa5Id7DPTL61ixhl7WZjujspeXZGSbmq0Kcnckb +mDgqkLECiOJW2NHP/j0McAkDLL4tysF8TLDO8gvuvzNC+WQ6drO2ThrypLVZQ+ry +eBIPmwKBgEZxhqa0gVvHQG/7Od69KWj4eJP28kq13RhKay8JOoN0vPmspXJo1HY3 +CKuHRG+AP579dncdUnOMvfXOtkdM4vk0+hWASBQzM9xzVcztCa+koAugjVaLS9A+ +9uQoqEeVNTckxx0S2bYevRy7hGQmUJTyQm3j1zEUR5jpdbL83Fbq +-----END RSA PRIVATE KEY----- diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/sample_key.pub juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/sample_key.pub --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/sample_key.pub 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/test/sample_key.pub 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4f5wg5l2hKsTeNem/V41 +fGnJm6gOdrj8ym3rFkEU/wT8RDtnSgFEZOQpHEgQ7JL38xUfU0Y3g6aYw9QT0hJ7 +mCpz9Er5qLaMXJwZxzHzAahlfA0icqabvJOMvQtzD6uQv6wPEyZtDTWiQi9AXwBp +HssPnpYGIn20ZZuNlX2BrClciHhCPUIIZOQn/MmqTD31jSyjoQoV7MhhMTATKJx2 +XrHhR+1DcKJzQBSTAGnpYVaqpsARap+nwRipr3nUTuxyGohBTSmjJ2usSeQXHI3b +ODIRe1AuTyHceAbewn8b462yEWKARdpd9AjQW5SIVPfdsz5B6GlYQ5LdYKtznTuy +7wIDAQAB +-----END PUBLIC KEY----- diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/token.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/token.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/token.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/token.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,126 @@ +package jwt + +import ( + "encoding/base64" + "encoding/json" + "net/http" + "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 propries 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 map[string]interface{} // 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 &Token{ + Header: map[string]interface{}{ + "typ": "JWT", + "alg": method.Alg(), + }, + Claims: make(map[string]interface{}), + 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 source map[string]interface{} + if i == 0 { + source = t.Header + } else { + source = t.Claims + } + + var jsonValue []byte + if jsonValue, err = json.Marshal(source); 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) +} + +// Try to find the token in an http.Request. +// This method will call ParseMultipartForm if there's no token in the header. +// Currently, it looks in the Authorization header as well as +// looking for an 'access_token' request parameter in req.Form. +func ParseFromRequest(req *http.Request, keyFunc Keyfunc) (token *Token, err error) { + + // Look for an Authorization header + if ah := req.Header.Get("Authorization"); ah != "" { + // Should be a bearer token + if len(ah) > 6 && strings.ToUpper(ah[0:6]) == "BEARER" { + return Parse(ah[7:], keyFunc) + } + } + + // Look for "access_token" parameter + req.ParseMultipartForm(10e6) + if tokStr := req.Form.Get("access_token"); tokStr != "" { + return Parse(tokStr, keyFunc) + } + + return nil, ErrNoTokenInRequest + +} + +// 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 -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/.travis.yml juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/.travis.yml --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/.travis.yml 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/.travis.yml 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,7 @@ +language: go + +go: + - 1.3.3 + - 1.4.2 + - 1.5 + - tip diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/dgrijalva/jwt-go/VERSION_HISTORY.md 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,67 @@ +## `jwt-go` Version History + +#### 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 -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/LICENSE juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/LICENSE --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/LICENSE 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,27 @@ +Copyright (c) 2009 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 -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/PATENTS juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/PATENTS --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/PATENTS 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/PATENTS 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google 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, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/bmp-string_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/bmp-string_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/bmp-string_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/bmp-string_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,63 @@ +// Copyright 2015 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 pkcs12 + +import ( + "bytes" + "encoding/hex" + "testing" +) + +var bmpStringTests = []struct { + in string + expectedHex string + shouldFail bool +}{ + {"", "0000", false}, + // Example from https://tools.ietf.org/html/rfc7292#appendix-B. + {"Beavis", "0042006500610076006900730000", false}, + // Some characters from the "Letterlike Symbols Unicode block". + {"\u2115 - Double-struck N", "21150020002d00200044006f00750062006c0065002d00730074007200750063006b0020004e0000", false}, + // any character outside the BMP should trigger an error. + {"\U0001f000 East wind (Mahjong)", "", true}, +} + +func TestBMPString(t *testing.T) { + for i, test := range bmpStringTests { + expected, err := hex.DecodeString(test.expectedHex) + if err != nil { + t.Fatalf("#%d: failed to decode expectation", i) + } + + out, err := bmpString(test.in) + if err == nil && test.shouldFail { + t.Errorf("#%d: expected to fail, but produced %x", i, out) + continue + } + + if err != nil && !test.shouldFail { + t.Errorf("#%d: failed unexpectedly: %s", i, err) + continue + } + + if !test.shouldFail { + if !bytes.Equal(out, expected) { + t.Errorf("#%d: expected %s, got %x", i, test.expectedHex, out) + continue + } + + roundTrip, err := decodeBMPString(out) + if err != nil { + t.Errorf("#%d: decoding output gave an error: %s", i, err) + continue + } + + if roundTrip != test.in { + t.Errorf("#%d: decoding output resulted in %q, but it should have been %q", i, roundTrip, test.in) + continue + } + } + } +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/crypto_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/crypto_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/crypto_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/crypto_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,125 @@ +// Copyright 2015 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 pkcs12 + +import ( + "bytes" + "crypto/x509/pkix" + "encoding/asn1" + "testing" +) + +var sha1WithTripleDES = asn1.ObjectIdentifier([]int{1, 2, 840, 113549, 1, 12, 1, 3}) + +func TestPbDecrypterFor(t *testing.T) { + params, _ := asn1.Marshal(pbeParams{ + Salt: []byte{1, 2, 3, 4, 5, 6, 7, 8}, + Iterations: 2048, + }) + alg := pkix.AlgorithmIdentifier{ + Algorithm: asn1.ObjectIdentifier([]int{1, 2, 3}), + Parameters: asn1.RawValue{ + FullBytes: params, + }, + } + + pass, _ := bmpString("Sesame open") + + _, _, err := pbDecrypterFor(alg, pass) + if _, ok := err.(NotImplementedError); !ok { + t.Errorf("expected not implemented error, got: %T %s", err, err) + } + + alg.Algorithm = sha1WithTripleDES + cbc, blockSize, err := pbDecrypterFor(alg, pass) + if err != nil { + t.Errorf("unexpected error from pbDecrypterFor %v", err) + } + if blockSize != 8 { + t.Errorf("unexpected block size %d, wanted 8", blockSize) + } + + plaintext := []byte{1, 2, 3, 4, 5, 6, 7, 8} + expectedCiphertext := []byte{185, 73, 135, 249, 137, 1, 122, 247} + ciphertext := make([]byte, len(plaintext)) + cbc.CryptBlocks(ciphertext, plaintext) + + if bytes.Compare(ciphertext, expectedCiphertext) != 0 { + t.Errorf("bad ciphertext, got %x but wanted %x", ciphertext, expectedCiphertext) + } +} + +var pbDecryptTests = []struct { + in []byte + expected []byte + expectedError error +}{ + { + []byte("\x33\x73\xf3\x9f\xda\x49\xae\xfc\xa0\x9a\xdf\x5a\x58\xa0\xea\x46"), // 7 padding bytes + []byte("A secret!"), + nil, + }, + { + []byte("\x33\x73\xf3\x9f\xda\x49\xae\xfc\x96\x24\x2f\x71\x7e\x32\x3f\xe7"), // 8 padding bytes + []byte("A secret"), + nil, + }, + { + []byte("\x35\x0c\xc0\x8d\xab\xa9\x5d\x30\x7f\x9a\xec\x6a\xd8\x9b\x9c\xd9"), // 9 padding bytes, incorrect + nil, + ErrDecryption, + }, + { + []byte("\xb2\xf9\x6e\x06\x60\xae\x20\xcf\x08\xa0\x7b\xd9\x6b\x20\xef\x41"), // incorrect padding bytes: [ ... 0x04 0x02 ] + nil, + ErrDecryption, + }, +} + +func TestPbDecrypt(t *testing.T) { + for i, test := range pbDecryptTests { + decryptable := testDecryptable{ + data: test.in, + algorithm: pkix.AlgorithmIdentifier{ + Algorithm: sha1WithTripleDES, + Parameters: pbeParams{ + Salt: []byte("\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8"), + Iterations: 4096, + }.RawASN1(), + }, + } + password, _ := bmpString("sesame") + + plaintext, err := pbDecrypt(decryptable, password) + if err != test.expectedError { + t.Errorf("#%d: got error %q, but wanted %q", i, err, test.expectedError) + continue + } + + if !bytes.Equal(plaintext, test.expected) { + t.Errorf("#%d: got %x, but wanted %x", i, plaintext, test.expected) + } + } +} + +type testDecryptable struct { + data []byte + algorithm pkix.AlgorithmIdentifier +} + +func (d testDecryptable) Algorithm() pkix.AlgorithmIdentifier { return d.algorithm } +func (d testDecryptable) Data() []byte { return d.data } + +func (params pbeParams) RawASN1() (raw asn1.RawValue) { + asn1Bytes, err := asn1.Marshal(params) + if err != nil { + panic(err) + } + _, err = asn1.Unmarshal(asn1Bytes, &raw) + if err != nil { + panic(err) + } + return +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/internal/rc2/bench_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/internal/rc2/bench_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/internal/rc2/bench_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/internal/rc2/bench_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,27 @@ +// Copyright 2015 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 rc2 + +import ( + "testing" +) + +func BenchmarkEncrypt(b *testing.B) { + r, _ := New([]byte{0, 0, 0, 0, 0, 0, 0, 0}, 64) + b.ResetTimer() + var src [8]byte + for i := 0; i < b.N; i++ { + r.Encrypt(src[:], src[:]) + } +} + +func BenchmarkDecrypt(b *testing.B) { + r, _ := New([]byte{0, 0, 0, 0, 0, 0, 0, 0}, 64) + b.ResetTimer() + var src [8]byte + for i := 0; i < b.N; i++ { + r.Decrypt(src[:], src[:]) + } +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/internal/rc2/rc2_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/internal/rc2/rc2_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/internal/rc2/rc2_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/internal/rc2/rc2_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,93 @@ +// Copyright 2015 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 rc2 + +import ( + "bytes" + "encoding/hex" + "testing" +) + +func TestEncryptDecrypt(t *testing.T) { + + // TODO(dgryski): add the rest of the test vectors from the RFC + var tests = []struct { + key string + plain string + cipher string + t1 int + }{ + { + "0000000000000000", + "0000000000000000", + "ebb773f993278eff", + 63, + }, + { + "ffffffffffffffff", + "ffffffffffffffff", + "278b27e42e2f0d49", + 64, + }, + { + "3000000000000000", + "1000000000000001", + "30649edf9be7d2c2", + 64, + }, + { + "88", + "0000000000000000", + "61a8a244adacccf0", + 64, + }, + { + "88bca90e90875a", + "0000000000000000", + "6ccf4308974c267f", + 64, + }, + { + "88bca90e90875a7f0f79c384627bafb2", + "0000000000000000", + "1a807d272bbe5db1", + 64, + }, + { + "88bca90e90875a7f0f79c384627bafb2", + "0000000000000000", + "2269552ab0f85ca6", + 128, + }, + { + "88bca90e90875a7f0f79c384627bafb216f80a6f85920584c42fceb0be255daf1e", + "0000000000000000", + "5b78d3a43dfff1f1", + 129, + }, + } + + for _, tt := range tests { + k, _ := hex.DecodeString(tt.key) + p, _ := hex.DecodeString(tt.plain) + c, _ := hex.DecodeString(tt.cipher) + + b, _ := New(k, tt.t1) + + var dst [8]byte + + b.Encrypt(dst[:], p) + + if !bytes.Equal(dst[:], c) { + t.Errorf("encrypt failed: got % 2x wanted % 2x\n", dst, c) + } + + b.Decrypt(dst[:], c) + + if !bytes.Equal(dst[:], p) { + t.Errorf("decrypt failed: got % 2x wanted % 2x\n", dst, p) + } + } +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/mac_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/mac_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/mac_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/mac_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,42 @@ +// Copyright 2015 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 pkcs12 + +import ( + "encoding/asn1" + "testing" +) + +func TestVerifyMac(t *testing.T) { + td := macData{ + Mac: digestInfo{ + Digest: []byte{0x18, 0x20, 0x3d, 0xff, 0x1e, 0x16, 0xf4, 0x92, 0xf2, 0xaf, 0xc8, 0x91, 0xa9, 0xba, 0xd6, 0xca, 0x9d, 0xee, 0x51, 0x93}, + }, + MacSalt: []byte{1, 2, 3, 4, 5, 6, 7, 8}, + Iterations: 2048, + } + + message := []byte{11, 12, 13, 14, 15} + password, _ := bmpString("") + + td.Mac.Algorithm.Algorithm = asn1.ObjectIdentifier([]int{1, 2, 3}) + err := verifyMac(&td, message, password) + if _, ok := err.(NotImplementedError); !ok { + t.Errorf("err: %v", err) + } + + td.Mac.Algorithm.Algorithm = asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}) + err = verifyMac(&td, message, password) + if err != ErrIncorrectPassword { + t.Errorf("Expected incorrect password, got err: %v", err) + } + + password, _ = bmpString("Sesame open") + err = verifyMac(&td, message, password) + if err != nil { + t.Errorf("err: %v", err) + } + +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/pbkdf.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/pbkdf.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/pbkdf.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/pbkdf.go 2016-05-17 20:01:14.000000000 +0000 @@ -103,6 +103,7 @@ // 6. For i=1, 2, ..., c, do the following: A := make([]byte, c*20) + var IjBuf []byte for i := 0; i < c; i++ { // A. Set A2=H^r(D||I). (i.e., the r-th hash of D||1, // H(H(H(... H(D||I)))) @@ -133,9 +134,23 @@ Ij.Add(Ij, Bbi) Ij.Add(Ij, one) Ijb := Ij.Bytes() + // We expect Ijb to be exactly v bytes, + // if it is longer or shorter we must + // adjust it accordingly. if len(Ijb) > v { Ijb = Ijb[len(Ijb)-v:] } + if len(Ijb) < v { + if IjBuf == nil { + IjBuf = make([]byte, v) + } + bytesShort := v - len(Ijb) + for i := 0; i < bytesShort; i++ { + IjBuf[i] = 0 + } + copy(IjBuf[bytesShort:], Ijb) + Ijb = IjBuf + } copy(I[j*v:(j+1)*v], Ijb) } } diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/pbkdf_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/pbkdf_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/pbkdf_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/pbkdf_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,34 @@ +// Copyright 2015 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 pkcs12 + +import ( + "bytes" + "testing" +) + +func TestThatPBKDFWorksCorrectlyForLongKeys(t *testing.T) { + cipherInfo := shaWithTripleDESCBC{} + + salt := []byte("\xff\xff\xff\xff\xff\xff\xff\xff") + password, _ := bmpString("sesame") + key := cipherInfo.deriveKey(salt, password, 2048) + + if expected := []byte("\x7c\xd9\xfd\x3e\x2b\x3b\xe7\x69\x1a\x44\xe3\xbe\xf0\xf9\xea\x0f\xb9\xb8\x97\xd4\xe3\x25\xd9\xd1"); bytes.Compare(key, expected) != 0 { + t.Fatalf("expected key '%x', but found '%x'", expected, key) + } +} + +func TestThatPBKDFHandlesLeadingZeros(t *testing.T) { + // This test triggers a case where I_j (in step 6C) ends up with leading zero + // byte, meaning that len(Ijb) < v (leading zeros get stripped by big.Int). + // This was previously causing bug whereby certain inputs would break the + // derivation and produce the wrong output. + key := pbkdf(sha1Sum, 20, 64, []byte("\xf3\x7e\x05\xb5\x18\x32\x4b\x4b"), []byte("\x00\x00"), 2048, 1, 24) + expected := []byte("\x00\xf7\x59\xff\x47\xd1\x4d\xd0\x36\x65\xd5\x94\x3c\xb3\xc4\xa3\x9a\x25\x55\xc0\x2a\xed\x66\xe1") + if bytes.Compare(key, expected) != 0 { + t.Fatalf("expected key '%x', but found '%x'", expected, key) + } +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/pkcs12_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/pkcs12_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/pkcs12_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/golang.org/x/crypto/pkcs12/pkcs12_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,138 @@ +// Copyright 2015 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 pkcs12 + +import ( + "crypto/rsa" + "crypto/tls" + "encoding/base64" + "encoding/pem" + "testing" +) + +func TestPfx(t *testing.T) { + for commonName, base64P12 := range testdata { + p12, _ := base64.StdEncoding.DecodeString(base64P12) + + priv, cert, err := Decode(p12, "") + if err != nil { + t.Fatal(err) + } + + if err := priv.(*rsa.PrivateKey).Validate(); err != nil { + t.Errorf("error while validating private key: %v", err) + } + + if cert.Subject.CommonName != commonName { + t.Errorf("expected common name to be %q, but found %q", commonName, cert.Subject.CommonName) + } + } +} + +func TestPEM(t *testing.T) { + for commonName, base64P12 := range testdata { + p12, _ := base64.StdEncoding.DecodeString(base64P12) + + blocks, err := ToPEM(p12, "") + if err != nil { + t.Fatalf("error while converting to PEM: %s", err) + } + + var pemData []byte + for _, b := range blocks { + pemData = append(pemData, pem.EncodeToMemory(b)...) + } + + cert, err := tls.X509KeyPair(pemData, pemData) + if err != nil { + t.Errorf("err while converting to key pair: %v", err) + } + config := tls.Config{ + Certificates: []tls.Certificate{cert}, + } + config.BuildNameToCertificate() + + if _, exists := config.NameToCertificate[commonName]; !exists { + t.Errorf("did not find our cert in PEM?: %v", config.NameToCertificate) + } + } +} + +func ExampleToPEM() { + p12, _ := base64.StdEncoding.DecodeString(`MIIJzgIBAzCCCZQGCS ... CA+gwggPk==`) + + blocks, err := ToPEM(p12, "password") + if err != nil { + panic(err) + } + + var pemData []byte + for _, b := range blocks { + pemData = append(pemData, pem.EncodeToMemory(b)...) + } + + // then use PEM data for tls to construct tls certificate: + cert, err := tls.X509KeyPair(pemData, pemData) + if err != nil { + panic(err) + } + + config := &tls.Config{ + Certificates: []tls.Certificate{cert}, + } + + _ = config +} + +var testdata = map[string]string{ + // 'null' password test case + "Windows Azure Tools": `MIIKDAIBAzCCCcwGCSqGSIb3DQEHAaCCCb0Eggm5MIIJtTCCBe4GCSqGSIb3DQEHAaCCBd8EggXbMIIF1zCCBdMGCyqGSIb3DQEMCgECoIIE7jCCBOowHAYKKoZIhvcNAQwBAzAOBAhStUNnlTGV+gICB9AEggTIJ81JIossF6boFWpPtkiQRPtI6DW6e9QD4/WvHAVrM2bKdpMzSMsCML5NyuddANTKHBVq00Jc9keqGNAqJPKkjhSUebzQFyhe0E1oI9T4zY5UKr/I8JclOeccH4QQnsySzYUG2SnniXnQ+JrG3juetli7EKth9h6jLc6xbubPadY5HMB3wL/eG/kJymiXwU2KQ9Mgd4X6jbcV+NNCE/8jbZHvSTCPeYTJIjxfeX61Sj5kFKUCzERbsnpyevhY3X0eYtEDezZQarvGmXtMMdzf8HJHkWRdk9VLDLgjk8uiJif/+X4FohZ37ig0CpgC2+dP4DGugaZZ51hb8tN9GeCKIsrmWogMXDIVd0OACBp/EjJVmFB6y0kUCXxUE0TZt0XA1tjAGJcjDUpBvTntZjPsnH/4ZySy+s2d9OOhJ6pzRQBRm360TzkFdSwk9DLiLdGfv4pwMMu/vNGBlqjP/1sQtj+jprJiD1sDbCl4AdQZVoMBQHadF2uSD4/o17XG/Ci0r2h6Htc2yvZMAbEY4zMjjIn2a+vqIxD6onexaek1R3zbkS9j19D6EN9EWn8xgz80YRCyW65znZk8xaIhhvlU/mg7sTxeyuqroBZNcq6uDaQTehDpyH7bY2l4zWRpoj10a6JfH2q5shYz8Y6UZC/kOTfuGqbZDNZWro/9pYquvNNW0M847E5t9bsf9VkAAMHRGBbWoVoU9VpI0UnoXSfvpOo+aXa2DSq5sHHUTVY7A9eov3z5IqT+pligx11xcs+YhDWcU8di3BTJisohKvv5Y8WSkm/rloiZd4ig269k0jTRk1olP/vCksPli4wKG2wdsd5o42nX1yL7mFfXocOANZbB+5qMkiwdyoQSk+Vq+C8nAZx2bbKhUq2MbrORGMzOe0Hh0x2a0PeObycN1Bpyv7Mp3ZI9h5hBnONKCnqMhtyQHUj/nNvbJUnDVYNfoOEqDiEqqEwB7YqWzAKz8KW0OIqdlM8uiQ4JqZZlFllnWJUfaiDrdFM3lYSnFQBkzeVlts6GpDOOBjCYd7dcCNS6kq6pZC6p6HN60Twu0JnurZD6RT7rrPkIGE8vAenFt4iGe/yF52fahCSY8Ws4K0UTwN7bAS+4xRHVCWvE8sMRZsRCHizb5laYsVrPZJhE6+hux6OBb6w8kwPYXc+ud5v6UxawUWgt6uPwl8mlAtU9Z7Miw4Nn/wtBkiLL/ke1UI1gqJtcQXgHxx6mzsjh41+nAgTvdbsSEyU6vfOmxGj3Rwc1eOrIhJUqn5YjOWfzzsz/D5DzWKmwXIwdspt1p+u+kol1N3f2wT9fKPnd/RGCb4g/1hc3Aju4DQYgGY782l89CEEdalpQ/35bQczMFk6Fje12HykakWEXd/bGm9Unh82gH84USiRpeOfQvBDYoqEyrY3zkFZzBjhDqa+jEcAj41tcGx47oSfDq3iVYCdL7HSIjtnyEktVXd7mISZLoMt20JACFcMw+mrbjlug+eU7o2GR7T+LwtOp/p4LZqyLa7oQJDwde1BNZtm3TCK2P1mW94QDL0nDUps5KLtr1DaZXEkRbjSJub2ZE9WqDHyU3KA8G84Tq/rN1IoNu/if45jacyPje1Npj9IftUZSP22nV7HMwZtwQ4P4MYHRMBMGCSqGSIb3DQEJFTEGBAQBAAAAMFsGCSqGSIb3DQEJFDFOHkwAewBCADQAQQA0AEYARQBCADAALQBBADEAOABBAC0ANAA0AEIAQgAtAEIANQBGADIALQA0ADkAMQBFAEYAMQA1ADIAQgBBADEANgB9MF0GCSsGAQQBgjcRATFQHk4ATQBpAGMAcgBvAHMAbwBmAHQAIABTAG8AZgB0AHcAYQByAGUAIABLAGUAeQAgAFMAdABvAHIAYQBnAGUAIABQAHIAbwB2AGkAZABlAHIwggO/BgkqhkiG9w0BBwagggOwMIIDrAIBADCCA6UGCSqGSIb3DQEHATAcBgoqhkiG9w0BDAEGMA4ECEBk5ZAYpu0WAgIH0ICCA3hik4mQFGpw9Ha8TQPtk+j2jwWdxfF0+sTk6S8PTsEfIhB7wPltjiCK92Uv2tCBQnodBUmatIfkpnRDEySmgmdglmOCzj204lWAMRs94PoALGn3JVBXbO1vIDCbAPOZ7Z0Hd0/1t2hmk8v3//QJGUg+qr59/4y/MuVfIg4qfkPcC2QSvYWcK3oTf6SFi5rv9B1IOWFgN5D0+C+x/9Lb/myPYX+rbOHrwtJ4W1fWKoz9g7wwmGFA9IJ2DYGuH8ifVFbDFT1Vcgsvs8arSX7oBsJVW0qrP7XkuDRe3EqCmKW7rBEwYrFznhxZcRDEpMwbFoSvgSIZ4XhFY9VKYglT+JpNH5iDceYEBOQL4vBLpxNUk3l5jKaBNxVa14AIBxq18bVHJ+STInhLhad4u10v/Xbx7wIL3f9DX1yLAkPrpBYbNHS2/ew6H/ySDJnoIDxkw2zZ4qJ+qUJZ1S0lbZVG+VT0OP5uF6tyOSpbMlcGkdl3z254n6MlCrTifcwkzscysDsgKXaYQw06rzrPW6RDub+t+hXzGny799fS9jhQMLDmOggaQ7+LA4oEZsfT89HLMWxJYDqjo3gIfjciV2mV54R684qLDS+AO09U49e6yEbwGlq8lpmO/pbXCbpGbB1b3EomcQbxdWxW2WEkkEd/VBn81K4M3obmywwXJkw+tPXDXfBmzzaqqCR+onMQ5ME1nMkY8ybnfoCc1bDIupjVWsEL2Wvq752RgI6KqzVNr1ew1IdqV5AWN2fOfek+0vi3Jd9FHF3hx8JMwjJL9dZsETV5kHtYJtE7wJ23J68BnCt2eI0GEuwXcCf5EdSKN/xXCTlIokc4Qk/gzRdIZsvcEJ6B1lGovKG54X4IohikqTjiepjbsMWj38yxDmK3mtENZ9ci8FPfbbvIEcOCZIinuY3qFUlRSbx7VUerEoV1IP3clUwexVQo4lHFee2jd7ocWsdSqSapW7OWUupBtDzRkqVhE7tGria+i1W2d6YLlJ21QTjyapWJehAMO637OdbJCCzDs1cXbodRRE7bsP492ocJy8OX66rKdhYbg8srSFNKdb3pF3UDNbN9jhI/t8iagRhNBhlQtTr1me2E/c86Q18qcRXl4bcXTt6acgCeffK6Y26LcVlrgjlD33AEYRRUeyC+rpxbT0aMjdFderlndKRIyG23mSp0HaUwNzAfMAcGBSsOAwIaBBRlviCbIyRrhIysg2dc/KbLFTc2vQQUg4rfwHMM4IKYRD/fsd1x6dda+wQ=`, + // empty string password test case + "testing@example.com": `MIIJzgIBAzCCCZQGCSqGSIb3DQEHAaCCCYUEggmBMIIJfTCCA/cGCSqGSIb3DQEHBqCCA+gwggPk +AgEAMIID3QYJKoZIhvcNAQcBMBwGCiqGSIb3DQEMAQYwDgQIIszfRGqcmPcCAggAgIIDsOZ9Eg1L +s5Wx8JhYoV3HAL4aRnkAWvTYB5NISZOgSgIQTssmt/3A7134dibTmaT/93LikkL3cTKLnQzJ4wDf +YZ1bprpVJvUqz+HFT79m27bP9zYXFrvxWBJbxjYKTSjQMgz+h8LAEpXXGajCmxMJ1oCOtdXkhhzc +LdZN6SAYgtmtyFnCdMEDskSggGuLb3fw84QEJ/Sj6FAULXunW/CPaS7Ce0TMsKmNU/jfFWj3yXXw +ro0kwjKiVLpVFlnBlHo2OoVU7hmkm59YpGhLgS7nxLD3n7nBroQ0ID1+8R01NnV9XLGoGzxMm1te +6UyTCkr5mj+kEQ8EP1Ys7g/TC411uhVWySMt/rcpkx7Vz1r9kYEAzJpONAfr6cuEVkPKrxpq4Fh0 +2fzlKBky0i/hrfIEUmngh+ERHUb/Mtv/fkv1j5w9suESbhsMLLiCXAlsP1UWMX+3bNizi3WVMEts +FM2k9byn+p8IUD/A8ULlE4kEaWeoc+2idkCNQkLGuIdGUXUFVm58se0auUkVRoRJx8x4CkMesT8j +b1H831W66YRWoEwwDQp2kK1lA2vQXxdVHWlFevMNxJeromLzj3ayiaFrfByeUXhR2S+Hpm+c0yNR +4UVU9WED2kacsZcpRm9nlEa5sr28mri5JdBrNa/K02OOhvKCxr5ZGmbOVzUQKla2z4w+Ku9k8POm +dfDNU/fGx1b5hcFWtghXe3msWVsSJrQihnN6q1ughzNiYZlJUGcHdZDRtiWwCFI0bR8h/Dmg9uO9 +4rawQQrjIRT7B8yF3UbkZyAqs8Ppb1TsMeNPHh1rxEfGVQknh/48ouJYsmtbnzugTUt3mJCXXiL+ +XcPMV6bBVAUu4aaVKSmg9+yJtY4/VKv10iw88ktv29fViIdBe3t6l/oPuvQgbQ8dqf4T8w0l/uKZ +9lS1Na9jfT1vCoS7F5TRi+tmyj1vL5kr/amEIW6xKEP6oeAMvCMtbPAzVEj38zdJ1R22FfuIBxkh +f0Zl7pdVbmzRxl/SBx9iIBJSqAvcXItiT0FIj8HxQ+0iZKqMQMiBuNWJf5pYOLWGrIyntCWwHuaQ +wrx0sTGuEL9YXLEAsBDrsvzLkx/56E4INGZFrH8G7HBdW6iGqb22IMI4GHltYSyBRKbB0gadYTyv +abPEoqww8o7/85aPSzOTJ/53ozD438Q+d0u9SyDuOb60SzCD/zPuCEd78YgtXJwBYTuUNRT27FaM +3LGMX8Hz+6yPNRnmnA2XKPn7dx/IlaqAjIs8MIIFfgYJKoZIhvcNAQcBoIIFbwSCBWswggVnMIIF +YwYLKoZIhvcNAQwKAQKgggTuMIIE6jAcBgoqhkiG9w0BDAEDMA4ECJr0cClYqOlcAgIIAASCBMhe +OQSiP2s0/46ONXcNeVAkz2ksW3u/+qorhSiskGZ0b3dFa1hhgBU2Q7JVIkc4Hf7OXaT1eVQ8oqND +uhqsNz83/kqYo70+LS8Hocj49jFgWAKrf/yQkdyP1daHa2yzlEw4mkpqOfnIORQHvYCa8nEApspZ +wVu8y6WVuLHKU67mel7db2xwstQp7PRuSAYqGjTfAylElog8ASdaqqYbYIrCXucF8iF9oVgmb/Qo +xrXshJ9aSLO4MuXlTPELmWgj07AXKSb90FKNihE+y0bWb9LPVFY1Sly3AX9PfrtkSXIZwqW3phpv +MxGxQl/R6mr1z+hlTfY9Wdpb5vlKXPKA0L0Rt8d2pOesylFi6esJoS01QgP1kJILjbrV731kvDc0 +Jsd+Oxv4BMwA7ClG8w1EAOInc/GrV1MWFGw/HeEqj3CZ/l/0jv9bwkbVeVCiIhoL6P6lVx9pXq4t +KZ0uKg/tk5TVJmG2vLcMLvezD0Yk3G2ZOMrywtmskrwoF7oAUpO9e87szoH6fEvUZlkDkPVW1NV4 +cZk3DBSQiuA3VOOg8qbo/tx/EE3H59P0axZWno2GSB0wFPWd1aj+b//tJEJHaaNR6qPRj4IWj9ru +Qbc8eRAcVWleHg8uAehSvUXlFpyMQREyrnpvMGddpiTC8N4UMrrBRhV7+UbCOWhxPCbItnInBqgl +1JpSZIP7iUtsIMdu3fEC2cdbXMTRul+4rdzUR7F9OaezV3jjvcAbDvgbK1CpyC+MJ1Mxm/iTgk9V +iUArydhlR8OniN84GyGYoYCW9O/KUwb6ASmeFOu/msx8x6kAsSQHIkKqMKv0TUR3kZnkxUvdpBGP +KTl4YCTvNGX4dYALBqrAETRDhua2KVBD/kEttDHwBNVbN2xi81+Mc7ml461aADfk0c66R/m2sjHB +2tN9+wG12OIWFQjL6wF/UfJMYamxx2zOOExiId29Opt57uYiNVLOO4ourPewHPeH0u8Gz35aero7 +lkt7cZAe1Q0038JUuE/QGlnK4lESK9UkSIQAjSaAlTsrcfwtQxB2EjoOoLhwH5mvxUEmcNGNnXUc +9xj3M5BD3zBz3Ft7G3YMMDwB1+zC2l+0UG0MGVjMVaeoy32VVNvxgX7jk22OXG1iaOB+PY9kdk+O +X+52BGSf/rD6X0EnqY7XuRPkMGgjtpZeAYxRQnFtCZgDY4wYheuxqSSpdF49yNczSPLkgB3CeCfS ++9NTKN7aC6hBbmW/8yYh6OvSiCEwY0lFS/T+7iaVxr1loE4zI1y/FFp4Pe1qfLlLttVlkygga2UU +SCunTQ8UB/M5IXWKkhMOO11dP4niWwb39Y7pCWpau7mwbXOKfRPX96cgHnQJK5uG+BesDD1oYnX0 +6frN7FOnTSHKruRIwuI8KnOQ/I+owmyz71wiv5LMQt+yM47UrEjB/EZa5X8dpEwOZvkdqL7utcyo +l0XH5kWMXdW856LL/FYftAqJIDAmtX1TXF/rbP6mPyN/IlDC0gjP84Uzd/a2UyTIWr+wk49Ek3vQ +/uDamq6QrwAxVmNh5Tset5Vhpc1e1kb7mRMZIzxSP8JcTuYd45oFKi98I8YjvueHVZce1g7OudQP +SbFQoJvdT46iBg1TTatlltpOiH2mFaxWVS0xYjAjBgkqhkiG9w0BCRUxFgQUdA9eVqvETX4an/c8 +p8SsTugkit8wOwYJKoZIhvcNAQkUMS4eLABGAHIAaQBlAG4AZABsAHkAIABuAGEAbQBlACAAZgBv +AHIAIABjAGUAcgB0MDEwITAJBgUrDgMCGgUABBRFsNz3Zd1O1GI8GTuFwCWuDOjEEwQIuBEfIcAy +HQ8CAggA`, +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/benchmark.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/benchmark.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/benchmark.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/benchmark.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,187 @@ +// 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. + +package check + +import ( + "fmt" + "runtime" + "time" +) + +var memStats runtime.MemStats + +// testingB is a type passed to Benchmark functions to manage benchmark +// timing and to specify the number of iterations to run. +type timer struct { + start time.Time // Time test or benchmark started + duration time.Duration + N int + bytes int64 + timerOn bool + benchTime time.Duration + // The initial states of memStats.Mallocs and memStats.TotalAlloc. + startAllocs uint64 + startBytes uint64 + // The net total of this test after being run. + netAllocs uint64 + netBytes uint64 +} + +// StartTimer starts timing a test. This function is called automatically +// before a benchmark starts, but it can also used to resume timing after +// a call to StopTimer. +func (c *C) StartTimer() { + if !c.timerOn { + c.start = time.Now() + c.timerOn = true + + runtime.ReadMemStats(&memStats) + c.startAllocs = memStats.Mallocs + c.startBytes = memStats.TotalAlloc + } +} + +// StopTimer stops timing a test. This can be used to pause the timer +// while performing complex initialization that you don't +// want to measure. +func (c *C) StopTimer() { + if c.timerOn { + c.duration += time.Now().Sub(c.start) + c.timerOn = false + runtime.ReadMemStats(&memStats) + c.netAllocs += memStats.Mallocs - c.startAllocs + c.netBytes += memStats.TotalAlloc - c.startBytes + } +} + +// ResetTimer sets the elapsed benchmark time to zero. +// It does not affect whether the timer is running. +func (c *C) ResetTimer() { + if c.timerOn { + c.start = time.Now() + runtime.ReadMemStats(&memStats) + c.startAllocs = memStats.Mallocs + c.startBytes = memStats.TotalAlloc + } + c.duration = 0 + c.netAllocs = 0 + c.netBytes = 0 +} + +// SetBytes informs the number of bytes that the benchmark processes +// on each iteration. If this is called in a benchmark it will also +// report MB/s. +func (c *C) SetBytes(n int64) { + c.bytes = n +} + +func (c *C) nsPerOp() int64 { + if c.N <= 0 { + return 0 + } + return c.duration.Nanoseconds() / int64(c.N) +} + +func (c *C) mbPerSec() float64 { + if c.bytes <= 0 || c.duration <= 0 || c.N <= 0 { + return 0 + } + return (float64(c.bytes) * float64(c.N) / 1e6) / c.duration.Seconds() +} + +func (c *C) timerString() string { + if c.N <= 0 { + return fmt.Sprintf("%3.3fs", float64(c.duration.Nanoseconds())/1e9) + } + mbs := c.mbPerSec() + mb := "" + if mbs != 0 { + mb = fmt.Sprintf("\t%7.2f MB/s", mbs) + } + nsop := c.nsPerOp() + ns := fmt.Sprintf("%10d ns/op", nsop) + if c.N > 0 && nsop < 100 { + // The format specifiers here make sure that + // the ones digits line up for all three possible formats. + if nsop < 10 { + ns = fmt.Sprintf("%13.2f ns/op", float64(c.duration.Nanoseconds())/float64(c.N)) + } else { + ns = fmt.Sprintf("%12.1f ns/op", float64(c.duration.Nanoseconds())/float64(c.N)) + } + } + memStats := "" + if c.benchMem { + allocedBytes := fmt.Sprintf("%8d B/op", int64(c.netBytes)/int64(c.N)) + allocs := fmt.Sprintf("%8d allocs/op", int64(c.netAllocs)/int64(c.N)) + memStats = fmt.Sprintf("\t%s\t%s", allocedBytes, allocs) + } + return fmt.Sprintf("%8d\t%s%s%s", c.N, ns, mb, memStats) +} + +func min(x, y int) int { + if x > y { + return y + } + return x +} + +func max(x, y int) int { + if x < y { + return y + } + return x +} + +// roundDown10 rounds a number down to the nearest power of 10. +func roundDown10(n int) int { + var tens = 0 + // tens = floor(log_10(n)) + for n > 10 { + n = n / 10 + tens++ + } + // result = 10^tens + result := 1 + for i := 0; i < tens; i++ { + result *= 10 + } + return result +} + +// roundUp rounds x up to a number of the form [1eX, 2eX, 5eX]. +func roundUp(n int) int { + base := roundDown10(n) + if n < (2 * base) { + return 2 * base + } + if n < (5 * base) { + return 5 * base + } + return 10 * base +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/benchmark_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,91 @@ +// These tests verify the test running logic. + +package check_test + +import ( + . "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1" + "time" +) + +var benchmarkS = Suite(&BenchmarkS{}) + +type BenchmarkS struct{} + +func (s *BenchmarkS) TestCountSuite(c *C) { + suitesRun += 1 +} + +func (s *BenchmarkS) TestBasicTestTiming(c *C) { + helper := FixtureHelper{sleepOn: "Test1", sleep: 1000000 * time.Nanosecond} + output := String{} + runConf := RunConf{Output: &output, Verbose: true} + Run(&helper, &runConf) + + expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test1\t0\\.001s\n" + + "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t0\\.000s\n" + c.Assert(output.value, Matches, expected) +} + +func (s *BenchmarkS) TestStreamTestTiming(c *C) { + helper := FixtureHelper{sleepOn: "SetUpSuite", sleep: 1000000 * time.Nanosecond} + output := String{} + runConf := RunConf{Output: &output, Stream: true} + Run(&helper, &runConf) + + expected := "(?s).*\nPASS: check_test\\.go:[0-9]+: FixtureHelper\\.SetUpSuite\t *0\\.001s\n.*" + c.Assert(output.value, Matches, expected) +} + +func (s *BenchmarkS) TestBenchmark(c *C) { + helper := FixtureHelper{sleep: 100000} + output := String{} + runConf := RunConf{ + Output: &output, + Benchmark: true, + BenchmarkTime: 10000000, + Filter: "Benchmark1", + } + Run(&helper, &runConf) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Benchmark1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "SetUpTest") + c.Check(helper.calls[5], Equals, "Benchmark1") + c.Check(helper.calls[6], Equals, "TearDownTest") + // ... and more. + + expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark1\t *100\t *[12][0-9]{5} ns/op\n" + c.Assert(output.value, Matches, expected) +} + +func (s *BenchmarkS) TestBenchmarkBytes(c *C) { + helper := FixtureHelper{sleep: 100000} + output := String{} + runConf := RunConf{ + Output: &output, + Benchmark: true, + BenchmarkTime: 10000000, + Filter: "Benchmark2", + } + Run(&helper, &runConf) + + expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark2\t *100\t *[12][0-9]{5} ns/op\t *[4-9]\\.[0-9]{2} MB/s\n" + c.Assert(output.value, Matches, expected) +} + +func (s *BenchmarkS) TestBenchmarkMem(c *C) { + helper := FixtureHelper{sleep: 100000} + output := String{} + runConf := RunConf{ + Output: &output, + Benchmark: true, + BenchmarkMem: true, + BenchmarkTime: 10000000, + Filter: "Benchmark3", + } + Run(&helper, &runConf) + + expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark3\t *100\t *[12][0-9]{5} ns/op\t *[0-9]+ B/op\t *[1-9] allocs/op\n" + c.Assert(output.value, Matches, expected) +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/bootstrap_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/bootstrap_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/bootstrap_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/bootstrap_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,82 @@ +// These initial tests are for bootstrapping. They verify that we can +// basically use the testing infrastructure itself to check if the test +// system is working. +// +// These tests use will break down the test runner badly in case of +// errors because if they simply fail, we can't be sure the developer +// will ever see anything (because failing means the failing system +// somehow isn't working! :-) +// +// Do not assume *any* internal functionality works as expected besides +// what's actually tested here. + +package check_test + +import ( + "fmt" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1" + "strings" +) + +type BootstrapS struct{} + +var boostrapS = check.Suite(&BootstrapS{}) + +func (s *BootstrapS) TestCountSuite(c *check.C) { + suitesRun += 1 +} + +func (s *BootstrapS) TestFailedAndFail(c *check.C) { + if c.Failed() { + critical("c.Failed() must be false first!") + } + c.Fail() + if !c.Failed() { + critical("c.Fail() didn't put the test in a failed state!") + } + c.Succeed() +} + +func (s *BootstrapS) TestFailedAndSucceed(c *check.C) { + c.Fail() + c.Succeed() + if c.Failed() { + critical("c.Succeed() didn't put the test back in a non-failed state") + } +} + +func (s *BootstrapS) TestLogAndGetTestLog(c *check.C) { + c.Log("Hello there!") + log := c.GetTestLog() + if log != "Hello there!\n" { + critical(fmt.Sprintf("Log() or GetTestLog() is not working! Got: %#v", log)) + } +} + +func (s *BootstrapS) TestLogfAndGetTestLog(c *check.C) { + c.Logf("Hello %v", "there!") + log := c.GetTestLog() + if log != "Hello there!\n" { + critical(fmt.Sprintf("Logf() or GetTestLog() is not working! Got: %#v", log)) + } +} + +func (s *BootstrapS) TestRunShowsErrors(c *check.C) { + output := String{} + check.Run(&FailHelper{}, &check.RunConf{Output: &output}) + if strings.Index(output.value, "Expected failure!") == -1 { + critical(fmt.Sprintf("RunWithWriter() output did not contain the "+ + "expected failure! Got: %#v", + output.value)) + } +} + +func (s *BootstrapS) TestRunDoesntShowSuccesses(c *check.C) { + output := String{} + check.Run(&SuccessHelper{}, &check.RunConf{Output: &output}) + if strings.Index(output.value, "Expected success!") != -1 { + critical(fmt.Sprintf("RunWithWriter() output contained a successful "+ + "test! Got: %#v", + output.value)) + } +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/checkers.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/checkers.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/checkers.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/checkers.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,458 @@ +package check + +import ( + "fmt" + "reflect" + "regexp" +) + +// ----------------------------------------------------------------------- +// CommentInterface and Commentf helper, to attach extra information to checks. + +type comment struct { + format string + args []interface{} +} + +// Commentf returns an infomational value to use with Assert or Check calls. +// If the checker test fails, the provided arguments will be passed to +// fmt.Sprintf, and will be presented next to the logged failure. +// +// For example: +// +// c.Assert(v, Equals, 42, Commentf("Iteration #%d failed.", i)) +// +// Note that if the comment is constant, a better option is to +// simply use a normal comment right above or next to the line, as +// it will also get printed with any errors: +// +// c.Assert(l, Equals, 8192) // Ensure buffer size is correct (bug #123) +// +func Commentf(format string, args ...interface{}) CommentInterface { + return &comment{format, args} +} + +// CommentInterface must be implemented by types that attach extra +// information to failed checks. See the Commentf function for details. +type CommentInterface interface { + CheckCommentString() string +} + +func (c *comment) CheckCommentString() string { + return fmt.Sprintf(c.format, c.args...) +} + +// ----------------------------------------------------------------------- +// The Checker interface. + +// The Checker interface must be provided by checkers used with +// the Assert and Check verification methods. +type Checker interface { + Info() *CheckerInfo + Check(params []interface{}, names []string) (result bool, error string) +} + +// See the Checker interface. +type CheckerInfo struct { + Name string + Params []string +} + +func (info *CheckerInfo) Info() *CheckerInfo { + return info +} + +// ----------------------------------------------------------------------- +// Not checker logic inverter. + +// The Not checker inverts the logic of the provided checker. The +// resulting checker will succeed where the original one failed, and +// vice-versa. +// +// For example: +// +// c.Assert(a, Not(Equals), b) +// +func Not(checker Checker) Checker { + return ¬Checker{checker} +} + +type notChecker struct { + sub Checker +} + +func (checker *notChecker) Info() *CheckerInfo { + info := *checker.sub.Info() + info.Name = "Not(" + info.Name + ")" + return &info +} + +func (checker *notChecker) Check(params []interface{}, names []string) (result bool, error string) { + result, error = checker.sub.Check(params, names) + result = !result + return +} + +// ----------------------------------------------------------------------- +// IsNil checker. + +type isNilChecker struct { + *CheckerInfo +} + +// The IsNil checker tests whether the obtained value is nil. +// +// For example: +// +// c.Assert(err, IsNil) +// +var IsNil Checker = &isNilChecker{ + &CheckerInfo{Name: "IsNil", Params: []string{"value"}}, +} + +func (checker *isNilChecker) Check(params []interface{}, names []string) (result bool, error string) { + return isNil(params[0]), "" +} + +func isNil(obtained interface{}) (result bool) { + if obtained == nil { + result = true + } else { + switch v := reflect.ValueOf(obtained); v.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + return v.IsNil() + } + } + return +} + +// ----------------------------------------------------------------------- +// NotNil checker. Alias for Not(IsNil), since it's so common. + +type notNilChecker struct { + *CheckerInfo +} + +// The NotNil checker verifies that the obtained value is not nil. +// +// For example: +// +// c.Assert(iface, NotNil) +// +// This is an alias for Not(IsNil), made available since it's a +// fairly common check. +// +var NotNil Checker = ¬NilChecker{ + &CheckerInfo{Name: "NotNil", Params: []string{"value"}}, +} + +func (checker *notNilChecker) Check(params []interface{}, names []string) (result bool, error string) { + return !isNil(params[0]), "" +} + +// ----------------------------------------------------------------------- +// Equals checker. + +type equalsChecker struct { + *CheckerInfo +} + +// The Equals checker verifies that the obtained value is equal to +// the expected value, according to usual Go semantics for ==. +// +// For example: +// +// c.Assert(value, Equals, 42) +// +var Equals Checker = &equalsChecker{ + &CheckerInfo{Name: "Equals", Params: []string{"obtained", "expected"}}, +} + +func (checker *equalsChecker) Check(params []interface{}, names []string) (result bool, error string) { + defer func() { + if v := recover(); v != nil { + result = false + error = fmt.Sprint(v) + } + }() + return params[0] == params[1], "" +} + +// ----------------------------------------------------------------------- +// DeepEquals checker. + +type deepEqualsChecker struct { + *CheckerInfo +} + +// The DeepEquals checker verifies that the obtained value is deep-equal to +// the expected value. The check will work correctly even when facing +// slices, interfaces, and values of different types (which always fail +// the test). +// +// For example: +// +// c.Assert(value, DeepEquals, 42) +// c.Assert(array, DeepEquals, []string{"hi", "there"}) +// +var DeepEquals Checker = &deepEqualsChecker{ + &CheckerInfo{Name: "DeepEquals", Params: []string{"obtained", "expected"}}, +} + +func (checker *deepEqualsChecker) Check(params []interface{}, names []string) (result bool, error string) { + return reflect.DeepEqual(params[0], params[1]), "" +} + +// ----------------------------------------------------------------------- +// HasLen checker. + +type hasLenChecker struct { + *CheckerInfo +} + +// The HasLen checker verifies that the obtained value has the +// provided length. In many cases this is superior to using Equals +// in conjuction with the len function because in case the check +// fails the value itself will be printed, instead of its length, +// providing more details for figuring the problem. +// +// For example: +// +// c.Assert(list, HasLen, 5) +// +var HasLen Checker = &hasLenChecker{ + &CheckerInfo{Name: "HasLen", Params: []string{"obtained", "n"}}, +} + +func (checker *hasLenChecker) Check(params []interface{}, names []string) (result bool, error string) { + n, ok := params[1].(int) + if !ok { + return false, "n must be an int" + } + value := reflect.ValueOf(params[0]) + switch value.Kind() { + case reflect.Map, reflect.Array, reflect.Slice, reflect.Chan, reflect.String: + default: + return false, "obtained value type has no length" + } + return value.Len() == n, "" +} + +// ----------------------------------------------------------------------- +// ErrorMatches checker. + +type errorMatchesChecker struct { + *CheckerInfo +} + +// The ErrorMatches checker verifies that the error value +// is non nil and matches the regular expression provided. +// +// For example: +// +// c.Assert(err, ErrorMatches, "perm.*denied") +// +var ErrorMatches Checker = errorMatchesChecker{ + &CheckerInfo{Name: "ErrorMatches", Params: []string{"value", "regex"}}, +} + +func (checker errorMatchesChecker) Check(params []interface{}, names []string) (result bool, errStr string) { + if params[0] == nil { + return false, "Error value is nil" + } + err, ok := params[0].(error) + if !ok { + return false, "Value is not an error" + } + params[0] = err.Error() + names[0] = "error" + return matches(params[0], params[1]) +} + +// ----------------------------------------------------------------------- +// Matches checker. + +type matchesChecker struct { + *CheckerInfo +} + +// The Matches checker verifies that the string provided as the obtained +// value (or the string resulting from obtained.String()) matches the +// regular expression provided. +// +// For example: +// +// c.Assert(err, Matches, "perm.*denied") +// +var Matches Checker = &matchesChecker{ + &CheckerInfo{Name: "Matches", Params: []string{"value", "regex"}}, +} + +func (checker *matchesChecker) Check(params []interface{}, names []string) (result bool, error string) { + return matches(params[0], params[1]) +} + +func matches(value, regex interface{}) (result bool, error string) { + reStr, ok := regex.(string) + if !ok { + return false, "Regex must be a string" + } + valueStr, valueIsStr := value.(string) + if !valueIsStr { + if valueWithStr, valueHasStr := value.(fmt.Stringer); valueHasStr { + valueStr, valueIsStr = valueWithStr.String(), true + } + } + if valueIsStr { + matches, err := regexp.MatchString("^"+reStr+"$", valueStr) + if err != nil { + return false, "Can't compile regex: " + err.Error() + } + return matches, "" + } + return false, "Obtained value is not a string and has no .String()" +} + +// ----------------------------------------------------------------------- +// Panics checker. + +type panicsChecker struct { + *CheckerInfo +} + +// The Panics checker verifies that calling the provided zero-argument +// function will cause a panic which is deep-equal to the provided value. +// +// For example: +// +// c.Assert(func() { f(1, 2) }, Panics, &SomeErrorType{"BOOM"}). +// +// +var Panics Checker = &panicsChecker{ + &CheckerInfo{Name: "Panics", Params: []string{"function", "expected"}}, +} + +func (checker *panicsChecker) Check(params []interface{}, names []string) (result bool, error string) { + f := reflect.ValueOf(params[0]) + if f.Kind() != reflect.Func || f.Type().NumIn() != 0 { + return false, "Function must take zero arguments" + } + defer func() { + // If the function has not panicked, then don't do the check. + if error != "" { + return + } + params[0] = recover() + names[0] = "panic" + result = reflect.DeepEqual(params[0], params[1]) + }() + f.Call(nil) + return false, "Function has not panicked" +} + +type panicMatchesChecker struct { + *CheckerInfo +} + +// The PanicMatches checker verifies that calling the provided zero-argument +// function will cause a panic with an error value matching +// the regular expression provided. +// +// For example: +// +// c.Assert(func() { f(1, 2) }, PanicMatches, `open.*: no such file or directory`). +// +// +var PanicMatches Checker = &panicMatchesChecker{ + &CheckerInfo{Name: "PanicMatches", Params: []string{"function", "expected"}}, +} + +func (checker *panicMatchesChecker) Check(params []interface{}, names []string) (result bool, errmsg string) { + f := reflect.ValueOf(params[0]) + if f.Kind() != reflect.Func || f.Type().NumIn() != 0 { + return false, "Function must take zero arguments" + } + defer func() { + // If the function has not panicked, then don't do the check. + if errmsg != "" { + return + } + obtained := recover() + names[0] = "panic" + if e, ok := obtained.(error); ok { + params[0] = e.Error() + } else if _, ok := obtained.(string); ok { + params[0] = obtained + } else { + errmsg = "Panic value is not a string or an error" + return + } + result, errmsg = matches(params[0], params[1]) + }() + f.Call(nil) + return false, "Function has not panicked" +} + +// ----------------------------------------------------------------------- +// FitsTypeOf checker. + +type fitsTypeChecker struct { + *CheckerInfo +} + +// The FitsTypeOf checker verifies that the obtained value is +// assignable to a variable with the same type as the provided +// sample value. +// +// For example: +// +// c.Assert(value, FitsTypeOf, int64(0)) +// c.Assert(value, FitsTypeOf, os.Error(nil)) +// +var FitsTypeOf Checker = &fitsTypeChecker{ + &CheckerInfo{Name: "FitsTypeOf", Params: []string{"obtained", "sample"}}, +} + +func (checker *fitsTypeChecker) Check(params []interface{}, names []string) (result bool, error string) { + obtained := reflect.ValueOf(params[0]) + sample := reflect.ValueOf(params[1]) + if !obtained.IsValid() { + return false, "" + } + if !sample.IsValid() { + return false, "Invalid sample value" + } + return obtained.Type().AssignableTo(sample.Type()), "" +} + +// ----------------------------------------------------------------------- +// Implements checker. + +type implementsChecker struct { + *CheckerInfo +} + +// The Implements checker verifies that the obtained value +// implements the interface specified via a pointer to an interface +// variable. +// +// For example: +// +// var e os.Error +// c.Assert(err, Implements, &e) +// +var Implements Checker = &implementsChecker{ + &CheckerInfo{Name: "Implements", Params: []string{"obtained", "ifaceptr"}}, +} + +func (checker *implementsChecker) Check(params []interface{}, names []string) (result bool, error string) { + obtained := reflect.ValueOf(params[0]) + ifaceptr := reflect.ValueOf(params[1]) + if !obtained.IsValid() { + return false, "" + } + if !ifaceptr.IsValid() || ifaceptr.Kind() != reflect.Ptr || ifaceptr.Elem().Kind() != reflect.Interface { + return false, "ifaceptr should be a pointer to an interface variable" + } + return obtained.Type().Implements(ifaceptr.Elem().Type()), "" +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/checkers_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/checkers_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/checkers_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/checkers_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,272 @@ +package check_test + +import ( + "errors" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1" + "reflect" + "runtime" +) + +type CheckersS struct{} + +var _ = check.Suite(&CheckersS{}) + +func testInfo(c *check.C, checker check.Checker, name string, paramNames []string) { + info := checker.Info() + if info.Name != name { + c.Fatalf("Got name %s, expected %s", info.Name, name) + } + if !reflect.DeepEqual(info.Params, paramNames) { + c.Fatalf("Got param names %#v, expected %#v", info.Params, paramNames) + } +} + +func testCheck(c *check.C, checker check.Checker, result bool, error string, params ...interface{}) ([]interface{}, []string) { + info := checker.Info() + if len(params) != len(info.Params) { + c.Fatalf("unexpected param count in test; expected %d got %d", len(info.Params), len(params)) + } + names := append([]string{}, info.Params...) + result_, error_ := checker.Check(params, names) + if result_ != result || error_ != error { + c.Fatalf("%s.Check(%#v) returned (%#v, %#v) rather than (%#v, %#v)", + info.Name, params, result_, error_, result, error) + } + return params, names +} + +func (s *CheckersS) TestComment(c *check.C) { + bug := check.Commentf("a %d bc", 42) + comment := bug.CheckCommentString() + if comment != "a 42 bc" { + c.Fatalf("Commentf returned %#v", comment) + } +} + +func (s *CheckersS) TestIsNil(c *check.C) { + testInfo(c, check.IsNil, "IsNil", []string{"value"}) + + testCheck(c, check.IsNil, true, "", nil) + testCheck(c, check.IsNil, false, "", "a") + + testCheck(c, check.IsNil, true, "", (chan int)(nil)) + testCheck(c, check.IsNil, false, "", make(chan int)) + testCheck(c, check.IsNil, true, "", (error)(nil)) + testCheck(c, check.IsNil, false, "", errors.New("")) + testCheck(c, check.IsNil, true, "", ([]int)(nil)) + testCheck(c, check.IsNil, false, "", make([]int, 1)) + testCheck(c, check.IsNil, false, "", int(0)) +} + +func (s *CheckersS) TestNotNil(c *check.C) { + testInfo(c, check.NotNil, "NotNil", []string{"value"}) + + testCheck(c, check.NotNil, false, "", nil) + testCheck(c, check.NotNil, true, "", "a") + + testCheck(c, check.NotNil, false, "", (chan int)(nil)) + testCheck(c, check.NotNil, true, "", make(chan int)) + testCheck(c, check.NotNil, false, "", (error)(nil)) + testCheck(c, check.NotNil, true, "", errors.New("")) + testCheck(c, check.NotNil, false, "", ([]int)(nil)) + testCheck(c, check.NotNil, true, "", make([]int, 1)) +} + +func (s *CheckersS) TestNot(c *check.C) { + testInfo(c, check.Not(check.IsNil), "Not(IsNil)", []string{"value"}) + + testCheck(c, check.Not(check.IsNil), false, "", nil) + testCheck(c, check.Not(check.IsNil), true, "", "a") +} + +type simpleStruct struct { + i int +} + +func (s *CheckersS) TestEquals(c *check.C) { + testInfo(c, check.Equals, "Equals", []string{"obtained", "expected"}) + + // The simplest. + testCheck(c, check.Equals, true, "", 42, 42) + testCheck(c, check.Equals, false, "", 42, 43) + + // Different native types. + testCheck(c, check.Equals, false, "", int32(42), int64(42)) + + // With nil. + testCheck(c, check.Equals, false, "", 42, nil) + + // Slices + testCheck(c, check.Equals, false, "runtime error: comparing uncomparable type []uint8", []byte{1, 2}, []byte{1, 2}) + + // Struct values + testCheck(c, check.Equals, true, "", simpleStruct{1}, simpleStruct{1}) + testCheck(c, check.Equals, false, "", simpleStruct{1}, simpleStruct{2}) + + // Struct pointers + testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{1}) + testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{2}) +} + +func (s *CheckersS) TestDeepEquals(c *check.C) { + testInfo(c, check.DeepEquals, "DeepEquals", []string{"obtained", "expected"}) + + // The simplest. + testCheck(c, check.DeepEquals, true, "", 42, 42) + testCheck(c, check.DeepEquals, false, "", 42, 43) + + // Different native types. + testCheck(c, check.DeepEquals, false, "", int32(42), int64(42)) + + // With nil. + testCheck(c, check.DeepEquals, false, "", 42, nil) + + // Slices + testCheck(c, check.DeepEquals, true, "", []byte{1, 2}, []byte{1, 2}) + testCheck(c, check.DeepEquals, false, "", []byte{1, 2}, []byte{1, 3}) + + // Struct values + testCheck(c, check.DeepEquals, true, "", simpleStruct{1}, simpleStruct{1}) + testCheck(c, check.DeepEquals, false, "", simpleStruct{1}, simpleStruct{2}) + + // Struct pointers + testCheck(c, check.DeepEquals, true, "", &simpleStruct{1}, &simpleStruct{1}) + testCheck(c, check.DeepEquals, false, "", &simpleStruct{1}, &simpleStruct{2}) +} + +func (s *CheckersS) TestHasLen(c *check.C) { + testInfo(c, check.HasLen, "HasLen", []string{"obtained", "n"}) + + testCheck(c, check.HasLen, true, "", "abcd", 4) + testCheck(c, check.HasLen, true, "", []int{1, 2}, 2) + testCheck(c, check.HasLen, false, "", []int{1, 2}, 3) + + testCheck(c, check.HasLen, false, "n must be an int", []int{1, 2}, "2") + testCheck(c, check.HasLen, false, "obtained value type has no length", nil, 2) +} + +func (s *CheckersS) TestErrorMatches(c *check.C) { + testInfo(c, check.ErrorMatches, "ErrorMatches", []string{"value", "regex"}) + + testCheck(c, check.ErrorMatches, false, "Error value is nil", nil, "some error") + testCheck(c, check.ErrorMatches, false, "Value is not an error", 1, "some error") + testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "some error") + testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "so.*or") + + // Verify params mutation + params, names := testCheck(c, check.ErrorMatches, false, "", errors.New("some error"), "other error") + c.Assert(params[0], check.Equals, "some error") + c.Assert(names[0], check.Equals, "error") +} + +func (s *CheckersS) TestMatches(c *check.C) { + testInfo(c, check.Matches, "Matches", []string{"value", "regex"}) + + // Simple matching + testCheck(c, check.Matches, true, "", "abc", "abc") + testCheck(c, check.Matches, true, "", "abc", "a.c") + + // Must match fully + testCheck(c, check.Matches, false, "", "abc", "ab") + testCheck(c, check.Matches, false, "", "abc", "bc") + + // String()-enabled values accepted + testCheck(c, check.Matches, true, "", reflect.ValueOf("abc"), "a.c") + testCheck(c, check.Matches, false, "", reflect.ValueOf("abc"), "a.d") + + // Some error conditions. + testCheck(c, check.Matches, false, "Obtained value is not a string and has no .String()", 1, "a.c") + testCheck(c, check.Matches, false, "Can't compile regex: error parsing regexp: missing closing ]: `[c$`", "abc", "a[c") +} + +func (s *CheckersS) TestPanics(c *check.C) { + testInfo(c, check.Panics, "Panics", []string{"function", "expected"}) + + // Some errors. + testCheck(c, check.Panics, false, "Function has not panicked", func() bool { return false }, "BOOM") + testCheck(c, check.Panics, false, "Function must take zero arguments", 1, "BOOM") + + // Plain strings. + testCheck(c, check.Panics, true, "", func() { panic("BOOM") }, "BOOM") + testCheck(c, check.Panics, false, "", func() { panic("KABOOM") }, "BOOM") + testCheck(c, check.Panics, true, "", func() bool { panic("BOOM") }, "BOOM") + + // Error values. + testCheck(c, check.Panics, true, "", func() { panic(errors.New("BOOM")) }, errors.New("BOOM")) + testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM")) + + type deep struct{ i int } + // Deep value + testCheck(c, check.Panics, true, "", func() { panic(&deep{99}) }, &deep{99}) + + // Verify params/names mutation + params, names := testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM")) + c.Assert(params[0], check.ErrorMatches, "KABOOM") + c.Assert(names[0], check.Equals, "panic") + + // Verify a nil panic + testCheck(c, check.Panics, true, "", func() { panic(nil) }, nil) + testCheck(c, check.Panics, false, "", func() { panic(nil) }, "NOPE") +} + +func (s *CheckersS) TestPanicMatches(c *check.C) { + testInfo(c, check.PanicMatches, "PanicMatches", []string{"function", "expected"}) + + // Error matching. + testCheck(c, check.PanicMatches, true, "", func() { panic(errors.New("BOOM")) }, "BO.M") + testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BO.M") + + // Some errors. + testCheck(c, check.PanicMatches, false, "Function has not panicked", func() bool { return false }, "BOOM") + testCheck(c, check.PanicMatches, false, "Function must take zero arguments", 1, "BOOM") + + // Plain strings. + testCheck(c, check.PanicMatches, true, "", func() { panic("BOOM") }, "BO.M") + testCheck(c, check.PanicMatches, false, "", func() { panic("KABOOM") }, "BOOM") + testCheck(c, check.PanicMatches, true, "", func() bool { panic("BOOM") }, "BO.M") + + // Verify params/names mutation + params, names := testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BOOM") + c.Assert(params[0], check.Equals, "KABOOM") + c.Assert(names[0], check.Equals, "panic") + + // Verify a nil panic + testCheck(c, check.PanicMatches, false, "Panic value is not a string or an error", func() { panic(nil) }, "") +} + +func (s *CheckersS) TestFitsTypeOf(c *check.C) { + testInfo(c, check.FitsTypeOf, "FitsTypeOf", []string{"obtained", "sample"}) + + // Basic types + testCheck(c, check.FitsTypeOf, true, "", 1, 0) + testCheck(c, check.FitsTypeOf, false, "", 1, int64(0)) + + // Aliases + testCheck(c, check.FitsTypeOf, false, "", 1, errors.New("")) + testCheck(c, check.FitsTypeOf, false, "", "error", errors.New("")) + testCheck(c, check.FitsTypeOf, true, "", errors.New("error"), errors.New("")) + + // Structures + testCheck(c, check.FitsTypeOf, false, "", 1, simpleStruct{}) + testCheck(c, check.FitsTypeOf, false, "", simpleStruct{42}, &simpleStruct{}) + testCheck(c, check.FitsTypeOf, true, "", simpleStruct{42}, simpleStruct{}) + testCheck(c, check.FitsTypeOf, true, "", &simpleStruct{42}, &simpleStruct{}) + + // Some bad values + testCheck(c, check.FitsTypeOf, false, "Invalid sample value", 1, interface{}(nil)) + testCheck(c, check.FitsTypeOf, false, "", interface{}(nil), 0) +} + +func (s *CheckersS) TestImplements(c *check.C) { + testInfo(c, check.Implements, "Implements", []string{"obtained", "ifaceptr"}) + + var e error + var re runtime.Error + testCheck(c, check.Implements, true, "", errors.New(""), &e) + testCheck(c, check.Implements, false, "", errors.New(""), &re) + + // Some bad values + testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, errors.New("")) + testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, interface{}(nil)) + testCheck(c, check.Implements, false, "", interface{}(nil), &e) +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/check.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/check.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/check.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/check.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,954 @@ +// Package check is a rich testing extension for Go's testing package. +// +// For details about the project, see: +// +// http://labix.org/gocheck +// +package check + +import ( + "bytes" + "errors" + "fmt" + "io" + "math/rand" + "os" + "path" + "path/filepath" + "reflect" + "regexp" + "runtime" + "strconv" + "strings" + "sync" + "sync/atomic" + "time" +) + +// ----------------------------------------------------------------------- +// Internal type which deals with suite method calling. + +const ( + fixtureKd = iota + testKd +) + +type funcKind int + +const ( + succeededSt = iota + failedSt + skippedSt + panickedSt + fixturePanickedSt + missedSt +) + +type funcStatus uint32 + +// A method value can't reach its own Method structure. +type methodType struct { + reflect.Value + Info reflect.Method +} + +func newMethod(receiver reflect.Value, i int) *methodType { + return &methodType{receiver.Method(i), receiver.Type().Method(i)} +} + +func (method *methodType) PC() uintptr { + return method.Info.Func.Pointer() +} + +func (method *methodType) suiteName() string { + t := method.Info.Type.In(0) + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + return t.Name() +} + +func (method *methodType) String() string { + return method.suiteName() + "." + method.Info.Name +} + +func (method *methodType) matches(re *regexp.Regexp) bool { + return (re.MatchString(method.Info.Name) || + re.MatchString(method.suiteName()) || + re.MatchString(method.String())) +} + +type C struct { + method *methodType + kind funcKind + testName string + _status funcStatus + logb *logger + logw io.Writer + done chan *C + reason string + mustFail bool + tempDir *tempDir + benchMem bool + startTime time.Time + timer +} + +func (c *C) status() funcStatus { + return funcStatus(atomic.LoadUint32((*uint32)(&c._status))) +} + +func (c *C) setStatus(s funcStatus) { + atomic.StoreUint32((*uint32)(&c._status), uint32(s)) +} + +func (c *C) stopNow() { + runtime.Goexit() +} + +// logger is a concurrency safe byte.Buffer +type logger struct { + sync.Mutex + writer bytes.Buffer +} + +func (l *logger) Write(buf []byte) (int, error) { + l.Lock() + defer l.Unlock() + return l.writer.Write(buf) +} + +func (l *logger) WriteTo(w io.Writer) (int64, error) { + l.Lock() + defer l.Unlock() + return l.writer.WriteTo(w) +} + +func (l *logger) String() string { + l.Lock() + defer l.Unlock() + return l.writer.String() +} + +// ----------------------------------------------------------------------- +// Handling of temporary files and directories. + +type tempDir struct { + sync.Mutex + path string + counter int +} + +func (td *tempDir) newPath() string { + td.Lock() + defer td.Unlock() + if td.path == "" { + var err error + for i := 0; i != 100; i++ { + path := fmt.Sprintf("%s%ccheck-%d", os.TempDir(), os.PathSeparator, rand.Int()) + if err = os.Mkdir(path, 0700); err == nil { + td.path = path + break + } + } + if td.path == "" { + panic("Couldn't create temporary directory: " + err.Error()) + } + } + result := filepath.Join(td.path, strconv.Itoa(td.counter)) + td.counter += 1 + return result +} + +func (td *tempDir) removeAll() { + td.Lock() + defer td.Unlock() + if td.path != "" { + err := os.RemoveAll(td.path) + if err != nil { + fmt.Fprintf(os.Stderr, "WARNING: Error cleaning up temporaries: "+err.Error()) + } + } +} + +// Create a new temporary directory which is automatically removed after +// the suite finishes running. +func (c *C) MkDir() string { + path := c.tempDir.newPath() + if err := os.Mkdir(path, 0700); err != nil { + panic(fmt.Sprintf("Couldn't create temporary directory %s: %s", path, err.Error())) + } + return path +} + +// ----------------------------------------------------------------------- +// Low-level logging functions. + +func (c *C) log(args ...interface{}) { + c.writeLog([]byte(fmt.Sprint(args...) + "\n")) +} + +func (c *C) logf(format string, args ...interface{}) { + c.writeLog([]byte(fmt.Sprintf(format+"\n", args...))) +} + +func (c *C) logNewLine() { + c.writeLog([]byte{'\n'}) +} + +func (c *C) writeLog(buf []byte) { + c.logb.Write(buf) + if c.logw != nil { + c.logw.Write(buf) + } +} + +func hasStringOrError(x interface{}) (ok bool) { + _, ok = x.(fmt.Stringer) + if ok { + return + } + _, ok = x.(error) + return +} + +func (c *C) logValue(label string, value interface{}) { + if label == "" { + if hasStringOrError(value) { + c.logf("... %#v (%q)", value, value) + } else { + c.logf("... %#v", value) + } + } else if value == nil { + c.logf("... %s = nil", label) + } else { + if hasStringOrError(value) { + fv := fmt.Sprintf("%#v", value) + qv := fmt.Sprintf("%q", value) + if fv != qv { + c.logf("... %s %s = %s (%s)", label, reflect.TypeOf(value), fv, qv) + return + } + } + if s, ok := value.(string); ok && isMultiLine(s) { + c.logf(`... %s %s = "" +`, label, reflect.TypeOf(value)) + c.logMultiLine(s) + } else { + c.logf("... %s %s = %#v", label, reflect.TypeOf(value), value) + } + } +} + +func (c *C) logMultiLine(s string) { + b := make([]byte, 0, len(s)*2) + i := 0 + n := len(s) + for i < n { + j := i + 1 + for j < n && s[j-1] != '\n' { + j++ + } + b = append(b, "... "...) + b = strconv.AppendQuote(b, s[i:j]) + if j < n { + b = append(b, " +"...) + } + b = append(b, '\n') + i = j + } + c.writeLog(b) +} + +func isMultiLine(s string) bool { + for i := 0; i+1 < len(s); i++ { + if s[i] == '\n' { + return true + } + } + return false +} + +func (c *C) logString(issue string) { + c.log("... ", issue) +} + +func (c *C) logCaller(skip int) { + // This is a bit heavier than it ought to be. + skip += 1 // Our own frame. + pc, callerFile, callerLine, ok := runtime.Caller(skip) + if !ok { + return + } + var testFile string + var testLine int + testFunc := runtime.FuncForPC(c.method.PC()) + if runtime.FuncForPC(pc) != testFunc { + for { + skip += 1 + if pc, file, line, ok := runtime.Caller(skip); ok { + // Note that the test line may be different on + // distinct calls for the same test. Showing + // the "internal" line is helpful when debugging. + if runtime.FuncForPC(pc) == testFunc { + testFile, testLine = file, line + break + } + } else { + break + } + } + } + if testFile != "" && (testFile != callerFile || testLine != callerLine) { + c.logCode(testFile, testLine) + } + c.logCode(callerFile, callerLine) +} + +func (c *C) logCode(path string, line int) { + c.logf("%s:%d:", nicePath(path), line) + code, err := printLine(path, line) + if code == "" { + code = "..." // XXX Open the file and take the raw line. + if err != nil { + code += err.Error() + } + } + c.log(indent(code, " ")) +} + +var valueGo = filepath.Join("reflect", "value.go") +var asmGo = filepath.Join("runtime", "asm_") + +func (c *C) logPanic(skip int, value interface{}) { + skip++ // Our own frame. + initialSkip := skip + for ; ; skip++ { + if pc, file, line, ok := runtime.Caller(skip); ok { + if skip == initialSkip { + c.logf("... Panic: %s (PC=0x%X)\n", value, pc) + } + name := niceFuncName(pc) + path := nicePath(file) + if strings.Contains(path, "/gopkg.in/check.v") { + continue + } + if name == "Value.call" && strings.HasSuffix(path, valueGo) { + continue + } + if (name == "call16" || name == "call32") && strings.Contains(path, asmGo) { + continue + } + c.logf("%s:%d\n in %s", nicePath(file), line, name) + } else { + break + } + } +} + +func (c *C) logSoftPanic(issue string) { + c.log("... Panic: ", issue) +} + +func (c *C) logArgPanic(method *methodType, expectedType string) { + c.logf("... Panic: %s argument should be %s", + niceFuncName(method.PC()), expectedType) +} + +// ----------------------------------------------------------------------- +// Some simple formatting helpers. + +var initWD, initWDErr = os.Getwd() + +func init() { + if initWDErr == nil { + initWD = strings.Replace(initWD, "\\", "/", -1) + "/" + } +} + +func nicePath(path string) string { + if initWDErr == nil { + if strings.HasPrefix(path, initWD) { + return path[len(initWD):] + } + } + return path +} + +func niceFuncPath(pc uintptr) string { + function := runtime.FuncForPC(pc) + if function != nil { + filename, line := function.FileLine(pc) + return fmt.Sprintf("%s:%d", nicePath(filename), line) + } + return "" +} + +func niceFuncName(pc uintptr) string { + function := runtime.FuncForPC(pc) + if function != nil { + name := path.Base(function.Name()) + if i := strings.Index(name, "."); i > 0 { + name = name[i+1:] + } + if strings.HasPrefix(name, "(*") { + if i := strings.Index(name, ")"); i > 0 { + name = name[2:i] + name[i+1:] + } + } + if i := strings.LastIndex(name, ".*"); i != -1 { + name = name[:i] + "." + name[i+2:] + } + if i := strings.LastIndex(name, "·"); i != -1 { + name = name[:i] + "." + name[i+2:] + } + return name + } + return "" +} + +// ----------------------------------------------------------------------- +// Result tracker to aggregate call results. + +type Result struct { + Succeeded int + Failed int + Skipped int + Panicked int + FixturePanicked int + ExpectedFailures int + Missed int // Not even tried to run, related to a panic in the fixture. + RunError error // Houston, we've got a problem. + WorkDir string // If KeepWorkDir is true +} + +type resultTracker struct { + result Result + _lastWasProblem bool + _waiting int + _missed int + _expectChan chan *C + _doneChan chan *C + _stopChan chan bool +} + +func newResultTracker() *resultTracker { + return &resultTracker{_expectChan: make(chan *C), // Synchronous + _doneChan: make(chan *C, 32), // Asynchronous + _stopChan: make(chan bool)} // Synchronous +} + +func (tracker *resultTracker) start() { + go tracker._loopRoutine() +} + +func (tracker *resultTracker) waitAndStop() { + <-tracker._stopChan +} + +func (tracker *resultTracker) expectCall(c *C) { + tracker._expectChan <- c +} + +func (tracker *resultTracker) callDone(c *C) { + tracker._doneChan <- c +} + +func (tracker *resultTracker) _loopRoutine() { + for { + var c *C + if tracker._waiting > 0 { + // Calls still running. Can't stop. + select { + // XXX Reindent this (not now to make diff clear) + case c = <-tracker._expectChan: + tracker._waiting += 1 + case c = <-tracker._doneChan: + tracker._waiting -= 1 + switch c.status() { + case succeededSt: + if c.kind == testKd { + if c.mustFail { + tracker.result.ExpectedFailures++ + } else { + tracker.result.Succeeded++ + } + } + case failedSt: + tracker.result.Failed++ + case panickedSt: + if c.kind == fixtureKd { + tracker.result.FixturePanicked++ + } else { + tracker.result.Panicked++ + } + case fixturePanickedSt: + // Track it as missed, since the panic + // was on the fixture, not on the test. + tracker.result.Missed++ + case missedSt: + tracker.result.Missed++ + case skippedSt: + if c.kind == testKd { + tracker.result.Skipped++ + } + } + } + } else { + // No calls. Can stop, but no done calls here. + select { + case tracker._stopChan <- true: + return + case c = <-tracker._expectChan: + tracker._waiting += 1 + case c = <-tracker._doneChan: + panic("Tracker got an unexpected done call.") + } + } + } +} + +// ----------------------------------------------------------------------- +// The underlying suite runner. + +type suiteRunner struct { + suite interface{} + setUpSuite, tearDownSuite *methodType + setUpTest, tearDownTest *methodType + tests []*methodType + tracker *resultTracker + tempDir *tempDir + keepDir bool + output *outputWriter + reportedProblemLast bool + benchTime time.Duration + benchMem bool +} + +type RunConf struct { + Output io.Writer + Stream bool + Verbose bool + Filter string + Benchmark bool + BenchmarkTime time.Duration // Defaults to 1 second + BenchmarkMem bool + KeepWorkDir bool +} + +// Create a new suiteRunner able to run all methods in the given suite. +func newSuiteRunner(suite interface{}, runConf *RunConf) *suiteRunner { + var conf RunConf + if runConf != nil { + conf = *runConf + } + if conf.Output == nil { + conf.Output = os.Stdout + } + if conf.Benchmark { + conf.Verbose = true + } + + suiteType := reflect.TypeOf(suite) + suiteNumMethods := suiteType.NumMethod() + suiteValue := reflect.ValueOf(suite) + + runner := &suiteRunner{ + suite: suite, + output: newOutputWriter(conf.Output, conf.Stream, conf.Verbose), + tracker: newResultTracker(), + benchTime: conf.BenchmarkTime, + benchMem: conf.BenchmarkMem, + tempDir: &tempDir{}, + keepDir: conf.KeepWorkDir, + tests: make([]*methodType, 0, suiteNumMethods), + } + if runner.benchTime == 0 { + runner.benchTime = 1 * time.Second + } + + var filterRegexp *regexp.Regexp + if conf.Filter != "" { + if regexp, err := regexp.Compile(conf.Filter); err != nil { + msg := "Bad filter expression: " + err.Error() + runner.tracker.result.RunError = errors.New(msg) + return runner + } else { + filterRegexp = regexp + } + } + + for i := 0; i != suiteNumMethods; i++ { + method := newMethod(suiteValue, i) + switch method.Info.Name { + case "SetUpSuite": + runner.setUpSuite = method + case "TearDownSuite": + runner.tearDownSuite = method + case "SetUpTest": + runner.setUpTest = method + case "TearDownTest": + runner.tearDownTest = method + default: + prefix := "Test" + if conf.Benchmark { + prefix = "Benchmark" + } + if !strings.HasPrefix(method.Info.Name, prefix) { + continue + } + if filterRegexp == nil || method.matches(filterRegexp) { + runner.tests = append(runner.tests, method) + } + } + } + return runner +} + +// Run all methods in the given suite. +func (runner *suiteRunner) run() *Result { + if runner.tracker.result.RunError == nil && len(runner.tests) > 0 { + runner.tracker.start() + if runner.checkFixtureArgs() { + c := runner.runFixture(runner.setUpSuite, "", nil) + if c == nil || c.status() == succeededSt { + for i := 0; i != len(runner.tests); i++ { + c := runner.runTest(runner.tests[i]) + if c.status() == fixturePanickedSt { + runner.skipTests(missedSt, runner.tests[i+1:]) + break + } + } + } else if c != nil && c.status() == skippedSt { + runner.skipTests(skippedSt, runner.tests) + } else { + runner.skipTests(missedSt, runner.tests) + } + runner.runFixture(runner.tearDownSuite, "", nil) + } else { + runner.skipTests(missedSt, runner.tests) + } + runner.tracker.waitAndStop() + if runner.keepDir { + runner.tracker.result.WorkDir = runner.tempDir.path + } else { + runner.tempDir.removeAll() + } + } + return &runner.tracker.result +} + +// Create a call object with the given suite method, and fork a +// goroutine with the provided dispatcher for running it. +func (runner *suiteRunner) forkCall(method *methodType, kind funcKind, testName string, logb *logger, dispatcher func(c *C)) *C { + var logw io.Writer + if runner.output.Stream { + logw = runner.output + } + if logb == nil { + logb = new(logger) + } + c := &C{ + method: method, + kind: kind, + testName: testName, + logb: logb, + logw: logw, + tempDir: runner.tempDir, + done: make(chan *C, 1), + timer: timer{benchTime: runner.benchTime}, + startTime: time.Now(), + benchMem: runner.benchMem, + } + runner.tracker.expectCall(c) + go (func() { + runner.reportCallStarted(c) + defer runner.callDone(c) + dispatcher(c) + })() + return c +} + +// Same as forkCall(), but wait for call to finish before returning. +func (runner *suiteRunner) runFunc(method *methodType, kind funcKind, testName string, logb *logger, dispatcher func(c *C)) *C { + c := runner.forkCall(method, kind, testName, logb, dispatcher) + <-c.done + return c +} + +// Handle a finished call. If there were any panics, update the call status +// accordingly. Then, mark the call as done and report to the tracker. +func (runner *suiteRunner) callDone(c *C) { + value := recover() + if value != nil { + switch v := value.(type) { + case *fixturePanic: + if v.status == skippedSt { + c.setStatus(skippedSt) + } else { + c.logSoftPanic("Fixture has panicked (see related PANIC)") + c.setStatus(fixturePanickedSt) + } + default: + c.logPanic(1, value) + c.setStatus(panickedSt) + } + } + if c.mustFail { + switch c.status() { + case failedSt: + c.setStatus(succeededSt) + case succeededSt: + c.setStatus(failedSt) + c.logString("Error: Test succeeded, but was expected to fail") + c.logString("Reason: " + c.reason) + } + } + + runner.reportCallDone(c) + c.done <- c +} + +// Runs a fixture call synchronously. The fixture will still be run in a +// goroutine like all suite methods, but this method will not return +// while the fixture goroutine is not done, because the fixture must be +// run in a desired order. +func (runner *suiteRunner) runFixture(method *methodType, testName string, logb *logger) *C { + if method != nil { + c := runner.runFunc(method, fixtureKd, testName, logb, func(c *C) { + c.ResetTimer() + c.StartTimer() + defer c.StopTimer() + c.method.Call([]reflect.Value{reflect.ValueOf(c)}) + }) + return c + } + return nil +} + +// Run the fixture method with runFixture(), but panic with a fixturePanic{} +// in case the fixture method panics. This makes it easier to track the +// fixture panic together with other call panics within forkTest(). +func (runner *suiteRunner) runFixtureWithPanic(method *methodType, testName string, logb *logger, skipped *bool) *C { + if skipped != nil && *skipped { + return nil + } + c := runner.runFixture(method, testName, logb) + if c != nil && c.status() != succeededSt { + if skipped != nil { + *skipped = c.status() == skippedSt + } + panic(&fixturePanic{c.status(), method}) + } + return c +} + +type fixturePanic struct { + status funcStatus + method *methodType +} + +// Run the suite test method, together with the test-specific fixture, +// asynchronously. +func (runner *suiteRunner) forkTest(method *methodType) *C { + testName := method.String() + return runner.forkCall(method, testKd, testName, nil, func(c *C) { + var skipped bool + defer runner.runFixtureWithPanic(runner.tearDownTest, testName, nil, &skipped) + defer c.StopTimer() + benchN := 1 + for { + runner.runFixtureWithPanic(runner.setUpTest, testName, c.logb, &skipped) + mt := c.method.Type() + if mt.NumIn() != 1 || mt.In(0) != reflect.TypeOf(c) { + // Rather than a plain panic, provide a more helpful message when + // the argument type is incorrect. + c.setStatus(panickedSt) + c.logArgPanic(c.method, "*check.C") + return + } + if strings.HasPrefix(c.method.Info.Name, "Test") { + c.ResetTimer() + c.StartTimer() + c.method.Call([]reflect.Value{reflect.ValueOf(c)}) + return + } + if !strings.HasPrefix(c.method.Info.Name, "Benchmark") { + panic("unexpected method prefix: " + c.method.Info.Name) + } + + runtime.GC() + c.N = benchN + c.ResetTimer() + c.StartTimer() + c.method.Call([]reflect.Value{reflect.ValueOf(c)}) + c.StopTimer() + if c.status() != succeededSt || c.duration >= c.benchTime || benchN >= 1e9 { + return + } + perOpN := int(1e9) + if c.nsPerOp() != 0 { + perOpN = int(c.benchTime.Nanoseconds() / c.nsPerOp()) + } + + // Logic taken from the stock testing package: + // - Run more iterations than we think we'll need for a second (1.5x). + // - Don't grow too fast in case we had timing errors previously. + // - Be sure to run at least one more than last time. + benchN = max(min(perOpN+perOpN/2, 100*benchN), benchN+1) + benchN = roundUp(benchN) + + skipped = true // Don't run the deferred one if this panics. + runner.runFixtureWithPanic(runner.tearDownTest, testName, nil, nil) + skipped = false + } + }) +} + +// Same as forkTest(), but wait for the test to finish before returning. +func (runner *suiteRunner) runTest(method *methodType) *C { + c := runner.forkTest(method) + <-c.done + return c +} + +// Helper to mark tests as skipped or missed. A bit heavy for what +// it does, but it enables homogeneous handling of tracking, including +// nice verbose output. +func (runner *suiteRunner) skipTests(status funcStatus, methods []*methodType) { + for _, method := range methods { + runner.runFunc(method, testKd, "", nil, func(c *C) { + c.setStatus(status) + }) + } +} + +// Verify if the fixture arguments are *check.C. In case of errors, +// log the error as a panic in the fixture method call, and return false. +func (runner *suiteRunner) checkFixtureArgs() bool { + succeeded := true + argType := reflect.TypeOf(&C{}) + for _, method := range []*methodType{runner.setUpSuite, runner.tearDownSuite, runner.setUpTest, runner.tearDownTest} { + if method != nil { + mt := method.Type() + if mt.NumIn() != 1 || mt.In(0) != argType { + succeeded = false + runner.runFunc(method, fixtureKd, "", nil, func(c *C) { + c.logArgPanic(method, "*check.C") + c.setStatus(panickedSt) + }) + } + } + } + return succeeded +} + +func (runner *suiteRunner) reportCallStarted(c *C) { + runner.output.WriteCallStarted("START", c) +} + +func (runner *suiteRunner) reportCallDone(c *C) { + runner.tracker.callDone(c) + switch c.status() { + case succeededSt: + if c.mustFail { + runner.output.WriteCallSuccess("FAIL EXPECTED", c) + } else { + runner.output.WriteCallSuccess("PASS", c) + } + case skippedSt: + runner.output.WriteCallSuccess("SKIP", c) + case failedSt: + runner.output.WriteCallProblem("FAIL", c) + case panickedSt: + runner.output.WriteCallProblem("PANIC", c) + case fixturePanickedSt: + // That's a testKd call reporting that its fixture + // has panicked. The fixture call which caused the + // panic itself was tracked above. We'll report to + // aid debugging. + runner.output.WriteCallProblem("PANIC", c) + case missedSt: + runner.output.WriteCallSuccess("MISS", c) + } +} + +// ----------------------------------------------------------------------- +// Output writer manages atomic output writing according to settings. + +type outputWriter struct { + m sync.Mutex + writer io.Writer + wroteCallProblemLast bool + Stream bool + Verbose bool +} + +func newOutputWriter(writer io.Writer, stream, verbose bool) *outputWriter { + return &outputWriter{writer: writer, Stream: stream, Verbose: verbose} +} + +func (ow *outputWriter) Write(content []byte) (n int, err error) { + ow.m.Lock() + n, err = ow.writer.Write(content) + ow.m.Unlock() + return +} + +func (ow *outputWriter) WriteCallStarted(label string, c *C) { + if ow.Stream { + header := renderCallHeader(label, c, "", "\n") + ow.m.Lock() + ow.writer.Write([]byte(header)) + ow.m.Unlock() + } +} + +func (ow *outputWriter) WriteCallProblem(label string, c *C) { + var prefix string + if !ow.Stream { + prefix = "\n-----------------------------------" + + "-----------------------------------\n" + } + header := renderCallHeader(label, c, prefix, "\n\n") + ow.m.Lock() + ow.wroteCallProblemLast = true + ow.writer.Write([]byte(header)) + if !ow.Stream { + c.logb.WriteTo(ow.writer) + } + ow.m.Unlock() +} + +func (ow *outputWriter) WriteCallSuccess(label string, c *C) { + if ow.Stream || (ow.Verbose && c.kind == testKd) { + // TODO Use a buffer here. + var suffix string + if c.reason != "" { + suffix = " (" + c.reason + ")" + } + if c.status() == succeededSt { + suffix += "\t" + c.timerString() + } + suffix += "\n" + if ow.Stream { + suffix += "\n" + } + header := renderCallHeader(label, c, "", suffix) + ow.m.Lock() + // Resist temptation of using line as prefix above due to race. + if !ow.Stream && ow.wroteCallProblemLast { + header = "\n-----------------------------------" + + "-----------------------------------\n" + + header + } + ow.wroteCallProblemLast = false + ow.writer.Write([]byte(header)) + ow.m.Unlock() + } +} + +func renderCallHeader(label string, c *C, prefix, suffix string) string { + pc := c.method.PC() + return fmt.Sprintf("%s%s: %s: %s%s", prefix, label, niceFuncPath(pc), + niceFuncName(pc), suffix) +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/check_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/check_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/check_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/check_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,207 @@ +// This file contains just a few generic helpers which are used by the +// other test files. + +package check_test + +import ( + "flag" + "fmt" + "os" + "regexp" + "runtime" + "testing" + "time" + + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1" +) + +// We count the number of suites run at least to get a vague hint that the +// test suite is behaving as it should. Otherwise a bug introduced at the +// very core of the system could go unperceived. +const suitesRunExpected = 8 + +var suitesRun int = 0 + +func Test(t *testing.T) { + check.TestingT(t) + if suitesRun != suitesRunExpected && flag.Lookup("check.f").Value.String() == "" { + critical(fmt.Sprintf("Expected %d suites to run rather than %d", + suitesRunExpected, suitesRun)) + } +} + +// ----------------------------------------------------------------------- +// Helper functions. + +// Break down badly. This is used in test cases which can't yet assume +// that the fundamental bits are working. +func critical(error string) { + fmt.Fprintln(os.Stderr, "CRITICAL: "+error) + os.Exit(1) +} + +// Return the file line where it's called. +func getMyLine() int { + if _, _, line, ok := runtime.Caller(1); ok { + return line + } + return -1 +} + +// ----------------------------------------------------------------------- +// Helper type implementing a basic io.Writer for testing output. + +// Type implementing the io.Writer interface for analyzing output. +type String struct { + value string +} + +// The only function required by the io.Writer interface. Will append +// written data to the String.value string. +func (s *String) Write(p []byte) (n int, err error) { + s.value += string(p) + return len(p), nil +} + +// Trivial wrapper to test errors happening on a different file +// than the test itself. +func checkEqualWrapper(c *check.C, obtained, expected interface{}) (result bool, line int) { + return c.Check(obtained, check.Equals, expected), getMyLine() +} + +// ----------------------------------------------------------------------- +// Helper suite for testing basic fail behavior. + +type FailHelper struct { + testLine int +} + +func (s *FailHelper) TestLogAndFail(c *check.C) { + s.testLine = getMyLine() - 1 + c.Log("Expected failure!") + c.Fail() +} + +// ----------------------------------------------------------------------- +// Helper suite for testing basic success behavior. + +type SuccessHelper struct{} + +func (s *SuccessHelper) TestLogAndSucceed(c *check.C) { + c.Log("Expected success!") +} + +// ----------------------------------------------------------------------- +// Helper suite for testing ordering and behavior of fixture. + +type FixtureHelper struct { + calls []string + panicOn string + skip bool + skipOnN int + sleepOn string + sleep time.Duration + bytes int64 +} + +func (s *FixtureHelper) trace(name string, c *check.C) { + s.calls = append(s.calls, name) + if name == s.panicOn { + panic(name) + } + if s.sleep > 0 && s.sleepOn == name { + time.Sleep(s.sleep) + } + if s.skip && s.skipOnN == len(s.calls)-1 { + c.Skip("skipOnN == n") + } +} + +func (s *FixtureHelper) SetUpSuite(c *check.C) { + s.trace("SetUpSuite", c) +} + +func (s *FixtureHelper) TearDownSuite(c *check.C) { + s.trace("TearDownSuite", c) +} + +func (s *FixtureHelper) SetUpTest(c *check.C) { + s.trace("SetUpTest", c) +} + +func (s *FixtureHelper) TearDownTest(c *check.C) { + s.trace("TearDownTest", c) +} + +func (s *FixtureHelper) Test1(c *check.C) { + s.trace("Test1", c) +} + +func (s *FixtureHelper) Test2(c *check.C) { + s.trace("Test2", c) +} + +func (s *FixtureHelper) Benchmark1(c *check.C) { + s.trace("Benchmark1", c) + for i := 0; i < c.N; i++ { + time.Sleep(s.sleep) + } +} + +func (s *FixtureHelper) Benchmark2(c *check.C) { + s.trace("Benchmark2", c) + c.SetBytes(1024) + for i := 0; i < c.N; i++ { + time.Sleep(s.sleep) + } +} + +func (s *FixtureHelper) Benchmark3(c *check.C) { + var x []int64 + s.trace("Benchmark3", c) + for i := 0; i < c.N; i++ { + time.Sleep(s.sleep) + x = make([]int64, 5) + _ = x + } +} + +// ----------------------------------------------------------------------- +// Helper which checks the state of the test and ensures that it matches +// the given expectations. Depends on c.Errorf() working, so shouldn't +// be used to test this one function. + +type expectedState struct { + name string + result interface{} + failed bool + log string +} + +// Verify the state of the test. Note that since this also verifies if +// the test is supposed to be in a failed state, no other checks should +// be done in addition to what is being tested. +func checkState(c *check.C, result interface{}, expected *expectedState) { + failed := c.Failed() + c.Succeed() + log := c.GetTestLog() + matched, matchError := regexp.MatchString("^"+expected.log+"$", log) + if matchError != nil { + c.Errorf("Error in matching expression used in testing %s", + expected.name) + } else if !matched { + c.Errorf("%s logged:\n----------\n%s----------\n\nExpected:\n----------\n%s\n----------", + expected.name, log, expected.log) + } + if result != expected.result { + c.Errorf("%s returned %#v rather than %#v", + expected.name, result, expected.result) + } + if failed != expected.failed { + if failed { + c.Errorf("%s has failed when it shouldn't", expected.name) + } else { + c.Errorf("%s has not failed when it should", expected.name) + } + } +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/export_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/export_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/export_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/export_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,9 @@ +package check + +func PrintLine(filename string, line int) (string, error) { + return printLine(filename, line) +} + +func Indent(s, with string) string { + return indent(s, with) +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/fixture_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/fixture_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/fixture_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/fixture_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,484 @@ +// Tests for the behavior of the test fixture system. + +package check_test + +import ( + . "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1" +) + +// ----------------------------------------------------------------------- +// Fixture test suite. + +type FixtureS struct{} + +var fixtureS = Suite(&FixtureS{}) + +func (s *FixtureS) TestCountSuite(c *C) { + suitesRun += 1 +} + +// ----------------------------------------------------------------------- +// Basic fixture ordering verification. + +func (s *FixtureS) TestOrder(c *C) { + helper := FixtureHelper{} + Run(&helper, nil) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "SetUpTest") + c.Check(helper.calls[5], Equals, "Test2") + c.Check(helper.calls[6], Equals, "TearDownTest") + c.Check(helper.calls[7], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 8) +} + +// ----------------------------------------------------------------------- +// Check the behavior when panics occur within tests and fixtures. + +func (s *FixtureS) TestPanicOnTest(c *C) { + helper := FixtureHelper{panicOn: "Test1"} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "SetUpTest") + c.Check(helper.calls[5], Equals, "Test2") + c.Check(helper.calls[6], Equals, "TearDownTest") + c.Check(helper.calls[7], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 8) + + expected := "^\n-+\n" + + "PANIC: check_test\\.go:[0-9]+: FixtureHelper.Test1\n\n" + + "\\.\\.\\. Panic: Test1 \\(PC=[xA-F0-9]+\\)\n\n" + + ".+:[0-9]+\n" + + " in (go)?panic\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.trace\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.Test1\n" + + "(.|\n)*$" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnSetUpTest(c *C) { + helper := FixtureHelper{panicOn: "SetUpTest"} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "TearDownTest") + c.Check(helper.calls[3], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 4) + + expected := "^\n-+\n" + + "PANIC: check_test\\.go:[0-9]+: " + + "FixtureHelper\\.SetUpTest\n\n" + + "\\.\\.\\. Panic: SetUpTest \\(PC=[xA-F0-9]+\\)\n\n" + + ".+:[0-9]+\n" + + " in (go)?panic\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.trace\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.SetUpTest\n" + + "(.|\n)*" + + "\n-+\n" + + "PANIC: check_test\\.go:[0-9]+: " + + "FixtureHelper\\.Test1\n\n" + + "\\.\\.\\. Panic: Fixture has panicked " + + "\\(see related PANIC\\)\n$" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnTearDownTest(c *C) { + helper := FixtureHelper{panicOn: "TearDownTest"} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 5) + + expected := "^\n-+\n" + + "PANIC: check_test\\.go:[0-9]+: " + + "FixtureHelper.TearDownTest\n\n" + + "\\.\\.\\. Panic: TearDownTest \\(PC=[xA-F0-9]+\\)\n\n" + + ".+:[0-9]+\n" + + " in (go)?panic\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.trace\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.TearDownTest\n" + + "(.|\n)*" + + "\n-+\n" + + "PANIC: check_test\\.go:[0-9]+: " + + "FixtureHelper\\.Test1\n\n" + + "\\.\\.\\. Panic: Fixture has panicked " + + "\\(see related PANIC\\)\n$" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnSetUpSuite(c *C) { + helper := FixtureHelper{panicOn: "SetUpSuite"} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 2) + + expected := "^\n-+\n" + + "PANIC: check_test\\.go:[0-9]+: " + + "FixtureHelper.SetUpSuite\n\n" + + "\\.\\.\\. Panic: SetUpSuite \\(PC=[xA-F0-9]+\\)\n\n" + + ".+:[0-9]+\n" + + " in (go)?panic\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.trace\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.SetUpSuite\n" + + "(.|\n)*$" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnTearDownSuite(c *C) { + helper := FixtureHelper{panicOn: "TearDownSuite"} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "SetUpTest") + c.Check(helper.calls[5], Equals, "Test2") + c.Check(helper.calls[6], Equals, "TearDownTest") + c.Check(helper.calls[7], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 8) + + expected := "^\n-+\n" + + "PANIC: check_test\\.go:[0-9]+: " + + "FixtureHelper.TearDownSuite\n\n" + + "\\.\\.\\. Panic: TearDownSuite \\(PC=[xA-F0-9]+\\)\n\n" + + ".+:[0-9]+\n" + + " in (go)?panic\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.trace\n" + + ".*check_test.go:[0-9]+\n" + + " in FixtureHelper.TearDownSuite\n" + + "(.|\n)*$" + + c.Check(output.value, Matches, expected) +} + +// ----------------------------------------------------------------------- +// A wrong argument on a test or fixture will produce a nice error. + +func (s *FixtureS) TestPanicOnWrongTestArg(c *C) { + helper := WrongTestArgHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "TearDownTest") + c.Check(helper.calls[3], Equals, "SetUpTest") + c.Check(helper.calls[4], Equals, "Test2") + c.Check(helper.calls[5], Equals, "TearDownTest") + c.Check(helper.calls[6], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 7) + + expected := "^\n-+\n" + + "PANIC: fixture_test\\.go:[0-9]+: " + + "WrongTestArgHelper\\.Test1\n\n" + + "\\.\\.\\. Panic: WrongTestArgHelper\\.Test1 argument " + + "should be \\*check\\.C\n" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnWrongSetUpTestArg(c *C) { + helper := WrongSetUpTestArgHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(len(helper.calls), Equals, 0) + + expected := + "^\n-+\n" + + "PANIC: fixture_test\\.go:[0-9]+: " + + "WrongSetUpTestArgHelper\\.SetUpTest\n\n" + + "\\.\\.\\. Panic: WrongSetUpTestArgHelper\\.SetUpTest argument " + + "should be \\*check\\.C\n" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnWrongSetUpSuiteArg(c *C) { + helper := WrongSetUpSuiteArgHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(len(helper.calls), Equals, 0) + + expected := + "^\n-+\n" + + "PANIC: fixture_test\\.go:[0-9]+: " + + "WrongSetUpSuiteArgHelper\\.SetUpSuite\n\n" + + "\\.\\.\\. Panic: WrongSetUpSuiteArgHelper\\.SetUpSuite argument " + + "should be \\*check\\.C\n" + + c.Check(output.value, Matches, expected) +} + +// ----------------------------------------------------------------------- +// Nice errors also when tests or fixture have wrong arg count. + +func (s *FixtureS) TestPanicOnWrongTestArgCount(c *C) { + helper := WrongTestArgCountHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "TearDownTest") + c.Check(helper.calls[3], Equals, "SetUpTest") + c.Check(helper.calls[4], Equals, "Test2") + c.Check(helper.calls[5], Equals, "TearDownTest") + c.Check(helper.calls[6], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 7) + + expected := "^\n-+\n" + + "PANIC: fixture_test\\.go:[0-9]+: " + + "WrongTestArgCountHelper\\.Test1\n\n" + + "\\.\\.\\. Panic: WrongTestArgCountHelper\\.Test1 argument " + + "should be \\*check\\.C\n" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnWrongSetUpTestArgCount(c *C) { + helper := WrongSetUpTestArgCountHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(len(helper.calls), Equals, 0) + + expected := + "^\n-+\n" + + "PANIC: fixture_test\\.go:[0-9]+: " + + "WrongSetUpTestArgCountHelper\\.SetUpTest\n\n" + + "\\.\\.\\. Panic: WrongSetUpTestArgCountHelper\\.SetUpTest argument " + + "should be \\*check\\.C\n" + + c.Check(output.value, Matches, expected) +} + +func (s *FixtureS) TestPanicOnWrongSetUpSuiteArgCount(c *C) { + helper := WrongSetUpSuiteArgCountHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(len(helper.calls), Equals, 0) + + expected := + "^\n-+\n" + + "PANIC: fixture_test\\.go:[0-9]+: " + + "WrongSetUpSuiteArgCountHelper\\.SetUpSuite\n\n" + + "\\.\\.\\. Panic: WrongSetUpSuiteArgCountHelper" + + "\\.SetUpSuite argument should be \\*check\\.C\n" + + c.Check(output.value, Matches, expected) +} + +// ----------------------------------------------------------------------- +// Helper test suites with wrong function arguments. + +type WrongTestArgHelper struct { + FixtureHelper +} + +func (s *WrongTestArgHelper) Test1(t int) { +} + +type WrongSetUpTestArgHelper struct { + FixtureHelper +} + +func (s *WrongSetUpTestArgHelper) SetUpTest(t int) { +} + +type WrongSetUpSuiteArgHelper struct { + FixtureHelper +} + +func (s *WrongSetUpSuiteArgHelper) SetUpSuite(t int) { +} + +type WrongTestArgCountHelper struct { + FixtureHelper +} + +func (s *WrongTestArgCountHelper) Test1(c *C, i int) { +} + +type WrongSetUpTestArgCountHelper struct { + FixtureHelper +} + +func (s *WrongSetUpTestArgCountHelper) SetUpTest(c *C, i int) { +} + +type WrongSetUpSuiteArgCountHelper struct { + FixtureHelper +} + +func (s *WrongSetUpSuiteArgCountHelper) SetUpSuite(c *C, i int) { +} + +// ----------------------------------------------------------------------- +// Ensure fixture doesn't run without tests. + +type NoTestsHelper struct { + hasRun bool +} + +func (s *NoTestsHelper) SetUpSuite(c *C) { + s.hasRun = true +} + +func (s *NoTestsHelper) TearDownSuite(c *C) { + s.hasRun = true +} + +func (s *FixtureS) TestFixtureDoesntRunWithoutTests(c *C) { + helper := NoTestsHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Check(helper.hasRun, Equals, false) +} + +// ----------------------------------------------------------------------- +// Verify that checks and assertions work correctly inside the fixture. + +type FixtureCheckHelper struct { + fail string + completed bool +} + +func (s *FixtureCheckHelper) SetUpSuite(c *C) { + switch s.fail { + case "SetUpSuiteAssert": + c.Assert(false, Equals, true) + case "SetUpSuiteCheck": + c.Check(false, Equals, true) + } + s.completed = true +} + +func (s *FixtureCheckHelper) SetUpTest(c *C) { + switch s.fail { + case "SetUpTestAssert": + c.Assert(false, Equals, true) + case "SetUpTestCheck": + c.Check(false, Equals, true) + } + s.completed = true +} + +func (s *FixtureCheckHelper) Test(c *C) { + // Do nothing. +} + +func (s *FixtureS) TestSetUpSuiteCheck(c *C) { + helper := FixtureCheckHelper{fail: "SetUpSuiteCheck"} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Assert(output.value, Matches, + "\n---+\n"+ + "FAIL: fixture_test\\.go:[0-9]+: "+ + "FixtureCheckHelper\\.SetUpSuite\n\n"+ + "fixture_test\\.go:[0-9]+:\n"+ + " c\\.Check\\(false, Equals, true\\)\n"+ + "\\.+ obtained bool = false\n"+ + "\\.+ expected bool = true\n\n") + c.Assert(helper.completed, Equals, true) +} + +func (s *FixtureS) TestSetUpSuiteAssert(c *C) { + helper := FixtureCheckHelper{fail: "SetUpSuiteAssert"} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Assert(output.value, Matches, + "\n---+\n"+ + "FAIL: fixture_test\\.go:[0-9]+: "+ + "FixtureCheckHelper\\.SetUpSuite\n\n"+ + "fixture_test\\.go:[0-9]+:\n"+ + " c\\.Assert\\(false, Equals, true\\)\n"+ + "\\.+ obtained bool = false\n"+ + "\\.+ expected bool = true\n\n") + c.Assert(helper.completed, Equals, false) +} + +// ----------------------------------------------------------------------- +// Verify that logging within SetUpTest() persists within the test log itself. + +type FixtureLogHelper struct { + c *C +} + +func (s *FixtureLogHelper) SetUpTest(c *C) { + s.c = c + c.Log("1") +} + +func (s *FixtureLogHelper) Test(c *C) { + c.Log("2") + s.c.Log("3") + c.Log("4") + c.Fail() +} + +func (s *FixtureLogHelper) TearDownTest(c *C) { + s.c.Log("5") +} + +func (s *FixtureS) TestFixtureLogging(c *C) { + helper := FixtureLogHelper{} + output := String{} + Run(&helper, &RunConf{Output: &output}) + c.Assert(output.value, Matches, + "\n---+\n"+ + "FAIL: fixture_test\\.go:[0-9]+: "+ + "FixtureLogHelper\\.Test\n\n"+ + "1\n2\n3\n4\n5\n") +} + +// ----------------------------------------------------------------------- +// Skip() within fixture methods. + +func (s *FixtureS) TestSkipSuite(c *C) { + helper := FixtureHelper{skip: true, skipOnN: 0} + output := String{} + result := Run(&helper, &RunConf{Output: &output}) + c.Assert(output.value, Equals, "") + c.Assert(helper.calls[0], Equals, "SetUpSuite") + c.Assert(helper.calls[1], Equals, "TearDownSuite") + c.Assert(len(helper.calls), Equals, 2) + c.Assert(result.Skipped, Equals, 2) +} + +func (s *FixtureS) TestSkipTest(c *C) { + helper := FixtureHelper{skip: true, skipOnN: 1} + output := String{} + result := Run(&helper, &RunConf{Output: &output}) + c.Assert(helper.calls[0], Equals, "SetUpSuite") + c.Assert(helper.calls[1], Equals, "SetUpTest") + c.Assert(helper.calls[2], Equals, "SetUpTest") + c.Assert(helper.calls[3], Equals, "Test2") + c.Assert(helper.calls[4], Equals, "TearDownTest") + c.Assert(helper.calls[5], Equals, "TearDownSuite") + c.Assert(len(helper.calls), Equals, 6) + c.Assert(result.Skipped, Equals, 1) +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/foundation_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/foundation_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/foundation_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/foundation_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,335 @@ +// These tests check that the foundations of gocheck are working properly. +// They already assume that fundamental failing is working already, though, +// since this was tested in bootstrap_test.go. Even then, some care may +// still have to be taken when using external functions, since they should +// of course not rely on functionality tested here. + +package check_test + +import ( + "fmt" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1" + "log" + "os" + "regexp" + "strings" +) + +// ----------------------------------------------------------------------- +// Foundation test suite. + +type FoundationS struct{} + +var foundationS = check.Suite(&FoundationS{}) + +func (s *FoundationS) TestCountSuite(c *check.C) { + suitesRun += 1 +} + +func (s *FoundationS) TestErrorf(c *check.C) { + // Do not use checkState() here. It depends on Errorf() working. + expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+ + " c.Errorf(\"Error %%v!\", \"message\")\n"+ + "... Error: Error message!\n\n", + getMyLine()+1) + c.Errorf("Error %v!", "message") + failed := c.Failed() + c.Succeed() + if log := c.GetTestLog(); log != expectedLog { + c.Logf("Errorf() logged %#v rather than %#v", log, expectedLog) + c.Fail() + } + if !failed { + c.Logf("Errorf() didn't put the test in a failed state") + c.Fail() + } +} + +func (s *FoundationS) TestError(c *check.C) { + expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+ + " c\\.Error\\(\"Error \", \"message!\"\\)\n"+ + "\\.\\.\\. Error: Error message!\n\n", + getMyLine()+1) + c.Error("Error ", "message!") + checkState(c, nil, + &expectedState{ + name: "Error(`Error `, `message!`)", + failed: true, + log: expectedLog, + }) +} + +func (s *FoundationS) TestFailNow(c *check.C) { + defer (func() { + if !c.Failed() { + c.Error("FailNow() didn't fail the test") + } else { + c.Succeed() + if c.GetTestLog() != "" { + c.Error("Something got logged:\n" + c.GetTestLog()) + } + } + })() + + c.FailNow() + c.Log("FailNow() didn't stop the test") +} + +func (s *FoundationS) TestSucceedNow(c *check.C) { + defer (func() { + if c.Failed() { + c.Error("SucceedNow() didn't succeed the test") + } + if c.GetTestLog() != "" { + c.Error("Something got logged:\n" + c.GetTestLog()) + } + })() + + c.Fail() + c.SucceedNow() + c.Log("SucceedNow() didn't stop the test") +} + +func (s *FoundationS) TestFailureHeader(c *check.C) { + output := String{} + failHelper := FailHelper{} + check.Run(&failHelper, &check.RunConf{Output: &output}) + header := fmt.Sprintf(""+ + "\n-----------------------------------"+ + "-----------------------------------\n"+ + "FAIL: check_test.go:%d: FailHelper.TestLogAndFail\n", + failHelper.testLine) + if strings.Index(output.value, header) == -1 { + c.Errorf(""+ + "Failure didn't print a proper header.\n"+ + "... Got:\n%s... Expected something with:\n%s", + output.value, header) + } +} + +func (s *FoundationS) TestFatal(c *check.C) { + var line int + defer (func() { + if !c.Failed() { + c.Error("Fatal() didn't fail the test") + } else { + c.Succeed() + expected := fmt.Sprintf("foundation_test.go:%d:\n"+ + " c.Fatal(\"Die \", \"now!\")\n"+ + "... Error: Die now!\n\n", + line) + if c.GetTestLog() != expected { + c.Error("Incorrect log:", c.GetTestLog()) + } + } + })() + + line = getMyLine() + 1 + c.Fatal("Die ", "now!") + c.Log("Fatal() didn't stop the test") +} + +func (s *FoundationS) TestFatalf(c *check.C) { + var line int + defer (func() { + if !c.Failed() { + c.Error("Fatalf() didn't fail the test") + } else { + c.Succeed() + expected := fmt.Sprintf("foundation_test.go:%d:\n"+ + " c.Fatalf(\"Die %%s!\", \"now\")\n"+ + "... Error: Die now!\n\n", + line) + if c.GetTestLog() != expected { + c.Error("Incorrect log:", c.GetTestLog()) + } + } + })() + + line = getMyLine() + 1 + c.Fatalf("Die %s!", "now") + c.Log("Fatalf() didn't stop the test") +} + +func (s *FoundationS) TestCallerLoggingInsideTest(c *check.C) { + log := fmt.Sprintf(""+ + "foundation_test.go:%d:\n"+ + " result := c.Check\\(10, check.Equals, 20\\)\n"+ + "\\.\\.\\. obtained int = 10\n"+ + "\\.\\.\\. expected int = 20\n\n", + getMyLine()+1) + result := c.Check(10, check.Equals, 20) + checkState(c, result, + &expectedState{ + name: "Check(10, Equals, 20)", + result: false, + failed: true, + log: log, + }) +} + +func (s *FoundationS) TestCallerLoggingInDifferentFile(c *check.C) { + result, line := checkEqualWrapper(c, 10, 20) + testLine := getMyLine() - 1 + log := fmt.Sprintf(""+ + "foundation_test.go:%d:\n"+ + " result, line := checkEqualWrapper\\(c, 10, 20\\)\n"+ + "check_test.go:%d:\n"+ + " return c.Check\\(obtained, check.Equals, expected\\), getMyLine\\(\\)\n"+ + "\\.\\.\\. obtained int = 10\n"+ + "\\.\\.\\. expected int = 20\n\n", + testLine, line) + checkState(c, result, + &expectedState{ + name: "Check(10, Equals, 20)", + result: false, + failed: true, + log: log, + }) +} + +// ----------------------------------------------------------------------- +// ExpectFailure() inverts the logic of failure. + +type ExpectFailureSucceedHelper struct{} + +func (s *ExpectFailureSucceedHelper) TestSucceed(c *check.C) { + c.ExpectFailure("It booms!") + c.Error("Boom!") +} + +type ExpectFailureFailHelper struct{} + +func (s *ExpectFailureFailHelper) TestFail(c *check.C) { + c.ExpectFailure("Bug #XYZ") +} + +func (s *FoundationS) TestExpectFailureFail(c *check.C) { + helper := ExpectFailureFailHelper{} + output := String{} + result := check.Run(&helper, &check.RunConf{Output: &output}) + + expected := "" + + "^\n-+\n" + + "FAIL: foundation_test\\.go:[0-9]+:" + + " ExpectFailureFailHelper\\.TestFail\n\n" + + "\\.\\.\\. Error: Test succeeded, but was expected to fail\n" + + "\\.\\.\\. Reason: Bug #XYZ\n$" + + matched, err := regexp.MatchString(expected, output.value) + if err != nil { + c.Error("Bad expression: ", expected) + } else if !matched { + c.Error("ExpectFailure() didn't log properly:\n", output.value) + } + + c.Assert(result.ExpectedFailures, check.Equals, 0) +} + +func (s *FoundationS) TestExpectFailureSucceed(c *check.C) { + helper := ExpectFailureSucceedHelper{} + output := String{} + result := check.Run(&helper, &check.RunConf{Output: &output}) + + c.Assert(output.value, check.Equals, "") + c.Assert(result.ExpectedFailures, check.Equals, 1) +} + +func (s *FoundationS) TestExpectFailureSucceedVerbose(c *check.C) { + helper := ExpectFailureSucceedHelper{} + output := String{} + result := check.Run(&helper, &check.RunConf{Output: &output, Verbose: true}) + + expected := "" + + "FAIL EXPECTED: foundation_test\\.go:[0-9]+:" + + " ExpectFailureSucceedHelper\\.TestSucceed \\(It booms!\\)\t *[.0-9]+s\n" + + matched, err := regexp.MatchString(expected, output.value) + if err != nil { + c.Error("Bad expression: ", expected) + } else if !matched { + c.Error("ExpectFailure() didn't log properly:\n", output.value) + } + + c.Assert(result.ExpectedFailures, check.Equals, 1) +} + +// ----------------------------------------------------------------------- +// Skip() allows stopping a test without positive/negative results. + +type SkipTestHelper struct{} + +func (s *SkipTestHelper) TestFail(c *check.C) { + c.Skip("Wrong platform or whatever") + c.Error("Boom!") +} + +func (s *FoundationS) TestSkip(c *check.C) { + helper := SkipTestHelper{} + output := String{} + check.Run(&helper, &check.RunConf{Output: &output}) + + if output.value != "" { + c.Error("Skip() logged something:\n", output.value) + } +} + +func (s *FoundationS) TestSkipVerbose(c *check.C) { + helper := SkipTestHelper{} + output := String{} + check.Run(&helper, &check.RunConf{Output: &output, Verbose: true}) + + expected := "SKIP: foundation_test\\.go:[0-9]+: SkipTestHelper\\.TestFail" + + " \\(Wrong platform or whatever\\)" + matched, err := regexp.MatchString(expected, output.value) + if err != nil { + c.Error("Bad expression: ", expected) + } else if !matched { + c.Error("Skip() didn't log properly:\n", output.value) + } +} + +// ----------------------------------------------------------------------- +// Check minimum *log.Logger interface provided by *check.C. + +type minLogger interface { + Output(calldepth int, s string) error +} + +func (s *BootstrapS) TestMinLogger(c *check.C) { + var logger minLogger + logger = log.New(os.Stderr, "", 0) + logger = c + logger.Output(0, "Hello there") + expected := `\[LOG\] [0-9]+:[0-9][0-9]\.[0-9][0-9][0-9] +Hello there\n` + output := c.GetTestLog() + c.Assert(output, check.Matches, expected) +} + +// ----------------------------------------------------------------------- +// Ensure that suites with embedded types are working fine, including the +// the workaround for issue 906. + +type EmbeddedInternalS struct { + called bool +} + +type EmbeddedS struct { + EmbeddedInternalS +} + +var embeddedS = check.Suite(&EmbeddedS{}) + +func (s *EmbeddedS) TestCountSuite(c *check.C) { + suitesRun += 1 +} + +func (s *EmbeddedInternalS) TestMethod(c *check.C) { + c.Error("TestMethod() of the embedded type was called!?") +} + +func (s *EmbeddedS) TestMethod(c *check.C) { + // http://code.google.com/p/go/issues/detail?id=906 + c.Check(s.called, check.Equals, false) // Go issue 906 is affecting the runner? + s.called = true +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/helpers.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/helpers.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/helpers.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/helpers.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,231 @@ +package check + +import ( + "fmt" + "strings" + "time" +) + +// TestName returns the current test name in the form "SuiteName.TestName" +func (c *C) TestName() string { + return c.testName +} + +// ----------------------------------------------------------------------- +// Basic succeeding/failing logic. + +// Failed returns whether the currently running test has already failed. +func (c *C) Failed() bool { + return c.status() == failedSt +} + +// Fail marks the currently running test as failed. +// +// Something ought to have been previously logged so the developer can tell +// what went wrong. The higher level helper functions will fail the test +// and do the logging properly. +func (c *C) Fail() { + c.setStatus(failedSt) +} + +// FailNow marks the currently running test as failed and stops running it. +// Something ought to have been previously logged so the developer can tell +// what went wrong. The higher level helper functions will fail the test +// and do the logging properly. +func (c *C) FailNow() { + c.Fail() + c.stopNow() +} + +// Succeed marks the currently running test as succeeded, undoing any +// previous failures. +func (c *C) Succeed() { + c.setStatus(succeededSt) +} + +// SucceedNow marks the currently running test as succeeded, undoing any +// previous failures, and stops running the test. +func (c *C) SucceedNow() { + c.Succeed() + c.stopNow() +} + +// ExpectFailure informs that the running test is knowingly broken for +// the provided reason. If the test does not fail, an error will be reported +// to raise attention to this fact. This method is useful to temporarily +// disable tests which cover well known problems until a better time to +// fix the problem is found, without forgetting about the fact that a +// failure still exists. +func (c *C) ExpectFailure(reason string) { + if reason == "" { + panic("Missing reason why the test is expected to fail") + } + c.mustFail = true + c.reason = reason +} + +// Skip skips the running test for the provided reason. If run from within +// SetUpTest, the individual test being set up will be skipped, and if run +// from within SetUpSuite, the whole suite is skipped. +func (c *C) Skip(reason string) { + if reason == "" { + panic("Missing reason why the test is being skipped") + } + c.reason = reason + c.setStatus(skippedSt) + c.stopNow() +} + +// ----------------------------------------------------------------------- +// Basic logging. + +// GetTestLog returns the current test error output. +func (c *C) GetTestLog() string { + return c.logb.String() +} + +// Log logs some information into the test error output. +// The provided arguments are assembled together into a string with fmt.Sprint. +func (c *C) Log(args ...interface{}) { + c.log(args...) +} + +// Log logs some information into the test error output. +// The provided arguments are assembled together into a string with fmt.Sprintf. +func (c *C) Logf(format string, args ...interface{}) { + c.logf(format, args...) +} + +// Output enables *C to be used as a logger in functions that require only +// the minimum interface of *log.Logger. +func (c *C) Output(calldepth int, s string) error { + d := time.Now().Sub(c.startTime) + msec := d / time.Millisecond + sec := d / time.Second + min := d / time.Minute + + c.Logf("[LOG] %d:%02d.%03d %s", min, sec%60, msec%1000, s) + return nil +} + +// Error logs an error into the test error output and marks the test as failed. +// The provided arguments are assembled together into a string with fmt.Sprint. +func (c *C) Error(args ...interface{}) { + c.logCaller(1) + c.logString(fmt.Sprint("Error: ", fmt.Sprint(args...))) + c.logNewLine() + c.Fail() +} + +// Errorf logs an error into the test error output and marks the test as failed. +// The provided arguments are assembled together into a string with fmt.Sprintf. +func (c *C) Errorf(format string, args ...interface{}) { + c.logCaller(1) + c.logString(fmt.Sprintf("Error: "+format, args...)) + c.logNewLine() + c.Fail() +} + +// Fatal logs an error into the test error output, marks the test as failed, and +// stops the test execution. The provided arguments are assembled together into +// a string with fmt.Sprint. +func (c *C) Fatal(args ...interface{}) { + c.logCaller(1) + c.logString(fmt.Sprint("Error: ", fmt.Sprint(args...))) + c.logNewLine() + c.FailNow() +} + +// Fatlaf logs an error into the test error output, marks the test as failed, and +// stops the test execution. The provided arguments are assembled together into +// a string with fmt.Sprintf. +func (c *C) Fatalf(format string, args ...interface{}) { + c.logCaller(1) + c.logString(fmt.Sprint("Error: ", fmt.Sprintf(format, args...))) + c.logNewLine() + c.FailNow() +} + +// ----------------------------------------------------------------------- +// Generic checks and assertions based on checkers. + +// Check verifies if the first value matches the expected value according +// to the provided checker. If they do not match, an error is logged, the +// test is marked as failed, and the test execution continues. +// +// Some checkers may not need the expected argument (e.g. IsNil). +// +// Extra arguments provided to the function are logged next to the reported +// problem when the matching fails. +func (c *C) Check(obtained interface{}, checker Checker, args ...interface{}) bool { + return c.internalCheck("Check", obtained, checker, args...) +} + +// Assert ensures that the first value matches the expected value according +// to the provided checker. If they do not match, an error is logged, the +// test is marked as failed, and the test execution stops. +// +// Some checkers may not need the expected argument (e.g. IsNil). +// +// Extra arguments provided to the function are logged next to the reported +// problem when the matching fails. +func (c *C) Assert(obtained interface{}, checker Checker, args ...interface{}) { + if !c.internalCheck("Assert", obtained, checker, args...) { + c.stopNow() + } +} + +func (c *C) internalCheck(funcName string, obtained interface{}, checker Checker, args ...interface{}) bool { + if checker == nil { + c.logCaller(2) + c.logString(fmt.Sprintf("%s(obtained, nil!?, ...):", funcName)) + c.logString("Oops.. you've provided a nil checker!") + c.logNewLine() + c.Fail() + return false + } + + // If the last argument is a bug info, extract it out. + var comment CommentInterface + if len(args) > 0 { + if c, ok := args[len(args)-1].(CommentInterface); ok { + comment = c + args = args[:len(args)-1] + } + } + + params := append([]interface{}{obtained}, args...) + info := checker.Info() + + if len(params) != len(info.Params) { + names := append([]string{info.Params[0], info.Name}, info.Params[1:]...) + c.logCaller(2) + c.logString(fmt.Sprintf("%s(%s):", funcName, strings.Join(names, ", "))) + c.logString(fmt.Sprintf("Wrong number of parameters for %s: want %d, got %d", info.Name, len(names), len(params)+1)) + c.logNewLine() + c.Fail() + return false + } + + // Copy since it may be mutated by Check. + names := append([]string{}, info.Params...) + + // Do the actual check. + result, error := checker.Check(params, names) + if !result || error != "" { + c.logCaller(2) + for i := 0; i != len(params); i++ { + c.logValue(names[i], params[i]) + } + if comment != nil { + c.logString(comment.CheckCommentString()) + } + if error != "" { + c.logString(error) + } + c.logNewLine() + c.Fail() + return false + } + return true +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/helpers_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/helpers_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/helpers_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/helpers_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,519 @@ +// These tests verify the inner workings of the helper methods associated +// with check.T. + +package check_test + +import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1" + "os" + "reflect" + "runtime" + "sync" +) + +var helpersS = check.Suite(&HelpersS{}) + +type HelpersS struct{} + +func (s *HelpersS) TestCountSuite(c *check.C) { + suitesRun += 1 +} + +// ----------------------------------------------------------------------- +// Fake checker and bug info to verify the behavior of Assert() and Check(). + +type MyChecker struct { + info *check.CheckerInfo + params []interface{} + names []string + result bool + error string +} + +func (checker *MyChecker) Info() *check.CheckerInfo { + if checker.info == nil { + return &check.CheckerInfo{Name: "MyChecker", Params: []string{"myobtained", "myexpected"}} + } + return checker.info +} + +func (checker *MyChecker) Check(params []interface{}, names []string) (bool, string) { + rparams := checker.params + rnames := checker.names + checker.params = append([]interface{}{}, params...) + checker.names = append([]string{}, names...) + if rparams != nil { + copy(params, rparams) + } + if rnames != nil { + copy(names, rnames) + } + return checker.result, checker.error +} + +type myCommentType string + +func (c myCommentType) CheckCommentString() string { + return string(c) +} + +func myComment(s string) myCommentType { + return myCommentType(s) +} + +// ----------------------------------------------------------------------- +// Ensure a real checker actually works fine. + +func (s *HelpersS) TestCheckerInterface(c *check.C) { + testHelperSuccess(c, "Check(1, Equals, 1)", true, func() interface{} { + return c.Check(1, check.Equals, 1) + }) +} + +// ----------------------------------------------------------------------- +// Tests for Check(), mostly the same as for Assert() following these. + +func (s *HelpersS) TestCheckSucceedWithExpected(c *check.C) { + checker := &MyChecker{result: true} + testHelperSuccess(c, "Check(1, checker, 2)", true, func() interface{} { + return c.Check(1, checker, 2) + }) + if !reflect.DeepEqual(checker.params, []interface{}{1, 2}) { + c.Fatalf("Bad params for check: %#v", checker.params) + } +} + +func (s *HelpersS) TestCheckSucceedWithoutExpected(c *check.C) { + checker := &MyChecker{result: true, info: &check.CheckerInfo{Params: []string{"myvalue"}}} + testHelperSuccess(c, "Check(1, checker)", true, func() interface{} { + return c.Check(1, checker) + }) + if !reflect.DeepEqual(checker.params, []interface{}{1}) { + c.Fatalf("Bad params for check: %#v", checker.params) + } +} + +func (s *HelpersS) TestCheckFailWithExpected(c *check.C) { + checker := &MyChecker{result: false} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker, 2\\)\n" + + "\\.+ myobtained int = 1\n" + + "\\.+ myexpected int = 2\n\n" + testHelperFailure(c, "Check(1, checker, 2)", false, false, log, + func() interface{} { + return c.Check(1, checker, 2) + }) +} + +func (s *HelpersS) TestCheckFailWithExpectedAndComment(c *check.C) { + checker := &MyChecker{result: false} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker, 2, myComment\\(\"Hello world!\"\\)\\)\n" + + "\\.+ myobtained int = 1\n" + + "\\.+ myexpected int = 2\n" + + "\\.+ Hello world!\n\n" + testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log, + func() interface{} { + return c.Check(1, checker, 2, myComment("Hello world!")) + }) +} + +func (s *HelpersS) TestCheckFailWithExpectedAndStaticComment(c *check.C) { + checker := &MyChecker{result: false} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " // Nice leading comment\\.\n" + + " return c\\.Check\\(1, checker, 2\\) // Hello there\n" + + "\\.+ myobtained int = 1\n" + + "\\.+ myexpected int = 2\n\n" + testHelperFailure(c, "Check(1, checker, 2, msg)", false, false, log, + func() interface{} { + // Nice leading comment. + return c.Check(1, checker, 2) // Hello there + }) +} + +func (s *HelpersS) TestCheckFailWithoutExpected(c *check.C) { + checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker\\)\n" + + "\\.+ myvalue int = 1\n\n" + testHelperFailure(c, "Check(1, checker)", false, false, log, + func() interface{} { + return c.Check(1, checker) + }) +} + +func (s *HelpersS) TestCheckFailWithoutExpectedAndMessage(c *check.C) { + checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker, myComment\\(\"Hello world!\"\\)\\)\n" + + "\\.+ myvalue int = 1\n" + + "\\.+ Hello world!\n\n" + testHelperFailure(c, "Check(1, checker, msg)", false, false, log, + func() interface{} { + return c.Check(1, checker, myComment("Hello world!")) + }) +} + +func (s *HelpersS) TestCheckWithMissingExpected(c *check.C) { + checker := &MyChecker{result: true} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker\\)\n" + + "\\.+ Check\\(myobtained, MyChecker, myexpected\\):\n" + + "\\.+ Wrong number of parameters for MyChecker: " + + "want 3, got 2\n\n" + testHelperFailure(c, "Check(1, checker, !?)", false, false, log, + func() interface{} { + return c.Check(1, checker) + }) +} + +func (s *HelpersS) TestCheckWithTooManyExpected(c *check.C) { + checker := &MyChecker{result: true} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker, 2, 3\\)\n" + + "\\.+ Check\\(myobtained, MyChecker, myexpected\\):\n" + + "\\.+ Wrong number of parameters for MyChecker: " + + "want 3, got 4\n\n" + testHelperFailure(c, "Check(1, checker, 2, 3)", false, false, log, + func() interface{} { + return c.Check(1, checker, 2, 3) + }) +} + +func (s *HelpersS) TestCheckWithError(c *check.C) { + checker := &MyChecker{result: false, error: "Some not so cool data provided!"} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker, 2\\)\n" + + "\\.+ myobtained int = 1\n" + + "\\.+ myexpected int = 2\n" + + "\\.+ Some not so cool data provided!\n\n" + testHelperFailure(c, "Check(1, checker, 2)", false, false, log, + func() interface{} { + return c.Check(1, checker, 2) + }) +} + +func (s *HelpersS) TestCheckWithNilChecker(c *check.C) { + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, nil\\)\n" + + "\\.+ Check\\(obtained, nil!\\?, \\.\\.\\.\\):\n" + + "\\.+ Oops\\.\\. you've provided a nil checker!\n\n" + testHelperFailure(c, "Check(obtained, nil)", false, false, log, + func() interface{} { + return c.Check(1, nil) + }) +} + +func (s *HelpersS) TestCheckWithParamsAndNamesMutation(c *check.C) { + checker := &MyChecker{result: false, params: []interface{}{3, 4}, names: []string{"newobtained", "newexpected"}} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " return c\\.Check\\(1, checker, 2\\)\n" + + "\\.+ newobtained int = 3\n" + + "\\.+ newexpected int = 4\n\n" + testHelperFailure(c, "Check(1, checker, 2) with mutation", false, false, log, + func() interface{} { + return c.Check(1, checker, 2) + }) +} + +// ----------------------------------------------------------------------- +// Tests for Assert(), mostly the same as for Check() above. + +func (s *HelpersS) TestAssertSucceedWithExpected(c *check.C) { + checker := &MyChecker{result: true} + testHelperSuccess(c, "Assert(1, checker, 2)", nil, func() interface{} { + c.Assert(1, checker, 2) + return nil + }) + if !reflect.DeepEqual(checker.params, []interface{}{1, 2}) { + c.Fatalf("Bad params for check: %#v", checker.params) + } +} + +func (s *HelpersS) TestAssertSucceedWithoutExpected(c *check.C) { + checker := &MyChecker{result: true, info: &check.CheckerInfo{Params: []string{"myvalue"}}} + testHelperSuccess(c, "Assert(1, checker)", nil, func() interface{} { + c.Assert(1, checker) + return nil + }) + if !reflect.DeepEqual(checker.params, []interface{}{1}) { + c.Fatalf("Bad params for check: %#v", checker.params) + } +} + +func (s *HelpersS) TestAssertFailWithExpected(c *check.C) { + checker := &MyChecker{result: false} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " c\\.Assert\\(1, checker, 2\\)\n" + + "\\.+ myobtained int = 1\n" + + "\\.+ myexpected int = 2\n\n" + testHelperFailure(c, "Assert(1, checker, 2)", nil, true, log, + func() interface{} { + c.Assert(1, checker, 2) + return nil + }) +} + +func (s *HelpersS) TestAssertFailWithExpectedAndMessage(c *check.C) { + checker := &MyChecker{result: false} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " c\\.Assert\\(1, checker, 2, myComment\\(\"Hello world!\"\\)\\)\n" + + "\\.+ myobtained int = 1\n" + + "\\.+ myexpected int = 2\n" + + "\\.+ Hello world!\n\n" + testHelperFailure(c, "Assert(1, checker, 2, msg)", nil, true, log, + func() interface{} { + c.Assert(1, checker, 2, myComment("Hello world!")) + return nil + }) +} + +func (s *HelpersS) TestAssertFailWithoutExpected(c *check.C) { + checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " c\\.Assert\\(1, checker\\)\n" + + "\\.+ myvalue int = 1\n\n" + testHelperFailure(c, "Assert(1, checker)", nil, true, log, + func() interface{} { + c.Assert(1, checker) + return nil + }) +} + +func (s *HelpersS) TestAssertFailWithoutExpectedAndMessage(c *check.C) { + checker := &MyChecker{result: false, info: &check.CheckerInfo{Params: []string{"myvalue"}}} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " c\\.Assert\\(1, checker, myComment\\(\"Hello world!\"\\)\\)\n" + + "\\.+ myvalue int = 1\n" + + "\\.+ Hello world!\n\n" + testHelperFailure(c, "Assert(1, checker, msg)", nil, true, log, + func() interface{} { + c.Assert(1, checker, myComment("Hello world!")) + return nil + }) +} + +func (s *HelpersS) TestAssertWithMissingExpected(c *check.C) { + checker := &MyChecker{result: true} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " c\\.Assert\\(1, checker\\)\n" + + "\\.+ Assert\\(myobtained, MyChecker, myexpected\\):\n" + + "\\.+ Wrong number of parameters for MyChecker: " + + "want 3, got 2\n\n" + testHelperFailure(c, "Assert(1, checker, !?)", nil, true, log, + func() interface{} { + c.Assert(1, checker) + return nil + }) +} + +func (s *HelpersS) TestAssertWithError(c *check.C) { + checker := &MyChecker{result: false, error: "Some not so cool data provided!"} + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " c\\.Assert\\(1, checker, 2\\)\n" + + "\\.+ myobtained int = 1\n" + + "\\.+ myexpected int = 2\n" + + "\\.+ Some not so cool data provided!\n\n" + testHelperFailure(c, "Assert(1, checker, 2)", nil, true, log, + func() interface{} { + c.Assert(1, checker, 2) + return nil + }) +} + +func (s *HelpersS) TestAssertWithNilChecker(c *check.C) { + log := "(?s)helpers_test\\.go:[0-9]+:.*\nhelpers_test\\.go:[0-9]+:\n" + + " c\\.Assert\\(1, nil\\)\n" + + "\\.+ Assert\\(obtained, nil!\\?, \\.\\.\\.\\):\n" + + "\\.+ Oops\\.\\. you've provided a nil checker!\n\n" + testHelperFailure(c, "Assert(obtained, nil)", nil, true, log, + func() interface{} { + c.Assert(1, nil) + return nil + }) +} + +// ----------------------------------------------------------------------- +// Ensure that values logged work properly in some interesting cases. + +func (s *HelpersS) TestValueLoggingWithArrays(c *check.C) { + checker := &MyChecker{result: false} + log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" + + " return c\\.Check\\(\\[\\]byte{1, 2}, checker, \\[\\]byte{1, 3}\\)\n" + + "\\.+ myobtained \\[\\]uint8 = \\[\\]byte{0x1, 0x2}\n" + + "\\.+ myexpected \\[\\]uint8 = \\[\\]byte{0x1, 0x3}\n\n" + testHelperFailure(c, "Check([]byte{1}, chk, []byte{3})", false, false, log, + func() interface{} { + return c.Check([]byte{1, 2}, checker, []byte{1, 3}) + }) +} + +func (s *HelpersS) TestValueLoggingWithMultiLine(c *check.C) { + checker := &MyChecker{result: false} + log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" + + " return c\\.Check\\(\"a\\\\nb\\\\n\", checker, \"a\\\\nb\\\\nc\"\\)\n" + + "\\.+ myobtained string = \"\" \\+\n" + + "\\.+ \"a\\\\n\" \\+\n" + + "\\.+ \"b\\\\n\"\n" + + "\\.+ myexpected string = \"\" \\+\n" + + "\\.+ \"a\\\\n\" \\+\n" + + "\\.+ \"b\\\\n\" \\+\n" + + "\\.+ \"c\"\n\n" + testHelperFailure(c, `Check("a\nb\n", chk, "a\nb\nc")`, false, false, log, + func() interface{} { + return c.Check("a\nb\n", checker, "a\nb\nc") + }) +} + +func (s *HelpersS) TestValueLoggingWithMultiLineException(c *check.C) { + // If the newline is at the end of the string, don't log as multi-line. + checker := &MyChecker{result: false} + log := "(?s)helpers_test.go:[0-9]+:.*\nhelpers_test.go:[0-9]+:\n" + + " return c\\.Check\\(\"a b\\\\n\", checker, \"a\\\\nb\"\\)\n" + + "\\.+ myobtained string = \"a b\\\\n\"\n" + + "\\.+ myexpected string = \"\" \\+\n" + + "\\.+ \"a\\\\n\" \\+\n" + + "\\.+ \"b\"\n\n" + testHelperFailure(c, `Check("a b\n", chk, "a\nb")`, false, false, log, + func() interface{} { + return c.Check("a b\n", checker, "a\nb") + }) +} + +// ----------------------------------------------------------------------- +// MakeDir() tests. + +type MkDirHelper struct { + path1 string + path2 string + isDir1 bool + isDir2 bool + isDir3 bool + isDir4 bool +} + +func (s *MkDirHelper) SetUpSuite(c *check.C) { + s.path1 = c.MkDir() + s.isDir1 = isDir(s.path1) +} + +func (s *MkDirHelper) Test(c *check.C) { + s.path2 = c.MkDir() + s.isDir2 = isDir(s.path2) +} + +func (s *MkDirHelper) TearDownSuite(c *check.C) { + s.isDir3 = isDir(s.path1) + s.isDir4 = isDir(s.path2) +} + +func (s *HelpersS) TestMkDir(c *check.C) { + helper := MkDirHelper{} + output := String{} + check.Run(&helper, &check.RunConf{Output: &output}) + c.Assert(output.value, check.Equals, "") + c.Check(helper.isDir1, check.Equals, true) + c.Check(helper.isDir2, check.Equals, true) + c.Check(helper.isDir3, check.Equals, true) + c.Check(helper.isDir4, check.Equals, true) + c.Check(helper.path1, check.Not(check.Equals), + helper.path2) + c.Check(isDir(helper.path1), check.Equals, false) + c.Check(isDir(helper.path2), check.Equals, false) +} + +func isDir(path string) bool { + if stat, err := os.Stat(path); err == nil { + return stat.IsDir() + } + return false +} + +// Concurrent logging should not corrupt the underling buffer. +// Use go test -race to detect the race in this test. +func (s *HelpersS) TestConcurrentLogging(c *check.C) { + defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(runtime.NumCPU())) + var start, stop sync.WaitGroup + start.Add(1) + for i, n := 0, runtime.NumCPU()*2; i < n; i++ { + stop.Add(1) + go func(i int) { + start.Wait() + for j := 0; j < 30; j++ { + c.Logf("Worker %d: line %d", i, j) + } + stop.Done() + }(i) + } + start.Done() + stop.Wait() +} + +// ----------------------------------------------------------------------- +// Test the TestName function + +type TestNameHelper struct { + name1 string + name2 string + name3 string + name4 string + name5 string +} + +func (s *TestNameHelper) SetUpSuite(c *check.C) { s.name1 = c.TestName() } +func (s *TestNameHelper) SetUpTest(c *check.C) { s.name2 = c.TestName() } +func (s *TestNameHelper) Test(c *check.C) { s.name3 = c.TestName() } +func (s *TestNameHelper) TearDownTest(c *check.C) { s.name4 = c.TestName() } +func (s *TestNameHelper) TearDownSuite(c *check.C) { s.name5 = c.TestName() } + +func (s *HelpersS) TestTestName(c *check.C) { + helper := TestNameHelper{} + output := String{} + check.Run(&helper, &check.RunConf{Output: &output}) + c.Check(helper.name1, check.Equals, "") + c.Check(helper.name2, check.Equals, "TestNameHelper.Test") + c.Check(helper.name3, check.Equals, "TestNameHelper.Test") + c.Check(helper.name4, check.Equals, "TestNameHelper.Test") + c.Check(helper.name5, check.Equals, "") +} + +// ----------------------------------------------------------------------- +// A couple of helper functions to test helper functions. :-) + +func testHelperSuccess(c *check.C, name string, expectedResult interface{}, closure func() interface{}) { + var result interface{} + defer (func() { + if err := recover(); err != nil { + panic(err) + } + checkState(c, result, + &expectedState{ + name: name, + result: expectedResult, + failed: false, + log: "", + }) + })() + result = closure() +} + +func testHelperFailure(c *check.C, name string, expectedResult interface{}, shouldStop bool, log string, closure func() interface{}) { + var result interface{} + defer (func() { + if err := recover(); err != nil { + panic(err) + } + checkState(c, result, + &expectedState{ + name: name, + result: expectedResult, + failed: true, + log: log, + }) + })() + result = closure() + if shouldStop { + c.Logf("%s didn't stop when it should", name) + } +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/LICENSE juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/LICENSE --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/LICENSE 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,25 @@ +Gocheck - A rich testing framework for Go + +Copyright (c) 2010-2013 Gustavo Niemeyer + +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 -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/printer.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/printer.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/printer.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/printer.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,168 @@ +package check + +import ( + "bytes" + "go/ast" + "go/parser" + "go/printer" + "go/token" + "os" +) + +func indent(s, with string) (r string) { + eol := true + for i := 0; i != len(s); i++ { + c := s[i] + switch { + case eol && c == '\n' || c == '\r': + case c == '\n' || c == '\r': + eol = true + case eol: + eol = false + s = s[:i] + with + s[i:] + i += len(with) + } + } + return s +} + +func printLine(filename string, line int) (string, error) { + fset := token.NewFileSet() + file, err := os.Open(filename) + if err != nil { + return "", err + } + fnode, err := parser.ParseFile(fset, filename, file, parser.ParseComments) + if err != nil { + return "", err + } + config := &printer.Config{Mode: printer.UseSpaces, Tabwidth: 4} + lp := &linePrinter{fset: fset, fnode: fnode, line: line, config: config} + ast.Walk(lp, fnode) + result := lp.output.Bytes() + // Comments leave \n at the end. + n := len(result) + for n > 0 && result[n-1] == '\n' { + n-- + } + return string(result[:n]), nil +} + +type linePrinter struct { + config *printer.Config + fset *token.FileSet + fnode *ast.File + line int + output bytes.Buffer + stmt ast.Stmt +} + +func (lp *linePrinter) emit() bool { + if lp.stmt != nil { + lp.trim(lp.stmt) + lp.printWithComments(lp.stmt) + lp.stmt = nil + return true + } + return false +} + +func (lp *linePrinter) printWithComments(n ast.Node) { + nfirst := lp.fset.Position(n.Pos()).Line + nlast := lp.fset.Position(n.End()).Line + for _, g := range lp.fnode.Comments { + cfirst := lp.fset.Position(g.Pos()).Line + clast := lp.fset.Position(g.End()).Line + if clast == nfirst-1 && lp.fset.Position(n.Pos()).Column == lp.fset.Position(g.Pos()).Column { + for _, c := range g.List { + lp.output.WriteString(c.Text) + lp.output.WriteByte('\n') + } + } + if cfirst >= nfirst && cfirst <= nlast && n.End() <= g.List[0].Slash { + // The printer will not include the comment if it starts past + // the node itself. Trick it into printing by overlapping the + // slash with the end of the statement. + g.List[0].Slash = n.End() - 1 + } + } + node := &printer.CommentedNode{n, lp.fnode.Comments} + lp.config.Fprint(&lp.output, lp.fset, node) +} + +func (lp *linePrinter) Visit(n ast.Node) (w ast.Visitor) { + if n == nil { + if lp.output.Len() == 0 { + lp.emit() + } + return nil + } + first := lp.fset.Position(n.Pos()).Line + last := lp.fset.Position(n.End()).Line + if first <= lp.line && last >= lp.line { + // Print the innermost statement containing the line. + if stmt, ok := n.(ast.Stmt); ok { + if _, ok := n.(*ast.BlockStmt); !ok { + lp.stmt = stmt + } + } + if first == lp.line && lp.emit() { + return nil + } + return lp + } + return nil +} + +func (lp *linePrinter) trim(n ast.Node) bool { + stmt, ok := n.(ast.Stmt) + if !ok { + return true + } + line := lp.fset.Position(n.Pos()).Line + if line != lp.line { + return false + } + switch stmt := stmt.(type) { + case *ast.IfStmt: + stmt.Body = lp.trimBlock(stmt.Body) + case *ast.SwitchStmt: + stmt.Body = lp.trimBlock(stmt.Body) + case *ast.TypeSwitchStmt: + stmt.Body = lp.trimBlock(stmt.Body) + case *ast.CaseClause: + stmt.Body = lp.trimList(stmt.Body) + case *ast.CommClause: + stmt.Body = lp.trimList(stmt.Body) + case *ast.BlockStmt: + stmt.List = lp.trimList(stmt.List) + } + return true +} + +func (lp *linePrinter) trimBlock(stmt *ast.BlockStmt) *ast.BlockStmt { + if !lp.trim(stmt) { + return lp.emptyBlock(stmt) + } + stmt.Rbrace = stmt.Lbrace + return stmt +} + +func (lp *linePrinter) trimList(stmts []ast.Stmt) []ast.Stmt { + for i := 0; i != len(stmts); i++ { + if !lp.trim(stmts[i]) { + stmts[i] = lp.emptyStmt(stmts[i]) + break + } + } + return stmts +} + +func (lp *linePrinter) emptyStmt(n ast.Node) *ast.ExprStmt { + return &ast.ExprStmt{&ast.Ellipsis{n.Pos(), nil}} +} + +func (lp *linePrinter) emptyBlock(n ast.Node) *ast.BlockStmt { + p := n.Pos() + return &ast.BlockStmt{p, []ast.Stmt{lp.emptyStmt(n)}, p} +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/printer_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,109 @@ +package check_test + +import ( + . "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1" +) + +var _ = Suite(&PrinterS{}) + +type PrinterS struct{} + +func (s *PrinterS) TestCountSuite(c *C) { + suitesRun += 1 +} + +var printTestFuncLine int + +func init() { + printTestFuncLine = getMyLine() + 3 +} + +func printTestFunc() { + println(1) // Comment1 + if 2 == 2 { // Comment2 + println(3) // Comment3 + } + switch 5 { + case 6: + println(6) // Comment6 + println(7) + } + switch interface{}(9).(type) { // Comment9 + case int: + println(10) + println(11) + } + select { + case <-(chan bool)(nil): + println(14) + println(15) + default: + println(16) + println(17) + } + println(19, + 20) + _ = func() { + println(21) + println(22) + } + println(24, func() { + println(25) + }) + // Leading comment + // with multiple lines. + println(29) // Comment29 +} + +var printLineTests = []struct { + line int + output string +}{ + {1, "println(1) // Comment1"}, + {2, "if 2 == 2 { // Comment2\n ...\n}"}, + {3, "println(3) // Comment3"}, + {5, "switch 5 {\n...\n}"}, + {6, "case 6:\n println(6) // Comment6\n ..."}, + {7, "println(7)"}, + {9, "switch interface{}(9).(type) { // Comment9\n...\n}"}, + {10, "case int:\n println(10)\n ..."}, + {14, "case <-(chan bool)(nil):\n println(14)\n ..."}, + {15, "println(15)"}, + {16, "default:\n println(16)\n ..."}, + {17, "println(17)"}, + {19, "println(19,\n 20)"}, + {20, "println(19,\n 20)"}, + {21, "_ = func() {\n println(21)\n println(22)\n}"}, + {22, "println(22)"}, + {24, "println(24, func() {\n println(25)\n})"}, + {25, "println(25)"}, + {26, "println(24, func() {\n println(25)\n})"}, + {29, "// Leading comment\n// with multiple lines.\nprintln(29) // Comment29"}, +} + +func (s *PrinterS) TestPrintLine(c *C) { + for _, test := range printLineTests { + output, err := PrintLine("printer_test.go", printTestFuncLine+test.line) + c.Assert(err, IsNil) + c.Assert(output, Equals, test.output) + } +} + +var indentTests = []struct { + in, out string +}{ + {"", ""}, + {"\n", "\n"}, + {"a", ">>>a"}, + {"a\n", ">>>a\n"}, + {"a\nb", ">>>a\n>>>b"}, + {" ", ">>> "}, +} + +func (s *PrinterS) TestIndent(c *C) { + for _, test := range indentTests { + out := Indent(test.in, ">>>") + c.Assert(out, Equals, test.out) + } + +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/README.md juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/README.md --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/README.md 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/README.md 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,20 @@ +Instructions +============ + +Install the package with: + + go get gopkg.in/check.v1 + +Import it with: + + import "gopkg.in/check.v1" + +and use _check_ as the package name inside the code. + +For more details, visit the project page: + +* http://labix.org/gocheck + +and the API documentation: + +* https://gopkg.in/check.v1 diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/run.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/run.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/run.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/run.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,175 @@ +package check + +import ( + "bufio" + "flag" + "fmt" + "os" + "testing" + "time" +) + +// ----------------------------------------------------------------------- +// Test suite registry. + +var allSuites []interface{} + +// Suite registers the given value as a test suite to be run. Any methods +// starting with the Test prefix in the given value will be considered as +// a test method. +func Suite(suite interface{}) interface{} { + allSuites = append(allSuites, suite) + return suite +} + +// ----------------------------------------------------------------------- +// Public running interface. + +var ( + oldFilterFlag = flag.String("gocheck.f", "", "Regular expression selecting which tests and/or suites to run") + oldVerboseFlag = flag.Bool("gocheck.v", false, "Verbose mode") + oldStreamFlag = flag.Bool("gocheck.vv", false, "Super verbose mode (disables output caching)") + oldBenchFlag = flag.Bool("gocheck.b", false, "Run benchmarks") + oldBenchTime = flag.Duration("gocheck.btime", 1*time.Second, "approximate run time for each benchmark") + oldListFlag = flag.Bool("gocheck.list", false, "List the names of all tests that will be run") + oldWorkFlag = flag.Bool("gocheck.work", false, "Display and do not remove the test working directory") + + newFilterFlag = flag.String("check.f", "", "Regular expression selecting which tests and/or suites to run") + newVerboseFlag = flag.Bool("check.v", false, "Verbose mode") + newStreamFlag = flag.Bool("check.vv", false, "Super verbose mode (disables output caching)") + newBenchFlag = flag.Bool("check.b", false, "Run benchmarks") + newBenchTime = flag.Duration("check.btime", 1*time.Second, "approximate run time for each benchmark") + newBenchMem = flag.Bool("check.bmem", false, "Report memory benchmarks") + newListFlag = flag.Bool("check.list", false, "List the names of all tests that will be run") + newWorkFlag = flag.Bool("check.work", false, "Display and do not remove the test working directory") +) + +// TestingT runs all test suites registered with the Suite function, +// printing results to stdout, and reporting any failures back to +// the "testing" package. +func TestingT(testingT *testing.T) { + benchTime := *newBenchTime + if benchTime == 1*time.Second { + benchTime = *oldBenchTime + } + conf := &RunConf{ + Filter: *oldFilterFlag + *newFilterFlag, + Verbose: *oldVerboseFlag || *newVerboseFlag, + Stream: *oldStreamFlag || *newStreamFlag, + Benchmark: *oldBenchFlag || *newBenchFlag, + BenchmarkTime: benchTime, + BenchmarkMem: *newBenchMem, + KeepWorkDir: *oldWorkFlag || *newWorkFlag, + } + if *oldListFlag || *newListFlag { + w := bufio.NewWriter(os.Stdout) + for _, name := range ListAll(conf) { + fmt.Fprintln(w, name) + } + w.Flush() + return + } + result := RunAll(conf) + println(result.String()) + if !result.Passed() { + testingT.Fail() + } +} + +// RunAll runs all test suites registered with the Suite function, using the +// provided run configuration. +func RunAll(runConf *RunConf) *Result { + result := Result{} + for _, suite := range allSuites { + result.Add(Run(suite, runConf)) + } + return &result +} + +// Run runs the provided test suite using the provided run configuration. +func Run(suite interface{}, runConf *RunConf) *Result { + runner := newSuiteRunner(suite, runConf) + return runner.run() +} + +// ListAll returns the names of all the test functions registered with the +// Suite function that will be run with the provided run configuration. +func ListAll(runConf *RunConf) []string { + var names []string + for _, suite := range allSuites { + names = append(names, List(suite, runConf)...) + } + return names +} + +// List returns the names of the test functions in the given +// suite that will be run with the provided run configuration. +func List(suite interface{}, runConf *RunConf) []string { + var names []string + runner := newSuiteRunner(suite, runConf) + for _, t := range runner.tests { + names = append(names, t.String()) + } + return names +} + +// ----------------------------------------------------------------------- +// Result methods. + +func (r *Result) Add(other *Result) { + r.Succeeded += other.Succeeded + r.Skipped += other.Skipped + r.Failed += other.Failed + r.Panicked += other.Panicked + r.FixturePanicked += other.FixturePanicked + r.ExpectedFailures += other.ExpectedFailures + r.Missed += other.Missed + if r.WorkDir != "" && other.WorkDir != "" { + r.WorkDir += ":" + other.WorkDir + } else if other.WorkDir != "" { + r.WorkDir = other.WorkDir + } +} + +func (r *Result) Passed() bool { + return (r.Failed == 0 && r.Panicked == 0 && + r.FixturePanicked == 0 && r.Missed == 0 && + r.RunError == nil) +} + +func (r *Result) String() string { + if r.RunError != nil { + return "ERROR: " + r.RunError.Error() + } + + var value string + if r.Failed == 0 && r.Panicked == 0 && r.FixturePanicked == 0 && + r.Missed == 0 { + value = "OK: " + } else { + value = "OOPS: " + } + value += fmt.Sprintf("%d passed", r.Succeeded) + if r.Skipped != 0 { + value += fmt.Sprintf(", %d skipped", r.Skipped) + } + if r.ExpectedFailures != 0 { + value += fmt.Sprintf(", %d expected failures", r.ExpectedFailures) + } + if r.Failed != 0 { + value += fmt.Sprintf(", %d FAILED", r.Failed) + } + if r.Panicked != 0 { + value += fmt.Sprintf(", %d PANICKED", r.Panicked) + } + if r.FixturePanicked != 0 { + value += fmt.Sprintf(", %d FIXTURE-PANICKED", r.FixturePanicked) + } + if r.Missed != 0 { + value += fmt.Sprintf(", %d MISSED", r.Missed) + } + if r.WorkDir != "" { + value += "\nWORK=" + r.WorkDir + } + return value +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/run_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/run_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/run_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/run_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,419 @@ +// These tests verify the test running logic. + +package check_test + +import ( + "errors" + . "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1" + "os" + "sync" +) + +var runnerS = Suite(&RunS{}) + +type RunS struct{} + +func (s *RunS) TestCountSuite(c *C) { + suitesRun += 1 +} + +// ----------------------------------------------------------------------- +// Tests ensuring result counting works properly. + +func (s *RunS) TestSuccess(c *C) { + output := String{} + result := Run(&SuccessHelper{}, &RunConf{Output: &output}) + c.Check(result.Succeeded, Equals, 1) + c.Check(result.Failed, Equals, 0) + c.Check(result.Skipped, Equals, 0) + c.Check(result.Panicked, Equals, 0) + c.Check(result.FixturePanicked, Equals, 0) + c.Check(result.Missed, Equals, 0) + c.Check(result.RunError, IsNil) +} + +func (s *RunS) TestFailure(c *C) { + output := String{} + result := Run(&FailHelper{}, &RunConf{Output: &output}) + c.Check(result.Succeeded, Equals, 0) + c.Check(result.Failed, Equals, 1) + c.Check(result.Skipped, Equals, 0) + c.Check(result.Panicked, Equals, 0) + c.Check(result.FixturePanicked, Equals, 0) + c.Check(result.Missed, Equals, 0) + c.Check(result.RunError, IsNil) +} + +func (s *RunS) TestFixture(c *C) { + output := String{} + result := Run(&FixtureHelper{}, &RunConf{Output: &output}) + c.Check(result.Succeeded, Equals, 2) + c.Check(result.Failed, Equals, 0) + c.Check(result.Skipped, Equals, 0) + c.Check(result.Panicked, Equals, 0) + c.Check(result.FixturePanicked, Equals, 0) + c.Check(result.Missed, Equals, 0) + c.Check(result.RunError, IsNil) +} + +func (s *RunS) TestPanicOnTest(c *C) { + output := String{} + helper := &FixtureHelper{panicOn: "Test1"} + result := Run(helper, &RunConf{Output: &output}) + c.Check(result.Succeeded, Equals, 1) + c.Check(result.Failed, Equals, 0) + c.Check(result.Skipped, Equals, 0) + c.Check(result.Panicked, Equals, 1) + c.Check(result.FixturePanicked, Equals, 0) + c.Check(result.Missed, Equals, 0) + c.Check(result.RunError, IsNil) +} + +func (s *RunS) TestPanicOnSetUpTest(c *C) { + output := String{} + helper := &FixtureHelper{panicOn: "SetUpTest"} + result := Run(helper, &RunConf{Output: &output}) + c.Check(result.Succeeded, Equals, 0) + c.Check(result.Failed, Equals, 0) + c.Check(result.Skipped, Equals, 0) + c.Check(result.Panicked, Equals, 0) + c.Check(result.FixturePanicked, Equals, 1) + c.Check(result.Missed, Equals, 2) + c.Check(result.RunError, IsNil) +} + +func (s *RunS) TestPanicOnSetUpSuite(c *C) { + output := String{} + helper := &FixtureHelper{panicOn: "SetUpSuite"} + result := Run(helper, &RunConf{Output: &output}) + c.Check(result.Succeeded, Equals, 0) + c.Check(result.Failed, Equals, 0) + c.Check(result.Skipped, Equals, 0) + c.Check(result.Panicked, Equals, 0) + c.Check(result.FixturePanicked, Equals, 1) + c.Check(result.Missed, Equals, 2) + c.Check(result.RunError, IsNil) +} + +// ----------------------------------------------------------------------- +// Check result aggregation. + +func (s *RunS) TestAdd(c *C) { + result := &Result{ + Succeeded: 1, + Skipped: 2, + Failed: 3, + Panicked: 4, + FixturePanicked: 5, + Missed: 6, + ExpectedFailures: 7, + } + result.Add(&Result{ + Succeeded: 10, + Skipped: 20, + Failed: 30, + Panicked: 40, + FixturePanicked: 50, + Missed: 60, + ExpectedFailures: 70, + }) + c.Check(result.Succeeded, Equals, 11) + c.Check(result.Skipped, Equals, 22) + c.Check(result.Failed, Equals, 33) + c.Check(result.Panicked, Equals, 44) + c.Check(result.FixturePanicked, Equals, 55) + c.Check(result.Missed, Equals, 66) + c.Check(result.ExpectedFailures, Equals, 77) + c.Check(result.RunError, IsNil) +} + +// ----------------------------------------------------------------------- +// Check the Passed() method. + +func (s *RunS) TestPassed(c *C) { + c.Assert((&Result{}).Passed(), Equals, true) + c.Assert((&Result{Succeeded: 1}).Passed(), Equals, true) + c.Assert((&Result{Skipped: 1}).Passed(), Equals, true) + c.Assert((&Result{Failed: 1}).Passed(), Equals, false) + c.Assert((&Result{Panicked: 1}).Passed(), Equals, false) + c.Assert((&Result{FixturePanicked: 1}).Passed(), Equals, false) + c.Assert((&Result{Missed: 1}).Passed(), Equals, false) + c.Assert((&Result{RunError: errors.New("!")}).Passed(), Equals, false) +} + +// ----------------------------------------------------------------------- +// Check that result printing is working correctly. + +func (s *RunS) TestPrintSuccess(c *C) { + result := &Result{Succeeded: 5} + c.Check(result.String(), Equals, "OK: 5 passed") +} + +func (s *RunS) TestPrintFailure(c *C) { + result := &Result{Failed: 5} + c.Check(result.String(), Equals, "OOPS: 0 passed, 5 FAILED") +} + +func (s *RunS) TestPrintSkipped(c *C) { + result := &Result{Skipped: 5} + c.Check(result.String(), Equals, "OK: 0 passed, 5 skipped") +} + +func (s *RunS) TestPrintExpectedFailures(c *C) { + result := &Result{ExpectedFailures: 5} + c.Check(result.String(), Equals, "OK: 0 passed, 5 expected failures") +} + +func (s *RunS) TestPrintPanicked(c *C) { + result := &Result{Panicked: 5} + c.Check(result.String(), Equals, "OOPS: 0 passed, 5 PANICKED") +} + +func (s *RunS) TestPrintFixturePanicked(c *C) { + result := &Result{FixturePanicked: 5} + c.Check(result.String(), Equals, "OOPS: 0 passed, 5 FIXTURE-PANICKED") +} + +func (s *RunS) TestPrintMissed(c *C) { + result := &Result{Missed: 5} + c.Check(result.String(), Equals, "OOPS: 0 passed, 5 MISSED") +} + +func (s *RunS) TestPrintAll(c *C) { + result := &Result{Succeeded: 1, Skipped: 2, ExpectedFailures: 3, + Panicked: 4, FixturePanicked: 5, Missed: 6} + c.Check(result.String(), Equals, + "OOPS: 1 passed, 2 skipped, 3 expected failures, 4 PANICKED, "+ + "5 FIXTURE-PANICKED, 6 MISSED") +} + +func (s *RunS) TestPrintRunError(c *C) { + result := &Result{Succeeded: 1, Failed: 1, + RunError: errors.New("Kaboom!")} + c.Check(result.String(), Equals, "ERROR: Kaboom!") +} + +// ----------------------------------------------------------------------- +// Verify that the method pattern flag works correctly. + +func (s *RunS) TestFilterTestName(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Filter: "Test[91]"} + Run(&helper, &runConf) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 5) +} + +func (s *RunS) TestFilterTestNameWithAll(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Filter: ".*"} + Run(&helper, &runConf) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "SetUpTest") + c.Check(helper.calls[5], Equals, "Test2") + c.Check(helper.calls[6], Equals, "TearDownTest") + c.Check(helper.calls[7], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 8) +} + +func (s *RunS) TestFilterSuiteName(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Filter: "FixtureHelper"} + Run(&helper, &runConf) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test1") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "SetUpTest") + c.Check(helper.calls[5], Equals, "Test2") + c.Check(helper.calls[6], Equals, "TearDownTest") + c.Check(helper.calls[7], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 8) +} + +func (s *RunS) TestFilterSuiteNameAndTestName(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Filter: "FixtureHelper\\.Test2"} + Run(&helper, &runConf) + c.Check(helper.calls[0], Equals, "SetUpSuite") + c.Check(helper.calls[1], Equals, "SetUpTest") + c.Check(helper.calls[2], Equals, "Test2") + c.Check(helper.calls[3], Equals, "TearDownTest") + c.Check(helper.calls[4], Equals, "TearDownSuite") + c.Check(len(helper.calls), Equals, 5) +} + +func (s *RunS) TestFilterAllOut(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Filter: "NotFound"} + Run(&helper, &runConf) + c.Check(len(helper.calls), Equals, 0) +} + +func (s *RunS) TestRequirePartialMatch(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Filter: "est"} + Run(&helper, &runConf) + c.Check(len(helper.calls), Equals, 8) +} + +func (s *RunS) TestFilterError(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Filter: "]["} + result := Run(&helper, &runConf) + c.Check(result.String(), Equals, + "ERROR: Bad filter expression: error parsing regexp: missing closing ]: `[`") + c.Check(len(helper.calls), Equals, 0) +} + +// ----------------------------------------------------------------------- +// Verify that List works correctly. + +func (s *RunS) TestListFiltered(c *C) { + names := List(&FixtureHelper{}, &RunConf{Filter: "1"}) + c.Assert(names, DeepEquals, []string{ + "FixtureHelper.Test1", + }) +} + +func (s *RunS) TestList(c *C) { + names := List(&FixtureHelper{}, &RunConf{}) + c.Assert(names, DeepEquals, []string{ + "FixtureHelper.Test1", + "FixtureHelper.Test2", + }) +} + +// ----------------------------------------------------------------------- +// Verify that verbose mode prints tests which pass as well. + +func (s *RunS) TestVerboseMode(c *C) { + helper := FixtureHelper{} + output := String{} + runConf := RunConf{Output: &output, Verbose: true} + Run(&helper, &runConf) + + expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test1\t *[.0-9]+s\n" + + "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t *[.0-9]+s\n" + + c.Assert(output.value, Matches, expected) +} + +func (s *RunS) TestVerboseModeWithFailBeforePass(c *C) { + helper := FixtureHelper{panicOn: "Test1"} + output := String{} + runConf := RunConf{Output: &output, Verbose: true} + Run(&helper, &runConf) + + expected := "(?s).*PANIC.*\n-+\n" + // Should have an extra line. + "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t *[.0-9]+s\n" + + c.Assert(output.value, Matches, expected) +} + +// ----------------------------------------------------------------------- +// Verify the stream output mode. In this mode there's no output caching. + +type StreamHelper struct { + l2 sync.Mutex + l3 sync.Mutex +} + +func (s *StreamHelper) SetUpSuite(c *C) { + c.Log("0") +} + +func (s *StreamHelper) Test1(c *C) { + c.Log("1") + s.l2.Lock() + s.l3.Lock() + go func() { + s.l2.Lock() // Wait for "2". + c.Log("3") + s.l3.Unlock() + }() +} + +func (s *StreamHelper) Test2(c *C) { + c.Log("2") + s.l2.Unlock() + s.l3.Lock() // Wait for "3". + c.Fail() + c.Log("4") +} + +func (s *RunS) TestStreamMode(c *C) { + helper := &StreamHelper{} + output := String{} + runConf := RunConf{Output: &output, Stream: true} + Run(helper, &runConf) + + expected := "START: run_test\\.go:[0-9]+: StreamHelper\\.SetUpSuite\n0\n" + + "PASS: run_test\\.go:[0-9]+: StreamHelper\\.SetUpSuite\t *[.0-9]+s\n\n" + + "START: run_test\\.go:[0-9]+: StreamHelper\\.Test1\n1\n" + + "PASS: run_test\\.go:[0-9]+: StreamHelper\\.Test1\t *[.0-9]+s\n\n" + + "START: run_test\\.go:[0-9]+: StreamHelper\\.Test2\n2\n3\n4\n" + + "FAIL: run_test\\.go:[0-9]+: StreamHelper\\.Test2\n\n" + + c.Assert(output.value, Matches, expected) +} + +type StreamMissHelper struct{} + +func (s *StreamMissHelper) SetUpSuite(c *C) { + c.Log("0") + c.Fail() +} + +func (s *StreamMissHelper) Test1(c *C) { + c.Log("1") +} + +func (s *RunS) TestStreamModeWithMiss(c *C) { + helper := &StreamMissHelper{} + output := String{} + runConf := RunConf{Output: &output, Stream: true} + Run(helper, &runConf) + + expected := "START: run_test\\.go:[0-9]+: StreamMissHelper\\.SetUpSuite\n0\n" + + "FAIL: run_test\\.go:[0-9]+: StreamMissHelper\\.SetUpSuite\n\n" + + "START: run_test\\.go:[0-9]+: StreamMissHelper\\.Test1\n" + + "MISS: run_test\\.go:[0-9]+: StreamMissHelper\\.Test1\n\n" + + c.Assert(output.value, Matches, expected) +} + +// ----------------------------------------------------------------------- +// Verify that that the keep work dir request indeed does so. + +type WorkDirSuite struct{} + +func (s *WorkDirSuite) Test(c *C) { + c.MkDir() +} + +func (s *RunS) TestKeepWorkDir(c *C) { + output := String{} + runConf := RunConf{Output: &output, Verbose: true, KeepWorkDir: true} + result := Run(&WorkDirSuite{}, &runConf) + + c.Assert(result.String(), Matches, ".*\nWORK="+result.WorkDir) + + stat, err := os.Stat(result.WorkDir) + c.Assert(err, IsNil) + c.Assert(stat.IsDir(), Equals, true) +} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/TODO juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/TODO --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/TODO 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1/TODO 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,2 @@ +- Assert(slice, Contains, item) +- Parallel test support diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/management/virtualmachine/client.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/management/virtualmachine/client.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/management/virtualmachine/client.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/management/virtualmachine/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -9,12 +9,14 @@ ) const ( - azureDeploymentListURL = "services/hostedservices/%s/deployments" - 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" - azureRoleSizeListURL = "rolesizes" + azureDeploymentListURL = "services/hostedservices/%s/deployments" + azureDeploymentURL = "services/hostedservices/%s/deployments/%s" + azureListDeploymentsInSlotURL = "services/hostedservices/%s/deploymentslots/Production" + deleteAzureDeploymentURL = "services/hostedservices/%s/deployments/%s?comp=media" + azureAddRoleURL = "services/hostedservices/%s/deployments/%s/roles" + azureRoleURL = "services/hostedservices/%s/deployments/%s/roles/%s" + azureOperationsURL = "services/hostedservices/%s/deployments/%s/roleinstances/%s/Operations" + azureRoleSizeListURL = "rolesizes" errParamNotSpecified = "Parameter %s is not specified." ) @@ -61,6 +63,32 @@ return vm.client.SendAzurePostRequest(requestURL, data) } +// GetDeploymentName queries an existing Azure cloud service for the name of the Deployment, +// if any, in its 'Production' slot (the only slot possible). If none exists, it returns empty +// string but no error +// +//https://msdn.microsoft.com/en-us/library/azure/ee460804.aspx +func (vm VirtualMachineClient) GetDeploymentName(cloudServiceName string) (string, error) { + var deployment DeploymentResponse + if cloudServiceName == "" { + return "", fmt.Errorf(errParamNotSpecified, "cloudServiceName") + } + requestURL := fmt.Sprintf(azureListDeploymentsInSlotURL, cloudServiceName) + response, err := vm.client.SendAzureGetRequest(requestURL) + if err != nil { + if management.IsResourceNotFoundError(err) { + return "", nil + } + return "", err + } + err = xml.Unmarshal(response, &deployment) + if err != nil { + return "", err + } + + return deployment.Name, nil +} + func (vm VirtualMachineClient) GetDeployment(cloudServiceName, deploymentName string) (DeploymentResponse, error) { var deployment DeploymentResponse if cloudServiceName == "" { @@ -118,6 +146,25 @@ return role, nil } +// AddRole adds a Virtual Machine to a deployment of Virtual Machines, where role name = VM name +// See https://msdn.microsoft.com/en-us/library/azure/jj157186.aspx +func (vm VirtualMachineClient) AddRole(cloudServiceName string, deploymentName string, role Role) (management.OperationID, error) { + if cloudServiceName == "" { + return "", fmt.Errorf(errParamNotSpecified, "cloudServiceName") + } + if deploymentName == "" { + return "", fmt.Errorf(errParamNotSpecified, "deploymentName") + } + + data, err := xml.Marshal(PersistentVMRole{Role: role}) + if err != nil { + return "", err + } + + requestURL := fmt.Sprintf(azureAddRoleURL, cloudServiceName, deploymentName) + return vm.client.SendAzurePostRequest(requestURL, data) +} + // UpdateRole updates the configuration of the specified virtual machine // See https://msdn.microsoft.com/en-us/library/azure/jj157187.aspx func (vm VirtualMachineClient) UpdateRole(cloudServiceName, deploymentName, roleName string, role Role) (management.OperationID, error) { diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/management/vmutils/integration_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/management/vmutils/integration_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/management/vmutils/integration_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/management/vmutils/integration_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -12,10 +12,9 @@ "github.com/Azure/azure-sdk-for-go/management/location" "github.com/Azure/azure-sdk-for-go/management/osimage" storage "github.com/Azure/azure-sdk-for-go/management/storageservice" + "github.com/Azure/azure-sdk-for-go/management/testutils" vm "github.com/Azure/azure-sdk-for-go/management/virtualmachine" vmimage "github.com/Azure/azure-sdk-for-go/management/virtualmachineimage" - - "github.com/Azure/azure-sdk-for-go/management/testutils" ) func TestDeployPlatformImage(t *testing.T) { diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/storage/blob_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/storage/blob_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/storage/blob_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/storage/blob_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,7 +14,7 @@ "testing" "time" - chk "gopkg.in/check.v1" + chk "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1" ) type StorageBlobSuite struct{} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/storage/client_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/storage/client_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/storage/client_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/storage/client_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -6,7 +6,7 @@ "os" "testing" - chk "gopkg.in/check.v1" + chk "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1" ) // Hook up gocheck to testing diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/storage/file_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/storage/file_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/storage/file_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/storage/file_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -1,7 +1,7 @@ package storage import ( - chk "gopkg.in/check.v1" + chk "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1" ) type StorageFileSuite struct{} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/storage/queue_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/storage/queue_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/storage/queue_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/storage/queue_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -3,7 +3,7 @@ import ( "time" - chk "gopkg.in/check.v1" + chk "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1" ) type StorageQueueSuite struct{} diff -Nru juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/storage/util_test.go juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/storage/util_test.go --- juju-core-2.0~beta6/src/github.com/Azure/azure-sdk-for-go/storage/util_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/Azure/azure-sdk-for-go/storage/util_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -7,7 +7,7 @@ "strings" "time" - chk "gopkg.in/check.v1" + chk "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/gopkg.in/check.v1" ) func (s *StorageClientSuite) Test_timeRfc1123Formatted(c *chk.C) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/blockdevice.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/blockdevice.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/blockdevice.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/blockdevice.go 2016-05-17 20:01:14.000000000 +0000 @@ -130,7 +130,7 @@ "id": schema.ForceInt(), "name": schema.String(), - "model": schema.String(), + "model": schema.OneOf(schema.Nil(""), schema.String()), "path": schema.String(), "used_for": schema.String(), "tags": schema.List(schema.String()), @@ -155,12 +155,13 @@ return nil, errors.Trace(err) } + model, _ := valid["model"].(string) result := &blockdevice{ resourceURI: valid["resource_uri"].(string), id: valid["id"].(int), name: valid["name"].(string), - model: valid["model"].(string), + model: model, path: valid["path"].(string), usedFor: valid["used_for"].(string), tags: convertToStringSlice(valid["tags"]), diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/blockdevice_test.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/blockdevice_test.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/blockdevice_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/blockdevice_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -42,6 +42,15 @@ c.Check(partition.UsedFor(), gc.Equals, "ext4 formatted filesystem mounted at /") } +func (*blockdeviceSuite) TestReadBlockDevicesWithNulls(c *gc.C) { + blockdevices, err := readBlockDevices(twoDotOh, parseJSON(c, blockdevicesWithNullsResponse)) + c.Assert(err, jc.ErrorIsNil) + c.Assert(blockdevices, gc.HasLen, 1) + blockdevice := blockdevices[0] + + c.Check(blockdevice.Model(), gc.Equals, "") +} + func (*blockdeviceSuite) TestLowVersion(c *gc.C) { _, err := readBlockDevices(version.MustParse("1.9.0"), parseJSON(c, blockdevicesResponse)) c.Assert(err, jc.Satisfies, IsUnsupportedVersionError) @@ -97,3 +106,28 @@ } ] ` + +var blockdevicesWithNullsResponse = ` +[ + { + "path": "/dev/disk/by-dname/sda", + "name": "sda", + "used_for": "MBR partitioned with 1 partition", + "partitions": [], + "filesystem": null, + "id_path": null, + "resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/blockdevices/34/", + "id": 34, + "serial": null, + "type": "physical", + "block_size": 4096, + "used_size": 8586788864, + "available_size": 0, + "partition_table_type": null, + "uuid": null, + "size": 8589934592, + "model": null, + "tags": [] + } +] +` diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/bootresource.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/bootresource.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/bootresource.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/bootresource.go 2016-05-17 20:01:14.000000000 +0000 @@ -110,7 +110,11 @@ "subarches": schema.String(), "kflavor": schema.String(), } - checker := schema.FieldMap(fields, nil) // no defaults + defaults := schema.Defaults{ + "subarches": "", + "kflavor": "", + } + checker := schema.FieldMap(fields, defaults) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, WrapWithDeserializationError(err, "boot resource 2.0 schema check failed") diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/bootresource_test.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/bootresource_test.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/bootresource_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/bootresource_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -61,7 +61,6 @@ "architecture": "amd64/hwe-u", "type": "Synced", "subarches": "generic,hwe-p,hwe-q,hwe-r,hwe-s,hwe-t,hwe-u", - "kflavor": "generic", "name": "ubuntu/trusty", "id": 1, "resource_uri": "/MAAS/api/2.0/boot-resources/1/" @@ -78,7 +77,6 @@ { "architecture": "amd64/hwe-w", "type": "Synced", - "subarches": "generic,hwe-p,hwe-q,hwe-r,hwe-s,hwe-t,hwe-u,hwe-v,hwe-w", "kflavor": "generic", "name": "ubuntu/trusty", "id": 4, diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/controller.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/controller.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/controller.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/controller.go 2016-05-17 20:01:14.000000000 +0000 @@ -442,13 +442,13 @@ //.how the allocated machine matched the storage and interfaces constraints specified. // The labels that were used in the constraints are the keys in the maps. type ConstraintMatches struct { - // Interface is a mapping of the constraint label specified to the Interface - // that matches that constraint. - Interfaces map[string]Interface - - // Storage is a mapping of the constraint label specified to the BlockDevice - // that matches that constraint. - Storage map[string]BlockDevice + // Interface is a mapping of the constraint label specified to the Interfaces + // that match that constraint. + Interfaces map[string][]Interface + + // Storage is a mapping of the constraint label specified to the BlockDevices + // that match that constraint. + Storage map[string][]BlockDevice } // AllocateMachine implements Controller. @@ -807,8 +807,8 @@ func parseAllocateConstraintsResponse(source interface{}, machine *machine) (ConstraintMatches, error) { var empty ConstraintMatches matchFields := schema.Fields{ - "storage": schema.StringMap(schema.ForceInt()), - "interfaces": schema.StringMap(schema.ForceInt()), + "storage": schema.StringMap(schema.List(schema.ForceInt())), + "interfaces": schema.StringMap(schema.List(schema.ForceInt())), } matchDefaults := schema.Defaults{ "storage": schema.Omit, @@ -825,30 +825,52 @@ valid := coerced.(map[string]interface{}) constraintsMap := valid["constraints_by_type"].(map[string]interface{}) result := ConstraintMatches{ - Interfaces: make(map[string]Interface), - Storage: make(map[string]BlockDevice), + Interfaces: make(map[string][]Interface), + Storage: make(map[string][]BlockDevice), } if interfaceMatches, found := constraintsMap["interfaces"]; found { - for label, value := range interfaceMatches.(map[string]interface{}) { - id := value.(int) - iface := machine.Interface(id) - if iface == nil { - return empty, NewDeserializationError("constraint match interface %q: %d does not match an interface for the machine", label, id) + matches := convertConstraintMatches(interfaceMatches) + for label, ids := range matches { + interfaces := make([]Interface, len(ids)) + for index, id := range ids { + iface := machine.Interface(id) + if iface == nil { + return empty, NewDeserializationError("constraint match interface %q: %d does not match an interface for the machine", label, id) + } + interfaces[index] = iface } - result.Interfaces[label] = iface + result.Interfaces[label] = interfaces } } if storageMatches, found := constraintsMap["storage"]; found { - for label, value := range storageMatches.(map[string]interface{}) { - id := value.(int) - blockDevice := machine.PhysicalBlockDevice(id) - if blockDevice == nil { - return empty, NewDeserializationError("constraint match storage %q: %d does not match a physical block device for the machine", label, id) + matches := convertConstraintMatches(storageMatches) + for label, ids := range matches { + blockDevices := make([]BlockDevice, len(ids)) + for index, id := range ids { + blockDevice := machine.PhysicalBlockDevice(id) + if blockDevice == nil { + return empty, NewDeserializationError("constraint match storage %q: %d does not match a physical block device for the machine", label, id) + } + blockDevices[index] = blockDevice } - result.Storage[label] = blockDevice + result.Storage[label] = blockDevices } } return result, nil } + +func convertConstraintMatches(source interface{}) map[string][]int { + // These casts are all safe because of the schema check. + result := make(map[string][]int) + matchMap := source.(map[string]interface{}) + for label, values := range matchMap { + items := values.([]interface{}) + result[label] = make([]int, len(items)) + for index, value := range items { + result[label][index] = value.(int) + } + } + return result +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/controller_test.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/controller_test.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/controller_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/controller_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -403,7 +403,9 @@ } } -func (s *controllerSuite) addAllocateResponse(c *gc.C, status int, interfaceMatches, storageMatches map[string]int) { +type constraintMatchInfo map[string][]int + +func (s *controllerSuite) addAllocateResponse(c *gc.C, status int, interfaceMatches, storageMatches constraintMatchInfo) { constraints := make(map[string]interface{}) if interfaceMatches != nil { constraints["interfaces"] = interfaceMatches @@ -426,8 +428,8 @@ } func (s *controllerSuite) TestAllocateMachineInterfacesMatch(c *gc.C) { - s.addAllocateResponse(c, http.StatusOK, map[string]int{ - "database": 35, + s.addAllocateResponse(c, http.StatusOK, constraintMatchInfo{ + "database": []int{35, 99}, }, nil) controller := s.getController(c) _, match, err := controller.AllocateMachine(AllocateMachineArgs{ @@ -439,15 +441,17 @@ }) c.Assert(err, jc.ErrorIsNil) c.Assert(match.Interfaces, gc.HasLen, 1) - iface := match.Interfaces["database"] - c.Assert(iface.ID(), gc.Equals, 35) + ifaces := match.Interfaces["database"] + c.Assert(ifaces, gc.HasLen, 2) + c.Assert(ifaces[0].ID(), gc.Equals, 35) + c.Assert(ifaces[1].ID(), gc.Equals, 99) } func (s *controllerSuite) TestAllocateMachineInterfacesMatchMissing(c *gc.C) { // This should never happen, but if it does it is a clear indication of a // bug somewhere. - s.addAllocateResponse(c, http.StatusOK, map[string]int{ - "database": 40, + s.addAllocateResponse(c, http.StatusOK, constraintMatchInfo{ + "database": []int{40}, }, nil) controller := s.getController(c) _, _, err := controller.AllocateMachine(AllocateMachineArgs{ @@ -460,8 +464,8 @@ } func (s *controllerSuite) TestAllocateMachineStorageMatches(c *gc.C) { - s.addAllocateResponse(c, http.StatusOK, nil, map[string]int{ - "root": 34, + s.addAllocateResponse(c, http.StatusOK, nil, constraintMatchInfo{ + "root": []int{34, 98}, }) controller := s.getController(c) _, match, err := controller.AllocateMachine(AllocateMachineArgs{ @@ -473,15 +477,17 @@ }) c.Assert(err, jc.ErrorIsNil) c.Assert(match.Storage, gc.HasLen, 1) - storage := match.Storage["root"] - c.Assert(storage.ID(), gc.Equals, 34) + storages := match.Storage["root"] + c.Assert(storages, gc.HasLen, 2) + c.Assert(storages[0].ID(), gc.Equals, 34) + c.Assert(storages[1].ID(), gc.Equals, 98) } func (s *controllerSuite) TestAllocateMachineStorageMatchMissing(c *gc.C) { // This should never happen, but if it does it is a clear indication of a // bug somewhere. - s.addAllocateResponse(c, http.StatusOK, nil, map[string]int{ - "root": 50, + s.addAllocateResponse(c, http.StatusOK, nil, constraintMatchInfo{ + "root": []int{50}, }) controller := s.getController(c) _, _, err := controller.AllocateMachine(AllocateMachineArgs{ diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/device.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/device.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/device.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/device.go 2016-05-17 20:01:14.000000000 +0000 @@ -246,14 +246,18 @@ "system_id": schema.String(), "hostname": schema.String(), "fqdn": schema.String(), - "parent": schema.String(), - "owner": schema.String(), + "parent": schema.OneOf(schema.Nil(""), schema.String()), + "owner": schema.OneOf(schema.Nil(""), schema.String()), "ip_addresses": schema.List(schema.String()), "interface_set": schema.List(schema.StringMap(schema.Any())), "zone": schema.StringMap(schema.Any()), } - checker := schema.FieldMap(fields, nil) // no defaults + defaults := schema.Defaults{ + "owner": "", + "parent": "", + } + checker := schema.FieldMap(fields, defaults) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, WrapWithDeserializationError(err, "device 2.0 schema check failed") @@ -270,15 +274,16 @@ if err != nil { return nil, errors.Trace(err) } - + owner, _ := valid["owner"].(string) + parent, _ := valid["parent"].(string) result := &device{ resourceURI: valid["resource_uri"].(string), systemID: valid["system_id"].(string), hostname: valid["hostname"].(string), fqdn: valid["fqdn"].(string), - parent: valid["parent"].(string), - owner: valid["owner"].(string), + parent: parent, + owner: owner, ipAddresses: convertToStringSlice(valid["ip_addresses"]), interfaceSet: interfaceSet, diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/device_test.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/device_test.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/device_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/device_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -45,6 +45,20 @@ c.Check(zone.Name(), gc.Equals, "default") } +func (*deviceSuite) TestReadDevicesNils(c *gc.C) { + json := parseJSON(c, devicesResponse) + deviceMap := json.([]interface{})[0].(map[string]interface{}) + deviceMap["owner"] = nil + deviceMap["parent"] = nil + devices, err := readDevices(twoDotOh, json) + c.Assert(err, jc.ErrorIsNil) + c.Assert(devices, gc.HasLen, 1) + + device := devices[0] + c.Check(device.Owner(), gc.Equals, "") + c.Check(device.Parent(), gc.Equals, "") +} + func (*deviceSuite) TestLowVersion(c *gc.C) { _, err := readDevices(version.MustParse("1.9.0"), parseJSON(c, devicesResponse)) c.Assert(err, jc.Satisfies, IsUnsupportedVersionError) diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/filesystem.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/filesystem.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/filesystem.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/filesystem.go 2016-05-17 20:01:14.000000000 +0000 @@ -39,12 +39,17 @@ func filesystem2_0(source map[string]interface{}) (*filesystem, error) { fields := schema.Fields{ "fstype": schema.String(), - "mount_point": schema.String(), - "label": schema.String(), + "mount_point": schema.OneOf(schema.Nil(""), schema.String()), + "label": schema.OneOf(schema.Nil(""), schema.String()), "uuid": schema.String(), - // TODO: mount_options when we know the type. + // TODO: mount_options when we know the type (note it can be + // nil). } - checker := schema.FieldMap(fields, nil) + defaults := schema.Defaults{ + "mount_point": "", + "label": "", + } + checker := schema.FieldMap(fields, defaults) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, WrapWithDeserializationError(err, "filesystem 2.0 schema check failed") @@ -52,11 +57,12 @@ valid := coerced.(map[string]interface{}) // From here we know that the map returned from the schema coercion // contains fields of the right type. - + mount_point, _ := valid["mount_point"].(string) + label, _ := valid["label"].(string) result := &filesystem{ fstype: valid["fstype"].(string), - mountPoint: valid["mount_point"].(string), - label: valid["label"].(string), + mountPoint: mount_point, + label: label, uuid: valid["uuid"].(string), } return result, nil diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/filesystem_test.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/filesystem_test.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/filesystem_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/filesystem_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -27,6 +27,21 @@ c.Check(fs.UUID(), gc.Equals, "fake-uuid") } +func (*filesystemSuite) TestParse2_Defaults(c *gc.C) { + source := map[string]interface{}{ + "fstype": "ext4", + "mount_point": nil, + "label": nil, + "uuid": "fake-uuid", + } + fs, err := filesystem2_0(source) + c.Assert(err, jc.ErrorIsNil) + c.Check(fs.Type(), gc.Equals, "ext4") + c.Check(fs.MountPoint(), gc.Equals, "") + c.Check(fs.Label(), gc.Equals, "") + c.Check(fs.UUID(), gc.Equals, "fake-uuid") +} + func (*filesystemSuite) TestParse2_0BadSchema(c *gc.C) { source := map[string]interface{}{ "mount_point": "/", diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/interface.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/interface.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/interface.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/interface.go 2016-05-17 20:01:14.000000000 +0000 @@ -381,18 +381,21 @@ "name": schema.String(), "type": schema.String(), "enabled": schema.Bool(), - "tags": schema.List(schema.String()), + "tags": schema.OneOf(schema.Nil(""), schema.List(schema.String())), - "vlan": schema.StringMap(schema.Any()), + "vlan": schema.OneOf(schema.Nil(""), schema.StringMap(schema.Any())), "links": schema.List(schema.StringMap(schema.Any())), - "mac_address": schema.String(), + "mac_address": schema.OneOf(schema.Nil(""), schema.String()), "effective_mtu": schema.ForceInt(), "parents": schema.List(schema.String()), "children": schema.List(schema.String()), } - checker := schema.FieldMap(fields, nil) // no defaults + defaults := schema.Defaults{ + "mac_address": "", + } + checker := schema.FieldMap(fields, defaults) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, WrapWithDeserializationError(err, "interface 2.0 schema check failed") @@ -401,15 +404,20 @@ // From here we know that the map returned from the schema coercion // contains fields of the right type. - vlan, err := vlan_2_0(valid["vlan"].(map[string]interface{})) - if err != nil { - return nil, errors.Trace(err) + var vlan *vlan + // If it's not an attribute map then we know it's nil from the schema check. + if vlanMap, ok := valid["vlan"].(map[string]interface{}); ok { + vlan, err = vlan_2_0(vlanMap) + if err != nil { + return nil, errors.Trace(err) + } } + links, err := readLinkList(valid["links"].([]interface{}), link_2_0) if err != nil { return nil, errors.Trace(err) } - + macAddress, _ := valid["mac_address"].(string) result := &interface_{ resourceURI: valid["resource_uri"].(string), @@ -422,7 +430,7 @@ vlan: vlan, links: links, - macAddress: valid["mac_address"].(string), + macAddress: macAddress, effectiveMTU: valid["effective_mtu"].(int), parents: convertToStringSlice(valid["parents"]), diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/interface_test.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/interface_test.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/interface_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/interface_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -38,6 +38,15 @@ c.Assert(err, gc.ErrorMatches, `interface 0: interface 2.0 schema check failed: .*`) } +func (*interfaceSuite) TestReadInterfacesNulls(c *gc.C) { + iface, err := readInterface(twoDotOh, parseJSON(c, interfaceNullsResponse)) + c.Assert(err, jc.ErrorIsNil) + + c.Check(iface.MACAddress(), gc.Equals, "") + c.Check(iface.Tags(), jc.DeepEquals, []string{}) + c.Check(iface.VLAN(), gc.IsNil) +} + func (s *interfaceSuite) checkInterface(c *gc.C, iface *interface_) { c.Check(iface.ID(), gc.Equals, 40) c.Check(iface.Name(), gc.Equals, "eth0") @@ -73,6 +82,14 @@ s.checkInterface(c, result) } +func (s *interfaceSuite) TestReadInterfaceNilMAC(c *gc.C) { + json := parseJSON(c, interfaceResponse) + json.(map[string]interface{})["mac_address"] = nil + result, err := readInterface(twoDotOh, json) + c.Assert(err, jc.ErrorIsNil) + c.Assert(result.MACAddress(), gc.Equals, "") +} + func (*interfaceSuite) TestLowVersion(c *gc.C) { _, err := readInterfaces(version.MustParse("1.9.0"), parseJSON(c, interfacesResponse)) c.Assert(err, jc.Satisfies, IsUnsupportedVersionError) @@ -405,6 +422,50 @@ "links": [ { "id": 69, + "mode": "auto", + "subnet": { + "resource_uri": "/MAAS/api/2.0/subnets/1/", + "id": 1, + "rdns_mode": 2, + "vlan": { + "resource_uri": "/MAAS/api/2.0/vlans/1/", + "id": 1, + "secondary_rack": null, + "mtu": 1500, + "primary_rack": "4y3h7n", + "name": "untagged", + "fabric": "fabric-0", + "dhcp_on": true, + "vid": 0 + }, + "dns_servers": [], + "space": "space-0", + "name": "192.168.100.0/24", + "gateway_ip": "192.168.100.1", + "cidr": "192.168.100.0/24" + } + } + ] +} +` + interfaceNullsResponse = ` +{ + "effective_mtu": 1500, + "mac_address": null, + "children": ["eth0.1", "eth0.2"], + "discovered": [], + "params": "some params", + "vlan": null, + "name": "eth0", + "enabled": true, + "parents": ["bond0"], + "id": 40, + "type": "physical", + "resource_uri": "/MAAS/api/2.0/nodes/4y3ha6/interfaces/40/", + "tags": null, + "links": [ + { + "id": 69, "mode": "auto", "subnet": { "resource_uri": "/MAAS/api/2.0/subnets/1/", diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/machine.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/machine.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/machine.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/machine.go 2016-05-17 20:01:14.000000000 +0000 @@ -308,7 +308,7 @@ updateArgs.Name = args.InterfaceName } if iface.VLAN().ID() != args.Subnet.VLAN().ID() { - updateArgs.VLAN = iface.VLAN() + updateArgs.VLAN = args.Subnet.VLAN() } err = iface.Update(updateArgs) if err != nil { @@ -402,23 +402,26 @@ "osystem": schema.String(), "distro_series": schema.String(), - "architecture": schema.String(), + "architecture": schema.OneOf(schema.Nil(""), schema.String()), "memory": schema.ForceInt(), "cpu_count": schema.ForceInt(), "ip_addresses": schema.List(schema.String()), "power_state": schema.String(), "status_name": schema.String(), - "status_message": schema.String(), + "status_message": schema.OneOf(schema.Nil(""), schema.String()), - "boot_interface": schema.StringMap(schema.Any()), + "boot_interface": schema.OneOf(schema.Nil(""), schema.StringMap(schema.Any())), "interface_set": schema.List(schema.StringMap(schema.Any())), "zone": schema.StringMap(schema.Any()), "physicalblockdevice_set": schema.List(schema.StringMap(schema.Any())), "blockdevice_set": schema.List(schema.StringMap(schema.Any())), } - checker := schema.FieldMap(fields, nil) // no defaults + defaults := schema.Defaults{ + "architecture": "", + } + checker := schema.FieldMap(fields, defaults) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, WrapWithDeserializationError(err, "machine 2.0 schema check failed") @@ -427,10 +430,14 @@ // From here we know that the map returned from the schema coercion // contains fields of the right type. - bootInterface, err := interface_2_0(valid["boot_interface"].(map[string]interface{})) - if err != nil { - return nil, errors.Trace(err) + var bootInterface *interface_ + if ifaceMap, ok := valid["boot_interface"].(map[string]interface{}); ok { + bootInterface, err = interface_2_0(ifaceMap) + if err != nil { + return nil, errors.Trace(err) + } } + interfaceSet, err := readInterfaceList(valid["interface_set"].([]interface{}), interface_2_0) if err != nil { return nil, errors.Trace(err) @@ -447,7 +454,8 @@ if err != nil { return nil, errors.Trace(err) } - + architecture, _ := valid["architecture"].(string) + statusMessage, _ := valid["status_message"].(string) result := &machine{ resourceURI: valid["resource_uri"].(string), @@ -458,14 +466,14 @@ operatingSystem: valid["osystem"].(string), distroSeries: valid["distro_series"].(string), - architecture: valid["architecture"].(string), + architecture: architecture, memory: valid["memory"].(int), cpuCount: valid["cpu_count"].(int), ipAddresses: convertToStringSlice(valid["ip_addresses"]), powerState: valid["power_state"].(string), statusName: valid["status_name"].(string), - statusMessage: valid["status_message"].(string), + statusMessage: statusMessage, bootInterface: bootInterface, interfaceSet: interfaceSet, diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/machine_test.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/machine_test.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/machine_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/machine_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -69,24 +69,41 @@ c.Check(bootInterface.Name(), gc.Equals, "eth0") interfaceSet := machine.InterfaceSet() - c.Assert(interfaceSet, gc.HasLen, 1) + c.Assert(interfaceSet, gc.HasLen, 2) id := interfaceSet[0].ID() c.Assert(machine.Interface(id), jc.DeepEquals, interfaceSet[0]) c.Assert(machine.Interface(id+5), gc.IsNil) blockDevices := machine.BlockDevices() - c.Assert(blockDevices, gc.HasLen, 1) + c.Assert(blockDevices, gc.HasLen, 2) c.Assert(blockDevices[0].Name(), gc.Equals, "sda") + c.Assert(blockDevices[1].Name(), gc.Equals, "sdb") blockDevices = machine.PhysicalBlockDevices() - c.Assert(blockDevices, gc.HasLen, 1) + c.Assert(blockDevices, gc.HasLen, 2) c.Assert(blockDevices[0].Name(), gc.Equals, "sda") + c.Assert(blockDevices[1].Name(), gc.Equals, "sdb") id = blockDevices[0].ID() c.Assert(machine.PhysicalBlockDevice(id), jc.DeepEquals, blockDevices[0]) c.Assert(machine.PhysicalBlockDevice(id+5), gc.IsNil) } +func (*machineSuite) TestReadMachinesNilValues(c *gc.C) { + json := parseJSON(c, machinesResponse) + data := json.([]interface{})[0].(map[string]interface{}) + data["architecture"] = nil + data["status_message"] = nil + data["boot_interface"] = nil + machines, err := readMachines(twoDotOh, json) + c.Assert(err, jc.ErrorIsNil) + c.Assert(machines, gc.HasLen, 3) + machine := machines[0] + c.Check(machine.Architecture(), gc.Equals, "") + c.Check(machine.StatusMessage(), gc.Equals, "") + c.Check(machine.BootInterface(), gc.IsNil) +} + func (*machineSuite) TestLowVersion(c *gc.C) { _, err := readMachines(version.MustParse("1.9.0"), parseJSON(c, machinesResponse)) c.Assert(err, jc.Satisfies, IsUnsupportedVersionError) @@ -270,6 +287,7 @@ }) c.Assert(err, jc.ErrorIsNil) c.Assert(device.InterfaceSet()[0].Name(), gc.Equals, "eth4") + c.Assert(device.InterfaceSet()[0].VLAN().ID(), gc.Equals, subnet.VLAN().ID()) } func (s *machineSuite) TestCreateDeviceTriesToDeleteDeviceOnError(c *gc.C) { @@ -359,6 +377,46 @@ "tags": [ "rotary" ] + }, + { + "path": "/dev/disk/by-dname/sdb", + "name": "sdb", + "used_for": "MBR partitioned with 1 partition", + "partitions": [ + { + "bootable": false, + "id": 101, + "path": "/dev/disk/by-dname/sdb-part1", + "filesystem": { + "fstype": "ext4", + "mount_point": "/home", + "label": "home", + "mount_options": null, + "uuid": "fcd7745e-f1b5-4f5d-9575-9b0bb796b753" + }, + "type": "partition", + "resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/blockdevices/98/partition/101", + "uuid": "6199b7c9-b66f-40f6-a238-a938a58a0ae0", + "used_for": "ext4 formatted filesystem mounted at /home", + "size": 8581545984 + } + ], + "filesystem": null, + "id_path": "/dev/disk/by-id/ata-QEMU_HARDDISK_QM00002", + "resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/blockdevices/98/", + "id": 98, + "serial": "QM00002", + "type": "physical", + "block_size": 4096, + "used_size": 8586788864, + "available_size": 0, + "partition_table_type": "MBR", + "uuid": null, + "size": 8589934592, + "model": "QEMU HARDDISK", + "tags": [ + "rotary" + ] } ], "interface_set": [ @@ -414,6 +472,59 @@ "mode": "auto" } ] + }, + { + "effective_mtu": 1500, + "mac_address": "52:54:00:55:b6:81", + "children": [], + "discovered": [], + "params": "", + "vlan": { + "resource_uri": "/MAAS/api/2.0/vlans/1/", + "id": 1, + "secondary_rack": null, + "mtu": 1500, + "primary_rack": "4y3h7n", + "name": "untagged", + "fabric": "fabric-0", + "dhcp_on": true, + "vid": 0 + }, + "name": "eth0", + "enabled": true, + "parents": [], + "id": 99, + "type": "physical", + "resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/interfaces/99/", + "tags": [], + "links": [ + { + "id": 83, + "ip_address": "192.168.100.5", + "subnet": { + "resource_uri": "/MAAS/api/2.0/subnets/1/", + "id": 1, + "rdns_mode": 2, + "vlan": { + "resource_uri": "/MAAS/api/2.0/vlans/1/", + "id": 1, + "secondary_rack": null, + "mtu": 1500, + "primary_rack": "4y3h7n", + "name": "untagged", + "fabric": "fabric-0", + "dhcp_on": true, + "vid": 0 + }, + "dns_servers": [], + "space": "space-0", + "name": "192.168.100.0/24", + "gateway_ip": "192.168.100.1", + "cidr": "192.168.100.0/24" + }, + "mode": "auto" + } + ] } ], "resource_uri": "/MAAS/api/2.0/machines/4y3ha3/", @@ -524,6 +635,46 @@ "uuid": null, "size": 8589934592, "model": "QEMU HARDDISK" + }, + { + "path": "/dev/disk/by-dname/sdb", + "name": "sdb", + "used_for": "MBR partitioned with 1 partition", + "partitions": [ + { + "bootable": false, + "id": 101, + "path": "/dev/disk/by-dname/sdb-part1", + "filesystem": { + "fstype": "ext4", + "mount_point": "/home", + "label": "home", + "mount_options": null, + "uuid": "fcd7745e-f1b5-4f5d-9575-9b0bb796b753" + }, + "type": "partition", + "resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/blockdevices/98/partition/101", + "uuid": "6199b7c9-b66f-40f6-a238-a938a58a0ae0", + "used_for": "ext4 formatted filesystem mounted at /home", + "size": 8581545984 + } + ], + "filesystem": null, + "id_path": "/dev/disk/by-id/ata-QEMU_HARDDISK_QM00002", + "resource_uri": "/MAAS/api/2.0/nodes/4y3ha3/blockdevices/98/", + "id": 98, + "serial": "QM00002", + "type": "physical", + "block_size": 4096, + "used_size": 8586788864, + "available_size": 0, + "partition_table_type": "MBR", + "uuid": null, + "size": 8589934592, + "model": "QEMU HARDDISK", + "tags": [ + "rotary" + ] } ], "zone": { diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/partition.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/partition.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/partition.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/partition.go 2016-05-17 20:01:14.000000000 +0000 @@ -105,14 +105,17 @@ "id": schema.ForceInt(), "path": schema.String(), - "uuid": schema.String(), + "uuid": schema.OneOf(schema.Nil(""), schema.String()), "used_for": schema.String(), "size": schema.ForceUint(), "filesystem": schema.OneOf(schema.Nil(""), schema.StringMap(schema.Any())), } - checker := schema.FieldMap(fields, nil) + defaults := schema.Defaults{ + "uuid": "", + } + checker := schema.FieldMap(fields, defaults) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, WrapWithDeserializationError(err, "partition 2.0 schema check failed") @@ -128,12 +131,12 @@ return nil, errors.Trace(err) } } - + uuid, _ := valid["uuid"].(string) result := &partition{ resourceURI: valid["resource_uri"].(string), id: valid["id"].(int), path: valid["path"].(string), - uuid: valid["uuid"].(string), + uuid: uuid, usedFor: valid["used_for"].(string), size: valid["size"].(uint64), filesystem: filesystem, diff -Nru juju-core-2.0~beta6/src/github.com/juju/gomaasapi/partition_test.go juju-core-2.0~beta7/src/github.com/juju/gomaasapi/partition_test.go --- juju-core-2.0~beta6/src/github.com/juju/gomaasapi/partition_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/gomaasapi/partition_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -42,6 +42,16 @@ c.Assert(fs.MountPoint(), gc.Equals, "/") } +func (*partitionSuite) TestReadPartitionsNilUUID(c *gc.C) { + json := parseJSON(c, partitionsResponse) + json.([]interface{})[0].(map[string]interface{})["uuid"] = nil + partitions, err := readPartitions(twoDotOh, json) + c.Assert(err, jc.ErrorIsNil) + c.Assert(partitions, gc.HasLen, 1) + partition := partitions[0] + c.Check(partition.UUID(), gc.Equals, "") +} + func (*partitionSuite) TestLowVersion(c *gc.C) { _, err := readPartitions(version.MustParse("1.9.0"), parseJSON(c, partitionsResponse)) c.Assert(err, jc.Satisfies, IsUnsupportedVersionError) diff -Nru juju-core-2.0~beta6/src/github.com/juju/httprequest/client.go juju-core-2.0~beta7/src/github.com/juju/httprequest/client.go --- juju-core-2.0~beta6/src/github.com/juju/httprequest/client.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/httprequest/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -13,6 +13,7 @@ "net/url" "reflect" "strings" + "sync" "gopkg.in/errgo.v1" ) @@ -166,7 +167,14 @@ httpResp, err = doer1.DoWithBody(req, body) } else { if body != nil { - req.Body = ioutil.NopCloser(body) + // Work around Go issue 12796 by using a body + // that can't be read from after it's been closed, + // so if the caller of Do calls body.Close immediately after + // Do returns, the http request logic won't be + // able to call body.Close or body.Read + // because the readStopper will prevent that. + req.Body = &readStopper{r: body} + defer req.Body.Close() } httpResp, err = doer.Do(req) } @@ -329,3 +337,36 @@ } return b, nil } + +// readStopper implements io.ReadCloser by preventing +// all reads after Close has been called. +// This is necessary to work around http://golang.org/issue/12796 +// +// TODO export this, as it may be useful for other +// clients of net/http too? +type readStopper struct { + mu sync.Mutex + r io.Reader +} + +func (r *readStopper) Read(buf []byte) (int, error) { + r.mu.Lock() + defer r.mu.Unlock() + if r.r == nil { + // Note: we have to use io.EOF here because otherwise + // another connection can (in rare circumstances) be + // polluted by the error returned here. Although this + // means the file may appear truncated to the server, + // that shouldn't matter because the body will only + // be closed after the server has replied. + return 0, io.EOF + } + return r.r.Read(buf) +} + +func (r *readStopper) Close() error { + r.mu.Lock() + r.r = nil + r.mu.Unlock() + return nil +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/httprequest/client_test.go juju-core-2.0~beta7/src/github.com/juju/httprequest/client_test.go --- juju-core-2.0~beta6/src/github.com/juju/httprequest/client_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/httprequest/client_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -395,6 +395,25 @@ c.Assert(doer.closedBodies, gc.Equals, 1) } +func (s *clientSuite) TestDoDoesNotReadRequestBodyAfterReturning(c *gc.C) { + body := &largeReader{total: 300 * 1024} + // Closing the body will cause a panic under the race + // detector if the Do method reads after returning. + defer body.Close() + + srv := s.newServer() + defer srv.Close() + + req, err := http.NewRequest("GET", "/not-an-endpoint", nil) + c.Assert(err, gc.IsNil) + + client := &httprequest.Client{ + BaseURL: srv.URL, + } + err = client.Do(req, body, nil) + c.Assert(err, gc.ErrorMatches, `GET .*/not-an-endpoint: cannot unmarshal error response \(status 404 Not Found\): unexpected content type text/plain; want application/json; content: 404 page not found`) +} + func (s *clientSuite) TestGet(c *gc.C) { srv := s.newServer() defer srv.Close() @@ -617,3 +636,35 @@ r.doer.closedBodies++ return r.ReadCloser.Close() } + +// largeReader implements a reader that produces up to total bytes +// in 1 byte reads. +type largeReader struct { + total int + n int +} + +func (r *largeReader) Read(buf []byte) (int, error) { + if r.n >= r.total { + return 0, io.EOF + } + r.n++ + return copy(buf, []byte("a")), nil +} + +func (r *largeReader) Seek(offset int64, whence int) (int64, error) { + if offset != 0 || whence != 0 { + panic("unexpected seek") + } + r.n = 0 + return 0, nil +} + +func (r *largeReader) Close() error { + // By setting n to zero, we ensure that if there's + // a concurrent read, it will also read from n + // and so the race detector should pick up the + // problem. + r.n = 0 + return nil +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/httprequest/cmd/httprequest-generate-client/main.go juju-core-2.0~beta7/src/github.com/juju/httprequest/cmd/httprequest-generate-client/main.go --- juju-core-2.0~beta6/src/github.com/juju/httprequest/cmd/httprequest-generate-client/main.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/httprequest/cmd/httprequest-generate-client/main.go 2016-05-17 20:01:14.000000000 +0000 @@ -1,3 +1,5 @@ +// +build go1.6 + package main import ( @@ -14,7 +16,7 @@ "text/template" "golang.org/x/tools/go/loader" - "golang.org/x/tools/go/types" + "go/types" "gopkg.in/errgo.v1" ) @@ -42,10 +44,10 @@ } type templateArg struct { - PkgName string - Imports []string - Methods []method - ClientType string + PkgName string + Imports []string + Methods []method + ClientType string } var code = template.Must(template.New("").Parse(` @@ -98,10 +100,10 @@ return errgo.Mask(err) } arg := templateArg{ - Imports: imports, - Methods: methods, - PkgName: localPkg.Name, - ClientType: clientType, + Imports: imports, + Methods: methods, + PkgName: localPkg.Name, + ClientType: clientType, } var buf bytes.Buffer if err := code.Execute(&buf, arg); err != nil { diff -Nru juju-core-2.0~beta6/src/github.com/juju/httprequest/dependencies.tsv juju-core-2.0~beta7/src/github.com/juju/httprequest/dependencies.tsv --- juju-core-2.0~beta6/src/github.com/juju/httprequest/dependencies.tsv 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/httprequest/dependencies.tsv 2016-05-17 20:01:14.000000000 +0000 @@ -1,8 +1,8 @@ github.com/juju/loggo git 8477fc936adf0e382d680310047ca27e128a309a 2015-05-27T03:58:39Z -github.com/juju/testing git 5955efc6d5f61e41a13e4409ec6bae7a6975546f 2015-10-10T23:46:57Z -github.com/julienschmidt/httprouter git b59a38004596b696aca7aa2adccfa68760864d86 2015-04-08T17:04:29Z -golang.org/x/net git 446d52dd4018303a13b36097e26d0888aca5d6ef 2015-07-21T02:27:38Z -golang.org/x/tools git c5ca59aab8c27791ce3f820caad760cff360cfc8 2015-07-14T18:01:18Z -gopkg.in/check.v1 git b3d3430320d4260e5fea99841af984b3badcea63 2015-06-26T10:50:28Z -gopkg.in/errgo.v1 git 15098963088579c1cd9eb1a7da285831e548390b 2015-07-07T18:34:45Z -gopkg.in/yaml.v2 git 53feefa2559fb8dfa8d81baad31be332c97d6c77 2015-09-24T14:23:14Z +github.com/juju/testing git 162fafccebf20a4207ab93d63b986c230e3f4d2e 2016-04-04T09:43:17Z +github.com/julienschmidt/httprouter git 77a895ad01ebc98a4dc95d8355bc825ce80a56f6 2015-10-13T22:55:20Z +golang.org/x/net git ea47fc708ee3e20177f3ca3716217c4ab75942cb 2015-08-29T23:03:18Z +golang.org/x/tools git 1f1b3322f67af76803c942fd237291538ec68262 2016-04-27T05:26:01Z +gopkg.in/check.v1 git 4f90aeace3a26ad7021961c297b22c42160c7b25 2016-01-05T16:49:36Z +gopkg.in/errgo.v1 git 66cb46252b94c1f3d65646f54ee8043ab38d766c 2015-10-07T15:31:57Z +gopkg.in/yaml.v2 git a83829b6f1293c91addabc89d0571c246397bbf4 2016-03-01T20:40:22Z diff -Nru juju-core-2.0~beta6/src/github.com/juju/httprequest/handler.go juju-core-2.0~beta7/src/github.com/juju/httprequest/handler.go --- juju-core-2.0~beta6/src/github.com/juju/httprequest/handler.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/httprequest/handler.go 2016-05-17 20:01:14.000000000 +0000 @@ -80,9 +80,10 @@ Path: rt.path, Handle: func(w http.ResponseWriter, req *http.Request, p httprouter.Params) { hf(fv, Params{ - Response: w, - Request: req, - PathVar: p, + Response: w, + Request: req, + PathVar: p, + PathPattern: rt.path, }) }, } @@ -140,9 +141,10 @@ handler := func(w http.ResponseWriter, req *http.Request, p httprouter.Params) { terrv := fv.Call([]reflect.Value{ reflect.ValueOf(Params{ - Response: w, - Request: req, - PathVar: p, + Response: w, + Request: req, + PathVar: p, + PathPattern: rt.path, }), }) tv, errv := terrv[0], terrv[1] @@ -154,9 +156,10 @@ defer tv.Interface().(io.Closer).Close() } hf(tv.Method(i), Params{ - Response: w, - Request: req, - PathVar: p, + Response: w, + Request: req, + PathVar: p, + PathPattern: rt.path, }) } @@ -365,6 +368,9 @@ // HandleJSON returns a handler that writes the return value of handle // as a JSON response. If handle returns an error, it is passed through // the error mapper. +// +// Note that the Params argument passed to handle will not +// have its PathPattern set as that information is not available. func (e ErrorMapper) HandleJSON(handle JSONHandler) httprouter.Handle { return func(w http.ResponseWriter, req *http.Request, p httprouter.Params) { val, err := handle(Params{ @@ -383,6 +389,9 @@ // HandleErrors returns a handler that passes any non-nil error returned // by handle through the error mapper and writes it as a JSON response. +// +// Note that the Params argument passed to handle will not +// have its PathPattern set as that information is not available. func (e ErrorMapper) HandleErrors(handle ErrorHandler) httprouter.Handle { return func(w http.ResponseWriter, req *http.Request, p httprouter.Params) { w1 := responseWriter{ diff -Nru juju-core-2.0~beta6/src/github.com/juju/httprequest/handler_test.go juju-core-2.0~beta7/src/github.com/juju/httprequest/handler_test.go --- juju-core-2.0~beta6/src/github.com/juju/httprequest/handler_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/httprequest/handler_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -53,6 +53,7 @@ c.Assert(p.Request.Form, jc.DeepEquals, url.Values{ "c": {"43"}, }) + c.Assert(p.PathPattern, gc.Equals, "") p.Response.Header().Set("Content-Type", "application/json") p.Response.Write([]byte("true")) } @@ -77,6 +78,7 @@ } return func(p httprequest.Params, s *testStruct) error { c.Assert(s, jc.DeepEquals, &testStruct{123}) + c.Assert(p.PathPattern, gc.Equals, "") p.Response.Header().Set("Content-Type", "application/json") p.Response.Write([]byte("true")) return nil @@ -95,6 +97,7 @@ A int `httprequest:"a,path"` } return func(p httprequest.Params, s *testStruct) error { + c.Assert(p.PathPattern, gc.Equals, "") c.Assert(s, jc.DeepEquals, &testStruct{123}) return errUnauth } @@ -116,6 +119,7 @@ A int `httprequest:"a,path"` } return func(p httprequest.Params, s *testStruct) (int, error) { + c.Assert(p.PathPattern, gc.Equals, "") c.Assert(s, jc.DeepEquals, &testStruct{123}) return 1234, nil } @@ -133,6 +137,7 @@ A int `httprequest:"a,path"` } return func(p httprequest.Params, s *testStruct) (int, error) { + c.Assert(p.PathPattern, gc.Equals, "") c.Assert(s, jc.DeepEquals, &testStruct{123}) return 0, errUnauth } @@ -154,6 +159,7 @@ A int `httprequest:"a,path"` } return func(p httprequest.Params, s *testStruct) (int, error) { + c.Assert(p.PathPattern, gc.Equals, "") _, err := p.Response.Write(nil) c.Assert(err, gc.ErrorMatches, "inappropriate call to ResponseWriter.Write in JSON-returning handler") p.Response.WriteHeader(http.StatusTeapot) @@ -352,8 +358,9 @@ httprequest.Route `httprequest:"GET /foo/:bar"` A string `httprequest:"bar,path"` } - return func(s *testStruct) { + return func(p httprequest.Params, s *testStruct) { c.Check(s.A, gc.Equals, "val") + c.Assert(p.PathPattern, gc.Equals, "/foo/:bar") } }, req: &http.Request{}, @@ -462,19 +469,22 @@ } var handlersTests = []struct { - calledMethod string - callParams httptesting.JSONCallParams + calledMethod string + callParams httptesting.JSONCallParams + expectPathPattern string }{{ calledMethod: "M1", callParams: httptesting.JSONCallParams{ URL: "/m1/99", }, + expectPathPattern: "/m1/:p", }, { calledMethod: "M2", callParams: httptesting.JSONCallParams{ URL: "/m2/99", ExpectBody: 999, }, + expectPathPattern: "/m2/:p", }, { calledMethod: "M3", callParams: httptesting.JSONCallParams{ @@ -484,6 +494,7 @@ }, ExpectStatus: http.StatusInternalServerError, }, + expectPathPattern: "/m3/:p", }, { calledMethod: "M3Post", callParams: httptesting.JSONCallParams{ @@ -491,6 +502,7 @@ URL: "/m3/99", JSONBody: make(map[string]interface{}), }, + expectPathPattern: "/m3/:p", }} func (*handlerSuite) TestHandlers(c *gc.C) { @@ -530,10 +542,13 @@ } for i, test := range handlersTests { c.Logf("test %d: %s", i, test.calledMethod) - handleVal.calledMethod = "" + handleVal = testHandlers{ + c: c, + } test.callParams.Handler = router httptesting.AssertJSONCall(c, test.callParams) c.Assert(handleVal.calledMethod, gc.Equals, test.calledMethod) + c.Assert(handleVal.p.PathPattern, gc.Equals, test.expectPathPattern) } } @@ -552,6 +567,7 @@ h.c.Check(p.Response, gc.Equals, h.p.Response) h.c.Check(p.Request, gc.Equals, h.p.Request) h.c.Check(p.PathVar, gc.DeepEquals, h.p.PathVar) + h.c.Check(p.PathPattern, gc.Equals, "/m1/:p") } func (h *testHandlers) M2(arg *struct { @@ -890,6 +906,7 @@ handler := errorMapper.HandleErrors(func(p httprequest.Params) error { c.Assert(p.Request, jc.DeepEquals, req) c.Assert(p.PathVar, jc.DeepEquals, params) + c.Assert(p.PathPattern, gc.Equals, "") return errUnauth }) rec := httptest.NewRecorder() @@ -905,6 +922,7 @@ handler = errorMapper.HandleErrors(func(p httprequest.Params) error { c.Assert(p.Request, jc.DeepEquals, req) c.Assert(p.PathVar, jc.DeepEquals, params) + c.Assert(p.PathPattern, gc.Equals, "") p.Response.WriteHeader(http.StatusCreated) p.Response.Write([]byte("something")) return nil @@ -956,6 +974,7 @@ handler := errorMapper.HandleJSON(func(p httprequest.Params) (interface{}, error) { c.Assert(p.Request, jc.DeepEquals, req) c.Assert(p.PathVar, jc.DeepEquals, params) + c.Assert(p.PathPattern, gc.Equals, "") return nil, errUnauth }) rec := httptest.NewRecorder() @@ -971,6 +990,7 @@ handler = errorMapper.HandleJSON(func(p httprequest.Params) (interface{}, error) { c.Assert(p.Request, jc.DeepEquals, req) c.Assert(p.PathVar, jc.DeepEquals, params) + c.Assert(p.PathPattern, gc.Equals, "") p.Response.Header().Set("Some-Header", "value") return "something", nil }) diff -Nru juju-core-2.0~beta6/src/github.com/juju/httprequest/type.go juju-core-2.0~beta7/src/github.com/juju/httprequest/type.go --- juju-core-2.0~beta6/src/github.com/juju/httprequest/type.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/httprequest/type.go 2016-05-17 20:01:14.000000000 +0000 @@ -38,6 +38,11 @@ Response http.ResponseWriter Request *http.Request PathVar httprouter.Params + // PathPattern holds the path pattern matched by httprouter. + // It is only set where httprequest has the information; + // that is where the call was made by ErrorMapper.Handler + // or ErrorMapper.Handlers. + PathPattern string } // resultMaker is provided to the unmarshal functions. diff -Nru juju-core-2.0~beta6/src/github.com/juju/httprequest/unmarshal_test.go juju-core-2.0~beta7/src/github.com/juju/httprequest/unmarshal_test.go --- juju-core-2.0~beta6/src/github.com/juju/httprequest/unmarshal_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/httprequest/unmarshal_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -133,22 +133,6 @@ }, }, }, { - about: "unexported embedded type for body works ok", - val: struct { - sFG `httprequest:",body"` - }{ - sFG: sFG{ - F: 99, - G: 100, - }, - }, - params: httprequest.Params{ - Request: &http.Request{ - Header: http.Header{"Content-Type": {"application/json"}}, - Body: body(`{"F": 99, "G": 100}`), - }, - }, -}, { about: "unexported type for body is ignored", val: struct { foo sFG `httprequest:",body"` diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/agent/agentbootstrap/bootstrap_test.go juju-core-2.0~beta7/src/github.com/juju/juju/agent/agentbootstrap/bootstrap_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/agent/agentbootstrap/bootstrap_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/agent/agentbootstrap/bootstrap_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -23,6 +23,7 @@ "github.com/juju/juju/environs/config" "github.com/juju/juju/instance" "github.com/juju/juju/mongo" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/network" "github.com/juju/juju/provider/dummy" "github.com/juju/juju/state" @@ -144,7 +145,7 @@ adminUser := names.NewLocalUserTag("agent-admin") st, m, err := agentbootstrap.InitializeState( adminUser, cfg, envCfg, hostedModelConfigAttrs, mcfg, - mongo.DefaultDialOpts(), environs.NewStatePolicy(), + mongotest.DialOpts(), environs.NewStatePolicy(), ) c.Assert(err, jc.ErrorIsNil) defer st.Close() @@ -232,7 +233,7 @@ info, ok := cfg.MongoInfo() c.Assert(ok, jc.IsTrue) c.Assert(info.Password, gc.Not(gc.Equals), testing.DefaultMongoPassword) - st1, err := state.Open(newCfg.Model(), info, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + st1, err := state.Open(newCfg.Model(), info, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st1.Close() } @@ -254,7 +255,7 @@ c.Assert(available, jc.IsFalse) adminUser := names.NewLocalUserTag("agent-admin") - _, _, err = agentbootstrap.InitializeState(adminUser, cfg, nil, nil, agentbootstrap.BootstrapMachineConfig{}, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + _, _, err = agentbootstrap.InitializeState(adminUser, cfg, nil, nil, agentbootstrap.BootstrapMachineConfig{}, mongotest.DialOpts(), environs.NewStatePolicy()) // InitializeState will fail attempting to get the api port information c.Assert(err, gc.ErrorMatches, "state serving information not available") } @@ -302,12 +303,12 @@ adminUser := names.NewLocalUserTag("agent-admin") st, _, err := agentbootstrap.InitializeState( adminUser, cfg, envCfg, hostedModelConfigAttrs, mcfg, - mongo.DefaultDialOpts(), state.Policy(nil), + mongotest.DialOpts(), state.Policy(nil), ) c.Assert(err, jc.ErrorIsNil) st.Close() - st, _, err = agentbootstrap.InitializeState(adminUser, cfg, envCfg, nil, mcfg, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + st, _, err = agentbootstrap.InitializeState(adminUser, cfg, envCfg, nil, mcfg, mongotest.DialOpts(), environs.NewStatePolicy()) if err == nil { st.Close() } @@ -351,7 +352,7 @@ Tag: nil, // admin user Password: password, } - st, err := state.Open(modelTag, info, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + st, err := state.Open(modelTag, info, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() _, err = st.Machine("0") diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/agent/machine_test.go juju-core-2.0~beta7/src/github.com/juju/juju/api/agent/machine_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/agent/machine_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/agent/machine_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -20,6 +20,7 @@ "github.com/juju/juju/environs" "github.com/juju/juju/juju/testing" "github.com/juju/juju/mongo" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/rpc" "github.com/juju/juju/state" "github.com/juju/juju/state/multiwatcher" @@ -180,7 +181,7 @@ } func tryOpenState(modelTag names.ModelTag, info *mongo.MongoInfo) error { - st, err := state.Open(modelTag, info, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + st, err := state.Open(modelTag, info, mongotest.DialOpts(), environs.NewStatePolicy()) if err == nil { st.Close() } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/apiclient.go juju-core-2.0~beta7/src/github.com/juju/juju/api/apiclient.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/apiclient.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/apiclient.go 2016-05-17 20:01:14.000000000 +0000 @@ -247,12 +247,12 @@ if len(info.Addrs) == 0 { return nil, nil, errors.New("no API addresses to connect to") } - tlsConfig := &tls.Config{ - // We want to be specific here (rather than just using "anything". - // See commit 7fc118f015d8480dfad7831788e4b8c0432205e8 (PR 899). - ServerName: "juju-apiserver", - InsecureSkipVerify: opts.InsecureSkipVerify, - } + tlsConfig := utils.SecureTLSConfig() + // We want to be specific here (rather than just using "anything". + // See commit 7fc118f015d8480dfad7831788e4b8c0432205e8 (PR 899). + tlsConfig.ServerName = "juju-apiserver" + tlsConfig.InsecureSkipVerify = opts.InsecureSkipVerify + if !tlsConfig.InsecureSkipVerify { certPool, err := CreateCertPool(info.CACert) if err != nil { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/backups/restore.go juju-core-2.0~beta7/src/github.com/juju/juju/api/backups/restore.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/backups/restore.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/backups/restore.go 2016-05-17 20:01:14.000000000 +0000 @@ -85,7 +85,7 @@ backupId, err := c.Upload(r, *meta) if err != nil { finishErr := finishRestore(newClient) - logger.Errorf("could not exit restoring status: %v", finishErr) + logger.Errorf("could not clean up after failed backup upload: %v", finishErr) return errors.Annotatef(err, "cannot upload backup file") } return c.restore(backupId, newClient) @@ -140,14 +140,14 @@ } if remoteError != nil || !isUpgradeInProgressErr(err) { finishErr := finishRestore(newClient) - logger.Errorf("could not exit restoring status: %v", finishErr) + logger.Errorf("could not clean up after failed restore attempt: %v", finishErr) return errors.Annotatef(err, "cannot perform restore: %v", remoteError) } } if !cleanExit { finishErr := finishRestore(newClient) if finishErr != nil { - logger.Errorf("could not exit restoring status: %v", finishErr) + logger.Errorf("could not clean up failed restore: %v", finishErr) } return errors.Annotatef(err, "cannot perform restore: %v", remoteError) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/client.go juju-core-2.0~beta7/src/github.com/juju/juju/api/client.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/client.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -24,6 +24,7 @@ "github.com/juju/juju/api/base" "github.com/juju/juju/apiserver/params" "github.com/juju/juju/constraints" + "github.com/juju/juju/downloader" "github.com/juju/juju/network" "github.com/juju/juju/tools" ) @@ -425,6 +426,53 @@ return urlInfo.URL, nil } +// OpenCharm streams out the identified charm from the controller via +// the API. +func (c *Client) OpenCharm(curl *charm.URL) (io.ReadCloser, error) { + // The returned httpClient sets the base url to /model/ if it can. + httpClient, err := c.st.HTTPClient() + if err != nil { + return nil, errors.Trace(err) + } + blob, err := openCharm(httpClient, curl) + if err != nil { + return nil, errors.Trace(err) + } + return blob, nil +} + +// openCharm streams out the identified charm from the controller via +// the API. +func openCharm(httpClient HTTPDoer, curl *charm.URL) (io.ReadCloser, error) { + query := make(url.Values) + query.Add("url", curl.String()) + query.Add("file", "*") + blob, err := openBlob(httpClient, "/charms", query) + if err != nil { + return nil, errors.Trace(err) + } + return blob, nil +} + +// NewCharmDownloader returns a new charm downloader that wraps the +// provided API client. +func NewCharmDownloader(client *Client) *downloader.Downloader { + dlr := &downloader.Downloader{ + OpenBlob: func(url *url.URL) (io.ReadCloser, error) { + curl, err := charm.ParseURL(url.String()) + if err != nil { + return nil, errors.Annotate(err, "did not receive a valid charm URL") + } + reader, err := client.OpenCharm(curl) + if err != nil { + return nil, errors.Trace(err) + } + return reader, nil + }, + } + return dlr +} + // UploadTools uploads tools at the specified location to the API server over HTTPS. func (c *Client) UploadTools(r io.ReadSeeker, vers version.Binary, additionalSeries ...string) (tools.List, error) { endpoint := fmt.Sprintf("/tools?binaryVersion=%s&series=%s", vers, strings.Join(additionalSeries, ",")) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/client_test.go juju-core-2.0~beta7/src/github.com/juju/juju/api/client_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/client_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/client_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -234,6 +234,38 @@ } } +func (s *clientSuite) TestOpenCharmFound(c *gc.C) { + client := s.APIState.Client() + curl, ch := addLocalCharm(c, client, "dummy") + expected, err := ioutil.ReadFile(ch.Path) + c.Assert(err, jc.ErrorIsNil) + + reader, err := client.OpenCharm(curl) + defer reader.Close() + c.Assert(err, jc.ErrorIsNil) + + data, err := ioutil.ReadAll(reader) + c.Assert(err, jc.ErrorIsNil) + c.Check(data, jc.DeepEquals, expected) +} + +func (s *clientSuite) TestOpenCharmMissing(c *gc.C) { + curl := charm.MustParseURL("cs:quantal/spam-3") + client := s.APIState.Client() + + _, err := client.OpenCharm(curl) + + c.Check(err, gc.ErrorMatches, `.*unable to retrieve and save the charm: cannot get charm from state: charm "cs:quantal/spam-3" not found`) +} + +func addLocalCharm(c *gc.C, client *api.Client, name string) (*charm.URL, *charm.CharmArchive) { + charmArchive := testcharms.Repo.CharmArchive(c.MkDir(), name) + curl := charm.MustParseURL(fmt.Sprintf("local:quantal/%s-%d", charmArchive.Meta().Name, charmArchive.Revision())) + _, err := client.AddLocalCharm(curl, charmArchive) + c.Assert(err, jc.ErrorIsNil) + return curl, charmArchive +} + func fakeAPIEndpoint(c *gc.C, client *api.Client, address, method string, handle func(http.ResponseWriter, *http.Request)) net.Listener { lis, err := net.Listen("tcp", "127.0.0.1:0") c.Assert(err, jc.ErrorIsNil) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/facadeversions.go juju-core-2.0~beta7/src/github.com/juju/juju/api/facadeversions.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/facadeversions.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/facadeversions.go 2016-05-17 20:01:14.000000000 +0000 @@ -70,6 +70,7 @@ "ServiceScaler": 1, "Singular": 1, "Spaces": 2, + "SSHClient": 1, "StatusHistory": 2, "Storage": 2, "StorageProvisioner": 2, diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/http.go juju-core-2.0~beta7/src/github.com/juju/juju/api/http.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/http.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/http.go 2016-05-17 20:01:14.000000000 +0000 @@ -187,3 +187,30 @@ }, } } + +// HTTPDoer exposes the functionality of httprequest.Client needed here. +type HTTPDoer interface { + // Do sends the given request. + Do(req *http.Request, body io.ReadSeeker, resp interface{}) error +} + +// openBlob streams the identified blob from the controller via the +// provided HTTP client. +func openBlob(httpClient HTTPDoer, endpoint string, args url.Values) (io.ReadCloser, error) { + apiURL, err := url.Parse(endpoint) + if err != nil { + return nil, errors.Trace(err) + } + apiURL.RawQuery = args.Encode() + + req, err := http.NewRequest("GET", apiURL.String(), nil) + if err != nil { + return nil, errors.Annotate(err, "cannot create HTTP request") + } + + var resp *http.Response + if err := httpClient.Do(req, nil, &resp); err != nil { + return nil, errors.Trace(err) + } + return resp.Body, nil +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/interface.go juju-core-2.0~beta7/src/github.com/juju/juju/api/interface.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/interface.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/interface.go 2016-05-17 20:01:14.000000000 +0000 @@ -180,6 +180,10 @@ // keeping it for now, but it's not apparently used anywhere else. AllFacadeVersions() map[string][]int + // AuthTag returns the tag of the authorized user of the state API + // connection. + AuthTag() names.Tag + // These methods expose a bunch of worker-specific facades, and basically // just should not exist; but removing them is too noisy for a single CL. // Client in particular is intimately coupled with State -- and the others diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/provisioner/provisioner_test.go juju-core-2.0~beta7/src/github.com/juju/juju/api/provisioner/provisioner_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/provisioner/provisioner_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/provisioner/provisioner_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -30,7 +30,7 @@ "github.com/juju/juju/feature" "github.com/juju/juju/instance" "github.com/juju/juju/juju/testing" - "github.com/juju/juju/mongo" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/network" "github.com/juju/juju/state" "github.com/juju/juju/status" @@ -585,7 +585,7 @@ func (s *provisionerSuite) TestContainerManagerConfigLXC(c *gc.C) { args := params.ContainerManagerConfigParams{Type: instance.LXC} - st, err := state.Open(s.State.ModelTag(), s.MongoInfo(c), mongo.DefaultDialOpts(), state.Policy(nil)) + st, err := state.Open(s.State.ModelTag(), s.MongoInfo(c), mongotest.DialOpts(), state.Policy(nil)) c.Assert(err, jc.ErrorIsNil) defer st.Close() diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/sshclient/facade.go juju-core-2.0~beta7/src/github.com/juju/juju/api/sshclient/facade.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/sshclient/facade.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/sshclient/facade.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,112 @@ +// Copyright 2016 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package sshclient + +import ( + "github.com/juju/errors" + "github.com/juju/names" + + "github.com/juju/juju/api/base" + "github.com/juju/juju/apiserver/params" +) + +// NewFacade returns a new Facade based on an existing API connection. +func NewFacade(caller base.APICaller) *Facade { + return &Facade{base.NewFacadeCaller(caller, "SSHClient")} +} + +type Facade struct { + caller base.FacadeCaller +} + +// PublicAddress returns the public address for the SSH target +// provided. The target may be provided as a machine ID or unit name. +func (facade *Facade) PublicAddress(target string) (string, error) { + addr, err := facade.addressCall("PublicAddress", target) + return addr, errors.Trace(err) +} + +// PrivateAddress returns the private address for the SSH target +// provided. The target may be provided as a machine ID or unit name. +func (facade *Facade) PrivateAddress(target string) (string, error) { + addr, err := facade.addressCall("PrivateAddress", target) + return addr, errors.Trace(err) +} + +func (facade *Facade) addressCall(callName, target string) (string, error) { + entities, err := targetToEntities(target) + if err != nil { + return "", errors.Trace(err) + } + var out params.SSHAddressResults + err = facade.caller.FacadeCall(callName, entities, &out) + if err != nil { + return "", errors.Trace(err) + } + if len(out.Results) != 1 { + return "", countError(len(out.Results)) + } + if err := out.Results[0].Error; err != nil { + return "", errors.Trace(err) + } + return out.Results[0].Address, nil +} + +// PublicKeys returns the SSH public host keys for the SSH target +// provided. The target may be provided as a machine ID or unit name. +func (facade *Facade) PublicKeys(target string) ([]string, error) { + entities, err := targetToEntities(target) + if err != nil { + return nil, errors.Trace(err) + } + var out params.SSHPublicKeysResults + err = facade.caller.FacadeCall("PublicKeys", entities, &out) + if err != nil { + return nil, errors.Trace(err) + } + if len(out.Results) != 1 { + return nil, countError(len(out.Results)) + } + if err := out.Results[0].Error; err != nil { + return nil, errors.Trace(err) + } + return out.Results[0].PublicKeys, nil +} + +// Proxy returns whether SSH connections should be proxied through the +// controller hosts for the associated model. +func (facade *Facade) Proxy() (bool, error) { + var out params.SSHProxyResult + err := facade.caller.FacadeCall("Proxy", nil, &out) + if err != nil { + return false, errors.Trace(err) + } + return out.UseProxy, nil +} + +func targetToEntities(target string) (params.Entities, error) { + tag, err := targetToTag(target) + if err != nil { + return params.Entities{}, errors.Trace(err) + } + return params.Entities{ + Entities: []params.Entity{{Tag: tag.String()}}, + }, nil +} + +func targetToTag(target string) (names.Tag, error) { + switch { + case names.IsValidMachine(target): + return names.NewMachineTag(target), nil + case names.IsValidUnit(target): + return names.NewUnitTag(target), nil + default: + return nil, errors.NotValidf("target %q", target) + } +} + +// countError complains about malformed results. +func countError(count int) error { + return errors.Errorf("expected 1 result, got %d", count) +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/sshclient/facade_test.go juju-core-2.0~beta7/src/github.com/juju/juju/api/sshclient/facade_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/sshclient/facade_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/sshclient/facade_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,225 @@ +// Copyright 2016 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package sshclient_test + +import ( + "github.com/juju/errors" + "github.com/juju/names" + jujutesting "github.com/juju/testing" + jc "github.com/juju/testing/checkers" + gc "gopkg.in/check.v1" + + apitesting "github.com/juju/juju/api/base/testing" + "github.com/juju/juju/api/sshclient" + "github.com/juju/juju/apiserver/common" + "github.com/juju/juju/apiserver/params" +) + +type FacadeSuite struct { + jujutesting.IsolationSuite +} + +var _ = gc.Suite(&FacadeSuite{}) + +func (s *FacadeSuite) TestAddress(c *gc.C) { + var stub jujutesting.Stub + apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { + stub.AddCall(objType+"."+request, arg) + c.Check(id, gc.Equals, "") + *result.(*params.SSHAddressResults) = params.SSHAddressResults{ + Results: []params.SSHAddressResult{{Address: "1.1.1.1"}}, + } + return nil + }) + facade := sshclient.NewFacade(apiCaller) + expectedArg := []interface{}{params.Entities{[]params.Entity{{ + names.NewUnitTag("foo/0").String(), + }}}} + + public, err := facade.PublicAddress("foo/0") + c.Assert(err, jc.ErrorIsNil) + c.Check(public, gc.Equals, "1.1.1.1") + stub.CheckCalls(c, []jujutesting.StubCall{{"SSHClient.PublicAddress", expectedArg}}) + stub.ResetCalls() + + private, err := facade.PrivateAddress("foo/0") + c.Assert(err, jc.ErrorIsNil) + c.Check(private, gc.Equals, "1.1.1.1") + stub.CheckCalls(c, []jujutesting.StubCall{{"SSHClient.PrivateAddress", expectedArg}}) +} + +func (s *FacadeSuite) TestAddressError(c *gc.C) { + apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { + return errors.New("boom") + }) + facade := sshclient.NewFacade(apiCaller) + + public, err := facade.PublicAddress("foo/0") + c.Check(public, gc.Equals, "") + c.Check(err, gc.ErrorMatches, "boom") + + private, err := facade.PrivateAddress("foo/0") + c.Check(private, gc.Equals, "") + c.Check(err, gc.ErrorMatches, "boom") +} + +func (s *FacadeSuite) TestAddressTargetError(c *gc.C) { + apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { + *result.(*params.SSHAddressResults) = params.SSHAddressResults{ + Results: []params.SSHAddressResult{{Error: common.ServerError(errors.New("boom"))}}, + } + return nil + }) + facade := sshclient.NewFacade(apiCaller) + + public, err := facade.PublicAddress("foo/0") + c.Check(public, gc.Equals, "") + c.Check(err, gc.ErrorMatches, "boom") + + private, err := facade.PrivateAddress("foo/0") + c.Check(private, gc.Equals, "") + c.Check(err, gc.ErrorMatches, "boom") +} + +func (s *FacadeSuite) TestAddressMissingResults(c *gc.C) { + apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { + return nil + }) + facade := sshclient.NewFacade(apiCaller) + expectedErr := "expected 1 result, got 0" + + public, err := facade.PublicAddress("foo/0") + c.Check(public, gc.Equals, "") + c.Check(err, gc.ErrorMatches, expectedErr) + + private, err := facade.PrivateAddress("foo/0") + c.Check(private, gc.Equals, "") + c.Check(err, gc.ErrorMatches, expectedErr) +} + +func (s *FacadeSuite) TestAddressExtraResults(c *gc.C) { + apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { + *result.(*params.SSHAddressResults) = params.SSHAddressResults{ + Results: []params.SSHAddressResult{ + {Address: "1.1.1.1"}, + {Address: "2.2.2.2"}, + }, + } + return nil + }) + facade := sshclient.NewFacade(apiCaller) + expectedErr := "expected 1 result, got 2" + + public, err := facade.PublicAddress("foo/0") + c.Check(public, gc.Equals, "") + c.Check(err, gc.ErrorMatches, expectedErr) + + private, err := facade.PrivateAddress("foo/0") + c.Check(private, gc.Equals, "") + c.Check(err, gc.ErrorMatches, expectedErr) +} + +func (s *FacadeSuite) TestPublicKeys(c *gc.C) { + var stub jujutesting.Stub + apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { + stub.AddCall(objType+"."+request, arg) + c.Check(id, gc.Equals, "") + *result.(*params.SSHPublicKeysResults) = params.SSHPublicKeysResults{ + Results: []params.SSHPublicKeysResult{{PublicKeys: []string{"rsa", "dsa"}}}, + } + return nil + }) + facade := sshclient.NewFacade(apiCaller) + keys, err := facade.PublicKeys("foo/0") + c.Assert(err, jc.ErrorIsNil) + c.Check(keys, gc.DeepEquals, []string{"rsa", "dsa"}) + stub.CheckCalls(c, []jujutesting.StubCall{{ + "SSHClient.PublicKeys", + []interface{}{params.Entities{[]params.Entity{{ + Tag: names.NewUnitTag("foo/0").String(), + }}}}, + }}) +} + +func (s *FacadeSuite) TestPublicKeysError(c *gc.C) { + apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { + return errors.New("boom") + }) + facade := sshclient.NewFacade(apiCaller) + keys, err := facade.PublicKeys("foo/0") + c.Check(keys, gc.IsNil) + c.Check(err, gc.ErrorMatches, "boom") +} + +func (s *FacadeSuite) TestPublicKeysTargetError(c *gc.C) { + var stub jujutesting.Stub + apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { + stub.AddCall(objType+"."+request, arg) + c.Check(id, gc.Equals, "") + *result.(*params.SSHPublicKeysResults) = params.SSHPublicKeysResults{ + Results: []params.SSHPublicKeysResult{{Error: common.ServerError(errors.New("boom"))}}, + } + return nil + }) + facade := sshclient.NewFacade(apiCaller) + keys, err := facade.PublicKeys("foo/0") + c.Check(keys, gc.IsNil) + c.Check(err, gc.ErrorMatches, "boom") +} + +func (s *FacadeSuite) TestPublicKeysMissingResults(c *gc.C) { + apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { + return nil + }) + facade := sshclient.NewFacade(apiCaller) + keys, err := facade.PublicKeys("foo/0") + c.Check(keys, gc.IsNil) + c.Check(err, gc.ErrorMatches, "expected 1 result, got 0") +} + +func (s *FacadeSuite) TestPublicKeysExtraResults(c *gc.C) { + apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { + *result.(*params.SSHPublicKeysResults) = params.SSHPublicKeysResults{ + Results: []params.SSHPublicKeysResult{ + {PublicKeys: []string{"rsa"}}, + {PublicKeys: []string{"rsa"}}, + }, + } + return nil + }) + facade := sshclient.NewFacade(apiCaller) + keys, err := facade.PublicKeys("foo/0") + c.Check(keys, gc.IsNil) + c.Check(err, gc.ErrorMatches, "expected 1 result, got 2") +} + +func (s *FacadeSuite) TestProxy(c *gc.C) { + checkProxy(c, true) + checkProxy(c, false) +} + +func checkProxy(c *gc.C, useProxy bool) { + var stub jujutesting.Stub + apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { + stub.AddCall(objType+"."+request, arg) + *result.(*params.SSHProxyResult) = params.SSHProxyResult{ + UseProxy: useProxy, + } + return nil + }) + facade := sshclient.NewFacade(apiCaller) + result, err := facade.Proxy() + c.Check(err, jc.ErrorIsNil) + c.Check(result, gc.Equals, useProxy) + stub.CheckCalls(c, []jujutesting.StubCall{{"SSHClient.Proxy", []interface{}{nil}}}) +} + +func (s *FacadeSuite) TestProxyError(c *gc.C) { + apiCaller := apitesting.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error { + return errors.New("boom") + }) + facade := sshclient.NewFacade(apiCaller) + _, err := facade.Proxy() + c.Check(err, gc.ErrorMatches, "boom") +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/sshclient/package_test.go juju-core-2.0~beta7/src/github.com/juju/juju/api/sshclient/package_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/sshclient/package_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/sshclient/package_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,14 @@ +// Copyright 2016 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package sshclient_test + +import ( + "testing" + + gc "gopkg.in/check.v1" +) + +func TestPackage(t *testing.T) { + gc.TestingT(t) +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/state.go juju-core-2.0~beta7/src/github.com/juju/juju/api/state.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/state.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/state.go 2016-05-17 20:01:14.000000000 +0000 @@ -98,6 +98,13 @@ } } + if result.UserInfo != nil { + // This was a macaroon based user authentication. + tag, err = names.ParseTag(result.UserInfo.Identity) + if err != nil { + return errors.Trace(err) + } + } servers := params.NetworkHostsPorts(result.Servers) err = st.setLoginResult(tag, result.ModelTag, result.ControllerTag, servers, result.Facades) if err != nil { @@ -133,6 +140,11 @@ return nil } +// AuthTag returns the tag of the authorized user of the state API connection. +func (st *state) AuthTag() names.Tag { + return st.authTag +} + // slideAddressToFront moves the address at the location (serverIndex, addrIndex) to be // the first address of the first server. func slideAddressToFront(servers [][]network.HostPort, serverIndex, addrIndex int) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/state_test.go juju-core-2.0~beta7/src/github.com/juju/juju/api/state_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/state_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/state_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -107,6 +107,7 @@ c.Assert(err, jc.ErrorIsNil) err = apistate.Login(tag, "", "", []macaroon.Slice{{mac}}) c.Assert(err, jc.ErrorIsNil) + c.Assert(apistate.AuthTag(), gc.Equals, tag) } func (s *stateSuite) TestLoginMacaroonInvalidId(c *gc.C) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/uniter/charm.go juju-core-2.0~beta7/src/github.com/juju/juju/api/uniter/charm.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/uniter/charm.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/uniter/charm.go 2016-05-17 20:01:14.000000000 +0000 @@ -5,9 +5,7 @@ import ( "fmt" - "net/url" - "github.com/juju/errors" "gopkg.in/juju/charm.v6-unstable" "github.com/juju/juju/apiserver/params" @@ -32,35 +30,6 @@ return c.curl } -// ArchiveURLs returns the URLs to the charm archive (bundle) in the -// model storage. Each URL should be tried until one succeeds. -func (c *Charm) ArchiveURLs() ([]*url.URL, error) { - var results params.StringsResults - args := params.CharmURLs{ - URLs: []params.CharmURL{{URL: c.curl.String()}}, - } - err := c.st.facade.FacadeCall("CharmArchiveURLs", args, &results) - if err != nil { - return nil, err - } - if len(results.Results) != 1 { - return nil, fmt.Errorf("expected 1 result, got %d", len(results.Results)) - } - result := results.Results[0] - if result.Error != nil { - return nil, result.Error - } - archiveURLs := make([]*url.URL, len(result.Result)) - for i, rawurl := range result.Result { - archiveURL, err := url.Parse(rawurl) - if err != nil { - return nil, errors.Annotate(err, "server returned an invalid URL") - } - archiveURLs[i] = archiveURL - } - return archiveURLs, nil -} - // ArchiveSha256 returns the SHA256 digest of the charm archive // (bundle) bytes. // diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/api/uniter/charm_test.go juju-core-2.0~beta7/src/github.com/juju/juju/api/uniter/charm_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/api/uniter/charm_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/api/uniter/charm_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,9 +4,6 @@ package uniter_test import ( - "fmt" - "net/url" - jc "github.com/juju/testing/checkers" gc "gopkg.in/check.v1" @@ -47,21 +44,6 @@ c.Assert(s.apiCharm.URL(), gc.DeepEquals, s.wordpressCharm.URL()) } -func (s *charmSuite) TestArchiveURLs(c *gc.C) { - apiInfo := s.APIInfo(c) - url, err := url.Parse(fmt.Sprintf( - "https://0.1.2.3:1234/model/%s/charms?file=%s&url=%s", - apiInfo.ModelTag.Id(), - url.QueryEscape("*"), - url.QueryEscape(s.apiCharm.URL().String()), - )) - c.Assert(err, jc.ErrorIsNil) - archiveURLs, err := s.apiCharm.ArchiveURLs() - c.Assert(err, jc.ErrorIsNil) - c.Assert(archiveURLs, gc.HasLen, 1) - c.Assert(archiveURLs[0], gc.DeepEquals, url) -} - func (s *charmSuite) TestArchiveSha256(c *gc.C) { archiveSha256, err := s.apiCharm.ArchiveSha256() c.Assert(err, jc.ErrorIsNil) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/admin.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/admin.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/admin.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/admin.go 2016-05-17 20:01:14.000000000 +0000 @@ -71,17 +71,20 @@ } var agentPingerNeeded = true - var isUser bool - kind, err := names.TagKind(req.AuthTag) - if err != nil || kind != names.UserTagKind { - // Users are not rate limited, all other entities are - if !a.srv.limiter.Acquire() { - logger.Debugf("rate limiting for agent %s", req.AuthTag) - return fail, common.ErrTryAgain + isUser := true + kind := names.UserTagKind + if req.AuthTag != "" { + var err error + kind, err = names.TagKind(req.AuthTag) + if err != nil || kind != names.UserTagKind { + isUser = false + // Users are not rate limited, all other entities are. + if !a.srv.limiter.Acquire() { + logger.Debugf("rate limiting for agent %s", req.AuthTag) + return fail, common.ErrTryAgain + } + defer a.srv.limiter.Release() } - defer a.srv.limiter.Release() - } else { - isUser = true } serverOnlyLogin := a.root.modelUUID == "" diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/admin_test.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/admin_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/admin_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/admin_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -847,7 +847,10 @@ } client, err := api.Open(s.APIInfo(c), api.DialOpts{}) c.Assert(err, jc.ErrorIsNil) - client.Close() + defer client.Close() + + // The auth tag has been correctly returned by the server. + c.Assert(client.AuthTag(), gc.Equals, names.NewUserTag("test@somewhere")) } func (s *macaroonLoginSuite) TestFailedToObtainDischargeLogin(c *gc.C) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/allfacades.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/allfacades.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/allfacades.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/allfacades.go 2016-05-17 20:01:14.000000000 +0000 @@ -56,6 +56,7 @@ _ "github.com/juju/juju/apiserver/servicescaler" _ "github.com/juju/juju/apiserver/singular" _ "github.com/juju/juju/apiserver/spaces" + _ "github.com/juju/juju/apiserver/sshclient" _ "github.com/juju/juju/apiserver/statushistory" _ "github.com/juju/juju/apiserver/storage" _ "github.com/juju/juju/apiserver/storageprovisioner" diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/apiserver.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/apiserver.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/apiserver.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/apiserver.go 2016-05-17 20:01:14.000000000 +0000 @@ -187,10 +187,8 @@ } // TODO(rog) check that *srvRoot is a valid type for using // as an RPC server. - tlsConfig := &tls.Config{ - Certificates: []tls.Certificate{tlsCert}, - MinVersion: tls.VersionTLS10, - } + tlsConfig := utils.SecureTLSConfig() + tlsConfig.Certificates = []tls.Certificate{tlsCert} stPool := cfg.StatePool if stPool == nil { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/authhttp_test.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/authhttp_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/authhttp_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/authhttp_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -5,7 +5,6 @@ import ( "bufio" - "crypto/tls" "crypto/x509" "encoding/json" "io" @@ -108,7 +107,9 @@ config.Header = header caCerts := x509.NewCertPool() c.Assert(caCerts.AppendCertsFromPEM([]byte(testing.CACert)), jc.IsTrue) - config.TlsConfig = &tls.Config{RootCAs: caCerts, ServerName: "anything"} + config.TlsConfig = utils.SecureTLSConfig() + config.TlsConfig.RootCAs = caCerts + config.TlsConfig.ServerName = "anything" return config } @@ -207,9 +208,9 @@ bclient.Client = client } else { // Configure the default client to skip verification/ - bclient.Client.Transport = utils.NewHttpTLSTransport(&tls.Config{ - InsecureSkipVerify: true, - }) + tlsConfig := utils.SecureTLSConfig() + tlsConfig.InsecureSkipVerify = true + bclient.Client.Transport = utils.NewHttpTLSTransport(tlsConfig) } return func(req *http.Request) (*http.Response, error) { var body io.ReadSeeker diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/backups/restore.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/backups/restore.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/backups/restore.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/backups/restore.go 2016-05-17 20:01:14.000000000 +0000 @@ -44,10 +44,7 @@ } - info, err := a.st.RestoreInfoSetter() - if err != nil { - return errors.Trace(err) - } + info := a.st.RestoreInfo() // Signal to current state and api server that restore will begin err = info.SetStatus(state.RestoreInProgress) if err != nil { @@ -102,29 +99,37 @@ // After restoring, the api server needs a forced restart, tomb will not work // this is because we change all of juju configuration files and mongo too. // Exiting with 0 would prevent upstart to respawn the process + + // NOTE(fwereade): the apiserver needs to be restarted, yes, but + // this approach is completely broken. The only place it's ever + // ok to use os.Exit is in a main() func that's *so* simple as to + // be reasonably left untested. + // + // And passing os.Exit in wouldn't make this any better either, + // just using it subverts the expectations of *everything* else + // running in the process. os.Exit(1) return nil } // PrepareRestore implements the server side of Backups.PrepareRestore. func (a *API) PrepareRestore() error { - info, err := a.st.RestoreInfoSetter() - if err != nil { - return errors.Trace(err) - } + info := a.st.RestoreInfo() logger.Infof("entering restore preparation mode") return info.SetStatus(state.RestorePending) } // FinishRestore implements the server side of Backups.FinishRestore. func (a *API) FinishRestore() error { - info, err := a.st.RestoreInfoSetter() + info := a.st.RestoreInfo() + currentStatus, err := info.Status() if err != nil { return errors.Trace(err) } - currentStatus := info.Status() if currentStatus != state.RestoreFinished { - info.SetStatus(state.RestoreFailed) + if err := info.SetStatus(state.RestoreFailed); err != nil { + return errors.Trace(err) + } return errors.Errorf("Restore did not finish succesfuly") } logger.Infof("Succesfully restored") diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/charms.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/charms.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/charms.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/charms.go 2016-05-17 20:01:14.000000000 +0000 @@ -72,8 +72,7 @@ } func (h *charmsHandler) serveGet(w http.ResponseWriter, r *http.Request) error { - // TODO (bug #1499338 2015/09/24) authenticate this. - st, err := h.ctxt.stateForRequestUnauthenticated(r) + st, _, err := h.ctxt.stateForRequestAuthenticated(r) if err != nil { return errors.Trace(err) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/charms_test.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/charms_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/charms_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/charms_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -111,9 +111,9 @@ s.assertErrorResponse(c, resp, http.StatusUnauthorized, "no credentials provided") } -func (s *charmsSuite) TestGETDoesNotRequireAuth(c *gc.C) { +func (s *charmsSuite) TestGETRequiresAuth(c *gc.C) { resp := s.sendRequest(c, httpRequestParams{method: "GET", url: s.charmsURI(c, "")}) - s.assertErrorResponse(c, resp, http.StatusBadRequest, "expected url=CharmURL query argument") + s.assertErrorResponse(c, resp, http.StatusUnauthorized, "no credentials provided") } func (s *charmsSuite) TestRequiresPOSTorGET(c *gc.C) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/client/client_test.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/client/client_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/client/client_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/client/client_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -13,6 +13,7 @@ "github.com/juju/errors" "github.com/juju/names" jc "github.com/juju/testing/checkers" + "github.com/juju/utils/series" "github.com/juju/version" gc "gopkg.in/check.v1" "gopkg.in/juju/charm.v6-unstable" @@ -980,7 +981,7 @@ c.Assert(len(machines), gc.Equals, 3) for i, machineResult := range machines { c.Assert(machineResult.Machine, gc.DeepEquals, strconv.Itoa(i)) - s.checkMachine(c, machineResult.Machine, coretesting.FakeDefaultSeries, apiParams[i].Constraints.String()) + s.checkMachine(c, machineResult.Machine, series.LatestLts(), apiParams[i].Constraints.String()) } } @@ -996,7 +997,7 @@ c.Assert(len(machines), gc.Equals, 3) for i, machineResult := range machines { c.Assert(machineResult.Machine, gc.DeepEquals, strconv.Itoa(i)) - s.checkMachine(c, machineResult.Machine, coretesting.FakeDefaultSeries, apiParams[i].Constraints.String()) + s.checkMachine(c, machineResult.Machine, series.LatestLts(), apiParams[i].Constraints.String()) } } @@ -1079,7 +1080,7 @@ c.Assert(len(machines), gc.Equals, 3) for i, machineResult := range machines { c.Assert(machineResult.Machine, gc.DeepEquals, strconv.Itoa(i)) - s.checkMachine(c, machineResult.Machine, coretesting.FakeDefaultSeries, apiParams[i].Constraints.String()) + s.checkMachine(c, machineResult.Machine, series.LatestLts(), apiParams[i].Constraints.String()) } } @@ -1169,7 +1170,7 @@ c.Assert(machineResult.Error, gc.ErrorMatches, "cannot add a new machine: cannot add a machine with an instance id and no nonce") } else { c.Assert(machineResult.Machine, gc.DeepEquals, strconv.Itoa(i)) - s.checkMachine(c, machineResult.Machine, coretesting.FakeDefaultSeries, apiParams[i].Constraints.String()) + s.checkMachine(c, machineResult.Machine, series.LatestLts(), apiParams[i].Constraints.String()) instanceId := fmt.Sprintf("1234-%d", i) s.checkInstance(c, machineResult.Machine, instanceId, "foo", hc, addrs) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/deployer/deployer.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/deployer/deployer.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/deployer/deployer.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/deployer/deployer.go 2016-05-17 20:01:14.000000000 +0000 @@ -78,13 +78,21 @@ // ConnectionInfo returns all the address information that the // deployer task needs in one call. func (d *DeployerAPI) ConnectionInfo() (result params.DeployerConnectionValues, err error) { - info, err := d.st.DeployerConnectionInfo() - if info != nil { - result = params.DeployerConnectionValues{ - StateAddresses: info.StateAddresses, - APIAddresses: info.APIAddresses, - } + stateAddrs, err := d.StateAddresses() + if err != nil { + return result, err } + + apiAddrs, err := d.APIAddresses() + if err != nil { + return result, err + } + + result = params.DeployerConnectionValues{ + StateAddresses: stateAddrs.Result, + APIAddresses: apiAddrs.Result, + } + return result, err } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/deployer/deployer_test.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/deployer/deployer_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/deployer/deployer_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/deployer/deployer_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -332,3 +332,25 @@ Result: []byte(s.State.CACert()), }) } + +func (s *deployerSuite) TestConnectionInfo(c *gc.C) { + err := s.machine0.SetProviderAddresses(network.NewScopedAddress("0.1.2.3", network.ScopePublic), + network.NewScopedAddress("1.2.3.4", network.ScopeCloudLocal)) + c.Assert(err, jc.ErrorIsNil) + + // Default host port scope is public, so change the cloud-local one + hostPorts := network.NewHostPorts(1234, "0.1.2.3", "1.2.3.4") + hostPorts[1].Scope = network.ScopeCloudLocal + + err = s.State.SetAPIHostPorts([][]network.HostPort{hostPorts}) + c.Assert(err, jc.ErrorIsNil) + + expected := params.DeployerConnectionValues{ + StateAddresses: []string{"1.2.3.4:1234"}, + APIAddresses: []string{"1.2.3.4:1234", "0.1.2.3:1234"}, + } + + result, err := s.deployer.ConnectionInfo() + c.Assert(err, jc.ErrorIsNil) + c.Assert(result, gc.DeepEquals, expected) +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/imagemetadata/functions_test.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/imagemetadata/functions_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/imagemetadata/functions_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/imagemetadata/functions_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -7,12 +7,12 @@ "fmt" jc "github.com/juju/testing/checkers" + "github.com/juju/utils/series" gc "gopkg.in/check.v1" "github.com/juju/juju/apiserver/imagemetadata" "github.com/juju/juju/apiserver/params" "github.com/juju/juju/environs" - "github.com/juju/juju/environs/config" envtesting "github.com/juju/juju/environs/testing" "github.com/juju/juju/jujuclient/jujuclienttesting" "github.com/juju/juju/state/cloudimagemetadata" @@ -48,7 +48,7 @@ cloudimagemetadata.MetadataAttributes{ Stream: "released", Source: "custom", - Series: config.LatestLtsSeries(), + Series: series.LatestLts(), Arch: "amd64", Region: "dummy_region", }, diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/modelmanager/modelinfo_test.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/modelmanager/modelinfo_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/modelmanager/modelinfo_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/modelmanager/modelinfo_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -10,6 +10,7 @@ "github.com/juju/names" gitjujutesting "github.com/juju/testing" jc "github.com/juju/testing/checkers" + "github.com/juju/utils/series" gc "gopkg.in/check.v1" "github.com/juju/juju/apiserver/common" @@ -83,7 +84,7 @@ ControllerUUID: coretesting.ModelTag.Id(), OwnerTag: "user-bob@local", ProviderType: "someprovider", - DefaultSeries: coretesting.FakeDefaultSeries, + DefaultSeries: series.LatestLts(), Life: params.Dying, Status: params.EntityStatus{ Status: status.StatusDestroying, diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/params/ssh.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/params/ssh.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/params/ssh.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/params/ssh.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,3 +14,34 @@ Tag string `json:"tag"` PublicKeys []string `json:"public-keys"` } + +// SSHProxyResult defines the response from the SSHClient.Proxy API. +type SSHProxyResult struct { + UseProxy bool `json:"use-proxy"` +} + +// SSHAddressResults defines the response from various APIs on the +// SSHClient facade. +type SSHAddressResults struct { + Results []SSHAddressResult `json:"results"` +} + +// SSHAddressResult defines a single SSH address result (see +// SSHAddressResults). +type SSHAddressResult struct { + Error *Error `json:"error,omitempty"` + Address string `json:"address,omitempty"` +} + +// SSHPublicKeysResults is used to return SSH public host keys for one +// or more target for the SSHClient.PublicKeys API. +type SSHPublicKeysResults struct { + Results []SSHPublicKeysResult `json:"results"` +} + +// SSHPublicKeysResult is used to return the SSH public host keys for +// one SSH target (see SSHPublicKeysResults). +type SSHPublicKeysResult struct { + Error *Error `json:"error,omitempty"` + PublicKeys []string `json:"public-keys,omitempty"` +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/presence/pinger.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/presence/pinger.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/presence/pinger.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/presence/pinger.go 2016-05-17 20:01:14.000000000 +0000 @@ -74,35 +74,31 @@ } name := fmt.Sprintf("juju.apiserver.presence.%s", config.Identity) w := &Worker{ - config: config, - logger: loggo.GetLogger(name), + config: config, + logger: loggo.GetLogger(name), + running: make(chan struct{}), } - ready := make(chan struct{}) - // We make a copy of the variable so we can observe it being closed, - // while the worker function itself wants to change the variable to - // 'nil' so that it doesn't close it twice. - // See https://pad.lv/1574632 - readyCopy := ready err := catacomb.Invoke(catacomb.Plan{ Site: &w.catacomb, - Work: func() error { - // Run once to prime presence before diving into the loop. - pinger := w.startPinger() - if ready != nil { - close(ready) - ready = nil - } - if pinger != nil { - w.waitOnPinger(pinger) - } - return w.loop() - }, + Work: w.loop, }) if err != nil { return nil, errors.Trace(err) } - <-readyCopy - return w, nil + + // To support unhappy assumptions in apiserver/server_test.go, + // we block New until at least one attempt to start a Pinger + // has been made. This preserves the apparent behaviour of an + // unwrapped Pinger under normal conditions. + select { + case <-w.catacomb.Dying(): + if err := w.Wait(); err != nil { + return nil, errors.Trace(err) + } + return nil, errors.New("worker stopped abnormally without reporting an error") + case <-w.running: + return w, nil + } } // Worker creates a Pinger as configured, and recreates it as it fails @@ -112,6 +108,7 @@ catacomb catacomb.Catacomb config Config logger loggo.Logger + running chan struct{} } // Kill is part of the worker.Worker interface. @@ -135,53 +132,77 @@ // loop runs Pingers until w is stopped. func (w *Worker) loop() error { var delay time.Duration - clock := w.config.Clock for { select { case <-w.catacomb.Dying(): return w.catacomb.ErrDying() - case <-clock.After(delay): - delay = 0 - pinger := w.startPinger() - if pinger == nil { - // Failed to start. - delay = w.config.RetryDelay - continue - } - w.waitOnPinger(pinger) + case <-w.config.Clock.After(delay): + maybePinger := w.maybeStartPinger() + w.reportRunning() + w.waitPinger(maybePinger) } + delay = w.config.RetryDelay } } -// startPinger starts a single Pinger. It returns nil if the pinger -// could not be started. -func (w *Worker) startPinger() Pinger { - w.logger.Debugf("starting pinger...") +// maybeStartPinger starts and returns a new Pinger; or, if it +// encounters an error, logs it and returns nil. +func (w *Worker) maybeStartPinger() Pinger { + w.logger.Tracef("starting pinger...") pinger, err := w.config.Start() if err != nil { - w.logger.Errorf("pinger failed to start: %v", err) + w.logger.Errorf("cannot start pinger: %v", err) return nil } - w.logger.Debugf("pinger started") + w.logger.Tracef("pinger started") return pinger } -// waitOnPinger waits indefinitely for the given Pinger to complete, -// stopping it only when the Worker is Kill()ed. -func (w *Worker) waitOnPinger(pinger Pinger) { - // Start a goroutine that waits for the Worker to be stopped, - // and then stops the Pinger. Note also that we ignore errors - // out of Stop(): they will be caught by the Pinger anyway, and - // we'll see them come out of Wait() below. +// reportRunning is a foul hack designed to delay apparent worker start +// until at least one ping has been delivered (or attempted). It only +// exists to make various distant tests, which should ideally not be +// depending on these implementation details, reliable. +func (w *Worker) reportRunning() { + select { + case <-w.running: + default: + close(w.running) + } +} + +// waitPinger waits for the death of either the pinger or the worker; +// stops the pinger if necessary; and returns once the pinger is +// finished. If pinger is nil, it returns immediately. +func (w *Worker) waitPinger(pinger Pinger) { + if pinger == nil { + return + } + + // Set up a channel that will last as long as this method call. + done := make(chan struct{}) + defer close(done) + + // Start a goroutine to stop the Pinger if the worker is killed. + // If the enclosing method completes, we know that the Pinger + // has already stopped, and we can return immediately. + // + // Note that we ignore errors out of Stop(), depending on the + // Pinger to manage errors properly and report them via Wait() + // below. go func() { - <-w.catacomb.Dying() - pinger.Stop() + select { + case <-done: + case <-w.catacomb.Dying(): + w.logger.Tracef("stopping pinger") + pinger.Stop() + } }() // Now, just wait for the Pinger to stop. It might be caused by // the Worker's death, or it might have failed on its own; in // any case, errors are worth recording, but we don't need to // respond in any way because that's loop()'s responsibility. + w.logger.Tracef("waiting for pinger...") if err := pinger.Wait(); err != nil { w.logger.Errorf("pinger failed: %v", err) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/presence/pinger_test.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/presence/pinger_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/presence/pinger_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/presence/pinger_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -7,323 +7,171 @@ "time" "github.com/juju/errors" - "github.com/juju/names" "github.com/juju/testing" jc "github.com/juju/testing/checkers" - "github.com/juju/utils/clock" gc "gopkg.in/check.v1" "github.com/juju/juju/apiserver/presence" - coretesting "github.com/juju/juju/testing" "github.com/juju/juju/worker/workertest" ) type WorkerSuite struct { testing.IsolationSuite - - stub *testing.Stub - pinger *stubPinger - clock *stubClock - cfg presence.Config } var _ = gc.Suite(&WorkerSuite{}) -func (s *WorkerSuite) SetUpTest(c *gc.C) { - s.IsolationSuite.SetUpTest(c) - - s.stub = &testing.Stub{} - s.pinger = &stubPinger{Stub: s.stub} - s.clock = &stubClock{StubClock: coretesting.NewStubClock(s.stub)} - s.cfg = presence.Config{ - Identity: names.NewMachineTag("1"), - Start: s.start, - Clock: s.clock, - RetryDelay: time.Nanosecond, - } -} - -func (s *WorkerSuite) start() (presence.Pinger, error) { - s.stub.AddCall("start") - if err := s.stub.NextErr(); err != nil { - return nil, errors.Trace(err) - } - return s.pinger, nil -} - func (s *WorkerSuite) TestConfigValidateOkay(c *gc.C) { - cfg := presence.Config{ - Identity: names.NewMachineTag("1"), - Start: func() (presence.Pinger, error) { return nil, nil }, - Clock: struct{ clock.Clock }{}, - RetryDelay: time.Second, - } - - err := cfg.Validate() - + err := validConfig().Validate() c.Check(err, jc.ErrorIsNil) } -func (s *WorkerSuite) TestConfigValidateNothingUsed(c *gc.C) { - cfg := presence.Config{ - Identity: names.NewMachineTag("1"), - Start: s.start, - Clock: coretesting.NewStubClock(s.stub), - RetryDelay: time.Second, - } - - err := cfg.Validate() - c.Assert(err, jc.ErrorIsNil) - - s.stub.CheckNoCalls(c) -} - -func (s *WorkerSuite) TestConfigValidateZeroValue(c *gc.C) { - var cfg presence.Config - - err := cfg.Validate() - - c.Check(err, gc.NotNil) -} - func (s *WorkerSuite) TestConfigValidateMissingIdentity(c *gc.C) { - cfg := presence.Config{ - Start: func() (presence.Pinger, error) { return nil, nil }, - Clock: struct{ clock.Clock }{}, - RetryDelay: time.Second, - } - - err := cfg.Validate() - - c.Check(err, jc.Satisfies, errors.IsNotValid) - c.Check(err, gc.ErrorMatches, `nil Identity not valid`) + config := validConfig() + config.Identity = nil + checkInvalid(c, config, "nil Identity not valid") } func (s *WorkerSuite) TestConfigValidateMissingStart(c *gc.C) { - cfg := presence.Config{ - Identity: names.NewMachineTag("1"), - Clock: struct{ clock.Clock }{}, - RetryDelay: time.Second, - } - - err := cfg.Validate() - - c.Check(err, jc.Satisfies, errors.IsNotValid) - c.Check(err, gc.ErrorMatches, `nil Start not valid`) + config := validConfig() + config.Start = nil + checkInvalid(c, config, "nil Start not valid") } func (s *WorkerSuite) TestConfigValidateMissingClock(c *gc.C) { - cfg := presence.Config{ - Identity: names.NewMachineTag("1"), - Start: func() (presence.Pinger, error) { return nil, nil }, - RetryDelay: time.Second, - } - - err := cfg.Validate() - - c.Check(err, jc.Satisfies, errors.IsNotValid) - c.Check(err, gc.ErrorMatches, `nil Clock not valid`) + config := validConfig() + config.Clock = nil + checkInvalid(c, config, "nil Clock not valid") } func (s *WorkerSuite) TestConfigValidateMissingRetryDelay(c *gc.C) { - cfg := presence.Config{ - Identity: names.NewMachineTag("1"), - Start: func() (presence.Pinger, error) { return nil, nil }, - Clock: struct{ clock.Clock }{}, - } - - err := cfg.Validate() - - c.Check(err, jc.Satisfies, errors.IsNotValid) - c.Check(err, gc.ErrorMatches, `non-positive RetryDelay not valid`) -} - -func (s *WorkerSuite) TestNewRunOnceBeforeLoop(c *gc.C) { - waitChan := make(chan struct{}) - s.clock.notify = waitChan - - w, err := presence.New(s.cfg) - c.Assert(err, jc.ErrorIsNil) - defer workertest.CleanKill(c, w) - <-waitChan - - s.stub.CheckCallNames(c, - "start", - "Wait", - "After", - ) -} - -func (s *WorkerSuite) TestNewFailStart(c *gc.C) { - waitChan := make(chan struct{}) - s.clock.notify = waitChan - failure := errors.New("") - s.stub.SetErrors(failure) - - w, err := presence.New(s.cfg) - c.Assert(err, jc.ErrorIsNil) - defer workertest.CleanKill(c, w) - <-waitChan - - s.stub.CheckCallNames(c, - "start", - "After", // continued on - ) -} - -func (s *WorkerSuite) TestNewFailWait(c *gc.C) { - waitChan := make(chan struct{}) - s.clock.notify = waitChan - failure := errors.New("") - s.stub.SetErrors(nil, failure) - - w, err := presence.New(s.cfg) - c.Assert(err, jc.ErrorIsNil) - defer workertest.CleanKill(c, w) - <-waitChan - - s.stub.CheckCallNames(c, - "start", - "Wait", - "After", // continued on - ) -} - -func (s *WorkerSuite) TestNewLoop(c *gc.C) { - waitChan := make(chan struct{}) - block := make(chan struct{}) - s.clock.setAfter(4) - count := 0 - s.cfg.Start = func() (presence.Pinger, error) { - pinger, err := s.start() - c.Logf("%d", count) - if count > 3 { - s.pinger.notify = waitChan - s.pinger.waitBlock = block - } - count += 1 - return pinger, err - } - - w, err := presence.New(s.cfg) - c.Assert(err, jc.ErrorIsNil) - defer workertest.CleanKill(c, w) - defer close(block) - <-waitChan - - s.stub.CheckCallNames(c, - "start", "Wait", "After", - "start", "Wait", "After", - "start", "Wait", "After", - "start", "Wait", "After", - "start", "Wait", - ) -} - -func (s *WorkerSuite) TestNewRetry(c *gc.C) { - failure := errors.New("") - s.stub.SetErrors( - nil, nil, nil, - failure, nil, - failure, nil, - nil, failure, nil, - nil, nil, - failure, // never reached - ) - waitChan := make(chan struct{}) - block := make(chan struct{}) - s.clock.setAfter(5) - delay := time.Nanosecond - s.cfg.RetryDelay = delay - count := 0 - s.cfg.Start = func() (presence.Pinger, error) { - pinger, err := s.start() - if count > 4 { - s.pinger.notify = waitChan - s.pinger.waitBlock = block + config := validConfig() + config.RetryDelay = 0 + checkInvalid(c, config, `non-positive RetryDelay not valid`) +} + +func (s *WorkerSuite) TestConfigValidateNegativeRetryDelay(c *gc.C) { + config := validConfig() + config.RetryDelay = -time.Minute + checkInvalid(c, config, `non-positive RetryDelay not valid`) +} + +func (s *WorkerSuite) TestInitialSuccess(c *gc.C) { + fix := NewFixture() + stub := fix.Run(c, func(context Context, worker *presence.Worker) { + workertest.CleanKill(c, worker) + // Despite immediate kill, a pinger was still started. + context.WaitPinger() + }) + stub.CheckCallNames(c, "Start") +} + +func (s *WorkerSuite) TestInitialFailedStart(c *gc.C) { + // First start attempt fails. + fix := NewFixture(errors.New("zap")) + stub := fix.Run(c, func(context Context, worker *presence.Worker) { + workertest.CleanKill(c, worker) + // Despite immediate kill, we didn't exit until the + // second time through the loop. + context.WaitAlarms(2) + }) + stub.CheckCallNames(c, "Start") +} + +func (s *WorkerSuite) TestInitialRetryIsDelayed(c *gc.C) { + // First start attempt fails. + fix := NewFixture(errors.New("zap")) + stub := fix.Run(c, func(context Context, worker *presence.Worker) { + context.WaitAlarms(2) + // Now we know the worker is waiting to start the next + // pinger, advance *almost* far enough to trigger it. + context.AdvanceClock(almostFiveSeconds) + workertest.CheckAlive(c, worker) + }) + stub.CheckCallNames(c, "Start") +} + +func (s *WorkerSuite) TestInitialRetryIsNotDelayedTooMuch(c *gc.C) { + // First start attempt fails. + fix := NewFixture(errors.New("zap")) + stub := fix.Run(c, func(context Context, worker *presence.Worker) { + context.WaitAlarms(2) + // Now we know the worker is waiting to start the next + // pinger, advance *just* far enough to trigger it. + context.AdvanceClock(fiveSeconds) + context.WaitPinger() + }) + stub.CheckCallNames(c, "Start", "Start") +} + +func (s *WorkerSuite) TestFailedPingerRestartIsDelayed(c *gc.C) { + // First start succeeds; pinger will die with error when killed. + fix := NewFixture(nil, errors.New("zap")) + stub := fix.Run(c, func(context Context, worker *presence.Worker) { + context.WaitPinger().Kill() + context.WaitAlarms(2) + // Now we know the first pinger has been stopped, and + // the worker is waiting to start the next one, advance + // *almost* far enough to trigger it. + context.AdvanceClock(almostFiveSeconds) + workertest.CheckAlive(c, worker) + }) + stub.CheckCallNames(c, "Start") +} + +func (s *WorkerSuite) TestFailedPingerRestartIsNotDelayedTooMuch(c *gc.C) { + // First start succeeds; pinger will die with error when killed. + fix := NewFixture(nil, errors.New("zap")) + stub := fix.Run(c, func(context Context, worker *presence.Worker) { + context.WaitPinger().Kill() + context.WaitAlarms(2) + // Now we know the first pinger has been stopped, and + // the worker is waiting to start the next one, advance + // *just* far enough to trigger it. + context.AdvanceClock(fiveSeconds) + context.WaitPinger() + }) + stub.CheckCallNames(c, "Start", "Start") +} + +func (s *WorkerSuite) TestStoppedPingerRestartIsDelayed(c *gc.C) { + fix := NewFixture() + stub := fix.Run(c, func(context Context, worker *presence.Worker) { + context.WaitPinger().Kill() + context.WaitAlarms(2) + // Now we know the first pinger has been stopped (no + // error), and the worker is waiting to start the next + // one, advance *almost* far enough to trigger it. + context.AdvanceClock(almostFiveSeconds) + workertest.CheckAlive(c, worker) + }) + stub.CheckCallNames(c, "Start") +} + +func (s *WorkerSuite) TestStoppedPingerRestartIsNotDelayedTooMuch(c *gc.C) { + fix := NewFixture() + stub := fix.Run(c, func(context Context, worker *presence.Worker) { + context.WaitPinger().Kill() + context.WaitAlarms(2) + // Now we know the first pinger has been stopped (no + // error), and the worker is waiting to start the next + // one, advance *just* far enough to trigger it. + context.AdvanceClock(fiveSeconds) + context.WaitPinger() + }) + stub.CheckCallNames(c, "Start", "Start") +} + +func (s *WorkerSuite) TestManyRestarts(c *gc.C) { + fix := NewFixture() + stub := fix.Run(c, func(context Context, worker *presence.Worker) { + context.WaitAlarms(1) + for i := 0; i < 4; i++ { + context.WaitPinger().Kill() + context.WaitAlarms(1) + context.AdvanceClock(fiveSeconds) } - count += 1 - return pinger, err - } - - w, err := presence.New(s.cfg) - c.Assert(err, jc.ErrorIsNil) - defer workertest.CleanKill(c, w) - defer close(block) - <-waitChan - - s.stub.CheckCallNames(c, - "start", "Wait", "After", - "start", "After", - "start", "After", - "start", "Wait", "After", - "start", "Wait", "After", - "start", "Wait", - ) - var noWait time.Duration - s.stub.CheckCall(c, 2, "After", noWait) - s.stub.CheckCall(c, 4, "After", delay) - s.stub.CheckCall(c, 6, "After", delay) - s.stub.CheckCall(c, 9, "After", noWait) - s.stub.CheckCall(c, 12, "After", noWait) -} - -func (s *WorkerSuite) TestNewInvalidConfig(c *gc.C) { - var cfg presence.Config - - _, err := presence.New(cfg) - - c.Check(err, jc.Satisfies, errors.IsNotValid) -} - -type stubPinger struct { - *testing.Stub - - waitBlock chan struct{} - notify chan struct{} -} - -func (s *stubPinger) Stop() error { - s.AddCall("Stop") - if err := s.NextErr(); err != nil { - return errors.Trace(err) - } - return nil -} - -func (s *stubPinger) Wait() error { - s.AddCall("Wait") - if err := s.NextErr(); err != nil { - return errors.Trace(err) - } - - if s.notify != nil { - s.notify <- struct{}{} - } - if s.waitBlock != nil { - <-s.waitBlock - } - return nil -} - -type stubClock struct { - *coretesting.StubClock - - notify chan struct{} -} - -func (s *stubClock) setAfter(numCalls int) { - after := make(chan time.Time, numCalls) - for i := 0; i < numCalls; i++ { - after <- time.Now() - } - s.ReturnAfter = after -} - -func (s *stubClock) After(d time.Duration) <-chan time.Time { - after := s.StubClock.After(d) - if s.notify != nil { - s.notify <- struct{}{} - } - return after + workertest.CheckAlive(c, worker) + }) + stub.CheckCallNames(c, "Start", "Start", "Start", "Start", "Start") } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/presence/util_test.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/presence/util_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/presence/util_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/presence/util_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,194 @@ +// Copyright 2016 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package presence_test + +import ( + "sync" + "time" + + "github.com/juju/errors" + "github.com/juju/names" + "github.com/juju/testing" + jc "github.com/juju/testing/checkers" + "github.com/juju/utils/clock" + gc "gopkg.in/check.v1" + + "github.com/juju/juju/apiserver/presence" + coretesting "github.com/juju/juju/testing" + "github.com/juju/juju/worker" + "github.com/juju/juju/worker/workertest" +) + +var ( + fiveSeconds = 5 * time.Second + almostFiveSeconds = fiveSeconds - time.Nanosecond +) + +// Context exposes useful functionality to fixture tests. +type Context interface { + + // WaitPinger() returns the first pinger started by the SUT that + // has not already been returned from this method. + WaitPinger() worker.Worker + + // WaitAlarms() returns once the SUT has set (but not + // necessarily responded to) N alarms (e.g. calls to + // clock.After). + WaitAlarms(int) + + // AdvanceClock() advances the SUT's clock by the duration. If + // you're testing alarms, be sure that you've waited for the + // relevant alarm to be set before you advance the clock. + AdvanceClock(time.Duration) +} + +// FixtureTest is called with a Context and a running Worker. +type FixtureTest func(Context, *presence.Worker) + +func NewFixture(errors ...error) *Fixture { + return &Fixture{errors} +} + +// Fixture makes it easy to manipulate a running worker's environment +// and test its behaviour in response. +type Fixture struct { + errors []error +} + +// Run runs test against a fresh Stub, which is returned to the client +// for further analysis. +func (fix *Fixture) Run(c *gc.C, test FixtureTest) *testing.Stub { + stub := &testing.Stub{} + stub.SetErrors(fix.errors...) + run(c, stub, test) + return stub +} + +func run(c *gc.C, stub *testing.Stub, test FixtureTest) { + context := &context{ + c: c, + stub: stub, + clock: coretesting.NewClock(time.Now()), + timeout: time.After(time.Second), + starts: make(chan worker.Worker, 1000), + } + defer context.checkCleanedUp() + + worker, err := presence.New(presence.Config{ + Identity: names.NewMachineTag("1"), + Start: context.startPinger, + Clock: context.clock, + RetryDelay: fiveSeconds, + }) + c.Assert(err, jc.ErrorIsNil) + defer workertest.CleanKill(c, worker) + + test(context, worker) +} + +// context implements Context. +type context struct { + c *gc.C + stub *testing.Stub + clock *coretesting.Clock + timeout <-chan time.Time + + starts chan worker.Worker + mu sync.Mutex + current worker.Worker +} + +// WaitPinger is part of the Context interface. +func (context *context) WaitPinger() worker.Worker { + context.c.Logf("waiting for pinger...") + select { + case pinger := <-context.starts: + return pinger + case <-context.timeout: + context.c.Fatalf("timed out waiting for pinger") + return nil + } +} + +// WaitAlarms is part of the Context interface. +func (context *context) WaitAlarms(count int) { + context.c.Logf("waiting for %d alarms...", count) + for i := 0; i < count; i++ { + select { + case <-context.clock.Alarms(): + case <-context.timeout: + context.c.Fatalf("timed out waiting for alarm %d", i) + } + } +} + +// AdvanceClock is part of the Context interface. +func (context *context) AdvanceClock(d time.Duration) { + context.clock.Advance(d) +} + +func (context *context) startPinger() (presence.Pinger, error) { + context.stub.AddCall("Start") + context.checkCleanedUp() + if startErr := context.stub.NextErr(); startErr != nil { + return nil, startErr + } + + context.mu.Lock() + defer context.mu.Unlock() + pingerErr := context.stub.NextErr() + context.current = workertest.NewErrorWorker(pingerErr) + context.starts <- context.current + return mockPinger{context.current}, nil +} + +func (context *context) checkCleanedUp() { + context.c.Logf("checking no active current pinger") + context.mu.Lock() + defer context.mu.Unlock() + if context.current != nil { + workertest.CheckKilled(context.c, context.current) + } +} + +// mockPinger implements presence.Pinger for the convenience of the +// tests. +type mockPinger struct { + worker.Worker +} + +func (mock mockPinger) Stop() error { + return worker.Stop(mock.Worker) +} + +func (mock mockPinger) Wait() error { + return mock.Worker.Wait() +} + +// validConfig returns a presence.Config that will validate, but fail +// violently if actually used for anything. +func validConfig() presence.Config { + return presence.Config{ + Identity: struct{ names.Tag }{}, + Start: func() (presence.Pinger, error) { panic("no") }, + Clock: struct{ clock.Clock }{}, + RetryDelay: time.Nanosecond, + } +} + +func checkInvalid(c *gc.C, config presence.Config, message string) { + check := func(err error) { + c.Check(err, gc.ErrorMatches, message) + c.Check(err, jc.Satisfies, errors.IsNotValid) + } + + err := config.Validate() + check(err) + + worker, err := presence.New(config) + if !c.Check(worker, gc.IsNil) { + workertest.CleanKill(c, worker) + } + check(err) +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/proxyupdater/proxyupdater.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/proxyupdater/proxyupdater.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/proxyupdater/proxyupdater.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/proxyupdater/proxyupdater.go 2016-05-17 20:01:14.000000000 +0000 @@ -55,12 +55,13 @@ result = params.NotifyWatchResult{ NotifyWatcherId: api.resources.Register(watch), } + } else { + result.Error = common.ServerError(watcher.EnsureErr(watch)) } - result.Error = common.ServerError(watcher.EnsureErr(watch)) return result } -// WatchChanges watches for cleanups to be perfomed in state +// WatchForProxyConfigAndAPIHostPortChanges watches for cleanups to be perfomed in state func (api *ProxyUpdaterAPI) WatchForProxyConfigAndAPIHostPortChanges(args params.Entities) params.NotifyWatchResults { results := params.NotifyWatchResults{ Results: make([]params.NotifyWatchResult, len(args.Entities)), @@ -70,8 +71,9 @@ for i := range args.Entities { if errors.Results[i].Error == nil { results.Results[i] = api.oneWatch() + } else { + results.Results[i].Error = errors.Results[i].Error } - results.Results[i].Error = errors.Results[i].Error } return results diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/proxyupdater/proxyupdater_test.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/proxyupdater/proxyupdater_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/proxyupdater/proxyupdater_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/proxyupdater/proxyupdater_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,6 +4,8 @@ package proxyupdater_test import ( + "time" + "github.com/juju/names" jc "github.com/juju/testing/checkers" gc "gopkg.in/check.v1" @@ -15,7 +17,6 @@ "github.com/juju/juju/environs/config" "github.com/juju/juju/network" "github.com/juju/juju/state" - statetesting "github.com/juju/juju/state/testing" coretesting "github.com/juju/juju/testing" "github.com/juju/juju/worker/workertest" "github.com/juju/testing" @@ -64,17 +65,27 @@ func (s *ProxyUpdaterSuite) TestWatchForProxyConfigAndAPIHostPortChanges(c *gc.C) { // WatchForProxyConfigAndAPIHostPortChanges combines WatchForModelConfigChanges // and WatchAPIHostPorts. Check that they are both called and we get the - s.facade.WatchForProxyConfigAndAPIHostPortChanges(s.oneEntity()) - - // Verify the watcher resource was registered. - c.Assert(s.resources.Count(), gc.Equals, 1) - resource := s.resources.Get("1") - defer statetesting.AssertStop(c, resource) + result := s.facade.WatchForProxyConfigAndAPIHostPortChanges(s.oneEntity()) + c.Assert(result.Results, gc.HasLen, 1) + c.Assert(result.Results[0].Error, gc.IsNil) s.state.Stub.CheckCallNames(c, "WatchForModelConfigChanges", "WatchAPIHostPorts", ) + + // Verify the watcher resource was registered. + c.Assert(s.resources.Count(), gc.Equals, 1) + resource := s.resources.Get(result.Results[0].NotifyWatcherId) + watcher, ok := resource.(state.NotifyWatcher) + c.Assert(ok, jc.IsTrue) + + // Verify the initial event was consumed. + select { + case <-watcher.Changes(): + c.Fatalf("initial event never consumed") + case <-time.After(coretesting.ShortWait): + } } func (s *ProxyUpdaterSuite) oneEntity() params.Entities { @@ -168,8 +179,8 @@ "http-proxy": "http proxy", "https-proxy": "https proxy", } - sb.hpWatcher = workertest.NewFakeWatcher(2, 2) - sb.confWatcher = workertest.NewFakeWatcher(2, 2) + sb.hpWatcher = workertest.NewFakeWatcher(1, 1) + sb.confWatcher = workertest.NewFakeWatcher(1, 1) } func (sb *stubBackend) Kill() { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/server_test.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/server_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/server_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/server_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -16,6 +16,7 @@ "github.com/juju/names" "github.com/juju/testing" jc "github.com/juju/testing/checkers" + "github.com/juju/utils" "golang.org/x/net/websocket" gc "gopkg.in/check.v1" "gopkg.in/macaroon-bakery.v1/bakery" @@ -30,7 +31,7 @@ "github.com/juju/juju/cert" "github.com/juju/juju/environs/config" jujutesting "github.com/juju/juju/juju/testing" - "github.com/juju/juju/mongo" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/network" "github.com/juju/juju/rpc" "github.com/juju/juju/state" @@ -192,7 +193,7 @@ proxy := testing.NewTCPProxy(c, mongoInfo.Addrs[0]) mongoInfo.Addrs = []string{proxy.Addr()} - st, err := state.Open(s.State.ModelTag(), mongoInfo, mongo.DefaultDialOpts(), nil) + st, err := state.Open(s.State.ModelTag(), mongoInfo, mongotest.DialOpts(), nil) c.Assert(err, gc.IsNil) defer st.Close() @@ -262,10 +263,13 @@ xcert, err := cert.ParseCert(coretesting.CACert) c.Assert(err, jc.ErrorIsNil) pool.AddCert(xcert) - config.TlsConfig = &tls.Config{ - RootCAs: pool, - MaxVersion: tlsVersion, + config.TlsConfig = utils.SecureTLSConfig() + if tlsVersion > 0 { + // This is for testing only. Please don't muck with the maxtlsversion in + // production. + config.TlsConfig.MaxVersion = tlsVersion } + config.TlsConfig.RootCAs = pool return websocket.DialConfig(config) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/sshclient/facade.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/sshclient/facade.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/sshclient/facade.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/sshclient/facade.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,97 @@ +// Copyright 2016 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +// Package sshclient implements the API endpoint required for Juju +// clients that wish to make SSH connections to Juju managed machines. +package sshclient + +import ( + "github.com/juju/juju/apiserver/common" + "github.com/juju/juju/apiserver/params" + "github.com/juju/juju/network" +) + +func init() { + common.RegisterStandardFacade("SSHClient", 1, newFacade) +} + +// Facade implements the API required by the sshclient worker. +type Facade struct { + backend Backend +} + +// New returns a new API facade for the sshclient worker. +func New(backend Backend, _ *common.Resources, authorizer common.Authorizer) (*Facade, error) { + if !authorizer.AuthClient() { + return nil, common.ErrPerm + } + return &Facade{backend: backend}, nil +} + +// PublicAddress reports the preferred public network address for one +// or more entities. Machines and units are suppored. +func (facade *Facade) PublicAddress(args params.Entities) (params.SSHAddressResults, error) { + getter := func(m SSHMachine) (network.Address, error) { return m.PublicAddress() } + return facade.getAddresses(args, getter) +} + +// PrivateAddress reports the preferred private network address for one or +// more entities. Machines and units are supported. +func (facade *Facade) PrivateAddress(args params.Entities) (params.SSHAddressResults, error) { + getter := func(m SSHMachine) (network.Address, error) { return m.PrivateAddress() } + return facade.getAddresses(args, getter) +} + +func (facade *Facade) getAddresses(args params.Entities, getter func(SSHMachine) (network.Address, error)) ( + params.SSHAddressResults, error, +) { + out := params.SSHAddressResults{ + Results: make([]params.SSHAddressResult, len(args.Entities)), + } + for i, entity := range args.Entities { + machine, err := facade.backend.GetMachineForEntity(entity.Tag) + if err != nil { + out.Results[i].Error = common.ServerError(common.ErrPerm) + } else { + address, err := getter(machine) + if err != nil { + out.Results[i].Error = common.ServerError(err) + } else { + out.Results[i].Address = address.Value + } + } + } + return out, nil +} + +// PublicKeys returns the public SSH hosts for one or more +// entities. Machines and units are supported. +func (facade *Facade) PublicKeys(args params.Entities) (params.SSHPublicKeysResults, error) { + out := params.SSHPublicKeysResults{ + Results: make([]params.SSHPublicKeysResult, len(args.Entities)), + } + for i, entity := range args.Entities { + machine, err := facade.backend.GetMachineForEntity(entity.Tag) + if err != nil { + out.Results[i].Error = common.ServerError(common.ErrPerm) + } else { + keys, err := facade.backend.GetSSHHostKeys(machine.MachineTag()) + if err != nil { + out.Results[i].Error = common.ServerError(err) + } else { + out.Results[i].PublicKeys = []string(keys) + } + } + } + return out, nil +} + +// Proxy returns whether SSH connections should be proxied through the +// controller hosts for the model associated with the API connection. +func (facade *Facade) Proxy() (params.SSHProxyResult, error) { + config, err := facade.backend.ModelConfig() + if err != nil { + return params.SSHProxyResult{}, err + } + return params.SSHProxyResult{UseProxy: config.ProxySSH()}, nil +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/sshclient/facade_test.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/sshclient/facade_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/sshclient/facade_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/sshclient/facade_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,214 @@ +// Copyright 2016 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package sshclient_test + +import ( + "github.com/juju/errors" + "github.com/juju/names" + jujutesting "github.com/juju/testing" + jc "github.com/juju/testing/checkers" + gc "gopkg.in/check.v1" + + "github.com/juju/juju/apiserver/common" + "github.com/juju/juju/apiserver/params" + "github.com/juju/juju/apiserver/sshclient" + apiservertesting "github.com/juju/juju/apiserver/testing" + "github.com/juju/juju/environs/config" + "github.com/juju/juju/network" + "github.com/juju/juju/state" + "github.com/juju/juju/testing" +) + +type facadeSuite struct { + testing.BaseSuite + backend *mockBackend + authorizer *apiservertesting.FakeAuthorizer + facade *sshclient.Facade + m0, uFoo, uOther string +} + +var _ = gc.Suite(&facadeSuite{}) + +func (s *facadeSuite) SetUpSuite(c *gc.C) { + s.BaseSuite.SetUpSuite(c) + s.m0 = names.NewMachineTag("0").String() + s.uFoo = names.NewUnitTag("foo/0").String() + s.uOther = names.NewUnitTag("other/1").String() +} + +func (s *facadeSuite) SetUpTest(c *gc.C) { + s.BaseSuite.SetUpTest(c) + + s.backend = new(mockBackend) + s.authorizer = new(apiservertesting.FakeAuthorizer) + s.authorizer.Tag = names.NewUserTag("igor") + facade, err := sshclient.New(s.backend, nil, s.authorizer) + c.Assert(err, jc.ErrorIsNil) + s.facade = facade +} + +func (s *facadeSuite) TestMachineAuthNotAllowed(c *gc.C) { + s.authorizer.Tag = names.NewMachineTag("0") + _, err := sshclient.New(s.backend, nil, s.authorizer) + c.Assert(err, gc.Equals, common.ErrPerm) +} + +func (s *facadeSuite) TestUnitAuthNotAllowed(c *gc.C) { + s.authorizer.Tag = names.NewUnitTag("foo/0") + _, err := sshclient.New(s.backend, nil, s.authorizer) + c.Assert(err, gc.Equals, common.ErrPerm) +} + +func (s *facadeSuite) TestPublicAddress(c *gc.C) { + args := params.Entities{ + Entities: []params.Entity{{s.m0}, {s.uFoo}, {s.uOther}}, + } + results, err := s.facade.PublicAddress(args) + + c.Assert(err, jc.ErrorIsNil) + c.Check(results, gc.DeepEquals, params.SSHAddressResults{ + Results: []params.SSHAddressResult{ + {Address: "1.1.1.1"}, + {Address: "3.3.3.3"}, + {Error: apiservertesting.ErrUnauthorized}, + }, + }) + s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ + {"GetMachineForEntity", []interface{}{s.m0}}, + {"GetMachineForEntity", []interface{}{s.uFoo}}, + {"GetMachineForEntity", []interface{}{s.uOther}}, + }) +} + +func (s *facadeSuite) TestPrivateAddress(c *gc.C) { + args := params.Entities{ + Entities: []params.Entity{{s.uOther}, {s.m0}, {s.uFoo}}, + } + results, err := s.facade.PrivateAddress(args) + + c.Assert(err, jc.ErrorIsNil) + c.Check(results, gc.DeepEquals, params.SSHAddressResults{ + Results: []params.SSHAddressResult{ + {Error: apiservertesting.ErrUnauthorized}, + {Address: "2.2.2.2"}, + {Address: "4.4.4.4"}, + }, + }) + s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ + {"GetMachineForEntity", []interface{}{s.uOther}}, + {"GetMachineForEntity", []interface{}{s.m0}}, + {"GetMachineForEntity", []interface{}{s.uFoo}}, + }) +} + +func (s *facadeSuite) TestPublicKeys(c *gc.C) { + args := params.Entities{ + Entities: []params.Entity{{s.m0}, {s.uOther}, {s.uFoo}}, + } + results, err := s.facade.PublicKeys(args) + + c.Assert(err, jc.ErrorIsNil) + c.Check(results, gc.DeepEquals, params.SSHPublicKeysResults{ + Results: []params.SSHPublicKeysResult{ + {PublicKeys: []string{"rsa0", "dsa0"}}, + {Error: apiservertesting.ErrUnauthorized}, + {PublicKeys: []string{"rsa1", "dsa1"}}, + }, + }) + s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ + {"GetMachineForEntity", []interface{}{s.m0}}, + {"GetSSHHostKeys", []interface{}{names.NewMachineTag("0")}}, + {"GetMachineForEntity", []interface{}{s.uOther}}, + {"GetMachineForEntity", []interface{}{s.uFoo}}, + {"GetSSHHostKeys", []interface{}{names.NewMachineTag("1")}}, + }) +} + +func (s *facadeSuite) TestProxyTrue(c *gc.C) { + s.backend.proxySSH = true + result, err := s.facade.Proxy() + c.Assert(err, jc.ErrorIsNil) + c.Check(result.UseProxy, jc.IsTrue) + s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ + {"ModelConfig", []interface{}{}}, + }) +} + +func (s *facadeSuite) TestProxyFalse(c *gc.C) { + s.backend.proxySSH = false + result, err := s.facade.Proxy() + c.Assert(err, jc.ErrorIsNil) + c.Check(result.UseProxy, jc.IsFalse) + s.backend.stub.CheckCalls(c, []jujutesting.StubCall{ + {"ModelConfig", []interface{}{}}, + }) +} + +type mockBackend struct { + stub jujutesting.Stub + proxySSH bool +} + +func (backend *mockBackend) ModelConfig() (*config.Config, error) { + backend.stub.AddCall("ModelConfig") + attrs := testing.FakeConfig() + attrs["proxy-ssh"] = backend.proxySSH + conf, err := config.New(config.NoDefaults, attrs) + if err != nil { + return nil, errors.Trace(err) + } + return conf, nil +} + +func (backend *mockBackend) GetMachineForEntity(tagString string) (sshclient.SSHMachine, error) { + backend.stub.AddCall("GetMachineForEntity", tagString) + switch tagString { + case names.NewMachineTag("0").String(): + return &mockMachine{ + tag: names.NewMachineTag("0"), + publicAddress: "1.1.1.1", + privateAddress: "2.2.2.2", + }, nil + case names.NewUnitTag("foo/0").String(): + return &mockMachine{ + tag: names.NewMachineTag("1"), + publicAddress: "3.3.3.3", + privateAddress: "4.4.4.4", + }, nil + } + return nil, errors.New("unknown entity") +} + +func (backend *mockBackend) GetSSHHostKeys(tag names.MachineTag) (state.SSHHostKeys, error) { + backend.stub.AddCall("GetSSHHostKeys", tag) + switch tag { + case names.NewMachineTag("0"): + return state.SSHHostKeys{"rsa0", "dsa0"}, nil + case names.NewMachineTag("1"): + return state.SSHHostKeys{"rsa1", "dsa1"}, nil + } + return nil, errors.New("machine not found") +} + +type mockMachine struct { + tag names.MachineTag + publicAddress string + privateAddress string +} + +func (m *mockMachine) MachineTag() names.MachineTag { + return m.tag +} + +func (m *mockMachine) PublicAddress() (network.Address, error) { + return network.Address{ + Value: m.publicAddress, + }, nil +} + +func (m *mockMachine) PrivateAddress() (network.Address, error) { + return network.Address{ + Value: m.privateAddress, + }, nil +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/sshclient/package_test.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/sshclient/package_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/sshclient/package_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/sshclient/package_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,14 @@ +// Copyright 2016 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package sshclient_test + +import ( + "testing" + + gc "gopkg.in/check.v1" +) + +func Test(t *testing.T) { + gc.TestingT(t) +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/sshclient/shim.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/sshclient/shim.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/sshclient/shim.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/sshclient/shim.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,72 @@ +// Copyright 2016 Canonical Ltd. +// Licensed under the LGPLv3, see LICENCE file for details. + +package sshclient + +import ( + "github.com/juju/errors" + "github.com/juju/names" + + "github.com/juju/juju/apiserver/common" + "github.com/juju/juju/environs/config" + "github.com/juju/juju/network" + "github.com/juju/juju/state" +) + +// Backend defines the State API used by the sshclient facade. +type Backend interface { + ModelConfig() (*config.Config, error) + GetMachineForEntity(tag string) (SSHMachine, error) + GetSSHHostKeys(names.MachineTag) (state.SSHHostKeys, error) +} + +// SSHMachine specifies the methods on State.Machine of interest to +// the SSHClient facade. +type SSHMachine interface { + MachineTag() names.MachineTag + PublicAddress() (network.Address, error) + PrivateAddress() (network.Address, error) +} + +// newFacade wraps New to express the supplied *state.State as a Backend. +func newFacade(st *state.State, res *common.Resources, auth common.Authorizer) (*Facade, error) { + return New(&backend{st}, res, auth) +} + +type backend struct { + *state.State +} + +// GetMachineForEntity takes a machine or unit tag (as a string) and +// returns the associated SSHMachine. +func (b *backend) GetMachineForEntity(tagString string) (SSHMachine, error) { + tag, err := names.ParseTag(tagString) + if err != nil { + return nil, errors.Trace(err) + } + + switch tag := tag.(type) { + case names.MachineTag: + machine, err := b.State.Machine(tag.Id()) + if err != nil { + return nil, errors.Trace(err) + } + return machine, nil + case names.UnitTag: + unit, err := b.State.Unit(tag.Id()) + if err != nil { + return nil, errors.Trace(err) + } + machineId, err := unit.AssignedMachineId() + if err != nil { + return nil, errors.Trace(err) + } + machine, err := b.State.Machine(machineId) + if err != nil { + return nil, errors.Trace(err) + } + return machine, nil + default: + return nil, errors.Errorf("unsupported entity: %q", tagString) + } +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/uniter/uniter.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/uniter/uniter.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/uniter/uniter.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/uniter/uniter.go 2016-05-17 20:01:14.000000000 +0000 @@ -7,8 +7,6 @@ import ( "fmt" - "net/url" - "path" "github.com/juju/errors" "github.com/juju/loggo" @@ -858,45 +856,6 @@ } return result, nil } - -// CharmArchiveURLs returns the URLS for the charm archive -// (bundle) data for each charm url in the given parameters. -func (u *UniterAPIV3) CharmArchiveURLs(args params.CharmURLs) (params.StringsResults, error) { - apiHostPorts, err := u.st.APIHostPorts() - if err != nil { - return params.StringsResults{}, err - } - modelUUID := u.st.ModelUUID() - result := params.StringsResults{ - Results: make([]params.StringsResult, len(args.URLs)), - } - for i, curl := range args.URLs { - if _, err := charm.ParseURL(curl.URL); err != nil { - result.Results[i].Error = common.ServerError(common.ErrPerm) - continue - } - urlPath := "/" - if modelUUID != "" { - urlPath = path.Join(urlPath, "model", modelUUID) - } - urlPath = path.Join(urlPath, "charms") - archiveURLs := make([]string, len(apiHostPorts)) - for j, server := range apiHostPorts { - archiveURL := &url.URL{ - Scheme: "https", - Host: network.SelectInternalHostPort(server, false), - Path: urlPath, - } - q := archiveURL.Query() - q.Set("url", curl.URL) - q.Set("file", "*") - archiveURL.RawQuery = q.Encode() - archiveURLs[j] = archiveURL.String() - } - result.Results[i].Result = archiveURLs - } - return result, nil -} // Relation returns information about all given relation/unit pairs, // including their id, key and the local endpoint. diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/uniter/uniter_test.go juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/uniter/uniter_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/apiserver/uniter/uniter_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/apiserver/uniter/uniter_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -25,7 +25,6 @@ "github.com/juju/juju/state/multiwatcher" statetesting "github.com/juju/juju/state/testing" "github.com/juju/juju/status" - coretesting "github.com/juju/juju/testing" "github.com/juju/juju/testing/factory" jujuFactory "github.com/juju/juju/testing/factory" ) @@ -1039,47 +1038,6 @@ }, }) } - -func (s *uniterSuite) TestCharmArchiveURLs(c *gc.C) { - dummyCharm := s.AddTestingCharm(c, "dummy") - - hostPorts := [][]network.HostPort{ - network.AddressesWithPort([]network.Address{ - network.NewScopedAddress("1.2.3.4", network.ScopePublic), - network.NewScopedAddress("0.1.2.3", network.ScopeCloudLocal), - }, 1234), - network.AddressesWithPort([]network.Address{ - network.NewScopedAddress("1.2.3.5", network.ScopePublic), - }, 1234), - } - err := s.State.SetAPIHostPorts(hostPorts) - c.Assert(err, jc.ErrorIsNil) - - args := params.CharmURLs{URLs: []params.CharmURL{ - {URL: "something-invalid!"}, - {URL: s.wpCharm.String()}, - {URL: dummyCharm.String()}, - }} - result, err := s.uniter.CharmArchiveURLs(args) - c.Assert(err, jc.ErrorIsNil) - - wordpressURLs := []string{ - fmt.Sprintf("https://0.1.2.3:1234/model/%s/charms?file=%%2A&url=cs%%3Aquantal%%2Fwordpress-3", coretesting.ModelTag.Id()), - fmt.Sprintf("https://1.2.3.5:1234/model/%s/charms?file=%%2A&url=cs%%3Aquantal%%2Fwordpress-3", coretesting.ModelTag.Id()), - } - dummyURLs := []string{ - fmt.Sprintf("https://0.1.2.3:1234/model/%s/charms?file=%%2A&url=local%%3Aquantal%%2Fdummy-1", coretesting.ModelTag.Id()), - fmt.Sprintf("https://1.2.3.5:1234/model/%s/charms?file=%%2A&url=local%%3Aquantal%%2Fdummy-1", coretesting.ModelTag.Id()), - } - - c.Assert(result, jc.DeepEquals, params.StringsResults{ - Results: []params.StringsResult{ - {Error: apiservertesting.ErrUnauthorized}, - {Result: wordpressURLs}, - {Result: dummyURLs}, - }, - }) -} func (s *uniterSuite) TestCurrentModel(c *gc.C) { env, err := s.State.Model() diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cert/cert_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cert/cert_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cert/cert_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cert/cert_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -16,6 +16,7 @@ "time" jc "github.com/juju/testing/checkers" + "github.com/juju/utils" gc "gopkg.in/check.v1" "github.com/juju/juju/cert" @@ -237,14 +238,13 @@ var clientState tls.ConnectionState done := make(chan error) go func() { - config := tls.Config{ - Certificates: []tls.Certificate{{ - Certificate: [][]byte{srvCert.Raw}, - PrivateKey: srvKey, - }}, - } + config := utils.SecureTLSConfig() + config.Certificates = []tls.Certificate{{ + Certificate: [][]byte{srvCert.Raw}, + PrivateKey: srvKey, + }} - conn := tls.Server(p1, &config) + conn := tls.Server(p1, config) defer conn.Close() data, err := ioutil.ReadAll(conn) c.Assert(err, jc.ErrorIsNil) @@ -252,10 +252,10 @@ close(done) }() - clientConn := tls.Client(p0, &tls.Config{ - ServerName: "anyServer", - RootCAs: clientCertPool, - }) + tlsConfig := utils.SecureTLSConfig() + tlsConfig.ServerName = "anyServer" + tlsConfig.RootCAs = clientCertPool + clientConn := tls.Client(p0, tlsConfig) defer clientConn.Close() _, err := clientConn.Write([]byte(msg)) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cloud/clouds.go juju-core-2.0~beta7/src/github.com/juju/juju/cloud/clouds.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cloud/clouds.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cloud/clouds.go 2016-05-17 20:01:14.000000000 +0000 @@ -122,8 +122,14 @@ StorageEndpoint string `yaml:"storage-endpoint,omitempty"` } -// BuiltInProviderNames work out of the box. -var BuiltInProviderNames = []string{"lxd", "manual", "maas"} +// BuiltInClouds work out of the box. +var BuiltInClouds = map[string]Cloud{ + "localhost": { + Type: "lxd", + AuthTypes: []AuthType{EmptyAuthType}, + Regions: []Region{{Name: "localhost"}}, + }, +} // CloudByName returns the cloud with the specified name. // If there exists no cloud with the specified name, an @@ -146,6 +152,9 @@ if cloud, ok := clouds[name]; ok { return &cloud, nil } + if cloud, ok := BuiltInClouds[name]; ok { + return &cloud, nil + } return nil, errors.NotFoundf("cloud %s", name) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cloudconfig/userdatacfg_win.go juju-core-2.0~beta7/src/github.com/juju/juju/cloudconfig/userdatacfg_win.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cloudconfig/userdatacfg_win.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cloudconfig/userdatacfg_win.go 2016-05-17 20:01:14.000000000 +0000 @@ -202,7 +202,7 @@ if err != nil { return nil, err } - caCert := base64.URLEncoding.EncodeToString(parsedCert.Raw) + caCert := base64.StdEncoding.EncodeToString(parsedCert.Raw) cmds = []string{fmt.Sprintf(`$cacert = "%s"`, caCert), `$cert_bytes = $cacert | %{ ,[System.Text.Encoding]::UTF8.GetBytes($_) }`, `$cert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2(,$cert_bytes)`, @@ -217,6 +217,7 @@ cmds = []string{ `$WebClient = New-Object System.Net.WebClient`, `[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}`, + `[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12`, } getDownloadFileCmd = func(url string) string { return fmt.Sprintf(`$WebClient.DownloadFile('%s', "$binDir\tools.tar.gz");`, url) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cloudconfig/windows_userdata_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cloudconfig/windows_userdata_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cloudconfig/windows_userdata_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cloudconfig/windows_userdata_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -690,6 +690,7 @@ mkdir $binDir $WebClient = New-Object System.Net.WebClient [System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true} +[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 ExecRetry { TryExecAll @({ $WebClient.DownloadFile('https://state-addr.testing.invalid:54321/deadbeef-0bad-400d-8000-4b1d0d06f00d/tools/1.2.3-win8-amd64', "$binDir\tools.tar.gz"); }) } $dToolsHash = Get-FileSHA256 -FilePath "$binDir\tools.tar.gz" $dToolsHash > "$binDir\juju1.2.3-win8-amd64.sha256" diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/backups/export_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/backups/export_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/backups/export_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/backups/export_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -76,6 +76,9 @@ getEnvironFunc: getEnviron, newAPIClientFunc: func() (RestoreAPI, error) { return api, nil + }, + waitForAgentFunc: func(ctx *cmd.Context, c *modelcmd.ModelCommandBase, controllerName string) error { + return nil }} if getEnviron == nil { c.getEnvironFunc = func(controllerNme string, meta *params.BackupsMetadataResult) (environs.Environ, error) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/backups/restore.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/backups/restore.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/backups/restore.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/backups/restore.go 2016-05-17 20:01:14.000000000 +0000 @@ -17,11 +17,14 @@ "github.com/juju/juju/api/backups" "github.com/juju/juju/apiserver/params" + "github.com/juju/juju/cmd/juju/common" "github.com/juju/juju/cmd/modelcmd" "github.com/juju/juju/constraints" "github.com/juju/juju/environs" "github.com/juju/juju/environs/bootstrap" "github.com/juju/juju/environs/config" + "github.com/juju/juju/environs/sync" + "github.com/juju/juju/jujuclient" ) // NewRestoreCommand returns a command used to restore a backup. @@ -32,6 +35,7 @@ return restoreCmd.newClient() } restoreCmd.getArchiveFunc = getArchive + restoreCmd.waitForAgentFunc = common.WaitForAgentInitialisation return modelcmd.Wrap(restoreCmd) } @@ -48,6 +52,7 @@ newAPIClientFunc func() (RestoreAPI, error) getEnvironFunc func(string, *params.BackupsMetadataResult) (environs.Environ, error) getArchiveFunc func(string) (ArchiveReader, *params.BackupsMetadataResult, error) + waitForAgentFunc func(ctx *cmd.Context, c *modelcmd.ModelCommandBase, controllerName string) error } // RestoreAPI is used to invoke various API calls. @@ -145,6 +150,18 @@ return nil, errors.Trace(err) } + // We may have previous controller metadata. We need to update that so it + // will contain the new CA Cert and UUID required to connect to the newly + // bootstrapped controller API. + details := jujuclient.ControllerDetails{ + ControllerUUID: cfg.ControllerUUID(), + CACert: meta.CACert, + } + err = store.UpdateController(controllerName, details) + if err != nil { + return nil, errors.Trace(err) + } + // Get the local admin user so we can use the password as the admin secret. var adminSecret string account, err := store.AccountByName(controllerName, environs.AdminUser) @@ -211,12 +228,23 @@ args := bootstrap.BootstrapParams{ ModelConstraints: c.constraints, UploadTools: c.uploadTools, + BuildToolsTarball: sync.BuildToolsTarball, HostedModelConfig: hostedModelConfig, } if err := BootstrapFunc(modelcmd.BootstrapContext(ctx), env, args); err != nil { return errors.Annotatef(err, "cannot bootstrap new instance") } - return nil + + // New controller is bootstrapped, so now record the API address so + // we can connect. + err = common.SetBootstrapEndpointAddress(c.ClientStore(), c.ControllerName(), env) + if err != nil { + errors.Trace(err) + } + // To avoid race conditions when running scripted bootstraps, wait + // for the controller's machine agent to be ready to accept commands + // before exiting this bootstrap command. + return c.waitForAgentFunc(ctx, &c.ModelCommandBase, c.ControllerName()) } func (c *restoreCommand) newClient() (*backups.Client, error) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/backups/restore_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/backups/restore_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/backups/restore_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/backups/restore_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,17 +4,23 @@ package backups_test import ( + "io" + "github.com/juju/errors" + jc "github.com/juju/testing/checkers" gc "gopkg.in/check.v1" + apibackups "github.com/juju/juju/api/backups" "github.com/juju/juju/apiserver/params" "github.com/juju/juju/cloud" "github.com/juju/juju/cmd/juju/backups" "github.com/juju/juju/environs" "github.com/juju/juju/environs/bootstrap" + "github.com/juju/juju/environs/config" "github.com/juju/juju/instance" "github.com/juju/juju/jujuclient" "github.com/juju/juju/jujuclient/jujuclienttesting" + "github.com/juju/juju/network" _ "github.com/juju/juju/provider/dummy" "github.com/juju/juju/testing" ) @@ -91,6 +97,10 @@ return nil } +func (*mockRestoreAPI) RestoreReader(io.ReadSeeker, *params.BackupsMetadataResult, apibackups.ClientConnection) error { + return nil +} + type mockArchiveReader struct { backups.ArchiveReader } @@ -152,11 +162,45 @@ c.Assert(err, gc.ErrorMatches, ".*failed to bootstrap new controller") } +func (s *restoreSuite) TestRestoreReboostrapWritesUpdatedControllerInfo(c *gc.C) { + metadata := params.BackupsMetadataResult{ + CACert: testing.CACert, + CAPrivateKey: testing.CAKey, + } + fakeEnv := fakeEnviron{} + s.command = backups.NewRestoreCommandForTest( + s.store, &mockRestoreAPI{}, + func(string) (backups.ArchiveReader, *params.BackupsMetadataResult, error) { + return &mockArchiveReader{}, &metadata, nil + }, + func(string, *params.BackupsMetadataResult) (environs.Environ, error) { + return fakeEnv, nil + }) + s.PatchValue(&backups.BootstrapFunc, func(ctx environs.BootstrapContext, environ environs.Environ, args bootstrap.BootstrapParams) error { + return nil + }) + + _, err := testing.RunCommand(c, s.command, "restore", "-m", "testing:test1", "--file", "afile", "-b") + c.Assert(err, jc.ErrorIsNil) + c.Assert(s.store.Controllers["testing"], jc.DeepEquals, jujuclient.ControllerDetails{ + CACert: testing.CACert, + ControllerUUID: "deadbeef-0bad-400d-8000-4b1d0d06f00d", + APIEndpoints: []string{"10.0.0.1:100"}, + UnresolvedAPIEndpoints: []string{"10.0.0.1:100"}, + }) +} + type fakeInstance struct { instance.Instance id instance.Id } +func (f fakeInstance) Addresses() ([]network.Address, error) { + return []network.Address{ + {Value: "10.0.0.1"}, + }, nil +} + type fakeEnviron struct { environs.Environ controllerInstances []instance.Id @@ -169,3 +213,13 @@ func (f fakeEnviron) Instances(ids []instance.Id) ([]instance.Instance, error) { return []instance.Instance{fakeInstance{id: "1"}}, nil } + +func (f fakeEnviron) AllInstances() ([]instance.Instance, error) { + return []instance.Instance{fakeInstance{id: "1"}}, nil +} + +func (f fakeEnviron) Config() *config.Config { + attrs := testing.FakeConfig().Merge(map[string]interface{}{"api-port": "100"}) + cfg, _ := config.New(config.NoDefaults, attrs) + return cfg +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/block/export_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/block/export_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/block/export_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/block/export_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -56,5 +56,7 @@ } func NewUnblockCommandWithClient(client UnblockClientAPI) cmd.Command { - return modelcmd.Wrap(&unblockCommand{client: client}) + return modelcmd.Wrap(&unblockCommand{getClient: func() (UnblockClientAPI, error) { + return client, nil + }}) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/block/unblock.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/block/unblock.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/block/unblock.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/block/unblock.go 2016-05-17 20:01:14.000000000 +0000 @@ -17,14 +17,18 @@ // NewUnblockCommand returns a new command that removes the block from // the specified operation. func NewUnblockCommand() cmd.Command { - return modelcmd.Wrap(&unblockCommand{}) + c := &unblockCommand{} + c.getClient = func() (UnblockClientAPI, error) { + return getBlockAPI(&c.ModelCommandBase) + } + return modelcmd.Wrap(c) } // unblockCommand removes the block from desired operation. type unblockCommand struct { modelcmd.ModelCommandBase operation string - client UnblockClientAPI + getClient func() (UnblockClientAPI, error) } var ( @@ -151,14 +155,11 @@ // Run unblocks previously blocked commands. // Satisfying Command interface. func (c *unblockCommand) Run(_ *cmd.Context) error { - client := c.client - if client == nil { - client, err := getBlockAPI(&c.ModelCommandBase) - if err != nil { - return errors.Trace(err) - } - defer client.Close() + client, err := c.getClient() + if err != nil { + return errors.Trace(err) } + defer client.Close() return client.SwitchBlockOff(TypeFromOperation(c.operation)) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/cloud/addcredential_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/cloud/addcredential_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/cloud/addcredential_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/cloud/addcredential_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -84,8 +84,9 @@ } func (s *addCredentialSuite) TestNoCredentialsRequired(c *gc.C) { - _, err := s.run(c, nil, "manual") - c.Assert(err, gc.ErrorMatches, `cloud "manual" does not require credentials`) + s.authTypes = nil + _, err := s.run(c, nil, "somecloud") + c.Assert(err, gc.ErrorMatches, `cloud "somecloud" does not require credentials`) } func (s *addCredentialSuite) createTestCredentialData(c *gc.C) string { @@ -333,10 +334,10 @@ }, } stdin := strings.NewReader("fred\nauth:token\n") - _, err := s.run(c, stdin, "maas") + _, err := s.run(c, stdin, "somecloud") c.Assert(err, jc.ErrorIsNil) c.Assert(s.store.Credentials, jc.DeepEquals, map[string]jujucloud.CloudCredential{ - "maas": { + "somecloud": { AuthCredentials: map[string]jujucloud.Credential{ "fred": jujucloud.NewCredential(jujucloud.OAuth1AuthType, map[string]string{ "maas-oauth": "auth:token", diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/cloud/defaultcredential_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/cloud/defaultcredential_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/cloud/defaultcredential_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/cloud/defaultcredential_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -69,5 +69,5 @@ } func (s *defaultCredentialSuite) TestSetDefaultCredentialBuiltIn(c *gc.C) { - s.assertSetDefaultCredential(c, "maas") + s.assertSetDefaultCredential(c, "localhost") } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/cloud/defaultregion_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/cloud/defaultregion_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/cloud/defaultregion_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/cloud/defaultregion_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -50,7 +50,11 @@ } func (s *defaultRegionSuite) assertSetDefaultRegion(c *gc.C, cmd cmd.Command, store *jujuclienttesting.MemStore, cloud, errStr string) { - ctx, err := testing.RunCommand(c, cmd, cloud, "us-west-1") + s.assertSetCustomDefaultRegion(c, cmd, store, cloud, "us-west-1", errStr) +} + +func (s *defaultRegionSuite) assertSetCustomDefaultRegion(c *gc.C, cmd cmd.Command, store *jujuclienttesting.MemStore, cloud, desiredDefault, errStr string) { + ctx, err := testing.RunCommand(c, cmd, cloud, desiredDefault) output := testing.Stderr(ctx) output = strings.Replace(output, "\n", "", -1) if errStr != "" { @@ -60,8 +64,8 @@ return } c.Assert(err, jc.ErrorIsNil) - c.Assert(output, gc.Equals, fmt.Sprintf(`Default region in %s set to "us-west-1".`, cloud)) - c.Assert(store.Credentials[cloud].DefaultRegion, gc.Equals, "us-west-1") + c.Assert(output, gc.Equals, fmt.Sprintf(`Default region in %s set to %q.`, cloud, desiredDefault)) + c.Assert(store.Credentials[cloud].DefaultRegion, gc.Equals, desiredDefault) } func (s *defaultRegionSuite) TestSetDefaultRegion(c *gc.C) { @@ -73,8 +77,8 @@ func (s *defaultRegionSuite) TestSetDefaultRegionBuiltIn(c *gc.C) { store := jujuclienttesting.NewMemStore() cmd := cloud.NewSetDefaultRegionCommandForTest(store) - // maas has no regions - s.assertSetDefaultRegion(c, cmd, store, "maas", `cloud maas has no regions`) + // Cloud 'localhost' is of type lxd. + s.assertSetCustomDefaultRegion(c, cmd, store, "localhost", "localhost", "") } func (s *defaultRegionSuite) TestOverwriteDefaultRegion(c *gc.C) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/cloud/listcredentials.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/cloud/listcredentials.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/cloud/listcredentials.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/cloud/listcredentials.go 2016-05-17 20:01:14.000000000 +0000 @@ -24,7 +24,7 @@ Lists credentials for a cloud.`[1:] var usageListCredentialsDetails = ` -Credentials are used with `[1:] + "`juju bootstrap`" + ` and ` + "`juju create-model`" + `. +Credentials are used with `[1:] + "`juju bootstrap`" + ` and ` + "`juju add-model`" + `. An arbitrary "credential name" is used to represent credentials, which are added either via ` + "`juju add-credential` or `juju autoload-credentials`" + `. Note that there can be multiple sets of credentials and thus multiple diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/cloud/list.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/cloud/list.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/cloud/list.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/cloud/list.go 2016-05-17 20:01:14.000000000 +0000 @@ -70,29 +70,73 @@ const localPrefix = "local:" func (c *listCloudsCommand) Run(ctxt *cmd.Context) error { - details, err := getCloudDetails() + details, err := listCloudDetails() if err != nil { return err } - return c.out.Write(ctxt, details) + + var output interface{} + switch c.out.Name() { + case "yaml", "json": + output = details.all() + default: + output = details + } + err = c.out.Write(ctxt, output) + if err != nil { + return err + } + return nil +} + +type cloudList struct { + public map[string]*cloudDetails + builtin map[string]*cloudDetails + personal map[string]*cloudDetails +} + +func newCloudList() *cloudList { + return &cloudList{ + make(map[string]*cloudDetails), + make(map[string]*cloudDetails), + make(map[string]*cloudDetails), + } } -func getCloudDetails() (map[string]*cloudDetails, error) { +func (c *cloudList) all() map[string]*cloudDetails { + if len(c.personal) == 0 && len(c.builtin) == 0 && len(c.personal) == 0 { + return nil + } + + result := make(map[string]*cloudDetails) + addAll := func(someClouds map[string]*cloudDetails) { + for name, cloud := range someClouds { + result[name] = cloud + } + } + + addAll(c.public) + addAll(c.builtin) + addAll(c.personal) + return result +} + +func listCloudDetails() (*cloudList, error) { clouds, _, err := jujucloud.PublicCloudMetadata(jujucloud.JujuPublicCloudsPath()) if err != nil { return nil, err } - details := make(map[string]*cloudDetails) + details := newCloudList() for name, cloud := range clouds { cloudDetails := makeCloudDetails(cloud) - details[name] = cloudDetails + details.public[name] = cloudDetails } - // Add in built in providers like "lxd" and "manual". - for name, cloud := range common.BuiltInProviders() { + // Add in built in clouds like localhost (lxd). + for name, cloud := range common.BuiltInClouds() { cloudDetails := makeCloudDetails(cloud) cloudDetails.Source = "built-in" - details[name] = cloudDetails + details.builtin[name] = cloudDetails } personalClouds, err := jujucloud.PersonalCloudMetadata() @@ -103,39 +147,19 @@ // Add to result with "local:" prefix. cloudDetails := makeCloudDetails(cloud) cloudDetails.Source = "local" - details[localPrefix+name] = cloudDetails + details.personal[localPrefix+name] = cloudDetails } - return details, nil -} - -// Public clouds sorted first, then personal ie has a prefix of "local:". -type cloudSourceOrder []string -func (a cloudSourceOrder) Len() int { return len(a) } -func (a cloudSourceOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a cloudSourceOrder) Less(i, j int) bool { - isLeftLocal := strings.HasPrefix(a[i], localPrefix) - isRightLocal := strings.HasPrefix(a[j], localPrefix) - if isLeftLocal == isRightLocal { - return a[i] < a[j] - } - return isRightLocal + return details, nil } // formatCloudsTabular returns a tabular summary of cloud information. func formatCloudsTabular(value interface{}) ([]byte, error) { - clouds, ok := value.(map[string]*cloudDetails) + clouds, ok := value.(*cloudList) if !ok { return nil, errors.Errorf("expected value of type %T, got %T", clouds, value) } - // For tabular we'll sort alphabetically, user clouds last. - var cloudNames []string - for name, _ := range clouds { - cloudNames = append(cloudNames, name) - } - sort.Sort(cloudSourceOrder(cloudNames)) - var out bytes.Buffer const ( // To format things into columns. @@ -151,27 +175,45 @@ fmt.Fprintln(tw, text) } p("CLOUD\tTYPE\tREGIONS") - for _, name := range cloudNames { - info := clouds[name] - var regions []string - for _, region := range info.Regions { - regions = append(regions, fmt.Sprint(region.Key)) - } - // TODO(wallyworld) - we should be smarter about handling - // long region text, for now we'll display the first 7 as - // that covers all clouds except AWS and Azure and will - // prevent wrapping on a reasonable terminal width. - regionCount := len(regions) - if regionCount > 7 { - regionCount = 7 + + cloudNamesSorted := func(someClouds map[string]*cloudDetails) []string { + // For tabular we'll sort alphabetically, user clouds last. + var names []string + for name, _ := range someClouds { + names = append(names, name) } - regionText := strings.Join(regions[:regionCount], ", ") - if len(regions) > 7 { - regionText = regionText + " ..." + sort.Strings(names) + return names + } + + printClouds := func(someClouds map[string]*cloudDetails) { + cloudNames := cloudNamesSorted(someClouds) + + for _, name := range cloudNames { + info := someClouds[name] + var regions []string + for _, region := range info.Regions { + regions = append(regions, fmt.Sprint(region.Key)) + } + // TODO(wallyworld) - we should be smarter about handling + // long region text, for now we'll display the first 7 as + // that covers all clouds except AWS and Azure and will + // prevent wrapping on a reasonable terminal width. + regionCount := len(regions) + if regionCount > 7 { + regionCount = 7 + } + regionText := strings.Join(regions[:regionCount], ", ") + if len(regions) > 7 { + regionText = regionText + " ..." + } + p(name, info.CloudType, regionText) } - p(name, info.CloudType, regionText) } - tw.Flush() + printClouds(clouds.public) + printClouds(clouds.builtin) + printClouds(clouds.personal) + tw.Flush() return out.Bytes(), nil } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/cloud/list_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/cloud/list_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/cloud/list_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/cloud/list_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -28,13 +28,11 @@ c.Assert(err, jc.ErrorIsNil) out := testing.Stdout(ctx) out = strings.Replace(out, "\n", "", -1) - // Just check a snippet of the output to make sure it looks ok. + // Just check couple of snippets of the output to make sure it looks ok. c.Assert(out, gc.Matches, `.*aws-china[ ]*ec2[ ]*cn-north-1.*`) // TODO(wallyworld) - uncomment when we build with go 1.3 or greater // LXD should be there too. - //c.Assert(out, gc.Matches, `.*lxd[ ]*lxd[ ]*localhost.*`) - // And also manual. - c.Assert(out, gc.Matches, `.*manual[ ]*manual[ ].*`) + // c.Assert(out, gc.Matches, `.*localhost[ ]*lxd[ ]*localhost.*`) } func (s *listSuite) TestListPublicAndPersonal(c *gc.C) { @@ -57,7 +55,7 @@ out = strings.Replace(out, "\n", "", -1) // Just check a snippet of the output to make sure it looks ok. // local: clouds are last. - c.Assert(out, gc.Matches, `.*local\:homestack[ ]*openstack[ ]*london$`) + c.Assert(out, jc.Contains, `local:homestack openstack london`) } func (s *listSuite) TestListYAML(c *gc.C) { @@ -78,7 +76,7 @@ c.Assert(out, gc.Matches, `.*{"aws":{"defined":"public","type":"ec2","auth-types":\["access-key"\].*`) } -func (s *showSuite) TestListPreservesRegionOrder(c *gc.C) { +func (s *listSuite) TestListPreservesRegionOrder(c *gc.C) { ctx, err := testing.RunCommand(c, cloud.NewListCloudsCommand(), "--format", "yaml") c.Assert(err, jc.ErrorIsNil) lines := strings.Split(testing.Stdout(ctx), "\n") diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/cloud/show.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/cloud/show.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/cloud/show.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/cloud/show.go 2016-05-17 20:01:14.000000000 +0000 @@ -118,3 +118,11 @@ } return result } + +func getCloudDetails() (map[string]*cloudDetails, error) { + result, err := listCloudDetails() + if err != nil { + return nil, errors.Trace(err) + } + return result.all(), nil +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/bootstrap.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/bootstrap.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/bootstrap.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/bootstrap.go 2016-05-17 20:01:14.000000000 +0000 @@ -5,10 +5,8 @@ import ( "fmt" - "io" "os" "strings" - "time" "github.com/juju/cmd" "github.com/juju/errors" @@ -18,22 +16,18 @@ "gopkg.in/juju/charm.v6-unstable" "launchpad.net/gnuflag" - apiblock "github.com/juju/juju/api/block" - "github.com/juju/juju/apiserver/params" jujucloud "github.com/juju/juju/cloud" - "github.com/juju/juju/cmd/juju/block" "github.com/juju/juju/cmd/juju/common" "github.com/juju/juju/cmd/modelcmd" "github.com/juju/juju/constraints" "github.com/juju/juju/environs" "github.com/juju/juju/environs/bootstrap" "github.com/juju/juju/environs/config" + "github.com/juju/juju/environs/sync" "github.com/juju/juju/feature" "github.com/juju/juju/instance" - "github.com/juju/juju/juju" "github.com/juju/juju/juju/osenv" "github.com/juju/juju/jujuclient" - "github.com/juju/juju/network" jujuversion "github.com/juju/juju/version" ) @@ -91,7 +85,7 @@ See also: add-credentials - create-model + add-model set-constraints` // defaultHostedModelName is the name of the hosted model created in each @@ -240,8 +234,9 @@ } var ( - environsPrepare = environs.Prepare - environsDestroy = environs.Destroy + environsPrepare = environs.Prepare + environsDestroy = environs.Destroy + waitForAgentInitialisation = common.WaitForAgentInitialisation ) var ambiguousCredentialError = errors.New(` @@ -516,6 +511,7 @@ BootstrapImage: c.BootstrapImage, Placement: c.Placement, UploadTools: c.UploadTools, + BuildToolsTarball: sync.BuildToolsTarball, AgentVersion: c.AgentVersion, MetadataDir: metadataDir, HostedModelConfig: hostedModelConfig, @@ -529,7 +525,7 @@ return errors.Trace(err) } - err = c.setBootstrapEndpointAddress(environ) + err = common.SetBootstrapEndpointAddress(c.ClientStore(), c.controllerName, environ) if err != nil { return errors.Annotate(err, "saving bootstrap endpoint address") } @@ -537,7 +533,7 @@ // To avoid race conditions when running scripted bootstraps, wait // for the controller's machine agent to be ready to accept commands // before exiting this bootstrap command. - return c.waitForAgentInitialisation(ctx) + return waitForAgentInitialisation(ctx, &c.ModelCommandBase, c.controllerName) } // getRegion returns the cloud.Region to use, based on the specified @@ -586,80 +582,6 @@ return regionNames } -var ( - bootstrapReadyPollDelay = 1 * time.Second - bootstrapReadyPollCount = 60 - blockAPI = getBlockAPI -) - -// getBlockAPI returns a block api for listing blocks. -func getBlockAPI(c *modelcmd.ModelCommandBase) (block.BlockListAPI, error) { - root, err := c.NewAPIRoot() - if err != nil { - return nil, err - } - return apiblock.NewClient(root), nil -} - -// tryAPI attempts to open the API and makes a trivial call -// to check if the API is available yet. -func (c *bootstrapCommand) tryAPI() error { - client, err := blockAPI(&c.ModelCommandBase) - if err == nil { - _, err = client.List() - closeErr := client.Close() - if closeErr != nil { - logger.Debugf("Error closing client: %v", closeErr) - } - } - return err -} - -// waitForAgentInitialisation polls the bootstrapped controller with a read-only -// command which will fail until the controller is fully initialised. -// TODO(wallyworld) - add a bespoke command to maybe the admin facade for this purpose. -func (c *bootstrapCommand) waitForAgentInitialisation(ctx *cmd.Context) error { - attempts := utils.AttemptStrategy{ - Min: bootstrapReadyPollCount, - Delay: bootstrapReadyPollDelay, - } - var ( - apiAttempts int - err error - ) - - apiAttempts = 1 - for attempt := attempts.Start(); attempt.Next(); apiAttempts++ { - err = c.tryAPI() - if err == nil { - ctx.Infof("Bootstrap complete, %s now available.", c.controllerName) - break - } - // As the API server is coming up, it goes through a number of steps. - // Initially the upgrade steps run, but the api server allows some - // calls to be processed during the upgrade, but not the list blocks. - // Logins are also blocked during space discovery. - // It is also possible that the underlying database causes connections - // to be dropped as it is initialising, or reconfiguring. These can - // lead to EOF or "connection is shut down" error messages. We skip - // these too, hoping that things come back up before the end of the - // retry poll count. - errorMessage := errors.Cause(err).Error() - switch { - case errors.Cause(err) == io.EOF, - strings.HasSuffix(errorMessage, "connection is shut down"), - strings.Contains(errorMessage, "spaces are still being discovered"): - ctx.Infof("Waiting for API to become available") - continue - case params.ErrCode(err) == params.CodeUpgradeInProgress: - ctx.Infof("Waiting for API to become available: %v", err) - continue - } - break - } - return errors.Annotatef(err, "unable to contact api server after %d attempts", apiAttempts) -} - // checkProviderType ensures the provider type is okay. func checkProviderType(envType string) error { featureflag.SetFlagsFromEnvironment(osenv.JujuFeatureFlagEnvKey) @@ -686,37 +608,3 @@ logger.Errorf("error cleaning up: %v", err) } } - -var allInstances = func(environ environs.Environ) ([]instance.Instance, error) { - return environ.AllInstances() -} - -// setBootstrapEndpointAddress writes the API endpoint address of the -// bootstrap server into the connection information. This should only be run -// once directly after Bootstrap. It assumes that there is just one instance -// in the environment - the bootstrap instance. -func (c *bootstrapCommand) setBootstrapEndpointAddress(environ environs.Environ) error { - instances, err := allInstances(environ) - if err != nil { - return errors.Trace(err) - } - length := len(instances) - if length == 0 { - return errors.Errorf("found no instances, expected at least one") - } - if length > 1 { - logger.Warningf("expected one instance, got %d", length) - } - bootstrapInstance := instances[0] - - // Don't use c.ConnectionEndpoint as it attempts to contact the state - // server if no addresses are found in connection info. - netAddrs, err := bootstrapInstance.Addresses() - if err != nil { - return errors.Annotate(err, "failed to get bootstrap instance addresses") - } - cfg := environ.Config() - apiPort := cfg.APIPort() - apiHostPorts := network.AddressesWithPort(netAddrs, apiPort) - return juju.UpdateControllerAddresses(c.ClientStore(), c.controllerName, nil, apiHostPorts...) -} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/bootstrap_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/bootstrap_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/bootstrap_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/bootstrap_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -5,13 +5,11 @@ import ( "fmt" - "io" "io/ioutil" "os" "path/filepath" "runtime" "strings" - "time" "github.com/juju/cmd" "github.com/juju/errors" @@ -24,15 +22,12 @@ "github.com/juju/version" gc "gopkg.in/check.v1" - "github.com/juju/juju/apiserver/params" "github.com/juju/juju/cloud" - "github.com/juju/juju/cmd/juju/block" "github.com/juju/juju/cmd/modelcmd" cmdtesting "github.com/juju/juju/cmd/testing" "github.com/juju/juju/constraints" "github.com/juju/juju/environs" "github.com/juju/juju/environs/bootstrap" - "github.com/juju/juju/environs/config" "github.com/juju/juju/environs/filestorage" "github.com/juju/juju/environs/gui" "github.com/juju/juju/environs/imagemetadata" @@ -49,7 +44,6 @@ "github.com/juju/juju/jujuclient/jujuclienttesting" "github.com/juju/juju/network" "github.com/juju/juju/provider/dummy" - "github.com/juju/juju/rpc" coretesting "github.com/juju/juju/testing" coretools "github.com/juju/juju/tools" jujuversion "github.com/juju/juju/version" @@ -59,8 +53,7 @@ coretesting.FakeJujuXDGDataHomeSuite testing.MgoSuite envtesting.ToolsFixture - mockBlockClient *mockBlockClient - store *jujuclienttesting.MemStore + store *jujuclienttesting.MemStore } var _ = gc.Suite(&BootstrapSuite{}) @@ -101,18 +94,8 @@ s.PatchValue(&envtools.BundleTools, toolstesting.GetMockBundleTools(c)) - s.mockBlockClient = &mockBlockClient{} - s.PatchValue(&blockAPI, func(c *modelcmd.ModelCommandBase) (block.BlockListAPI, error) { - err := s.mockBlockClient.loginError - if err != nil { - s.mockBlockClient.loginError = nil - return nil, err - } - if s.mockBlockClient.discoveringSpacesError > 0 { - s.mockBlockClient.discoveringSpacesError -= 1 - return nil, errors.New("spaces are still being discovered") - } - return s.mockBlockClient, nil + s.PatchValue(&waitForAgentInitialisation, func(*cmd.Context, *modelcmd.ModelCommandBase, string) error { + return nil }) // TODO(wallyworld) - add test data when tests are improved @@ -137,135 +120,6 @@ return modelcmd.Wrap(c) } -type mockBlockClient struct { - retryCount int - numRetries int - discoveringSpacesError int - loginError error -} - -var errOther = errors.New("other error") - -func (c *mockBlockClient) List() ([]params.Block, error) { - c.retryCount += 1 - if c.retryCount == 5 { - return nil, &rpc.RequestError{Message: params.CodeUpgradeInProgress, Code: params.CodeUpgradeInProgress} - } - if c.numRetries < 0 { - return nil, errOther - } - if c.retryCount < c.numRetries { - return nil, &rpc.RequestError{Message: params.CodeUpgradeInProgress, Code: params.CodeUpgradeInProgress} - } - return []params.Block{}, nil -} - -func (c *mockBlockClient) Close() error { - return nil -} - -func (s *BootstrapSuite) TestBootstrapAPIReadyRetries(c *gc.C) { - s.PatchValue(&bootstrapReadyPollDelay, 1*time.Millisecond) - s.PatchValue(&bootstrapReadyPollCount, 5) - defaultSeriesVersion := jujuversion.Current - // Force a dev version by having a non zero build number. - // This is because we have not uploaded any tools and auto - // upload is only enabled for dev versions. - defaultSeriesVersion.Build = 1234 - s.PatchValue(&jujuversion.Current, defaultSeriesVersion) - for _, t := range []struct { - numRetries int - err error - }{ - {0, nil}, // agent ready immediately - {2, nil}, // agent ready after 2 polls - {6, &rpc.RequestError{ - Message: params.CodeUpgradeInProgress, - Code: params.CodeUpgradeInProgress, - }}, // agent ready after 6 polls but that's too long - {-1, errOther}, // another error is returned - } { - resetJujuXDGDataHome(c) - dummy.Reset(c) - s.store = jujuclienttesting.NewMemStore() - - s.mockBlockClient.numRetries = t.numRetries - s.mockBlockClient.retryCount = 0 - _, err := coretesting.RunCommand( - c, s.newBootstrapCommand(), - "devcontroller", "dummy", "--auto-upgrade", - ) - c.Check(errors.Cause(err), gc.DeepEquals, t.err) - expectedRetries := t.numRetries - if t.numRetries <= 0 { - expectedRetries = 1 - } - // Only retry maximum of bootstrapReadyPollCount times. - if expectedRetries > 5 { - expectedRetries = 5 - } - c.Check(s.mockBlockClient.retryCount, gc.Equals, expectedRetries) - } -} - -func (s *BootstrapSuite) TestBootstrapAPIReadyWaitsForSpaceDiscovery(c *gc.C) { - s.PatchValue(&bootstrapReadyPollDelay, 1*time.Millisecond) - s.PatchValue(&bootstrapReadyPollCount, 5) - defaultSeriesVersion := jujuversion.Current - // Force a dev version by having a non zero build number. - // This is because we have not uploaded any tools and auto - // upload is only enabled for dev versions. - defaultSeriesVersion.Build = 1234 - s.PatchValue(&jujuversion.Current, defaultSeriesVersion) - resetJujuXDGDataHome(c) - - s.mockBlockClient.discoveringSpacesError = 2 - _, err := coretesting.RunCommand(c, s.newBootstrapCommand(), "devcontroller", "dummy", "--auto-upgrade") - c.Assert(err, jc.ErrorIsNil) - c.Assert(s.mockBlockClient.discoveringSpacesError, gc.Equals, 0) -} - -func (s *BootstrapSuite) TestBootstrapAPIReadyRetriesWithOpenEOFErr(c *gc.C) { - s.PatchValue(&bootstrapReadyPollDelay, 1*time.Millisecond) - s.PatchValue(&bootstrapReadyPollCount, 5) - defaultSeriesVersion := jujuversion.Current - // Force a dev version by having a non zero build number. - // This is because we have not uploaded any tools and auto - // upload is only enabled for dev versions. - defaultSeriesVersion.Build = 1234 - s.PatchValue(&jujuversion.Current, defaultSeriesVersion) - resetJujuXDGDataHome(c) - - s.mockBlockClient.numRetries = 0 - s.mockBlockClient.retryCount = 0 - s.mockBlockClient.loginError = io.EOF - _, err := coretesting.RunCommand(c, s.newBootstrapCommand(), "devcontroller", "dummy", "--auto-upgrade") - c.Check(err, jc.ErrorIsNil) - - c.Check(s.mockBlockClient.retryCount, gc.Equals, 1) -} - -func (s *BootstrapSuite) TestBootstrapAPIReadyStopsRetriesWithOpenErr(c *gc.C) { - s.PatchValue(&bootstrapReadyPollDelay, 1*time.Millisecond) - s.PatchValue(&bootstrapReadyPollCount, 5) - defaultSeriesVersion := jujuversion.Current - // Force a dev version by having a non zero build number. - // This is because we have not uploaded any tools and auto - // upload is only enabled for dev versions. - defaultSeriesVersion.Build = 1234 - s.PatchValue(&jujuversion.Current, defaultSeriesVersion) - - resetJujuXDGDataHome(c) - - s.mockBlockClient.numRetries = 0 - s.mockBlockClient.retryCount = 0 - s.mockBlockClient.loginError = errors.NewUnauthorized(nil, "") - _, err := coretesting.RunCommand(c, s.newBootstrapCommand(), "devcontroller", "dummy", "--auto-upgrade") - c.Check(err, jc.Satisfies, errors.IsUnauthorized) - - c.Check(s.mockBlockClient.retryCount, gc.Equals, 0) -} - func (s *BootstrapSuite) TestRunTests(c *gc.C) { for i, test := range bootstrapTests { c.Logf("\ntest %d: %s", i, test.info) @@ -316,7 +170,7 @@ s.store = jujuclienttesting.NewMemStore() } if test.version != "" { - useVersion := strings.Replace(test.version, "%LTS%", config.LatestLtsSeries(), 1) + useVersion := strings.Replace(test.version, "%LTS%", series.LatestLts(), 1) v := version.MustParseBinary(useVersion) restore = restore.Add(testing.PatchValue(&jujuversion.Current, v.Number)) restore = restore.Add(testing.PatchValue(&arch.HostArch, func() string { return v.Arch })) @@ -491,6 +345,11 @@ c.Check(err, gc.ErrorMatches, "controller name and cloud name are required") } +func (s *BootstrapSuite) TestRunCloudNameUnknown(c *gc.C) { + _, err := coretesting.RunCommand(c, s.newBootstrapCommand(), "my-controller", "unknown") + c.Check(err, gc.ErrorMatches, `unknown cloud "unknown", please try "juju update-clouds"`) +} + func (s *BootstrapSuite) TestCheckProviderProvisional(c *gc.C) { err := checkProviderType("devcontroller") c.Assert(err, jc.ErrorIsNil) @@ -859,6 +718,7 @@ func (s *BootstrapSuite) TestAutoSyncLocalSource(c *gc.C) { sourceDir := createToolsSource(c, vAll) s.PatchValue(&jujuversion.Current, version.MustParse("1.2.0")) + series.SetLatestLtsForTesting("trusty") resetJujuXDGDataHome(c) // Bootstrap the controller with the valid source. @@ -899,7 +759,7 @@ } func (s *BootstrapSuite) TestAutoUploadAfterFailedSync(c *gc.C) { - s.PatchValue(&series.HostSeries, func() string { return config.LatestLtsSeries() }) + s.PatchValue(&series.HostSeries, func() string { return series.LatestLts() }) s.setupAutoUploadTest(c, "1.7.3", "quantal") // Run command and check for that upload has been run for tools matching // the current juju version. diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/main.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/main.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/main.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/main.go 2016-05-17 20:01:14.000000000 +0000 @@ -13,6 +13,8 @@ "github.com/juju/loggo" rcmd "github.com/juju/romulus/cmd/commands" "github.com/juju/utils/featureflag" + utilsos "github.com/juju/utils/os" + "github.com/juju/utils/series" "github.com/juju/version" jujucmd "github.com/juju/juju/cmd" @@ -78,12 +80,13 @@ Common commands: + add-cloud Adds a user-defined cloud to Juju. add-credential Adds or replaces credentials for a cloud. add-relation Adds a relation between two services. add-unit Adds extra units of a deployed service. add-user Adds a Juju user to a controller. bootstrap Initializes a cloud environment. - create-model Creates a hosted model. + add-model Adds a hosted model. deploy Deploys a new service. expose Makes a service publicly available over the network. list-controllers Lists all controllers. @@ -103,20 +106,34 @@ // Main registers subcommands for the juju executable, and hands over control // to the cmd package. This function is not redundant with main, because it // provides an entry point for testing with arbitrary command line arguments. -func Main(args []string) { +// This function returns the exit code, for main to pass to os.Exit. +func Main(args []string) int { + return main{ + execCommand: exec.Command, + }.Run(args) +} + +// main is a type that captures dependencies for running the main function. +type main struct { + // execCommand abstracts away exec.Command. + execCommand func(command string, args ...string) *exec.Cmd +} + +// Run is the main entry point for the juju client. +func (m main) Run(args []string) int { ctx, err := cmd.DefaultContext() if err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) - os.Exit(2) + return 2 } - if shouldWarnJuju1x() { - warnJuju1x() - } + // note that this has to come before we init the juju home directory, + // since it relies on detecting the lack of said directory. + m.maybeWarnJuju1x() if err = juju.InitJujuXDGDataHome(); err != nil { fmt.Fprintf(os.Stderr, "error: %s\n", err) - os.Exit(2) + return 2 } for i := range x { @@ -124,16 +141,34 @@ } if len(args) == 2 && args[1] == string(x[0:2]) { os.Stdout.Write(x[2:]) - os.Exit(0) + return 0 } jcmd := NewJujuCommand(ctx) - os.Exit(cmd.Main(jcmd, ctx, args[1:])) + return cmd.Main(jcmd, ctx, args[1:]) } -func warnJuju1x() { - ver := "1.x" - out, err := execCommand(juju1xCmdName, "version").Output() +func (m main) maybeWarnJuju1x() { + if !shouldWarnJuju1x() { + return + } + ver, exists := m.juju1xVersion() + if !exists { + return + } + fmt.Fprintf(os.Stderr, ` + Welcome to Juju %s. If you meant to use Juju %s you can continue using it + with the command %s e.g. '%s switch'. + See https://jujucharms.com/docs/stable/introducing-2 for more details. +`[1:], jujuversion.Current, ver, juju1xCmdName, juju1xCmdName) +} + +func (m main) juju1xVersion() (ver string, exists bool) { + out, err := m.execCommand(juju1xCmdName, "version").Output() + if err == exec.ErrNotFound { + return "", false + } + ver = "1.x" if err == nil { v := strings.TrimSpace(string(out)) // parse so we can drop the series and arch @@ -142,22 +177,16 @@ ver = bin.Number.String() } } - fmt.Fprintf(os.Stderr, ` - Welcome to Juju %s. If you meant to use Juju %s you can continue using it - with the command %s e.g. '%s switch'. - See https://jujucharms.com/docs/stable/introducing-2 for more details. - `[1:], jujuversion.Current, ver, juju1xCmdName, juju1xCmdName) + return ver, true } -var execCommand = exec.Command -var execLookPath = exec.LookPath - func shouldWarnJuju1x() bool { - if _, err := execLookPath(juju1xCmdName); err != nil { + // this code only applies to Ubuntu, where we renamed Juju 1.x to juju-1. + ostype, err := series.GetOSFromSeries(series.HostSeries()) + if err != nil || ostype != utilsos.Ubuntu { return false } - return osenv.Juju1xEnvConfigExists() && - !juju2xConfigDataExists() + return osenv.Juju1xEnvConfigExists() && !juju2xConfigDataExists() } func juju2xConfigDataExists() bool { @@ -323,7 +352,7 @@ } // Manage controllers - r.Register(controller.NewCreateModelCommand()) + r.Register(controller.NewAddModelCommand()) r.Register(controller.NewDestroyCommand()) r.Register(controller.NewListModelsCommand()) r.Register(controller.NewKillCommand()) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/main_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/main_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/main_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/main_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -7,13 +7,10 @@ "fmt" "io/ioutil" "os" - "os/exec" "path/filepath" - "reflect" "runtime" "sort" "strings" - stdtesting "testing" "github.com/juju/cmd" gitjujutesting "github.com/juju/testing" @@ -38,6 +35,7 @@ type MainSuite struct { testing.FakeJujuXDGDataHomeSuite + gitjujutesting.PatchExecHelper } var _ = gc.Suite(&MainSuite{}) @@ -176,152 +174,181 @@ } } -func (s *MainSuite) TestFirstRun2xFrom1x(c *gc.C) { - // patch out lookpath to always return a nil error (and thus indicates success). - s.PatchValue(&execLookPath, func(s string) (string, error) { - c.Assert(s, gc.Equals, "juju-1") - return "we ignore this anyway", nil - }) +func (s *MainSuite) TestFirstRun2xFrom1xOnUbuntu(c *gc.C) { + if runtime.GOOS == "windows" { + // This test can't work on Windows and shouldn't need to + c.Skip("test doesn't work on Windows because Juju's 1.x and 2.x config directory are the same") + } - // patch out the exec.Command used to run juju-1 so that it runs our test helper instead. - s.PatchValue(&execCommand, func(command string, args ...string) *exec.Cmd { - cs := []string{"-test.run=TestFirstRun2xFrom1xHelper", "--", command} - cs = append(cs, args...) - cmd := exec.Command(os.Args[0], cs...) - cmd.Env = []string{"JUJU_WANT_HELPER_PROCESS=1"} - return cmd + // Code should only run on ubuntu series, so patch out the series for + // when non-ubuntu OSes run this test. + s.PatchValue(&series.HostSeries, func() string { return "trusty" }) + + argChan := make(chan []string, 1) + + execCommand := s.GetExecCommand(gitjujutesting.PatchExecConfig{ + Stdout: "1.25.0-trusty-amd64", + Args: argChan, }) // remove the new juju-home and create a fake old juju home. err := os.Remove(osenv.JujuXDGDataHome()) c.Assert(err, jc.ErrorIsNil) - oldhome := osenv.OldJujuHomeDir() - err = os.MkdirAll(oldhome, 0700) - c.Assert(err, jc.ErrorIsNil) - err = ioutil.WriteFile(filepath.Join(oldhome, "environments.yaml"), []byte("boo!"), 0600) - c.Assert(err, jc.ErrorIsNil) + makeValidOldHome(c) - // dump stderr to a file so we can examine it without any wacky re-running - // of the executable (since we need to mock things out.) - stderr, err := os.OpenFile(filepath.Join(oldhome, "stderr"), os.O_RDWR|os.O_CREATE, 0600) - c.Assert(err, jc.ErrorIsNil) - defer stderr.Close() - - // dump stdout to a file so it doesn't spam the test output. - stdout, err := os.OpenFile(filepath.Join(oldhome, "stdout"), os.O_RDWR|os.O_CREATE, 0600) - c.Assert(err, jc.ErrorIsNil) + var code int + f := func() { + code = main{ + execCommand: execCommand, + }.Run([]string{"juju", "version"}) + } - runMain(stderr, stdout, []string{"juju", "version"}) + stdout, stderr := gitjujutesting.CaptureOutput(c, f) - _, err = stderr.Seek(0, 0) - c.Assert(err, jc.ErrorIsNil) - output, err := ioutil.ReadAll(stderr) - c.Assert(err, jc.ErrorIsNil) + select { + case args := <-argChan: + c.Assert(args, gc.DeepEquals, []string{"juju-1", "version"}) + default: + c.Fatalf("Exec function not called.") + } - c.Check(err, jc.ErrorIsNil) - c.Check(string(output), gc.Equals, fmt.Sprintf(` + c.Check(code, gc.Equals, 0) + c.Check(string(stderr), gc.Equals, fmt.Sprintf(` Welcome to Juju %s. If you meant to use Juju 1.25.0 you can continue using it with the command juju-1 e.g. 'juju-1 switch'. See https://jujucharms.com/docs/stable/introducing-2 for more details. `[1:], jujuversion.Current)) + checkVersionOutput(c, string(stdout)) +} + +func (s *MainSuite) TestFirstRun2xFrom1xNotUbuntu(c *gc.C) { + // Code should only run on ubuntu series, so pretend to be something else. + s.PatchValue(&series.HostSeries, func() string { return "win8" }) + + argChan := make(chan []string, 1) + + // we shouldn't actually be running anything, but if we do, this will + // provide some consistent results. + execCommand := s.GetExecCommand(gitjujutesting.PatchExecConfig{ + Stdout: "1.25.0-trusty-amd64", + Args: argChan, + }) + + // remove the new juju-home and create a fake old juju home. + err := os.Remove(osenv.JujuXDGDataHome()) + c.Assert(err, jc.ErrorIsNil) + + makeValidOldHome(c) + + var code int + stdout, stderr := gitjujutesting.CaptureOutput(c, func() { + code = main{ + execCommand: execCommand, + }.Run([]string{"juju", "version"}) + }) + + c.Assert(code, gc.Equals, 0) + + assertNoArgs(c, argChan) + + c.Check(string(stderr), gc.Equals, "") + checkVersionOutput(c, string(stdout)) } func (s *MainSuite) TestNoWarn1xWith2xData(c *gc.C) { - // patch out lookpath to always return a nil error (and thus indicates success). - s.PatchValue(&execLookPath, func(s string) (string, error) { - c.Assert(s, gc.Equals, "juju-1") - return "we ignore this anyway", nil + // Code should only rnu on ubuntu series, so patch out the series for + // when non-ubuntu OSes run this test. + s.PatchValue(&series.HostSeries, func() string { return "trusty" }) + + argChan := make(chan []string, 1) + + // we shouldn't actually be running anything, but if we do, this will + // provide some consistent results. + execCommand := s.GetExecCommand(gitjujutesting.PatchExecConfig{ + Stdout: "1.25.0-trusty-amd64", + Args: argChan, }) // there should be a 2x home directory already created by the test setup. // create a fake old juju home. - oldhome := osenv.OldJujuHomeDir() - err := os.MkdirAll(oldhome, 0700) - c.Assert(err, jc.ErrorIsNil) - err = ioutil.WriteFile(filepath.Join(oldhome, "environments.yaml"), []byte("boo!"), 0600) - c.Assert(err, jc.ErrorIsNil) - - // dump stderr to a file so we can examine it without any wacky re-running - // of the executable (since we need to mock things out.) - stderr, err := os.OpenFile(filepath.Join(oldhome, "stderr"), os.O_RDWR|os.O_CREATE, 0600) - c.Assert(err, jc.ErrorIsNil) - defer stderr.Close() + makeValidOldHome(c) - // dump stdout to a file so it doesn't spam the test output. - stdout, err := os.OpenFile(filepath.Join(oldhome, "stdout"), os.O_RDWR|os.O_CREATE, 0600) - c.Assert(err, jc.ErrorIsNil) + var code int + stdout, stderr := gitjujutesting.CaptureOutput(c, func() { + code = main{ + execCommand: execCommand, + }.Run([]string{"juju", "version"}) + }) - runMain(stderr, stdout, []string{"juju", "version"}) + c.Assert(code, gc.Equals, 0) - _, err = stderr.Seek(0, 0) - c.Assert(err, jc.ErrorIsNil) - output, err := ioutil.ReadAll(stderr) - c.Assert(err, jc.ErrorIsNil) - c.Assert(string(output), gc.Equals, "") + assertNoArgs(c, argChan) + c.Assert(string(stderr), gc.Equals, "") + checkVersionOutput(c, string(stdout)) } func (s *MainSuite) TestNoWarnWithNo1xOr2xData(c *gc.C) { - // patch out lookpath to always return a nil error (and thus indicates success). - s.PatchValue(&execLookPath, func(s string) (string, error) { - c.Assert(s, gc.Equals, "juju-1") - return "we ignore this anyway", nil + // Code should only rnu on ubuntu series, so patch out the series for + // when non-ubuntu OSes run this test. + s.PatchValue(&series.HostSeries, func() string { return "trusty" }) + + argChan := make(chan []string, 1) + // we shouldn't actually be running anything, but if we do, this will + // provide some consistent results. + execCommand := s.GetExecCommand(gitjujutesting.PatchExecConfig{ + Stdout: "1.25.0-trusty-amd64", + Args: argChan, }) // remove the new juju-home. err := os.Remove(osenv.JujuXDGDataHome()) + c.Assert(err, jc.ErrorIsNil) // create fake (empty) old juju home. path := c.MkDir() s.PatchEnvironment("JUJU_HOME", path) - outdir := c.MkDir() - // dump stderr to a file so we can examine it without any wacky re-running - // of the executable (since we need to mock things out.) - stderr, err := os.OpenFile(filepath.Join(outdir, "stderr"), os.O_RDWR|os.O_CREATE, 0600) - c.Assert(err, jc.ErrorIsNil) - defer stderr.Close() + var code int + stdout, stderr := gitjujutesting.CaptureOutput(c, func() { + code = main{ + execCommand: execCommand, + }.Run([]string{"juju", "version"}) + }) - // dump stdout to a file so it doesn't spam the test output. - stdout, err := os.OpenFile(filepath.Join(outdir, "stdout"), os.O_RDWR|os.O_CREATE, 0600) - c.Assert(err, jc.ErrorIsNil) + c.Assert(code, gc.Equals, 0) - runMain(stderr, stdout, []string{"juju", "version"}) + assertNoArgs(c, argChan) + c.Assert(string(stderr), gc.Equals, "") + checkVersionOutput(c, string(stdout)) +} - _, err = stderr.Seek(0, 0) +func makeValidOldHome(c *gc.C) { + oldhome := osenv.OldJujuHomeDir() + err := os.MkdirAll(oldhome, 0700) c.Assert(err, jc.ErrorIsNil) - output, err := ioutil.ReadAll(stderr) + err = ioutil.WriteFile(filepath.Join(oldhome, "environments.yaml"), []byte("boo!"), 0600) c.Assert(err, jc.ErrorIsNil) - c.Assert(string(output), gc.Equals, "") } -func runMain(stderr, stdout *os.File, args []string) { - // we don't use patchvalue here because we need these reset as soon as we - // leave this function, so we don't interfere with test output later. - origErr := os.Stderr - defer func() { os.Stderr = origErr }() - origOut := os.Stdout - defer func() { os.Stdout = origOut }() - os.Stderr = stderr - os.Stdout = stdout - - Main(args) -} - -// This is a test helper that only runs after getting executed by -// MainSuite.TestFirstRun2xFrom1x. It simulates running juju-1 version. -func TestFirstRun2xFrom1xHelper(t *stdtesting.T) { - if os.Getenv("JUJU_WANT_HELPER_PROCESS") != "1" { - return +func checkVersionOutput(c *gc.C, output string) { + ver := version.Binary{ + Number: jujuversion.Current, + Arch: arch.HostArch(), + Series: series.HostSeries(), } - if !reflect.DeepEqual(os.Args[3:], []string{"juju-1", "version"}) { - fmt.Fprintf(os.Stderr, "unexpected command run: %q", os.Args[3:]) - os.Exit(1) - } + c.Check(output, gc.Equals, ver.String()+"\n") +} - fmt.Fprintf(os.Stdout, "1.25.0-trusty-amd64") - os.Exit(0) +func assertNoArgs(c *gc.C, argChan <-chan []string) { + select { + case args := <-argChan: + c.Fatalf("Exec function called when it shouldn't have been (with args %q).", args) + default: + // this is the good path - there shouldn't be any args, which indicates + // the executable was not called. + } } var commandNames = []string{ @@ -330,6 +357,7 @@ "add-credential", "add-machine", "add-machines", + "add-model", "add-relation", "add-space", "add-ssh-key", @@ -351,7 +379,6 @@ "collect-metrics", "create-backup", "create-budget", - "create-model", "create-storage-pool", "debug-hooks", "debug-log", diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/package_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/package_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/package_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/package_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -5,6 +5,7 @@ import ( "flag" + "os" "runtime" stdtesting "testing" @@ -29,6 +30,6 @@ // tool itself. func TestRunMain(t *stdtesting.T) { if *cmdtesting.FlagRunMain { - Main(flag.Args()) + os.Exit(Main(flag.Args())) } } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/ssh_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/ssh_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/ssh_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/ssh_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -38,6 +38,7 @@ func (s *SSHCommonSuite) SetUpTest(c *gc.C) { s.JujuConnSuite.SetUpTest(c) + ssh.ClearClientKeys() s.PatchValue(&getJujuExecutable, func() (string, error) { return "juju", nil }) s.bin = c.MkDir() diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/switch.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/switch.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/switch.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/switch.go 2016-05-17 20:01:14.000000000 +0000 @@ -139,11 +139,10 @@ if newControllerName != "" { // A controller was specified so see if we should use a local version. newControllerName, err = modelcmd.ResolveControllerName(c.Store, newControllerName) - if err == nil { - newName = modelcmd.JoinModelName(newControllerName, modelName) - } else { - newName = c.Target + if err != nil { + return errors.Trace(err) } + newName = modelcmd.JoinModelName(newControllerName, modelName) } else { if currentControllerName == "" { return unknownSwitchTargetError(c.Target) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/switch_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/switch_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/switch_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/switch_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -82,6 +82,13 @@ c.Assert(coretesting.Stdout(ctx), gc.Equals, "a-controller\n") } +func (s *SwitchSimpleSuite) TestUnknownControllerNameReturnsError(c *gc.C) { + s.addController(c, "a-controller") + s.currentController = "a-controller" + _, err := s.run(c, "another-controller:modela") + c.Assert(err, gc.ErrorMatches, "controller another-controller not found") +} + func (s *SwitchSimpleSuite) TestNoArgsCurrentModel(c *gc.C) { s.addController(c, "a-controller") s.currentController = "a-controller" diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/upgradejuju_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/upgradejuju_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/commands/upgradejuju_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/commands/upgradejuju_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -22,7 +22,6 @@ apiservertesting "github.com/juju/juju/apiserver/testing" cmdcommon "github.com/juju/juju/cmd/juju/common" "github.com/juju/juju/cmd/modelcmd" - "github.com/juju/juju/environs/config" "github.com/juju/juju/environs/filestorage" "github.com/juju/juju/environs/sync" envtesting "github.com/juju/juju/environs/testing" @@ -361,7 +360,7 @@ for _, uploaded := range test.expectUploaded { // Substitute latest LTS for placeholder in expected series for uploaded tools - uploaded = strings.Replace(uploaded, "%LTS%", config.LatestLtsSeries(), 1) + uploaded = strings.Replace(uploaded, "%LTS%", series.LatestLts(), 1) vers := version.MustParseBinary(uploaded) s.checkToolsUploaded(c, vers, agentVersion) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/common/cloud.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/common/cloud.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/common/cloud.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/common/cloud.go 2016-05-17 20:01:14.000000000 +0000 @@ -11,7 +11,7 @@ "github.com/juju/juju/environs" ) -var logger = loggo.GetLogger("juju.cmd.juju.cloud") +var logger = loggo.GetLogger("juju.cmd.juju.common") // CloudOrProvider finds and returns cloud or provider. func CloudOrProvider(cloudName string, cloudByNameFunc func(string) (*cloud.Cloud, error)) (cloud *cloud.Cloud, err error) { @@ -19,8 +19,8 @@ if !errors.IsNotFound(err) { return nil, err } - builtInProviders := BuiltInProviders() - if builtIn, ok := builtInProviders[cloudName]; !ok { + builtInClouds := BuiltInClouds() + if builtIn, ok := builtInClouds[cloudName]; !ok { return nil, errors.NotValidf("cloud %v", cloudName) } else { cloud = &builtIn @@ -29,36 +29,20 @@ return cloud, nil } -// BuiltInProviders returns cloud information for those +// BuiltInClouds returns cloud information for those // providers which are built in to Juju. -func BuiltInProviders() map[string]cloud.Cloud { +func BuiltInClouds() map[string]cloud.Cloud { + // TODO (anastasiamac 2016-04-14) + // This whole method will be redundant after we move to 1.3+. builtIn := make(map[string]cloud.Cloud) - for _, name := range cloud.BuiltInProviderNames { - provider, err := environs.Provider(name) + for name, aCloud := range cloud.BuiltInClouds { + _, err := environs.Provider(aCloud.Type) if err != nil { // Should never happen but it will on go 1.2 // because lxd provider is not built. logger.Warningf("cloud %q not available on this platform", name) continue } - var regions []cloud.Region - if detector, ok := provider.(environs.CloudRegionDetector); ok { - regions, err = detector.DetectRegions() - if err != nil && !errors.IsNotFound(err) { - logger.Warningf("could not detect regions for %q: %v", name, err) - } - } - aCloud := cloud.Cloud{ - Type: name, - Regions: regions, - } - schema := provider.CredentialSchemas() - for authType := range schema { - if authType == cloud.EmptyAuthType { - continue - } - aCloud.AuthTypes = append(aCloud.AuthTypes, authType) - } builtIn[name] = aCloud } return builtIn diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/common/controller.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/common/controller.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/common/controller.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/common/controller.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,132 @@ +// Copyright 2016 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package common + +import ( + "io" + "strings" + "time" + + "github.com/juju/cmd" + "github.com/juju/errors" + "github.com/juju/utils" + + apiblock "github.com/juju/juju/api/block" + "github.com/juju/juju/apiserver/params" + "github.com/juju/juju/cmd/juju/block" + "github.com/juju/juju/cmd/modelcmd" + "github.com/juju/juju/environs" + "github.com/juju/juju/instance" + "github.com/juju/juju/juju" + "github.com/juju/juju/jujuclient" + "github.com/juju/juju/network" +) + +var allInstances = func(environ environs.Environ) ([]instance.Instance, error) { + return environ.AllInstances() +} + +// SetBootstrapEndpointAddress writes the API endpoint address of the +// bootstrap server into the connection information. This should only be run +// once directly after Bootstrap. It assumes that there is just one instance +// in the environment - the bootstrap instance. +func SetBootstrapEndpointAddress(store jujuclient.ControllerStore, controllerName string, environ environs.Environ) error { + instances, err := allInstances(environ) + if err != nil { + return errors.Trace(err) + } + length := len(instances) + if length == 0 { + return errors.Errorf("found no instances, expected at least one") + } + if length > 1 { + logger.Warningf("expected one instance, got %d", length) + } + bootstrapInstance := instances[0] + + // Don't use c.ConnectionEndpoint as it attempts to contact the state + // server if no addresses are found in connection info. + netAddrs, err := bootstrapInstance.Addresses() + if err != nil { + return errors.Annotate(err, "failed to get bootstrap instance addresses") + } + cfg := environ.Config() + apiPort := cfg.APIPort() + apiHostPorts := network.AddressesWithPort(netAddrs, apiPort) + return juju.UpdateControllerAddresses(store, controllerName, nil, apiHostPorts...) +} + +var ( + bootstrapReadyPollDelay = 1 * time.Second + bootstrapReadyPollCount = 60 + blockAPI = getBlockAPI +) + +// getBlockAPI returns a block api for listing blocks. +func getBlockAPI(c *modelcmd.ModelCommandBase) (block.BlockListAPI, error) { + root, err := c.NewAPIRoot() + if err != nil { + return nil, err + } + return apiblock.NewClient(root), nil +} + +// tryAPI attempts to open the API and makes a trivial call +// to check if the API is available yet. +func tryAPI(c *modelcmd.ModelCommandBase) error { + client, err := blockAPI(c) + if err == nil { + _, err = client.List() + closeErr := client.Close() + if closeErr != nil { + logger.Debugf("Error closing client: %v", closeErr) + } + } + return err +} + +// WaitForAgentInitialisation polls the bootstrapped controller with a read-only +// command which will fail until the controller is fully initialised. +// TODO(wallyworld) - add a bespoke command to maybe the admin facade for this purpose. +func WaitForAgentInitialisation(ctx *cmd.Context, c *modelcmd.ModelCommandBase, controllerName string) error { + attempts := utils.AttemptStrategy{ + Min: bootstrapReadyPollCount, + Delay: bootstrapReadyPollDelay, + } + var ( + apiAttempts int + err error + ) + + apiAttempts = 1 + for attempt := attempts.Start(); attempt.Next(); apiAttempts++ { + err = tryAPI(c) + if err == nil { + ctx.Infof("Bootstrap complete, %s now available.", controllerName) + break + } + // As the API server is coming up, it goes through a number of steps. + // Initially the upgrade steps run, but the api server allows some + // calls to be processed during the upgrade, but not the list blocks. + // Logins are also blocked during space discovery. + // It is also possible that the underlying database causes connections + // to be dropped as it is initialising, or reconfiguring. These can + // lead to EOF or "connection is shut down" error messages. We skip + // these too, hoping that things come back up before the end of the + // retry poll count. + errorMessage := errors.Cause(err).Error() + switch { + case errors.Cause(err) == io.EOF, + strings.HasSuffix(errorMessage, "connection is shut down"), + strings.Contains(errorMessage, "spaces are still being discovered"): + ctx.Infof("Waiting for API to become available") + continue + case params.ErrCode(err) == params.CodeUpgradeInProgress: + ctx.Infof("Waiting for API to become available: %v", err) + continue + } + break + } + return errors.Annotatef(err, "unable to contact api server after %d attempts", apiAttempts) +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/common/controller_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/common/controller_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/common/controller_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/common/controller_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,135 @@ +// Copyright 2016 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package common + +import ( + "io" + "time" + + "github.com/juju/errors" + jc "github.com/juju/testing/checkers" + gc "gopkg.in/check.v1" + + "github.com/juju/juju/apiserver/params" + "github.com/juju/juju/cmd/juju/block" + "github.com/juju/juju/cmd/modelcmd" + cmdtesting "github.com/juju/juju/cmd/testing" + "github.com/juju/juju/rpc" + "github.com/juju/juju/testing" + "github.com/juju/juju/version" +) + +var _ = gc.Suite(&controllerSuite{}) + +type controllerSuite struct { + testing.BaseSuite + mockBlockClient *mockBlockClient +} + +func (s *controllerSuite) SetUpTest(c *gc.C) { + s.mockBlockClient = &mockBlockClient{} + s.PatchValue(&blockAPI, func(*modelcmd.ModelCommandBase) (block.BlockListAPI, error) { + err := s.mockBlockClient.loginError + if err != nil { + s.mockBlockClient.loginError = nil + return nil, err + } + if s.mockBlockClient.discoveringSpacesError > 0 { + s.mockBlockClient.discoveringSpacesError -= 1 + return nil, errors.New("spaces are still being discovered") + } + return s.mockBlockClient, nil + }) +} + +type mockBlockClient struct { + retryCount int + numRetries int + discoveringSpacesError int + loginError error +} + +var errOther = errors.New("other error") + +func (c *mockBlockClient) List() ([]params.Block, error) { + c.retryCount += 1 + if c.retryCount == 5 { + return nil, &rpc.RequestError{Message: params.CodeUpgradeInProgress, Code: params.CodeUpgradeInProgress} + } + if c.numRetries < 0 { + return nil, errOther + } + if c.retryCount < c.numRetries { + return nil, &rpc.RequestError{Message: params.CodeUpgradeInProgress, Code: params.CodeUpgradeInProgress} + } + return []params.Block{}, nil +} + +func (c *mockBlockClient) Close() error { + return nil +} + +func (s *controllerSuite) TestWaitForAgentAPIReadyRetries(c *gc.C) { + s.PatchValue(&bootstrapReadyPollDelay, 1*time.Millisecond) + s.PatchValue(&bootstrapReadyPollCount, 5) + defaultSeriesVersion := version.Current + // Force a dev version by having a non zero build number. + // This is because we have not uploaded any tools and auto + // upload is only enabled for dev versions. + defaultSeriesVersion.Build = 1234 + s.PatchValue(&version.Current, defaultSeriesVersion) + for _, t := range []struct { + numRetries int + err error + }{ + {0, nil}, // agent ready immediately + {2, nil}, // agent ready after 2 polls + {6, &rpc.RequestError{ + Message: params.CodeUpgradeInProgress, + Code: params.CodeUpgradeInProgress, + }}, // agent ready after 6 polls but that's too long + {-1, errOther}, // another error is returned + } { + s.mockBlockClient.numRetries = t.numRetries + s.mockBlockClient.retryCount = 0 + err := WaitForAgentInitialisation(cmdtesting.NullContext(c), nil, "controller") + c.Check(errors.Cause(err), gc.DeepEquals, t.err) + expectedRetries := t.numRetries + if t.numRetries <= 0 { + expectedRetries = 1 + } + // Only retry maximum of bootstrapReadyPollCount times. + if expectedRetries > 5 { + expectedRetries = 5 + } + c.Check(s.mockBlockClient.retryCount, gc.Equals, expectedRetries) + } +} + +func (s *controllerSuite) TestWaitForAgentAPIReadyWaitsForSpaceDiscovery(c *gc.C) { + s.mockBlockClient.discoveringSpacesError = 2 + err := WaitForAgentInitialisation(cmdtesting.NullContext(c), nil, "controller") + c.Assert(err, jc.ErrorIsNil) + c.Assert(s.mockBlockClient.discoveringSpacesError, gc.Equals, 0) +} + +func (s *controllerSuite) TestWaitForAgentAPIReadyRetriesWithOpenEOFErr(c *gc.C) { + s.mockBlockClient.numRetries = 0 + s.mockBlockClient.retryCount = 0 + s.mockBlockClient.loginError = io.EOF + err := WaitForAgentInitialisation(cmdtesting.NullContext(c), nil, "controller") + c.Check(err, jc.ErrorIsNil) + + c.Check(s.mockBlockClient.retryCount, gc.Equals, 1) +} + +func (s *controllerSuite) TestWaitForAgentAPIReadyStopsRetriesWithOpenErr(c *gc.C) { + s.mockBlockClient.numRetries = 0 + s.mockBlockClient.retryCount = 0 + s.mockBlockClient.loginError = errors.NewUnauthorized(nil, "") + err := WaitForAgentInitialisation(cmdtesting.NullContext(c), nil, "controller") + c.Check(err, jc.Satisfies, errors.IsUnauthorized) + + c.Check(s.mockBlockClient.retryCount, gc.Equals, 0) +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/addmodel.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/addmodel.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/addmodel.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/addmodel.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,225 @@ +// Copyright 2015 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package controller + +import ( + "strings" + + "github.com/juju/cmd" + "github.com/juju/errors" + "github.com/juju/names" + "launchpad.net/gnuflag" + + "github.com/juju/juju/apiserver/params" + "github.com/juju/juju/cloud" + "github.com/juju/juju/cmd/juju/common" + "github.com/juju/juju/cmd/modelcmd" + "github.com/juju/juju/jujuclient" +) + +// NewAddModelCommand returns a command to add a model. +func NewAddModelCommand() cmd.Command { + return modelcmd.WrapController(&addModelCommand{ + credentialStore: jujuclient.NewFileCredentialStore(), + }) +} + +// addModelCommand calls the API to add a new model. +type addModelCommand struct { + modelcmd.ControllerCommandBase + api CreateModelAPI + credentialStore jujuclient.CredentialStore + + Name string + Owner string + CredentialSpec string + CloudName string + CloudType string + CredentialName string + Config common.ConfigFlag +} + +const addModelHelpDoc = ` +This command will add another model within the current Juju +Controller. The provider has to match, and the model config must +specify all the required configuration values for the provider. + +If configuration values are passed by both extra command line +arguments and the --config option, the command line args take +priority. + +If adding a model in a controller for which you are not the +administrator, the cloud credentials and authorized ssh keys must +be specified. The credentials are specified using the argument +--credential :. The authorized ssh keys are +specified using a --config argument, either authorized=keys=value +or via a config yaml file. + +Any credentials used must be for a cloud with the same provider +type as the controller. Controller administrators do not have to +specify credentials or ssh keys; by default, the credentials and +keys used to bootstrap the controller are used if no others are +specified. + +Examples: + + juju add-model new-model + + juju add-model new-model --config aws-creds.yaml --config image-stream=daily + + juju add-model new-model --credential aws:mysekrets --config authorized-keys="ssh-rsa ..." + +See Also: + juju help grant +` + +func (c *addModelCommand) Info() *cmd.Info { + return &cmd.Info{ + Name: "add-model", + Args: " [--config key=[value] ...] [--credential :]", + Purpose: "Add a model within the Juju Model Server", + Doc: strings.TrimSpace(addModelHelpDoc), + } +} + +func (c *addModelCommand) SetFlags(f *gnuflag.FlagSet) { + f.StringVar(&c.Owner, "owner", "", "The owner of the new model if not the current user") + f.StringVar(&c.CredentialSpec, "credential", "", "The name of the cloud and credentials the new model uses to create cloud resources") + f.Var(&c.Config, "config", "Specify a controller config file, or one or more controller configuration options (--config config.yaml [--config k=v ...])") +} + +func (c *addModelCommand) Init(args []string) error { + if len(args) == 0 { + return errors.New("model name is required") + } + c.Name, args = args[0], args[1:] + + if c.Owner != "" && !names.IsValidUser(c.Owner) { + return errors.Errorf("%q is not a valid user", c.Owner) + } + + if c.CredentialSpec != "" { + parts := strings.Split(c.CredentialSpec, ":") + if len(parts) < 2 { + return errors.Errorf("invalid cloud credential %s, expected :", c.CredentialSpec) + } + c.CloudName = parts[0] + if cloud, err := common.CloudOrProvider(c.CloudName, cloud.CloudByName); err != nil { + return errors.Trace(err) + } else { + c.CloudType = cloud.Type + } + c.CredentialName = parts[1] + } + return nil +} + +type CreateModelAPI interface { + Close() error + ConfigSkeleton(provider, region string) (params.ModelConfig, error) + CreateModel(owner string, account, config map[string]interface{}) (params.Model, error) +} + +func (c *addModelCommand) getAPI() (CreateModelAPI, error) { + if c.api != nil { + return c.api, nil + } + return c.NewModelManagerAPIClient() +} + +func (c *addModelCommand) Run(ctx *cmd.Context) error { + client, err := c.getAPI() + if err != nil { + return errors.Trace(err) + } + defer client.Close() + + store := c.ClientStore() + controllerName := c.ControllerName() + accountName, err := store.CurrentAccount(controllerName) + if err != nil { + return errors.Trace(err) + } + currentAccount, err := store.AccountByName(controllerName, accountName) + if err != nil { + return errors.Trace(err) + } + + modelOwner := currentAccount.User + if c.Owner != "" { + if !names.IsValidUser(c.Owner) { + return errors.Errorf("%q is not a valid user name", c.Owner) + } + modelOwner = names.NewUserTag(c.Owner).Canonical() + } + + serverSkeleton, err := client.ConfigSkeleton(c.CloudType, "") + if err != nil { + return errors.Trace(err) + } + + attrs, err := c.getConfigValues(ctx, serverSkeleton) + if err != nil { + return errors.Trace(err) + } + + accountDetails := map[string]interface{}{} + if c.CredentialName != "" { + cred, _, _, err := modelcmd.GetCredentials( + c.credentialStore, "", c.CredentialName, c.CloudName, c.CloudType, + ) + if err != nil { + return errors.Trace(err) + } + for k, v := range cred.Attributes() { + accountDetails[k] = v + } + } + model, err := client.CreateModel(modelOwner, accountDetails, attrs) + if err != nil { + return errors.Trace(err) + } + if modelOwner == currentAccount.User { + controllerName := c.ControllerName() + accountName := c.AccountName() + if err := store.UpdateModel(controllerName, accountName, c.Name, jujuclient.ModelDetails{ + model.UUID, + }); err != nil { + return errors.Trace(err) + } + if err := store.SetCurrentModel(controllerName, accountName, c.Name); err != nil { + return errors.Trace(err) + } + ctx.Infof("added model %q", c.Name) + } else { + ctx.Infof("added model %q for %q", c.Name, c.Owner) + } + + return nil +} + +func (c *addModelCommand) getConfigValues(ctx *cmd.Context, serverSkeleton params.ModelConfig) (map[string]interface{}, error) { + configValues := make(map[string]interface{}) + for key, value := range serverSkeleton { + configValues[key] = value + } + configAttr, err := c.Config.ReadAttrs(ctx) + if err != nil { + return nil, errors.Annotate(err, "unable to parse config") + } + for key, value := range configAttr { + configValues[key] = value + } + configValues["name"] = c.Name + coercedValues, err := common.ConformYAML(configValues) + if err != nil { + return nil, errors.Annotatef(err, "unable to parse config") + } + stringParams, ok := coercedValues.(map[string]interface{}) + if !ok { + return nil, errors.New("params must contain a YAML map with string keys") + } + + return stringParams, nil +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/addmodel_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/addmodel_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/addmodel_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/addmodel_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,318 @@ +// Copyright 2015 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package controller_test + +import ( + "io/ioutil" + + "github.com/juju/cmd" + "github.com/juju/errors" + jc "github.com/juju/testing/checkers" + "github.com/juju/utils" + gc "gopkg.in/check.v1" + "gopkg.in/yaml.v2" + + "github.com/juju/juju/apiserver/params" + "github.com/juju/juju/cloud" + "github.com/juju/juju/cmd/juju/controller" + "github.com/juju/juju/cmd/modelcmd" + "github.com/juju/juju/jujuclient" + "github.com/juju/juju/jujuclient/jujuclienttesting" + _ "github.com/juju/juju/provider/ec2" + "github.com/juju/juju/testing" +) + +type addSuite struct { + testing.FakeJujuXDGDataHomeSuite + fake *fakeCreateClient + store *jujuclienttesting.MemStore +} + +var _ = gc.Suite(&addSuite{}) + +func (s *addSuite) SetUpTest(c *gc.C) { + s.FakeJujuXDGDataHomeSuite.SetUpTest(c) + s.fake = &fakeCreateClient{ + model: params.Model{ + Name: "test", + UUID: "fake-model-uuid", + OwnerTag: "ignored-for-now", + }, + } + + // Set up the current controller, and write just enough info + // so we don't try to refresh + controllerName := "local.test-master" + err := modelcmd.WriteCurrentController(controllerName) + c.Assert(err, jc.ErrorIsNil) + + s.store = jujuclienttesting.NewMemStore() + s.store.Controllers["local.test-master"] = jujuclient.ControllerDetails{} + s.store.Accounts[controllerName] = &jujuclient.ControllerAccounts{ + Accounts: map[string]jujuclient.AccountDetails{ + "bob@local": {User: "bob@local"}, + }, + CurrentAccount: "bob@local", + } + s.store.Credentials["aws"] = cloud.CloudCredential{ + AuthCredentials: map[string]cloud.Credential{ + "secrets": cloud.NewCredential(cloud.AccessKeyAuthType, map[string]string{ + "access-key": "key", + "secret-key": "sekret", + }), + }, + } +} + +func (s *addSuite) run(c *gc.C, args ...string) (*cmd.Context, error) { + command, _ := controller.NewAddModelCommandForTest(s.fake, s.store, s.store) + return testing.RunCommand(c, command, args...) +} + +func (s *addSuite) TestInit(c *gc.C) { + + for i, test := range []struct { + args []string + err string + name string + owner string + values map[string]interface{} + }{ + { + err: "model name is required", + }, { + args: []string{"new-model"}, + name: "new-model", + }, { + args: []string{"new-model", "--owner", "foo"}, + name: "new-model", + owner: "foo", + }, { + args: []string{"new-model", "--owner", "not=valid"}, + err: `"not=valid" is not a valid user`, + }, { + args: []string{"new-model", "--credential", "secrets"}, + err: `invalid cloud credential secrets, expected :`, + }, { + args: []string{"new-model", "--config", "key=value", "--config", "key2=value2"}, + name: "new-model", + values: map[string]interface{}{"key": "value", "key2": "value2"}, + }, + } { + c.Logf("test %d", i) + wrappedCommand, command := controller.NewAddModelCommandForTest(nil, s.store, s.store) + err := testing.InitCommand(wrappedCommand, test.args) + if test.err != "" { + c.Assert(err, gc.ErrorMatches, test.err) + continue + } + + c.Assert(err, jc.ErrorIsNil) + c.Assert(command.Name, gc.Equals, test.name) + c.Assert(command.Owner, gc.Equals, test.owner) + attrs, err := command.Config.ReadAttrs(nil) + c.Assert(err, jc.ErrorIsNil) + if len(test.values) == 0 { + c.Assert(attrs, gc.HasLen, 0) + } else { + c.Assert(attrs, jc.DeepEquals, test.values) + } + } +} + +func (s *addSuite) TestAddExistingName(c *gc.C) { + // If there's any model details existing, we just overwrite them. The + // controller will error out if the model already exists. Overwriting + // means we'll replace any stale details from an previously existing + // model with the same name. + err := s.store.UpdateModel("local.test-master", "bob@local", "test", jujuclient.ModelDetails{ + "stale-uuid", + }) + c.Assert(err, jc.ErrorIsNil) + + _, err = s.run(c, "test") + c.Assert(err, jc.ErrorIsNil) + + details, err := s.store.ModelByName("local.test-master", "bob@local", "test") + c.Assert(err, jc.ErrorIsNil) + c.Assert(details, jc.DeepEquals, &jujuclient.ModelDetails{"fake-model-uuid"}) +} + +func (s *addSuite) TestCredentialsPassedThrough(c *gc.C) { + _, err := s.run(c, "test", "--credential", "aws:secrets") + c.Assert(err, jc.ErrorIsNil) + + c.Assert(s.fake.config["type"], gc.Equals, "ec2") + c.Assert(s.fake.account, jc.DeepEquals, map[string]interface{}{ + "access-key": "key", + "secret-key": "sekret", + }) +} + +func (s *addSuite) TestComandLineConfigPassedThrough(c *gc.C) { + _, err := s.run(c, "test", "--config", "account=magic", "--config", "cloud=special") + c.Assert(err, jc.ErrorIsNil) + + c.Assert(s.fake.config["account"], gc.Equals, "magic") + c.Assert(s.fake.config["cloud"], gc.Equals, "special") +} + +func (s *addSuite) TestConfigFileValuesPassedThrough(c *gc.C) { + config := map[string]string{ + "account": "magic", + "cloud": "9", + } + bytes, err := yaml.Marshal(config) + c.Assert(err, jc.ErrorIsNil) + file, err := ioutil.TempFile(c.MkDir(), "") + c.Assert(err, jc.ErrorIsNil) + file.Write(bytes) + file.Close() + + _, err = s.run(c, "test", "--config", file.Name()) + c.Assert(err, jc.ErrorIsNil) + c.Assert(s.fake.config["account"], gc.Equals, "magic") + c.Assert(s.fake.config["cloud"], gc.Equals, "9") +} + +func (s *addSuite) TestConfigFileWithNestedMaps(c *gc.C) { + nestedConfig := map[string]interface{}{ + "account": "magic", + "cloud": "9", + } + config := map[string]interface{}{ + "foo": "bar", + "nested": nestedConfig, + } + + bytes, err := yaml.Marshal(config) + c.Assert(err, jc.ErrorIsNil) + file, err := ioutil.TempFile(c.MkDir(), "") + c.Assert(err, jc.ErrorIsNil) + file.Write(bytes) + file.Close() + + _, err = s.run(c, "test", "--config", file.Name()) + c.Assert(err, jc.ErrorIsNil) + c.Assert(s.fake.config["foo"], gc.Equals, "bar") + c.Assert(s.fake.config["nested"], jc.DeepEquals, nestedConfig) +} + +func (s *addSuite) TestConfigFileFailsToConform(c *gc.C) { + nestedConfig := map[int]interface{}{ + 9: "9", + } + config := map[string]interface{}{ + "foo": "bar", + "nested": nestedConfig, + } + bytes, err := yaml.Marshal(config) + c.Assert(err, jc.ErrorIsNil) + file, err := ioutil.TempFile(c.MkDir(), "") + c.Assert(err, jc.ErrorIsNil) + file.Write(bytes) + file.Close() + + _, err = s.run(c, "test", "--config", file.Name()) + c.Assert(err, gc.ErrorMatches, `unable to parse config: map keyed with non-string value`) +} + +func (s *addSuite) TestConfigFileFormatError(c *gc.C) { + file, err := ioutil.TempFile(c.MkDir(), "") + c.Assert(err, jc.ErrorIsNil) + file.Write(([]byte)("not: valid: yaml")) + file.Close() + + _, err = s.run(c, "test", "--config", file.Name()) + c.Assert(err, gc.ErrorMatches, `unable to parse config: yaml: .*`) +} + +func (s *addSuite) TestConfigFileDoesntExist(c *gc.C) { + _, err := s.run(c, "test", "--config", "missing-file") + errMsg := ".*" + utils.NoSuchFileErrRegexp + c.Assert(err, gc.ErrorMatches, errMsg) +} + +func (s *addSuite) TestConfigValuePrecedence(c *gc.C) { + config := map[string]string{ + "account": "magic", + "cloud": "9", + } + bytes, err := yaml.Marshal(config) + c.Assert(err, jc.ErrorIsNil) + file, err := ioutil.TempFile(c.MkDir(), "") + c.Assert(err, jc.ErrorIsNil) + file.Write(bytes) + file.Close() + + _, err = s.run(c, "test", "--config", file.Name(), "--config", "account=magic", "--config", "cloud=special") + c.Assert(err, jc.ErrorIsNil) + c.Assert(s.fake.config["account"], gc.Equals, "magic") + c.Assert(s.fake.config["cloud"], gc.Equals, "special") +} + +func (s *addSuite) TestAddErrorRemoveConfigstoreInfo(c *gc.C) { + s.fake.err = errors.New("bah humbug") + + _, err := s.run(c, "test") + c.Assert(err, gc.ErrorMatches, "bah humbug") + + _, err = s.store.ModelByName("local.test-master", "bob@local", "test") + c.Assert(err, jc.Satisfies, errors.IsNotFound) +} + +func (s *addSuite) TestAddStoresValues(c *gc.C) { + _, err := s.run(c, "test") + c.Assert(err, jc.ErrorIsNil) + + model, err := s.store.ModelByName("local.test-master", "bob@local", "test") + c.Assert(err, jc.ErrorIsNil) + c.Assert(model, jc.DeepEquals, &jujuclient.ModelDetails{"fake-model-uuid"}) +} + +func (s *addSuite) TestNoEnvCacheOtherUser(c *gc.C) { + _, err := s.run(c, "test", "--owner", "zeus") + c.Assert(err, jc.ErrorIsNil) + + // Creating a model for another user does not update the model cache. + _, err = s.store.ModelByName("local.test-master", "bob@local", "test") + c.Assert(err, jc.Satisfies, errors.IsNotFound) + _, err = s.store.ModelByName("local.test-master", "zeus@local", "test") + c.Assert(err, jc.Satisfies, errors.IsNotFound) +} + +// fakeCreateClient is used to mock out the behavior of the real +// CreateModel command. +type fakeCreateClient struct { + owner string + account map[string]interface{} + config map[string]interface{} + err error + model params.Model +} + +var _ controller.CreateModelAPI = (*fakeCreateClient)(nil) + +func (*fakeCreateClient) Close() error { + return nil +} + +func (*fakeCreateClient) ConfigSkeleton(provider, region string) (params.ModelConfig, error) { + if provider == "" { + provider = "dummy" + } + return params.ModelConfig{ + "type": provider, + "controller": false, + }, nil +} +func (f *fakeCreateClient) CreateModel(owner string, account, config map[string]interface{}) (params.Model, error) { + if f.err != nil { + return params.Model{}, f.err + } + f.owner = owner + f.account = account + f.config = config + return f.model, nil +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/createmodel.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/createmodel.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/createmodel.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/createmodel.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,225 +0,0 @@ -// Copyright 2015 Canonical Ltd. -// Licensed under the AGPLv3, see LICENCE file for details. - -package controller - -import ( - "strings" - - "github.com/juju/cmd" - "github.com/juju/errors" - "github.com/juju/names" - "launchpad.net/gnuflag" - - "github.com/juju/juju/apiserver/params" - "github.com/juju/juju/cloud" - "github.com/juju/juju/cmd/juju/common" - "github.com/juju/juju/cmd/modelcmd" - "github.com/juju/juju/jujuclient" -) - -// NewCreateModelCommand returns a command to create an model. -func NewCreateModelCommand() cmd.Command { - return modelcmd.WrapController(&createModelCommand{ - credentialStore: jujuclient.NewFileCredentialStore(), - }) -} - -// createModelCommand calls the API to create a new model. -type createModelCommand struct { - modelcmd.ControllerCommandBase - api CreateModelAPI - credentialStore jujuclient.CredentialStore - - Name string - Owner string - CredentialSpec string - CloudName string - CloudType string - CredentialName string - Config common.ConfigFlag -} - -const createModelHelpDoc = ` -This command will create another model within the current Juju -Controller. The provider has to match, and the model config must -specify all the required configuration values for the provider. - -If configuration values are passed by both extra command line -arguments and the --config option, the command line args take -priority. - -If creating a model in a controller for which you are not the -administrator, the cloud credentials and authorized ssh keys must -be specified. The credentials are specified using the argument ---credential :. The authorized ssh keys are -specified using a --config argument, either authorized=keys=value -or via a config yaml file. - -Any credentials used must be for a cloud with the same provider -type as the controller. Controller administrators do not have to -specify credentials or ssh keys; by default, the credentials and -keys used to bootstrap the controller are used if no others are -specified. - -Examples: - - juju create-model new-model - - juju create-model new-model --config aws-creds.yaml --config image-stream=daily - - juju create-model new-model --credential aws:mysekrets --config authorized-keys="ssh-rsa ..." - -See Also: - juju help model share -` - -func (c *createModelCommand) Info() *cmd.Info { - return &cmd.Info{ - Name: "create-model", - Args: " [--config key=[value] ...] [--credential :]", - Purpose: "create an model within the Juju Model Server", - Doc: strings.TrimSpace(createModelHelpDoc), - } -} - -func (c *createModelCommand) SetFlags(f *gnuflag.FlagSet) { - f.StringVar(&c.Owner, "owner", "", "the owner of the new model if not the current user") - f.StringVar(&c.CredentialSpec, "credential", "", "the name of the cloud and credentials the new model uses to create cloud resources") - f.Var(&c.Config, "config", "specify a controller config file, or one or more controller configuration options (--config config.yaml [--config k=v ...])") -} - -func (c *createModelCommand) Init(args []string) error { - if len(args) == 0 { - return errors.New("model name is required") - } - c.Name, args = args[0], args[1:] - - if c.Owner != "" && !names.IsValidUser(c.Owner) { - return errors.Errorf("%q is not a valid user", c.Owner) - } - - if c.CredentialSpec != "" { - parts := strings.Split(c.CredentialSpec, ":") - if len(parts) < 2 { - return errors.Errorf("invalid cloud credential %s, expected :", c.CredentialSpec) - } - c.CloudName = parts[0] - if cloud, err := common.CloudOrProvider(c.CloudName, cloud.CloudByName); err != nil { - return errors.Trace(err) - } else { - c.CloudType = cloud.Type - } - c.CredentialName = parts[1] - } - return nil -} - -type CreateModelAPI interface { - Close() error - ConfigSkeleton(provider, region string) (params.ModelConfig, error) - CreateModel(owner string, account, config map[string]interface{}) (params.Model, error) -} - -func (c *createModelCommand) getAPI() (CreateModelAPI, error) { - if c.api != nil { - return c.api, nil - } - return c.NewModelManagerAPIClient() -} - -func (c *createModelCommand) Run(ctx *cmd.Context) error { - client, err := c.getAPI() - if err != nil { - return errors.Trace(err) - } - defer client.Close() - - store := c.ClientStore() - controllerName := c.ControllerName() - accountName, err := store.CurrentAccount(controllerName) - if err != nil { - return errors.Trace(err) - } - currentAccount, err := store.AccountByName(controllerName, accountName) - if err != nil { - return errors.Trace(err) - } - - modelOwner := currentAccount.User - if c.Owner != "" { - if !names.IsValidUser(c.Owner) { - return errors.Errorf("%q is not a valid user name", c.Owner) - } - modelOwner = names.NewUserTag(c.Owner).Canonical() - } - - serverSkeleton, err := client.ConfigSkeleton(c.CloudType, "") - if err != nil { - return errors.Trace(err) - } - - attrs, err := c.getConfigValues(ctx, serverSkeleton) - if err != nil { - return errors.Trace(err) - } - - accountDetails := map[string]interface{}{} - if c.CredentialName != "" { - cred, _, _, err := modelcmd.GetCredentials( - c.credentialStore, "", c.CredentialName, c.CloudName, c.CloudType, - ) - if err != nil { - return errors.Trace(err) - } - for k, v := range cred.Attributes() { - accountDetails[k] = v - } - } - model, err := client.CreateModel(modelOwner, accountDetails, attrs) - if err != nil { - return errors.Trace(err) - } - if modelOwner == currentAccount.User { - controllerName := c.ControllerName() - accountName := c.AccountName() - if err := store.UpdateModel(controllerName, accountName, c.Name, jujuclient.ModelDetails{ - model.UUID, - }); err != nil { - return errors.Trace(err) - } - if err := store.SetCurrentModel(controllerName, accountName, c.Name); err != nil { - return errors.Trace(err) - } - ctx.Infof("created model %q", c.Name) - } else { - ctx.Infof("created model %q for %q", c.Name, c.Owner) - } - - return nil -} - -func (c *createModelCommand) getConfigValues(ctx *cmd.Context, serverSkeleton params.ModelConfig) (map[string]interface{}, error) { - configValues := make(map[string]interface{}) - for key, value := range serverSkeleton { - configValues[key] = value - } - configAttr, err := c.Config.ReadAttrs(ctx) - if err != nil { - return nil, errors.Annotate(err, "unable to parse config") - } - for key, value := range configAttr { - configValues[key] = value - } - configValues["name"] = c.Name - coercedValues, err := common.ConformYAML(configValues) - if err != nil { - return nil, errors.Annotatef(err, "unable to parse config") - } - stringParams, ok := coercedValues.(map[string]interface{}) - if !ok { - return nil, errors.New("params must contain a YAML map with string keys") - } - - return stringParams, nil -} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/createmodel_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/createmodel_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/createmodel_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/createmodel_test.go 1970-01-01 00:00:00.000000000 +0000 @@ -1,318 +0,0 @@ -// Copyright 2015 Canonical Ltd. -// Licensed under the AGPLv3, see LICENCE file for details. - -package controller_test - -import ( - "io/ioutil" - - "github.com/juju/cmd" - "github.com/juju/errors" - jc "github.com/juju/testing/checkers" - "github.com/juju/utils" - gc "gopkg.in/check.v1" - "gopkg.in/yaml.v2" - - "github.com/juju/juju/apiserver/params" - "github.com/juju/juju/cloud" - "github.com/juju/juju/cmd/juju/controller" - "github.com/juju/juju/cmd/modelcmd" - "github.com/juju/juju/jujuclient" - "github.com/juju/juju/jujuclient/jujuclienttesting" - _ "github.com/juju/juju/provider/ec2" - "github.com/juju/juju/testing" -) - -type createSuite struct { - testing.FakeJujuXDGDataHomeSuite - fake *fakeCreateClient - store *jujuclienttesting.MemStore -} - -var _ = gc.Suite(&createSuite{}) - -func (s *createSuite) SetUpTest(c *gc.C) { - s.FakeJujuXDGDataHomeSuite.SetUpTest(c) - s.fake = &fakeCreateClient{ - model: params.Model{ - Name: "test", - UUID: "fake-model-uuid", - OwnerTag: "ignored-for-now", - }, - } - - // Set up the current controller, and write just enough info - // so we don't try to refresh - controllerName := "local.test-master" - err := modelcmd.WriteCurrentController(controllerName) - c.Assert(err, jc.ErrorIsNil) - - s.store = jujuclienttesting.NewMemStore() - s.store.Controllers["local.test-master"] = jujuclient.ControllerDetails{} - s.store.Accounts[controllerName] = &jujuclient.ControllerAccounts{ - Accounts: map[string]jujuclient.AccountDetails{ - "bob@local": {User: "bob@local"}, - }, - CurrentAccount: "bob@local", - } - s.store.Credentials["aws"] = cloud.CloudCredential{ - AuthCredentials: map[string]cloud.Credential{ - "secrets": cloud.NewCredential(cloud.AccessKeyAuthType, map[string]string{ - "access-key": "key", - "secret-key": "sekret", - }), - }, - } -} - -func (s *createSuite) run(c *gc.C, args ...string) (*cmd.Context, error) { - command, _ := controller.NewCreateModelCommandForTest(s.fake, s.store, s.store) - return testing.RunCommand(c, command, args...) -} - -func (s *createSuite) TestInit(c *gc.C) { - - for i, test := range []struct { - args []string - err string - name string - owner string - values map[string]interface{} - }{ - { - err: "model name is required", - }, { - args: []string{"new-model"}, - name: "new-model", - }, { - args: []string{"new-model", "--owner", "foo"}, - name: "new-model", - owner: "foo", - }, { - args: []string{"new-model", "--owner", "not=valid"}, - err: `"not=valid" is not a valid user`, - }, { - args: []string{"new-model", "--credential", "secrets"}, - err: `invalid cloud credential secrets, expected :`, - }, { - args: []string{"new-model", "--config", "key=value", "--config", "key2=value2"}, - name: "new-model", - values: map[string]interface{}{"key": "value", "key2": "value2"}, - }, - } { - c.Logf("test %d", i) - wrappedCommand, command := controller.NewCreateModelCommandForTest(nil, s.store, s.store) - err := testing.InitCommand(wrappedCommand, test.args) - if test.err != "" { - c.Assert(err, gc.ErrorMatches, test.err) - continue - } - - c.Assert(err, jc.ErrorIsNil) - c.Assert(command.Name, gc.Equals, test.name) - c.Assert(command.Owner, gc.Equals, test.owner) - attrs, err := command.Config.ReadAttrs(nil) - c.Assert(err, jc.ErrorIsNil) - if len(test.values) == 0 { - c.Assert(attrs, gc.HasLen, 0) - } else { - c.Assert(attrs, jc.DeepEquals, test.values) - } - } -} - -func (s *createSuite) TestCreateExistingName(c *gc.C) { - // If there's any model details existing, we just overwrite them. The - // controller will error out if the model already exists. Overwriting - // means we'll replace any stale details from an previously existing - // model with the same name. - err := s.store.UpdateModel("local.test-master", "bob@local", "test", jujuclient.ModelDetails{ - "stale-uuid", - }) - c.Assert(err, jc.ErrorIsNil) - - _, err = s.run(c, "test") - c.Assert(err, jc.ErrorIsNil) - - details, err := s.store.ModelByName("local.test-master", "bob@local", "test") - c.Assert(err, jc.ErrorIsNil) - c.Assert(details, jc.DeepEquals, &jujuclient.ModelDetails{"fake-model-uuid"}) -} - -func (s *createSuite) TestCredentialsPassedThrough(c *gc.C) { - _, err := s.run(c, "test", "--credential", "aws:secrets") - c.Assert(err, jc.ErrorIsNil) - - c.Assert(s.fake.config["type"], gc.Equals, "ec2") - c.Assert(s.fake.account, jc.DeepEquals, map[string]interface{}{ - "access-key": "key", - "secret-key": "sekret", - }) -} - -func (s *createSuite) TestComandLineConfigPassedThrough(c *gc.C) { - _, err := s.run(c, "test", "--config", "account=magic", "--config", "cloud=special") - c.Assert(err, jc.ErrorIsNil) - - c.Assert(s.fake.config["account"], gc.Equals, "magic") - c.Assert(s.fake.config["cloud"], gc.Equals, "special") -} - -func (s *createSuite) TestConfigFileValuesPassedThrough(c *gc.C) { - config := map[string]string{ - "account": "magic", - "cloud": "9", - } - bytes, err := yaml.Marshal(config) - c.Assert(err, jc.ErrorIsNil) - file, err := ioutil.TempFile(c.MkDir(), "") - c.Assert(err, jc.ErrorIsNil) - file.Write(bytes) - file.Close() - - _, err = s.run(c, "test", "--config", file.Name()) - c.Assert(err, jc.ErrorIsNil) - c.Assert(s.fake.config["account"], gc.Equals, "magic") - c.Assert(s.fake.config["cloud"], gc.Equals, "9") -} - -func (s *createSuite) TestConfigFileWithNestedMaps(c *gc.C) { - nestedConfig := map[string]interface{}{ - "account": "magic", - "cloud": "9", - } - config := map[string]interface{}{ - "foo": "bar", - "nested": nestedConfig, - } - - bytes, err := yaml.Marshal(config) - c.Assert(err, jc.ErrorIsNil) - file, err := ioutil.TempFile(c.MkDir(), "") - c.Assert(err, jc.ErrorIsNil) - file.Write(bytes) - file.Close() - - _, err = s.run(c, "test", "--config", file.Name()) - c.Assert(err, jc.ErrorIsNil) - c.Assert(s.fake.config["foo"], gc.Equals, "bar") - c.Assert(s.fake.config["nested"], jc.DeepEquals, nestedConfig) -} - -func (s *createSuite) TestConfigFileFailsToConform(c *gc.C) { - nestedConfig := map[int]interface{}{ - 9: "9", - } - config := map[string]interface{}{ - "foo": "bar", - "nested": nestedConfig, - } - bytes, err := yaml.Marshal(config) - c.Assert(err, jc.ErrorIsNil) - file, err := ioutil.TempFile(c.MkDir(), "") - c.Assert(err, jc.ErrorIsNil) - file.Write(bytes) - file.Close() - - _, err = s.run(c, "test", "--config", file.Name()) - c.Assert(err, gc.ErrorMatches, `unable to parse config: map keyed with non-string value`) -} - -func (s *createSuite) TestConfigFileFormatError(c *gc.C) { - file, err := ioutil.TempFile(c.MkDir(), "") - c.Assert(err, jc.ErrorIsNil) - file.Write(([]byte)("not: valid: yaml")) - file.Close() - - _, err = s.run(c, "test", "--config", file.Name()) - c.Assert(err, gc.ErrorMatches, `unable to parse config: yaml: .*`) -} - -func (s *createSuite) TestConfigFileDoesntExist(c *gc.C) { - _, err := s.run(c, "test", "--config", "missing-file") - errMsg := ".*" + utils.NoSuchFileErrRegexp - c.Assert(err, gc.ErrorMatches, errMsg) -} - -func (s *createSuite) TestConfigValuePrecedence(c *gc.C) { - config := map[string]string{ - "account": "magic", - "cloud": "9", - } - bytes, err := yaml.Marshal(config) - c.Assert(err, jc.ErrorIsNil) - file, err := ioutil.TempFile(c.MkDir(), "") - c.Assert(err, jc.ErrorIsNil) - file.Write(bytes) - file.Close() - - _, err = s.run(c, "test", "--config", file.Name(), "--config", "account=magic", "--config", "cloud=special") - c.Assert(err, jc.ErrorIsNil) - c.Assert(s.fake.config["account"], gc.Equals, "magic") - c.Assert(s.fake.config["cloud"], gc.Equals, "special") -} - -func (s *createSuite) TestCreateErrorRemoveConfigstoreInfo(c *gc.C) { - s.fake.err = errors.New("bah humbug") - - _, err := s.run(c, "test") - c.Assert(err, gc.ErrorMatches, "bah humbug") - - _, err = s.store.ModelByName("local.test-master", "bob@local", "test") - c.Assert(err, jc.Satisfies, errors.IsNotFound) -} - -func (s *createSuite) TestCreateStoresValues(c *gc.C) { - _, err := s.run(c, "test") - c.Assert(err, jc.ErrorIsNil) - - model, err := s.store.ModelByName("local.test-master", "bob@local", "test") - c.Assert(err, jc.ErrorIsNil) - c.Assert(model, jc.DeepEquals, &jujuclient.ModelDetails{"fake-model-uuid"}) -} - -func (s *createSuite) TestNoEnvCacheOtherUser(c *gc.C) { - _, err := s.run(c, "test", "--owner", "zeus") - c.Assert(err, jc.ErrorIsNil) - - // Creating a model for another user does not update the model cache. - _, err = s.store.ModelByName("local.test-master", "bob@local", "test") - c.Assert(err, jc.Satisfies, errors.IsNotFound) - _, err = s.store.ModelByName("local.test-master", "zeus@local", "test") - c.Assert(err, jc.Satisfies, errors.IsNotFound) -} - -// fakeCreateClient is used to mock out the behavior of the real -// CreateModel command. -type fakeCreateClient struct { - owner string - account map[string]interface{} - config map[string]interface{} - err error - model params.Model -} - -var _ controller.CreateModelAPI = (*fakeCreateClient)(nil) - -func (*fakeCreateClient) Close() error { - return nil -} - -func (*fakeCreateClient) ConfigSkeleton(provider, region string) (params.ModelConfig, error) { - if provider == "" { - provider = "dummy" - } - return params.ModelConfig{ - "type": provider, - "controller": false, - }, nil -} -func (f *fakeCreateClient) CreateModel(owner string, account, config map[string]interface{}) (params.Model, error) { - if f.err != nil { - return params.Model{}, f.err - } - f.owner = owner - f.account = account - f.config = config - return f.model, nil -} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/export_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/export_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/export_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/export_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -28,23 +28,23 @@ } } -type CreateModelCommand struct { - *createModelCommand +type AddModelCommand struct { + *addModelCommand } -// NewCreateModelCommandForTest returns a CreateModelCommand with +// NewAddModelCommandForTest returns a AddModelCommand with // the api provided as specified. -func NewCreateModelCommandForTest( +func NewAddModelCommandForTest( api CreateModelAPI, store jujuclient.ClientStore, credentialStore jujuclient.CredentialStore, -) (cmd.Command, *CreateModelCommand) { - c := &createModelCommand{ +) (cmd.Command, *AddModelCommand) { + c := &addModelCommand{ api: api, credentialStore: credentialStore, } c.SetClientStore(store) - return modelcmd.WrapController(c), &CreateModelCommand{c} + return modelcmd.WrapController(c), &AddModelCommand{c} } // NewListModelsCommandForTest returns a ListModelsCommand with the API diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/listmodels.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/listmodels.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/listmodels.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/listmodels.go 2016-05-17 20:01:14.000000000 +0000 @@ -49,7 +49,7 @@ juju list-models juju list-models --user bob -See also: create-model +See also: add-model share-model unshare-model ` diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/register.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/register.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/register.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/register.go 2016-05-17 20:01:14.000000000 +0000 @@ -31,8 +31,8 @@ ) var errNoModels = errors.New(` -There are no models available. You can create models with -"juju create-model", or you can ask an administrator or owner +There are no models available. You can add models with +"juju add-model", or you can ask an administrator or owner of a model to grant access to that model with "juju grant".`[1:]) // NewRegisterCommand returns a command to allow the user to register a controller. @@ -63,9 +63,9 @@ that is referred to in Usage. The user will be prompted for a password, which, once set, causes the registration string to be voided. In order to start using Juju the user -can now either create a model or wait for a model to be shared with them. +can now either add a model or wait for a model to be shared with them. Some machine providers will require the user to be in possession of -certain credentials in order to create a model. +certain credentials in order to add a model. Examples: diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/register_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/register_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/controller/register_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/controller/register_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -141,8 +141,8 @@ Welcome, bob. You are now logged into "controller-name". -There are no models available. You can create models with -"juju create-model", or you can ask an administrator or owner +There are no models available. You can add models with +"juju add-model", or you can ask an administrator or owner of a model to grant access to that model with "juju grant". `[1:]) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/main.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/main.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/main.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/main.go 2016-05-17 20:01:14.000000000 +0000 @@ -24,5 +24,5 @@ } func main() { - commands.Main(os.Args) + os.Exit(commands.Main(os.Args)) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/metricsdebug/collectmetrics.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/metricsdebug/collectmetrics.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/metricsdebug/collectmetrics.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/metricsdebug/collectmetrics.go 2016-05-17 20:01:14.000000000 +0000 @@ -120,7 +120,7 @@ return tag.Id(), nil } if strings.Contains(stderr, "No such file or directory") { - return "", errors.New("not a metered charm") + return "", errors.New("not a locally-deployed metered charm") } return tag.Id(), nil } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/service/bundle_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/service/bundle_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/service/bundle_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/service/bundle_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -25,6 +25,11 @@ coretesting "github.com/juju/juju/testing" ) +// LTS-dependent requires new entry upon new LTS release. There are numerous +// places "xenial" exists in strings throughout this file. If we update the +// target in testing/base.go:SetupSuite we'll need to also update the entries +// herein. + // runDeployCommand executes the deploy command in order to deploy the given // charm or bundle. The deployment output and error are returned. func runDeployCommand(c *gc.C, id string, args ...string) (string, error) { @@ -39,37 +44,37 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleInvalidFlags(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/mysql-42", "mysql") - testcharms.UploadCharm(c, s.client, "trusty/wordpress-47", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/mysql-42", "mysql") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-47", "wordpress") testcharms.UploadBundle(c, s.client, "bundle/wordpress-simple-1", "wordpress-simple") _, err := runDeployCommand(c, "bundle/wordpress-simple", "--config", "config.yaml") c.Assert(err, gc.ErrorMatches, "Flags provided but not supported when deploying a bundle: --config.") _, err = runDeployCommand(c, "bundle/wordpress-simple", "-n", "2") c.Assert(err, gc.ErrorMatches, "Flags provided but not supported when deploying a bundle: -n.") - _, err = runDeployCommand(c, "bundle/wordpress-simple", "--series", "trusty", "--force") + _, err = runDeployCommand(c, "bundle/wordpress-simple", "--series", "xenial", "--force") c.Assert(err, gc.ErrorMatches, "Flags provided but not supported when deploying a bundle: --force, --series.") } func (s *BundleDeployCharmStoreSuite) TestDeployBundleSuccess(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/mysql-42", "mysql") - testcharms.UploadCharm(c, s.client, "trusty/wordpress-47", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/mysql-42", "mysql") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-47", "wordpress") testcharms.UploadBundle(c, s.client, "bundle/wordpress-simple-1", "wordpress-simple") output, err := runDeployCommand(c, "bundle/wordpress-simple") c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/mysql-42 -service mysql deployed (charm cs:trusty/mysql-42 with the charm series "trusty") -added charm cs:trusty/wordpress-47 -service wordpress deployed (charm cs:trusty/wordpress-47 with the charm series "trusty") +added charm cs:xenial/mysql-42 +service mysql deployed (charm cs:xenial/mysql-42 with the charm series "xenial") +added charm cs:xenial/wordpress-47 +service wordpress deployed (charm cs:xenial/wordpress-47 with the charm series "xenial") related wordpress:db and mysql:server added mysql/0 unit to new machine added wordpress/0 unit to new machine deployment of bundle "cs:bundle/wordpress-simple-1" completed` c.Assert(output, gc.Equals, strings.TrimSpace(expectedOutput)) - s.assertCharmsUploaded(c, "cs:trusty/mysql-42", "cs:trusty/wordpress-47") + s.assertCharmsUploaded(c, "cs:xenial/mysql-42", "cs:xenial/wordpress-47") s.assertServicesDeployed(c, map[string]serviceInfo{ - "mysql": {charm: "cs:trusty/mysql-42"}, - "wordpress": {charm: "cs:trusty/wordpress-47"}, + "mysql": {charm: "cs:xenial/mysql-42"}, + "wordpress": {charm: "cs:xenial/wordpress-47"}, }) s.assertRelationsEstablished(c, "wordpress:db mysql:server") s.assertUnitsCreated(c, map[string]string{ @@ -79,24 +84,24 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleWithTermsSuccess(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/terms1-17", "terms1") - testcharms.UploadCharm(c, s.client, "trusty/terms2-42", "terms2") + testcharms.UploadCharm(c, s.client, "xenial/terms1-17", "terms1") + testcharms.UploadCharm(c, s.client, "xenial/terms2-42", "terms2") testcharms.UploadBundle(c, s.client, "bundle/terms-simple-1", "terms-simple") output, err := runDeployCommand(c, "bundle/terms-simple") c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/terms1-17 -service terms1 deployed (charm cs:trusty/terms1-17 with the charm series "trusty") -added charm cs:trusty/terms2-42 -service terms2 deployed (charm cs:trusty/terms2-42 with the charm series "trusty") +added charm cs:xenial/terms1-17 +service terms1 deployed (charm cs:xenial/terms1-17 with the charm series "xenial") +added charm cs:xenial/terms2-42 +service terms2 deployed (charm cs:xenial/terms2-42 with the charm series "xenial") added terms1/0 unit to new machine added terms2/0 unit to new machine deployment of bundle "cs:bundle/terms-simple-1" completed` c.Assert(output, gc.Equals, strings.TrimSpace(expectedOutput)) - s.assertCharmsUploaded(c, "cs:trusty/terms1-17", "cs:trusty/terms2-42") + s.assertCharmsUploaded(c, "cs:xenial/terms1-17", "cs:xenial/terms2-42") s.assertServicesDeployed(c, map[string]serviceInfo{ - "terms1": {charm: "cs:trusty/terms1-17"}, - "terms2": {charm: "cs:trusty/terms2-42"}, + "terms1": {charm: "cs:xenial/terms1-17"}, + "terms2": {charm: "cs:xenial/terms2-42"}, }) s.assertUnitsCreated(c, map[string]string{ "terms1/0": "0", @@ -106,8 +111,8 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleStorage(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/mysql-42", "mysql-storage") - testcharms.UploadCharm(c, s.client, "trusty/wordpress-47", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/mysql-42", "mysql-storage") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-47", "wordpress") testcharms.UploadBundle(c, s.client, "bundle/wordpress-with-mysql-storage-1", "wordpress-with-mysql-storage") output, err := runDeployCommand( c, "bundle/wordpress-with-mysql-storage", @@ -115,25 +120,25 @@ ) c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/mysql-42 -service mysql deployed (charm cs:trusty/mysql-42 with the charm series "trusty") -added charm cs:trusty/wordpress-47 -service wordpress deployed (charm cs:trusty/wordpress-47 with the charm series "trusty") +added charm cs:xenial/mysql-42 +service mysql deployed (charm cs:xenial/mysql-42 with the charm series "xenial") +added charm cs:xenial/wordpress-47 +service wordpress deployed (charm cs:xenial/wordpress-47 with the charm series "xenial") related wordpress:db and mysql:server added mysql/0 unit to new machine added wordpress/0 unit to new machine deployment of bundle "cs:bundle/wordpress-with-mysql-storage-1" completed` c.Assert(output, gc.Equals, strings.TrimSpace(expectedOutput)) - s.assertCharmsUploaded(c, "cs:trusty/mysql-42", "cs:trusty/wordpress-47") + s.assertCharmsUploaded(c, "cs:xenial/mysql-42", "cs:xenial/wordpress-47") s.assertServicesDeployed(c, map[string]serviceInfo{ "mysql": { - charm: "cs:trusty/mysql-42", + charm: "cs:xenial/mysql-42", storage: map[string]state.StorageConstraints{ "data": state.StorageConstraints{Pool: "rootfs", Size: 50 * 1024, Count: 1}, "logs": state.StorageConstraints{Pool: "tmpfs", Size: 10 * 1024, Count: 1}, }, }, - "wordpress": {charm: "cs:trusty/wordpress-47"}, + "wordpress": {charm: "cs:xenial/wordpress-47"}, }) s.assertRelationsEstablished(c, "wordpress:db mysql:server") s.assertUnitsCreated(c, map[string]string{ @@ -143,15 +148,15 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleEndpointBindingsSpaceMissing(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/mysql-42", "mysql") - testcharms.UploadCharm(c, s.client, "trusty/wordpress-extra-bindings-47", "wordpress-extra-bindings") + testcharms.UploadCharm(c, s.client, "xenial/mysql-42", "mysql") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-extra-bindings-47", "wordpress-extra-bindings") testcharms.UploadBundle(c, s.client, "bundle/wordpress-with-endpoint-bindings-1", "wordpress-with-endpoint-bindings") output, err := runDeployCommand(c, "bundle/wordpress-with-endpoint-bindings") c.Assert(err, gc.ErrorMatches, "cannot deploy bundle: cannot deploy service \"mysql\": "+ "cannot add service \"mysql\": unknown space \"db\" not valid") - c.Assert(output, gc.Equals, "added charm cs:trusty/mysql-42") - s.assertCharmsUploaded(c, "cs:trusty/mysql-42") + c.Assert(output, gc.Equals, "added charm cs:xenial/mysql-42") + s.assertCharmsUploaded(c, "cs:xenial/mysql-42") s.assertServicesDeployed(c, map[string]serviceInfo{}) s.assertUnitsCreated(c, map[string]string{}) } @@ -162,26 +167,26 @@ _, err = s.State.AddSpace("public", "", nil, false) c.Assert(err, jc.ErrorIsNil) - testcharms.UploadCharm(c, s.client, "trusty/mysql-42", "mysql") - testcharms.UploadCharm(c, s.client, "trusty/wordpress-extra-bindings-47", "wordpress-extra-bindings") + testcharms.UploadCharm(c, s.client, "xenial/mysql-42", "mysql") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-extra-bindings-47", "wordpress-extra-bindings") testcharms.UploadBundle(c, s.client, "bundle/wordpress-with-endpoint-bindings-1", "wordpress-with-endpoint-bindings") output, err := runDeployCommand(c, "bundle/wordpress-with-endpoint-bindings") c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/mysql-42 -service mysql deployed (charm cs:trusty/mysql-42 with the charm series "trusty") -added charm cs:trusty/wordpress-extra-bindings-47 -service wordpress-extra-bindings deployed (charm cs:trusty/wordpress-extra-bindings-47 with the charm series "trusty") +added charm cs:xenial/mysql-42 +service mysql deployed (charm cs:xenial/mysql-42 with the charm series "xenial") +added charm cs:xenial/wordpress-extra-bindings-47 +service wordpress-extra-bindings deployed (charm cs:xenial/wordpress-extra-bindings-47 with the charm series "xenial") related wordpress-extra-bindings:db and mysql:server added mysql/0 unit to new machine added wordpress-extra-bindings/0 unit to new machine deployment of bundle "cs:bundle/wordpress-with-endpoint-bindings-1" completed` c.Assert(output, gc.Equals, strings.TrimSpace(expectedOutput)) - s.assertCharmsUploaded(c, "cs:trusty/mysql-42", "cs:trusty/wordpress-extra-bindings-47") + s.assertCharmsUploaded(c, "cs:xenial/mysql-42", "cs:xenial/wordpress-extra-bindings-47") s.assertServicesDeployed(c, map[string]serviceInfo{ - "mysql": {charm: "cs:trusty/mysql-42"}, - "wordpress-extra-bindings": {charm: "cs:trusty/wordpress-extra-bindings-47"}, + "mysql": {charm: "cs:xenial/mysql-42"}, + "wordpress-extra-bindings": {charm: "cs:xenial/wordpress-extra-bindings-47"}, }) s.assertDeployedServiceBindings(c, map[string]serviceInfo{ "mysql": { @@ -209,27 +214,27 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleTwice(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/mysql-42", "mysql") - testcharms.UploadCharm(c, s.client, "trusty/wordpress-47", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/mysql-42", "mysql") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-47", "wordpress") testcharms.UploadBundle(c, s.client, "bundle/wordpress-simple-1", "wordpress-simple") _, err := runDeployCommand(c, "bundle/wordpress-simple") c.Assert(err, jc.ErrorIsNil) output, err := runDeployCommand(c, "bundle/wordpress-simple") c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/mysql-42 -reusing service mysql (charm: cs:trusty/mysql-42) -added charm cs:trusty/wordpress-47 -reusing service wordpress (charm: cs:trusty/wordpress-47) +added charm cs:xenial/mysql-42 +reusing service mysql (charm: cs:xenial/mysql-42) +added charm cs:xenial/wordpress-47 +reusing service wordpress (charm: cs:xenial/wordpress-47) wordpress:db and mysql:server are already related avoid adding new units to service mysql: 1 unit already present avoid adding new units to service wordpress: 1 unit already present deployment of bundle "cs:bundle/wordpress-simple-1" completed` c.Assert(output, gc.Equals, strings.TrimSpace(expectedOutput)) - s.assertCharmsUploaded(c, "cs:trusty/mysql-42", "cs:trusty/wordpress-47") + s.assertCharmsUploaded(c, "cs:xenial/mysql-42", "cs:xenial/wordpress-47") s.assertServicesDeployed(c, map[string]serviceInfo{ - "mysql": {charm: "cs:trusty/mysql-42"}, - "wordpress": {charm: "cs:trusty/wordpress-47"}, + "mysql": {charm: "cs:xenial/mysql-42"}, + "wordpress": {charm: "cs:xenial/wordpress-47"}, }) s.assertRelationsEstablished(c, "wordpress:db mysql:server") s.assertUnitsCreated(c, map[string]string{ @@ -239,16 +244,16 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleGatedCharm(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/mysql-42", "mysql") - url, _ := testcharms.UploadCharm(c, s.client, "trusty/wordpress-47", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/mysql-42", "mysql") + url, _ := testcharms.UploadCharm(c, s.client, "xenial/wordpress-47", "wordpress") s.changeReadPerm(c, url, clientUserName) testcharms.UploadBundle(c, s.client, "bundle/wordpress-simple-1", "wordpress-simple") _, err := runDeployCommand(c, "bundle/wordpress-simple") c.Assert(err, jc.ErrorIsNil) - s.assertCharmsUploaded(c, "cs:trusty/mysql-42", "cs:trusty/wordpress-47") + s.assertCharmsUploaded(c, "cs:xenial/mysql-42", "cs:xenial/wordpress-47") s.assertServicesDeployed(c, map[string]serviceInfo{ - "mysql": {charm: "cs:trusty/mysql-42"}, - "wordpress": {charm: "cs:trusty/wordpress-47"}, + "mysql": {charm: "cs:xenial/mysql-42"}, + "wordpress": {charm: "cs:xenial/wordpress-47"}, }) } @@ -257,7 +262,7 @@ testcharms.Repo.ClonedDir(dir, "dummy") path := filepath.Join(dir, "mybundle") data := ` - series: trusty + series: xenial services: dummy: charm: ./dummy @@ -307,8 +312,8 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleGatedCharmUnauthorized(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/mysql-42", "mysql") - url, _ := testcharms.UploadCharm(c, s.client, "trusty/wordpress-47", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/mysql-42", "mysql") + url, _ := testcharms.UploadCharm(c, s.client, "xenial/wordpress-47", "wordpress") s.changeReadPerm(c, url, "who") testcharms.UploadBundle(c, s.client, "bundle/wordpress-simple-1", "wordpress-simple") _, err := runDeployCommand(c, "bundle/wordpress-simple") @@ -363,10 +368,10 @@ content: ` services: rails: - charm: trusty/rails-42 + charm: xenial/rails-42 num_units: 1 `, - err: `cannot deploy bundle: cannot resolve URL "trusty/rails-42": cannot resolve URL "cs:trusty/rails-42": charm not found`, + err: `cannot deploy bundle: cannot resolve URL "xenial/rails-42": cannot resolve URL "cs:xenial/rails-42": charm not found`, }, { about: "invalid bundle content", content: "!", @@ -424,11 +429,11 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleInvalidOptions(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/wordpress-42", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-42", "wordpress") _, err := s.DeployBundleYAML(c, ` services: wp: - charm: trusty/wordpress-42 + charm: xenial/wordpress-42 num_units: 1 options: blog-title: 42 @@ -437,11 +442,11 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleInvalidMachineContainerType(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/wordpress-42", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-42", "wordpress") _, err := s.DeployBundleYAML(c, ` services: wp: - charm: trusty/wordpress + charm: xenial/wordpress num_units: 1 to: ["bad:1"] machines: @@ -461,7 +466,7 @@ - 1 machines: 1: - series: trusty + series: xenial `) c.Assert(err, gc.ErrorMatches, `cannot deploy bundle: cannot add unit for service "django": adding new machine to host unit "django/0": cannot assign unit "django/0" to machine 0: series does not match`) } @@ -480,8 +485,8 @@ return watcher, nil }) - testcharms.UploadCharm(c, s.client, "trusty/django-0", "dummy") - testcharms.UploadCharm(c, s.client, "trusty/wordpress-0", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/django-0", "dummy") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-0", "wordpress") s.PatchValue(&updateUnitStatusPeriod, 0*time.Second) _, err := s.DeployBundleYAML(c, ` services: @@ -501,7 +506,7 @@ mysqlPath := testcharms.Repo.ClonedDirPath(charmsPath, "mysql") wordpressPath := testcharms.Repo.ClonedDirPath(charmsPath, "wordpress") output, err := s.DeployBundleYAML(c, fmt.Sprintf(` - series: trusty + series: xenial services: wordpress: charm: %s @@ -514,20 +519,20 @@ `, wordpressPath, mysqlPath)) c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm local:trusty/mysql-1 -service mysql deployed (charm local:trusty/mysql-1 with the series "trusty" defined by the bundle) -added charm local:trusty/wordpress-3 -service wordpress deployed (charm local:trusty/wordpress-3 with the series "trusty" defined by the bundle) +added charm local:xenial/mysql-1 +service mysql deployed (charm local:xenial/mysql-1 with the series "xenial" defined by the bundle) +added charm local:xenial/wordpress-3 +service wordpress deployed (charm local:xenial/wordpress-3 with the series "xenial" defined by the bundle) related wordpress:db and mysql:server added mysql/0 unit to new machine added mysql/1 unit to new machine added wordpress/0 unit to new machine deployment of bundle "local:bundle/example-0" completed` c.Assert(output, gc.Equals, strings.TrimSpace(expectedOutput)) - s.assertCharmsUploaded(c, "local:trusty/mysql-1", "local:trusty/wordpress-3") + s.assertCharmsUploaded(c, "local:xenial/mysql-1", "local:xenial/wordpress-3") s.assertServicesDeployed(c, map[string]serviceInfo{ - "mysql": {charm: "local:trusty/mysql-1"}, - "wordpress": {charm: "local:trusty/wordpress-3"}, + "mysql": {charm: "local:xenial/mysql-1"}, + "wordpress": {charm: "local:xenial/wordpress-3"}, }) s.assertRelationsEstablished(c, "wordpress:db mysql:server") s.assertUnitsCreated(c, map[string]string{ @@ -539,14 +544,14 @@ func (s *BundleDeployCharmStoreSuite) TestDeployBundleLocalAndCharmStoreCharms(c *gc.C) { charmsPath := c.MkDir() - testcharms.UploadCharm(c, s.client, "trusty/wordpress-42", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-42", "wordpress") mysqlPath := testcharms.Repo.ClonedDirPath(charmsPath, "mysql") output, err := s.DeployBundleYAML(c, fmt.Sprintf(` - series: trusty + series: xenial services: wordpress: - charm: trusty/wordpress-42 - series: trusty + charm: xenial/wordpress-42 + series: xenial num_units: 1 mysql: charm: %s @@ -556,19 +561,19 @@ `, mysqlPath)) c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm local:trusty/mysql-1 -service mysql deployed (charm local:trusty/mysql-1 with the series "trusty" defined by the bundle) -added charm cs:trusty/wordpress-42 -service wordpress deployed (charm cs:trusty/wordpress-42 with the series "trusty" defined by the bundle) +added charm local:xenial/mysql-1 +service mysql deployed (charm local:xenial/mysql-1 with the series "xenial" defined by the bundle) +added charm cs:xenial/wordpress-42 +service wordpress deployed (charm cs:xenial/wordpress-42 with the series "xenial" defined by the bundle) related wordpress:db and mysql:server added mysql/0 unit to new machine added wordpress/0 unit to new machine deployment of bundle "local:bundle/example-0" completed` c.Assert(output, gc.Equals, strings.TrimSpace(expectedOutput)) - s.assertCharmsUploaded(c, "local:trusty/mysql-1", "cs:trusty/wordpress-42") + s.assertCharmsUploaded(c, "local:xenial/mysql-1", "cs:xenial/wordpress-42") s.assertServicesDeployed(c, map[string]serviceInfo{ - "mysql": {charm: "local:trusty/mysql-1"}, - "wordpress": {charm: "cs:trusty/wordpress-42"}, + "mysql": {charm: "local:xenial/mysql-1"}, + "wordpress": {charm: "cs:xenial/wordpress-42"}, }) s.assertRelationsEstablished(c, "wordpress:db mysql:server") s.assertUnitsCreated(c, map[string]string{ @@ -578,7 +583,7 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleServiceOptions(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/wordpress-42", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-42", "wordpress") testcharms.UploadCharm(c, s.client, "precise/dummy-0", "dummy") output, err := s.DeployBundleYAML(c, ` services: @@ -598,20 +603,20 @@ expectedOutput := ` added charm cs:precise/dummy-0 service customized deployed (charm cs:precise/dummy-0 with the series "precise" defined by the bundle) -added charm cs:trusty/wordpress-42 -service wordpress deployed (charm cs:trusty/wordpress-42 with the charm series "trusty") +added charm cs:xenial/wordpress-42 +service wordpress deployed (charm cs:xenial/wordpress-42 with the charm series "xenial") added customized/0 unit to new machine added wordpress/0 unit to new machine deployment of bundle "local:bundle/example-0" completed` c.Assert(output, gc.Equals, strings.TrimSpace(expectedOutput)) - s.assertCharmsUploaded(c, "cs:precise/dummy-0", "cs:trusty/wordpress-42") + s.assertCharmsUploaded(c, "cs:precise/dummy-0", "cs:xenial/wordpress-42") s.assertServicesDeployed(c, map[string]serviceInfo{ "customized": { charm: "cs:precise/dummy-0", config: charm.Settings{"username": "who", "skill-level": int64(47)}, }, "wordpress": { - charm: "cs:trusty/wordpress-42", + charm: "cs:xenial/wordpress-42", config: charm.Settings{"blog-title": "these are the voyages"}, }, }) @@ -622,7 +627,7 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleServiceConstrants(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/wordpress-42", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-42", "wordpress") testcharms.UploadCharm(c, s.client, "precise/dummy-0", "dummy") output, err := s.DeployBundleYAML(c, ` services: @@ -638,19 +643,19 @@ expectedOutput := ` added charm cs:precise/dummy-0 service customized deployed (charm cs:precise/dummy-0 with the series "precise" defined by the bundle) -added charm cs:trusty/wordpress-42 -service wordpress deployed (charm cs:trusty/wordpress-42 with the charm series "trusty") +added charm cs:xenial/wordpress-42 +service wordpress deployed (charm cs:xenial/wordpress-42 with the charm series "xenial") added customized/0 unit to new machine deployment of bundle "local:bundle/example-0" completed` c.Assert(output, gc.Equals, strings.TrimSpace(expectedOutput)) - s.assertCharmsUploaded(c, "cs:precise/dummy-0", "cs:trusty/wordpress-42") + s.assertCharmsUploaded(c, "cs:precise/dummy-0", "cs:xenial/wordpress-42") s.assertServicesDeployed(c, map[string]serviceInfo{ "customized": { charm: "cs:precise/dummy-0", constraints: constraints.MustParse("arch=i386"), }, "wordpress": { - charm: "cs:trusty/wordpress-42", + charm: "cs:xenial/wordpress-42", constraints: constraints.MustParse("mem=4G cpu-cores=2"), }, }) @@ -660,7 +665,7 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleServiceUpgrade(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/wordpress-42", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-42", "wordpress") testcharms.UploadCharm(c, s.client, "vivid/upgrade-1", "upgrade1") testcharms.UploadCharm(c, s.client, "vivid/upgrade-2", "upgrade2") @@ -681,13 +686,13 @@ expectedOutput := ` added charm cs:vivid/upgrade-1 service up deployed (charm cs:vivid/upgrade-1 with the series "vivid" defined by the bundle) -added charm cs:trusty/wordpress-42 -service wordpress deployed (charm cs:trusty/wordpress-42 with the charm series "trusty") +added charm cs:xenial/wordpress-42 +service wordpress deployed (charm cs:xenial/wordpress-42 with the charm series "xenial") added up/0 unit to new machine added wordpress/0 unit to new machine deployment of bundle "local:bundle/example-0" completed` c.Assert(output, gc.Equals, strings.TrimSpace(expectedOutput)) - s.assertCharmsUploaded(c, "cs:vivid/upgrade-1", "cs:trusty/wordpress-42") + s.assertCharmsUploaded(c, "cs:vivid/upgrade-1", "cs:xenial/wordpress-42") // Then deploy a new bundle with modified charm revision and options. output, err = s.DeployBundleYAML(c, ` @@ -706,19 +711,19 @@ expectedOutput = ` added charm cs:vivid/upgrade-2 upgraded charm for existing service up (from cs:vivid/upgrade-1 to cs:vivid/upgrade-2) -added charm cs:trusty/wordpress-42 -reusing service wordpress (charm: cs:trusty/wordpress-42) +added charm cs:xenial/wordpress-42 +reusing service wordpress (charm: cs:xenial/wordpress-42) configuration updated for service wordpress constraints applied for service wordpress avoid adding new units to service up: 1 unit already present avoid adding new units to service wordpress: 1 unit already present deployment of bundle "local:bundle/example-0" completed` c.Assert(output, gc.Equals, strings.TrimSpace(expectedOutput)) - s.assertCharmsUploaded(c, "cs:vivid/upgrade-1", "cs:vivid/upgrade-2", "cs:trusty/wordpress-42") + s.assertCharmsUploaded(c, "cs:vivid/upgrade-1", "cs:vivid/upgrade-2", "cs:xenial/wordpress-42") s.assertServicesDeployed(c, map[string]serviceInfo{ "up": {charm: "cs:vivid/upgrade-2"}, "wordpress": { - charm: "cs:trusty/wordpress-42", + charm: "cs:xenial/wordpress-42", config: charm.Settings{"blog-title": "new title"}, constraints: constraints.MustParse("spaces=new cpu-cores=8"), }, @@ -730,7 +735,7 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleExpose(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/wordpress-42", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-42", "wordpress") content := ` services: wordpress: @@ -740,7 +745,7 @@ ` expectedServices := map[string]serviceInfo{ "wordpress": { - charm: "cs:trusty/wordpress-42", + charm: "cs:xenial/wordpress-42", exposed: true, }, } @@ -749,8 +754,8 @@ output, err := s.DeployBundleYAML(c, content) c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/wordpress-42 -service wordpress deployed (charm cs:trusty/wordpress-42 with the charm series "trusty") +added charm cs:xenial/wordpress-42 +service wordpress deployed (charm cs:xenial/wordpress-42 with the charm series "xenial") service wordpress exposed added wordpress/0 unit to new machine deployment of bundle "local:bundle/example-0" completed` @@ -762,8 +767,8 @@ output, err = s.DeployBundleYAML(c, content) c.Assert(err, jc.ErrorIsNil) expectedOutput = ` -added charm cs:trusty/wordpress-42 -reusing service wordpress (charm: cs:trusty/wordpress-42) +added charm cs:xenial/wordpress-42 +reusing service wordpress (charm: cs:xenial/wordpress-42) service wordpress exposed avoid adding new units to service wordpress: 1 unit already present deployment of bundle "local:bundle/example-0" completed` @@ -781,8 +786,8 @@ `) c.Assert(err, jc.ErrorIsNil) expectedOutput = ` -added charm cs:trusty/wordpress-42 -reusing service wordpress (charm: cs:trusty/wordpress-42) +added charm cs:xenial/wordpress-42 +reusing service wordpress (charm: cs:xenial/wordpress-42) avoid adding new units to service wordpress: 1 unit already present deployment of bundle "local:bundle/example-0" completed` c.Assert(output, gc.Equals, strings.TrimSpace(expectedOutput)) @@ -793,14 +798,14 @@ s.AddTestingService(c, "wordpress", s.AddTestingCharm(c, "wordpress")) // Try upgrading to a different charm name. - testcharms.UploadCharm(c, s.client, "trusty/incompatible-42", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/incompatible-42", "wordpress") _, err := s.DeployBundleYAML(c, ` services: wordpress: - charm: trusty/incompatible-42 + charm: xenial/incompatible-42 num_units: 1 `) - c.Assert(err, gc.ErrorMatches, `cannot deploy bundle: cannot upgrade service "wordpress": bundle charm "cs:trusty/incompatible-42" is incompatible with existing charm "local:quantal/wordpress-3"`) + c.Assert(err, gc.ErrorMatches, `cannot deploy bundle: cannot upgrade service "wordpress": bundle charm "cs:xenial/incompatible-42" is incompatible with existing charm "local:quantal/wordpress-3"`) // Try upgrading to a different series. // Note that this test comes before the next one because @@ -817,21 +822,21 @@ c.Assert(err, gc.ErrorMatches, `cannot deploy bundle: cannot upgrade service "wordpress": bundle charm "cs:vivid/wordpress-42" is incompatible with existing charm "local:quantal/wordpress-3"`) // Try upgrading to a different user. - testcharms.UploadCharm(c, s.client, "~who/trusty/wordpress-42", "wordpress") + testcharms.UploadCharm(c, s.client, "~who/xenial/wordpress-42", "wordpress") _, err = s.DeployBundleYAML(c, ` services: wordpress: - charm: cs:~who/trusty/wordpress-42 + charm: cs:~who/xenial/wordpress-42 num_units: 1 `) - c.Assert(err, gc.ErrorMatches, `cannot deploy bundle: cannot upgrade service "wordpress": bundle charm "cs:~who/trusty/wordpress-42" is incompatible with existing charm "local:quantal/wordpress-3"`) + c.Assert(err, gc.ErrorMatches, `cannot deploy bundle: cannot upgrade service "wordpress": bundle charm "cs:~who/xenial/wordpress-42" is incompatible with existing charm "local:quantal/wordpress-3"`) } func (s *BundleDeployCharmStoreSuite) TestDeployBundleMultipleRelations(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/wordpress-0", "wordpress") - testcharms.UploadCharm(c, s.client, "trusty/mysql-1", "mysql") - testcharms.UploadCharm(c, s.client, "trusty/postgres-2", "mysql") - testcharms.UploadCharm(c, s.client, "trusty/varnish-3", "varnish") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-0", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/mysql-1", "mysql") + testcharms.UploadCharm(c, s.client, "xenial/postgres-2", "mysql") + testcharms.UploadCharm(c, s.client, "xenial/varnish-3", "varnish") output, err := s.DeployBundleYAML(c, ` services: wp: @@ -841,10 +846,10 @@ charm: mysql num_units: 1 pgres: - charm: trusty/postgres-2 + charm: xenial/postgres-2 num_units: 1 varnish: - charm: trusty/varnish + charm: xenial/varnish num_units: 1 relations: - ["wp:db", "mysql:server"] @@ -853,14 +858,14 @@ `) c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/mysql-1 -service mysql deployed (charm cs:trusty/mysql-1 with the charm series "trusty") -added charm cs:trusty/postgres-2 -service pgres deployed (charm cs:trusty/postgres-2 with the series "trusty" defined by the bundle) -added charm cs:trusty/varnish-3 -service varnish deployed (charm cs:trusty/varnish-3 with the series "trusty" defined by the bundle) -added charm cs:trusty/wordpress-0 -service wp deployed (charm cs:trusty/wordpress-0 with the charm series "trusty") +added charm cs:xenial/mysql-1 +service mysql deployed (charm cs:xenial/mysql-1 with the charm series "xenial") +added charm cs:xenial/postgres-2 +service pgres deployed (charm cs:xenial/postgres-2 with the series "xenial" defined by the bundle) +added charm cs:xenial/varnish-3 +service varnish deployed (charm cs:xenial/varnish-3 with the series "xenial" defined by the bundle) +added charm cs:xenial/wordpress-0 +service wp deployed (charm cs:xenial/wordpress-0 with the charm series "xenial") related wp:db and mysql:server related wp:db and pgres:server related varnish:webcache and wp:cache @@ -880,10 +885,10 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleNewRelations(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/wordpress-0", "wordpress") - testcharms.UploadCharm(c, s.client, "trusty/mysql-1", "mysql") - testcharms.UploadCharm(c, s.client, "trusty/postgres-2", "mysql") - testcharms.UploadCharm(c, s.client, "trusty/varnish-3", "varnish") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-0", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/mysql-1", "mysql") + testcharms.UploadCharm(c, s.client, "xenial/postgres-2", "mysql") + testcharms.UploadCharm(c, s.client, "xenial/varnish-3", "varnish") _, err := s.DeployBundleYAML(c, ` services: wp: @@ -893,7 +898,7 @@ charm: mysql num_units: 1 varnish: - charm: trusty/varnish + charm: xenial/varnish num_units: 1 relations: - ["wp:db", "mysql:server"] @@ -908,7 +913,7 @@ charm: mysql num_units: 1 varnish: - charm: trusty/varnish + charm: xenial/varnish num_units: 1 relations: - ["wp:db", "mysql:server"] @@ -916,12 +921,12 @@ `) c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/mysql-1 -reusing service mysql (charm: cs:trusty/mysql-1) -added charm cs:trusty/varnish-3 -reusing service varnish (charm: cs:trusty/varnish-3) -added charm cs:trusty/wordpress-0 -reusing service wp (charm: cs:trusty/wordpress-0) +added charm cs:xenial/mysql-1 +reusing service mysql (charm: cs:xenial/mysql-1) +added charm cs:xenial/varnish-3 +reusing service varnish (charm: cs:xenial/varnish-3) +added charm cs:xenial/wordpress-0 +reusing service wp (charm: cs:xenial/wordpress-0) wp:db and mysql:server are already related related varnish:webcache and wp:cache avoid adding new units to service mysql: 1 unit already present @@ -938,12 +943,12 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleMachinesUnitsPlacement(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/wordpress-0", "wordpress") - testcharms.UploadCharm(c, s.client, "trusty/mysql-2", "mysql") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-0", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/mysql-2", "mysql") content := ` services: wp: - charm: cs:trusty/wordpress-0 + charm: cs:xenial/wordpress-0 num_units: 2 to: - 1 @@ -951,23 +956,23 @@ options: blog-title: these are the voyages sql: - charm: cs:trusty/mysql + charm: cs:xenial/mysql num_units: 2 to: - lxc:wp/0 - new machines: 1: - series: trusty + series: xenial 2: ` output, err := s.DeployBundleYAML(c, content) c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/mysql-2 -service sql deployed (charm cs:trusty/mysql-2 with the series "trusty" defined by the bundle) -added charm cs:trusty/wordpress-0 -service wp deployed (charm cs:trusty/wordpress-0 with the series "trusty" defined by the bundle) +added charm cs:xenial/mysql-2 +service sql deployed (charm cs:xenial/mysql-2 with the series "xenial" defined by the bundle) +added charm cs:xenial/wordpress-0 +service wp deployed (charm cs:xenial/wordpress-0 with the series "xenial" defined by the bundle) created new machine 0 for holding wp unit created new machine 1 for holding wp unit added wp/0 unit to machine 0 @@ -980,9 +985,9 @@ deployment of bundle "local:bundle/example-0" completed` c.Assert(output, gc.Equals, strings.TrimSpace(expectedOutput)) s.assertServicesDeployed(c, map[string]serviceInfo{ - "sql": {charm: "cs:trusty/mysql-2"}, + "sql": {charm: "cs:xenial/mysql-2"}, "wp": { - charm: "cs:trusty/wordpress-0", + charm: "cs:xenial/wordpress-0", config: charm.Settings{"blog-title": "these are the voyages"}, }, }) @@ -1015,10 +1020,10 @@ output, err = s.DeployBundleYAML(c, content) c.Assert(err, jc.ErrorIsNil) expectedOutput = ` -added charm cs:trusty/mysql-2 -reusing service sql (charm: cs:trusty/mysql-2) -added charm cs:trusty/wordpress-0 -reusing service wp (charm: cs:trusty/wordpress-0) +added charm cs:xenial/mysql-2 +reusing service sql (charm: cs:xenial/mysql-2) +added charm cs:xenial/wordpress-0 +reusing service wp (charm: cs:xenial/wordpress-0) configuration updated for service wp avoid creating other machines to host wp units avoid adding new units to service wp: 2 units already present @@ -1035,26 +1040,26 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleMachineAttributes(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/django-42", "dummy") + testcharms.UploadCharm(c, s.client, "xenial/django-42", "dummy") output, err := s.DeployBundleYAML(c, ` services: django: - charm: cs:trusty/django-42 + charm: cs:xenial/django-42 num_units: 2 to: - 1 - new machines: 1: - series: trusty + series: xenial constraints: "cpu-cores=4 mem=4G" annotations: foo: bar `) c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/django-42 -service django deployed (charm cs:trusty/django-42 with the series "trusty" defined by the bundle) +added charm cs:xenial/django-42 +service django deployed (charm cs:xenial/django-42 with the series "xenial" defined by the bundle) created new machine 0 for holding django unit annotations set for machine 0 added django/0 unit to machine 0 @@ -1063,7 +1068,7 @@ deployment of bundle "local:bundle/example-0" completed` c.Assert(output, gc.Equals, strings.TrimSpace(expectedOutput)) s.assertServicesDeployed(c, map[string]serviceInfo{ - "django": {charm: "cs:trusty/django-42"}, + "django": {charm: "cs:xenial/django-42"}, }) s.assertRelationsEstablished(c) s.assertUnitsCreated(c, map[string]string{ @@ -1072,7 +1077,7 @@ }) m, err := s.State.Machine("0") c.Assert(err, jc.ErrorIsNil) - c.Assert(m.Series(), gc.Equals, "trusty") + c.Assert(m.Series(), gc.Equals, "xenial") cons, err := m.Constraints() c.Assert(err, jc.ErrorIsNil) expectedCons, err := constraints.Parse("cpu-cores=4 mem=4G") @@ -1084,24 +1089,24 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleTwiceScaleUp(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/django-42", "dummy") + testcharms.UploadCharm(c, s.client, "xenial/django-42", "dummy") _, err := s.DeployBundleYAML(c, ` services: django: - charm: cs:trusty/django-42 + charm: cs:xenial/django-42 num_units: 2 `) c.Assert(err, jc.ErrorIsNil) output, err := s.DeployBundleYAML(c, ` services: django: - charm: cs:trusty/django-42 + charm: cs:xenial/django-42 num_units: 5 `) c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/django-42 -reusing service django (charm: cs:trusty/django-42) +added charm cs:xenial/django-42 +reusing service django (charm: cs:xenial/django-42) added django/2 unit to new machine added django/3 unit to new machine added django/4 unit to new machine @@ -1118,24 +1123,24 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleUnitPlacedInService(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/django-42", "dummy") - testcharms.UploadCharm(c, s.client, "trusty/wordpress-0", "wordpress") + testcharms.UploadCharm(c, s.client, "xenial/django-42", "dummy") + testcharms.UploadCharm(c, s.client, "xenial/wordpress-0", "wordpress") output, err := s.DeployBundleYAML(c, ` services: wordpress: charm: wordpress num_units: 3 django: - charm: cs:trusty/django-42 + charm: cs:xenial/django-42 num_units: 2 to: [wordpress] `) c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/django-42 -service django deployed (charm cs:trusty/django-42 with the series "trusty" defined by the bundle) -added charm cs:trusty/wordpress-0 -service wordpress deployed (charm cs:trusty/wordpress-0 with the charm series "trusty") +added charm cs:xenial/django-42 +service django deployed (charm cs:xenial/django-42 with the series "xenial" defined by the bundle) +added charm cs:xenial/wordpress-0 +service wordpress deployed (charm cs:xenial/wordpress-0 with the charm series "xenial") added wordpress/0 unit to new machine added wordpress/1 unit to new machine added wordpress/2 unit to new machine @@ -1153,17 +1158,17 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleUnitColocationWithUnit(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/django-42", "dummy") - testcharms.UploadCharm(c, s.client, "trusty/mem-47", "dummy") - testcharms.UploadCharm(c, s.client, "trusty/rails-0", "dummy") + testcharms.UploadCharm(c, s.client, "xenial/django-42", "dummy") + testcharms.UploadCharm(c, s.client, "xenial/mem-47", "dummy") + testcharms.UploadCharm(c, s.client, "xenial/rails-0", "dummy") output, err := s.DeployBundleYAML(c, ` services: memcached: - charm: cs:trusty/mem-47 + charm: cs:xenial/mem-47 num_units: 3 to: [1, new] django: - charm: cs:trusty/django-42 + charm: cs:xenial/django-42 num_units: 5 to: - memcached/0 @@ -1178,16 +1183,16 @@ - 1 machines: 1: - series: trusty + series: xenial `) c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/django-42 -service django deployed (charm cs:trusty/django-42 with the series "trusty" defined by the bundle) -added charm cs:trusty/mem-47 -service memcached deployed (charm cs:trusty/mem-47 with the series "trusty" defined by the bundle) -added charm cs:trusty/rails-0 -service ror deployed (charm cs:trusty/rails-0 with the charm series "trusty") +added charm cs:xenial/django-42 +service django deployed (charm cs:xenial/django-42 with the series "xenial" defined by the bundle) +added charm cs:xenial/mem-47 +service memcached deployed (charm cs:xenial/mem-47 with the series "xenial" defined by the bundle) +added charm cs:xenial/rails-0 +service ror deployed (charm cs:xenial/rails-0 with the charm series "xenial") created new machine 0 for holding memcached and ror units added memcached/0 unit to machine 0 added ror/0 unit to machine 0 @@ -1223,7 +1228,7 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleUnitPlacedToMachines(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/django-42", "dummy") + testcharms.UploadCharm(c, s.client, "xenial/django-42", "dummy") output, err := s.DeployBundleYAML(c, ` services: django: @@ -1242,8 +1247,8 @@ `) c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/django-42 -service django deployed (charm cs:trusty/django-42 with the charm series "trusty") +added charm cs:xenial/django-42 +service django deployed (charm cs:xenial/django-42 with the charm series "xenial") created new machine 0 for holding django unit created new machine 1 for holding django unit added django/0 unit to machine 0 @@ -1273,17 +1278,17 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleMassiveUnitColocation(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/django-42", "dummy") - testcharms.UploadCharm(c, s.client, "trusty/mem-47", "dummy") - testcharms.UploadCharm(c, s.client, "trusty/rails-0", "dummy") + testcharms.UploadCharm(c, s.client, "xenial/django-42", "dummy") + testcharms.UploadCharm(c, s.client, "xenial/mem-47", "dummy") + testcharms.UploadCharm(c, s.client, "xenial/rails-0", "dummy") output, err := s.DeployBundleYAML(c, ` services: memcached: - charm: cs:trusty/mem-47 + charm: cs:xenial/mem-47 num_units: 3 to: [1, 2, 3] django: - charm: cs:trusty/django-42 + charm: cs:xenial/django-42 num_units: 4 to: - 1 @@ -1301,12 +1306,12 @@ `) c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/django-42 -service django deployed (charm cs:trusty/django-42 with the series "trusty" defined by the bundle) -added charm cs:trusty/mem-47 -service memcached deployed (charm cs:trusty/mem-47 with the series "trusty" defined by the bundle) -added charm cs:trusty/rails-0 -service ror deployed (charm cs:trusty/rails-0 with the charm series "trusty") +added charm cs:xenial/django-42 +service django deployed (charm cs:xenial/django-42 with the series "xenial" defined by the bundle) +added charm cs:xenial/mem-47 +service memcached deployed (charm cs:xenial/mem-47 with the series "xenial" defined by the bundle) +added charm cs:xenial/rails-0 +service ror deployed (charm cs:xenial/rails-0 with the charm series "xenial") created new machine 0 for holding django, memcached and ror units created new machine 1 for holding memcached unit created new machine 2 for holding memcached and ror units @@ -1345,17 +1350,17 @@ content := ` services: memcached: - charm: cs:trusty/mem-47 + charm: cs:xenial/mem-47 num_units: 3 to: [1, 2, 3] django: - charm: cs:trusty/django-42 + charm: cs:xenial/django-42 num_units: 4 to: - 1 - lxc:memcached node: - charm: cs:trusty/django-42 + charm: cs:xenial/django-42 num_units: 1 to: - lxc:memcached @@ -1367,11 +1372,11 @@ output, err = s.DeployBundleYAML(c, content) c.Assert(err, jc.ErrorIsNil) expectedOutput = ` -added charm cs:trusty/django-42 -reusing service django (charm: cs:trusty/django-42) -added charm cs:trusty/mem-47 -reusing service memcached (charm: cs:trusty/mem-47) -service node deployed (charm cs:trusty/django-42 with the series "trusty" defined by the bundle) +added charm cs:xenial/django-42 +reusing service django (charm: cs:xenial/django-42) +added charm cs:xenial/mem-47 +reusing service memcached (charm: cs:xenial/mem-47) +service node deployed (charm cs:xenial/django-42 with the series "xenial" defined by the bundle) avoid creating other machines to host django and memcached units avoid adding new units to service django: 4 units already present avoid adding new units to service memcached: 3 units already present @@ -1384,11 +1389,11 @@ output, err = s.DeployBundleYAML(c, content) c.Assert(err, jc.ErrorIsNil) expectedOutput = ` -added charm cs:trusty/django-42 -reusing service django (charm: cs:trusty/django-42) -added charm cs:trusty/mem-47 -reusing service memcached (charm: cs:trusty/mem-47) -reusing service node (charm: cs:trusty/django-42) +added charm cs:xenial/django-42 +reusing service django (charm: cs:xenial/django-42) +added charm cs:xenial/mem-47 +reusing service memcached (charm: cs:xenial/mem-47) +reusing service node (charm: cs:xenial/django-42) avoid creating other machines to host django and memcached units avoid adding new units to service django: 4 units already present avoid adding new units to service memcached: 3 units already present @@ -1412,8 +1417,8 @@ } func (s *BundleDeployCharmStoreSuite) TestDeployBundleAnnotations(c *gc.C) { - testcharms.UploadCharm(c, s.client, "trusty/django-42", "dummy") - testcharms.UploadCharm(c, s.client, "trusty/mem-47", "dummy") + testcharms.UploadCharm(c, s.client, "xenial/django-42", "dummy") + testcharms.UploadCharm(c, s.client, "xenial/mem-47", "dummy") output, err := s.DeployBundleYAML(c, ` services: django: @@ -1424,7 +1429,7 @@ key2: value2 to: [1] memcached: - charm: trusty/mem-47 + charm: xenial/mem-47 num_units: 1 machines: 1: @@ -1432,11 +1437,11 @@ `) c.Assert(err, jc.ErrorIsNil) expectedOutput := ` -added charm cs:trusty/django-42 -service django deployed (charm cs:trusty/django-42 with the charm series "trusty") +added charm cs:xenial/django-42 +service django deployed (charm cs:xenial/django-42 with the charm series "xenial") annotations set for service django -added charm cs:trusty/mem-47 -service memcached deployed (charm cs:trusty/mem-47 with the series "trusty" defined by the bundle) +added charm cs:xenial/mem-47 +service memcached deployed (charm cs:xenial/mem-47 with the series "xenial" defined by the bundle) created new machine 0 for holding django unit annotations set for machine 0 added django/0 unit to machine 0 @@ -1473,8 +1478,8 @@ `) c.Assert(err, jc.ErrorIsNil) expectedOutput = ` -added charm cs:trusty/django-42 -reusing service django (charm: cs:trusty/django-42) +added charm cs:xenial/django-42 +reusing service django (charm: cs:xenial/django-42) annotations set for service django avoid creating other machines to host django units annotations set for machine 0 diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/service/deploy.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/service/deploy.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/service/deploy.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/service/deploy.go 2016-05-17 20:01:14.000000000 +0000 @@ -13,6 +13,7 @@ "github.com/juju/cmd" "github.com/juju/errors" "github.com/juju/names" + "github.com/juju/utils/series" "gopkg.in/juju/charm.v6-unstable" charmresource "gopkg.in/juju/charm.v6-unstable/resource" "gopkg.in/juju/charmrepo.v2-unstable" @@ -530,7 +531,7 @@ } // Use latest LTS. - latestLtsSeries := config.LatestLtsSeries() + latestLtsSeries := series.LatestLts() if !force && !isSeriesSupported(latestLtsSeries, supportedSeries) { return "", "", charm.NewUnsupportedSeriesError(latestLtsSeries, supportedSeries) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/service/deploy_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/service/deploy_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/service/deploy_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/service/deploy_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -21,6 +21,7 @@ jujutesting "github.com/juju/testing" jc "github.com/juju/testing/checkers" "github.com/juju/utils" + "github.com/juju/utils/series" gc "gopkg.in/check.v1" "gopkg.in/juju/charm.v6-unstable" "gopkg.in/juju/charmrepo.v2-unstable" @@ -339,7 +340,7 @@ func (s *DeploySuite) TestPlacement(c *gc.C) { ch := testcharms.Repo.ClonedDirPath(s.CharmsPath, "dummy") // Add a machine that will be ignored due to placement directive. - machine, err := s.State.AddMachine(coretesting.FakeDefaultSeries, state.JobHostUnits) + machine, err := s.State.AddMachine(series.LatestLts(), state.JobHostUnits) c.Assert(err, jc.ErrorIsNil) err = runDeploy(c, ch, "-n", "1", "--to", "valid", "--series", "quantal") @@ -403,9 +404,9 @@ func (s *DeploySuite) TestForceMachine(c *gc.C) { ch := testcharms.Repo.CharmArchivePath(s.CharmsPath, "dummy") - machine, err := s.State.AddMachine(coretesting.FakeDefaultSeries, state.JobHostUnits) + machine, err := s.State.AddMachine(series.LatestLts(), state.JobHostUnits) c.Assert(err, jc.ErrorIsNil) - err = runDeploy(c, "--to", machine.Id(), ch, "portlandia", "--series", coretesting.FakeDefaultSeries) + err = runDeploy(c, "--to", machine.Id(), ch, "portlandia", "--series", series.LatestLts()) c.Assert(err, jc.ErrorIsNil) s.assertForceMachine(c, machine.Id()) } @@ -413,12 +414,12 @@ func (s *DeploySuite) TestForceMachineExistingContainer(c *gc.C) { ch := testcharms.Repo.CharmArchivePath(s.CharmsPath, "dummy") template := state.MachineTemplate{ - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, } container, err := s.State.AddMachineInsideNewMachine(template, template, instance.LXC) c.Assert(err, jc.ErrorIsNil) - err = runDeploy(c, "--to", container.Id(), ch, "portlandia", "--series", coretesting.FakeDefaultSeries) + err = runDeploy(c, "--to", container.Id(), ch, "portlandia", "--series", series.LatestLts()) c.Assert(err, jc.ErrorIsNil) s.assertForceMachine(c, container.Id()) machines, err := s.State.AllMachines() @@ -428,9 +429,9 @@ func (s *DeploySuite) TestForceMachineNewContainer(c *gc.C) { ch := testcharms.Repo.CharmArchivePath(s.CharmsPath, "dummy") - machine, err := s.State.AddMachine(coretesting.FakeDefaultSeries, state.JobHostUnits) + machine, err := s.State.AddMachine(series.LatestLts(), state.JobHostUnits) c.Assert(err, jc.ErrorIsNil) - err = runDeploy(c, "--to", "lxc:"+machine.Id(), ch, "portlandia", "--series", coretesting.FakeDefaultSeries) + err = runDeploy(c, "--to", "lxc:"+machine.Id(), ch, "portlandia", "--series", series.LatestLts()) c.Assert(err, jc.ErrorIsNil) s.assertForceMachine(c, machine.Id()+"/lxc/0") @@ -456,7 +457,7 @@ } func (s *DeploySuite) TestForceMachineSubordinate(c *gc.C) { - machine, err := s.State.AddMachine(coretesting.FakeDefaultSeries, state.JobHostUnits) + machine, err := s.State.AddMachine(series.LatestLts(), state.JobHostUnits) c.Assert(err, jc.ErrorIsNil) ch := testcharms.Repo.CharmArchivePath(s.CharmsPath, "logging") err = runDeploy(c, "--to", machine.Id(), ch, "--series", "quantal") @@ -501,7 +502,7 @@ supportedSeries: []string{"trusty", "precise"}, err: `series "wily" not supported by charm, supported series are: trusty,precise`, }, { - ltsSeries: config.LatestLtsSeries(), + ltsSeries: series.LatestLts(), err: `series .* not supported by charm, supported series are: .*`, }, { modelSeries: "xenial", @@ -519,9 +520,9 @@ message: "with the user specified series %q", force: true, }, { - ltsSeries: config.LatestLtsSeries(), + ltsSeries: series.LatestLts(), force: true, - expectedSeries: config.LatestLtsSeries(), + expectedSeries: series.LatestLts(), message: "with the latest LTS series %q", }, { ltsSeries: "precise", diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/service/removeunit_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/service/removeunit_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/service/removeunit_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/service/removeunit_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -7,6 +7,7 @@ "fmt" jc "github.com/juju/testing/checkers" + "github.com/juju/utils/series" gc "gopkg.in/check.v1" "gopkg.in/juju/charm.v6-unstable" @@ -38,9 +39,9 @@ func (s *RemoveUnitSuite) setupUnitForRemove(c *gc.C) *state.Service { ch := testcharms.Repo.CharmArchivePath(s.CharmsPath, "dummy") - err := runDeploy(c, "-n", "2", ch, "dummy", "--series", testing.FakeDefaultSeries) + err := runDeploy(c, "-n", "2", ch, "dummy", "--series", series.LatestLts()) c.Assert(err, jc.ErrorIsNil) - curl := charm.MustParseURL(fmt.Sprintf("local:%s/dummy-1", testing.FakeDefaultSeries)) + curl := charm.MustParseURL(fmt.Sprintf("local:%s/dummy-1", series.LatestLts())) svc, _ := s.AssertService(c, "dummy", curl, 2, 0) return svc } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/status/output_summary.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/status/output_summary.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/juju/status/output_summary.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/juju/status/output_summary.go 2016-05-17 20:01:14.000000000 +0000 @@ -135,7 +135,7 @@ } } - ipNet := net.IPNet{ip, ip.DefaultMask()} + ipNet := net.IPNet{IP: ip, Mask: ip.DefaultMask()} f.ipAddrs = append(f.ipAddrs, ipNet) f.netStrings = append(f.netStrings, ipNet.String()) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/jujud/agent/machine.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/jujud/agent/machine.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/jujud/agent/machine.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/jujud/agent/machine.go 2016-05-17 20:01:14.000000000 +0000 @@ -575,11 +575,11 @@ // restoreChanged will be called whenever restoreInfo doc changes signaling a new // step in the restore process. func (a *MachineAgent) restoreChanged(st *state.State) error { - rinfo, err := st.RestoreInfoSetter() + status, err := st.RestoreInfo().Status() if err != nil { return errors.Annotate(err, "cannot read restore state") } - switch rinfo.Status() { + switch status { case state.RestorePending: a.PrepareRestore() case state.RestoreInProgress: diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/jujud/agent/machine_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/jujud/agent/machine_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/jujud/agent/machine_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/jujud/agent/machine_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -50,6 +50,7 @@ "github.com/juju/juju/juju" jujutesting "github.com/juju/juju/juju/testing" "github.com/juju/juju/mongo" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/network" "github.com/juju/juju/provider/dummy" "github.com/juju/juju/service/upstart" @@ -93,7 +94,7 @@ s.AgentSuite.SetUpSuite(c) s.TestSuite.SetUpSuite(c) s.AgentSuite.PatchValue(&jujuversion.Current, coretesting.FakeVersionNumber) - s.AgentSuite.PatchValue(&stateWorkerDialOpts, mongo.DefaultDialOpts()) + s.AgentSuite.PatchValue(&stateWorkerDialOpts, mongotest.DialOpts()) } func (s *commonMachineSuite) TearDownSuite(c *gc.C) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/jujud/agent/testing/agent.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/jujud/agent/testing/agent.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/jujud/agent/testing/agent.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/jujud/agent/testing/agent.go 2016-05-17 20:01:14.000000000 +0000 @@ -28,6 +28,7 @@ envtools "github.com/juju/juju/environs/tools" "github.com/juju/juju/juju/testing" "github.com/juju/juju/mongo" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/network" "github.com/juju/juju/state" coretesting "github.com/juju/juju/testing" @@ -244,7 +245,7 @@ c.Assert(err, jc.ErrorIsNil) info, ok := config.MongoInfo() c.Assert(ok, jc.IsTrue) - st, err := state.Open(config.Model(), info, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + st, err := state.Open(config.Model(), info, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) st.Close() } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/jujud/bootstrap_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/jujud/bootstrap_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/jujud/bootstrap_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/jujud/bootstrap_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -49,6 +49,7 @@ "github.com/juju/juju/juju" jujutesting "github.com/juju/juju/juju/testing" "github.com/juju/juju/mongo" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/network" "github.com/juju/juju/provider/dummy" "github.com/juju/juju/state" @@ -270,7 +271,7 @@ CACert: testing.CACert, }, Password: testPassword, - }, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() @@ -383,7 +384,7 @@ CACert: testing.CACert, }, Password: testPassword, - }, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() machines, err := st.AllMachines() @@ -445,7 +446,7 @@ CACert: testing.CACert, }, Password: testPassword, - }, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() @@ -476,7 +477,7 @@ CACert: testing.CACert, }, Password: testPassword, - }, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() @@ -517,7 +518,7 @@ CACert: testing.CACert, }, Password: testPassword, - }, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() m, err := st.Machine("0") @@ -542,7 +543,7 @@ CACert: testing.CACert, }, Password: testPassword, - }, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() m, err := st.Machine("0") @@ -551,7 +552,7 @@ } func testOpenState(c *gc.C, info *mongo.MongoInfo, expectErrType error) { - st, err := state.Open(testing.ModelTag, info, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + st, err := state.Open(testing.ModelTag, info, mongotest.DialOpts(), environs.NewStatePolicy()) if st != nil { st.Close() } @@ -583,7 +584,7 @@ // Check we can log in to mongo as admin. // TODO(dfc) does passing nil for the admin user name make your skin crawl ? mine too. info.Tag, info.Password = nil, testPassword - st, err := state.Open(testing.ModelTag, info, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + st, err := state.Open(testing.ModelTag, info, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() @@ -592,7 +593,7 @@ // explicit Login will still be verified. adminDB := st.MongoSession().DB("admin") err = adminDB.Login("admin", "invalid-password") - c.Assert(err, gc.ErrorMatches, "auth fail(s|ed)") + c.Assert(err, gc.ErrorMatches, "(auth|(.*Authentication)) fail(s|ed)\\.?") err = adminDB.Login("admin", info.Password) c.Assert(err, jc.ErrorIsNil) @@ -610,7 +611,7 @@ stateinfo, ok := machineConf1.MongoInfo() c.Assert(ok, jc.IsTrue) - st, err = state.Open(testing.ModelTag, stateinfo, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + st, err = state.Open(testing.ModelTag, stateinfo, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() @@ -819,7 +820,7 @@ CACert: testing.CACert, }, Password: testPassword, - }, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() expectedSeries := make(set.Strings) @@ -945,7 +946,7 @@ CACert: testing.CACert, }, Password: testPassword, - }, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() @@ -1129,7 +1130,7 @@ CACert: testing.CACert, }, Password: testPassword, - }, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + }, mongotest.DialOpts(), environs.NewStatePolicy()) c.Assert(err, jc.ErrorIsNil) defer st.Close() diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/jujud/reboot/reboot_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/jujud/reboot/reboot_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/jujud/reboot/reboot_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/jujud/reboot/reboot_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -13,6 +13,7 @@ "github.com/juju/juju/agent" "github.com/juju/juju/api" "github.com/juju/juju/cmd/jujud/reboot" + "github.com/juju/juju/instance" jujutesting "github.com/juju/juju/juju/testing" "github.com/juju/juju/mongo" coretesting "github.com/juju/juju/testing" @@ -36,10 +37,15 @@ var _ = gc.Suite(&RebootSuite{}) +func (s *RebootSuite) SetUpSuite(c *gc.C) { + s.JujuConnSuite.SetUpSuite(c) + + // These tests only patch out LXC, so only run full-stack tests + // over LXC. + s.PatchValue(&instance.ContainerTypes, []instance.ContainerType{instance.LXC}) +} + func (s *RebootSuite) SetUpTest(c *gc.C) { - if testing.GOVERSION < 1.3 { - c.Skip("skipping test, lxd requires Go 1.3 or later") - } s.JujuConnSuite.SetUpTest(c) testing.PatchExecutableAsEchoArgs(c, s, rebootBin) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/jujud/upgrade_mongo.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/jujud/upgrade_mongo.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/jujud/upgrade_mongo.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/jujud/upgrade_mongo.go 2016-05-17 20:01:14.000000000 +0000 @@ -632,6 +632,9 @@ if err := pacman.Install(mongo.JujuMongoPackage); err != nil { return errors.Annotatef(err, "cannot install %v", mongo.JujuMongoPackage) } + if err := pacman.Install(mongo.JujuMongoToolsPackage); err != nil { + return errors.Annotatef(err, "cannot install %v", mongo.JujuMongoToolsPackage) + } return nil } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/modelcmd/modelcommand.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/modelcmd/modelcommand.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/modelcmd/modelcommand.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/modelcmd/modelcommand.go 2016-05-17 20:01:14.000000000 +0000 @@ -275,7 +275,7 @@ func (w *modelCommandWrapper) SetFlags(f *gnuflag.FlagSet) { if !w.skipFlags { - f.StringVar(&w.modelName, "m", "", "Model to operate in") + f.StringVar(&w.modelName, "m", "", "Model to operate in. Accepts [:]") f.StringVar(&w.modelName, "model", "", "") } w.ModelCommand.SetFlags(f) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/plugins/juju-metadata/imagemetadata.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/plugins/juju-metadata/imagemetadata.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/plugins/juju-metadata/imagemetadata.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/plugins/juju-metadata/imagemetadata.go 2016-05-17 20:01:14.000000000 +0000 @@ -11,6 +11,7 @@ "github.com/juju/cmd" "github.com/juju/errors" "github.com/juju/utils/arch" + "github.com/juju/utils/series" "launchpad.net/gnuflag" "github.com/juju/juju/cmd/modelcmd" @@ -131,7 +132,7 @@ logger.Infof("no model found, creating image metadata using user supplied data") } if c.Series == "" { - c.Series = config.LatestLtsSeries() + c.Series = series.LatestLts() } if c.ImageId == "" { return errors.Errorf("image id must be specified") diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/cmd/plugins/juju-metadata/imagemetadata_test.go juju-core-2.0~beta7/src/github.com/juju/juju/cmd/plugins/juju-metadata/imagemetadata_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/cmd/plugins/juju-metadata/imagemetadata_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/cmd/plugins/juju-metadata/imagemetadata_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -13,6 +13,7 @@ "github.com/juju/cmd" jc "github.com/juju/testing/checkers" + "github.com/juju/utils/series" gc "gopkg.in/check.v1" "github.com/juju/juju/cmd/modelcmd" @@ -167,7 +168,7 @@ c.Assert(err, jc.ErrorIsNil) out := testing.Stdout(ctx) expected := expectedMetadata{ - series: config.LatestLtsSeries(), + series: series.LatestLts(), arch: "arch", } s.assertCommandOutput(c, expected, out, defaultIndexFileName, defaultImageFileName) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/component/all/payload.go juju-core-2.0~beta7/src/github.com/juju/juju/component/all/payload.go --- juju-core-2.0~beta6/src/github.com/juju/juju/component/all/payload.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/component/all/payload.go 2016-05-17 20:01:14.000000000 +0000 @@ -82,7 +82,7 @@ if err != nil { return nil, errors.Trace(err) } - caller := base.NewFacadeCallerForVersion(apiCaller, payload.ComponentName, 0) + caller := base.NewFacadeCallerForVersion(apiCaller, payload.ComponentName, 1) listAPI := client.NewPublicClient(&facadeCaller{ FacadeCaller: caller, diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/controller/modelmanager/createmodel_test.go juju-core-2.0~beta7/src/github.com/juju/juju/controller/modelmanager/createmodel_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/controller/modelmanager/createmodel_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/controller/modelmanager/createmodel_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -286,7 +286,7 @@ provider: "azure", expected: []string{ "type", "ca-cert", "state-port", "api-port", "controller-uuid", - "location", "endpoint", "storage-endpoint", "controller-resource-group", + "location", "endpoint", "storage-endpoint", }, }, { provider: "dummy", @@ -314,7 +314,7 @@ provider: "ec2", expected: []string{ "type", "ca-cert", "state-port", "api-port", "controller-uuid", - "region", + "region", "vpc-id", "vpc-id-force", }, }} { c.Logf("%d: %s provider", i, test.provider) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/dependencies.tsv juju-core-2.0~beta7/src/github.com/juju/juju/dependencies.tsv --- juju-core-2.0~beta6/src/github.com/juju/juju/dependencies.tsv 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/dependencies.tsv 2016-05-17 20:01:14.000000000 +0000 @@ -1,4 +1,4 @@ -github.com/Azure/azure-sdk-for-go git 9f40dc1ee704920d20418200ddf6ec382456bb0e 2015-10-27T07:30:22Z +github.com/Azure/azure-sdk-for-go git 3b480eaaf6b4236d43a3c06cba969da6f53c8b66 2015-11-23T16:56:25Z github.com/ajstarks/svgo git 89e3ac64b5b3e403a5e7c35ea4f98d45db7b4518 2014-10-04T21:11:59Z github.com/altoros/gosigma git 31228935eec685587914528585da4eb9b073c76d 2015-04-08T14:52:32Z github.com/bmizerany/pat git 48be7df2c27e1cec821a3284a683ce6ef90d9052 2014-04-29T04:34:05Z @@ -19,10 +19,10 @@ github.com/juju/gojsonpointer git afe8b77aa08f272b49e01b82de78510c11f61500 2015-02-04T19:46:29Z github.com/juju/gojsonreference git f0d24ac5ee330baa21721cdff56d45e4ee42628e 2015-02-04T19:46:33Z github.com/juju/gojsonschema git e1ad140384f254c82f89450d9a7c8dd38a632838 2015-03-12T17:00:16Z -github.com/juju/gomaasapi git 9ec917cdad9e610c7573973393b08ca98d6e0886 2016-04-25T09:27:20Z +github.com/juju/gomaasapi git 5bd7212f416a2d801e4a39800b66e1ee4461c42e 2016-05-03T13:03:30Z github.com/juju/govmomi git 4354a88d4b34abe467215f77c2fc1cb9f78b66f7 2015-04-24T01:54:48Z github.com/juju/httpprof git 14bf14c307672fd2456bdbf35d19cf0ccd3cf565 2014-12-17T16:00:36Z -github.com/juju/httprequest git 89d547093c45e293599088cc63e805c6f1205dc0 2016-03-02T10:09:58Z +github.com/juju/httprequest git 796aaafaf712f666df58d31a482c51233038bf9f 2016-05-03T15:03:27Z github.com/juju/idmclient git 1995850da11150fb9247e43c6089e54eaeaae44a 2016-04-01T13:35:05Z github.com/juju/loggo git 8477fc936adf0e382d680310047ca27e128a309a 2015-05-27T03:58:39Z github.com/juju/mempool git 24974d6c264fe5a29716e7d56ea24c4bd904b7cc 2016-02-05T10:49:27Z @@ -31,12 +31,12 @@ github.com/juju/ratelimit git aa5bb718d4d435629821789cb90970319f57bfe5 2015-03-30T01:41:32Z github.com/juju/replicaset git fb7294cf57a1e2f08a57691f1246d129a87ab7e8 2015-05-08T02:21:43Z github.com/juju/retry git 62c62032529169c7ec02fa48f93349604c345e1f 2015-10-29T02:48:21Z -github.com/juju/romulus git df735617fa6a358e42bb71ff74b3c3ba4faf9f5f 2016-04-19T16:05:42Z +github.com/juju/romulus git 767a53ef0929d969a3c81c53c6b9f8e94a95dae5 2016-04-27T14:39:56Z github.com/juju/schema git 075de04f9b7d7580d60a1e12a0b3f50bb18e6998 2016-04-20T04:42:03Z -github.com/juju/testing git 162fafccebf20a4207ab93d63b986c230e3f4d2e 2016-04-04T09:43:17Z +github.com/juju/testing git 3ea8417b3125018f678eb9159731917d01121445 2016-05-02T22:59:23Z github.com/juju/txn git 99ec629d0066a4d73c54d8e021a7fc1dc07df614 2015-06-09T16:58:27Z github.com/juju/usso git 68a59c96c178fbbad65926e7f93db50a2cd14f33 2016-04-01T10:44:24Z -github.com/juju/utils git 951b27b4808bad43b9107412e002576c9d1b18bb 2016-04-20T20:18:51Z +github.com/juju/utils git d5423ca3ec0b0cc8ccf093fab1365b1c9f93eb2d 2016-05-02T18:15:00Z github.com/juju/version git ef897ad7f130870348ce306f61332f5335355063 2015-11-27T20:34:00Z github.com/juju/webbrowser git 54b8c57083b4afb7dc75da7f13e2967b2606a507 2016-03-09T14:36:29Z github.com/juju/xml git eb759a627588d35166bc505fceb51b88500e291e 2015-04-13T13:11:21Z @@ -49,18 +49,18 @@ golang.org/x/oauth2 git 11c60b6f71a6ad48ed6f93c65fa4c6f9b1b5b46a 2015-03-25T02:00:22Z google.golang.org/api git 0d3983fb069cb6651353fc44c5cb604e263f2a93 2014-12-10T23:51:26Z google.golang.org/cloud git f20d6dcccb44ed49de45ae3703312cb46e627db1 2015-03-19T22:36:35Z -gopkg.in/amz.v3 git 345e9291dbc9e6dd7b6c6c679b32b6d3366ca851 2016-02-24T10:59:20Z +gopkg.in/amz.v3 git a651c43e72df7778b14ac6b54e5ac119d32b1263 2016-04-20T02:16:08Z gopkg.in/check.v1 git 4f90aeace3a26ad7021961c297b22c42160c7b25 2016-01-05T16:49:36Z gopkg.in/errgo.v1 git 66cb46252b94c1f3d65646f54ee8043ab38d766c 2015-10-07T15:31:57Z gopkg.in/goose.v1 git 495e6fa2ab89bc5ed2c8e1bbcbc4c9e4a3c97d37 2016-03-17T17:25:46Z gopkg.in/ini.v1 git 776aa739ce9373377cd16f526cdf06cb4c89b40f 2016-02-22T23:24:41Z gopkg.in/juju/blobstore.v2 git 51fa6e26128d74e445c72d3a91af555151cc3654 2016-01-25T02:37:03Z -gopkg.in/juju/charm.v6-unstable git 728a5ea3ff1c1ae8b4c3ac4779c0027f693d1ca5 2016-04-08T11:12:17Z +gopkg.in/juju/charm.v6-unstable git 9857751ba31e81773bbb42557e85054d6b4de4dd 2016-04-27T02:42:06Z gopkg.in/juju/charmrepo.v2-unstable git c457416da598dffa665fc75aeb5c7265ff1273c0 2016-04-13T10:03:17Z gopkg.in/juju/charmstore.v5-unstable git 745fa1ca2260cdc9dd5a6df6282da51776baa59f 2016-04-12T11:34:55Z gopkg.in/juju/environschema.v1 git 7359fc7857abe2b11b5b3e23811a9c64cb6b01e0 2015-11-04T11:58:10Z gopkg.in/juju/jujusvg.v1 git a60359df348ef2ca40ec3bcd58a01de54f05658e 2016-02-11T10:02:50Z -gopkg.in/macaroon-bakery.v1 git fddb3dcd74806133259879d033fdfe92f9e67a8a 2016-04-01T12:14:21Z +gopkg.in/macaroon-bakery.v1 git c8e0209b0f4e48e8603ab0ae2477445f9443fbdc 2016-05-03T12:38:55Z gopkg.in/macaroon.v1 git ab3940c6c16510a850e1c2dd628b919f0f3f1464 2015-01-21T11:42:31Z gopkg.in/mgo.v2 git 4d04138ffef2791c479c0c8bbffc30b34081b8d9 2015-10-26T16:34:53Z gopkg.in/natefinch/lumberjack.v2 git 514cbda263a734ae8caac038dadf05f8f3f9f738 2016-01-25T11:17:49Z diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/doc/lts-update-issues.md juju-core-2.0~beta7/src/github.com/juju/juju/doc/lts-update-issues.md --- juju-core-2.0~beta6/src/github.com/juju/juju/doc/lts-update-issues.md 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/doc/lts-update-issues.md 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,11 @@ +LTS Update Issues +================= + +When we update ubuntu LTS versions we run into some issues updating tests. When updating from Trusty to Xenial we attempted to simplify future updates. There are still a few places that need modification when an LTS update happends. `grep -r LTS-dependent` at the top of the core repo to find the locations that are expected to require updates at the next LTS release. As of this writing that would be in the following files: + + - cmd/juju/service/bundle_test.go + - provider/ec2/export_test.go + - provider/ec2/image_test.go + - testing/base.go + +There will likely be other locations by the next release, but this should provide a headstart. diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/downloader/downloader.go juju-core-2.0~beta7/src/github.com/juju/juju/downloader/downloader.go --- juju-core-2.0~beta6/src/github.com/juju/juju/downloader/downloader.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/downloader/downloader.go 2016-05-17 20:01:14.000000000 +0000 @@ -1,121 +1,86 @@ -// Copyright 2012, 2013 Canonical Ltd. +// Copyright 2016 Canonical Ltd. // Licensed under the AGPLv3, see LICENCE file for details. package downloader import ( - "fmt" "io" - "io/ioutil" - "net/http" + "net/url" "os" + "github.com/juju/errors" "github.com/juju/loggo" "github.com/juju/utils" - "launchpad.net/tomb" ) var logger = loggo.GetLogger("juju.downloader") -// Status represents the status of a completed download. -type Status struct { - // File holds the downloaded data on success. - File *os.File - // Err describes any error encountered while downloading. - Err error -} - -// Download can download a file from the network. -type Download struct { - tomb tomb.Tomb - done chan Status - hostnameVerification utils.SSLHostnameVerification -} - -// New returns a new Download instance downloading from the given URL -// to the given directory. If dir is empty, it defaults to -// os.TempDir(). If disableSSLHostnameVerification is true then a non- -// validating http client will be used. -func New(url, dir string, hostnameVerification utils.SSLHostnameVerification) *Download { - d := &Download{ - done: make(chan Status), - hostnameVerification: hostnameVerification, - } - go d.run(url, dir) - return d -} - -// Stop stops any download that's in progress. -func (d *Download) Stop() { - d.tomb.Kill(nil) - d.tomb.Wait() -} - -// Done returns a channel that receives a status when the download has -// completed. It is the receiver's responsibility to close and remove -// the received file. -func (d *Download) Done() <-chan Status { - return d.done -} - -func (d *Download) run(url, dir string) { - defer d.tomb.Done() - // TODO(dimitern) 2013-10-03 bug #1234715 - // Add a testing HTTPS storage to verify the - // disableSSLHostnameVerification behavior here. - file, err := download(url, dir, d.hostnameVerification) - if err != nil { - err = fmt.Errorf("cannot download %q: %v", url, err) - } - status := Status{ - File: file, - Err: err, - } - select { - case d.done <- status: - case <-d.tomb.Dying(): - cleanTempFile(status.File) - } +// Downloader provides the functionality for downloading files. +type Downloader struct { + // OpenBlob is the func used to gain access to the blob, whether + // through an HTTP request or some other means. + OpenBlob func(*url.URL) (io.ReadCloser, error) } -func download(url, dir string, hostnameVerification utils.SSLHostnameVerification) (file *os.File, err error) { - if dir == "" { - dir = os.TempDir() - } - tempFile, err := ioutil.TempFile(dir, "inprogress-") - if err != nil { - return nil, err +// NewArgs holds the arguments to New(). +type NewArgs struct { + // HostnameVerification is that which should be used for the client. + // If it is disableSSLHostnameVerification then a non-validating + // client will be used. + HostnameVerification utils.SSLHostnameVerification +} + +// New returns a new Downloader for the given args. +func New(args NewArgs) *Downloader { + return &Downloader{ + OpenBlob: NewHTTPBlobOpener(args.HostnameVerification), } - defer func() { - if err != nil { - cleanTempFile(tempFile) - } - }() - // TODO(rog) make the download operation interruptible. - client := utils.GetHTTPClient(hostnameVerification) - resp, err := client.Get(url) - if err != nil { - return nil, err +} + +// Start starts a new download and returns it. +func (dlr Downloader) Start(req Request) *Download { + dl := StartDownload(req, dlr.OpenBlob) + return dl +} + +// Download starts a new download, waits for it to complete, and +// returns the local name of the file. +func (dlr Downloader) Download(req Request, abort <-chan struct{}) (filename string, err error) { + if err := os.MkdirAll(req.TargetDir, 0755); err != nil { + return "", errors.Trace(err) } - defer resp.Body.Close() - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("bad http response: %v", resp.Status) + dl := dlr.Start(req) + file, err := dl.Wait(abort) + if file != nil { + defer file.Close() } - _, err = io.Copy(tempFile, resp.Body) if err != nil { - return nil, err - } - if _, err := tempFile.Seek(0, 0); err != nil { - return nil, err + return "", errors.Trace(err) } - return tempFile, nil + return file.Name(), nil } -func cleanTempFile(f *os.File) { - if f != nil { - f.Close() - if err := os.Remove(f.Name()); err != nil { - logger.Warningf("cannot remove temp file %q: %v", f.Name(), err) +// DownloadWithAlternates tries each of the provided requests until +// one succeeds. If none succeed then the error from the most recent +// attempt is returned. At least one request must be provided. +func (dlr Downloader) DownloadWithAlternates(requests []Request, abort <-chan struct{}) (filename string, err error) { + if len(requests) == 0 { + return "", errors.New("no requests to try") + } + + for _, req := range requests { + filename, err = dlr.Download(req, abort) + if errors.IsNotValid(err) { + break + } + if err == nil { + break } + logger.Errorf("download request to %s failed: %v", req.URL, err) + // Try the next one. + } + if err != nil { + return "", errors.Trace(err) } + return filename, nil } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/downloader/downloader_test.go juju-core-2.0~beta7/src/github.com/juju/juju/downloader/downloader_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/downloader/downloader_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/downloader/downloader_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -1,13 +1,13 @@ -// Copyright 2012, 2013 Canonical Ltd. +// Copyright 2016 Canonical Ltd. // Licensed under the AGPLv3, see LICENCE file for details. package downloader_test import ( "io/ioutil" + "net/url" "os" "path/filepath" - stdtesting "testing" "time" gitjujutesting "github.com/juju/testing" @@ -19,74 +19,95 @@ "github.com/juju/juju/testing" ) -type suite struct { +type DownloaderSuite struct { testing.BaseSuite gitjujutesting.HTTPSuite } -func (s *suite) SetUpSuite(c *gc.C) { +func (s *DownloaderSuite) SetUpSuite(c *gc.C) { s.BaseSuite.SetUpSuite(c) s.HTTPSuite.SetUpSuite(c) } -func (s *suite) TearDownSuite(c *gc.C) { +func (s *DownloaderSuite) TearDownSuite(c *gc.C) { s.HTTPSuite.TearDownSuite(c) s.BaseSuite.TearDownSuite(c) } -func (s *suite) SetUpTest(c *gc.C) { +func (s *DownloaderSuite) SetUpTest(c *gc.C) { s.BaseSuite.SetUpTest(c) s.HTTPSuite.SetUpTest(c) } -func (s *suite) TearDownTest(c *gc.C) { +func (s *DownloaderSuite) TearDownTest(c *gc.C) { s.HTTPSuite.TearDownTest(c) s.BaseSuite.TearDownTest(c) } -var _ = gc.Suite(&suite{}) +var _ = gc.Suite(&DownloaderSuite{}) -func Test(t *stdtesting.T) { - gc.TestingT(t) +func (s *DownloaderSuite) URL(c *gc.C, path string) *url.URL { + urlStr := s.HTTPSuite.URL(path) + URL, err := url.Parse(urlStr) + c.Assert(err, jc.ErrorIsNil) + return URL } -func (s *suite) testDownload(c *gc.C, hostnameVerification utils.SSLHostnameVerification) { +func (s *DownloaderSuite) testDownload(c *gc.C, hostnameVerification utils.SSLHostnameVerification) { tmp := c.MkDir() gitjujutesting.Server.Response(200, nil, []byte("archive")) - d := downloader.New(s.URL("/archive.tgz"), tmp, hostnameVerification) - status := <-d.Done() - c.Assert(status.Err, gc.IsNil) - c.Assert(status.File, gc.NotNil) + dlr := downloader.New(downloader.NewArgs{ + HostnameVerification: hostnameVerification, + }) + dl := dlr.Start(downloader.Request{ + URL: s.URL(c, "/archive.tgz"), + TargetDir: tmp, + }) + status := <-dl.Done() defer os.Remove(status.File.Name()) defer status.File.Close() + c.Assert(status.Err, gc.IsNil) + c.Assert(status.File, gc.NotNil) dir, _ := filepath.Split(status.File.Name()) c.Assert(filepath.Clean(dir), gc.Equals, tmp) assertFileContents(c, status.File, "archive") } -func (s *suite) TestDownloadWithoutDisablingSSLHostnameVerification(c *gc.C) { +func (s *DownloaderSuite) TestDownloadWithoutDisablingSSLHostnameVerification(c *gc.C) { s.testDownload(c, utils.VerifySSLHostnames) } -func (s *suite) TestDownloadWithDisablingSSLHostnameVerification(c *gc.C) { +func (s *DownloaderSuite) TestDownloadWithDisablingSSLHostnameVerification(c *gc.C) { s.testDownload(c, utils.NoVerifySSLHostnames) } -func (s *suite) TestDownloadError(c *gc.C) { +func (s *DownloaderSuite) TestDownloadError(c *gc.C) { gitjujutesting.Server.Response(404, nil, nil) - d := downloader.New(s.URL("/archive.tgz"), c.MkDir(), utils.VerifySSLHostnames) - status := <-d.Done() + dlr := downloader.New(downloader.NewArgs{ + HostnameVerification: utils.VerifySSLHostnames, + }) + dl := dlr.Start(downloader.Request{ + URL: s.URL(c, "/archive.tgz"), + TargetDir: c.MkDir(), + }) + status := <-dl.Done() c.Assert(status.File, gc.IsNil) c.Assert(status.Err, gc.ErrorMatches, `cannot download ".*": bad http response: 404 Not Found`) } -func (s *suite) TestStopDownload(c *gc.C) { +func (s *DownloaderSuite) TestStopDownload(c *gc.C) { tmp := c.MkDir() - d := downloader.New(s.URL("/x.tgz"), tmp, utils.VerifySSLHostnames) - d.Stop() + dlr := downloader.New(downloader.NewArgs{ + HostnameVerification: utils.VerifySSLHostnames, + }) + dl := dlr.Start(downloader.Request{ + URL: s.URL(c, "/x.tgz"), + TargetDir: tmp, + }) + dl.Stop() select { - case status := <-d.Done(): + case status := <-dl.Done(): c.Fatalf("received status %#v after stop", status) case <-time.After(testing.ShortWait): } @@ -94,13 +115,3 @@ c.Assert(err, jc.ErrorIsNil) c.Assert(infos, gc.HasLen, 0) } - -func assertFileContents(c *gc.C, f *os.File, expect string) { - got, err := ioutil.ReadAll(f) - c.Assert(err, jc.ErrorIsNil) - if !c.Check(string(got), gc.Equals, expect) { - info, err := f.Stat() - c.Assert(err, jc.ErrorIsNil) - c.Logf("info %#v", info) - } -} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/downloader/download.go juju-core-2.0~beta7/src/github.com/juju/juju/downloader/download.go --- juju-core-2.0~beta6/src/github.com/juju/juju/downloader/download.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/downloader/download.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,190 @@ +// Copyright 2012, 2013 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package downloader + +import ( + "io" + "io/ioutil" + "net/url" + "os" + + "github.com/juju/errors" + "github.com/juju/utils" + "launchpad.net/tomb" +) + +// Request holds a single download request. +type Request struct { + // URL is the location from which the file will be downloaded. + URL *url.URL + + // TargetDir is the directory into which the file will be downloaded. + // It defaults to os.TempDir(). + TargetDir string + + // Verify is used to ensure that the download result is correct. If + // the download is invalid then the func must return errors.NotValid. + // If no func is provided then no verification happens. + Verify func(*os.File) error +} + +// Status represents the status of a completed download. +type Status struct { + // File holds the downloaded data on success. + File *os.File + + // Err describes any error encountered while downloading. + Err error +} + +// Download can download a file from the network. +type Download struct { + tomb tomb.Tomb + done chan Status + openBlob func(*url.URL) (io.ReadCloser, error) +} + +// StartDownload returns a new Download instance based on the provided +// request. openBlob is used to gain access to the blob, whether through +// an HTTP request or some other means. +func StartDownload(req Request, openBlob func(*url.URL) (io.ReadCloser, error)) *Download { + dl := newDownload(openBlob) + go dl.run(req) + return dl +} + +func newDownload(openBlob func(*url.URL) (io.ReadCloser, error)) *Download { + if openBlob == nil { + openBlob = NewHTTPBlobOpener(utils.NoVerifySSLHostnames) + } + return &Download{ + done: make(chan Status), + openBlob: openBlob, + } +} + +// Stop stops any download that's in progress. +func (dl *Download) Stop() { + dl.tomb.Kill(nil) + dl.tomb.Wait() +} + +// Done returns a channel that receives a status when the download has +// completed. It is the receiver's responsibility to close and remove +// the received file. +func (dl *Download) Done() <-chan Status { + return dl.done +} + +// Wait blocks until the download completes or the abort channel receives. +func (dl *Download) Wait(abort <-chan struct{}) (*os.File, error) { + defer dl.Stop() + + select { + case <-abort: + logger.Infof("download aborted") + return nil, errors.New("aborted") + case status := <-dl.Done(): + if status.Err != nil { + if status.File != nil { + if err := status.File.Close(); err != nil { + logger.Errorf("failed to close file: %v", err) + } + } + return nil, errors.Trace(status.Err) + } + return status.File, nil + } +} + +func (dl *Download) run(req Request) { + defer dl.tomb.Done() + + // TODO(dimitern) 2013-10-03 bug #1234715 + // Add a testing HTTPS storage to verify the + // disableSSLHostnameVerification behavior here. + file, err := download(req, dl.openBlob) + if err != nil { + err = errors.Annotatef(err, "cannot download %q", req.URL) + } + + if err == nil { + logger.Infof("download complete (%q)", req.URL) + if req.Verify != nil { + err = verifyDownload(file, req) + } + } + + status := Status{ + File: file, + Err: err, + } + select { + case dl.done <- status: + // no-op + case <-dl.tomb.Dying(): + cleanTempFile(file) + } +} + +func verifyDownload(file *os.File, req Request) error { + err := req.Verify(file) + if err != nil { + if errors.IsNotValid(err) { + logger.Errorf("download of %s invalid: %v", req.URL, err) + } + return errors.Trace(err) + } + logger.Infof("download verified (%q)", req.URL) + + if _, err := file.Seek(0, os.SEEK_SET); err != nil { + logger.Errorf("failed to seek to beginning of file: %v", err) + return errors.Trace(err) + } + return nil +} + +func download(req Request, openBlob func(*url.URL) (io.ReadCloser, error)) (file *os.File, err error) { + logger.Infof("downloading from %s", req.URL) + + dir := req.TargetDir + if dir == "" { + dir = os.TempDir() + } + tempFile, err := ioutil.TempFile(dir, "inprogress-") + if err != nil { + return nil, errors.Trace(err) + } + defer func() { + if err != nil { + cleanTempFile(tempFile) + } + }() + + reader, err := openBlob(req.URL) + if err != nil { + return nil, errors.Trace(err) + } + defer reader.Close() + + _, err = io.Copy(tempFile, reader) + if err != nil { + return nil, errors.Trace(err) + } + if _, err := tempFile.Seek(0, 0); err != nil { + return nil, errors.Trace(err) + } + return tempFile, nil +} + +func cleanTempFile(f *os.File) { + if f == nil { + return + } + + f.Close() + if err := os.Remove(f.Name()); err != nil { + logger.Warningf("cannot remove temp file %q: %v", f.Name(), err) + } +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/downloader/download_test.go juju-core-2.0~beta7/src/github.com/juju/juju/downloader/download_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/downloader/download_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/downloader/download_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,172 @@ +// Copyright 2012, 2013 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package downloader_test + +import ( + "io/ioutil" + "net/url" + "os" + "path/filepath" + "time" + + "github.com/juju/errors" + gitjujutesting "github.com/juju/testing" + jc "github.com/juju/testing/checkers" + "github.com/juju/utils" + gc "gopkg.in/check.v1" + + "github.com/juju/juju/downloader" + "github.com/juju/juju/testing" +) + +type DownloadSuite struct { + testing.BaseSuite + gitjujutesting.HTTPSuite +} + +func (s *DownloadSuite) SetUpSuite(c *gc.C) { + s.BaseSuite.SetUpSuite(c) + s.HTTPSuite.SetUpSuite(c) +} + +func (s *DownloadSuite) TearDownSuite(c *gc.C) { + s.HTTPSuite.TearDownSuite(c) + s.BaseSuite.TearDownSuite(c) +} + +func (s *DownloadSuite) SetUpTest(c *gc.C) { + s.BaseSuite.SetUpTest(c) + s.HTTPSuite.SetUpTest(c) +} + +func (s *DownloadSuite) TearDownTest(c *gc.C) { + s.HTTPSuite.TearDownTest(c) + s.BaseSuite.TearDownTest(c) +} + +var _ = gc.Suite(&DownloadSuite{}) + +func (s *DownloadSuite) URL(c *gc.C, path string) *url.URL { + urlStr := s.HTTPSuite.URL(path) + URL, err := url.Parse(urlStr) + c.Assert(err, jc.ErrorIsNil) + return URL +} + +func (s *DownloadSuite) testDownload(c *gc.C, hostnameVerification utils.SSLHostnameVerification) { + tmp := c.MkDir() + gitjujutesting.Server.Response(200, nil, []byte("archive")) + d := downloader.StartDownload( + downloader.Request{ + URL: s.URL(c, "/archive.tgz"), + TargetDir: tmp, + }, + downloader.NewHTTPBlobOpener(hostnameVerification), + ) + status := <-d.Done() + defer status.File.Close() + c.Assert(status.Err, gc.IsNil) + c.Assert(status.File, gc.NotNil) + + dir, _ := filepath.Split(status.File.Name()) + c.Assert(filepath.Clean(dir), gc.Equals, tmp) + assertFileContents(c, status.File, "archive") +} + +func (s *DownloadSuite) TestDownloadWithoutDisablingSSLHostnameVerification(c *gc.C) { + s.testDownload(c, utils.VerifySSLHostnames) +} + +func (s *DownloadSuite) TestDownloadWithDisablingSSLHostnameVerification(c *gc.C) { + s.testDownload(c, utils.NoVerifySSLHostnames) +} + +func (s *DownloadSuite) TestDownloadError(c *gc.C) { + gitjujutesting.Server.Response(404, nil, nil) + d := downloader.StartDownload( + downloader.Request{ + URL: s.URL(c, "/archive.tgz"), + TargetDir: c.MkDir(), + }, + downloader.NewHTTPBlobOpener(utils.VerifySSLHostnames), + ) + status := <-d.Done() + c.Assert(status.File, gc.IsNil) + c.Assert(status.Err, gc.ErrorMatches, `cannot download ".*": bad http response: 404 Not Found`) +} + +func (s *DownloadSuite) TestStop(c *gc.C) { + tmp := c.MkDir() + d := downloader.StartDownload( + downloader.Request{ + URL: s.URL(c, "/x.tgz"), + TargetDir: tmp, + }, + downloader.NewHTTPBlobOpener(utils.VerifySSLHostnames), + ) + d.Stop() + select { + case status := <-d.Done(): + c.Fatalf("received status %#v after stop", status) + case <-time.After(testing.ShortWait): + } + infos, err := ioutil.ReadDir(tmp) + c.Assert(err, jc.ErrorIsNil) + c.Assert(infos, gc.HasLen, 0) +} + +func (s *DownloadSuite) TestVerifyValid(c *gc.C) { + stub := &gitjujutesting.Stub{} + tmp := c.MkDir() + gitjujutesting.Server.Response(200, nil, []byte("archive")) + dl := downloader.StartDownload( + downloader.Request{ + URL: s.URL(c, "/archive.tgz"), + TargetDir: tmp, + Verify: func(f *os.File) error { + stub.AddCall("Verify", f) + return nil + }, + }, + downloader.NewHTTPBlobOpener(utils.VerifySSLHostnames), + ) + status := <-dl.Done() + c.Assert(status.Err, jc.ErrorIsNil) + + stub.CheckCallNames(c, "Verify") + stub.CheckCall(c, 0, "Verify", status.File) +} + +func (s *DownloadSuite) TestVerifyInvalid(c *gc.C) { + stub := &gitjujutesting.Stub{} + tmp := c.MkDir() + gitjujutesting.Server.Response(200, nil, []byte("archive")) + invalid := errors.NotValidf("oops") + dl := downloader.StartDownload( + downloader.Request{ + URL: s.URL(c, "/archive.tgz"), + TargetDir: tmp, + Verify: func(f *os.File) error { + stub.AddCall("Verify", f) + return invalid + }, + }, + downloader.NewHTTPBlobOpener(utils.VerifySSLHostnames), + ) + status := <-dl.Done() + + c.Check(errors.Cause(status.Err), gc.Equals, invalid) + stub.CheckCallNames(c, "Verify") + stub.CheckCall(c, 0, "Verify", status.File) +} + +func assertFileContents(c *gc.C, f *os.File, expect string) { + got, err := ioutil.ReadAll(f) + c.Assert(err, jc.ErrorIsNil) + if !c.Check(string(got), gc.Equals, expect) { + info, err := f.Stat() + c.Assert(err, jc.ErrorIsNil) + c.Logf("info %#v", info) + } +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/downloader/package_test.go juju-core-2.0~beta7/src/github.com/juju/juju/downloader/package_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/downloader/package_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/downloader/package_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,14 @@ +// Copyright 2016 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package downloader_test + +import ( + "testing" + + gc "gopkg.in/check.v1" +) + +func TestPackage(t *testing.T) { + gc.TestingT(t) +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/downloader/utils.go juju-core-2.0~beta7/src/github.com/juju/juju/downloader/utils.go --- juju-core-2.0~beta6/src/github.com/juju/juju/downloader/utils.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/downloader/utils.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,51 @@ +// Copyright 2016 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package downloader + +import ( + "io" + "net/http" + "net/url" + "os" + + "github.com/juju/errors" + "github.com/juju/utils" +) + +// NewHTTPBlobOpener returns a blob opener func suitable for use with +// Download. The opener func uses an HTTP client that enforces the +// provided SSL hostname verification policy. +func NewHTTPBlobOpener(hostnameVerification utils.SSLHostnameVerification) func(*url.URL) (io.ReadCloser, error) { + return func(url *url.URL) (io.ReadCloser, error) { + // TODO(rog) make the download operation interruptible. + client := utils.GetHTTPClient(hostnameVerification) + resp, err := client.Get(url.String()) + if err != nil { + return nil, err + } + if resp.StatusCode != http.StatusOK { + // resp.Body is always non-nil. (see https://golang.org/pkg/net/http/#Response) + resp.Body.Close() + return nil, errors.Errorf("bad http response: %v", resp.Status) + } + return resp.Body, nil + } +} + +// NewSha256Verifier returns a verifier suitable for Request. The +// verifier checks the SHA-256 checksum of the file to ensure that it +// matches the one returned by the provided func. +func NewSha256Verifier(expected string) func(*os.File) error { + return func(file *os.File) error { + actual, _, err := utils.ReadSHA256(file) + if err != nil { + return errors.Trace(err) + } + if actual != expected { + err := errors.Errorf("expected sha256 %q, got %q", expected, actual) + return errors.NewNotValid(err, "") + } + return nil + } +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/bootstrap/bootstrap.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/bootstrap/bootstrap.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/bootstrap/bootstrap.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/bootstrap/bootstrap.go 2016-05-17 20:01:14.000000000 +0000 @@ -72,9 +72,15 @@ Placement string // UploadTools reports whether we should upload the local tools and - // override the environment's specified agent-version. + // override the environment's specified agent-version. It is an error + // to specify UploadTools with a nil BuildToolsTarball. UploadTools bool + // BuildToolsTarball, if non-nil, is a function that may be used to + // build tools to upload. If this is nil, tools uploading will never + // take place. + BuildToolsTarball sync.BuildToolsTarballFunc + // MetadataDir is an optional path to a local directory containing // tools and/or image metadata. MetadataDir string @@ -155,7 +161,7 @@ logger.Debugf("network management by juju enabled: %v", !disableNetworkManagement) availableTools, err := findAvailableTools( environ, args.AgentVersion, bootstrapConstraints.Arch, - bootstrapSeries, args.UploadTools, + bootstrapSeries, args.UploadTools, args.BuildToolsTarball != nil, ) if errors.IsNotFound(err) { return errors.New(noToolsMessage) @@ -225,7 +231,7 @@ continue } ctx.Infof("Building tools to upload (%s)", selectedTools.Version) - builtTools, err := sync.BuildToolsTarball(&selectedTools.Version.Number, cfg.AgentStream()) + builtTools, err := args.BuildToolsTarball(&selectedTools.Version.Number, cfg.AgentStream()) if err != nil { return errors.Annotate(err, "cannot upload bootstrap tools") } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/bootstrap/bootstrap_test.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/bootstrap/bootstrap_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/bootstrap/bootstrap_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/bootstrap/bootstrap_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -33,6 +33,7 @@ "github.com/juju/juju/environs/simplestreams" sstesting "github.com/juju/juju/environs/simplestreams/testing" "github.com/juju/juju/environs/storage" + "github.com/juju/juju/environs/sync" envtesting "github.com/juju/juju/environs/testing" envtools "github.com/juju/juju/environs/tools" "github.com/juju/juju/juju" @@ -252,7 +253,11 @@ }) env := newEnviron("foo", useDefaultKeys, map[string]interface{}{ "agent-stream": "proposed"}) - err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) + err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), env, bootstrap.BootstrapParams{ + BuildToolsTarball: func(*version.Number, string) (*sync.BuiltTools, error) { + return &sync.BuiltTools{Dir: c.MkDir()}, nil + }, + }) // bootstrap.Bootstrap leaves it to the provider to // locate bootstrap tools. c.Assert(err, jc.ErrorIsNil) @@ -269,7 +274,11 @@ }) env := newEnviron("foo", useDefaultKeys, map[string]interface{}{ "development": true}) - err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) + err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), env, bootstrap.BootstrapParams{ + BuildToolsTarball: func(*version.Number, string) (*sync.BuiltTools, error) { + return &sync.BuiltTools{Dir: c.MkDir()}, nil + }, + }) // bootstrap.Bootstrap leaves it to the provider to // locate bootstrap tools. c.Assert(err, jc.ErrorIsNil) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/bootstrap/tools.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/bootstrap/tools.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/bootstrap/tools.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/bootstrap/tools.go 2016-05-17 20:01:14.000000000 +0000 @@ -67,9 +67,17 @@ // including tools that may be locally built and then // uploaded. Tools that need to be built will have an // empty URL. -func findAvailableTools(env environs.Environ, vers *version.Number, arch, series *string, upload bool) (coretools.List, error) { +func findAvailableTools( + env environs.Environ, + vers *version.Number, + arch, series *string, + upload, canBuild bool, +) (coretools.List, error) { if upload { // We're forcing an upload: ensure we can do so. + if !canBuild { + return nil, errors.New("cannot build tools to upload") + } if err := validateUploadAllowed(env, arch, series); err != nil { return nil, err } @@ -94,10 +102,10 @@ } preferredStream := envtools.PreferredStream(vers, env.Config().Development(), env.Config().AgentStream()) - if preferredStream == envtools.ReleasedStream || vers != nil { + if preferredStream == envtools.ReleasedStream || vers != nil || !canBuild { // We are not running a development build, or agent-version - // was specified; the only tools available are the ones we've - // just found. + // was specified, or we cannot build any tools; the only tools + // available are the ones we've just found. return toolsList, findToolsErr } // The tools located may not include the ones that the diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/bootstrap/tools_test.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/bootstrap/tools_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/bootstrap/tools_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/bootstrap/tools_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -162,7 +162,7 @@ return nil, errors.New("splat") }) env := newEnviron("foo", useDefaultKeys, nil) - _, err := bootstrap.FindAvailableTools(env, nil, nil, nil, false) + _, err := bootstrap.FindAvailableTools(env, nil, nil, nil, false, false) c.Assert(err, gc.ErrorMatches, "splat") } @@ -173,7 +173,7 @@ env := newEnviron("foo", useDefaultKeys, map[string]interface{}{ "agent-version": "1.17.1", }) - _, err := bootstrap.FindAvailableTools(env, nil, nil, nil, false) + _, err := bootstrap.FindAvailableTools(env, nil, nil, nil, false, false) c.Assert(err, jc.Satisfies, errors.IsNotFound) } @@ -185,7 +185,7 @@ return nil, errors.NotFoundf("tools") }) env := newEnviron("foo", useDefaultKeys, nil) - uploadedTools, err := bootstrap.FindAvailableTools(env, nil, nil, nil, true) + uploadedTools, err := bootstrap.FindAvailableTools(env, nil, nil, nil, true, true) c.Assert(err, jc.ErrorIsNil) c.Assert(uploadedTools, gc.Not(gc.HasLen), 0) c.Assert(findToolsCalled, gc.Equals, 0) @@ -207,7 +207,7 @@ return nil, errors.NotFoundf("tools") }) env := newEnviron("foo", useDefaultKeys, nil) - _, err := bootstrap.FindAvailableTools(env, nil, nil, nil, true) + _, err := bootstrap.FindAvailableTools(env, nil, nil, nil, true, true) c.Assert(err, gc.ErrorMatches, `model "foo" of type dummy does not support instances running on "i386"`) c.Assert(findToolsCalled, gc.Equals, 0) } @@ -237,7 +237,7 @@ }) env := newEnviron("foo", useDefaultKeys, nil) toolsVersion := version.MustParse("10.11.12") - result, err := bootstrap.FindAvailableTools(env, &toolsVersion, nil, nil, false) + result, err := bootstrap.FindAvailableTools(env, &toolsVersion, nil, nil, false, false) c.Assert(err, jc.ErrorIsNil) c.Assert(findToolsCalled, gc.Equals, 1) c.Assert(result, jc.DeepEquals, tools.List{ @@ -259,7 +259,7 @@ }) env := newEnviron("foo", useDefaultKeys, map[string]interface{}{ "agent-stream": "proposed"}) - availableTools, err := bootstrap.FindAvailableTools(env, nil, nil, nil, false) + availableTools, err := bootstrap.FindAvailableTools(env, nil, nil, nil, false, true) c.Assert(err, jc.ErrorIsNil) c.Assert(len(availableTools), jc.GreaterThan, 1) c.Assert(env.supportedArchitecturesCount, gc.Equals, 1) @@ -298,7 +298,7 @@ return allTools, nil }) env := newEnviron("foo", useDefaultKeys, nil) - availableTools, err := bootstrap.FindAvailableTools(env, nil, nil, nil, false) + availableTools, err := bootstrap.FindAvailableTools(env, nil, nil, nil, false, false) c.Assert(err, jc.ErrorIsNil) c.Assert(availableTools, gc.HasLen, len(allTools)) c.Assert(env.supportedArchitecturesCount, gc.Equals, 0) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/config/authkeys_test.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/config/authkeys_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/config/authkeys_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/config/authkeys_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -29,14 +29,16 @@ s.BaseSuite.SetUpTest(c) old := utils.Home() newhome := c.MkDir() - utils.SetHome(newhome) + err := utils.SetHome(newhome) + c.Assert(err, jc.ErrorIsNil) s.AddCleanup(func(*gc.C) { ssh.ClearClientKeys() - utils.SetHome(old) + err := utils.SetHome(old) + c.Assert(err, jc.ErrorIsNil) }) s.dotssh = filepath.Join(newhome, ".ssh") - err := os.Mkdir(s.dotssh, 0755) + err = os.Mkdir(s.dotssh, 0755) c.Assert(err, jc.ErrorIsNil) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/config/config.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/config/config.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/config/config.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/config/config.go 2016-05-17 20:01:14.000000000 +0000 @@ -8,7 +8,6 @@ "io/ioutil" "net/url" "os" - "os/exec" "path/filepath" "strings" "time" @@ -18,8 +17,8 @@ "github.com/juju/schema" "github.com/juju/utils" "github.com/juju/utils/proxy" + "github.com/juju/utils/series" "github.com/juju/version" - "gopkg.in/juju/charm.v6-unstable" "gopkg.in/juju/charmrepo.v2-unstable" "gopkg.in/juju/environschema.v1" "gopkg.in/macaroon-bakery.v1/bakery" @@ -29,7 +28,7 @@ "github.com/juju/juju/juju/osenv" ) -var logger = loggo.GetLogger("juju.environs.local/share") +var logger = loggo.GetLogger("juju.environs.config") const ( // FwInstance requests the use of an individual firewall per instance. @@ -65,10 +64,6 @@ // refresh addresses from the provider each time. DefaultBootstrapSSHAddressesDelay int = 10 - // fallbackLtsSeries is the latest LTS series we'll use, if we fail to - // obtain this information from the system. - fallbackLtsSeries string = "trusty" - // DefaultNumaControlPolicy should not be used by default. // Only use numactl if user specifically requests it DefaultNumaControlPolicy = false @@ -302,8 +297,6 @@ return method&HarvestUnknown != 0 } -var latestLtsSeries string - type HasDefaultSeries interface { DefaultSeries() (string, bool) } @@ -314,35 +307,7 @@ if series, ok := cfg.DefaultSeries(); ok { return series } - return LatestLtsSeries() -} - -func LatestLtsSeries() string { - if latestLtsSeries == "" { - series, err := distroLtsSeries() - if err != nil { - latestLtsSeries = fallbackLtsSeries - } else { - latestLtsSeries = series - } - } - return latestLtsSeries -} - -var distroLtsSeries = distroLtsSeriesFunc - -// distroLtsSeriesFunc returns the latest LTS series, if this information is -// available on this system. -func distroLtsSeriesFunc() (string, error) { - out, err := exec.Command("distro-info", "--lts").Output() - if err != nil { - return "", err - } - series := strings.TrimSpace(string(out)) - if !charm.IsValidSeries(series) { - return "", fmt.Errorf("not a valid LTS series: %q", series) - } - return series, nil + return series.LatestLts() } // Config holds an immutable environment configuration. diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/config/config_test.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/config/config_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/config/config_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/config/config_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -16,6 +16,7 @@ gitjujutesting "github.com/juju/testing" jc "github.com/juju/testing/checkers" "github.com/juju/utils/proxy" + "github.com/juju/utils/series" "github.com/juju/version" gc "gopkg.in/check.v1" "gopkg.in/juju/charmrepo.v2-unstable" @@ -62,7 +63,7 @@ "development": false, "state-port": 1234, "api-port": 4321, - "default-series": config.LatestLtsSeries(), + "default-series": series.LatestLts(), } type configTest struct { @@ -1273,7 +1274,7 @@ "bootstrap-timeout": 3600, "bootstrap-retry-delay": 30, "bootstrap-addresses-delay": 10, - "default-series": testing.FakeDefaultSeries, + "default-series": series.LatestLts(), "test-mode": false, } cfg, err := config.New(config.NoDefaults, attrs) @@ -1852,22 +1853,6 @@ return s } -func (s *ConfigSuite) TestLastestLtsSeriesFallback(c *gc.C) { - config.ResetCachedLtsSeries() - s.PatchValue(config.DistroLtsSeries, func() (string, error) { - return "", fmt.Errorf("error") - }) - c.Assert(config.LatestLtsSeries(), gc.Equals, "trusty") -} - -func (s *ConfigSuite) TestLastestLtsSeries(c *gc.C) { - config.ResetCachedLtsSeries() - s.PatchValue(config.DistroLtsSeries, func() (string, error) { - return "series", nil - }) - c.Assert(config.LatestLtsSeries(), gc.Equals, "series") -} - var caCert = ` -----BEGIN CERTIFICATE----- MIIBjDCCATigAwIBAgIBADALBgkqhkiG9w0BAQUwHjENMAsGA1UEChMEanVqdTEN diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/config/export_test.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/config/export_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/config/export_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/config/export_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,10 +4,5 @@ package config var ( - DistroLtsSeries = &distroLtsSeries - ConfigSchema = configSchema + ConfigSchema = configSchema ) - -func ResetCachedLtsSeries() { - latestLtsSeries = "" -} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/imagemetadata/urls_windows_test.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/imagemetadata/urls_windows_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/imagemetadata/urls_windows_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/imagemetadata/urls_windows_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -12,10 +12,10 @@ expectedErr error }{{ in: "C:/home/foo", - expected: "file://\\\\localhost\\C$/home/foo/images", + expected: "file://C:/home/foo/images", expectedErr: nil, }, { in: "C:/home/foo/images", - expected: "file://\\\\localhost\\C$/home/foo/images", + expected: "file://C:/home/foo/images", expectedErr: nil, }} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/instances/image.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/instances/image.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/instances/image.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/instances/image.go 2016-05-17 20:01:14.000000000 +0000 @@ -61,6 +61,7 @@ // which instances can be run. The InstanceConstraint is used to filter allInstanceTypes and then a suitable image // compatible with the matching instance types is returned. func FindInstanceSpec(possibleImages []Image, ic *InstanceConstraint, allInstanceTypes []InstanceType) (*InstanceSpec, error) { + logger.Debugf("instance constraints %+v", ic) if len(possibleImages) == 0 { return nil, fmt.Errorf("no %q images in %s with arches %s", ic.Series, ic.Region, ic.Arches) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/jujutest/livetests.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/jujutest/livetests.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/jujutest/livetests.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/jujutest/livetests.go 2016-05-17 20:01:14.000000000 +0000 @@ -5,6 +5,7 @@ import ( "fmt" + "path/filepath" "time" "github.com/juju/errors" @@ -105,7 +106,8 @@ t.CleanupSuite.SetUpTest(c) t.PatchValue(&jujuversion.Current, coretesting.FakeVersionNumber) storageDir := c.MkDir() - t.DefaultBaseURL = "file://" + storageDir + "/tools" + baseUrlPath := filepath.Join(storageDir, "tools") + t.DefaultBaseURL = utils.MakeFileURL(baseUrlPath) t.ToolsFixture.SetUpTest(c) stor, err := filestorage.NewFileStorageWriter(storageDir) c.Assert(err, jc.ErrorIsNil) @@ -163,7 +165,7 @@ // we could connect to (actual live tests, rather than local-only) cons := constraints.MustParse("mem=2G") if t.CanOpenState { - _, err := sync.Upload(t.toolsStorage, "released", nil, coretesting.FakeDefaultSeries) + _, err := sync.Upload(t.toolsStorage, "released", nil, series.LatestLts()) c.Assert(err, jc.ErrorIsNil) } err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), t.Env, bootstrap.BootstrapParams{ @@ -478,7 +480,7 @@ expectedVersion := version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), - Series: config.LatestLtsSeries(), + Series: series.LatestLts(), } mtools0 := waitAgentTools(c, mw0, expectedVersion) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/jujutest/tests.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/jujutest/tests.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/jujutest/tests.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/jujutest/tests.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,7 +4,10 @@ package jujutest import ( + "path/filepath" + jc "github.com/juju/testing/checkers" + "github.com/juju/utils" gc "gopkg.in/check.v1" "github.com/juju/juju/cloud" @@ -73,7 +76,8 @@ func (t *Tests) SetUpTest(c *gc.C) { storageDir := c.MkDir() - t.DefaultBaseURL = "file://" + storageDir + "/tools" + baseUrlPath := filepath.Join(storageDir, "tools") + t.DefaultBaseURL = utils.MakeFileURL(baseUrlPath) t.ToolsFixture.SetUpTest(c) stor, err := filestorage.NewFileStorageWriter(storageDir) c.Assert(err, jc.ErrorIsNil) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/manual/provisioner_test.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/manual/provisioner_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/manual/provisioner_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/manual/provisioner_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -8,6 +8,7 @@ "os" jc "github.com/juju/testing/checkers" + "github.com/juju/utils/series" "github.com/juju/utils/shell" "github.com/juju/version" gc "gopkg.in/check.v1" @@ -22,7 +23,6 @@ envtools "github.com/juju/juju/environs/tools" "github.com/juju/juju/instance" "github.com/juju/juju/juju/testing" - coretesting "github.com/juju/juju/testing" ) type provisionerSuite struct { @@ -44,7 +44,7 @@ } func (s *provisionerSuite) TestProvisionMachine(c *gc.C) { - const series = coretesting.FakeDefaultSeries + var series = series.LatestLts() const arch = "amd64" args := s.getArgs(c) @@ -124,7 +124,7 @@ } func (s *provisionerSuite) TestFinishInstancConfig(c *gc.C) { - const series = coretesting.FakeDefaultSeries + var series = series.LatestLts() const arch = "amd64" defer fakeSSH{ Series: series, @@ -148,7 +148,7 @@ } func (s *provisionerSuite) TestProvisioningScript(c *gc.C) { - const series = coretesting.FakeDefaultSeries + var series = series.LatestLts() const arch = "amd64" defer fakeSSH{ Series: series, diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/simplestreams/simplestreams.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/simplestreams/simplestreams.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/simplestreams/simplestreams.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/simplestreams/simplestreams.go 2016-05-17 20:01:14.000000000 +0000 @@ -123,6 +123,8 @@ ContentId string `json:"content_id"` RegionName string `json:"region,omitempty"` Endpoint string `json:"endpoint,omitempty"` + Storage string `json:"root_store,omitempty"` + VirtType string `json:"virt,omitempty"` } type MetadataCatalog struct { @@ -131,6 +133,8 @@ Arch string `json:"arch,omitempty"` RegionName string `json:"region,omitempty"` Endpoint string `json:"endpoint,omitempty"` + Storage string `json:"root_store,omitempty"` + VirtType string `json:"virt,omitempty"` // Items is a mapping from version to an ItemCollection, // where the version is the date the items were produced, @@ -146,6 +150,8 @@ Version string `json:"version,omitempty"` RegionName string `json:"region,omitempty"` Endpoint string `json:"endpoint,omitempty"` + Storage string `json:"root_store,omitempty"` + VirtType string `json:"virt,omitempty"` } // These structs define the model used for metadata indices. @@ -1051,6 +1057,10 @@ signingKeyFile := filepath.Join(agent.DefaultPaths.ConfDir, SimplestreamsPublicKeyFile) b, err := ioutil.ReadFile(signingKeyFile) if os.IsNotExist(err) { + // TODO (anastasiamac 2016-05-07) + // We should not swallow this error + // but propagate it up to the caller. + // Bug #1579279 return "", nil } if err != nil { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/simplestreams/simplestreams_test.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/simplestreams/simplestreams_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/simplestreams/simplestreams_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/simplestreams/simplestreams_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -367,7 +367,7 @@ func (s *simplestreamsSuite) TestMetadataCatalog(c *gc.C) { metadata := s.AssertGetMetadata(c) - c.Check(len(metadata.Products), gc.Equals, 3) + c.Check(len(metadata.Products), gc.Equals, 6) c.Check(len(metadata.Aliases), gc.Equals, 1) metadataCatalog := metadata.Products["com.ubuntu.cloud:server:12.04:amd64"] c.Check(len(metadataCatalog.Items), gc.Equals, 2) @@ -425,6 +425,37 @@ c.Check(ti.Endpoint, gc.Equals, "https://ec2.us-west-3.amazonaws.com") } +type storageVirtTest struct { + product, coll, item, storage, virt string +} + +func (s *simplestreamsSuite) TestStorageVirtFromTopLevel(c *gc.C) { + s.assertImageMetadata(c, + storageVirtTest{"com.ubuntu.cloud:server:13.04:amd64", "20160318", "nzww1pe", "ebs", "pv"}, + ) +} + +func (s *simplestreamsSuite) TestStorageVirtFromCatalog(c *gc.C) { + s.assertImageMetadata(c, + storageVirtTest{"com.ubuntu.cloud:server:14.10:amd64", "20160218", "nzww1pe", "ebs", "pv"}, + ) +} + +func (s *simplestreamsSuite) TestStorageVirtFromCollection(c *gc.C) { + s.assertImageMetadata(c, + storageVirtTest{"com.ubuntu.cloud:server:12.10:amd64", "20160118", "nzww1pe", "ebs", "pv"}, + ) +} + +func (s *simplestreamsSuite) assertImageMetadata(c *gc.C, one storageVirtTest) { + metadata := s.AssertGetMetadata(c) + metadataCatalog := metadata.Products[one.product] + ic := metadataCatalog.Items[one.coll] + ti := ic.Items[one.item].(*sstesting.TestItem) + c.Check(ti.Storage, gc.Equals, one.storage) + c.Check(ti.VirtType, gc.Equals, one.virt) +} + var getMirrorTests = []struct { region string endpoint string diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/simplestreams/testing/testing.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/simplestreams/testing/testing.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/simplestreams/testing/testing.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/simplestreams/testing/testing.go 2016-05-17 20:01:14.000000000 +0000 @@ -101,7 +101,11 @@ "format": "products:1.0", "products": [ "com.ubuntu.cloud:server:12.04:amd64", - "com.ubuntu.cloud:server:12.04:arm" + "com.ubuntu.cloud:server:12.10:amd64", + "com.ubuntu.cloud:server:13.04:amd64", + "com.ubuntu.cloud:server:14.04:amd64", + "com.ubuntu.cloud:server:14.10:amd64", + "com.ubuntu.cloud:server:12.04:arm" ], "path": "streams/v1/image_metadata.json" }, @@ -429,6 +433,8 @@ "content_id": "com.ubuntu.cloud:released:aws", "region": "nz-east-1", "endpoint": "https://anywhere", + "root_store": "ebs", + "virt": "pv", "products": { "com.ubuntu.cloud:server:14.04:amd64": { "release": "trusty", @@ -447,6 +453,58 @@ "label": "release" } } + }, + "com.ubuntu.cloud:server:13.04:amd64": { + "release": "raring", + "version": "13.04", + "arch": "amd64", + "versions": { + "20160318": { + "items": { + "nzww1pe": { + "id": "ami-36745463" + } + }, + "pubname": "ubuntu-utopic-13.04-amd64-server-20160318", + "label": "release" + } + } + }, + "com.ubuntu.cloud:server:14.10:amd64": { + "release": "utopic", + "version": "14.10", + "arch": "amd64", + "root_store": "ebs", + "virt": "pv", + "versions": { + "20160218": { + "items": { + "nzww1pe": { + "id": "ami-36745463" + } + }, + "pubname": "ubuntu-utopic-14.10-amd64-server-20160218", + "label": "release" + } + } + }, + "com.ubuntu.cloud:server:12.10:amd64": { + "release": "quantal", + "version": "12.10", + "arch": "amd64", + "versions": { + "20160118": { + "items": { + "nzww1pe": { + "id": "ami-36745463" + } + }, + "root_store": "ebs", + "virt": "pv", + "pubname": "ubuntu-quantal-12.10-amd64-server-20160118", + "label": "release" + } + } }, "com.ubuntu.cloud:server:12.04:amd64": { "release": "precise", diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/testing/tools.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/testing/tools.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/testing/tools.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/testing/tools.go 2016-05-17 20:01:14.000000000 +0000 @@ -32,8 +32,8 @@ "github.com/juju/juju/worker/upgrader" ) -// toolsLtsSeries records the known Ubuntu LTS series. -var toolsLtsSeries = []string{"precise", "trusty"} +// toolsltsseries records the known ubuntu lts series. +var toolsLtsSeries = series.SupportedLts() // ToolsFixture is used as a fixture to stub out the default tools URL so we // don't hit the real internet during tests. @@ -287,7 +287,7 @@ // UploadFakeTools puts fake tools into the supplied storage with a binary // version matching jujuversion.Current; if jujuversion.Current's series is different -// to coretesting.FakeDefaultSeries, matching fake tools will be uploaded for that +// to series.LatestLts(), matching fake tools will be uploaded for that // series. This is useful for tests that are kinda casual about specifying // their environment. func UploadFakeTools(c *gc.C, stor storage.Storage, toolsDir, stream string) { @@ -312,7 +312,7 @@ name := envtools.StorageName(toolsVersion, toolsDir) err := stor.Remove(name) c.Check(err, jc.ErrorIsNil) - defaultSeries := coretesting.FakeDefaultSeries + defaultSeries := series.LatestLts() if series.HostSeries() != defaultSeries { toolsVersion.Series = defaultSeries name := envtools.StorageName(toolsVersion, toolsDir) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/tools/build.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/tools/build.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/tools/build.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/tools/build.go 2016-05-17 20:01:14.000000000 +0000 @@ -5,6 +5,7 @@ import ( "archive/tar" + "bytes" "compress/gzip" "crypto/sha256" "fmt" @@ -15,6 +16,7 @@ "path/filepath" "strings" + "github.com/juju/errors" "github.com/juju/version" "github.com/juju/juju/juju/names" @@ -211,7 +213,7 @@ // Override for testing. var BundleTools BundleToolsFunc = bundleTools -// BundleTools bundles all the current juju tools in gzipped tar +// bundleTools bundles all the current juju tools in gzipped tar // format to the given writer. // If forceVersion is not nil, a FORCE-VERSION file is included in // the tools bundle so it will lie about its current version number. @@ -235,15 +237,10 @@ return version.Binary{}, "", err } } - cmd := exec.Command(filepath.Join(dir, names.Jujud), "version") - out, err := cmd.CombinedOutput() - if err != nil { - return version.Binary{}, "", fmt.Errorf("cannot get version from %q: %v; %s", cmd.Args[0], err, out) - } - tvs := strings.TrimSpace(string(out)) - tvers, err = version.ParseBinary(tvs) + + tvers, err = getVersionFromJujud(dir) if err != nil { - return version.Binary{}, "", fmt.Errorf("invalid version %q printed by jujud", tvs) + return version.Binary{}, "", errors.Trace(err) } sha256hash, err := archiveAndSHA256(w, dir) @@ -252,3 +249,23 @@ } return tvers, sha256hash, err } + +var execCommand = exec.Command + +func getVersionFromJujud(dir string) (version.Binary, error) { + path := filepath.Join(dir, names.Jujud) + cmd := execCommand(path, "version") + var stdout, stderr bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + if err := cmd.Run(); err != nil { + return version.Binary{}, errors.Errorf("cannot get version from %q: %v; %s", path, err, stderr.String()+stdout.String()) + } + tvs := strings.TrimSpace(stdout.String()) + tvers, err := version.ParseBinary(tvs) + if err != nil { + return version.Binary{}, errors.Errorf("invalid version %q printed by jujud", tvs) + } + return tvers, nil +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/tools/build_test.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/tools/build_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/tools/build_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/tools/build_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -13,10 +13,13 @@ "runtime" "strings" + exttest "github.com/juju/testing" jc "github.com/juju/testing/checkers" + "github.com/juju/version" gc "gopkg.in/check.v1" "github.com/juju/juju/environs/tools" + "github.com/juju/juju/juju/names" "github.com/juju/juju/testing" ) @@ -25,6 +28,7 @@ restore func() cwd string filePath string + exttest.PatchExecHelper } var _ = gc.Suite(&buildSuite{}) @@ -73,14 +77,17 @@ } func (b *buildSuite) TestFindExecutable(c *gc.C) { - + root := "/" + if runtime.GOOS == "windows" { + root = `C:\` + } for _, test := range []struct { execFile string expected string errorMatch string }{{ - execFile: filepath.Join("/", "some", "absolute", "path"), - expected: filepath.Join("/", "some", "absolute", "path"), + execFile: filepath.Join(root, "some", "absolute", "path"), + expected: filepath.Join(root, "some", "absolute", "path"), }, { execFile: "./foo", expected: filepath.Join(b.cwd, "foo"), @@ -123,3 +130,85 @@ h.Write([]byte(emptyArchive)) c.Assert(sha256hash, gc.Equals, fmt.Sprintf("%x", h.Sum(nil))) } + +func (b *buildSuite) TestGetVersionFromJujud(c *gc.C) { + ver := version.Binary{ + Number: version.Number{ + Major: 1, + Minor: 2, + Tag: "beta", + Patch: 1, + }, + Series: "trusty", + Arch: "amd64", + } + + argsCh := make(chan []string, 1) + execCommand := b.GetExecCommand(exttest.PatchExecConfig{ + Stderr: "hey, here's some logging you should ignore", + Stdout: ver.String(), + Args: argsCh, + }) + + b.PatchValue(tools.ExecCommand, execCommand) + + v, err := tools.GetVersionFromJujud("foo") + c.Assert(err, jc.ErrorIsNil) + c.Assert(v, gc.Equals, ver) + + select { + case args := <-argsCh: + cmd := filepath.Join("foo", names.Jujud) + c.Assert(args, gc.DeepEquals, []string{cmd, "version"}) + default: + c.Fatalf("Failed to get args sent to executable.") + } +} + +func (b *buildSuite) TestGetVersionFromJujudWithParseError(c *gc.C) { + argsCh := make(chan []string, 1) + execCommand := b.GetExecCommand(exttest.PatchExecConfig{ + Stderr: "hey, here's some logging", + Stdout: "oops, not a valid version", + Args: argsCh, + }) + + b.PatchValue(tools.ExecCommand, execCommand) + + _, err := tools.GetVersionFromJujud("foo") + c.Assert(err, gc.ErrorMatches, `invalid version "oops, not a valid version" printed by jujud`) + + select { + case args := <-argsCh: + cmd := filepath.Join("foo", names.Jujud) + c.Assert(args, gc.DeepEquals, []string{cmd, "version"}) + default: + c.Fatalf("Failed to get args sent to executable.") + } +} + +func (b *buildSuite) TestGetVersionFromJujudWithRunError(c *gc.C) { + argsCh := make(chan []string, 1) + execCommand := b.GetExecCommand(exttest.PatchExecConfig{ + Stderr: "the stderr", + Stdout: "the stdout", + ExitCode: 1, + Args: argsCh, + }) + + b.PatchValue(tools.ExecCommand, execCommand) + + _, err := tools.GetVersionFromJujud("foo") + + cmd := filepath.Join("foo", names.Jujud) + msg := fmt.Sprintf("cannot get version from %q: exit status 1; the stderr\nthe stdout\n", cmd) + + c.Assert(err.Error(), gc.Equals, msg) + + select { + case args := <-argsCh: + c.Assert(args, gc.DeepEquals, []string{cmd, "version"}) + default: + c.Fatalf("Failed to get args sent to executable.") + } +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/tools/export_test.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/tools/export_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/tools/export_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/tools/export_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -11,4 +11,6 @@ WriteMetadataFiles = &writeMetadataFiles CurrentStreamsVersion = currentStreamsVersion MarshalToolsMetadataIndexJSON = marshalToolsMetadataIndexJSON + GetVersionFromJujud = getVersionFromJujud + ExecCommand = &execCommand ) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/environs/tools/urls_windows_test.go juju-core-2.0~beta7/src/github.com/juju/juju/environs/tools/urls_windows_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/environs/tools/urls_windows_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/environs/tools/urls_windows_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -12,10 +12,10 @@ expectedErr error }{{ in: "C:/home/foo", - expected: "file://\\\\localhost\\C$/home/foo/tools", + expected: "file://C:/home/foo/tools", expectedErr: nil, }, { in: "C:/home/foo/tools", - expected: "file://\\\\localhost\\C$/home/foo/tools", + expected: "file://C:/home/foo/tools", expectedErr: nil, }} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/feature/flags.go juju-core-2.0~beta7/src/github.com/juju/juju/feature/flags.go --- juju-core-2.0~beta6/src/github.com/juju/juju/feature/flags.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/feature/flags.go 2016-05-17 20:01:14.000000000 +0000 @@ -41,6 +41,3 @@ // Migration enables the 'juju migrate' command. const Migration = "migration" - -// maas2 enables experimental support for MAAS 2.0. -const MAAS2 = "maas2" diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/featuretests/cmd_juju_controller_test.go juju-core-2.0~beta7/src/github.com/juju/juju/featuretests/cmd_juju_controller_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/featuretests/cmd_juju_controller_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/featuretests/cmd_juju_controller_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -85,7 +85,7 @@ "\n") } -func (s *cmdControllerSuite) TestCreateModelNormalUser(c *gc.C) { +func (s *cmdControllerSuite) TestAddModelNormalUser(c *gc.C) { s.createModelNormalUser(c, "new-model", false) context := s.run(c, "list-models", "--all") c.Assert(testing.Stdout(context), gc.Equals, ""+ @@ -139,13 +139,13 @@ "\n") } -func (s *cmdControllerSuite) TestCreateModel(c *gc.C) { +func (s *cmdControllerSuite) TestAddModel(c *gc.C) { // The JujuConnSuite doesn't set up an ssh key in the fake home dir, // so fake one on the command line. The dummy provider also expects // a config value for 'controller'. - context := s.run(c, "create-model", "new-model", "authorized-keys=fake-key", "controller=false") + context := s.run(c, "add-model", "new-model", "authorized-keys=fake-key", "controller=false") c.Check(testing.Stdout(context), gc.Equals, "") - c.Check(testing.Stderr(context), gc.Equals, "created model \"new-model\"\n") + c.Check(testing.Stderr(context), gc.Equals, "added model \"new-model\"\n") // Make sure that the saved server details are sufficient to connect // to the api server. diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/featuretests/cmd_juju_register_test.go juju-core-2.0~beta7/src/github.com/juju/juju/featuretests/cmd_juju_register_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/featuretests/cmd_juju_register_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/featuretests/cmd_juju_register_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -66,8 +66,8 @@ Welcome, bob. You are now logged into "bob-controller". -There are no models available. You can create models with -"juju create-model", or you can ask an administrator or owner +There are no models available. You can add models with +"juju add-model", or you can ask an administrator or owner of a model to grant access to that model with "juju grant". `[1:]) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/juju/api.go juju-core-2.0~beta7/src/github.com/juju/juju/juju/api.go --- juju-core-2.0~beta6/src/github.com/juju/juju/juju/api.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/juju/api.go 2016-05-17 20:01:14.000000000 +0000 @@ -141,7 +141,7 @@ args.ModelUUID, apiOpen, stop, delay, args.DialOpts, ) - if err != nil { + if err != nil && errors.Cause(err) != errAborted { // Errors are swallowed by parallel.Try, so we // log the failure here to aid in debugging. logger.Debugf("failed to connect via bootstrap config: %v", err) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/juju/sockets/sockets_nix.go juju-core-2.0~beta7/src/github.com/juju/juju/juju/sockets/sockets_nix.go --- juju-core-2.0~beta6/src/github.com/juju/juju/juju/sockets/sockets_nix.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/juju/sockets/sockets_nix.go 2016-05-17 20:01:14.000000000 +0000 @@ -6,6 +6,8 @@ "net" "net/rpc" "os" + + "github.com/juju/errors" ) func Dial(socketPath string) (*rpc.Client, error) { @@ -18,9 +20,5 @@ logger.Tracef("ignoring error on removing %q: %v", socketPath, err) } listener, err := net.Listen("unix", socketPath) - if err != nil { - logger.Errorf("failed to listen on unix:%s: %v", socketPath, err) - return nil, err - } - return listener, err + return listener, errors.Trace(err) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/juju/sockets/sockets_windows.go juju-core-2.0~beta7/src/github.com/juju/juju/juju/sockets/sockets_windows.go --- juju-core-2.0~beta6/src/github.com/juju/juju/juju/sockets/sockets_windows.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/juju/sockets/sockets_windows.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,22 +4,17 @@ "net" "net/rpc" + "github.com/juju/errors" + "gopkg.in/natefinch/npipe.v2" ) func Dial(socketPath string) (*rpc.Client, error) { conn, err := npipe.Dial(socketPath) - if err != nil { - return nil, err - } - return rpc.NewClient(conn), nil + return rpc.NewClient(conn), errors.Trace(err) } func Listen(socketPath string) (net.Listener, error) { listener, err := npipe.Listen(socketPath) - if err != nil { - logger.Errorf("failed to listen on:%s: %v", socketPath, err) - return nil, err - } - return listener, err + return listener, errors.Trace(err) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/juju/testing/conn.go juju-core-2.0~beta7/src/github.com/juju/juju/juju/testing/conn.go --- juju-core-2.0~beta6/src/github.com/juju/juju/juju/testing/conn.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/juju/testing/conn.go 2016-05-17 20:01:14.000000000 +0000 @@ -18,6 +18,7 @@ "github.com/juju/utils" "github.com/juju/utils/arch" "github.com/juju/utils/series" + "github.com/juju/utils/set" "github.com/juju/version" gc "gopkg.in/check.v1" "gopkg.in/juju/charm.v6-unstable" @@ -40,6 +41,7 @@ "github.com/juju/juju/juju/osenv" "github.com/juju/juju/jujuclient" "github.com/juju/juju/mongo" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/provider/dummy" "github.com/juju/juju/state" "github.com/juju/juju/state/binarystorage" @@ -198,14 +200,32 @@ return s.openAPIAs(c, machine.Tag(), password, "fake_nonce"), machine } -func PreferredDefaultVersions(conf *config.Config, template version.Binary) []version.Binary { - prefVersion := template - prefVersion.Series = config.PreferredSeries(conf) - defaultVersion := template - if prefVersion.Series != testing.FakeDefaultSeries { - defaultVersion.Series = testing.FakeDefaultSeries +// DefaultVersions returns a slice of unique 'versions' for the current +// environment's preferred series and host architecture, as well supported LTS +// series for the host architecture. Additionally, it ensures that 'versions' +// for amd64 are returned if that is not the current host's architecture. +func DefaultVersions(conf *config.Config) []version.Binary { + var versions []version.Binary + supported := series.SupportedLts() + defaultSeries := set.NewStrings(supported...) + defaultSeries.Add(config.PreferredSeries(conf)) + defaultSeries.Add(series.HostSeries()) + for _, s := range defaultSeries.Values() { + versions = append(versions, version.Binary{ + Number: jujuversion.Current, + Arch: arch.HostArch(), + Series: s, + }) + if arch.HostArch() != "amd64" { + versions = append(versions, version.Binary{ + Number: jujuversion.Current, + Arch: "amd64", + Series: s, + }) + + } } - return []version.Binary{prefVersion, defaultVersion} + return versions } func (s *JujuConnSuite) setUpConn(c *gc.C) { @@ -217,7 +237,8 @@ home := filepath.Join(s.RootDir, "/home/ubuntu") err := os.MkdirAll(home, 0777) c.Assert(err, jc.ErrorIsNil) - utils.SetHome(home) + err = utils.SetHome(home) + c.Assert(err, jc.ErrorIsNil) err = os.MkdirAll(filepath.Join(home, ".local", "share"), 0777) c.Assert(err, jc.ErrorIsNil) @@ -253,17 +274,7 @@ s.LogDir = c.MkDir() s.PatchValue(&dummy.LogDir, s.LogDir) - versions := PreferredDefaultVersions(environ.Config(), version.Binary{ - Number: jujuversion.Current, - Arch: "amd64", - Series: "precise", - }) - current := version.Binary{ - Number: jujuversion.Current, - Arch: arch.HostArch(), - Series: series.HostSeries(), - } - versions = append(versions, current) + versions := DefaultVersions(environ.Config()) // Upload tools for both preferred and fake default series s.DefaultToolsStorageDir = c.MkDir() @@ -337,24 +348,10 @@ } } -// AddDefaultToolsToState adds tools to tools storage for -// {Number: jujuversion.Current.Number, Arch: amd64}, for the -// "precise" series and the environment's preferred series. -// The preferred series is default-series if specified, -// otherwise the latest LTS. +// AddDefaultTools adds tools to tools storage for default juju +// series and architectures. func (s *JujuConnSuite) AddDefaultToolsToState(c *gc.C) { - preferredVersion := version.Binary{ - Number: jujuversion.Current, - Arch: "amd64", - Series: series.HostSeries(), - } - current := version.Binary{ - Number: jujuversion.Current, - Arch: arch.HostArch(), - Series: series.HostSeries(), - } - versions := PreferredDefaultVersions(s.Environ.Config(), preferredVersion) - versions = append(versions, current) + versions := DefaultVersions(s.Environ.Config()) s.AddToolsToState(c, versions...) } @@ -374,7 +371,7 @@ modelTag := names.NewModelTag(config.UUID()) mongoInfo.Password = password - opts := mongo.DefaultDialOpts() + opts := mongotest.DialOpts() st, err := state.Open(modelTag, mongoInfo, opts, environs.NewStatePolicy()) if errors.IsUnauthorized(errors.Cause(err)) { // We try for a while because we might succeed in @@ -451,10 +448,11 @@ if sch, err := st.Charm(curl); err == nil { return sch, nil } - return addCharm(st, curl, ch) + return AddCharm(st, curl, ch) } -func addCharm(st *state.State, curl *charm.URL, ch charm.Charm) (*state.Charm, error) { +// AddCharm adds the charm to state and storage. +func AddCharm(st *state.State, curl *charm.URL, ch charm.Charm) (*state.Charm, error) { var f *os.File name := charm.Quote(curl.String()) switch ch := ch.(type) { @@ -565,7 +563,8 @@ } dummy.Reset(c) - utils.SetHome(s.oldHome) + err := utils.SetHome(s.oldHome) + c.Assert(err, jc.ErrorIsNil) osenv.SetJujuXDGDataHome(s.oldJujuXDGDataHome) s.oldHome = "" s.RootDir = "" diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/juju/testing/instance.go juju-core-2.0~beta7/src/github.com/juju/juju/juju/testing/instance.go --- juju-core-2.0~beta6/src/github.com/juju/juju/juju/testing/instance.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/juju/testing/instance.go 2016-05-17 20:01:14.000000000 +0000 @@ -16,7 +16,6 @@ "github.com/juju/juju/environs/config" "github.com/juju/juju/environs/imagemetadata" "github.com/juju/juju/environs/simplestreams" - "github.com/juju/juju/environs/tags" "github.com/juju/juju/environs/tools" "github.com/juju/juju/instance" "github.com/juju/juju/mongo" @@ -176,7 +175,7 @@ if err != nil { return nil, errors.Trace(err) } - instanceConfig.Tags[tags.JujuModel] = env.Config().UUID() + instanceConfig.Tags = instancecfg.InstanceTags(env.Config(), nil) params.Tools = possibleTools params.InstanceConfig = instanceConfig return env.StartInstance(params) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/juju/testing/repo.go juju-core-2.0~beta7/src/github.com/juju/juju/juju/testing/repo.go --- juju-core-2.0~beta6/src/github.com/juju/juju/juju/testing/repo.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/juju/testing/repo.go 2016-05-17 20:01:14.000000000 +0000 @@ -6,10 +6,10 @@ "github.com/juju/names" jc "github.com/juju/testing/checkers" "github.com/juju/utils" + "github.com/juju/utils/series" gc "gopkg.in/check.v1" "gopkg.in/juju/charm.v6-unstable" - "github.com/juju/juju/environs/config" "github.com/juju/juju/state" "github.com/juju/juju/state/storage" ) @@ -23,7 +23,7 @@ s.JujuConnSuite.SetUpTest(c) s.CharmsPath = c.MkDir() // Change the environ's config to ensure we're using the one in state. - updateAttrs := map[string]interface{}{"default-series": config.LatestLtsSeries()} + updateAttrs := map[string]interface{}{"default-series": series.LatestLts()} err := s.State.UpdateModelConfig(updateAttrs, nil, nil) c.Assert(err, jc.ErrorIsNil) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/Makefile juju-core-2.0~beta7/src/github.com/juju/juju/Makefile --- juju-core-2.0~beta6/src/github.com/juju/juju/Makefile 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/Makefile 2016-05-17 20:01:14.000000000 +0000 @@ -9,8 +9,8 @@ PROJECT := github.com/juju/juju PROJECT_DIR := $(shell go list -e -f '{{.Dir}}' $(PROJECT)) -ifeq ($(shell uname -p | sed -r 's/.*(86|armel|armhf).*/golang/'), golang) - GO_C := golang +ifeq ($(shell uname -p | sed -r 's/.*(86|armel|armhf|aarch64|ppc64le|s390x).*/golang/'), golang) + GO_C := golang-1.[6-9] INSTALL_FLAGS := else GO_C := gccgo-4.9 gccgo-go @@ -24,7 +24,6 @@ distro-info-data git-core mercurial - juju-local zip $(GO_C) endef @@ -86,7 +85,7 @@ # Install packages required to develop Juju and run tests. The stable # PPA includes the required mongodb-server binaries. install-dependencies: -ifeq ($(shell lsb_release -cs|sed -r 's/precise/old/'),old) +ifeq ($(shell lsb_release -cs|sed -r 's/precise|wily/old/'),old) @echo Adding juju PPAs for golang and mongodb-server @sudo apt-add-repository --yes ppa:juju/golang @sudo apt-add-repository --yes ppa:juju/stable @@ -100,7 +99,17 @@ # Install bash_completion install-etc: @echo Installing bash completion - @sudo install -o root -g root -m 644 etc/bash_completion.d/juju-core /etc/bash_completion.d + @sudo install -o root -g root -m 644 etc/bash_completion.d/juju2 /etc/bash_completion.d + +setup-lxd: +ifeq ($(shell ifconfig lxdbr0 | grep -q "inet addr" && echo true),true) + @echo IPv4 networking is already setup for LXD. + @echo run "sudo scripts/setup-lxd.sh" to reconfigure IPv4 networking +else + @echo Setting up IPv4 networking for LXD + @sudo scripts/setup-lxd.sh || true +endif + GOCHECK_COUNT="$(shell go list -f '{{join .Deps "\n"}}' github.com/juju/juju/... | grep -c "gopkg.in/check.v*")" check-deps: diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/mongo/admin_test.go juju-core-2.0~beta7/src/github.com/juju/juju/mongo/admin_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/mongo/admin_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/mongo/admin_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -78,7 +78,7 @@ err = mongo.SetAdminMongoPassword(session, "auser", "foo") c.Assert(err, jc.ErrorIsNil) err = admin.Login("auser", "") - c.Assert(err, gc.ErrorMatches, "auth fail(s|ed)") + c.Assert(err, gc.ErrorMatches, "(auth|(.*Authentication)) fail(s|ed)\\.?") err = admin.Login("auser", "foo") c.Assert(err, jc.ErrorIsNil) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/mongo/mongo.go juju-core-2.0~beta7/src/github.com/juju/juju/mongo/mongo.go --- juju-core-2.0~beta6/src/github.com/juju/juju/mongo/mongo.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/mongo/mongo.go 2016-05-17 20:01:14.000000000 +0000 @@ -49,6 +49,10 @@ // installing mongo. JujuMongoPackage = "juju-mongodb3.2" + // JujuMongoTooldPackage is the mongo package Juju uses when + // installing mongo tools to get mongodump etc. + JujuMongoToolsPackage = "juju-mongo-tools3.2" + // MMAPV1 is the default storage engine in mongo db up to 3.x MMAPV1 StorageEngine = "mmapv1" @@ -610,10 +614,10 @@ case "precise", "quantal", "raring", "saucy", "centos7": return []string{"mongodb-server"}, []string{} case "trusty", "wily", "xenial": - return []string{JujuMongoPackage}, []string{"juju-mongodb"} + return []string{JujuMongoPackage, JujuMongoToolsPackage}, []string{"juju-mongodb"} default: // y and onwards - return []string{JujuMongoPackage}, []string{} + return []string{JujuMongoPackage, JujuMongoToolsPackage}, []string{} } } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/mongo/mongotest/opts.go juju-core-2.0~beta7/src/github.com/juju/juju/mongo/mongotest/opts.go --- juju-core-2.0~beta6/src/github.com/juju/juju/mongo/mongotest/opts.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/mongo/mongotest/opts.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,23 @@ +package mongotest + +import ( + "time" + + "github.com/juju/juju/mongo" +) + +const ( + DialTimeout = 5 * time.Minute + SocketTimeout = DialTimeout +) + +// DialOpts returns mongo.DialOpts suitable for use in tests that operate +// against a real MongoDB server. The timeouts are chosen to avoid failures +// caused by slow I/O; we do not expect the timeouts to be reached under +// normal circumstances. +func DialOpts() mongo.DialOpts { + return mongo.DialOpts{ + Timeout: DialTimeout, + SocketTimeout: SocketTimeout, + } +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/mongo/mongo_test.go juju-core-2.0~beta7/src/github.com/juju/juju/mongo/mongo_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/mongo/mongo_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/mongo/mongo_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -330,14 +330,15 @@ tests := []installs{ {"precise", [][]string{{"--target-release", "precise-updates/cloud-tools", "mongodb-server"}}}, - {"trusty", [][]string{{"juju-mongodb3.2"}}}, - {"wily", [][]string{{"juju-mongodb3.2"}}}, - {"xenial", [][]string{{"juju-mongodb3.2"}}}, + {"trusty", [][]string{{"juju-mongodb3.2"}, {"juju-mongo-tools3.2"}}}, + {"wily", [][]string{{"juju-mongodb3.2"}, {"juju-mongo-tools3.2"}}}, + {"xenial", [][]string{{"juju-mongodb3.2"}, {"juju-mongo-tools3.2"}}}, } testing.PatchExecutableAsEchoArgs(c, s, "add-apt-repository") testing.PatchExecutableAsEchoArgs(c, s, "apt-get") for _, test := range tests { + c.Logf("install for series %v", test.series) dataDir := c.MkDir() s.patchSeries(test.series) err := mongo.EnsureServer(makeEnsureServerParams(dataDir)) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/mongo/open.go juju-core-2.0~beta7/src/github.com/juju/juju/mongo/open.go --- juju-core-2.0~beta6/src/github.com/juju/juju/mongo/open.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/mongo/open.go 2016-05-17 20:01:14.000000000 +0000 @@ -13,6 +13,7 @@ "github.com/juju/errors" "github.com/juju/names" + "github.com/juju/utils" "gopkg.in/mgo.v2" "github.com/juju/juju/cert" @@ -57,6 +58,10 @@ // DefaultDialOpts returns a DialOpts representing the default // parameters for contacting a controller. +// +// NOTE(axw) these options are inappropriate for tests in CI, +// as CI tends to run on machines with slow I/O (or thrashed +// I/O with limited IOPs). For tests, use mongotest.DialOpts(). func DefaultDialOpts() DialOpts { return DialOpts{ Timeout: defaultDialTimeout, @@ -107,10 +112,19 @@ } pool := x509.NewCertPool() pool.AddCert(xcert) - tlsConfig := &tls.Config{ - RootCAs: pool, - ServerName: "juju-mongodb", + tlsConfig := utils.SecureTLSConfig() + + // TODO(natefinch): revisit this when are full-time on mongo 3. + // We have to add non-ECDHE suites because mongo doesn't support ECDHE. + moreSuites := []uint16{ + tls.TLS_RSA_WITH_AES_128_GCM_SHA256, + tls.TLS_RSA_WITH_AES_256_GCM_SHA384, } + + tlsConfig.CipherSuites = append(tlsConfig.CipherSuites, moreSuites...) + tlsConfig.RootCAs = pool + tlsConfig.ServerName = "juju-mongodb" + dial := func(addr net.Addr) (net.Conn, error) { c, err := net.Dial("tcp", addr.String()) if err != nil { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/mongo/service.go juju-core-2.0~beta7/src/github.com/juju/juju/mongo/service.go --- juju-core-2.0~beta6/src/github.com/juju/juju/mongo/service.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/mongo/service.go 2016-05-17 20:01:14.000000000 +0000 @@ -142,7 +142,9 @@ " --dbpath " + utils.ShQuote(dbDir) + " --sslOnNormalPorts" + " --sslPEMKeyFile " + utils.ShQuote(sslKeyPath(dataDir)) + - " --sslPEMKeyPassword ignored" + + // --sslPEMKeyPassword has to have its argument passed with = thanks to + // https://bugs.launchpad.net/juju-core/+bug/1581284. + " --sslPEMKeyPassword=ignored" + " --port " + fmt.Sprint(port) + " --syslog" + " --journal" + diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/mongo/service_test.go juju-core-2.0~beta7/src/github.com/juju/juju/mongo/service_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/mongo/service_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/mongo/service_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -41,7 +41,7 @@ " --dbpath '/var/lib/juju/db'" + " --sslOnNormalPorts" + " --sslPEMKeyFile '/var/lib/juju/server.pem'" + - " --sslPEMKeyPassword ignored" + + " --sslPEMKeyPassword=ignored" + " --port 12345" + " --syslog" + " --journal" + diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/config.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/config.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/config.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/config.go 2016-05-17 20:01:14.000000000 +0000 @@ -39,36 +39,28 @@ // account. configAttrStorageAccountKey = "storage-account-key" - // configAttrControllerResourceGroup is the resource group - // corresponding to the controller environment. Each environment needs - // to know this because some resources are shared, and live in the - // controller environment's resource group. - configAttrControllerResourceGroup = "controller-resource-group" - // resourceNameLengthMax is the maximum length of resource // names in Azure. resourceNameLengthMax = 80 ) var configFields = schema.Fields{ - configAttrLocation: schema.String(), - configAttrEndpoint: schema.String(), - configAttrStorageEndpoint: schema.String(), - configAttrAppId: schema.String(), - configAttrSubscriptionId: schema.String(), - configAttrTenantId: schema.String(), - configAttrAppPassword: schema.String(), - configAttrStorageAccount: schema.String(), - configAttrStorageAccountKey: schema.String(), - configAttrStorageAccountType: schema.String(), - configAttrControllerResourceGroup: schema.String(), + configAttrLocation: schema.String(), + configAttrEndpoint: schema.String(), + configAttrStorageEndpoint: schema.String(), + configAttrAppId: schema.String(), + configAttrSubscriptionId: schema.String(), + configAttrTenantId: schema.String(), + configAttrAppPassword: schema.String(), + configAttrStorageAccount: schema.String(), + configAttrStorageAccountKey: schema.String(), + configAttrStorageAccountType: schema.String(), } var configDefaults = schema.Defaults{ - configAttrStorageAccount: schema.Omit, - configAttrStorageAccountKey: schema.Omit, - configAttrControllerResourceGroup: schema.Omit, - configAttrStorageAccountType: string(storage.StandardLRS), + configAttrStorageAccount: schema.Omit, + configAttrStorageAccountKey: schema.Omit, + configAttrStorageAccountType: string(storage.StandardLRS), } var requiredConfigAttributes = []string{ @@ -79,13 +71,11 @@ configAttrLocation, configAttrEndpoint, configAttrStorageEndpoint, - configAttrControllerResourceGroup, } var immutableConfigAttributes = []string{ configAttrSubscriptionId, configAttrTenantId, - configAttrControllerResourceGroup, configAttrStorageAccount, configAttrStorageAccountType, } @@ -93,20 +83,18 @@ var internalConfigAttributes = []string{ configAttrStorageAccount, configAttrStorageAccountKey, - configAttrControllerResourceGroup, } type azureModelConfig struct { *config.Config - token *azure.ServicePrincipalToken - subscriptionId string - location string // canonicalized - endpoint string - storageEndpoint string - storageAccount string - storageAccountKey string - storageAccountType storage.AccountType - controllerResourceGroup string + token *azure.ServicePrincipalToken + subscriptionId string + location string // canonicalized + endpoint string + storageEndpoint string + storageAccount string + storageAccountKey string + storageAccountType storage.AccountType } var knownStorageAccountTypes = []string{ @@ -191,7 +179,6 @@ storageAccount, _ := validated[configAttrStorageAccount].(string) storageAccountKey, _ := validated[configAttrStorageAccountKey].(string) storageAccountType := validated[configAttrStorageAccountType].(string) - controllerResourceGroup := validated[configAttrControllerResourceGroup].(string) if newCfg.FirewallMode() == config.FwGlobal { // We do not currently support the "global" firewall mode. @@ -229,7 +216,6 @@ storageAccount, storageAccountKey, storage.AccountType(storageAccountType), - controllerResourceGroup, } return azureConfig, nil diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/config_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/config_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/config_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/config_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -75,7 +75,6 @@ s.assertConfigInvalid(c, testing.Attrs{"application-password": ""}, `"application-password" config not specified`) s.assertConfigInvalid(c, testing.Attrs{"tenant-id": ""}, `"tenant-id" config not specified`) s.assertConfigInvalid(c, testing.Attrs{"subscription-id": ""}, `"subscription-id" config not specified`) - s.assertConfigInvalid(c, testing.Attrs{"controller-resource-group": ""}, `"controller-resource-group" config not specified`) } func (s *configSuite) TestValidateStorageAccountCantChange(c *gc.C) { @@ -106,16 +105,15 @@ func makeTestModelConfig(c *gc.C, extra ...testing.Attrs) *config.Config { attrs := testing.Attrs{ - "type": "azure", - "application-id": fakeApplicationId, - "tenant-id": fakeTenantId, - "application-password": "opensezme", - "subscription-id": fakeSubscriptionId, - "location": "westus", - "endpoint": "https://api.azurestack.local", - "storage-endpoint": "https://storage.azurestack.local", - "controller-resource-group": "arbitrary", - "agent-version": "1.2.3", + "type": "azure", + "application-id": fakeApplicationId, + "tenant-id": fakeTenantId, + "application-password": "opensezme", + "subscription-id": fakeSubscriptionId, + "location": "westus", + "endpoint": "https://api.azurestack.local", + "storage-endpoint": "https://storage.azurestack.local", + "agent-version": "1.2.3", } for _, extra := range extra { attrs = attrs.Merge(extra) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/environ.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/environ.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/environ.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/environ.go 2016-05-17 20:01:14.000000000 +0000 @@ -6,7 +6,6 @@ import ( "fmt" "net/http" - "path" "sort" "strings" "sync" @@ -55,11 +54,6 @@ // subscription that corresponds to the environment. resourceGroup string - // controllerResourceGroup is the name of the Resource Group in the - // Azure subscription that corresponds to the Juju controller - // environment. - controllerResourceGroup string - // envName is the name of the environment. envName string @@ -86,7 +80,6 @@ } modelTag := names.NewModelTag(cfg.UUID()) env.resourceGroup = resourceGroupName(modelTag, cfg.Name()) - env.controllerResourceGroup = env.config.controllerResourceGroup env.envName = cfg.Name() return &env, nil } @@ -122,41 +115,35 @@ // see subnet creation). func (env *azureEnviron) initResourceGroup() (*config.Config, error) { location := env.config.location - tags, _ := env.config.ResourceTags() + tags := tags.ResourceTags( + names.NewModelTag(env.config.Config.UUID()), + names.NewModelTag(env.config.Config.ControllerUUID()), + env.config, + ) resourceGroupsClient := resources.GroupsClient{env.resources} logger.Debugf("creating resource group %q", env.resourceGroup) - _, err := resourceGroupsClient.CreateOrUpdate(env.resourceGroup, resources.Group{ - Location: to.StringPtr(location), - Tags: toTagsPtr(tags), - }) - if err != nil { + if err := env.callAPI(func() (autorest.Response, error) { + group, err := resourceGroupsClient.CreateOrUpdate(env.resourceGroup, resources.ResourceGroup{ + Location: to.StringPtr(location), + Tags: toTagsPtr(tags), + }) + return group.Response, err + }); err != nil { return nil, errors.Annotate(err, "creating resource group") } - var vnetPtr *network.VirtualNetwork - if env.resourceGroup == env.controllerResourceGroup { - // Create an internal network for all VMs to connect to. - vnetPtr, err = createInternalVirtualNetwork( - env.network, env.controllerResourceGroup, location, tags, - ) - if err != nil { - return nil, errors.Annotate(err, "creating virtual network") - } - } else { - // We're creating a hosted environment, so we need to fetch - // the virtual network to create a subnet below. - vnetClient := network.VirtualNetworksClient{env.network} - vnet, err := vnetClient.Get(env.controllerResourceGroup, internalNetworkName) - if err != nil { - return nil, errors.Annotate(err, "getting virtual network") - } - vnetPtr = &vnet + // Create an internal network for all VMs in the + // resource group to connect to. + vnetPtr, err := createInternalVirtualNetwork( + env.callAPI, env.network, env.resourceGroup, location, tags, + ) + if err != nil { + return nil, errors.Annotate(err, "creating virtual network") } _, err = createInternalSubnet( - env.network, env.resourceGroup, env.controllerResourceGroup, - vnetPtr, location, tags, + env.callAPI, env.network, env.resourceGroup, vnetPtr, location, tags, ) if err != nil { return nil, errors.Annotate(err, "creating subnet") @@ -165,7 +152,8 @@ // Create a storage account for the resource group. storageAccountsClient := storage.AccountsClient{env.storage} storageAccountName, storageAccountKey, err := createStorageAccount( - storageAccountsClient, env.config.storageAccountType, + env.callAPI, storageAccountsClient, + env.config.storageAccountType, env.resourceGroup, location, tags, env.provider.config.StorageAccountNameGenerator, ) @@ -179,6 +167,7 @@ } func createStorageAccount( + callAPI callAPIFunc, client storage.AccountsClient, accountType storage.AccountType, resourceGroup string, @@ -191,15 +180,19 @@ for remaining := maxAttempts; remaining > 0; remaining-- { accountName := accountNameGenerator() logger.Debugf("- checking storage account name %q", accountName) - result, err := client.CheckNameAvailability( - storage.AccountCheckNameAvailabilityParameters{ - Name: to.StringPtr(accountName), - // Azure is a little inconsistent with when Type is - // required. It's required here. - Type: to.StringPtr("Microsoft.Storage/storageAccounts"), - }, - ) - if err != nil { + var result storage.CheckNameAvailabilityResult + if err := callAPI(func() (autorest.Response, error) { + var err error + result, err = client.CheckNameAvailability( + storage.AccountCheckNameAvailabilityParameters{ + Name: to.StringPtr(accountName), + // Azure is a little inconsistent with when Type is + // required. It's required here. + Type: to.StringPtr("Microsoft.Storage/storageAccounts"), + }, + ) + return result.Response, err + }); err != nil { return "", "", errors.Annotate(err, "checking account name availability") } if !to.Bool(result.NameAvailable) { @@ -220,12 +213,20 @@ // TODO(axw) account creation can fail if the account name is // available, but contains profanity. We should retry a set // number of times even if creating fails. - if _, err := client.Create(resourceGroup, accountName, createParams); err != nil { + if err := callAPI(func() (autorest.Response, error) { + result, err := client.Create(resourceGroup, accountName, createParams) + return result.Response, err + }); err != nil { return "", "", errors.Trace(err) } + logger.Debugf("- listing storage account keys") - listKeysResult, err := client.ListKeys(resourceGroup, accountName) - if err != nil { + var listKeysResult storage.AccountKeys + if err := callAPI(func() (autorest.Response, error) { + var err error + listKeysResult, err = client.ListKeys(resourceGroup, accountName) + return listKeysResult.Response, err + }); err != nil { return "", "", errors.Annotate(err, "listing storage account keys") } return accountName, to.String(listKeysResult.Key1), nil @@ -238,7 +239,7 @@ // controllers are tagged with tags.JujuIsController, so just // list the instances in the controller resource group and pick // those ones out. - instances, err := env.allInstances(env.controllerResourceGroup, true) + instances, err := env.allInstances(env.resourceGroup, true) if err != nil { return nil, err } @@ -401,14 +402,17 @@ // ensure we obtain all information based on the same configuration. env.mu.Lock() location := env.config.location - envTags, _ := env.config.ResourceTags() + envTags := tags.ResourceTags( + names.NewModelTag(env.config.Config.UUID()), + names.NewModelTag(env.config.Config.ControllerUUID()), + env.config, + ) apiPort := env.config.APIPort() vmClient := compute.VirtualMachinesClient{env.compute} availabilitySetClient := compute.AvailabilitySetsClient{env.compute} networkClient := env.network vmImagesClient := compute.VirtualMachineImagesClient{env.compute} vmExtensionClient := compute.VirtualMachineExtensionsClient{env.compute} - subscriptionId := env.config.subscriptionId imageStream := env.config.ImageStream() storageEndpoint := env.config.storageEndpoint storageAccountName := env.config.storageAccount @@ -478,23 +482,17 @@ apiPortPtr = &apiPort } - // Construct the network security group ID for the environment. - nsgID := path.Join( - "/subscriptions", subscriptionId, "resourceGroups", - env.resourceGroup, "providers", "Microsoft.Network", - "networkSecurityGroups", internalSecurityGroupName, - ) - vm, err := createVirtualMachine( env.resourceGroup, location, vmName, vmTags, envTags, instanceSpec, args.InstanceConfig, args.DistributionGroup, env.Instances, - apiPortPtr, internalNetworkSubnet, nsgID, + apiPortPtr, internalNetworkSubnet, storageEndpoint, storageAccountName, networkClient, vmClient, availabilitySetClient, vmExtensionClient, + env.callAPI, ) if err != nil { logger.Errorf("creating instance failed, destroying: %v", err) @@ -534,11 +532,12 @@ instancesFunc func([]instance.Id) ([]instance.Instance, error), apiPort *int, internalNetworkSubnet *network.Subnet, - nsgID, storageEndpoint, storageAccountName string, + storageEndpoint, storageAccountName string, networkClient network.ManagementClient, vmClient compute.VirtualMachinesClient, availabilitySetClient compute.AvailabilitySetsClient, vmExtensionClient compute.VirtualMachineExtensionsClient, + callAPI callAPIFunc, ) (compute.VirtualMachine, error) { storageProfile, err := newStorageProfile( @@ -555,8 +554,8 @@ } networkProfile, err := newNetworkProfile( - networkClient, vmName, apiPort, - internalNetworkSubnet, nsgID, + callAPI, networkClient, + vmName, apiPort, internalNetworkSubnet, resourceGroup, location, vmTags, ) if err != nil { @@ -564,7 +563,7 @@ } availabilitySetId, err := createAvailabilitySet( - availabilitySetClient, + callAPI, availabilitySetClient, vmName, resourceGroup, location, vmTags, envTags, distributionGroupFunc, instancesFunc, @@ -590,8 +589,12 @@ }, }, } - vm, err := vmClient.CreateOrUpdate(resourceGroup, vmName, vmArgs) - if err != nil { + var vm compute.VirtualMachine + if err := callAPI(func() (autorest.Response, error) { + var err error + vm, err = vmClient.CreateOrUpdate(resourceGroup, vmName, vmArgs) + return vm.Response, err + }); err != nil { return compute.VirtualMachine{}, errors.Annotate(err, "creating virtual machine") } @@ -600,7 +603,7 @@ switch seriesOS { case os.Windows, os.CentOS: if err := createVMExtension( - vmExtensionClient, seriesOS, + callAPI, vmExtensionClient, seriesOS, resourceGroup, vmName, location, vmTags, ); err != nil { return compute.VirtualMachine{}, errors.Annotate( @@ -624,6 +627,7 @@ // - if there are no units assigned to the machine, then use the "juju" // availability set func createAvailabilitySet( + callAPI callAPIFunc, client compute.AvailabilitySetsClient, vmName, resourceGroup, location string, vmTags, envTags map[string]string, @@ -685,15 +689,19 @@ } logger.Debugf("- creating availability set %q", availabilitySetName) - availabilitySet, err := client.CreateOrUpdate( - resourceGroup, availabilitySetName, compute.AvailabilitySet{ - Location: to.StringPtr(location), - // NOTE(axw) we do *not* want to use vmTags here, - // because an availability set is shared by machines. - Tags: toTagsPtr(envTags), - }, - ) - if err != nil { + var availabilitySet compute.AvailabilitySet + if err := callAPI(func() (autorest.Response, error) { + var err error + availabilitySet, err = client.CreateOrUpdate( + resourceGroup, availabilitySetName, compute.AvailabilitySet{ + Location: to.StringPtr(location), + // NOTE(axw) we do *not* want to use vmTags here, + // because an availability set is shared by machines. + Tags: toTagsPtr(envTags), + }, + ) + return availabilitySet.Response, err + }); err != nil { return "", errors.Annotatef( err, "creating availability set %q", availabilitySetName, ) @@ -820,7 +828,8 @@ continue } if err := deleteInstance( - inst.(*azureInstance), computeClient, networkClient, storageClient, + inst.(*azureInstance), + env.callAPI, computeClient, networkClient, storageClient, ); err != nil { return errors.Annotatef(err, "deleting instance %q", inst.Id()) } @@ -832,6 +841,7 @@ // it owns, and any corresponding network security rules. func deleteInstance( inst *azureInstance, + callAPI callAPIFunc, computeClient compute.ManagementClient, networkClient network.ManagementClient, storageClient internalazurestorage.Client, @@ -845,8 +855,12 @@ logger.Debugf("deleting instance %q", vmName) logger.Debugf("- deleting virtual machine") - deleteResult, err := vmClient.Delete(inst.env.resourceGroup, vmName) - if err != nil { + var deleteResult autorest.Response + if err := callAPI(func() (autorest.Response, error) { + var err error + deleteResult, err = vmClient.Delete(inst.env.resourceGroup, vmName) + return deleteResult, err + }); err != nil { if deleteResult.Response == nil || deleteResult.StatusCode != http.StatusNotFound { return errors.Annotate(err, "deleting virtual machine") } @@ -862,7 +876,8 @@ // Delete network security rules that refer to the VM. logger.Debugf("- deleting security rules") if err := deleteInstanceNetworkSecurityRules( - inst.env.resourceGroup, inst.Id(), nsgClient, securityRuleClient, + inst.env.resourceGroup, inst.Id(), nsgClient, + securityRuleClient, inst.env.callAPI, ); err != nil { return errors.Annotate(err, "deleting network security rules") } @@ -886,9 +901,12 @@ detached = true } if detached { - if _, err := nicClient.CreateOrUpdate( - inst.env.resourceGroup, to.String(nic.Name), nic, - ); err != nil { + if err := callAPI(func() (autorest.Response, error) { + result, err := nicClient.CreateOrUpdate( + inst.env.resourceGroup, to.String(nic.Name), nic, + ) + return result.Response, err + }); err != nil { return errors.Annotate(err, "detaching public IP addresses") } } @@ -899,8 +917,12 @@ for _, pip := range inst.publicIPAddresses { pipName := to.String(pip.Name) logger.Tracef("deleting public IP %q", pipName) - result, err := publicIPClient.Delete(inst.env.resourceGroup, pipName) - if err != nil { + var result autorest.Response + if err := callAPI(func() (autorest.Response, error) { + var err error + result, err = publicIPClient.Delete(inst.env.resourceGroup, pipName) + return result, err + }); err != nil { if result.Response == nil || result.StatusCode != http.StatusNotFound { return errors.Annotate(err, "deleting public IP") } @@ -914,8 +936,12 @@ for _, nic := range inst.networkInterfaces { nicName := to.String(nic.Name) logger.Tracef("deleting NIC %q", nicName) - result, err := nicClient.Delete(inst.env.resourceGroup, nicName) - if err != nil { + var result autorest.Response + if err := callAPI(func() (autorest.Response, error) { + var err error + result, err = nicClient.Delete(inst.env.resourceGroup, nicName) + return result, err + }); err != nil { if result.Response == nil || result.StatusCode != http.StatusNotFound { return errors.Annotate(err, "deleting NIC") } @@ -989,8 +1015,12 @@ // unknown instances. StopInstances must delete VMs before NICs and // public IPs, because a VM cannot have less than 1 NIC. Thus, we can // potentially delete a VM but then fail to delete its NIC. - nicsResult, err := nicClient.List(resourceGroup) - if err != nil { + var nicsResult network.InterfaceListResult + if err := env.callAPI(func() (autorest.Response, error) { + var err error + nicsResult, err = nicClient.List(resourceGroup) + return nicsResult.Response, err + }); err != nil { if nicsResult.Response.Response != nil && nicsResult.StatusCode == http.StatusNotFound { // This will occur if the resource group does not // exist, e.g. in a fresh hosted environment. @@ -1003,8 +1033,12 @@ } // Create an azureInstance for each VM. - result, err := vmClient.List(resourceGroup) - if err != nil { + var result compute.VirtualMachineListResult + if err := env.callAPI(func() (autorest.Response, error) { + var err error + result, err = vmClient.List(resourceGroup) + return result.Response, err + }); err != nil { return nil, errors.Annotate(err, "listing virtual machines") } vmNames := make(set.Strings) @@ -1058,22 +1092,20 @@ if err := env.deleteResourceGroup(); err != nil { return errors.Trace(err) } - if env.resourceGroup == env.controllerResourceGroup { - // This is the controller resource group; once it has been - // deleted, there's nothing left. - return nil - } - logger.Debugf("- deleting internal subnet") - if err := env.deleteInternalSubnet(); err != nil { - return errors.Trace(err) - } + // Resource groups are self-contained and fully encompass + // all environ resources. Once you delete the group, there + // is nothing else to do. return nil } func (env *azureEnviron) deleteResourceGroup() error { client := resources.GroupsClient{env.resources} - result, err := client.Delete(env.resourceGroup) - if err != nil { + var result autorest.Response + if err := env.callAPI(func() (autorest.Response, error) { + var err error + result, err = client.Delete(env.resourceGroup) + return result, err + }); err != nil { if result.Response == nil || result.StatusCode != http.StatusNotFound { return errors.Annotatef(err, "deleting resource group %q", env.resourceGroup) } @@ -1141,9 +1173,13 @@ location := env.config.location client := compute.VirtualMachineSizesClient{env.compute} - result, err := client.List(location) - if err != nil { - return nil, errors.Trace(err) + var result compute.VirtualMachineSizeListResult + if err := env.callAPI(func() (autorest.Response, error) { + var err error + result, err = client.List(location) + return result.Response, err + }); err != nil { + return nil, errors.Annotate(err, "listing VM sizes") } instanceTypes := make(map[string]instances.InstanceType) if result.Value != nil { @@ -1164,9 +1200,13 @@ func (env *azureEnviron) getInternalSubnetLocked() (*network.Subnet, error) { client := network.SubnetsClient{env.network} vnetName := internalNetworkName - subnetName := env.resourceGroup - subnet, err := client.Get(env.controllerResourceGroup, vnetName, subnetName) - if err != nil { + subnetName := internalSubnetName + var subnet network.Subnet + if err := env.callAPI(func() (autorest.Response, error) { + var err error + subnet, err = client.Get(env.resourceGroup, vnetName, subnetName) + return subnet.Response, err + }); err != nil { return nil, errors.Annotate(err, "getting internal subnet") } return &subnet, nil @@ -1199,3 +1239,7 @@ Endpoint: fmt.Sprintf("https://%s/", env.config.storageEndpoint), }, nil } + +func (env *azureEnviron) callAPI(f func() (autorest.Response, error)) error { + return backoffAPIRequestCaller{env.provider.config.RetryClock}.call(f) +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/environprovider.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/environprovider.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/environprovider.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/environprovider.go 2016-05-17 20:01:14.000000000 +0000 @@ -7,7 +7,7 @@ "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" "github.com/juju/errors" "github.com/juju/loggo" - "github.com/juju/names" + "github.com/juju/utils/clock" "github.com/juju/juju/cloud" "github.com/juju/juju/environs" @@ -36,6 +36,9 @@ // StorageAccountNameGenerator is a function returning storage // account names. StorageAccountNameGenerator func() string + + // RetryClock is used when retrying API calls due to rate-limiting. + RetryClock clock.Clock } // Validate validates the Azure provider configuration. @@ -46,6 +49,9 @@ if cfg.StorageAccountNameGenerator == nil { return errors.NotValidf("nil StorageAccountNameGenerator") } + if cfg.RetryClock == nil { + return errors.NotValidf("nil RetryClock") + } return nil } @@ -78,10 +84,10 @@ // The result of RestrictedConfigAttributes is the names of attributes that // will be copied across to a hosted environment's initial configuration. func (prov *azureEnvironProvider) RestrictedConfigAttributes() []string { + // TODO(axw) there should be no restricted attributes. return []string{ configAttrLocation, configAttrEndpoint, - configAttrControllerResourceGroup, configAttrStorageEndpoint, } } @@ -111,13 +117,6 @@ configAttrLocation: args.CloudRegion, configAttrEndpoint: args.CloudEndpoint, configAttrStorageEndpoint: args.CloudStorageEndpoint, - - // Record the UUID that will be used for the controller - // model, which contains shared resources. - configAttrControllerResourceGroup: resourceGroupName( - names.NewModelTag(args.Config.UUID()), - args.Config.Name(), - ), } switch authType := args.Credentials.AuthType(); authType { case cloud.UserPassAuthType: diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/environprovider_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/environprovider_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/environprovider_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/environprovider_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -8,6 +8,7 @@ "fmt" "io/ioutil" "net/http" + "time" "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" jc "github.com/juju/testing/checkers" @@ -40,7 +41,6 @@ } func (s *environProviderSuite) TestBootstrapConfigWithInternalConfig(c *gc.C) { - s.testBootstrapConfigWithInternalConfig(c, "controller-resource-group") s.testBootstrapConfigWithInternalConfig(c, "storage-account") } @@ -68,11 +68,8 @@ func (s *environProviderSuite) TestBootstrapConfig(c *gc.C) { cfg := makeTestModelConfig(c) - cfg, err := cfg.Remove([]string{"controller-resource-group"}) - c.Assert(err, jc.ErrorIsNil) - s.sender = azuretesting.Senders{tokenRefreshSender()} - cfg, err = s.provider.BootstrapConfig(environs.BootstrapConfigParams{ + cfg, err := s.provider.BootstrapConfig(environs.BootstrapConfigParams{ Config: cfg, CloudRegion: "westus", CloudEndpoint: "https://api.azurestack.local", @@ -82,11 +79,10 @@ c.Check(err, jc.ErrorIsNil) c.Check(cfg, gc.NotNil) - c.Assert( - cfg.UnknownAttrs()["controller-resource-group"], - gc.Equals, - "juju-testenv-model-"+testing.ModelTag.Id(), - ) + attrs := cfg.UnknownAttrs() + c.Assert(attrs["location"], gc.Equals, "westus") + c.Assert(attrs["endpoint"], gc.Equals, "https://api.azurestack.local") + c.Assert(attrs["storage-endpoint"], gc.Equals, "https://storage.azurestack.local") } func newProviders(c *gc.C, config azure.ProviderConfig) (environs.EnvironProvider, storage.Provider) { @@ -99,6 +95,9 @@ return fakeStorageAccount } } + if config.RetryClock == nil { + config.RetryClock = testing.NewClock(time.Time{}) + } environProvider, storageProvider, err := azure.NewProviders(config) c.Assert(err, jc.ErrorIsNil) return environProvider, storageProvider diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/environ_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/environ_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/environ_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/environ_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -20,8 +20,10 @@ "github.com/Azure/azure-sdk-for-go/arm/resources" "github.com/Azure/azure-sdk-for-go/arm/storage" "github.com/juju/names" + gitjujutesting "github.com/juju/testing" jc "github.com/juju/testing/checkers" "github.com/juju/utils/arch" + "github.com/juju/utils/series" gc "gopkg.in/check.v1" "github.com/juju/juju/api" @@ -49,13 +51,16 @@ requests []*http.Request storageClient azuretesting.MockStorageClient sender azuretesting.Senders + retryClock mockClock tags map[string]*string + group *resources.ResourceGroup vmSizes *compute.VirtualMachineSizeListResult storageNameAvailabilityResult *storage.CheckNameAvailabilityResult storageAccount *storage.Account storageAccountKeys *storage.AccountKeys vnet *network.VirtualNetwork + nsg *network.SecurityGroup subnet *network.Subnet ubuntuServerSKUs []compute.VirtualMachineImageResource publicIPAddress *network.PublicIPAddress @@ -71,17 +76,30 @@ s.BaseSuite.SetUpTest(c) s.storageClient = azuretesting.MockStorageClient{} s.sender = nil + s.retryClock = mockClock{Clock: testing.NewClock(time.Time{})} + s.provider, _ = newProviders(c, azure.ProviderConfig{ Sender: &s.sender, RequestInspector: requestRecorder(&s.requests), NewStorageClient: s.storageClient.NewClient, + RetryClock: &testing.AutoAdvancingClock{ + &s.retryClock, s.retryClock.Advance, + }, }) - emptyTags := make(map[string]*string) + envTags := map[string]*string{ + "juju-model-uuid": to.StringPtr(testing.ModelTag.Id()), + "juju-controller-uuid": to.StringPtr(testing.ModelTag.Id()), + } s.tags = map[string]*string{ "juju-machine-name": to.StringPtr("machine-0"), } + s.group = &resources.ResourceGroup{ + Location: to.StringPtr("westus"), + Tags: &envTags, + } + vmSizes := []compute.VirtualMachineSize{{ Name: to.StringPtr("Standard_D1"), NumberOfCores: to.IntPtr(1), @@ -99,6 +117,7 @@ s.storageAccount = &storage.Account{ Name: to.StringPtr("my-storage-account"), Type: to.StringPtr("Standard_LRS"), + Tags: &envTags, Properties: &storage.AccountProperties{ PrimaryEndpoints: &storage.Endpoints{ Blob: to.StringPtr(fmt.Sprintf("https://%s.blob.storage.azurestack.local/", fakeStorageAccount)), @@ -110,25 +129,32 @@ Key1: to.StringPtr("key-1"), } - addressPrefixes := make([]string, 256) - for i := range addressPrefixes { - addressPrefixes[i] = fmt.Sprintf("10.%d.0.0/16", i) - } + addressPrefixes := []string{"10.0.0.0/16"} s.vnet = &network.VirtualNetwork{ - ID: to.StringPtr("juju-internal"), - Name: to.StringPtr("juju-internal"), + ID: to.StringPtr("juju-internal-network"), + Name: to.StringPtr("juju-internal-network"), Location: to.StringPtr("westus"), - Tags: &emptyTags, + Tags: &envTags, Properties: &network.VirtualNetworkPropertiesFormat{ AddressSpace: &network.AddressSpace{&addressPrefixes}, }, } + s.nsg = &network.SecurityGroup{ + ID: to.StringPtr(path.Join( + "/subscriptions", fakeSubscriptionId, + "resourceGroups", "juju-testenv-model-"+testing.ModelTag.Id(), + "providers/Microsoft.Network/networkSecurityGroups/juju-internal-nsg", + )), + Tags: &envTags, + } + s.subnet = &network.Subnet{ ID: to.StringPtr("subnet-id"), - Name: to.StringPtr("juju-testenv-model-deadbeef-0bad-400d-8000-4b1d0d06f00d"), + Name: to.StringPtr("juju-internal-subnet"), Properties: &network.SubnetPropertiesFormat{ - AddressPrefix: to.StringPtr("10.0.0.0/16"), + AddressPrefix: to.StringPtr("10.0.0.0/16"), + NetworkSecurityGroup: &network.SubResource{s.nsg.ID}, }, } @@ -138,6 +164,7 @@ {Name: to.StringPtr("14.04-LTS")}, {Name: to.StringPtr("15.04")}, {Name: to.StringPtr("15.10")}, + {Name: to.StringPtr("16.04-LTS")}, } s.publicIPAddress = &network.PublicIPAddress{ @@ -174,14 +201,6 @@ Value: &oldNetworkInterfaces, } - // nsgID is the name of the internal network security group. This NSG - // is created when the environment is created. - nsgID := path.Join( - "/subscriptions", fakeSubscriptionId, - "resourceGroups", "juju-testenv-model-"+testing.ModelTag.Id(), - "providers/Microsoft.Network/networkSecurityGroups/juju-internal", - ) - // The newly created IP/NIC. newIPConfigurations := []network.InterfaceIPConfiguration{{ ID: to.StringPtr("ip-configuration-1-id"), @@ -199,8 +218,7 @@ Location: to.StringPtr("westus"), Tags: &s.tags, Properties: &network.InterfacePropertiesFormat{ - IPConfigurations: &newIPConfigurations, - NetworkSecurityGroup: &network.SubResource{to.StringPtr(nsgID)}, + IPConfigurations: &newIPConfigurations, }, } @@ -208,7 +226,7 @@ ID: to.StringPtr("juju-availability-set-id"), Name: to.StringPtr("juju"), Location: to.StringPtr("westus"), - Tags: &emptyTags, + Tags: &envTags, } sshPublicKeys := []compute.SSHPublicKey{{ @@ -304,10 +322,8 @@ // Opening the environment should not incur network communication, // so we don't set s.sender until after opening. cfg := makeTestModelConfig(c, attrs...) - cfg, err := cfg.Remove([]string{"controller-resource-group"}) - c.Assert(err, jc.ErrorIsNil) *sender = azuretesting.Senders{tokenRefreshSender()} - cfg, err = provider.BootstrapConfig(environs.BootstrapConfigParams{ + cfg, err := provider.BootstrapConfig(environs.BootstrapConfigParams{ Config: cfg, CloudRegion: "westus", CloudEndpoint: "https://management.azure.com", @@ -333,10 +349,10 @@ func (s *environSuite) initResourceGroupSenders() azuretesting.Senders { resourceGroupName := "juju-testenv-model-deadbeef-0bad-400d-8000-4b1d0d06f00d" return azuretesting.Senders{ - s.makeSender(".*/resourcegroups/"+resourceGroupName, &resources.Group{}), - s.makeSender(".*/virtualnetworks/juju-internal", s.vnet), - s.makeSender(".*/networkSecurityGroups/juju-internal", &network.SecurityGroup{}), - s.makeSender(".*/virtualnetworks/juju-internal/subnets/"+resourceGroupName, &s.subnet), + s.makeSender(".*/resourcegroups/"+resourceGroupName, s.group), + s.makeSender(".*/virtualnetworks/juju-internal-network", s.vnet), + s.makeSender(".*/networkSecurityGroups/juju-internal-nsg", s.nsg), + s.makeSender(".*/virtualnetworks/juju-internal-network/subnets/juju-internal-subnet", s.subnet), s.makeSender(".*/checkNameAvailability", s.storageNameAvailabilityResult), s.makeSender(".*/storageAccounts/.*", s.storageAccount), s.makeSender(".*/storageAccounts/.*/listKeys", s.storageAccountKeys), @@ -346,7 +362,7 @@ func (s *environSuite) startInstanceSenders(controller bool) azuretesting.Senders { senders := azuretesting.Senders{ s.vmSizesSender(), - s.makeSender(".*/subnets/juju-testenv-model-deadbeef-0bad-400d-8000-4b1d0d06f00d", s.subnet), + s.makeSender(".*/subnets/juju-internal-subnet", s.subnet), s.makeSender(".*/Canonical/.*/UbuntuServer/skus", s.ubuntuServerSKUs), s.makeSender(".*/publicIPAddresses/machine-0-public-ip", s.publicIPAddress), s.makeSender(".*/networkInterfaces", s.oldNetworkInterfaces), @@ -354,10 +370,10 @@ } if controller { senders = append(senders, - s.makeSender(".*/networkSecurityGroups/juju-internal", &network.SecurityGroup{ + s.makeSender(".*/networkSecurityGroups/juju-internal-nsg", &network.SecurityGroup{ Properties: &network.SecurityGroupPropertiesFormat{}, }), - s.makeSender(".*/networkSecurityGroups/juju-internal", &network.SecurityGroup{}), + s.makeSender(".*/networkSecurityGroups/juju-internal-nsg", &network.SecurityGroup{}), ) } senders = append(senders, @@ -446,6 +462,17 @@ c.Assert(unmarshalled, jc.DeepEquals, expect) } +type mockClock struct { + gitjujutesting.Stub + *testing.Clock +} + +func (c *mockClock) After(d time.Duration) <-chan time.Time { + c.MethodCall(c, "After", d) + c.PopNoErr() + return c.Clock.After(d) +} + func (s *environSuite) TestOpen(c *gc.C) { cfg := makeTestModelConfig(c) env, err := s.provider.Open(cfg) @@ -488,11 +515,90 @@ RootDisk: &rootDisk, CpuCores: &cpuCores, }) - requests := s.assertStartInstanceRequests(c) + requests := s.assertStartInstanceRequests(c, s.requests) availabilitySetName := path.Base(requests.availabilitySet.URL.Path) c.Assert(availabilitySetName, gc.Equals, "juju") } +func (s *environSuite) TestStartInstanceTooManyRequests(c *gc.C) { + env := s.openEnviron(c) + senders := s.startInstanceSenders(false) + s.requests = nil + + // 6 failures to get to 1 minute, and show that we cap it there. + const failures = 6 + + // Make the VirtualMachines.CreateOrUpdate call respond with + // 429 (StatusTooManyRequests) failures, and then with success. + rateLimitedSender := mocks.NewSender() + rateLimitedSender.EmitStatus("(ã€ã‚œãƒ­ã‚œ)ã€", http.StatusTooManyRequests) + successSender := senders[len(senders)-1] + senders = senders[:len(senders)-1] + for i := 0; i < failures; i++ { + senders = append(senders, rateLimitedSender) + } + senders = append(senders, successSender) + s.sender = senders + + _, err := env.StartInstance(makeStartInstanceParams(c, "quantal")) + c.Assert(err, jc.ErrorIsNil) + + c.Assert(s.requests, gc.HasLen, 8+failures) + s.assertStartInstanceRequests(c, s.requests[:8]) + + // The last two requests should match the third-to-last, which + // is checked by assertStartInstanceRequests. + for i := 8; i < 8+failures; i++ { + c.Assert(s.requests[i].Method, gc.Equals, "PUT") + assertCreateVirtualMachineRequestBody(c, s.requests[i], s.virtualMachine) + } + + s.retryClock.CheckCalls(c, []gitjujutesting.StubCall{ + {"After", []interface{}{5 * time.Second}}, + {"After", []interface{}{10 * time.Second}}, + {"After", []interface{}{20 * time.Second}}, + {"After", []interface{}{40 * time.Second}}, + {"After", []interface{}{1 * time.Minute}}, + {"After", []interface{}{1 * time.Minute}}, + }) +} + +func (s *environSuite) TestStartInstanceTooManyRequestsTimeout(c *gc.C) { + env := s.openEnviron(c) + senders := s.startInstanceSenders(false) + s.requests = nil + + // 8 failures to get to 5 minutes, which is as long as we'll keep + // retrying before giving up. + const failures = 8 + + // Make the VirtualMachines.CreateOrUpdate call respond with + // enough 429 (StatusTooManyRequests) failures to cause the + // method to give up retrying. + rateLimitedSender := mocks.NewSender() + rateLimitedSender.EmitStatus("(ã€ã‚œãƒ­ã‚œ)ã€", http.StatusTooManyRequests) + senders = senders[:len(senders)-1] + for i := 0; i < failures; i++ { + senders = append(senders, rateLimitedSender) + } + s.sender = senders + + _, err := env.StartInstance(makeStartInstanceParams(c, "quantal")) + c.Assert(err, gc.ErrorMatches, "creating virtual machine.*: max duration exceeded: .*failed with.*") + + s.retryClock.CheckCalls(c, []gitjujutesting.StubCall{ + {"After", []interface{}{5 * time.Second}}, // t0 + 5s + {"After", []interface{}{10 * time.Second}}, // t0 + 15s + {"After", []interface{}{20 * time.Second}}, // t0 + 35s + {"After", []interface{}{40 * time.Second}}, // t0 + 1m15s + {"After", []interface{}{1 * time.Minute}}, // t0 + 2m15s + {"After", []interface{}{1 * time.Minute}}, // t0 + 3m15s + {"After", []interface{}{1 * time.Minute}}, // t0 + 4m15s + // There would be another call here, but since the time + // exceeds the give minute limit, retrying is aborted. + }) +} + func (s *environSuite) TestStartInstanceDistributionGroup(c *gc.C) { c.Skip("TODO: test StartInstance's DistributionGroup behaviour") } @@ -507,12 +613,12 @@ _, err := env.StartInstance(params) c.Assert(err, jc.ErrorIsNil) s.tags[tags.JujuUnitsDeployed] = &unitsDeployed - requests := s.assertStartInstanceRequests(c) + requests := s.assertStartInstanceRequests(c, s.requests) availabilitySetName := path.Base(requests.availabilitySet.URL.Path) c.Assert(availabilitySetName, gc.Equals, "mysql") } -func (s *environSuite) assertStartInstanceRequests(c *gc.C) startInstanceRequests { +func (s *environSuite) assertStartInstanceRequests(c *gc.C, requests []*http.Request) startInstanceRequests { // Clear the fields that don't get sent in the request. s.publicIPAddress.ID = nil s.publicIPAddress.Name = nil @@ -527,37 +633,40 @@ s.virtualMachine.Properties.ProvisioningState = nil // Validate HTTP request bodies. - c.Assert(s.requests, gc.HasLen, 8) - c.Assert(s.requests[0].Method, gc.Equals, "GET") // vmSizes - c.Assert(s.requests[1].Method, gc.Equals, "GET") // juju-testenv-model-deadbeef-0bad-400d-8000-4b1d0d06f00d - c.Assert(s.requests[2].Method, gc.Equals, "GET") // skus - c.Assert(s.requests[3].Method, gc.Equals, "PUT") - assertRequestBody(c, s.requests[3], s.publicIPAddress) - c.Assert(s.requests[4].Method, gc.Equals, "GET") // NICs - c.Assert(s.requests[5].Method, gc.Equals, "PUT") - assertRequestBody(c, s.requests[5], s.newNetworkInterface) - c.Assert(s.requests[6].Method, gc.Equals, "PUT") - assertRequestBody(c, s.requests[6], s.jujuAvailabilitySet) - c.Assert(s.requests[7].Method, gc.Equals, "PUT") + c.Assert(requests, gc.HasLen, 8) + c.Assert(requests[0].Method, gc.Equals, "GET") // vmSizes + c.Assert(requests[1].Method, gc.Equals, "GET") // juju-testenv-model-deadbeef-0bad-400d-8000-4b1d0d06f00d + c.Assert(requests[2].Method, gc.Equals, "GET") // skus + c.Assert(requests[3].Method, gc.Equals, "PUT") + assertRequestBody(c, requests[3], s.publicIPAddress) + c.Assert(requests[4].Method, gc.Equals, "GET") // NICs + c.Assert(requests[5].Method, gc.Equals, "PUT") + assertRequestBody(c, requests[5], s.newNetworkInterface) + c.Assert(requests[6].Method, gc.Equals, "PUT") + assertRequestBody(c, requests[6], s.jujuAvailabilitySet) + c.Assert(requests[7].Method, gc.Equals, "PUT") + assertCreateVirtualMachineRequestBody(c, requests[7], s.virtualMachine) + return startInstanceRequests{ + vmSizes: requests[0], + subnet: requests[1], + skus: requests[2], + publicIPAddress: requests[3], + nics: requests[4], + networkInterface: requests[5], + availabilitySet: requests[6], + virtualMachine: requests[7], + } +} + +func assertCreateVirtualMachineRequestBody(c *gc.C, req *http.Request, expect *compute.VirtualMachine) { // CustomData is non-deterministic, so don't compare it. // TODO(axw) shouldn't CustomData be deterministic? Look into this. var virtualMachine compute.VirtualMachine - unmarshalRequestBody(c, s.requests[7], &virtualMachine) + unmarshalRequestBody(c, req, &virtualMachine) c.Assert(to.String(virtualMachine.Properties.OsProfile.CustomData), gc.Not(gc.HasLen), 0) virtualMachine.Properties.OsProfile.CustomData = to.StringPtr("") - c.Assert(&virtualMachine, jc.DeepEquals, s.virtualMachine) - - return startInstanceRequests{ - vmSizes: s.requests[0], - subnet: s.requests[1], - skus: s.requests[2], - publicIPAddress: s.requests[3], - nics: s.requests[4], - networkInterface: s.requests[5], - availabilitySet: s.requests[6], - virtualMachine: s.requests[7], - } + c.Assert(&virtualMachine, jc.DeepEquals, expect) } type startInstanceRequests struct { @@ -582,12 +691,12 @@ s.requests = nil result, err := env.Bootstrap( ctx, environs.BootstrapParams{ - AvailableTools: makeToolsList("trusty"), + AvailableTools: makeToolsList(series.LatestLts()), }, ) c.Assert(err, jc.ErrorIsNil) c.Assert(result.Arch, gc.Equals, "amd64") - c.Assert(result.Series, gc.Equals, "trusty") + c.Assert(result.Series, gc.Equals, series.LatestLts()) c.Assert(len(s.requests), gc.Equals, 17) @@ -599,11 +708,7 @@ c.Assert(s.requests[5].Method, gc.Equals, "PUT") // create storage account c.Assert(s.requests[6].Method, gc.Equals, "POST") // get storage account keys - emptyTags := map[string]*string{} - assertRequestBody(c, s.requests[0], &resources.Group{ - Location: to.StringPtr("westus"), - Tags: &emptyTags, - }) + assertRequestBody(c, s.requests[0], &s.group) s.vnet.ID = nil s.vnet.Name = nil @@ -613,7 +718,7 @@ Name: to.StringPtr("SSHInbound"), Properties: &network.SecurityRulePropertiesFormat{ Description: to.StringPtr("Allow SSH access to all machines"), - Protocol: network.SecurityRuleProtocolTCP, + Protocol: network.TCP, SourceAddressPrefix: to.StringPtr("*"), SourcePortRange: to.StringPtr("*"), DestinationAddressPrefix: to.StringPtr("*"), @@ -625,7 +730,7 @@ }} assertRequestBody(c, s.requests[2], &network.SecurityGroup{ Location: to.StringPtr("westus"), - Tags: &emptyTags, + Tags: s.nsg.Tags, Properties: &network.SecurityGroupPropertiesFormat{ SecurityRules: &securityRules, }, @@ -642,7 +747,7 @@ assertRequestBody(c, s.requests[5], &storage.AccountCreateParameters{ Location: to.StringPtr("westus"), - Tags: &emptyTags, + Tags: s.storageAccount.Tags, Properties: &storage.AccountPropertiesCreateParameters{ AccountType: "Standard_LRS", }, @@ -694,17 +799,17 @@ s.publicIPAddressesSender( makePublicIPAddress("pip-0", "machine-0", "1.2.3.4"), ), - s.makeSender(".*/virtualMachines/machine-0", nil), // DELETE - s.makeSender(".*/networkSecurityGroups/juju-internal", nsg), // GET - s.makeSender(".*/networkSecurityGroups/juju-internal/securityRules/machine-0-80", nil), // DELETE - s.makeSender(".*/networkSecurityGroups/juju-internal/securityRules/machine-0-1000-2000", nil), // DELETE - s.makeSender(".*/networkInterfaces/nic-0", nic0), // PUT - s.makeSender(".*/publicIPAddresses/pip-0", nil), // DELETE - s.makeSender(".*/networkInterfaces/nic-0", nil), // DELETE - s.makeSender(".*/virtualMachines/machine-1", nil), // DELETE - s.makeSender(".*/networkSecurityGroups/juju-internal", nsg), // GET - s.makeSender(".*/networkInterfaces/nic-1", nil), // DELETE - s.makeSender(".*/networkInterfaces/nic-2", nil), // DELETE + s.makeSender(".*/virtualMachines/machine-0", nil), // DELETE + s.makeSender(".*/networkSecurityGroups/juju-internal-nsg", nsg), // GET + s.makeSender(".*/networkSecurityGroups/juju-internal-nsg/securityRules/machine-0-80", nil), // DELETE + s.makeSender(".*/networkSecurityGroups/juju-internal-nsg/securityRules/machine-0-1000-2000", nil), // DELETE + s.makeSender(".*/networkInterfaces/nic-0", nic0), // PUT + s.makeSender(".*/publicIPAddresses/pip-0", nil), // DELETE + s.makeSender(".*/networkInterfaces/nic-0", nil), // DELETE + s.makeSender(".*/virtualMachines/machine-1", nil), // DELETE + s.makeSender(".*/networkSecurityGroups/juju-internal-nsg", nsg), // GET + s.makeSender(".*/networkInterfaces/nic-1", nil), // DELETE + s.makeSender(".*/networkInterfaces/nic-2", nil), // DELETE } err := env.StopInstances("machine-0", "machine-1", "machine-2") c.Assert(err, jc.ErrorIsNil) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/init.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/init.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/init.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/init.go 2016-05-17 20:01:14.000000000 +0000 @@ -5,6 +5,7 @@ import ( "github.com/juju/errors" + "github.com/juju/utils/clock" "github.com/juju/juju/environs" "github.com/juju/juju/provider/azure/internal/azurestorage" @@ -31,6 +32,7 @@ environProvider, storageProvider, err := NewProviders(ProviderConfig{ NewStorageClient: azurestorage.NewClient, StorageAccountNameGenerator: RandomStorageAccountName, + RetryClock: &clock.WallClock, }) if err != nil { panic(err) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/instance.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/instance.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/instance.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/instance.go 2016-05-17 20:01:14.000000000 +0000 @@ -8,6 +8,7 @@ "net/http" "strings" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/to" "github.com/Azure/azure-sdk-for-go/arm/compute" "github.com/Azure/azure-sdk-for-go/arm/network" @@ -155,11 +156,8 @@ inst.env.mu.Lock() subscriptionId := inst.env.config.subscriptionId resourceGroup := inst.env.resourceGroup - controllerResourceGroup := inst.env.controllerResourceGroup inst.env.mu.Unlock() - internalSubnetId := internalSubnetId( - resourceGroup, controllerResourceGroup, subscriptionId, - ) + internalSubnetId := internalSubnetId(resourceGroup, subscriptionId) for _, nic := range inst.networkInterfaces { if nic.Properties.IPConfigurations == nil { @@ -197,8 +195,12 @@ } securityGroupName := internalSecurityGroupName - nsg, err := nsgClient.Get(inst.env.resourceGroup, securityGroupName) - if err != nil { + var nsg network.SecurityGroup + if err := inst.env.callAPI(func() (autorest.Response, error) { + var err error + nsg, err = nsgClient.Get(inst.env.resourceGroup, securityGroupName) + return nsg.Response, err + }); err != nil { return errors.Annotate(err, "querying network security group") } @@ -239,9 +241,9 @@ var protocol network.SecurityRuleProtocol switch ports.Protocol { case "tcp": - protocol = network.SecurityRuleProtocolTCP + protocol = network.TCP case "udp": - protocol = network.SecurityRuleProtocolUDP + protocol = network.UDP default: return errors.Errorf("invalid protocol %q", ports.Protocol) } @@ -266,9 +268,12 @@ Direction: network.Inbound, }, } - if _, err := securityRuleClient.CreateOrUpdate( - inst.env.resourceGroup, securityGroupName, ruleName, rule, - ); err != nil { + if err := inst.env.callAPI(func() (autorest.Response, error) { + result, err := securityRuleClient.CreateOrUpdate( + inst.env.resourceGroup, securityGroupName, ruleName, rule, + ) + return result.Response, err + }); err != nil { return errors.Annotatef(err, "creating security rule for %s", ports) } securityRules = append(securityRules, rule) @@ -290,10 +295,14 @@ for _, ports := range ports { ruleName := securityRuleName(prefix, ports) logger.Debugf("deleting security rule %q", ruleName) - result, err := securityRuleClient.Delete( - inst.env.resourceGroup, securityGroupName, ruleName, - ) - if err != nil { + var result autorest.Response + if err := inst.env.callAPI(func() (autorest.Response, error) { + var err error + result, err = securityRuleClient.Delete( + inst.env.resourceGroup, securityGroupName, ruleName, + ) + return result, err + }); err != nil { if result.Response == nil || result.StatusCode != http.StatusNotFound { return errors.Annotatef(err, "deleting security rule %q", ruleName) } @@ -309,8 +318,12 @@ inst.env.mu.Unlock() securityGroupName := internalSecurityGroupName - nsg, err := nsgClient.Get(inst.env.resourceGroup, securityGroupName) - if err != nil { + var nsg network.SecurityGroup + if err := inst.env.callAPI(func() (autorest.Response, error) { + var err error + nsg, err = nsgClient.Get(inst.env.resourceGroup, securityGroupName) + return nsg.Response, err + }); err != nil { return nil, errors.Annotate(err, "querying network security group") } if nsg.Properties.SecurityRules == nil { @@ -351,9 +364,9 @@ var protocols []string switch rule.Properties.Protocol { - case network.SecurityRuleProtocolTCP: + case network.TCP: protocols = []string{"tcp"} - case network.SecurityRuleProtocolUDP: + case network.UDP: protocols = []string{"udp"} default: protocols = []string{"tcp", "udp"} @@ -376,9 +389,14 @@ resourceGroup string, id instance.Id, nsgClient network.SecurityGroupsClient, securityRuleClient network.SecurityRulesClient, + callAPI callAPIFunc, ) error { - nsg, err := nsgClient.Get(resourceGroup, internalSecurityGroupName) - if err != nil { + var nsg network.SecurityGroup + if err := callAPI(func() (autorest.Response, error) { + var err error + nsg, err = nsgClient.Get(resourceGroup, internalSecurityGroupName) + return nsg.Response, err + }); err != nil { return errors.Annotate(err, "querying network security group") } if nsg.Properties.SecurityRules == nil { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/instance_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/instance_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/instance_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/instance_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -110,7 +110,7 @@ return network.SecurityRule{ Name: to.StringPtr(name), Properties: &network.SecurityRulePropertiesFormat{ - Protocol: network.SecurityRuleProtocolTCP, + Protocol: network.TCP, DestinationAddressPrefix: to.StringPtr(ipAddress), DestinationPortRange: to.StringPtr(ports), Access: network.Allow, @@ -158,7 +158,7 @@ SecurityRules: &rules, }, }) - nsgSender.PathPattern = ".*/networkSecurityGroups/juju-internal" + nsgSender.PathPattern = ".*/networkSecurityGroups/juju-internal-nsg" return nsgSender } @@ -257,7 +257,7 @@ nsgSender := networkSecurityGroupSender([]network.SecurityRule{{ Name: to.StringPtr("machine-0-xyzzy"), Properties: &network.SecurityRulePropertiesFormat{ - Protocol: network.SecurityRuleProtocolUDP, + Protocol: network.UDP, DestinationPortRange: to.StringPtr("*"), Access: network.Allow, Priority: to.IntPtr(200), @@ -266,7 +266,7 @@ }, { Name: to.StringPtr("machine-0-tcpcp"), Properties: &network.SecurityRulePropertiesFormat{ - Protocol: network.SecurityRuleProtocolTCP, + Protocol: network.TCP, DestinationPortRange: to.StringPtr("1000-2000"), Access: network.Allow, Priority: to.IntPtr(201), @@ -275,7 +275,7 @@ }, { Name: to.StringPtr("machine-0-http"), Properties: &network.SecurityRulePropertiesFormat{ - Protocol: network.SecurityRuleProtocolAsterisk, + Protocol: network.Asterisk, DestinationPortRange: to.StringPtr("80"), Access: network.Allow, Priority: to.IntPtr(202), @@ -284,7 +284,7 @@ }, { Name: to.StringPtr("machine-00-ignored"), Properties: &network.SecurityRulePropertiesFormat{ - Protocol: network.SecurityRuleProtocolTCP, + Protocol: network.TCP, DestinationPortRange: to.StringPtr("80"), Access: network.Allow, Priority: to.IntPtr(202), @@ -293,7 +293,7 @@ }, { Name: to.StringPtr("machine-0-ignored"), Properties: &network.SecurityRulePropertiesFormat{ - Protocol: network.SecurityRuleProtocolTCP, + Protocol: network.TCP, DestinationPortRange: to.StringPtr("80"), Access: network.Deny, Priority: to.IntPtr(202), @@ -302,7 +302,7 @@ }, { Name: to.StringPtr("machine-0-ignored"), Properties: &network.SecurityRulePropertiesFormat{ - Protocol: network.SecurityRuleProtocolTCP, + Protocol: network.TCP, DestinationPortRange: to.StringPtr("80"), Access: network.Allow, Priority: to.IntPtr(202), @@ -311,7 +311,7 @@ }, { Name: to.StringPtr("machine-0-ignored"), Properties: &network.SecurityRulePropertiesFormat{ - Protocol: network.SecurityRuleProtocolTCP, + Protocol: network.TCP, DestinationPortRange: to.StringPtr("80"), Access: network.Allow, Priority: to.IntPtr(199), // internal range @@ -369,8 +369,8 @@ func (s *instanceSuite) TestInstanceOpenPorts(c *gc.C) { internalSubnetId := path.Join( "/subscriptions", fakeSubscriptionId, - "resourceGroups/arbitrary/providers/Microsoft.Network/virtualnetworks/juju-internal/subnets", - "juju-testenv-model-"+testing.ModelTag.Id(), + "resourceGroups/juju-testenv-model-deadbeef-0bad-400d-8000-4b1d0d06f00d", + "providers/Microsoft.Network/virtualnetworks/juju-internal-network/subnets/juju-internal-subnet", ) ipConfiguration := network.InterfaceIPConfiguration{ Properties: &network.InterfaceIPConfigurationPropertiesFormat{ @@ -409,7 +409,7 @@ assertRequestBody(c, s.requests[1], &network.SecurityRule{ Properties: &network.SecurityRulePropertiesFormat{ Description: to.StringPtr("1000/tcp"), - Protocol: network.SecurityRuleProtocolTCP, + Protocol: network.TCP, SourcePortRange: to.StringPtr("*"), SourceAddressPrefix: to.StringPtr("*"), DestinationPortRange: to.StringPtr("1000"), @@ -424,7 +424,7 @@ assertRequestBody(c, s.requests[2], &network.SecurityRule{ Properties: &network.SecurityRulePropertiesFormat{ Description: to.StringPtr("1000-2000/udp"), - Protocol: network.SecurityRuleProtocolUDP, + Protocol: network.UDP, SourcePortRange: to.StringPtr("*"), SourceAddressPrefix: to.StringPtr("*"), DestinationPortRange: to.StringPtr("1000-2000"), @@ -439,8 +439,8 @@ func (s *instanceSuite) TestInstanceOpenPortsAlreadyOpen(c *gc.C) { internalSubnetId := path.Join( "/subscriptions", fakeSubscriptionId, - "resourceGroups/arbitrary/providers/Microsoft.Network/virtualnetworks/juju-internal/subnets", - "juju-testenv-model-"+testing.ModelTag.Id(), + "resourceGroups/juju-testenv-model-deadbeef-0bad-400d-8000-4b1d0d06f00d", + "providers/Microsoft.Network/virtualnetworks/juju-internal-network/subnets/juju-internal-subnet", ) ipConfiguration := network.InterfaceIPConfiguration{ Properties: &network.InterfaceIPConfigurationPropertiesFormat{ @@ -460,7 +460,7 @@ nsgSender := networkSecurityGroupSender([]network.SecurityRule{{ Name: to.StringPtr("machine-0-tcp-1000"), Properties: &network.SecurityRulePropertiesFormat{ - Protocol: network.SecurityRuleProtocolAsterisk, + Protocol: network.Asterisk, DestinationPortRange: to.StringPtr("1000"), Access: network.Allow, Priority: to.IntPtr(202), @@ -488,7 +488,7 @@ assertRequestBody(c, s.requests[1], &network.SecurityRule{ Properties: &network.SecurityRulePropertiesFormat{ Description: to.StringPtr("1000-2000/udp"), - Protocol: network.SecurityRuleProtocolUDP, + Protocol: network.UDP, SourcePortRange: to.StringPtr("*"), SourceAddressPrefix: to.StringPtr("*"), DestinationPortRange: to.StringPtr("1000-2000"), @@ -508,7 +508,7 @@ var internalSecurityGroupPath = path.Join( "/subscriptions", fakeSubscriptionId, "resourceGroups", "juju-testenv-model-"+testing.ModelTag.Id(), - "providers/Microsoft.Network/networkSecurityGroups/juju-internal", + "providers/Microsoft.Network/networkSecurityGroups/juju-internal-nsg", ) func securityRulePath(ruleName string) string { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/networking.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/networking.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/networking.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/networking.go 2016-05-17 20:01:14.000000000 +0000 @@ -6,9 +6,9 @@ import ( "fmt" "net" - "net/http" "path" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/to" "github.com/Azure/azure-sdk-for-go/arm/compute" "github.com/Azure/azure-sdk-for-go/arm/network" @@ -20,21 +20,21 @@ const ( // internalNetworkName is the name of the virtual network that all - // Juju machines are connected to, so that they can communicate - // with the controllers, and with each other. + // Juju machines within a resource group are connected to. // - // Each resource group is given its own subnet and network security - // group to manage. The first resource group will be assigned the - // subnet address prefix 10.0.0.0/16, the second 10.1.0.0/16, etc., - // which allows for up to 256 enviroments/resource groups. Azure - // only supports 100, but this can be extended by contacting support; - // we can make the address prefixes configurable if necessary. - internalNetworkName = "juju-internal" + // Each resource group is given its own network, subnet and network + // security group to manage. Each resource group will have its own + // private 10.0.0.0/16 network. + internalNetworkName = "juju-internal-network" + + // internalSubnetName is the name of the subnet that each machine's + // primary NIC is attached to. + internalSubnetName = "juju-internal-subnet" // internalSecurityGroupName is the name of the network security // group that each machine's primary (internal network) NIC is // attached to. - internalSecurityGroupName = "juju-internal" + internalSecurityGroupName = "juju-internal-nsg" ) const ( @@ -62,7 +62,7 @@ Name: to.StringPtr("SSHInbound"), Properties: &network.SecurityRulePropertiesFormat{ Description: to.StringPtr("Allow SSH access to all machines"), - Protocol: network.SecurityRuleProtocolTCP, + Protocol: network.TCP, SourceAddressPrefix: to.StringPtr("*"), SourcePortRange: to.StringPtr("*"), DestinationAddressPrefix: to.StringPtr("*"), @@ -74,15 +74,13 @@ } func createInternalVirtualNetwork( + callAPI callAPIFunc, client network.ManagementClient, - controllerResourceGroup string, + resourceGroup string, location string, tags map[string]string, ) (*network.VirtualNetwork, error) { - addressPrefixes := make([]string, 256) - for i := range addressPrefixes { - addressPrefixes[i] = fmt.Sprintf("10.%d.0.0/16", i) - } + addressPrefixes := []string{"10.0.0.0/16"} virtualNetworkParams := network.VirtualNetwork{ Location: to.StringPtr(location), Tags: toTagsPtr(tags), @@ -92,10 +90,14 @@ } logger.Debugf("creating virtual network %q", internalNetworkName) vnetClient := network.VirtualNetworksClient{client} - vnet, err := vnetClient.CreateOrUpdate( - controllerResourceGroup, internalNetworkName, virtualNetworkParams, - ) - if err != nil { + var vnet network.VirtualNetwork + if err := callAPI(func() (autorest.Response, error) { + var err error + vnet, err = vnetClient.CreateOrUpdate( + resourceGroup, internalNetworkName, virtualNetworkParams, + ) + return vnet.Response, err + }); err != nil { return nil, errors.Annotatef(err, "creating virtual network %q", internalNetworkName) } return &vnet, nil @@ -104,17 +106,14 @@ // createInternalSubnet creates an internal subnet for the specified resource group, // within the specified virtual network. // -// Subnets are tied to the resource group of the virtual network, so we must create -// them all in the controller resource group. We create the network security group -// for the subnet in the environment's resource group. -// // NOTE(axw) this method expects an up-to-date VirtualNetwork, and expects that are // no concurrent subnet additions to the virtual network. At the moment we have only // three places where we modify subnets: at bootstrap, when a new environment is // created, and when an environment is destroyed. func createInternalSubnet( + callAPI callAPIFunc, client network.ManagementClient, - resourceGroup, controllerResourceGroup string, + resourceGroup string, vnet *network.VirtualNetwork, location string, tags map[string]string, @@ -154,44 +153,47 @@ securityGroupClient := network.SecurityGroupsClient{client} securityGroupName := internalSecurityGroupName logger.Debugf("creating security group %q", securityGroupName) - _, err := securityGroupClient.CreateOrUpdate( - resourceGroup, securityGroupName, securityGroupParams, - ) - if err != nil { + var nsg network.SecurityGroup + if err := callAPI(func() (autorest.Response, error) { + var err error + nsg, err = securityGroupClient.CreateOrUpdate( + resourceGroup, securityGroupName, securityGroupParams, + ) + return nsg.Response, err + }); err != nil { return nil, errors.Annotatef(err, "creating security group %q", securityGroupName) } - // Now create a subnet with the next available address prefix. The - // subnet must be created in the controller resource group, as it - // must be co-located with the vnet. - subnetName := resourceGroup + // Now create a subnet with the next available address prefix, and + // associate the subnet with the NSG created above. + subnetName := internalSubnetName subnetParams := network.Subnet{ Properties: &network.SubnetPropertiesFormat{ - AddressPrefix: to.StringPtr(nextAddressPrefix), - // NOTE(axw) we do NOT want to set the network security - // group as default for the subnet, because that will - // create a dependency from the controller resource - // group to environment resource groups. Instead, we - // set the NSG on NICs. + AddressPrefix: to.StringPtr(nextAddressPrefix), + NetworkSecurityGroup: &network.SubResource{nsg.ID}, }, } logger.Debugf("creating subnet %q (%s)", subnetName, nextAddressPrefix) subnetClient := network.SubnetsClient{client} - subnet, err := subnetClient.CreateOrUpdate( - controllerResourceGroup, internalNetworkName, subnetName, subnetParams, - ) - if err != nil { + var subnet network.Subnet + if err := callAPI(func() (autorest.Response, error) { + var err error + subnet, err = subnetClient.CreateOrUpdate( + resourceGroup, internalNetworkName, subnetName, subnetParams, + ) + return subnet.Response, err + }); err != nil { return nil, errors.Annotatef(err, "creating subnet %q", subnetName) } return &subnet, nil } func newNetworkProfile( + callAPI callAPIFunc, client network.ManagementClient, vmName string, apiPort *int, internalSubnet *network.Subnet, - nsgID string, resourceGroup string, location string, tags map[string]string, @@ -209,8 +211,14 @@ }, } publicIPAddressName := vmName + "-public-ip" - publicIPAddress, err := pipClient.CreateOrUpdate(resourceGroup, publicIPAddressName, publicIPAddressParams) - if err != nil { + var publicIPAddress network.PublicIPAddress + if err := callAPI(func() (autorest.Response, error) { + var err error + publicIPAddress, err = pipClient.CreateOrUpdate( + resourceGroup, publicIPAddressName, publicIPAddressParams, + ) + return publicIPAddress.Response, err + }); err != nil { return nil, errors.Annotatef(err, "creating public IP address for %q", vmName) } @@ -239,15 +247,14 @@ Tags: toTagsPtr(tags), Properties: &network.InterfacePropertiesFormat{ IPConfigurations: &ipConfigurations, - // We set the network security group on the NIC, rather - // than the subnet, to avoid having the controller - // resource group dependent on the environment resource - // group. - NetworkSecurityGroup: &network.SubResource{to.StringPtr(nsgID)}, }, } - primaryNic, err := nicClient.CreateOrUpdate(resourceGroup, primaryNicName, primaryNicParams) - if err != nil { + var primaryNic network.Interface + if err := callAPI(func() (autorest.Response, error) { + var err error + primaryNic, err = nicClient.CreateOrUpdate(resourceGroup, primaryNicName, primaryNicParams) + return primaryNic.Response, err + }); err != nil { return nil, errors.Annotatef(err, "creating network interface for %q", vmName) } @@ -257,8 +264,12 @@ logger.Debugf("- querying network security group") securityGroupClient := network.SecurityGroupsClient{client} securityGroupName := internalSecurityGroupName - securityGroup, err := securityGroupClient.Get(resourceGroup, securityGroupName) - if err != nil { + var securityGroup network.SecurityGroup + if err := callAPI(func() (autorest.Response, error) { + var err error + securityGroup, err = securityGroupClient.Get(resourceGroup, securityGroupName) + return securityGroup.Response, err + }); err != nil { return nil, errors.Annotate(err, "querying network security group") } @@ -281,7 +292,7 @@ Name: to.StringPtr(apiSecurityRuleName), Properties: &network.SecurityRulePropertiesFormat{ Description: to.StringPtr("Allow API access to server machines"), - Protocol: network.SecurityRuleProtocolTCP, + Protocol: network.TCP, SourceAddressPrefix: to.StringPtr("*"), SourcePortRange: to.StringPtr("*"), DestinationAddressPrefix: to.StringPtr(privateIPAddress), @@ -293,10 +304,12 @@ } logger.Debugf("- creating API network security rule") securityRuleClient := network.SecurityRulesClient{client} - _, err = securityRuleClient.CreateOrUpdate( - resourceGroup, securityGroupName, apiSecurityRuleName, apiSecurityRule, - ) - if err != nil { + if err := callAPI(func() (autorest.Response, error) { + result, err := securityRuleClient.CreateOrUpdate( + resourceGroup, securityGroupName, apiSecurityRuleName, apiSecurityRule, + ) + return result.Response, err + }); err != nil { return nil, errors.Annotate(err, "creating API network security rule") } } @@ -311,20 +324,6 @@ return &compute.NetworkProfile{&networkInterfaces}, nil } -func (env *azureEnviron) deleteInternalSubnet() error { - client := network.SubnetsClient{env.network} - subnetName := env.resourceGroup - result, err := client.Delete( - env.controllerResourceGroup, internalNetworkName, subnetName, - ) - if err != nil { - if result.Response == nil || result.StatusCode != http.StatusNotFound { - return errors.Annotatef(err, "deleting subnet %q", subnetName) - } - } - return nil -} - // nextSecurityRulePriority returns the next available priority in the given // security group within a specified range. func nextSecurityRulePriority(group network.SecurityGroup, min, max int) (int, error) { @@ -390,11 +389,11 @@ // internalSubnetId returns the Azure resource ID of the internal network // subnet for the specified resource group. -func internalSubnetId(resourceGroup, controllerResourceGroup, subscriptionId string) string { +func internalSubnetId(resourceGroup, subscriptionId string) string { return path.Join( "/subscriptions", subscriptionId, - "resourceGroups", controllerResourceGroup, + "resourceGroups", resourceGroup, "providers/Microsoft.Network/virtualNetworks", - internalNetworkName, "subnets", resourceGroup, + internalNetworkName, "subnets", internalSubnetName, ) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/storage.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/storage.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/storage.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/storage.go 2016-05-17 20:01:14.000000000 +0000 @@ -7,6 +7,7 @@ "fmt" "strings" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/to" "github.com/Azure/azure-sdk-for-go/arm/compute" azurestorage "github.com/Azure/azure-sdk-for-go/storage" @@ -591,7 +592,12 @@ results[i] = vm.err continue } - if _, err := vmsClient.CreateOrUpdate(v.env.resourceGroup, to.String(vm.vm.Name), *vm.vm); err != nil { + if err := v.env.callAPI(func() (autorest.Response, error) { + result, err := vmsClient.CreateOrUpdate( + v.env.resourceGroup, to.String(vm.vm.Name), *vm.vm, + ) + return result.Response, err + }); err != nil { results[i] = err vm.err = err continue diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/utils.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/utils.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/utils.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/utils.go 2016-05-17 20:01:14.000000000 +0000 @@ -5,9 +5,20 @@ import ( "math/rand" + "net/http" + "time" + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/to" + "github.com/juju/retry" "github.com/juju/utils" + "github.com/juju/utils/clock" +) + +const ( + retryDelay = 5 * time.Second + maxRetryDelay = 1 * time.Minute + maxRetryDuration = 5 * time.Minute ) func toTagsPtr(tags map[string]string) *map[string]*string { @@ -42,3 +53,39 @@ } return string(password) } + +// callAPIFunc is a function type that should wrap any any +// Azure Resource Manager API calls. +type callAPIFunc func(func() (autorest.Response, error)) error + +// backoffAPIRequestCaller is a type whose "call" method can +// be used as a callAPIFunc. +type backoffAPIRequestCaller struct { + clock clock.Clock +} + +// call will call the supplied function, with exponential backoff +// as long as the request returns an http.StatusTooManyRequests +// status. +func (c backoffAPIRequestCaller) call(f func() (autorest.Response, error)) error { + var resp *http.Response + return retry.Call(retry.CallArgs{ + Func: func() error { + autorestResp, err := f() + resp = autorestResp.Response + return err + }, + IsFatalError: func(err error) bool { + return resp == nil || !autorest.ResponseHasStatusCode(resp, http.StatusTooManyRequests) + }, + NotifyFunc: func(err error, attempt int) { + logger.Debugf("attempt %d: %v", attempt, err) + }, + Attempts: -1, + Delay: retryDelay, + MaxDelay: maxRetryDelay, + MaxDuration: maxRetryDuration, + BackoffFunc: retry.DoubleDelay, + Clock: c.clock, + }) +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/vmextension.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/vmextension.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/azure/vmextension.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/azure/vmextension.go 2016-05-17 20:01:14.000000000 +0000 @@ -1,6 +1,7 @@ package azure import ( + "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest" "github.com/Azure/azure-sdk-for-go/Godeps/_workspace/src/github.com/Azure/go-autorest/autorest/to" "github.com/Azure/azure-sdk-for-go/arm/compute" "github.com/juju/errors" @@ -31,6 +32,7 @@ // createVMExtension creates a CustomScript VM extension for the given VM // which will execute the CustomData on the machine as a script. func createVMExtension( + callAPI callAPIFunc, vmExtensionClient compute.VirtualMachineExtensionsClient, os jujuos.OSType, resourceGroup, vmName, location string, vmTags map[string]string, ) error { @@ -54,8 +56,8 @@ return errors.NotSupportedf("CustomScript extension for OS %q", os) } - extensionSettings := map[string]*string{ - "commandToExecute": to.StringPtr(commandToExecute), + extensionSettings := map[string]interface{}{ + "commandToExecute": commandToExecute, } extension := compute.VirtualMachineExtension{ Location: to.StringPtr(location), @@ -68,8 +70,11 @@ Settings: &extensionSettings, }, } - _, err := vmExtensionClient.CreateOrUpdate( - resourceGroup, vmName, extensionName, extension, - ) + err := callAPI(func() (autorest.Response, error) { + result, err := vmExtensionClient.CreateOrUpdate( + resourceGroup, vmName, extensionName, extension, + ) + return result.Response, err + }) return err } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/common/bootstrap.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/common/bootstrap.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/common/bootstrap.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/common/bootstrap.go 2016-05-17 20:01:14.000000000 +0000 @@ -317,19 +317,17 @@ done <- connectSSH(hc.client, address, hc.checkHostScript) }() select { - case <-hc.closed: - return hc, lastErr case <-dying: return hc, lastErr case lastErr = <-done: if lastErr == nil { return hc, nil - } else { - logger.Debugf("connection attempt for %s failed: %v", address, lastErr) } + logger.Debugf("connection attempt for %s failed: %v", address, lastErr) } select { case <-hc.closed: + return hc, lastErr case <-dying: case <-time.After(hc.checkDelay): } @@ -403,7 +401,7 @@ return err } -// waitSSH waits for the instance to be assigned a routable +// WaitSSH waits for the instance to be assigned a routable // address, then waits until we can connect to it via SSH. // // waitSSH attempts on all addresses returned by the instance diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/dummy/environs.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/dummy/environs.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/dummy/environs.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/dummy/environs.go 2016-05-17 20:01:14.000000000 +0000 @@ -38,6 +38,7 @@ gitjujutesting "github.com/juju/testing" jc "github.com/juju/testing/checkers" "github.com/juju/utils/arch" + "github.com/juju/utils/series" gc "gopkg.in/check.v1" "gopkg.in/juju/environschema.v1" @@ -51,6 +52,7 @@ "github.com/juju/juju/environs/config" "github.com/juju/juju/instance" "github.com/juju/juju/mongo" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/network" "github.com/juju/juju/provider/common" "github.com/juju/juju/state" @@ -86,7 +88,7 @@ "development": false, "state-port": 1234, "api-port": 4321, - "default-series": config.LatestLtsSeries(), + "default-series": series.LatestLts(), "secret": "pork", "controller": true, @@ -736,7 +738,7 @@ // It is set just below. st, err := state.Initialize( names.NewUserTag("admin@local"), info, cfg, - mongo.DefaultDialOpts(), estate.statePolicy) + mongotest.DialOpts(), estate.statePolicy) if err != nil { panic(err) } @@ -842,7 +844,15 @@ } return err } - defer func() { estate.ops <- OpDestroy{Env: estate.name, Error: res} }() + defer func() { + // The estate is a pointer to a structure that is stored in the dummy global. + // The Listen method can change the ops channel of any state, and will do so + // under the covers. What we need to do is use the state mutex to add a memory + // barrier such that the ops channel we see here is the latest. + estate.mu.Lock() + defer estate.mu.Unlock() + estate.ops <- OpDestroy{Env: estate.name, Error: res} + }() if err := e.checkBroken("Destroy"); err != nil { return err } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/config.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/config.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/config.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/config.go 2016-05-17 20:01:14.000000000 +0000 @@ -5,6 +5,7 @@ import ( "fmt" + "strings" "github.com/juju/schema" "gopkg.in/amz.v3/aws" @@ -33,6 +34,19 @@ Description: "The EC2 region to use", Type: environschema.Tstring, }, + "vpc-id": { + Description: "Use a specific AWS VPC ID (optional). When not specified, Juju requires a default VPC to exist the chosen EC2 account/region.", + Example: "vpc-a1b2c3d4", + Type: environschema.Tstring, + Group: environschema.AccountGroup, + Immutable: true, + }, + "vpc-id-force": { + Description: "Force Juju to use the AWS VPC ID specified with vpc-id, when it fails the minimum validation criteria. Not accepted without vpc-id", + Type: environschema.Tbool, + Group: environschema.AccountGroup, + Immutable: true, + }, } var configFields = func() schema.Fields { @@ -44,9 +58,11 @@ }() var configDefaults = schema.Defaults{ - "access-key": "", - "secret-key": "", - "region": "us-east-1", + "access-key": "", + "secret-key": "", + "region": "us-east-1", + "vpc-id": "", + "vpc-id-force": false, } type environConfig struct { @@ -66,6 +82,14 @@ return c.attrs["secret-key"].(string) } +func (c *environConfig) vpcID() string { + return c.attrs["vpc-id"].(string) +} + +func (c *environConfig) forceVPCID() bool { + return c.attrs["vpc-id-force"].(bool) +} + func (p environProvider) newConfig(cfg *config.Config) (*environConfig, error) { valid, err := p.Validate(cfg, nil) if err != nil { @@ -102,15 +126,30 @@ ecfg.attrs["access-key"] = auth.AccessKey ecfg.attrs["secret-key"] = auth.SecretKey } + if _, ok := aws.Regions[ecfg.region()]; !ok { return nil, fmt.Errorf("invalid region name %q", ecfg.region()) } + if vpcID := ecfg.vpcID(); vpcID != "" && !strings.HasPrefix(vpcID, "vpc-") { + return nil, fmt.Errorf("vpc-id: %q is not a valid AWS VPC ID", vpcID) + } else if vpcID == "" && ecfg.forceVPCID() { + return nil, fmt.Errorf("cannot use vpc-id-force without specifying vpc-id as well") + } + if old != nil { attrs := old.UnknownAttrs() if region, _ := attrs["region"].(string); ecfg.region() != region { return nil, fmt.Errorf("cannot change region from %q to %q", region, ecfg.region()) } + + if vpcID, _ := attrs["vpc-id"].(string); vpcID != ecfg.vpcID() { + return nil, fmt.Errorf("cannot change vpc-id from %q to %q", vpcID, ecfg.vpcID()) + } + + if forceVPCID, _ := attrs["vpc-id-force"].(bool); forceVPCID != ecfg.forceVPCID() { + return nil, fmt.Errorf("cannot change vpc-id-force from %v to %v", forceVPCID, ecfg.forceVPCID()) + } } // ssl-hostname-verification cannot be disabled diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/config_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/config_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/config_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/config_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -36,7 +36,10 @@ EC2Endpoint: "testregion.nowhere:1234", } -var testAuth = aws.Auth{"gopher", "long teeth"} +var testAuth = aws.Auth{ + AccessKey: "gopher", + SecretKey: "long teeth", +} // configTest specifies a config parsing test, checking that env when // parsed as the ec2 section of a config file matches baseConfigResult @@ -47,6 +50,8 @@ change map[string]interface{} expect map[string]interface{} region string + vpcID string + forceVPCID bool accessKey string secretKey string firewallMode string @@ -90,6 +95,10 @@ if t.region != "" { c.Assert(ecfg.region(), gc.Equals, t.region) } + + c.Assert(ecfg.vpcID(), gc.Equals, t.vpcID) + c.Assert(ecfg.forceVPCID(), gc.Equals, t.forceVPCID) + if t.accessKey != "" { c.Assert(ecfg.accessKey(), gc.Equals, t.accessKey) c.Assert(ecfg.secretKey(), gc.Equals, t.secretKey) @@ -151,6 +160,117 @@ }, err: `.*expected string, got int\(666\)`, }, { + config: attrs{}, + vpcID: "", + forceVPCID: false, + }, { + config: attrs{ + "vpc-id": "invalid", + }, + err: `.*vpc-id: "invalid" is not a valid AWS VPC ID`, + vpcID: "", + forceVPCID: false, + }, { + config: attrs{ + "vpc-id": 42, + }, + err: `.*expected string, got int\(42\)`, + vpcID: "", + forceVPCID: false, + }, { + config: attrs{ + "vpc-id-force": "nonsense", + }, + err: `.*expected bool, got string\("nonsense"\)`, + vpcID: "", + forceVPCID: false, + }, { + config: attrs{ + "vpc-id": "vpc-anything", + "vpc-id-force": 999, + }, + err: `.*expected bool, got int\(999\)`, + vpcID: "", + forceVPCID: false, + }, { + config: attrs{ + "vpc-id": "", + "vpc-id-force": true, + }, + err: `.*cannot use vpc-id-force without specifying vpc-id as well`, + vpcID: "", + forceVPCID: true, + }, { + config: attrs{ + "vpc-id": "vpc-a1b2c3d4", + }, + vpcID: "vpc-a1b2c3d4", + forceVPCID: false, + }, { + config: attrs{ + "vpc-id": "vpc-some-id", + "vpc-id-force": true, + }, + vpcID: "vpc-some-id", + forceVPCID: true, + }, { + config: attrs{ + "vpc-id": "vpc-abcd", + "vpc-id-force": false, + }, + vpcID: "vpc-abcd", + forceVPCID: false, + }, { + config: attrs{ + "vpc-id": "vpc-unchanged", + "vpc-id-force": true, + }, + change: attrs{ + "vpc-id": "vpc-unchanged", + "vpc-id-force": false, + }, + err: `.*cannot change vpc-id-force from true to false`, + vpcID: "vpc-unchanged", + forceVPCID: true, + }, { + config: attrs{ + "vpc-id": "", + }, + change: attrs{ + "vpc-id": "vpc-changed", + }, + err: `.*cannot change vpc-id from "" to "vpc-changed"`, + vpcID: "", + forceVPCID: false, + }, { + config: attrs{ + "vpc-id": "vpc-initial", + }, + change: attrs{ + "vpc-id": "", + }, + err: `.*cannot change vpc-id from "vpc-initial" to ""`, + vpcID: "vpc-initial", + forceVPCID: false, + }, { + config: attrs{ + "vpc-id": "vpc-old", + }, + change: attrs{ + "vpc-id": "vpc-new", + }, + err: `.*cannot change vpc-id from "vpc-old" to "vpc-new"`, + vpcID: "vpc-old", + forceVPCID: false, + }, { + config: attrs{ + "vpc-id": "vpc-foo", + "vpc-id-force": true, + }, + change: attrs{}, + vpcID: "vpc-foo", + forceVPCID: true, + }, { config: attrs{ "access-key": 666, }, @@ -251,14 +371,16 @@ err = ioutil.WriteFile(filepath.Join(sshDir, "id_rsa.pub"), []byte("sshkey\n"), 0666) c.Assert(err, jc.ErrorIsNil) - utils.SetHome(home) + err = utils.SetHome(home) + c.Assert(err, jc.ErrorIsNil) os.Setenv("AWS_ACCESS_KEY_ID", testAuth.AccessKey) os.Setenv("AWS_SECRET_ACCESS_KEY", testAuth.SecretKey) aws.Regions["configtest"] = configTestRegion } func (s *ConfigSuite) TearDownTest(c *gc.C) { - utils.SetHome(s.savedHome) + err := utils.SetHome(s.savedHome) + c.Assert(err, jc.ErrorIsNil) os.Setenv("AWS_ACCESS_KEY_ID", s.savedAccessKey) os.Setenv("AWS_SECRET_ACCESS_KEY", s.savedSecretKey) delete(aws.Regions, "configtest") diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/credentials_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/credentials_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/credentials_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/credentials_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -59,9 +59,11 @@ func (s *credentialsSuite) TestDetectCredentialsEnvironmentVariables(c *gc.C) { home := utils.Home() dir := c.MkDir() - utils.SetHome(dir) + err := utils.SetHome(dir) + c.Assert(err, jc.ErrorIsNil) s.AddCleanup(func(*gc.C) { - utils.SetHome(home) + err := utils.SetHome(home) + c.Assert(err, jc.ErrorIsNil) }) s.PatchEnvironment("USER", "fred") s.PatchEnvironment("AWS_ACCESS_KEY_ID", "key-id") @@ -123,9 +125,11 @@ } home := utils.Home() dir := c.MkDir() - utils.SetHome(dir) + err := utils.SetHome(dir) + c.Assert(err, jc.ErrorIsNil) s.AddCleanup(func(*gc.C) { - utils.SetHome(home) + err := utils.SetHome(home) + c.Assert(err, jc.ErrorIsNil) }) s.assertDetectCredentialsKnownLocation(c, dir) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/ebs.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/ebs.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/ebs.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/ebs.go 2016-05-17 20:01:14.000000000 +0000 @@ -48,6 +48,8 @@ volumeTypeStandard = "standard" volumeTypeGp2 = "gp2" volumeTypeIo1 = "io1" + + rootDiskDeviceName = "/dev/sda1" ) // AWS error codes @@ -361,13 +363,31 @@ func (v *ebsVolumeSource) ListVolumes() ([]string, error) { filter := ec2.NewFilter() filter.Add("tag:"+tags.JujuModel, v.modelUUID) - resp, err := v.ec2.Volumes(nil, filter) + return listVolumes(v.ec2, filter) +} + +func listVolumes(client *ec2.EC2, filter *ec2.Filter) ([]string, error) { + resp, err := client.Volumes(nil, filter) if err != nil { return nil, err } - volumeIds := make([]string, len(resp.Volumes)) - for i, vol := range resp.Volumes { - volumeIds[i] = vol.Id + volumeIds := make([]string, 0, len(resp.Volumes)) + for _, vol := range resp.Volumes { + var isRootDisk bool + for _, att := range vol.Attachments { + if att.Device == rootDiskDeviceName { + isRootDisk = true + break + } + } + if isRootDisk { + // We don't want to list root disks in the output. + // These are managed by the instance provisioning + // code; they will be created and destroyed with + // instances. + continue + } + volumeIds = append(volumeIds, vol.Id) } return volumeIds, nil } @@ -410,17 +430,21 @@ // DestroyVolumes is specified on the storage.VolumeSource interface. func (v *ebsVolumeSource) DestroyVolumes(volIds []string) ([]error, error) { + return destroyVolumes(v.ec2, volIds), nil +} + +func destroyVolumes(client *ec2.EC2, volIds []string) []error { var wg sync.WaitGroup wg.Add(len(volIds)) results := make([]error, len(volIds)) for i, volumeId := range volIds { go func(i int, volumeId string) { defer wg.Done() - results[i] = v.destroyVolume(volumeId) + results[i] = destroyVolume(client, volumeId) }(i, volumeId) } wg.Wait() - return results, nil + return results } var destroyVolumeAttempt = utils.AttemptStrategy{ @@ -428,7 +452,7 @@ Delay: 5 * time.Second, } -func (v *ebsVolumeSource) destroyVolume(volumeId string) (err error) { +func destroyVolume(client *ec2.EC2, volumeId string) (err error) { defer func() { if err != nil { if ec2ErrCode(err) == volumeNotFound || errors.IsNotFound(err) { @@ -446,7 +470,7 @@ // Volumes must not be in-use when destroying. A volume may // still be in-use when the instance it is attached to is // in the process of being terminated. - volume, err := v.waitVolume(volumeId, destroyVolumeAttempt, func(volume *ec2.Volume) (bool, error) { + volume, err := waitVolume(client, volumeId, destroyVolumeAttempt, func(volume *ec2.Volume) (bool, error) { if volume.Status != volumeStatusInUse { // Volume is not in use, it should be OK to destroy now. return true, nil @@ -488,7 +512,7 @@ } } if len(deleteOnTermination) > 0 { - result, err := v.ec2.Instances(deleteOnTermination, nil) + result, err := client.Instances(deleteOnTermination, nil) if err != nil { return false, errors.Trace(err) } @@ -507,7 +531,7 @@ if len(args) == 0 { return false, nil } - results, err := v.DetachVolumes(args) + results, err := detachVolumes(client, args) if err != nil { return false, errors.Trace(err) } @@ -530,7 +554,7 @@ // nothing more to do. return nil } - if _, err := v.ec2.DeleteVolume(volumeId); err != nil { + if _, err := client.DeleteVolume(volumeId); err != nil { return errors.Annotatef(err, "destroying %q", volumeId) } return nil @@ -688,7 +712,7 @@ Delay: 200 * time.Millisecond, } var lastStatus string - volume, err := v.waitVolume(volumeId, attempt, func(volume *ec2.Volume) (bool, error) { + volume, err := waitVolume(v.ec2, volumeId, attempt, func(volume *ec2.Volume) (bool, error) { lastStatus = volume.Status return volume.Status != volumeStatusCreating, nil }) @@ -705,13 +729,14 @@ var errWaitVolumeTimeout = errors.New("timed out") -func (v *ebsVolumeSource) waitVolume( +func waitVolume( + client *ec2.EC2, volumeId string, attempt utils.AttemptStrategy, pred func(v *ec2.Volume) (bool, error), ) (*ec2.Volume, error) { for a := attempt.Start(); a.Next(); { - volume, err := v.describeVolume(volumeId) + volume, err := describeVolume(client, volumeId) if err != nil { return nil, errors.Trace(err) } @@ -726,8 +751,8 @@ return nil, errWaitVolumeTimeout } -func (v *ebsVolumeSource) describeVolume(volumeId string) (*ec2.Volume, error) { - resp, err := v.ec2.Volumes([]string{volumeId}, nil) +func describeVolume(client *ec2.EC2, volumeId string) (*ec2.Volume, error) { + resp, err := client.Volumes([]string{volumeId}, nil) if err != nil { return nil, errors.Annotate(err, "querying volume") } @@ -772,9 +797,13 @@ // DetachVolumes is specified on the storage.VolumeSource interface. func (v *ebsVolumeSource) DetachVolumes(attachParams []storage.VolumeAttachmentParams) ([]error, error) { + return detachVolumes(v.ec2, attachParams) +} + +func detachVolumes(client *ec2.EC2, attachParams []storage.VolumeAttachmentParams) ([]error, error) { results := make([]error, len(attachParams)) for i, params := range attachParams { - _, err := v.ec2.DetachVolume(params.VolumeId, string(params.InstanceId), "", false) + _, err := client.DetachVolume(params.VolumeId, string(params.InstanceId), "", false) // Process aws specific error information. if err != nil { if ec2Err, ok := err.(*ec2.Error); ok { @@ -855,7 +884,7 @@ } // The first block device is for the root disk. blockDeviceMappings := []ec2.BlockDeviceMapping{{ - DeviceName: "/dev/sda1", + DeviceName: rootDiskDeviceName, VolumeSize: int64(mibToGib(rootDiskSizeMiB)), }} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/ebs_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/ebs_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/ebs_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/ebs_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -13,6 +13,7 @@ "github.com/juju/names" jc "github.com/juju/testing/checkers" "github.com/juju/utils/arch" + "github.com/juju/utils/clock" "github.com/juju/utils/series" awsec2 "gopkg.in/amz.v3/ec2" "gopkg.in/amz.v3/ec2/ec2test" @@ -105,7 +106,7 @@ s.BaseSuite.SetUpTest(c) s.BaseSuite.PatchValue(&jujuversion.Current, testing.FakeVersionNumber) s.BaseSuite.PatchValue(&arch.HostArch, func() string { return arch.AMD64 }) - s.BaseSuite.PatchValue(&series.HostSeries, func() string { return testing.FakeDefaultSeries }) + s.BaseSuite.PatchValue(&series.HostSeries, func() string { return series.LatestLts() }) s.srv.startServer(c) s.Tests.SetUpTest(c) s.PatchValue(&ec2.DestroyVolumeAttempt.Delay, time.Duration(0)) @@ -215,7 +216,7 @@ c.Assert(ec2Vols.Volumes[2].Size, gc.Equals, 30) } -var deleteSecurityGroupForTestFunc = func(inst ec2.SecurityGroupCleaner, group awsec2.SecurityGroup) error { +var deleteSecurityGroupForTestFunc = func(inst ec2.SecurityGroupCleaner, group awsec2.SecurityGroup, _ clock.Clock) error { // With an exponential retry for deleting security groups, // we never return from local live tests. // No need to re-try in tests anyway - just call delete. @@ -426,6 +427,22 @@ c.Assert(volIds, jc.SameContents, []string{"vol-0"}) } +func (s *ebsVolumeSuite) TestListVolumesIgnoresRootDisks(c *gc.C) { + s.srv.ec2srv.SetCreateRootDisks(true) + s.srv.ec2srv.NewInstances(1, "m1.medium", imageId, ec2test.Pending, nil) + + // Tag the root disk with the model UUID. + _, err := s.srv.client.CreateTags([]string{"vol-0"}, []awsec2.Tag{ + {tags.JujuModel, s.TestConfig["uuid"].(string)}, + }) + c.Assert(err, jc.ErrorIsNil) + + vs := s.volumeSource(c, nil) + volIds, err := vs.ListVolumes() + c.Assert(err, jc.ErrorIsNil) + c.Assert(volIds, gc.HasLen, 0) +} + func (s *ebsVolumeSuite) TestCreateVolumesErrors(c *gc.C) { vs := s.volumeSource(c, nil) volume0 := names.NewVolumeTag("0") diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/environ.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/environ.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/environ.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/environ.go 2016-05-17 20:01:14.000000000 +0000 @@ -5,6 +5,7 @@ import ( "fmt" + "math/rand" "net" "strings" "sync" @@ -33,12 +34,10 @@ "github.com/juju/juju/network" "github.com/juju/juju/provider" "github.com/juju/juju/provider/common" - "github.com/juju/juju/state" "github.com/juju/juju/tools" ) const ( - none = "none" invalidParameterValue = "InvalidParameterValue" privateAddressLimitExceeded = "PrivateIpAddressLimitExceeded" @@ -47,11 +46,17 @@ tagName = "Name" ) -// Use shortAttempt to poll for short-term events or for retrying API calls. -var shortAttempt = utils.AttemptStrategy{ - Total: 5 * time.Second, - Delay: 200 * time.Millisecond, -} +var ( + // Use shortAttempt to poll for short-term events or for retrying API calls. + shortAttempt = utils.AttemptStrategy{ + Total: 5 * time.Second, + Delay: 200 * time.Millisecond, + } + + // aliveInstanceStates are the states which we filter by when listing + // instances in an environment. + aliveInstanceStates = []string{"pending", "running"} +) type environ struct { common.SupportsUnitPlacementPolicy @@ -73,19 +78,8 @@ availabilityZonesMutex sync.Mutex availabilityZones []common.AvailabilityZone - // cachedDefaultVpc caches the id of the ec2 default vpc - cachedDefaultVpc *defaultVpc -} - -// Ensure EC2 provider supports environs.NetworkingEnviron. -var _ environs.NetworkingEnviron = (*environ)(nil) -var _ simplestreams.HasRegion = (*environ)(nil) -var _ state.Prechecker = (*environ)(nil) -var _ state.InstanceDistributor = (*environ)(nil) - -type defaultVpc struct { - hasDefaultVpc bool - id network.Id + allocationMutex sync.Mutex + allocationSupported *bool } // AssignPrivateIPAddress is a wrapper around ec2Inst.AssignPrivateIPAddresses. @@ -108,7 +102,10 @@ return nil, nil, nil, err } - auth := aws.Auth{ecfg.accessKey(), ecfg.secretKey()} + auth := aws.Auth{ + AccessKey: ecfg.accessKey(), + SecretKey: ecfg.secretKey(), + } region := aws.Regions[ecfg.region()] signer := aws.SignV4Factory(region.Name, "ec2") return ec2.New(auth, region, signer), s3.New(auth, region), ecfg, nil @@ -119,6 +116,7 @@ if err != nil { return err } + e.ecfgMutex.Lock() defer e.ecfgMutex.Unlock() e.ecfgUnlocked = ecfg @@ -128,38 +126,6 @@ return nil } -func (e *environ) defaultVpc() (network.Id, bool, error) { - if e.cachedDefaultVpc != nil { - defaultVpc := e.cachedDefaultVpc - return defaultVpc.id, defaultVpc.hasDefaultVpc, nil - } - ec2 := e.ec2() - resp, err := ec2.AccountAttributes("default-vpc") - if err != nil { - return "", false, errors.Trace(err) - } - - hasDefault := true - defaultVpcId := "" - - if len(resp.Attributes) == 0 || len(resp.Attributes[0].Values) == 0 { - hasDefault = false - defaultVpcId = "" - } else { - defaultVpcId = resp.Attributes[0].Values[0] - if defaultVpcId == none { - hasDefault = false - defaultVpcId = "" - } - } - defaultVpc := &defaultVpc{ - id: network.Id(defaultVpcId), - hasDefaultVpc: hasDefault, - } - e.cachedDefaultVpc = defaultVpc - return defaultVpc.id, defaultVpc.hasDefaultVpc, nil -} - func (e *environ) ecfg() *environConfig { e.ecfgMutex.Lock() ecfg := e.ecfgUnlocked @@ -182,36 +148,6 @@ return common.Bootstrap(ctx, e, args) } -func (e *environ) ControllerInstances() ([]instance.Id, error) { - filter := ec2.NewFilter() - filter.Add("instance-state-name", "pending", "running") - filter.Add(fmt.Sprintf("tag:%s", tags.JujuModel), e.Config().UUID()) - filter.Add(fmt.Sprintf("tag:%s", tags.JujuIsController), "true") - err := e.addGroupFilter(filter) - if err != nil { - if ec2ErrCode(err) == "InvalidGroup.NotFound" { - return nil, environs.ErrNotBootstrapped - } - return nil, errors.Annotate(err, "adding a group filter for instances") - } - resp, err := e.ec2().Instances(nil, filter) - if err != nil { - return nil, errors.Annotate(err, "listing instances") - } - var insts []instance.Id - for _, r := range resp.Reservations { - for i := range r.Instances { - inst := &ec2Instance{ - e: e, - Instance: &r.Instances[i], - } - insts = append(insts, inst.Id()) - } - } - return insts, nil - -} - // SupportedArchitectures is specified on the EnvironCapability interface. func (e *environ) SupportedArchitectures() ([]string, error) { e.archMutex.Lock() @@ -244,14 +180,28 @@ // SupportsAddressAllocation is specified on environs.Networking. func (e *environ) SupportsAddressAllocation(_ network.Id) (bool, error) { - if !environs.AddressAllocationEnabled(provider.EC2) { - return false, errors.NotSupportedf("address allocation") + e.allocationMutex.Lock() + defer e.allocationMutex.Unlock() + + if e.allocationSupported == nil { + var notSupported bool + e.allocationSupported = ¬Supported + + if environs.AddressAllocationEnabled(provider.EC2) { + defaultVPCID, err := findDefaultVPCID(e.ec2()) + if err == nil { + logger.Infof("legacy address allocation supported with default VPC %q", defaultVPCID) + *e.allocationSupported = true + } else if errors.IsNotFound(err) { + logger.Infof("legacy address allocation not supported without a default VPC") + } + } } - _, hasDefaultVpc, err := e.defaultVpc() - if err != nil { - return false, errors.Trace(err) + + if *e.allocationSupported { + return true, nil } - return hasDefaultVpc, nil + return false, errors.NotSupportedf("address allocation") } var unsupportedConstraints = []string{ @@ -304,7 +254,7 @@ } func (z *ec2AvailabilityZone) Available() bool { - return z.AvailabilityZoneInfo.State == "available" + return z.AvailabilityZoneInfo.State == availableState } // AvailabilityZones returns a slice of availability zones @@ -472,7 +422,7 @@ if err != nil { return nil, err } - if placement.availabilityZone.State != "available" { + if placement.availabilityZone.State != availableState { return nil, errors.Errorf("availability zone %q is %s", placement.availabilityZone.Name, placement.availabilityZone.State) } availabilityZones = append(availabilityZones, placement.availabilityZone.Name) @@ -554,25 +504,8 @@ // distributed across AZs, but only within subnets of the space constraint. // // TODO(dimitern): This should be done in a provider-independant way. - zonesToSubnets := make(map[string]string, len(args.SubnetsToZones)) - var spaceSubnetIDs []string - for subnetID, zones := range args.SubnetsToZones { - // EC2-specific: subnets can only be in a single zone, hence the - // zones slice will always contain exactly one element when - // SubnetsToZones is populated. - zone := zones[0] - sid := string(subnetID) - zonesToSubnets[zone] = sid - spaceSubnetIDs = append(spaceSubnetIDs, sid) - } - - // TODO(dimitern): For the network model MVP we only respect the - // first positive (a.k.a. "included") space specified in the - // constraints. Once we support any given list of positive or - // negative (prefixed with "^") spaces, fix this approach. - var spaceName string - if spaces := args.Constraints.IncludeSpaces(); len(spaces) > 0 { - spaceName = spaces[0] + if spaces := args.Constraints.IncludeSpaces(); len(spaces) > 1 { + logger.Infof("ignoring all but the first positive space from constraints: %v", spaces) } var instResp *ec2.RunInstancesResp @@ -588,36 +521,43 @@ for _, zone := range availabilityZones { runArgs := commonRunArgs + runArgs.AvailZone = zone - if subnetID, found := zonesToSubnets[zone]; found { - // Use SubnetId explicitly here so the instance ends up in the - // right space. - runArgs.SubnetId = subnetID - } else if spaceName != "" { - // Ignore AZs not matching any subnet of the space in constraints. + var subnetIDsForZone []string + var subnetErr error + if e.ecfg().vpcID() != "" && !args.Constraints.HaveSpaces() { + subnetIDsForZone, subnetErr = getVPCSubnetIDsForAvailabilityZone(e.ec2(), e.ecfg().vpcID(), zone) + } else if e.ecfg().vpcID() == "" && args.Constraints.HaveSpaces() { + subnetIDsForZone, subnetErr = findSubnetIDsForAvailabilityZone(zone, args.SubnetsToZones) + } + + switch { + case subnetErr != nil && errors.IsNotFound(subnetErr): + logger.Infof("no matching subnets in zone %q; assuming zone is constrained and trying another", zone) + continue + case subnetErr != nil: + return nil, errors.Annotatef(subnetErr, "getting subnets for zone %q", zone) + case len(subnetIDsForZone) > 1: + // With multiple equally suitable subnets, picking one at random + // will allow for better instance spread within the same zone, and + // still work correctly if we happen to pick a constrained subnet + // (we'll just treat this the same way we treat constrained zones + // and retry). + runArgs.SubnetId = subnetIDsForZone[rand.Intn(len(subnetIDsForZone))] logger.Infof( - "skipping zone %q: not associated with any of space %q's subnets %q", - zone, spaceName, strings.Join(spaceSubnetIDs, ", "), + "selected random subnet %q from all matching in zone %q: %v", + runArgs.SubnetId, zone, subnetIDsForZone, ) - continue - } else { - // No space constraint specified, just use the usual zone - // distribution without an explicit SubnetId. - runArgs.AvailZone = zone + case len(subnetIDsForZone) == 1: + runArgs.SubnetId = subnetIDsForZone[0] + logger.Infof("selected subnet %q in zone %q", runArgs.SubnetId, zone) } instResp, err = runInstances(e.ec2(), runArgs) - if err == nil { - break - } - if runArgs.SubnetId != "" && isSubnetConstrainedError(err) { - subID := runArgs.SubnetId - logger.Infof("%q (in zone %q) is constrained, try another subnet", subID, zone) - continue - } else if !isZoneConstrainedError(err) { - // Something else went wrong - bail out. + if err == nil || !isZoneOrSubnetConstrainedError(err) { break } + logger.Infof("%q is constrained, trying another availability zone", zone) } @@ -633,7 +573,8 @@ Instance: &instResp.Instances[0], } instAZ, instSubnet := inst.Instance.AvailZone, inst.Instance.SubnetId - logger.Infof("started instance %q in AZ %q, subnet %q", inst.Id(), instAZ, instSubnet) + chosenVPCID := e.ecfg().vpcID() + logger.Infof("started instance %q in AZ %q, subnet %q, VPC %q", inst.Id(), instAZ, instSubnet, chosenVPCID) // Tag instance, for accounting and identification. instanceName := resourceName( @@ -737,7 +678,7 @@ func _runInstances(e *ec2.EC2, ri *ec2.RunInstances) (resp *ec2.RunInstancesResp, err error) { for a := shortAttempt.Start(); a.Next(); { resp, err = e.RunInstances(ri) - if err == nil || ec2ErrCode(err) != "InvalidGroup.NotFound" { + if err == nil || !isNotFoundError(err) { break } } @@ -751,15 +692,16 @@ // groupInfoByName returns information on the security group // with the given name including rules and other details. func (e *environ) groupInfoByName(groupName string) (ec2.SecurityGroupInfo, error) { - // Non-default VPC does not support name-based group lookups, can - // use a filter by group name instead when support is needed. - limitToGroups := []ec2.SecurityGroup{{Name: groupName}} - resp, err := e.ec2().SecurityGroups(limitToGroups, nil) + resp, err := e.securityGroupsByNameOrID(groupName) if err != nil { return ec2.SecurityGroupInfo{}, err } + if len(resp.Groups) != 1 { - return ec2.SecurityGroupInfo{}, fmt.Errorf("expected one security group named %q, got %v", groupName, resp.Groups) + return ec2.SecurityGroupInfo{}, errors.NewNotFound(fmt.Errorf( + "expected one security group named %q, got %v", + groupName, resp.Groups, + ), "") } return resp.Groups[0], nil } @@ -770,51 +712,63 @@ return groupInfo.SecurityGroup, err } -// addGroupFilter sets a limit an instance filter so only those machines -// with the juju environment wide security group associated will be listed. -// -// An EC2 API call is required to resolve the group name to an id, as VPC -// enabled accounts do not support name based filtering. -// TODO: Detect classic accounts and just filter by name for those. -// -// Callers must handle InvalidGroup.NotFound errors to mean the same as no -// matching instances. -func (e *environ) addGroupFilter(filter *ec2.Filter) error { - groupName := e.jujuGroupName() - group, err := e.groupByName(groupName) - if err != nil { - return err - } - // EC2 should support filtering with and without the 'instance.' - // prefix, but only the form with seems to work with default VPC. - filter.Add("instance.group-id", group.Id) - return nil +// isNotFoundError returns whether err is a typed NotFoundError or an EC2 error +// code for "group not found", indicating no matching instances (as they are +// filtered by group). +func isNotFoundError(err error) bool { + return err != nil && (errors.IsNotFound(err) || ec2ErrCode(err) == "InvalidGroup.NotFound") } -// gatherInstances tries to get information on each instance -// id whose corresponding insts slot is nil. -// It returns environs.ErrPartialInstances if the insts -// slice has not been completely filled. -func (e *environ) gatherInstances(ids []instance.Id, insts []instance.Instance) error { - var need []string - for i, inst := range insts { - if inst == nil { - need = append(need, string(ids[i])) +// Instances is part of the environs.Environ interface. +func (e *environ) Instances(ids []instance.Id) ([]instance.Instance, error) { + if len(ids) == 0 { + return nil, nil + } + insts := make([]instance.Instance, len(ids)) + // Make a series of requests to cope with eventual consistency. + // Each request will attempt to add more instances to the requested + // set. + var err error + for a := shortAttempt.Start(); a.Next(); { + var need []string + for i, inst := range insts { + if inst == nil { + need = append(need, string(ids[i])) + } + } + filter := ec2.NewFilter() + filter.Add("instance-state-name", aliveInstanceStates...) + filter.Add("instance-id", need...) + e.addModelFilter(filter) + err = e.gatherInstances(ids, insts, filter) + if err == nil || err != environs.ErrPartialInstances { + break } } - if len(need) == 0 { - return nil + if err == environs.ErrPartialInstances { + for _, inst := range insts { + if inst != nil { + return insts, environs.ErrPartialInstances + } + } + return nil, environs.ErrNoInstances } - filter := ec2.NewFilter() - filter.Add("instance-state-name", "pending", "running") - err := e.addGroupFilter(filter) if err != nil { - if ec2ErrCode(err) == "InvalidGroup.NotFound" { - return environs.ErrPartialInstances - } - return err + return nil, err } - filter.Add("instance-id", need...) + return insts, nil +} + +// gatherInstances tries to get information on each instance +// id whose corresponding insts slot is nil. +// +// This function returns environs.ErrPartialInstances if the +// insts slice has not been completely filled. +func (e *environ) gatherInstances( + ids []instance.Id, + insts []instance.Instance, + filter *ec2.Filter, +) error { resp, err := e.ec2().Instances(nil, filter) if err != nil { return err @@ -824,17 +778,19 @@ // if we find it in the response. for i, id := range ids { if insts[i] != nil { + n++ continue } for j := range resp.Reservations { r := &resp.Reservations[j] for k := range r.Instances { - if r.Instances[k].InstanceId == string(id) { - inst := r.Instances[k] - // TODO(wallyworld): lookup the details to fill in the instance type data - insts[i] = &ec2Instance{e: e, Instance: &inst} - n++ + if r.Instances[k].InstanceId != string(id) { + continue } + inst := r.Instances[k] + // TODO(wallyworld): lookup the details to fill in the instance type data + insts[i] = &ec2Instance{e: e, Instance: &inst} + n++ } } } @@ -844,35 +800,6 @@ return nil } -func (e *environ) Instances(ids []instance.Id) ([]instance.Instance, error) { - if len(ids) == 0 { - return nil, nil - } - insts := make([]instance.Instance, len(ids)) - // Make a series of requests to cope with eventual consistency. - // Each request will attempt to add more instances to the requested - // set. - var err error - for a := shortAttempt.Start(); a.Next(); { - err = e.gatherInstances(ids, insts) - if err == nil || err != environs.ErrPartialInstances { - break - } - } - if err == environs.ErrPartialInstances { - for _, inst := range insts { - if inst != nil { - return insts, environs.ErrPartialInstances - } - } - return nil, environs.ErrNoInstances - } - if err != nil { - return nil, err - } - return insts, nil -} - func (e *environ) fetchNetworkInterfaceId(ec2Inst *ec2.EC2, instId instance.Id) (string, error) { var err error var instancesResp *ec2.InstancesResp @@ -1165,34 +1092,97 @@ return "", false } +// AllInstances is part of the environs.InstanceBroker interface. +func (e *environ) AllInstances() ([]instance.Instance, error) { + return e.AllInstancesByState("pending", "running") +} + +// AllInstancesByState returns all instances in the environment +// with one of the specified instance states. func (e *environ) AllInstancesByState(states ...string) ([]instance.Instance, error) { + // NOTE(axw) we use security group filtering here because instances + // start out untagged. If Juju were to abort after starting an instance, + // but before tagging it, it would be leaked. We only need to do this + // for AllInstances, as it is the result of AllInstances that is used + // in "harvesting" unknown instances by the provisioner. + // + // One possible alternative is to modify ec2.RunInstances to allow the + // caller to specify ClientToken, and then format it like + // :: + // (with base64-encoding to keep the size under the 64-byte limit) + // + // It is possible to filter on "client-token", and specify wildcards; + // therefore we could use client-token filters everywhere in the ec2 + // provider instead of tags or security groups. The only danger is if + // we need to make non-idempotent calls to RunInstances for the machine + // ID. I don't think this is needed, but I am not confident enough to + // change this fundamental right now. + // + // An EC2 API call is required to resolve the group name to an id, as + // VPC enabled accounts do not support name based filtering. + groupName := e.jujuGroupName() + group, err := e.groupByName(groupName) + if isNotFoundError(err) { + // If there's no group, then there cannot be any instances. + return nil, nil + } else if err != nil { + return nil, errors.Trace(err) + } filter := ec2.NewFilter() filter.Add("instance-state-name", states...) - err := e.addGroupFilter(filter) + filter.Add("instance.group-id", group.Id) + return e.allInstances(filter) +} + +// ControllerInstances is part of the environs.Environ interface. +func (e *environ) ControllerInstances() ([]instance.Id, error) { + filter := ec2.NewFilter() + filter.Add("instance-state-name", aliveInstanceStates...) + filter.Add(fmt.Sprintf("tag:%s", tags.JujuIsController), "true") + e.addModelFilter(filter) + ids, err := e.allInstanceIDs(filter) if err != nil { - if ec2ErrCode(err) == "InvalidGroup.NotFound" { - return nil, nil - } - return nil, err + return nil, errors.Trace(err) + } + if len(ids) == 0 { + return nil, environs.ErrNotBootstrapped + } + return ids, nil +} + +// allControllerManagedInstances returns the IDs of all instances managed by +// this environment's controller. +// +// Note that this requires that all instances are tagged; we cannot filter on +// security groups, as we do not know the names of the models. +func (e *environ) allControllerManagedInstances() ([]instance.Id, error) { + filter := ec2.NewFilter() + filter.Add("instance-state-name", aliveInstanceStates...) + e.addControllerFilter(filter) + return e.allInstanceIDs(filter) +} + +func (e *environ) allInstanceIDs(filter *ec2.Filter) ([]instance.Id, error) { + insts, err := e.allInstances(filter) + if err != nil { + return nil, errors.Trace(err) + } + ids := make([]instance.Id, len(insts)) + for i, inst := range insts { + ids[i] = inst.Id() } + return ids, nil +} + +func (e *environ) allInstances(filter *ec2.Filter) ([]instance.Instance, error) { resp, err := e.ec2().Instances(nil, filter) if err != nil { - return nil, err + return nil, errors.Annotate(err, "listing instances") } - eUUID := e.Config().UUID() var insts []instance.Instance for _, r := range resp.Reservations { for i := range r.Instances { inst := r.Instances[i] - tagUUID, ok := getTagByKey(tags.JujuModel, inst.Tags) - // tagless instances will always be included to avoid - // breakage of old environments, if one of these exists it might - // hinder the ability to deploy a second environment of the same - // name. - if ok && tagUUID != eUUID { - continue - } - // TODO(wallyworld): lookup the details to fill in the instance type data insts = append(insts, &ec2Instance{e: e, Instance: &inst}) } @@ -1200,22 +1190,74 @@ return insts, nil } -func (e *environ) AllInstances() ([]instance.Instance, error) { - return e.AllInstancesByState("pending", "running") -} - +// Destroy is part of the environs.Environ interface. func (e *environ) Destroy() error { + cfg := e.Config() + if cfg.UUID() == cfg.ControllerUUID() { + // In case any hosted environment hasn't been cleaned up yet, + // we also attempt to delete their resources when the controller + // environment is destroyed. + if err := e.destroyControllerManagedEnvirons(); err != nil { + return errors.Annotate(err, "destroying managed environs") + } + } if err := common.Destroy(e); err != nil { return errors.Trace(err) } + if err := e.cleanEnvironmentSecurityGroups(); err != nil { + return errors.Annotate(err, "cannot delete environment security groups") + } + return nil +} + +// destroyControllerManagedEnvirons destroys all environments managed by this +// environment's controller. +func (e *environ) destroyControllerManagedEnvirons() error { + + // Terminate all instances managed by the controller. + instIds, err := e.allControllerManagedInstances() + if err != nil { + return errors.Annotate(err, "listing instances") + } + if err := e.terminateInstances(instIds); err != nil { + return errors.Annotate(err, "terminating instances") + } - if err := e.cleanEnvironmentSecurityGroup(); err != nil { - logger.Warningf("cannot delete default security group: %v", err) + // Delete all volumes managed by the controller. + volIds, err := e.allControllerManagedVolumes() + if err != nil { + return errors.Annotate(err, "listing volumes") + } + errs := destroyVolumes(e.ec2(), volIds) + for i, err := range errs { + if err == nil { + continue + } + return errors.Annotatef(err, "destroying volume %q", volIds[i], err) } + // Delete security groups managed by the controller. + groups, err := e.controllerSecurityGroups() + if err != nil { + return errors.Trace(err) + } + for _, g := range groups { + if err := deleteSecurityGroupInsistently(e.ec2(), g, clock.WallClock); err != nil { + return errors.Annotatef( + err, "cannot delete security group %q (%q)", + g.Name, g.Id, + ) + } + } return nil } +func (e *environ) allControllerManagedVolumes() ([]string, error) { + filter := ec2.NewFilter() + e.addControllerFilter(filter) + return listVolumes(e.ec2(), filter) +} + func portsToIPPerms(ports []network.PortRange) []ec2.IPPerm { ipPerms := make([]ec2.IPPerm, len(ports)) for i, p := range ports { @@ -1229,17 +1271,12 @@ return ipPerms } -func (e *environ) openPortsInGroup(name, legacyName string, ports []network.PortRange) error { +func (e *environ) openPortsInGroup(name string, ports []network.PortRange) error { if len(ports) == 0 { return nil } // Give permissions for anyone to access the given ports. g, err := e.groupByName(name) - if ec2ErrCode(err) != "InvalidGroup.NotFound" { - // We might be trying to destroy a legacy system - g, err = e.groupByName(legacyName) - } - if err != nil { return err } @@ -1267,7 +1304,7 @@ return nil } -func (e *environ) closePortsInGroup(name, legacyName string, ports []network.PortRange) error { +func (e *environ) closePortsInGroup(name string, ports []network.PortRange) error { if len(ports) == 0 { return nil } @@ -1275,10 +1312,6 @@ // Note that ec2 allows the revocation of permissions that aren't // granted, so this is naturally idempotent. g, err := e.groupByName(name) - if ec2ErrCode(err) != "InvalidGroup.NotFound" { - // We might be trying to destroy a legacy system - g, err = e.groupByName(legacyName) - } if err != nil { return err } @@ -1314,7 +1347,7 @@ return fmt.Errorf("invalid firewall mode %q for opening ports on model", e.Config().FirewallMode()) } - if err := e.openPortsInGroup(e.globalGroupName(), e.legacyGlobalGroupName(), ports); err != nil { + if err := e.openPortsInGroup(e.globalGroupName(), ports); err != nil { return err } logger.Infof("opened ports in global group: %v", ports) @@ -1326,7 +1359,7 @@ return fmt.Errorf("invalid firewall mode %q for closing ports on model", e.Config().FirewallMode()) } - if err := e.closePortsInGroup(e.globalGroupName(), e.legacyGlobalGroupName(), ports); err != nil { + if err := e.closePortsInGroup(e.globalGroupName(), ports); err != nil { return err } logger.Infof("closed ports in global group: %v", ports) @@ -1365,26 +1398,41 @@ securityGroups := []ec2.SecurityGroup{} for _, res := range resp.Reservations { for _, inst := range res.Instances { + logger.Debugf("instance %q has security groups %+v", inst.InstanceId, inst.SecurityGroups) securityGroups = append(securityGroups, inst.SecurityGroups...) } } return securityGroups, nil } -func (e *environ) cleanEnvironmentSecurityGroup() error { - ec2inst := e.ec2() - var err error +// controllerSecurityGroups returns the details of all security groups managed +// by the environment's controller. +func (e *environ) controllerSecurityGroups() ([]ec2.SecurityGroup, error) { + filter := ec2.NewFilter() + e.addControllerFilter(filter) + resp, err := e.ec2().SecurityGroups(nil, filter) + if err != nil { + return nil, errors.Annotate(err, "listing security groups") + } + groups := make([]ec2.SecurityGroup, len(resp.Groups)) + for i, info := range resp.Groups { + groups[i] = ec2.SecurityGroup{Id: info.Id, Name: info.Name} + } + return groups, nil +} + +// cleanEnvironmentSecurityGroups attempts to delete all security groups owned +// by the environment. +func (e *environ) cleanEnvironmentSecurityGroups() error { jujuGroup := e.jujuGroupName() g, err := e.groupByName(jujuGroup) - if ec2ErrCode(err) != "InvalidGroup.NotFound" { - // We might be trying to destroy a legacy system - g, err = e.groupByName(e.legacyJujuGroupName()) + if isNotFoundError(err) { + return nil } if err != nil { return errors.Annotatef(err, "cannot retrieve default security group: %q", jujuGroup) } - - if err := deleteSecurityGroupInsistently(ec2inst, g); err != nil { + if err := deleteSecurityGroupInsistently(e.ec2(), g, clock.WallClock); err != nil { return errors.Annotate(err, "cannot delete default security group") } return nil @@ -1454,32 +1502,34 @@ logger.Debugf("no need to delete security groups: no intances were terminated successfully") return } + // We only want to attempt deleting security groups for the // instances that have been successfully terminated. securityGroups, err := e.instanceSecurityGroups(ids, "shutting-down", "terminated") if err != nil { logger.Warningf("cannot determine security groups to delete: %v", err) } + // TODO(perrito666) we need to tag global security groups to be able // to tell them apart from future groups that are neither machine // nor environment group. // https://bugs.launchpad.net/juju-core/+bug/1534289 jujuGroup := e.jujuGroupName() - legacyJujuGroup := e.legacyJujuGroupName() ec2inst := e.ec2() for _, deletable := range securityGroups { - if deletable.Name != jujuGroup && deletable.Name != legacyJujuGroup { - if err := deleteSecurityGroupInsistently(ec2inst, deletable); err != nil { - // In ideal world, we would err out here. - // However: - // 1. We do not know if all instances have been terminated. - // If some instances erred out, they may still be using this security group. - // In this case, our failure to delete security group is reasonable: it's still in use. - // 2. Some security groups may be shared by multiple instances, - // for example, global firewalling. We should not delete these. - logger.Warningf("provider failure: %v", err) - } + if deletable.Name == jujuGroup { + continue + } + if err := deleteSecurityGroupInsistently(ec2inst, deletable, clock.WallClock); err != nil { + // In ideal world, we would err out here. + // However: + // 1. We do not know if all instances have been terminated. + // If some instances erred out, they may still be using this security group. + // In this case, our failure to delete security group is reasonable: it's still in use. + // 2. Some security groups may be shared by multiple instances, + // for example, global firewalling. We should not delete these. + logger.Warningf("provider failure: %v", err) } } } @@ -1492,20 +1542,20 @@ DeleteSecurityGroup(group ec2.SecurityGroup) (resp *ec2.SimpleResp, err error) } -var deleteSecurityGroupInsistently = func(inst SecurityGroupCleaner, group ec2.SecurityGroup) error { +var deleteSecurityGroupInsistently = func(inst SecurityGroupCleaner, group ec2.SecurityGroup, clock clock.Clock) error { var lastErr error err := retry.Call(retry.CallArgs{ Attempts: 30, Delay: time.Second, MaxDelay: time.Minute, // because 2**29 seconds is beyond reasonable BackoffFunc: retry.DoubleDelay, - Clock: clock.WallClock, + Clock: clock, Func: func() error { - _, deleteErr := inst.DeleteSecurityGroup(group) - if ec2ErrCode(deleteErr) != "InvalidGroup.NotFound" { - return errors.Trace(deleteErr) + _, err := inst.DeleteSecurityGroup(group) + if err == nil || isNotFoundError(err) { + return nil } - return nil + return errors.Trace(err) }, NotifyFunc: func(err error, attempt int) { lastErr = err @@ -1519,6 +1569,14 @@ return nil } +func (e *environ) addModelFilter(f *ec2.Filter) { + f.Add(fmt.Sprintf("tag:%s", tags.JujuModel), e.uuid()) +} + +func (e *environ) addControllerFilter(f *ec2.Filter) { + f.Add(fmt.Sprintf("tag:%s", tags.JujuController), e.Config().ControllerUUID()) +} + func (e *environ) uuid() string { return e.Config().UUID() } @@ -1535,21 +1593,6 @@ return "juju-" + e.uuid() } -// Legacy naming for groups, before multi environments with the same -// name where supported. - -func (e *environ) legacyGlobalGroupName() string { - return fmt.Sprintf("%s-global", e.legacyJujuGroupName()) -} - -func (e *environ) legacyMachineGroupName(machineId string) string { - return fmt.Sprintf("%s-%s", e.legacyJujuGroupName(), machineId) -} - -func (e *environ) legacyJujuGroupName() string { - return "juju-" + e.uuid() -} - // setUpGroups creates the security groups for the new machine, and // returns them. // @@ -1558,39 +1601,37 @@ // addition, a specific machine security group is created for each // machine, so that its firewall rules can be configured per machine. func (e *environ) setUpGroups(machineId string, apiPort int) ([]ec2.SecurityGroup, error) { + + // Ensure there's a global group for Juju-related traffic. jujuGroup, err := e.ensureGroup(e.jujuGroupName(), - []ec2.IPPerm{ - { - Protocol: "tcp", - FromPort: 22, - ToPort: 22, - SourceIPs: []string{"0.0.0.0/0"}, - }, - { - Protocol: "tcp", - FromPort: apiPort, - ToPort: apiPort, - SourceIPs: []string{"0.0.0.0/0"}, - }, - { - Protocol: "tcp", - FromPort: 0, - ToPort: 65535, - }, - { - Protocol: "udp", - FromPort: 0, - ToPort: 65535, - }, - { - Protocol: "icmp", - FromPort: -1, - ToPort: -1, - }, - }) + []ec2.IPPerm{{ + Protocol: "tcp", + FromPort: 22, + ToPort: 22, + SourceIPs: []string{"0.0.0.0/0"}, + }, { + Protocol: "tcp", + FromPort: apiPort, + ToPort: apiPort, + SourceIPs: []string{"0.0.0.0/0"}, + }, { + Protocol: "tcp", + FromPort: 0, + ToPort: 65535, + }, { + Protocol: "udp", + FromPort: 0, + ToPort: 65535, + }, { + Protocol: "icmp", + FromPort: -1, + ToPort: -1, + }}, + ) if err != nil { return nil, err } + var machineGroup ec2.SecurityGroup switch e.Config().FirewallMode() { case config.FwInstance: @@ -1607,26 +1648,70 @@ // zeroGroup holds the zero security group. var zeroGroup ec2.SecurityGroup +// securityGroupsByNameOrID calls ec2.SecurityGroups() either with the given +// groupName or with filter by vpc-id and group-name, depending on whether +// vpc-id is empty or not. +func (e *environ) securityGroupsByNameOrID(groupName string) (*ec2.SecurityGroupsResp, error) { + var ( + filter *ec2.Filter + groups []ec2.SecurityGroup + ) + + chosenVPCID := e.ecfg().vpcID() + if chosenVPCID != "" { + // AWS VPC API requires both of these filters (and no + // group names/ids set) for non-default EC2-VPC groups: + filter = ec2.NewFilter() + filter.Add("vpc-id", chosenVPCID) + filter.Add("group-name", groupName) + } else { + // EC2-Classic or EC2-VPC with implicit default VPC need to use the + // GroupName.X arguments instead of the filters. + groups = ec2.SecurityGroupNames(groupName) + } + + return e.ec2().SecurityGroups(groups, filter) +} + // ensureGroup returns the security group with name and perms. // If a group with name does not exist, one will be created. // If it exists, its permissions are set to perms. // Any entries in perms without SourceIPs will be granted for // the named group only. func (e *environ) ensureGroup(name string, perms []ec2.IPPerm) (g ec2.SecurityGroup, err error) { + // Specify explicit VPC ID if needed (not for default VPC). + chosenVPCID := e.ecfg().vpcID() + ec2inst := e.ec2() - resp, err := ec2inst.CreateSecurityGroup("", name, "juju group") + resp, err := ec2inst.CreateSecurityGroup(chosenVPCID, name, "juju group") if err != nil && ec2ErrCode(err) != "InvalidGroup.Duplicate" { + err = errors.Annotatef(err, "creating security group %q (in VPC %q)", name, chosenVPCID) return zeroGroup, err } var have permSet if err == nil { g = resp.SecurityGroup + // Tag the created group with the model and controller UUIDs. + cfg := e.Config() + tags := tags.ResourceTags( + names.NewModelTag(cfg.UUID()), + names.NewModelTag(cfg.ControllerUUID()), + cfg, + ) + if err := tagResources(ec2inst, tags, g.Id); err != nil { + return g, errors.Annotate(err, "tagging security group") + } + logger.Debugf("created security group %q in VPC %q with ID %q", name, chosenVPCID, g.Id) } else { - resp, err := ec2inst.SecurityGroups(ec2.SecurityGroupNames(name), nil) + resp, err := e.securityGroupsByNameOrID(name) if err != nil { + err = errors.Annotatef(err, "fetching security group %q (in VPC %q)", name, chosenVPCID) return zeroGroup, err } + if len(resp.Groups) == 0 { + return zeroGroup, errors.NotFoundf("security group %q in VPC %q", name, chosenVPCID) + } info := resp.Groups[0] // It's possible that the old group has the wrong // description here, but if it does it's probably due @@ -1635,6 +1720,7 @@ g = info.SecurityGroup have = newPermSetForGroup(info.IPPerms, g) } + want := newPermSetForGroup(perms, g) revoke := make(permSet) for p := range have { @@ -1645,7 +1731,8 @@ if len(revoke) > 0 { _, err := ec2inst.RevokeSecurityGroup(g, revoke.ipPerms()) if err != nil { - return zeroGroup, fmt.Errorf("cannot revoke security group: %v", err) + err = errors.Annotatef(err, "revoking security group %q (in VPC %q)", g.Id, chosenVPCID) + return zeroGroup, err } } @@ -1658,15 +1745,15 @@ if len(add) > 0 { _, err := ec2inst.AuthorizeSecurityGroup(g, add.ipPerms()) if err != nil { - return zeroGroup, fmt.Errorf("cannot authorize securityGroup: %v", err) + err = errors.Annotatef(err, "authorizing security group %q (in VPC %q)", g.Id, chosenVPCID) + return zeroGroup, err } } return g, nil } -// permKey represents a permission for a group or an ip address range -// to access the given range of ports. Only one of groupName or ipAddr -// should be non-empty. +// permKey represents a permission for a group or an ip address range to access +// the given range of ports. Only one of groupId or ipAddr should be non-empty. type permKey struct { protocol string fromPort int @@ -1723,6 +1810,10 @@ return } +func isZoneOrSubnetConstrainedError(err error) bool { + return isZoneConstrainedError(err) || isSubnetConstrainedError(err) +} + // isZoneConstrainedError reports whether or not the error indicates // RunInstances failed due to the specified availability zone being // constrained for the instance type being provisioned, or is diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/environ_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/environ_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/environ_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/environ_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -8,7 +8,18 @@ gc "gopkg.in/check.v1" "github.com/juju/juju/constraints" + "github.com/juju/juju/environs" + "github.com/juju/juju/environs/simplestreams" "github.com/juju/juju/network" + "github.com/juju/juju/state" +) + +// Ensure EC2 provider supports the expected interfaces, +var ( + _ environs.NetworkingEnviron = (*environ)(nil) + _ simplestreams.HasRegion = (*environ)(nil) + _ state.Prechecker = (*environ)(nil) + _ state.InstanceDistributor = (*environ)(nil) ) type Suite struct{} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/environ_vpc.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/environ_vpc.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/environ_vpc.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/environ_vpc.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,467 @@ +// Copyright 2016 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package ec2 + +import ( + "fmt" + + "github.com/juju/errors" + "github.com/juju/utils/set" + "gopkg.in/amz.v3/ec2" + + "github.com/juju/juju/network" +) + +const ( + activeState = "active" + availableState = "available" + localRouteGatewayID = "local" + defaultRouteCIDRBlock = "0.0.0.0/0" + defaultVPCIDNone = "none" +) + +var ( + vpcNotUsableErrorPrefix = ` +Juju cannot use the given vpc-id for bootstrapping a controller +instance. Please, double check the given VPC ID is correct, and that +the VPC contains at least one subnet. + +Error details`[1:] + + vpcNotRecommendedErrorPrefix = ` +The given vpc-id does not meet one or more of the following minimum +Juju requirements: + +1. VPC should be in "available" state and contain one or more subnets. +2. An Internet Gateway (IGW) should be attached to the VPC. +3. The main route table of the VPC should have both a default route + to the attached IGW and a local route matching the VPC CIDR block. +4. At least one of the VPC subnets should have MapPublicIPOnLaunch + attribute enabled (i.e. at least one subnet needs to be 'public'). +5. All subnets should be implicitly associated to the VPC main route + table, rather than explicitly to per-subnet route tables. + +A default VPC already satisfies all of the requirements above. If you +still want to use the VPC, try running 'juju bootstrap' again with: + + --config vpc-id=%s --config vpc-id-force=true + +to force Juju to bypass the requirements check (NOT recommended unless +you understand the implications: most importantly, not being able to +access the Juju controller, likely causing bootstrap to fail, or trying +to deploy exposed workloads on instances started in private or isolated +subnets). + +Error details`[1:] + + cannotValidateVPCErrorPrefix = ` +Juju could not verify whether the given vpc-id meets the minumum Juju +connectivity requirements. Please, double check the VPC ID is correct, +you have a working connection to the Internet, your AWS credentials are +sufficient to access VPC features, or simply retry bootstrapping again. + +Error details`[1:] + + vpcNotRecommendedButForcedWarning = ` +WARNING! The specified vpc-id does not satisfy the minimum Juju requirements, +but will be used anyway because vpc-id-force=true is also specified. + +`[1:] +) + +// vpcNotUsableError indicates a user-specified VPC cannot be used either +// because it is missing or because it contains no subnets. +type vpcNotUsableError struct { + errors.Err +} + +// vpcNotUsablef returns an error which satisfies isVPCNotUsableError(). +func vpcNotUsablef(optionalCause error, format string, args ...interface{}) error { + outerErr := errors.Errorf(format, args...) + if optionalCause != nil { + outerErr = errors.Maskf(optionalCause, format, args...) + } + + innerErr, _ := outerErr.(*errors.Err) // cannot fail. + return &vpcNotUsableError{*innerErr} +} + +// isVPCNotUsableError reports whether err was created with vpcNotUsablef(). +func isVPCNotUsableError(err error) bool { + err = errors.Cause(err) + _, ok := err.(*vpcNotUsableError) + return ok +} + +// vpcNotRecommendedError indicates a user-specified VPC is unlikely to be +// suitable for hosting a Juju controller instance and/or exposed workloads, due +// to not satisfying the mininum requirements described in validateVPC()'s doc +// comment. Users can still force Juju to use such a VPC by passing +// 'vpc-id-force=true' setting. +type vpcNotRecommendedError struct { + errors.Err +} + +// vpcNotRecommendedf returns an error which satisfies isVPCNotRecommendedError(). +func vpcNotRecommendedf(format string, args ...interface{}) error { + outerErr := errors.Errorf(format, args...) + innerErr, _ := outerErr.(*errors.Err) // cannot fail. + return &vpcNotRecommendedError{*innerErr} +} + +// isVPCNotRecommendedError reports whether err was created with vpcNotRecommendedf(). +func isVPCNotRecommendedError(err error) bool { + err = errors.Cause(err) + _, ok := err.(*vpcNotRecommendedError) + return ok +} + +// vpcAPIClient defines a subset of the goamz API calls needed to validate a VPC. +type vpcAPIClient interface { + // AccountAttributes, called with the "default-vpc" attribute. is used to + // find the ID of the region's default VPC (if any). + AccountAttributes(attributeNames ...string) (*ec2.AccountAttributesResp, error) + + // VPCs is used to get details for the VPC being validated, including + // whether it exists, is available, and its CIDRBlock and IsDefault fields. + VPCs(ids []string, filter *ec2.Filter) (*ec2.VPCsResp, error) + + // Subnets is used to get a list of all subnets of the validated VPC (if + // any),including their Id, AvailZone, and MapPublicIPOnLaunch fields. + Subnets(ids []string, filter *ec2.Filter) (*ec2.SubnetsResp, error) + + // InternetGateways is used to get details of the Internet Gateway (IGW) + // attached to the validated VPC (if any), its Id to check against routes, + // and whether it's available. + InternetGateways(ids []string, filter *ec2.Filter) (*ec2.InternetGatewaysResp, error) + + // RouteTables is used to find the main route table of the VPC (if any), + // whether it includes a default route to the attached IGW, a local route to + // the VPC CIDRBlock, and any per-subnet route tables. + RouteTables(ids []string, filter *ec2.Filter) (*ec2.RouteTablesResp, error) +} + +// validateVPC requires both arguments to be set and validates that vpcID refers +// to an existing AWS VPC (default or non-default) for the current region. +// Returns an error satifying isVPCNotUsableError() when the VPC with the given +// vpcID cannot be found, or when the VPC exists but contains no subnets. +// Returns an error satisfying isVPCNotRecommendedError() in the following +// cases: +// +// 1. The VPC's state is not "available". +// 2. The VPC does not have an Internet Gateway (IGW) attached. +// 3. A main route table is not associated with the VPC. +// 4. The main route table lacks both a default route via the IGW and a local +// route matching the VPC's CIDR block. +// 5. One or more of the VPC's subnets are not associated with the main route +// table of the VPC. +// 6. None of the the VPC's subnets have the MapPublicIPOnLaunch attribute set. +// +// With the vpc-id-force config setting set to true, the provider can ignore a +// vpcNotRecommendedError. A vpcNotUsableError cannot be ignored, while +// unexpected API responses and errors could be retried. +// +// The above minimal requirements allow Juju to work out-of-the-box with most +// common (and officially documented by AWS) VPC setups, easy try out with AWS +// Console / VPC Wizard / CLI. Detecting VPC setups indicating intentional +// customization by experienced users, protecting beginners from bad Juju-UX due +// to broken VPC setup, while still allowing power users to override that and +// continue (but knowing what that implies). +func validateVPC(apiClient vpcAPIClient, vpcID string) error { + if vpcID == "" || apiClient == nil { + return errors.Errorf("invalid arguments: empty VPC ID or nil client") + } + + vpc, err := getVPCByID(apiClient, vpcID) + if err != nil { + return errors.Trace(err) + } + + if err := checkVPCIsAvailable(vpc); err != nil { + return errors.Trace(err) + } + + subnets, err := getVPCSubnets(apiClient, vpc) + if err != nil { + return errors.Trace(err) + } + + publicSubnet, err := findFirstPublicSubnet(subnets) + if err != nil { + return errors.Trace(err) + } + + // TODO(dimitern): Rather than just logging that, use publicSubnet.Id or + // even publicSubnet.AvailZone as default bootstrap placement directive, so + // the controller would be reachable. + logger.Infof( + "found subnet %q (%s) in AZ %q, suitable for a Juju controller instance", + publicSubnet.Id, publicSubnet.CIDRBlock, publicSubnet.AvailZone, + ) + + gateway, err := getVPCInternetGateway(apiClient, vpc) + if err != nil { + return errors.Trace(err) + } + + if err := checkInternetGatewayIsAvailable(gateway); err != nil { + return errors.Trace(err) + } + + routeTables, err := getVPCRouteTables(apiClient, vpc) + if err != nil { + return errors.Trace(err) + } + + mainRouteTable, err := findVPCMainRouteTable(routeTables) + if err != nil { + return errors.Trace(err) + } + + if err := checkVPCRouteTableRoutes(vpc, mainRouteTable, gateway); err != nil { + return errors.Annotatef(err, "VPC %q main route table %q", vpcID, mainRouteTable.Id) + } + + logger.Infof("VPC %q is suitable for Juju controllers and expose-able workloads", vpc.Id) + return nil +} + +func getVPCByID(apiClient vpcAPIClient, vpcID string) (*ec2.VPC, error) { + response, err := apiClient.VPCs([]string{vpcID}, nil) + if isVPCNotFoundError(err) { + return nil, vpcNotUsablef(err, "") + } else if err != nil { + return nil, errors.Annotatef(err, "unexpected AWS response getting VPC %q", vpcID) + } + + if numResults := len(response.VPCs); numResults == 0 { + return nil, vpcNotUsablef(nil, "VPC %q not found", vpcID) + } else if numResults > 1 { + logger.Debugf("VPCs() returned %#v", response) + return nil, errors.Errorf("expected 1 result from AWS, got %d", numResults) + } + + vpc := response.VPCs[0] + return &vpc, nil +} + +func isVPCNotFoundError(err error) bool { + return err != nil && ec2ErrCode(err) == "InvalidVpcID.NotFound" +} + +func checkVPCIsAvailable(vpc *ec2.VPC) error { + if vpc.State != availableState { + return vpcNotRecommendedf("VPC has unexpected state %q", vpc.State) + } + + if vpc.IsDefault { + logger.Infof("VPC %q is the default VPC for the region", vpc.Id) + } + + return nil +} + +func getVPCSubnets(apiClient vpcAPIClient, vpc *ec2.VPC) ([]ec2.Subnet, error) { + filter := ec2.NewFilter() + filter.Add("vpc-id", vpc.Id) + response, err := apiClient.Subnets(nil, filter) + if err != nil { + return nil, errors.Annotatef(err, "unexpected AWS response getting subnets of VPC %q", vpc.Id) + } + + if len(response.Subnets) == 0 { + return nil, vpcNotUsablef(nil, "no subnets found for VPC %q", vpc.Id) + } + + return response.Subnets, nil +} + +func findFirstPublicSubnet(subnets []ec2.Subnet) (*ec2.Subnet, error) { + for _, subnet := range subnets { + if subnet.MapPublicIPOnLaunch { + return &subnet, nil + } + + } + return nil, vpcNotRecommendedf("VPC contains no public subnets") +} + +func getVPCInternetGateway(apiClient vpcAPIClient, vpc *ec2.VPC) (*ec2.InternetGateway, error) { + filter := ec2.NewFilter() + filter.Add("attachment.vpc-id", vpc.Id) + response, err := apiClient.InternetGateways(nil, filter) + if err != nil { + return nil, errors.Annotatef(err, "unexpected AWS response getting Internet Gateway of VPC %q", vpc.Id) + } + + if numResults := len(response.InternetGateways); numResults == 0 { + return nil, vpcNotRecommendedf("VPC has no Internet Gateway attached") + } else if numResults > 1 { + logger.Debugf("InternetGateways() returned %#v", response) + return nil, errors.Errorf("expected 1 result from AWS, got %d", numResults) + } + + gateway := response.InternetGateways[0] + return &gateway, nil +} + +func checkInternetGatewayIsAvailable(gateway *ec2.InternetGateway) error { + if state := gateway.AttachmentState; state != availableState { + return vpcNotRecommendedf("VPC has Internet Gateway %q in unexpected state %q", gateway.Id, state) + } + + return nil +} + +func getVPCRouteTables(apiClient vpcAPIClient, vpc *ec2.VPC) ([]ec2.RouteTable, error) { + filter := ec2.NewFilter() + filter.Add("vpc-id", vpc.Id) + response, err := apiClient.RouteTables(nil, filter) + if err != nil { + return nil, errors.Annotatef(err, "unexpected AWS response getting route tables of VPC %q", vpc.Id) + } + + if len(response.Tables) == 0 { + return nil, vpcNotRecommendedf("VPC has no route tables") + } + logger.Tracef("RouteTables() returned %#v", response) + + return response.Tables, nil +} + +func findVPCMainRouteTable(routeTables []ec2.RouteTable) (*ec2.RouteTable, error) { + var mainTable *ec2.RouteTable + for i, table := range routeTables { + if len(table.Associations) < 1 { + logger.Tracef("ignoring VPC %q route table %q with no associations", table.VPCId, table.Id) + continue + } + + for _, association := range table.Associations { + // TODO(dimitern): Of all the requirements, this seems like the most + // strict and likely to push users to use vpc-id-force=true. On the + // other hand, having to deal with more than the main route table's + // routes will likely overcomplicate the routes checks that follow. + if subnetID := association.SubnetId; subnetID != "" { + return nil, vpcNotRecommendedf("subnet %q not associated with VPC %q main route table", subnetID, table.VPCId) + } + + if association.IsMain && mainTable == nil { + logger.Tracef("main route table of VPC %q has ID %q", table.VPCId, table.Id) + mainTable = &routeTables[i] + } + } + } + + if mainTable == nil { + return nil, vpcNotRecommendedf("VPC has no associated main route table") + } + + return mainTable, nil +} + +func checkVPCRouteTableRoutes(vpc *ec2.VPC, routeTable *ec2.RouteTable, gateway *ec2.InternetGateway) error { + hasDefaultRoute := false + hasLocalRoute := false + + logger.Tracef("checking route table %+v routes", routeTable) + for _, route := range routeTable.Routes { + if route.State != activeState { + logger.Tracef("skipping inactive route %+v", route) + continue + } + + switch route.DestinationCIDRBlock { + case defaultRouteCIDRBlock: + if route.GatewayId == gateway.Id { + logger.Tracef("default route uses expected gateway %q", gateway.Id) + hasDefaultRoute = true + } + case vpc.CIDRBlock: + if route.GatewayId == localRouteGatewayID { + logger.Tracef("local route uses expected CIDR %q", vpc.CIDRBlock) + hasLocalRoute = true + } + default: + logger.Tracef("route %+v is neither local nor default (skipping)", route) + } + } + + if hasDefaultRoute && hasLocalRoute { + return nil + } + + if !hasDefaultRoute { + return vpcNotRecommendedf("missing default route via gateway %q", gateway.Id) + } + return vpcNotRecommendedf("missing local route with destination %q", vpc.CIDRBlock) +} + +func findDefaultVPCID(apiClient vpcAPIClient) (string, error) { + response, err := apiClient.AccountAttributes("default-vpc") + if err != nil { + return "", errors.Annotate(err, "unexpected AWS response getting default-vpc account attribute") + } + + if len(response.Attributes) == 0 || + len(response.Attributes[0].Values) == 0 || + response.Attributes[0].Name != "default-vpc" { + // No value for the requested "default-vpc" attribute, all bets are off. + return "", errors.NotFoundf("default-vpc account attribute") + } + + firstAttributeValue := response.Attributes[0].Values[0] + if firstAttributeValue == defaultVPCIDNone { + return "", errors.NotFoundf("default VPC") + } + + return firstAttributeValue, nil +} + +// getVPCSubnetIDsForAvailabilityZone returns a list of subnet IDs, which are +// both in the given vpcID and the given zoneName. Returns an error satisfying +// errors.IsNotFound() otherwise. +func getVPCSubnetIDsForAvailabilityZone(apiClient vpcAPIClient, vpcID, zoneName string) ([]string, error) { + vpc := &ec2.VPC{Id: vpcID} + subnets, err := getVPCSubnets(apiClient, vpc) + if err != nil && !isVPCNotUsableError(err) { + return nil, errors.Annotatef(err, "cannot get VPC %q subnets", vpcID) + } else if isVPCNotUsableError(err) { + // We're reusing getVPCSubnets(), but not while validating a VPC + // pre-bootstrap, so we should change vpcNotUsableError to a simple + // NotFoundError. + message := fmt.Sprintf("VPC %q has no subnets in AZ %q", vpcID, zoneName) + return nil, errors.NewNotFound(err, message) + } + + matchingSubnetIDs := set.NewStrings() + for _, subnet := range subnets { + if subnet.AvailZone == zoneName { + matchingSubnetIDs.Add(subnet.Id) + } + } + + if matchingSubnetIDs.IsEmpty() { + message := fmt.Sprintf("VPC %q has no subnets in AZ %q", vpcID, zoneName) + return nil, errors.NewNotFound(nil, message) + } + + return matchingSubnetIDs.SortedValues(), nil +} + +func findSubnetIDsForAvailabilityZone(zoneName string, subnetsToZones map[network.Id][]string) ([]string, error) { + matchingSubnetIDs := set.NewStrings() + for subnetID, zones := range subnetsToZones { + zonesSet := set.NewStrings(zones...) + if zonesSet.Contains(zoneName) { + matchingSubnetIDs.Add(string(subnetID)) + } + } + + if matchingSubnetIDs.IsEmpty() { + return nil, errors.NotFoundf("subnets in AZ %q", zoneName) + } + + return matchingSubnetIDs.SortedValues(), nil +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/environ_vpc_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/environ_vpc_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/environ_vpc_test.go 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/environ_vpc_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,900 @@ +// Copyright 2016 Canonical Ltd. +// Licensed under the AGPLv3, see LICENCE file for details. + +package ec2 + +import ( + "fmt" + + "github.com/juju/errors" + "github.com/juju/testing" + jc "github.com/juju/testing/checkers" + "gopkg.in/amz.v3/ec2" + gc "gopkg.in/check.v1" + + "github.com/juju/juju/network" +) + +type vpcSuite struct { + testing.IsolationSuite + + stubAPI *stubVPCAPIClient +} + +var _ = gc.Suite(&vpcSuite{}) + +func (s *vpcSuite) SetUpTest(c *gc.C) { + s.IsolationSuite.SetUpTest(c) + + s.stubAPI = &stubVPCAPIClient{Stub: &testing.Stub{}} +} + +// NOTE: validateVPC tests only verify expected error types for all code paths, +// but do not check passed API arguments or exact error messages, as those are +// extensively tested separately below. + +func (s *vpcSuite) TestValidateVPCWithEmptyVPCIDOrNilAPIClient(c *gc.C) { + err := validateVPC(s.stubAPI, "") + c.Assert(err, gc.ErrorMatches, "invalid arguments: empty VPC ID or nil client") + + err = validateVPC(nil, anyVPCID) + c.Assert(err, gc.ErrorMatches, "invalid arguments: empty VPC ID or nil client") + + s.stubAPI.CheckNoCalls(c) +} + +func (s *vpcSuite) TestValidateVPCWhenVPCIDNotFound(c *gc.C) { + s.stubAPI.SetErrors(makeVPCNotFoundError("foo")) + + err := validateVPC(s.stubAPI, anyVPCID) + c.Check(err, jc.Satisfies, isVPCNotUsableError) + + s.stubAPI.CheckCallNames(c, "VPCs") +} + +func (s *vpcSuite) TestValidateVPCWhenVPCHasNoSubnets(c *gc.C) { + s.stubAPI.SetVPCsResponse(1, availableState, notDefaultVPC) + s.stubAPI.SetSubnetsResponse(noResults, anyZone, noPublicIPOnLaunch) + + err := validateVPC(s.stubAPI, anyVPCID) + c.Check(err, jc.Satisfies, isVPCNotUsableError) + + s.stubAPI.CheckCallNames(c, "VPCs", "Subnets") +} +func (s *vpcSuite) TestValidateVPCWhenVPCNotAvailable(c *gc.C) { + s.stubAPI.PrepareValidateVPCResponses() + s.stubAPI.SetVPCsResponse(1, "bad-state", notDefaultVPC) + + s.stubAPI.CallValidateVPCAndCheckCallsUpToExpectingVPCNotRecommendedError(c, "VPCs") +} + +func (s *vpcSuite) TestValidateVPCWhenVPCHasNoPublicSubnets(c *gc.C) { + s.stubAPI.PrepareValidateVPCResponses() + s.stubAPI.SetSubnetsResponse(1, anyZone, noPublicIPOnLaunch) + + s.stubAPI.CallValidateVPCAndCheckCallsUpToExpectingVPCNotRecommendedError(c, "Subnets") +} + +func (s *vpcSuite) TestValidateVPCWhenVPCHasNoGateway(c *gc.C) { + s.stubAPI.PrepareValidateVPCResponses() + s.stubAPI.SetGatewaysResponse(noResults, anyState) + + s.stubAPI.CallValidateVPCAndCheckCallsUpToExpectingVPCNotRecommendedError(c, "InternetGateways") +} + +func (s *vpcSuite) TestValidateVPCWhenVPCHasNoAttachedGateway(c *gc.C) { + s.stubAPI.PrepareValidateVPCResponses() + s.stubAPI.SetGatewaysResponse(1, "pending") + + s.stubAPI.CallValidateVPCAndCheckCallsUpToExpectingVPCNotRecommendedError(c, "InternetGateways") +} + +func (s *vpcSuite) TestValidateVPCWhenVPCHasNoRouteTables(c *gc.C) { + s.stubAPI.PrepareValidateVPCResponses() + s.stubAPI.SetRouteTablesResponse() // no route tables at all + + s.stubAPI.CallValidateVPCAndCheckCallsUpToExpectingVPCNotRecommendedError(c, "RouteTables") +} + +func (s *vpcSuite) TestValidateVPCWhenVPCHasNoMainRouteTable(c *gc.C) { + s.stubAPI.PrepareValidateVPCResponses() + s.stubAPI.SetRouteTablesResponse( + makeEC2RouteTable(anyTableID, notMainRouteTable, nil, nil), + ) + + s.stubAPI.CallValidateVPCAndCheckCallsUpToExpectingVPCNotRecommendedError(c, "RouteTables") +} + +func (s *vpcSuite) TestValidateVPCWhenVPCHasMainRouteTableWithoutRoutes(c *gc.C) { + s.stubAPI.PrepareValidateVPCResponses() + s.stubAPI.SetRouteTablesResponse( + makeEC2RouteTable(anyTableID, mainRouteTable, nil, nil), + ) + + s.stubAPI.CallValidateVPCAndCheckCallsUpToExpectingVPCNotRecommendedError(c, "RouteTables") +} + +func (s *vpcSuite) TestValidateVPCSuccess(c *gc.C) { + s.stubAPI.PrepareValidateVPCResponses() + + err := validateVPC(s.stubAPI, anyVPCID) + c.Assert(err, jc.ErrorIsNil) + + s.stubAPI.CheckCallNames(c, "VPCs", "Subnets", "InternetGateways", "RouteTables") +} + +func (s *vpcSuite) TestGetVPCByIDWithMissingID(c *gc.C) { + s.stubAPI.SetErrors(makeVPCNotFoundError("foo")) + + vpc, err := getVPCByID(s.stubAPI, "foo") + c.Assert(err, gc.ErrorMatches, `The vpc ID 'foo' does not exist \(InvalidVpcID.NotFound\)`) + c.Check(err, jc.Satisfies, isVPCNotUsableError) + c.Check(vpc, gc.IsNil) + + s.stubAPI.CheckSingleVPCsCall(c, "foo") +} + +func (s *vpcSuite) TestGetVPCByIDUnexpectedAWSError(c *gc.C) { + s.stubAPI.SetErrors(errors.New("AWS failed!")) + + vpc, err := getVPCByID(s.stubAPI, "bar") + c.Assert(err, gc.ErrorMatches, `unexpected AWS response getting VPC "bar": AWS failed!`) + c.Check(vpc, gc.IsNil) + + s.stubAPI.CheckSingleVPCsCall(c, "bar") +} + +func (s *vpcSuite) TestGetVPCByIDNoResults(c *gc.C) { + s.stubAPI.SetVPCsResponse(noResults, anyState, notDefaultVPC) + + vpc, err := getVPCByID(s.stubAPI, "vpc-42") + c.Assert(err, gc.ErrorMatches, `VPC "vpc-42" not found`) + c.Check(err, jc.Satisfies, isVPCNotUsableError) + c.Check(vpc, gc.IsNil) + + s.stubAPI.CheckSingleVPCsCall(c, "vpc-42") +} + +func (s *vpcSuite) TestGetVPCByIDMultipleResults(c *gc.C) { + s.stubAPI.SetVPCsResponse(5, anyState, notDefaultVPC) + + vpc, err := getVPCByID(s.stubAPI, "vpc-33") + c.Assert(err, gc.ErrorMatches, "expected 1 result from AWS, got 5") + c.Check(vpc, gc.IsNil) + + s.stubAPI.CheckSingleVPCsCall(c, "vpc-33") +} + +func (s *vpcSuite) TestGetVPCByIDSuccess(c *gc.C) { + s.stubAPI.SetVPCsResponse(1, anyState, notDefaultVPC) + + vpc, err := getVPCByID(s.stubAPI, "vpc-1") + c.Assert(err, jc.ErrorIsNil) + c.Check(vpc, jc.DeepEquals, &s.stubAPI.vpcsResponse.VPCs[0]) + + s.stubAPI.CheckSingleVPCsCall(c, "vpc-1") +} + +func (s *vpcSuite) TestIsVPCNotFoundError(c *gc.C) { + c.Check(isVPCNotFoundError(nil), jc.IsFalse) + + nonEC2Error := errors.New("boom") + c.Check(isVPCNotFoundError(nonEC2Error), jc.IsFalse) + + ec2Error := makeEC2Error(444, "code", "bad stuff", "req-id") + c.Check(isVPCNotFoundError(ec2Error), jc.IsFalse) + + ec2Error = makeVPCNotFoundError("some-id") + c.Check(isVPCNotFoundError(ec2Error), jc.IsTrue) +} + +func (s *vpcSuite) TestCheckVPCIsAvailable(c *gc.C) { + availableVPC := makeEC2VPC(anyVPCID, availableState) + c.Check(checkVPCIsAvailable(availableVPC), jc.ErrorIsNil) + + defaultVPC := makeEC2VPC(anyVPCID, availableState) + defaultVPC.IsDefault = true + c.Check(checkVPCIsAvailable(defaultVPC), jc.ErrorIsNil) + + notAvailableVPC := makeEC2VPC(anyVPCID, anyState) + err := checkVPCIsAvailable(notAvailableVPC) + c.Assert(err, gc.ErrorMatches, `VPC has unexpected state "any state"`) + c.Check(err, jc.Satisfies, isVPCNotRecommendedError) +} + +func (s *vpcSuite) TestGetVPCSubnetUnexpectedAWSError(c *gc.C) { + s.stubAPI.SetErrors(errors.New("AWS failed!")) + + anyVPC := makeEC2VPC(anyVPCID, anyState) + subnets, err := getVPCSubnets(s.stubAPI, anyVPC) + c.Assert(err, gc.ErrorMatches, `unexpected AWS response getting subnets of VPC "vpc-anything": AWS failed!`) + c.Check(subnets, gc.IsNil) + + s.stubAPI.CheckSingleSubnetsCall(c, anyVPC) +} + +func (s *vpcSuite) TestGetVPCSubnetsNoResults(c *gc.C) { + s.stubAPI.SetSubnetsResponse(noResults, anyZone, noPublicIPOnLaunch) + + anyVPC := makeEC2VPC(anyVPCID, anyState) + subnets, err := getVPCSubnets(s.stubAPI, anyVPC) + c.Assert(err, gc.ErrorMatches, `no subnets found for VPC "vpc-anything"`) + c.Check(err, jc.Satisfies, isVPCNotUsableError) + c.Check(subnets, gc.IsNil) + + s.stubAPI.CheckSingleSubnetsCall(c, anyVPC) +} + +func (s *vpcSuite) TestGetVPCSubnetsSuccess(c *gc.C) { + s.stubAPI.SetSubnetsResponse(3, anyZone, noPublicIPOnLaunch) + + anyVPC := makeEC2VPC(anyVPCID, anyState) + subnets, err := getVPCSubnets(s.stubAPI, anyVPC) + c.Assert(err, jc.ErrorIsNil) + c.Check(subnets, jc.DeepEquals, s.stubAPI.subnetsResponse.Subnets) + + s.stubAPI.CheckSingleSubnetsCall(c, anyVPC) +} + +func (s *vpcSuite) TestFindFirstPublicSubnetSuccess(c *gc.C) { + s.stubAPI.SetSubnetsResponse(3, anyZone, withPublicIPOnLaunch) + s.stubAPI.subnetsResponse.Subnets[0].MapPublicIPOnLaunch = false + + subnet, err := findFirstPublicSubnet(s.stubAPI.subnetsResponse.Subnets) + c.Assert(err, jc.ErrorIsNil) + c.Check(subnet, jc.DeepEquals, &s.stubAPI.subnetsResponse.Subnets[1]) +} + +func (s *vpcSuite) TestFindFirstPublicSubnetNoneFound(c *gc.C) { + s.stubAPI.SetSubnetsResponse(3, anyZone, noPublicIPOnLaunch) + + subnet, err := findFirstPublicSubnet(s.stubAPI.subnetsResponse.Subnets) + c.Assert(err, gc.ErrorMatches, "VPC contains no public subnets") + c.Check(err, jc.Satisfies, isVPCNotRecommendedError) + c.Check(subnet, gc.IsNil) +} + +func (s *vpcSuite) TestGetVPCInternetGatewayNoResults(c *gc.C) { + s.stubAPI.SetGatewaysResponse(noResults, anyState) + + anyVPC := makeEC2VPC(anyVPCID, anyState) + gateway, err := getVPCInternetGateway(s.stubAPI, anyVPC) + c.Assert(err, gc.ErrorMatches, `VPC has no Internet Gateway attached`) + c.Check(err, jc.Satisfies, isVPCNotRecommendedError) + c.Check(gateway, gc.IsNil) + + s.stubAPI.CheckSingleInternetGatewaysCall(c, anyVPC) +} + +func (s *vpcSuite) TestGetVPCInternetGatewayUnexpectedAWSError(c *gc.C) { + s.stubAPI.SetErrors(errors.New("AWS failed!")) + + anyVPC := makeEC2VPC(anyVPCID, anyState) + gateway, err := getVPCInternetGateway(s.stubAPI, anyVPC) + c.Assert(err, gc.ErrorMatches, `unexpected AWS response getting Internet Gateway of VPC "vpc-anything": AWS failed!`) + c.Check(gateway, gc.IsNil) + + s.stubAPI.CheckSingleInternetGatewaysCall(c, anyVPC) +} + +func (s *vpcSuite) TestGetVPCInternetGatewayMultipleResults(c *gc.C) { + s.stubAPI.SetGatewaysResponse(3, anyState) + + anyVPC := makeEC2VPC(anyVPCID, anyState) + gateway, err := getVPCInternetGateway(s.stubAPI, anyVPC) + c.Assert(err, gc.ErrorMatches, "expected 1 result from AWS, got 3") + c.Check(gateway, gc.IsNil) + + s.stubAPI.CheckSingleInternetGatewaysCall(c, anyVPC) +} + +func (s *vpcSuite) TestGetVPCInternetGatewaySuccess(c *gc.C) { + s.stubAPI.SetGatewaysResponse(1, anyState) + + anyVPC := makeEC2VPC(anyVPCID, anyState) + gateway, err := getVPCInternetGateway(s.stubAPI, anyVPC) + c.Assert(err, jc.ErrorIsNil) + c.Check(gateway, jc.DeepEquals, &s.stubAPI.gatewaysResponse.InternetGateways[0]) + + s.stubAPI.CheckSingleInternetGatewaysCall(c, anyVPC) +} + +func (s *vpcSuite) TestCheckInternetGatewayIsAvailable(c *gc.C) { + availableIGW := makeEC2InternetGateway(anyGatewayID, availableState) + c.Check(checkInternetGatewayIsAvailable(availableIGW), jc.ErrorIsNil) + + pendingIGW := makeEC2InternetGateway(anyGatewayID, "pending") + err := checkInternetGatewayIsAvailable(pendingIGW) + c.Assert(err, gc.ErrorMatches, `VPC has Internet Gateway "igw-anything" in unexpected state "pending"`) + c.Check(err, jc.Satisfies, isVPCNotRecommendedError) +} + +func (s *vpcSuite) TestGetVPCRouteTablesNoResults(c *gc.C) { + s.stubAPI.SetRouteTablesResponse() // no results + + anyVPC := makeEC2VPC(anyVPCID, anyState) + tables, err := getVPCRouteTables(s.stubAPI, anyVPC) + c.Assert(err, gc.ErrorMatches, `VPC has no route tables`) + c.Check(err, jc.Satisfies, isVPCNotRecommendedError) + c.Check(tables, gc.IsNil) + + s.stubAPI.CheckSingleRouteTablesCall(c, anyVPC) +} + +func (s *vpcSuite) TestGetVPCRouteTablesUnexpectedAWSError(c *gc.C) { + s.stubAPI.SetErrors(errors.New("AWS failed!")) + + anyVPC := makeEC2VPC(anyVPCID, anyState) + tables, err := getVPCRouteTables(s.stubAPI, anyVPC) + c.Assert(err, gc.ErrorMatches, `unexpected AWS response getting route tables of VPC "vpc-anything": AWS failed!`) + c.Check(tables, gc.IsNil) + + s.stubAPI.CheckSingleRouteTablesCall(c, anyVPC) +} + +func (s *vpcSuite) TestGetVPCRouteTablesSuccess(c *gc.C) { + givenVPC := makeEC2VPC("vpc-given", anyState) + givenVPC.CIDRBlock = "0.1.0.0/16" + givenGateway := makeEC2InternetGateway("igw-given", availableState) + + s.stubAPI.SetRouteTablesResponse( + makeEC2RouteTable("rtb-other", notMainRouteTable, []string{"subnet-1", "subnet-2"}, nil), + makeEC2RouteTable("rtb-main", mainRouteTable, nil, makeEC2Routes( + givenGateway.Id, givenVPC.CIDRBlock, activeState, 3, // 3 extra routes + )), + ) + + tables, err := getVPCRouteTables(s.stubAPI, givenVPC) + c.Assert(err, jc.ErrorIsNil) + c.Check(tables, jc.DeepEquals, s.stubAPI.routeTablesResponse.Tables) + + s.stubAPI.CheckSingleRouteTablesCall(c, givenVPC) +} + +func (s *vpcSuite) TestFindVPCMainRouteTableWithMainAndPerSubnetTables(c *gc.C) { + givenTables := []ec2.RouteTable{ + *makeEC2RouteTable("rtb-main", mainRouteTable, nil, nil), + *makeEC2RouteTable("rtb-2-subnets", notMainRouteTable, []string{"subnet-1", "subnet-2"}, nil), + } + + mainTable, err := findVPCMainRouteTable(givenTables) + c.Assert(err, gc.ErrorMatches, `subnet "subnet-1" not associated with VPC "vpc-anything" main route table`) + c.Check(err, jc.Satisfies, isVPCNotRecommendedError) + c.Check(mainTable, gc.IsNil) +} + +func (s *vpcSuite) TestFindVPCMainRouteTableWithOnlyNonAssociatedTables(c *gc.C) { + givenTables := []ec2.RouteTable{ + *makeEC2RouteTable("rtb-1", notMainRouteTable, nil, nil), + *makeEC2RouteTable("rtb-2", notMainRouteTable, nil, nil), + *makeEC2RouteTable("rtb-3", notMainRouteTable, nil, nil), + } + + mainTable, err := findVPCMainRouteTable(givenTables) + c.Assert(err, gc.ErrorMatches, "VPC has no associated main route table") + c.Check(err, jc.Satisfies, isVPCNotRecommendedError) + c.Check(mainTable, gc.IsNil) +} + +func (s *vpcSuite) TestFindVPCMainRouteTableWithSingleMainTable(c *gc.C) { + givenTables := []ec2.RouteTable{ + *makeEC2RouteTable("rtb-main", mainRouteTable, nil, nil), + } + + mainTable, err := findVPCMainRouteTable(givenTables) + c.Assert(err, jc.ErrorIsNil) + c.Check(mainTable, jc.DeepEquals, &givenTables[0]) +} + +func (s *vpcSuite) TestFindVPCMainRouteTableWithExtraMainTables(c *gc.C) { + givenTables := []ec2.RouteTable{ + *makeEC2RouteTable("rtb-non-associated", notMainRouteTable, nil, nil), + *makeEC2RouteTable("rtb-main", mainRouteTable, nil, nil), + *makeEC2RouteTable("rtb-main-extra", mainRouteTable, nil, nil), + } + + mainTable, err := findVPCMainRouteTable(givenTables) + c.Assert(err, jc.ErrorIsNil) + c.Check(mainTable, jc.DeepEquals, &givenTables[1]) // first found counts +} + +func (s *vpcSuite) TestCheckVPCRouteTableRoutesWithNoDefaultRoute(c *gc.C) { + vpc, table, gateway := prepareCheckVPCRouteTableRoutesArgs() + c.Check(table.Routes, gc.HasLen, 0) // no routes at all + + checkFailed := func() { + err := checkVPCRouteTableRoutes(vpc, table, gateway) + c.Assert(err, gc.ErrorMatches, `missing default route via gateway "igw-anything"`) + c.Check(err, jc.Satisfies, isVPCNotRecommendedError) + } + checkFailed() + + table.Routes = makeEC2Routes(gateway.Id, vpc.CIDRBlock, "blackhole", 3) // inactive routes only + checkFailed() + + table.Routes = makeEC2Routes("", vpc.CIDRBlock, activeState, 1) // local and 1 extra route + checkFailed() + + table.Routes = makeEC2Routes("", vpc.CIDRBlock, activeState, 0) // local route only + checkFailed() +} + +func (s *vpcSuite) TestCheckVPCRouteTableRoutesWithDefaultButNoLocalRoutes(c *gc.C) { + vpc, table, gateway := prepareCheckVPCRouteTableRoutesArgs() + table.Routes = makeEC2Routes(gateway.Id, "", activeState, 3) // default and 3 extra routes; no local route + + checkFailed := func() { + err := checkVPCRouteTableRoutes(vpc, table, gateway) + c.Assert(err, gc.ErrorMatches, `missing local route with destination "0.1.0.0/16"`) + c.Check(err, jc.Satisfies, isVPCNotRecommendedError) + } + checkFailed() + + table.Routes = makeEC2Routes(gateway.Id, "", activeState, 0) // only default route + checkFailed() +} + +func (s *vpcSuite) TestCheckVPCRouteTableRoutesSuccess(c *gc.C) { + vpc, table, gateway := prepareCheckVPCRouteTableRoutesArgs() + table.Routes = makeEC2Routes(gateway.Id, vpc.CIDRBlock, activeState, 3) // default, local and 3 extra routes + + err := checkVPCRouteTableRoutes(vpc, table, gateway) + c.Assert(err, jc.ErrorIsNil) +} + +func (s *vpcSuite) TestFindDefaultVPCIDUnexpectedAWSError(c *gc.C) { + s.stubAPI.SetErrors(errors.New("AWS failed!")) + + vpcID, err := findDefaultVPCID(s.stubAPI) + c.Assert(err, gc.ErrorMatches, "unexpected AWS response getting default-vpc account attribute: AWS failed!") + c.Check(vpcID, gc.Equals, "") + + s.stubAPI.CheckSingleAccountAttributesCall(c, "default-vpc") +} + +func (s *vpcSuite) TestFindDefaultVPCIDNoAttributeOrNoValue(c *gc.C) { + s.stubAPI.SetAttributesResponse(nil) // no attributes at all + + checkFailed := func() { + vpcID, err := findDefaultVPCID(s.stubAPI) + c.Assert(err, gc.ErrorMatches, "default-vpc account attribute not found") + c.Check(err, jc.Satisfies, errors.IsNotFound) + c.Check(vpcID, gc.Equals, "") + + s.stubAPI.CheckSingleAccountAttributesCall(c, "default-vpc") + } + checkFailed() + + s.stubAPI.SetAttributesResponse(map[string][]string{ + "any-attribute": nil, // no values + }) + checkFailed() + + s.stubAPI.SetAttributesResponse(map[string][]string{ + "not-default-vpc-attribute": []string{"foo", "bar"}, // wrong name + }) + checkFailed() + + s.stubAPI.SetAttributesResponse(map[string][]string{ + "default-vpc": nil, // name ok, no values + }) + checkFailed() + + s.stubAPI.SetAttributesResponse(map[string][]string{ + "default-vpc": []string{}, // name ok, empty values + }) + checkFailed() +} + +func (s *vpcSuite) TestFindDefaultVPCIDWithExplicitNoneValue(c *gc.C) { + s.stubAPI.SetAttributesResponse(map[string][]string{ + "default-vpc": []string{"none"}, + }) + + vpcID, err := findDefaultVPCID(s.stubAPI) + c.Assert(err, gc.ErrorMatches, "default VPC not found") + c.Check(err, jc.Satisfies, errors.IsNotFound) + c.Check(vpcID, gc.Equals, "") + + s.stubAPI.CheckSingleAccountAttributesCall(c, "default-vpc") +} + +func (s *vpcSuite) TestFindDefaultVPCIDSuccess(c *gc.C) { + s.stubAPI.SetAttributesResponse(map[string][]string{ + "default-vpc": []string{"vpc-foo", "vpc-bar"}, + }) + + vpcID, err := findDefaultVPCID(s.stubAPI) + c.Assert(err, jc.ErrorIsNil) + c.Check(vpcID, gc.Equals, "vpc-foo") // always the first value is used. + + s.stubAPI.CheckSingleAccountAttributesCall(c, "default-vpc") +} + +func (s *vpcSuite) TestGetVPCSubnetIDsForAvailabilityZoneWithSubnetsError(c *gc.C) { + s.stubAPI.SetErrors(errors.New("too cloudy")) + + anyVPC := makeEC2VPC(anyVPCID, anyState) + subnetIDs, err := getVPCSubnetIDsForAvailabilityZone(s.stubAPI, anyVPC.Id, anyZone) + c.Assert(err, gc.ErrorMatches, `cannot get VPC "vpc-anything" subnets: unexpected AWS .*: too cloudy`) + c.Check(subnetIDs, gc.IsNil) + + s.stubAPI.CheckSingleSubnetsCall(c, anyVPC) +} + +func (s *vpcSuite) TestGetVPCSubnetIDsForAvailabilityZoneNoSubnetsAtAll(c *gc.C) { + s.stubAPI.SetSubnetsResponse(noResults, anyZone, noPublicIPOnLaunch) + + anyVPC := makeEC2VPC(anyVPCID, anyState) + subnetIDs, err := getVPCSubnetIDsForAvailabilityZone(s.stubAPI, anyVPC.Id, anyZone) + c.Assert(err, gc.ErrorMatches, `VPC "vpc-anything" has no subnets in AZ "any-zone": no subnets found for VPC.*`) + c.Check(err, jc.Satisfies, errors.IsNotFound) + c.Check(subnetIDs, gc.IsNil) + + s.stubAPI.CheckSingleSubnetsCall(c, anyVPC) +} + +func (s *vpcSuite) TestGetVPCSubnetIDsForAvailabilityZoneNoSubnetsInAZ(c *gc.C) { + s.stubAPI.SetSubnetsResponse(3, "other-zone", noPublicIPOnLaunch) + + anyVPC := makeEC2VPC(anyVPCID, anyState) + subnetIDs, err := getVPCSubnetIDsForAvailabilityZone(s.stubAPI, anyVPC.Id, "given-zone") + c.Assert(err, gc.ErrorMatches, `VPC "vpc-anything" has no subnets in AZ "given-zone"`) + c.Check(err, jc.Satisfies, errors.IsNotFound) + c.Check(subnetIDs, gc.IsNil) + + s.stubAPI.CheckSingleSubnetsCall(c, anyVPC) +} + +func (s *vpcSuite) TestGetVPCSubnetIDsForAvailabilityZoneSuccess(c *gc.C) { + s.stubAPI.SetSubnetsResponse(2, "my-zone", noPublicIPOnLaunch) + + anyVPC := makeEC2VPC(anyVPCID, anyState) + subnetIDs, err := getVPCSubnetIDsForAvailabilityZone(s.stubAPI, anyVPC.Id, "my-zone") + c.Assert(err, jc.ErrorIsNil) + // Result slice of IDs is always sorted. + c.Check(subnetIDs, jc.DeepEquals, []string{"subnet-0", "subnet-1"}) + + s.stubAPI.CheckSingleSubnetsCall(c, anyVPC) +} + +var fakeSubnetsToZones = map[network.Id][]string{ + "subnet-foo": []string{"az1", "az2"}, + "subnet-bar": []string{"az1"}, + "subnet-oof": []string{"az3"}, +} + +func (s *vpcSuite) TestFindSubnetIDsForAvailabilityZoneNoneFound(c *gc.C) { + subnetIDs, err := findSubnetIDsForAvailabilityZone("unknown-zone", fakeSubnetsToZones) + c.Assert(err, gc.ErrorMatches, `subnets in AZ "unknown-zone" not found`) + c.Check(err, jc.Satisfies, errors.IsNotFound) + c.Check(subnetIDs, gc.IsNil) +} + +func (s *vpcSuite) TestFindSubnetIDsForAvailabilityOneMatched(c *gc.C) { + subnetIDs, err := findSubnetIDsForAvailabilityZone("az3", fakeSubnetsToZones) + c.Assert(err, jc.ErrorIsNil) + c.Check(subnetIDs, gc.DeepEquals, []string{"subnet-oof"}) +} + +func (s *vpcSuite) TestFindSubnetIDsForAvailabilityMultipleMatched(c *gc.C) { + subnetIDs, err := findSubnetIDsForAvailabilityZone("az1", fakeSubnetsToZones) + c.Assert(err, jc.ErrorIsNil) + // Result slice of IDs is always sorted. + c.Check(subnetIDs, gc.DeepEquals, []string{"subnet-bar", "subnet-foo"}) +} + +const ( + notDefaultVPC = false + defaultVPC = true + + notMainRouteTable = false + mainRouteTable = true + + noResults = 0 + + anyState = "any state" + anyVPCID = "vpc-anything" + anyGatewayID = "igw-anything" + anyTableID = "rtb-anything" + anyZone = "any-zone" + + noPublicIPOnLaunch = false + withPublicIPOnLaunch = true +) + +type stubVPCAPIClient struct { + *testing.Stub + vpcAPIClient // embedded mostly for documentation + + attributesResponse *ec2.AccountAttributesResp + vpcsResponse *ec2.VPCsResp + subnetsResponse *ec2.SubnetsResp + gatewaysResponse *ec2.InternetGatewaysResp + routeTablesResponse *ec2.RouteTablesResp +} + +// AccountAttributes implements vpcAPIClient and is used to test finding the +// default VPC from the "default-vpc"" attribute. +func (s *stubVPCAPIClient) AccountAttributes(attributeNames ...string) (*ec2.AccountAttributesResp, error) { + s.Stub.AddCall("AccountAttributes", makeArgsFromStrings(attributeNames...)...) + return s.attributesResponse, s.Stub.NextErr() +} + +// VPCs implements vpcAPIClient and is used to test getting the details of a +// VPC. +func (s *stubVPCAPIClient) VPCs(ids []string, filter *ec2.Filter) (*ec2.VPCsResp, error) { + s.Stub.AddCall("VPCs", ids, filter) + return s.vpcsResponse, s.Stub.NextErr() +} + +// Subnets implements vpcAPIClient and is used to test getting a VPC's subnets. +func (s *stubVPCAPIClient) Subnets(ids []string, filter *ec2.Filter) (*ec2.SubnetsResp, error) { + s.Stub.AddCall("Subnets", ids, filter) + return s.subnetsResponse, s.Stub.NextErr() +} + +// InternetGateways implements vpcAPIClient and is used to test getting the +// attached IGW of a VPC. +func (s *stubVPCAPIClient) InternetGateways(ids []string, filter *ec2.Filter) (*ec2.InternetGatewaysResp, error) { + s.Stub.AddCall("InternetGateways", ids, filter) + return s.gatewaysResponse, s.Stub.NextErr() +} + +// RouteTables implements vpcAPIClient and is used to test getting all route +// tables of a VPC, alond with their routes. +func (s *stubVPCAPIClient) RouteTables(ids []string, filter *ec2.Filter) (*ec2.RouteTablesResp, error) { + s.Stub.AddCall("RouteTables", ids, filter) + return s.routeTablesResponse, s.Stub.NextErr() +} + +func (s *stubVPCAPIClient) SetAttributesResponse(attributeNameToValues map[string][]string) { + s.attributesResponse = &ec2.AccountAttributesResp{ + RequestId: "fake-request-id", + Attributes: make([]ec2.AccountAttribute, 0, len(attributeNameToValues)), + } + + for name, values := range attributeNameToValues { + attribute := ec2.AccountAttribute{ + Name: name, + Values: values, + } + s.attributesResponse.Attributes = append(s.attributesResponse.Attributes, attribute) + } +} +func (s *stubVPCAPIClient) CheckSingleAccountAttributesCall(c *gc.C, attributeNames ...string) { + s.Stub.CheckCallNames(c, "AccountAttributes") + s.Stub.CheckCall(c, 0, "AccountAttributes", makeArgsFromStrings(attributeNames...)...) + s.Stub.ResetCalls() +} + +func (s *stubVPCAPIClient) SetVPCsResponse(numResults int, state string, isDefault bool) { + s.vpcsResponse = &ec2.VPCsResp{ + RequestId: "fake-request-id", + VPCs: make([]ec2.VPC, numResults), + } + + for i := range s.vpcsResponse.VPCs { + id := fmt.Sprintf("vpc-%d", i) + vpc := makeEC2VPC(id, state) + vpc.IsDefault = isDefault + s.vpcsResponse.VPCs[i] = *vpc + } +} + +func (s *stubVPCAPIClient) CheckSingleVPCsCall(c *gc.C, vpcID string) { + var nilFilter *ec2.Filter + s.Stub.CheckCallNames(c, "VPCs") + s.Stub.CheckCall(c, 0, "VPCs", []string{vpcID}, nilFilter) + s.Stub.ResetCalls() +} + +func (s *stubVPCAPIClient) SetSubnetsResponse(numResults int, zone string, mapPublicIpOnLaunch bool) { + s.subnetsResponse = &ec2.SubnetsResp{ + RequestId: "fake-request-id", + Subnets: make([]ec2.Subnet, numResults), + } + + for i := range s.subnetsResponse.Subnets { + s.subnetsResponse.Subnets[i] = ec2.Subnet{ + Id: fmt.Sprintf("subnet-%d", i), + VPCId: anyVPCID, + State: anyState, + AvailZone: zone, + CIDRBlock: fmt.Sprintf("0.1.%d.0/20", i), + MapPublicIPOnLaunch: mapPublicIpOnLaunch, + } + } +} + +func (s *stubVPCAPIClient) CheckSingleSubnetsCall(c *gc.C, vpc *ec2.VPC) { + var nilIDs []string + filter := ec2.NewFilter() + filter.Add("vpc-id", vpc.Id) + + s.Stub.CheckCallNames(c, "Subnets") + s.Stub.CheckCall(c, 0, "Subnets", nilIDs, filter) + s.Stub.ResetCalls() +} + +func (s *stubVPCAPIClient) SetGatewaysResponse(numResults int, attachmentState string) { + s.gatewaysResponse = &ec2.InternetGatewaysResp{ + RequestId: "fake-request-id", + InternetGateways: make([]ec2.InternetGateway, numResults), + } + + for i := range s.gatewaysResponse.InternetGateways { + id := fmt.Sprintf("igw-%d", i) + gateway := makeEC2InternetGateway(id, attachmentState) + s.gatewaysResponse.InternetGateways[i] = *gateway + } +} + +func (s *stubVPCAPIClient) CheckSingleInternetGatewaysCall(c *gc.C, vpc *ec2.VPC) { + var nilIDs []string + filter := ec2.NewFilter() + filter.Add("attachment.vpc-id", vpc.Id) + + s.Stub.CheckCallNames(c, "InternetGateways") + s.Stub.CheckCall(c, 0, "InternetGateways", nilIDs, filter) + s.Stub.ResetCalls() +} + +func (s *stubVPCAPIClient) SetRouteTablesResponse(tables ...*ec2.RouteTable) { + s.routeTablesResponse = &ec2.RouteTablesResp{ + RequestId: "fake-request-id", + Tables: make([]ec2.RouteTable, len(tables)), + } + + for i := range s.routeTablesResponse.Tables { + s.routeTablesResponse.Tables[i] = *tables[i] + } +} + +func (s *stubVPCAPIClient) CheckSingleRouteTablesCall(c *gc.C, vpc *ec2.VPC) { + var nilIDs []string + filter := ec2.NewFilter() + filter.Add("vpc-id", vpc.Id) + + s.Stub.CheckCallNames(c, "RouteTables") + s.Stub.CheckCall(c, 0, "RouteTables", nilIDs, filter) + s.Stub.ResetCalls() +} + +func (s *stubVPCAPIClient) PrepareValidateVPCResponses() { + s.SetVPCsResponse(1, availableState, notDefaultVPC) + s.vpcsResponse.VPCs[0].CIDRBlock = "0.1.0.0/16" + s.SetSubnetsResponse(1, anyZone, withPublicIPOnLaunch) + s.SetGatewaysResponse(1, availableState) + onlyDefaultAndLocalRoutes := makeEC2Routes( + s.gatewaysResponse.InternetGateways[0].Id, + s.vpcsResponse.VPCs[0].CIDRBlock, + activeState, + 0, // no extra routes + ) + s.SetRouteTablesResponse( + makeEC2RouteTable(anyTableID, mainRouteTable, nil, onlyDefaultAndLocalRoutes), + ) +} + +func (s *stubVPCAPIClient) CallValidateVPCAndCheckCallsUpToExpectingVPCNotRecommendedError(c *gc.C, lastExpectedCallName string) { + err := validateVPC(s, anyVPCID) + c.Assert(err, jc.Satisfies, isVPCNotRecommendedError) + + allCalls := []string{"VPCs", "Subnets", "InternetGateways", "RouteTables"} + var expectedCalls []string + for i := range allCalls { + expectedCalls = append(expectedCalls, allCalls[i]) + if allCalls[i] == lastExpectedCallName { + break + } + } + s.CheckCallNames(c, expectedCalls...) +} + +func makeEC2VPC(vpcID, state string) *ec2.VPC { + return &ec2.VPC{ + Id: vpcID, + State: state, + } +} + +func makeEC2InternetGateway(gatewayID, attachmentState string) *ec2.InternetGateway { + return &ec2.InternetGateway{ + Id: gatewayID, + VPCId: anyVPCID, + AttachmentState: attachmentState, + } +} + +func makeEC2RouteTable(tableID string, isMain bool, associatedSubnetIDs []string, routes []ec2.Route) *ec2.RouteTable { + table := &ec2.RouteTable{ + Id: tableID, + VPCId: anyVPCID, + Routes: routes, + } + + if isMain { + table.Associations = []ec2.RouteTableAssociation{{ + Id: "rtbassoc-main", + TableId: tableID, + IsMain: true, + }} + } else { + table.Associations = make([]ec2.RouteTableAssociation, len(associatedSubnetIDs)) + for i := range associatedSubnetIDs { + table.Associations[i] = ec2.RouteTableAssociation{ + Id: fmt.Sprintf("rtbassoc-%d", i), + TableId: tableID, + SubnetId: associatedSubnetIDs[i], + } + } + } + return table +} + +func makeEC2Routes(defaultRouteGatewayID, localRouteCIDRBlock, state string, numExtraRoutes int) []ec2.Route { + var routes []ec2.Route + + if defaultRouteGatewayID != "" { + routes = append(routes, ec2.Route{ + DestinationCIDRBlock: defaultRouteCIDRBlock, + GatewayId: defaultRouteGatewayID, + State: state, + }) + } + + if localRouteCIDRBlock != "" { + routes = append(routes, ec2.Route{ + DestinationCIDRBlock: localRouteCIDRBlock, + GatewayId: localRouteGatewayID, + State: state, + }) + } + + if numExtraRoutes > 0 { + for i := 0; i < numExtraRoutes; i++ { + routes = append(routes, ec2.Route{ + DestinationCIDRBlock: fmt.Sprintf("0.1.%d.0/24", i), + State: state, + }) + } + } + + return routes +} + +func prepareCheckVPCRouteTableRoutesArgs() (*ec2.VPC, *ec2.RouteTable, *ec2.InternetGateway) { + anyVPC := makeEC2VPC(anyVPCID, anyState) + anyVPC.CIDRBlock = "0.1.0.0/16" + anyTable := makeEC2RouteTable(anyTableID, notMainRouteTable, nil, nil) + anyGateway := makeEC2InternetGateway(anyGatewayID, anyState) + + return anyVPC, anyTable, anyGateway +} + +func makeEC2Error(statusCode int, code, message, requestID string) error { + return &ec2.Error{ + StatusCode: statusCode, + Code: code, + Message: message, + RequestId: requestID, + } +} + +func makeVPCNotFoundError(vpcID string) error { + return makeEC2Error( + 400, + "InvalidVpcID.NotFound", + fmt.Sprintf("The vpc ID '%s' does not exist", vpcID), + "fake-request-id", + ) +} + +func makeArgsFromStrings(strings ...string) []interface{} { + args := make([]interface{}, len(strings)) + for i := range strings { + args[i] = strings[i] + } + return args +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/export_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/export_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/export_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/export_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -153,10 +153,14 @@ } var TestImageMetadata = []*imagemetadata.ImageMetadata{ + // LTS-dependent requires new entries upon new LTS release. + // 16.04:amd64 + makeImage("ami-00000133", "ssd", "pv", "amd64", "16.04", "test"), + makeImage("ami-00000139", "ebs", "pv", "amd64", "16.04", "test"), + makeImage("ami-00000135", "ssd", "hvm", "amd64", "16.04", "test"), + // 14.04:amd64 makeImage("ami-00000033", "ssd", "pv", "amd64", "14.04", "test"), - makeImage("ami-00000039", "ebs", "pv", "amd64", "14.04", "test"), - makeImage("ami-00000035", "ssd", "hvm", "amd64", "14.04", "test"), // 14.04:i386 makeImage("ami-00000034", "ssd", "pv", "i386", "14.04", "test"), @@ -172,6 +176,7 @@ } var TestImagesData = map[string]string{ + // LTS-dependent requires new/updated entries upon new LTS release. "/streams/v1/index.json": ` { "index": { @@ -187,10 +192,9 @@ "datatype": "image-ids", "format": "products:1.0", "products": [ + "com.ubuntu.cloud:server:16.04:amd64", "com.ubuntu.cloud:server:14.04:amd64", "com.ubuntu.cloud:server:14.04:i386", - "com.ubuntu.cloud:server:14.04:amd64", - "com.ubuntu.cloud:server:12.10:amd64", "com.ubuntu.cloud:server:12.10:i386", "com.ubuntu.cloud:server:13.04:i386" ], @@ -205,9 +209,9 @@ { "content_id": "com.ubuntu.cloud:released:aws", "products": { - "com.ubuntu.cloud:server:14.04:amd64": { + "com.ubuntu.cloud:server:16.04:amd64": { "release": "trusty", - "version": "14.04", + "version": "16.04", "arch": "amd64", "versions": { "20121218": { @@ -216,45 +220,64 @@ "root_store": "instance", "virt": "pv", "region": "us-east-1", - "id": "ami-00000011" + "id": "ami-00000111" }, "usww1pe": { "root_store": "ssd", "virt": "pv", "region": "eu-west-1", - "id": "ami-00000016" + "id": "ami-00000116" }, "apne1pe": { "root_store": "ssd", "virt": "pv", "region": "ap-northeast-1", - "id": "ami-00000026" + "id": "ami-00000126" }, "apne1he": { "root_store": "ssd", "virt": "hvm", "region": "ap-northeast-1", - "id": "ami-00000087" + "id": "ami-00000187" }, "test1peebs": { "root_store": "ssd", "virt": "pv", "region": "test", - "id": "ami-00000033" + "id": "ami-00000133" }, "test1pessd": { "root_store": "ebs", "virt": "pv", "region": "test", - "id": "ami-00000039" + "id": "ami-00000139" }, "test1he": { "root_store": "ssd", "virt": "hvm", "region": "test", - "id": "ami-00000035" + "id": "ami-00000135" } }, + "pubname": "ubuntu-trusty-16.04-amd64-server-20121218", + "label": "release" + } + } + }, + "com.ubuntu.cloud:server:14.04:amd64": { + "release": "trusty", + "version": "14.04", + "arch": "amd64", + "versions": { + "20121218": { + "items": { + "test1peebs": { + "root_store": "ssd", + "virt": "pv", + "region": "test", + "id": "ami-00000033" + } + }, "pubname": "ubuntu-trusty-14.04-amd64-server-20121218", "label": "release" } @@ -272,12 +295,6 @@ "virt": "pv", "region": "test", "id": "ami-00000034" - }, - "apne1pe": { - "root_store": "ssd", - "virt": "pv", - "region": "ap-northeast-1", - "id": "ami-00000023" } }, "pubname": "ubuntu-trusty-14.04-i386-server-20121218", diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/image.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/image.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/image.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/image.go 2016-05-17 20:01:14.000000000 +0000 @@ -24,11 +24,13 @@ for _, image := range images { imagesByStorage[image.Storage] = append(imagesByStorage[image.Storage], image) } + logger.Debugf("images by storage type %+v", imagesByStorage) // If a storage constraint has been specified, use that or else default to ssd. storageTypes := []string{ssdStorage} if ic != nil && len(ic.Storage) > 0 { storageTypes = ic.Storage } + logger.Debugf("filtering storage types %+v", storageTypes) // Return the first set of images for which we have a storage type match. for _, storageType := range storageTypes { if len(imagesByStorage[storageType]) > 0 { @@ -45,7 +47,7 @@ allImageMetadata []*imagemetadata.ImageMetadata, ic *instances.InstanceConstraint, ) (*instances.InstanceSpec, error) { - + logger.Debugf("received %d image(s)", len(allImageMetadata)) // If the instance type is set, don't also set a default CPU power // as this is implied. cons := ic.Constraints @@ -53,6 +55,7 @@ ic.Constraints.CpuPower = instances.CpuPower(defaultCpuPower) } suitableImages := filterImages(allImageMetadata, ic) + logger.Debugf("found %d suitable image(s)", len(suitableImages)) images := instances.ImageMetadataToImages(suitableImages) // Make a copy of the known EC2 instance types, filling in the cost for the specified region. diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/image_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/image_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/image_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/image_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,6 +4,8 @@ package ec2 import ( + "fmt" + jc "github.com/juju/testing/checkers" "github.com/juju/utils/series" gc "gopkg.in/check.v1" @@ -46,6 +48,7 @@ } var findInstanceSpecTests = []struct { + // LTS-dependent requires new or updated entries upon a new LTS release. series string arches []string cons string @@ -54,63 +57,88 @@ storage []string }{ { - series: testing.FakeDefaultSeries, - arches: both, + series: "xenial", + arches: []string{"amd64"}, itype: "m3.medium", - image: "ami-00000033", + image: "ami-00000133", }, { series: "quantal", arches: []string{"i386"}, itype: "c1.medium", image: "ami-01000034", }, { - series: testing.FakeDefaultSeries, - arches: both, + series: "xenial", + arches: []string{"amd64"}, cons: "cpu-cores=4", itype: "m3.xlarge", - image: "ami-00000033", + image: "ami-00000133", }, { - series: testing.FakeDefaultSeries, - arches: both, - cons: "cpu-cores=2 arch=i386", - itype: "c1.medium", - image: "ami-00000034", - }, { - series: testing.FakeDefaultSeries, - arches: both, + series: "xenial", + arches: []string{"amd64"}, cons: "mem=10G", itype: "m3.xlarge", - image: "ami-00000033", + image: "ami-00000133", }, { - series: testing.FakeDefaultSeries, - arches: both, + series: "xenial", + arches: []string{"amd64"}, cons: "mem=", itype: "m3.medium", - image: "ami-00000033", + image: "ami-00000133", }, { - series: testing.FakeDefaultSeries, - arches: both, + series: "xenial", + arches: []string{"amd64"}, cons: "cpu-power=", itype: "m3.medium", - image: "ami-00000033", + image: "ami-00000133", }, { - series: testing.FakeDefaultSeries, - arches: both, + series: "xenial", + arches: []string{"amd64"}, cons: "cpu-power=800", itype: "m3.xlarge", - image: "ami-00000033", + image: "ami-00000133", }, { - series: testing.FakeDefaultSeries, - arches: both, - cons: "cpu-power=500 arch=i386", - itype: "c1.medium", - image: "ami-00000034", + series: "xenial", + arches: []string{"amd64"}, + cons: "instance-type=m1.medium cpu-power=200", + itype: "m1.medium", + image: "ami-00000133", + }, { + series: "xenial", + arches: []string{"amd64"}, + cons: "mem=2G root-disk=16384M", + itype: "m3.medium", + image: "ami-00000133", + }, { + series: "xenial", + arches: []string{"amd64"}, + cons: "mem=4G root-disk=16384M", + itype: "m3.large", + storage: []string{"ssd", "ebs"}, + image: "ami-00000133", + }, { + series: "xenial", + arches: []string{"amd64"}, + cons: "mem=4G root-disk=16384M", + itype: "m3.large", + storage: []string{"ebs", "ssd"}, + image: "ami-00000139", + }, { + series: "xenial", + arches: []string{"amd64"}, + cons: "mem=4G root-disk=16384M", + itype: "m3.large", + storage: []string{"ebs"}, + image: "ami-00000139", }, { - series: testing.FakeDefaultSeries, + series: "trusty", + arches: []string{"amd64"}, + itype: "m3.medium", + image: "ami-00000033", + }, { + series: "quantal", arches: []string{"i386"}, - cons: "cpu-power=400", itype: "c1.medium", - image: "ami-00000034", + image: "ami-01000034", }, { series: "quantal", arches: both, @@ -124,44 +152,11 @@ itype: "cc2.8xlarge", image: "ami-01000035", }, { - series: testing.FakeDefaultSeries, + series: "trusty", arches: []string{"i386"}, cons: "instance-type=c1.medium", itype: "c1.medium", image: "ami-00000034", - }, { - series: testing.FakeDefaultSeries, - arches: []string{"amd64"}, - cons: "instance-type=m1.medium cpu-power=200", - itype: "m1.medium", - image: "ami-00000033", - }, { - series: testing.FakeDefaultSeries, - arches: both, - cons: "mem=2G root-disk=16384M", - itype: "m3.medium", - image: "ami-00000033", - }, { - series: testing.FakeDefaultSeries, - arches: both, - cons: "mem=4G root-disk=16384M", - itype: "m3.large", - storage: []string{"ssd", "ebs"}, - image: "ami-00000033", - }, { - series: testing.FakeDefaultSeries, - arches: both, - cons: "mem=4G root-disk=16384M", - itype: "m3.large", - storage: []string{"ebs", "ssd"}, - image: "ami-00000039", - }, { - series: testing.FakeDefaultSeries, - arches: both, - cons: "mem=4G root-disk=16384M", - itype: "m3.large", - storage: []string{"ebs"}, - image: "ami-00000039", }, } @@ -197,7 +192,7 @@ instanceConstraint := &instances.InstanceConstraint{ Region: "test", - Series: testing.FakeDefaultSeries, + Series: series.LatestLts(), Constraints: constraints.MustParse("instance-type=t2.medium"), } @@ -214,17 +209,17 @@ err string }{ { - series: testing.FakeDefaultSeries, + series: series.LatestLts(), arches: []string{"arm"}, - err: `no "trusty" images in test with arches \[arm\]`, + err: fmt.Sprintf(`no "%s" images in test with arches \[arm\]`, series.LatestLts()), }, { series: "raring", arches: both, cons: "mem=4G", err: `no "raring" images in test matching instance types \[m3.large m3.xlarge c1.xlarge m3.2xlarge cc2.8xlarge\]`, }, { - series: testing.FakeDefaultSeries, - arches: both, + series: series.LatestLts(), + arches: []string{"amd64"}, cons: "instance-type=m1.small mem=4G", err: `no instance types in test matching constraints "instance-type=m1.small mem=4096M"`, }, diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/instance.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/instance.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/instance.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/instance.go 2016-05-17 20:01:14.000000000 +0000 @@ -80,8 +80,7 @@ inst.e.Config().FirewallMode()) } name := inst.e.machineGroupName(machineId) - legacyName := inst.e.legacyMachineGroupName(machineId) - if err := inst.e.openPortsInGroup(name, legacyName, ports); err != nil { + if err := inst.e.openPortsInGroup(name, ports); err != nil { return err } logger.Infof("opened ports in security group %s: %v", name, ports) @@ -94,8 +93,7 @@ inst.e.Config().FirewallMode()) } name := inst.e.machineGroupName(machineId) - legacyName := inst.e.legacyMachineGroupName(machineId) - if err := inst.e.closePortsInGroup(name, legacyName, ports); err != nil { + if err := inst.e.closePortsInGroup(name, ports); err != nil { return err } logger.Infof("closed ports in security group %s: %v", name, ports) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/live_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/live_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/live_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/live_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -79,7 +79,7 @@ t.LiveTests.SetUpSuite(c) t.BaseSuite.PatchValue(&jujuversion.Current, coretesting.FakeVersionNumber) t.BaseSuite.PatchValue(&arch.HostArch, func() string { return arch.AMD64 }) - t.BaseSuite.PatchValue(&series.HostSeries, func() string { return coretesting.FakeDefaultSeries }) + t.BaseSuite.PatchValue(&series.HostSeries, func() string { return series.LatestLts() }) } func (t *LiveTests) TearDownSuite(c *gc.C) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/local_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/local_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/local_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/local_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -12,9 +12,11 @@ "strings" "github.com/juju/errors" + "github.com/juju/names" jc "github.com/juju/testing/checkers" "github.com/juju/utils" "github.com/juju/utils/arch" + "github.com/juju/utils/clock" "github.com/juju/utils/series" "github.com/juju/utils/set" "github.com/juju/utils/ssh" @@ -34,6 +36,7 @@ "github.com/juju/juju/environs/jujutest" "github.com/juju/juju/environs/simplestreams" sstesting "github.com/juju/juju/environs/simplestreams/testing" + "github.com/juju/juju/environs/tags" envtesting "github.com/juju/juju/environs/testing" "github.com/juju/juju/environs/tools" "github.com/juju/juju/feature" @@ -44,6 +47,7 @@ "github.com/juju/juju/network" "github.com/juju/juju/provider/common" "github.com/juju/juju/provider/ec2" + "github.com/juju/juju/storage" coretesting "github.com/juju/juju/testing" jujuversion "github.com/juju/juju/version" ) @@ -117,9 +121,13 @@ // instances. createRootDisks bool + client *amzec2.EC2 ec2srv *ec2test.Server s3srv *s3test.Server config *s3test.Config + + defaultVPC *amzec2.VPC + zones []amzec2.AvailabilityZoneInfo } func (srv *localServer) startServer(c *gc.C) { @@ -141,6 +149,10 @@ } srv.addSpice(c) + region := aws.Regions["test"] + signer := aws.SignV4Factory(region.Name, "ec2") + srv.client = amzec2.New(aws.Auth{}, region, signer) + zones := make([]amzec2.AvailabilityZoneInfo, 3) zones[0].Region = "test" zones[0].Name = "test-available" @@ -153,6 +165,11 @@ zones[2].State = "unavailable" srv.ec2srv.SetAvailabilityZones(zones) srv.ec2srv.SetInitialInstanceState(ec2test.Pending) + srv.zones = zones + + defaultVPC, err := srv.ec2srv.AddDefaultVPCAndSubnets() + c.Assert(err, jc.ErrorIsNil) + srv.defaultVPC = &defaultVPC } // addSpice adds some "spice" to the local server @@ -169,11 +186,14 @@ } func (srv *localServer) stopServer(c *gc.C) { + srv.ec2srv.Reset(false) srv.ec2srv.Quit() srv.s3srv.Quit() // Clear out the region because the server address is // no longer valid. delete(aws.Regions, "test") + + srv.defaultVPC = nil } // localServerSuite contains tests that run against a fake EC2 server @@ -210,7 +230,7 @@ t.BaseSuite.PatchValue(&juju.JujuPublicKey, sstesting.SignedMetadataPublicKey) t.BaseSuite.PatchValue(&jujuversion.Current, coretesting.FakeVersionNumber) t.BaseSuite.PatchValue(&arch.HostArch, func() string { return arch.AMD64 }) - t.BaseSuite.PatchValue(&series.HostSeries, func() string { return coretesting.FakeDefaultSeries }) + t.BaseSuite.PatchValue(&series.HostSeries, func() string { return series.LatestLts() }) t.BaseSuite.PatchValue(ec2.DeleteSecurityGroupInsistently, deleteSecurityGroupForTestFunc) t.srv.createRootDisks = true t.srv.startServer(c) @@ -247,9 +267,12 @@ return netenv } -func (t *localServerSuite) TestBootstrapInstanceUserDataAndState(c *gc.C) { +func (t *localServerSuite) TestSystemdBootstrapInstanceUserDataAndState(c *gc.C) { env := t.Prepare(c) - err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) + err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), env, bootstrap.BootstrapParams{ + // TODO(redir): BBB: When we no longer support upstart based systems this can change to series.LatestLts() + BootstrapSeries: "xenial", + }) c.Assert(err, jc.ErrorIsNil) // check that ControllerInstances returns the id of the bootstrap machine. @@ -262,11 +285,93 @@ c.Assert(insts, gc.HasLen, 1) c.Check(insts[0].Id(), gc.Equals, instanceIds[0]) - // check that the user data is configured to start zookeeper - // and the machine and provisioning agents. - // check that the user data is configured to only configure - // authorized SSH keys and set the log output; everything - // else happens after the machine is brought up. + // check that the user data is configured to and the machine and + // provisioning agents. check that the user data is configured to only + // configure authorized SSH keys and set the log output; everything else + // happens after the machine is brought up. + inst := t.srv.ec2srv.Instance(string(insts[0].Id())) + c.Assert(inst, gc.NotNil) + addresses, err := insts[0].Addresses() + c.Assert(err, jc.ErrorIsNil) + c.Assert(addresses, gc.Not(gc.HasLen), 0) + userData, err := utils.Gunzip(inst.UserData) + c.Assert(err, jc.ErrorIsNil) + c.Assert(string(userData), jc.YAMLEquals, map[interface{}]interface{}{ + "output": map[interface{}]interface{}{ + "all": "| tee -a /var/log/cloud-init-output.log", + }, + "users": []interface{}{ + map[interface{}]interface{}{ + "name": "ubuntu", + "lock_passwd": true, + "groups": []interface{}{"adm", "audio", + "cdrom", "dialout", "dip", "floppy", + "netdev", "plugdev", "sudo", "video"}, + "shell": "/bin/bash", + "sudo": []interface{}{"ALL=(ALL) NOPASSWD:ALL"}, + "ssh-authorized-keys": splitAuthKeys(env.Config().AuthorizedKeys()), + }, + }, + "runcmd": []interface{}{ + "set -xe", + "install -D -m 644 /dev/null '/etc/systemd/system/juju-clean-shutdown.service'", + "printf '%s\\n' '\n[Unit]\nDescription=Stop all network interfaces on shutdown\nDefaultDependencies=false\nAfter=final.target\n\n[Service]\nType=oneshot\nExecStart=/sbin/ifdown -a -v --force\nStandardOutput=tty\nStandardError=tty\n\n[Install]\nWantedBy=final.target\n' > '/etc/systemd/system/juju-clean-shutdown.service'", "/bin/systemctl enable '/etc/systemd/system/juju-clean-shutdown.service'", + "install -D -m 644 /dev/null '/var/lib/juju/nonce.txt'", + "printf '%s\\n' 'user-admin:bootstrap' > '/var/lib/juju/nonce.txt'", + }, + }) + + // check that a new instance will be started with a machine agent + inst1, hc := testing.AssertStartInstance(c, env, "1") + c.Check(*hc.Arch, gc.Equals, "amd64") + c.Check(*hc.Mem, gc.Equals, uint64(3840)) + c.Check(*hc.CpuCores, gc.Equals, uint64(1)) + c.Assert(*hc.CpuPower, gc.Equals, uint64(300)) + inst = t.srv.ec2srv.Instance(string(inst1.Id())) + c.Assert(inst, gc.NotNil) + userData, err = utils.Gunzip(inst.UserData) + c.Assert(err, jc.ErrorIsNil) + c.Logf("second instance: UserData: %q", userData) + var userDataMap map[interface{}]interface{} + err = goyaml.Unmarshal(userData, &userDataMap) + c.Assert(err, jc.ErrorIsNil) + CheckPackage(c, userDataMap, "curl", true) + CheckPackage(c, userDataMap, "mongodb-server", false) + CheckScripts(c, userDataMap, "jujud bootstrap-state", false) + CheckScripts(c, userDataMap, "/var/lib/juju/agents/machine-1/agent.conf", true) + // TODO check for provisioning agent + + err = env.Destroy() + c.Assert(err, jc.ErrorIsNil) + + _, err = env.ControllerInstances() + c.Assert(err, gc.Equals, environs.ErrNotBootstrapped) +} + +// TestUpstartBoostrapInstanceUserDataAndState is a test for legacy systems +// using upstart which will be around until trusty is no longer supported. +// TODO(redir): BBB: remove when trusty is no longer supported +func (t *localServerSuite) TestUpstartBootstrapInstanceUserDataAndState(c *gc.C) { + env := t.Prepare(c) + err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), env, bootstrap.BootstrapParams{ + BootstrapSeries: "trusty", + }) + c.Assert(err, jc.ErrorIsNil) + + // check that ControllerInstances returns the id of the bootstrap machine. + instanceIds, err := env.ControllerInstances() + c.Assert(err, jc.ErrorIsNil) + c.Assert(instanceIds, gc.HasLen, 1) + + insts, err := env.AllInstances() + c.Assert(err, jc.ErrorIsNil) + c.Assert(insts, gc.HasLen, 1) + c.Check(insts[0].Id(), gc.Equals, instanceIds[0]) + + // check that the user data is configured to and the machine and + // provisioning agents. check that the user data is configured to only + // configure authorized SSH keys and set the log output; everything else + // happens after the machine is brought up. inst := t.srv.ec2srv.Instance(string(insts[0].Id())) c.Assert(inst, gc.NotNil) addresses, err := insts[0].Addresses() @@ -407,22 +512,117 @@ c.Assert(groupsFilteredForTerminatedInstances, gc.HasLen, 0) } -func (t *localServerSuite) TestDestroySecurityGroupInsistentlyError(c *gc.C) { +func (t *localServerSuite) TestDestroyControllerModelDeleteSecurityGroupInsistentlyError(c *gc.C) { env := t.Prepare(c) err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) c.Assert(err, jc.ErrorIsNil) + t.testDestroyModelDeleteSecurityGroupInsistentlyError( + c, env, "destroying managed environs: cannot delete security group .*: ", + ) +} + +func (t *localServerSuite) TestDestroyHostedModelDeleteSecurityGroupInsistentlyError(c *gc.C) { + env := t.Prepare(c) + err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) - called := false + cfg, err := env.Config().Apply(map[string]interface{}{"controller-uuid": "7e386e08-cba7-44a4-a76e-7c1633584210"}) + c.Assert(err, jc.ErrorIsNil) + env, err = environs.New(cfg) + c.Assert(err, jc.ErrorIsNil) + t.testDestroyModelDeleteSecurityGroupInsistentlyError( + c, env, "cannot delete environment security groups: cannot delete default security group: ", + ) +} + +func (t *localServerSuite) testDestroyModelDeleteSecurityGroupInsistentlyError(c *gc.C, env environs.Environ, errPrefix string) { msg := "destroy security group error" - t.BaseSuite.PatchValue(ec2.DeleteSecurityGroupInsistently, func(inst ec2.SecurityGroupCleaner, group amzec2.SecurityGroup) error { - called = true + t.BaseSuite.PatchValue(ec2.DeleteSecurityGroupInsistently, func( + ec2.SecurityGroupCleaner, amzec2.SecurityGroup, clock.Clock, + ) error { return errors.New(msg) }) + err := env.Destroy() + c.Assert(err, gc.ErrorMatches, errPrefix+"destroy security group error") +} - err = env.Destroy() +func (t *localServerSuite) TestDestroyControllerDestroysHostedModelResources(c *gc.C) { + controllerEnv := t.Prepare(c) + err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), controllerEnv, bootstrap.BootstrapParams{}) + + // Create a hosted model environment with an instance and a volume. + t.srv.ec2srv.SetInitialInstanceState(ec2test.Running) + cfg, err := controllerEnv.Config().Apply(map[string]interface{}{ + "uuid": "7e386e08-cba7-44a4-a76e-7c1633584210", + "firewall-mode": "global", + }) c.Assert(err, jc.ErrorIsNil) - c.Assert(called, jc.IsTrue) - c.Assert(c.GetTestLog(), jc.Contains, "WARNING juju.provider.ec2 provider failure: destroy security group error") + env, err := environs.New(cfg) + c.Assert(err, jc.ErrorIsNil) + inst, _ := testing.AssertStartInstance(c, env, "0") + c.Assert(err, jc.ErrorIsNil) + ebsProvider := ec2.EBSProvider() + vs, err := ebsProvider.VolumeSource(env.Config(), nil) + c.Assert(err, jc.ErrorIsNil) + volumeResults, err := vs.CreateVolumes([]storage.VolumeParams{{ + Tag: names.NewVolumeTag("0"), + Size: 1024, + Provider: ec2.EBS_ProviderType, + ResourceTags: map[string]string{ + tags.JujuController: coretesting.ModelTag.Id(), + tags.JujuModel: "7e386e08-cba7-44a4-a76e-7c1633584210", + }, + Attachment: &storage.VolumeAttachmentParams{ + AttachmentParams: storage.AttachmentParams{ + InstanceId: inst.Id(), + }, + }, + }}) + c.Assert(err, jc.ErrorIsNil) + c.Assert(volumeResults, gc.HasLen, 1) + c.Assert(volumeResults[0].Error, jc.ErrorIsNil) + + assertInstances := func(expect ...instance.Id) { + insts, err := env.AllInstances() + c.Assert(err, jc.ErrorIsNil) + ids := make([]instance.Id, len(insts)) + for i, inst := range insts { + ids[i] = inst.Id() + } + c.Assert(ids, jc.SameContents, expect) + } + assertVolumes := func(expect ...string) { + volIds, err := vs.ListVolumes() + c.Assert(err, jc.ErrorIsNil) + c.Assert(volIds, jc.SameContents, expect) + } + assertGroups := func(expect ...string) { + groupsResp, err := t.srv.client.SecurityGroups(nil, nil) + c.Assert(err, jc.ErrorIsNil) + names := make([]string, len(groupsResp.Groups)) + for i, group := range groupsResp.Groups { + names[i] = group.Name + } + c.Assert(names, jc.SameContents, expect) + } + + assertInstances(inst.Id()) + assertVolumes(volumeResults[0].Volume.VolumeId) + assertGroups( + "default", + "juju-"+coretesting.ModelTag.Id(), + "juju-"+coretesting.ModelTag.Id()+"-0", + "juju-7e386e08-cba7-44a4-a76e-7c1633584210", + "juju-7e386e08-cba7-44a4-a76e-7c1633584210-global", + ) + + // Destroy the controller environment. This should destroy the hosted + // environment too. + err = controllerEnv.Destroy() + c.Assert(err, jc.ErrorIsNil) + + assertInstances() + assertVolumes() + assertGroups("default") } // splitAuthKeys splits the given authorized keys @@ -903,7 +1103,7 @@ env := t.Prepare(c) cons := constraints.MustParse("instance-type=m1.small root-disk=1G") placement := "" - err := env.PrecheckInstance(coretesting.FakeDefaultSeries, cons, placement) + err := env.PrecheckInstance(series.LatestLts(), cons, placement) c.Assert(err, jc.ErrorIsNil) } @@ -911,7 +1111,7 @@ env := t.Prepare(c) cons := constraints.MustParse("instance-type=m1.invalid") placement := "" - err := env.PrecheckInstance(coretesting.FakeDefaultSeries, cons, placement) + err := env.PrecheckInstance(series.LatestLts(), cons, placement) c.Assert(err, gc.ErrorMatches, `invalid AWS instance type "m1.invalid" specified`) } @@ -919,28 +1119,28 @@ env := t.Prepare(c) cons := constraints.MustParse("instance-type=cc1.4xlarge arch=i386") placement := "" - err := env.PrecheckInstance(coretesting.FakeDefaultSeries, cons, placement) + err := env.PrecheckInstance(series.LatestLts(), cons, placement) c.Assert(err, gc.ErrorMatches, `invalid AWS instance type "cc1.4xlarge" and arch "i386" specified`) } func (t *localServerSuite) TestPrecheckInstanceAvailZone(c *gc.C) { env := t.Prepare(c) placement := "zone=test-available" - err := env.PrecheckInstance(coretesting.FakeDefaultSeries, constraints.Value{}, placement) + err := env.PrecheckInstance(series.LatestLts(), constraints.Value{}, placement) c.Assert(err, jc.ErrorIsNil) } func (t *localServerSuite) TestPrecheckInstanceAvailZoneUnavailable(c *gc.C) { env := t.Prepare(c) placement := "zone=test-unavailable" - err := env.PrecheckInstance(coretesting.FakeDefaultSeries, constraints.Value{}, placement) + err := env.PrecheckInstance(series.LatestLts(), constraints.Value{}, placement) c.Assert(err, jc.ErrorIsNil) } func (t *localServerSuite) TestPrecheckInstanceAvailZoneUnknown(c *gc.C) { env := t.Prepare(c) placement := "zone=test-unknown" - err := env.PrecheckInstance(coretesting.FakeDefaultSeries, constraints.Value{}, placement) + err := env.PrecheckInstance(series.LatestLts(), constraints.Value{}, placement) c.Assert(err, gc.ErrorMatches, `invalid availability zone "test-unknown"`) } @@ -948,14 +1148,14 @@ env := t.Prepare(c) params, err := env.(simplestreams.MetadataValidator).MetadataLookupParams("test") c.Assert(err, jc.ErrorIsNil) - params.Series = coretesting.FakeDefaultSeries + params.Series = series.LatestLts() params.Endpoint = "https://ec2.endpoint.com" params.Sources, err = environs.ImageMetadataSources(env) c.Assert(err, jc.ErrorIsNil) image_ids, _, err := imagemetadata.ValidateImageMetadata(params) c.Assert(err, jc.ErrorIsNil) sort.Strings(image_ids) - c.Assert(image_ids, gc.DeepEquals, []string{"ami-00000033", "ami-00000034", "ami-00000035", "ami-00000039"}) + c.Assert(image_ids, gc.DeepEquals, []string{"ami-00000133", "ami-00000135", "ami-00000139"}) } func (t *localServerSuite) TestGetToolsMetadataSources(c *gc.C) { @@ -980,37 +1180,7 @@ c.Assert(supported, jc.IsTrue) } -func (t *localServerSuite) TestAllocateAddressFailureToFindNetworkInterface(c *gc.C) { - env := t.prepareEnviron(c) - err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) - c.Assert(err, jc.ErrorIsNil) - - instanceIds, err := env.ControllerInstances() - c.Assert(err, jc.ErrorIsNil) - - instId := instanceIds[0] - addr := network.Address{Value: "8.0.0.4"} - - // Invalid instance found - err = env.AllocateAddress(instId+"foo", "", &addr, "foo", "bar") - c.Assert(err, gc.ErrorMatches, ".*InvalidInstanceID.NotFound.*") - - // No network interface - err = env.AllocateAddress(instId, "", &addr, "foo", "bar") - c.Assert(errors.Cause(err), gc.ErrorMatches, "unexpected AWS response: network interface not found") - - // Nil or empty address given. - err = env.AllocateAddress(instId, "", nil, "foo", "bar") - c.Assert(errors.Cause(err), gc.ErrorMatches, "invalid address: nil or empty") - - err = env.AllocateAddress(instId, "", &network.Address{Value: ""}, "foo", "bar") - c.Assert(errors.Cause(err), gc.ErrorMatches, "invalid address: nil or empty") -} - func (t *localServerSuite) setUpInstanceWithDefaultVpc(c *gc.C) (environs.NetworkingEnviron, instance.Id) { - // Simulate a default VPC exists. - t.srv.ec2srv.AddDefaultVPCAndSubnets() - env := t.prepareEnviron(c) err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) c.Assert(err, jc.ErrorIsNil) @@ -1227,7 +1397,6 @@ } func (t *localServerSuite) TestSupportsAddressAllocationTrue(c *gc.C) { - t.srv.ec2srv.AddDefaultVPCAndSubnets() env := t.prepareEnviron(c) result, err := env.SupportsAddressAllocation("") c.Assert(err, jc.ErrorIsNil) @@ -1266,7 +1435,7 @@ }) env := t.prepareEnviron(c) result, err := env.SupportsAddressAllocation("") - c.Assert(err, jc.ErrorIsNil) + c.Assert(err, jc.Satisfies, errors.IsNotSupported) c.Assert(result, jc.IsFalse) // this value won't change normally, the change here is to @@ -1275,7 +1444,7 @@ "default-vpc": {"vpc-xxxxxxx"}, }) result, err = env.SupportsAddressAllocation("") - c.Assert(err, jc.ErrorIsNil) + c.Assert(err, jc.Satisfies, errors.IsNotSupported) c.Assert(result, jc.IsFalse) } @@ -1285,7 +1454,7 @@ }) env := t.prepareEnviron(c) result, err := env.SupportsAddressAllocation("") - c.Assert(err, jc.ErrorIsNil) + c.Assert(err, jc.Satisfies, errors.IsNotSupported) c.Assert(result, jc.IsFalse) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/provider.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/provider.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/provider.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/provider.go 2016-05-17 20:01:14.000000000 +0000 @@ -27,7 +27,7 @@ // RestrictedConfigAttributes is specified in the EnvironProvider interface. func (p environProvider) RestrictedConfigAttributes() []string { - return []string{"region"} + return []string{"region", "vpc-id", "vpc-id-force"} } // PrepareForCreateEnvironment is specified in the EnvironProvider interface. @@ -87,11 +87,35 @@ if err != nil { return nil, err } + + env := e.(*environ) if ctx.ShouldVerifyCredentials() { - if err := verifyCredentials(e.(*environ)); err != nil { + if err := verifyCredentials(env); err != nil { return nil, err } } + + vpcID, forceVPCID := env.ecfg().vpcID(), env.ecfg().forceVPCID() + if vpcID != "" { + err := validateVPC(env.ec2(), vpcID) + switch { + case isVPCNotUsableError(err): + // VPC missing or has no subnets at all. + return nil, errors.Annotate(err, vpcNotUsableErrorPrefix) + case isVPCNotRecommendedError(err): + // VPC does not meet minumum validation criteria. + if !forceVPCID { + return nil, errors.Annotatef(err, vpcNotRecommendedErrorPrefix, vpcID) + } + ctx.Infof(vpcNotRecommendedButForcedWarning) + case err != nil: + // Anything else unexpected while validating the VPC. + return nil, errors.Annotate(err, cannotValidateVPCErrorPrefix) + } + + ctx.Infof("Using VPC %q in region %q", vpcID, env.ecfg().region()) + } + return e, nil } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/securitygroups_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/securitygroups_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/ec2/securitygroups_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/ec2/securitygroups_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,8 +4,11 @@ package ec2_test import ( + "time" + "github.com/juju/testing" jc "github.com/juju/testing/checkers" + "github.com/juju/utils/clock" amzec2 "gopkg.in/amz.v3/ec2" gc "gopkg.in/check.v1" @@ -17,7 +20,7 @@ coretesting.BaseSuite instanceStub *stubInstance - deleteFunc func(inst ec2.SecurityGroupCleaner, group amzec2.SecurityGroup) error + deleteFunc func(ec2.SecurityGroupCleaner, amzec2.SecurityGroup, clock.Clock) error } var _ = gc.Suite(&SecurityGroupSuite{}) @@ -38,7 +41,7 @@ } func (s *SecurityGroupSuite) TestDeleteSecurityGroupSuccess(c *gc.C) { - err := s.deleteFunc(s.instanceStub, amzec2.SecurityGroup{}) + err := s.deleteFunc(s.instanceStub, amzec2.SecurityGroup{}, coretesting.NewClock(time.Time{})) c.Assert(err, jc.ErrorIsNil) s.instanceStub.CheckCallNames(c, "DeleteSecurityGroup") } @@ -47,22 +50,32 @@ s.instanceStub.deleteSecurityGroup = func(group amzec2.SecurityGroup) (resp *amzec2.SimpleResp, err error) { return nil, &amzec2.Error{Code: "InvalidGroup.NotFound"} } - err := s.deleteFunc(s.instanceStub, amzec2.SecurityGroup{}) + err := s.deleteFunc(s.instanceStub, amzec2.SecurityGroup{}, coretesting.NewClock(time.Time{})) c.Assert(err, jc.ErrorIsNil) s.instanceStub.CheckCallNames(c, "DeleteSecurityGroup") } func (s *SecurityGroupSuite) TestDeleteSecurityGroupFewCalls(c *gc.C) { + t0 := time.Time{} + clock := autoAdvancingClock{coretesting.NewClock(t0)} count := 0 maxCalls := 4 + expectedTimes := []time.Time{ + t0, + t0.Add(time.Second), + t0.Add(3 * time.Second), + t0.Add(7 * time.Second), + t0.Add(15 * time.Second), + } s.instanceStub.deleteSecurityGroup = func(group amzec2.SecurityGroup) (resp *amzec2.SimpleResp, err error) { + c.Assert(clock.Now(), gc.Equals, expectedTimes[count]) if count < maxCalls { count++ return nil, &amzec2.Error{Code: "keep going"} } return nil, nil } - err := s.deleteFunc(s.instanceStub, amzec2.SecurityGroup{}) + err := s.deleteFunc(s.instanceStub, amzec2.SecurityGroup{}, clock) c.Assert(err, jc.ErrorIsNil) expectedCalls := make([]string, maxCalls+1) @@ -72,6 +85,16 @@ s.instanceStub.CheckCallNames(c, expectedCalls...) } +type autoAdvancingClock struct { + *coretesting.Clock +} + +func (c autoAdvancingClock) After(d time.Duration) <-chan time.Time { + ch := c.Clock.After(d) + c.Advance(d) + return ch +} + type stubInstance struct { *testing.Stub deleteSecurityGroup func(group amzec2.SecurityGroup) (resp *amzec2.SimpleResp, err error) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/gce/credentials_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/gce/credentials_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/gce/credentials_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/gce/credentials_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -114,12 +114,14 @@ } home := utils.Home() dir := c.MkDir() - utils.SetHome(dir) + err := utils.SetHome(dir) + c.Assert(err, jc.ErrorIsNil) s.AddCleanup(func(*gc.C) { - utils.SetHome(home) + err := utils.SetHome(home) + c.Assert(err, jc.ErrorIsNil) }) path := filepath.Join(dir, ".config", "gcloud") - err := os.MkdirAll(path, 0700) + err = os.MkdirAll(path, 0700) c.Assert(err, jc.ErrorIsNil) jsonpath := createCredsFile(c, filepath.Join(path, "application_default_credentials.json")) s.assertDetectCredentialsKnownLocation(c, jsonpath) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/gce/environ_policy_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/gce/environ_policy_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/gce/environ_policy_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/gce/environ_policy_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -7,12 +7,12 @@ "github.com/juju/errors" jc "github.com/juju/testing/checkers" "github.com/juju/utils/arch" + "github.com/juju/utils/series" gc "gopkg.in/check.v1" "github.com/juju/juju/constraints" "github.com/juju/juju/provider/gce" "github.com/juju/juju/provider/gce/google" - "github.com/juju/juju/testing" ) type environPolSuite struct { @@ -24,7 +24,7 @@ func (s *environPolSuite) TestPrecheckInstance(c *gc.C) { cons := constraints.Value{} placement := "" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Check(err, jc.ErrorIsNil) } @@ -36,7 +36,7 @@ cons := constraints.Value{} placement := "" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Assert(err, jc.ErrorIsNil) c.Check(s.FakeConn.Calls, gc.HasLen, 0) @@ -49,7 +49,7 @@ cons := constraints.MustParse("instance-type=n1-standard-1 arch=amd64 root-disk=1G") placement := "zone=home-zone" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Assert(err, jc.ErrorIsNil) c.Check(s.FakeConn.Calls, gc.HasLen, 1) @@ -60,7 +60,7 @@ func (s *environPolSuite) TestPrecheckInstanceValidInstanceType(c *gc.C) { cons := constraints.MustParse("instance-type=n1-standard-1") placement := "" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Check(err, jc.ErrorIsNil) } @@ -68,7 +68,7 @@ func (s *environPolSuite) TestPrecheckInstanceInvalidInstanceType(c *gc.C) { cons := constraints.MustParse("instance-type=n1-standard-1.invalid") placement := "" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Check(err, gc.ErrorMatches, `.*invalid GCE instance type.*`) } @@ -76,7 +76,7 @@ func (s *environPolSuite) TestPrecheckInstanceDiskSize(c *gc.C) { cons := constraints.MustParse("instance-type=n1-standard-1 root-disk=1G") placement := "" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Check(err, jc.ErrorIsNil) } @@ -84,7 +84,7 @@ func (s *environPolSuite) TestPrecheckInstanceUnsupportedArch(c *gc.C) { cons := constraints.MustParse("instance-type=n1-standard-1 arch=i386") placement := "" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Check(err, jc.ErrorIsNil) } @@ -96,7 +96,7 @@ cons := constraints.Value{} placement := "zone=a-zone" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Check(err, jc.ErrorIsNil) } @@ -108,7 +108,7 @@ cons := constraints.Value{} placement := "zone=a-zone" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Check(err, gc.ErrorMatches, `.*availability zone "a-zone" is DOWN`) } @@ -120,7 +120,7 @@ cons := constraints.Value{} placement := "zone=a-zone" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Check(err, jc.Satisfies, errors.IsNotFound) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/joyent/export_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/joyent/export_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/joyent/export_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/joyent/export_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -49,6 +49,7 @@ "datatype": "image-ids", "format": "products:1.0", "products": [ + "com.ubuntu.cloud:server:16.04:amd64", "com.ubuntu.cloud:server:14.04:amd64", "com.ubuntu.cloud:server:12.10:amd64", "com.ubuntu.cloud:server:13.04:amd64" @@ -68,7 +69,25 @@ "updated": "Fri, 14 Feb 2014 13:39:35 +0000", "datatype": "image-ids", "products": { - "com.ubuntu.cloud:server:14.04:amd64": { + "com.ubuntu.cloud:server:16.04:amd64": { + "release": "trusty", + "version": "16.04", + "arch": "amd64", + "versions": { + "20160216": { + "items": { + "11223344-0a0a-ff99-11bb-0a1b2c3d4e5f": { + "region": "some-region", + "id": "11223344-0a0a-ff99-11bb-0a1b2c3d4e5f", + "virt": "kvm" + } + }, + "pubname": "ubuntu-trusty-16.04-amd64-server-20160216", + "label": "release" + } + } + }, + "com.ubuntu.cloud:server:14.04:amd64": { "release": "trusty", "version": "14.04", "arch": "amd64", diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/lxd/config_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/lxd/config_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/lxd/config_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/lxd/config_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -330,6 +330,9 @@ c.Skip("LXD not running locally") } + // TODO(redir): Remove after wily or in yakkety. + skipIfWily(c) + for i, test := range newConfigTests { c.Logf("test %d: %s", i, test.info) @@ -437,6 +440,9 @@ c.Skip("LXD not running locally") } + // TODO(redir): Remove after wily or in yakkety. + skipIfWily(c) + for i, test := range changeConfigTests { c.Logf("test %d: %s", i, test.info) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/lxd/credentials.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/lxd/credentials.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/lxd/credentials.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/lxd/credentials.go 2016-05-17 20:01:14.000000000 +0000 @@ -13,6 +13,9 @@ // CredentialSchemas is part of the environs.ProviderCredentials interface. func (environProviderCredentials) CredentialSchemas() map[cloud.AuthType]cloud.CredentialSchema { + // TODO (anastasiamac 2016-04-14) When/If this value changes, + // verify that juju/juju/cloud/clouds.go#BuiltInClouds + // with lxd type are up to-date. return map[cloud.AuthType]cloud.CredentialSchema{cloud.EmptyAuthType: {}} } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/lxd/environ_policy_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/lxd/environ_policy_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/lxd/environ_policy_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/lxd/environ_policy_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -10,11 +10,11 @@ jc "github.com/juju/testing/checkers" "github.com/juju/utils/arch" + "github.com/juju/utils/series" gc "gopkg.in/check.v1" "github.com/juju/juju/constraints" "github.com/juju/juju/provider/lxd" - "github.com/juju/juju/testing" ) type environPolSuite struct { @@ -26,7 +26,7 @@ func (s *environPolSuite) TestPrecheckInstanceOkay(c *gc.C) { cons := constraints.Value{} placement := "" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Check(err, jc.ErrorIsNil) } @@ -34,7 +34,7 @@ func (s *environPolSuite) TestPrecheckInstanceAPI(c *gc.C) { cons := constraints.Value{} placement := "" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Assert(err, jc.ErrorIsNil) s.CheckNoAPI(c) @@ -43,7 +43,7 @@ func (s *environPolSuite) TestPrecheckInstanceHasInstanceType(c *gc.C) { cons := constraints.MustParse("instance-type=some-instance-type") placement := "" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Check(err, gc.ErrorMatches, `LXD does not support instance types.*`) } @@ -51,7 +51,7 @@ func (s *environPolSuite) TestPrecheckInstanceDiskSize(c *gc.C) { cons := constraints.MustParse("root-disk=1G") placement := "" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Check(err, jc.ErrorIsNil) } @@ -61,7 +61,7 @@ cons := constraints.MustParse("arch=i386") placement := "" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Check(err, jc.ErrorIsNil) } @@ -69,7 +69,7 @@ func (s *environPolSuite) TestPrecheckInstanceAvailZone(c *gc.C) { cons := constraints.Value{} placement := "zone=a-zone" - err := s.Env.PrecheckInstance(testing.FakeDefaultSeries, cons, placement) + err := s.Env.PrecheckInstance(series.LatestLts(), cons, placement) c.Check(err, gc.ErrorMatches, `unknown placement directive: .*`) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/lxd/provider.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/lxd/provider.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/lxd/provider.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/lxd/provider.go 2016-05-17 20:01:14.000000000 +0000 @@ -106,6 +106,9 @@ // For now we just return a hard-coded "localhost" region, // i.e. the local LXD daemon. We may later want to detect // locally-configured remotes. + // TODO (anastasiamac 2016-04-14) When/If this value changes, + // verify that juju/juju/cloud/clouds.go#BuiltInClouds + // with lxd type are up to-date. return []cloud.Region{{Name: "localhost"}}, nil } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/lxd/provider_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/lxd/provider_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/lxd/provider_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/lxd/provider_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -6,15 +6,36 @@ package lxd_test import ( + "fmt" + jc "github.com/juju/testing/checkers" + "github.com/juju/utils/series" gc "gopkg.in/check.v1" "github.com/juju/juju/cloud" "github.com/juju/juju/environs" envtesting "github.com/juju/juju/environs/testing" "github.com/juju/juju/provider/lxd" + "github.com/juju/juju/tools/lxdclient" ) +// This is a quick hack to make wily pass with it's default, but unsupported, +// version of LXD. Wily is supported until 2016-7-??. AFAIU LXD will not be +// backported to wily... so we have this:| +// TODO(redir): Remove after wiley or in yakkety. +func skipIfWily(c *gc.C) { + if series.HostSeries() == "wily" { + cfg, _ := lxdclient.Config{}.WithDefaults() + _, err := lxdclient.Connect(cfg) + // We try to create a client here. On wily this should fail, because + // the default 0.20 lxd version should make juju/tools/lxdclient return + // an error. + if err != nil { + c.Skip(fmt.Sprintf("Skipping LXD tests because %s", err)) + } + } +} + var ( _ = gc.Suite(&providerSuite{}) _ = gc.Suite(&ProviderFunctionalSuite{}) @@ -71,6 +92,9 @@ c.Skip("LXD not running locally") } + // TODO(redir): Remove after wily or in yakkety. + skipIfWily(c) + s.BaseSuite.SetUpTest(c) provider, err := environs.Provider("lxd") diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/add-juju-bridge.py juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/add-juju-bridge.py --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/add-juju-bridge.py 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/add-juju-bridge.py 2016-05-17 20:01:14.000000000 +0000 @@ -73,33 +73,79 @@ def __str__(self): return self.name - # Returns an ordered set of stanzas to bridge this interface. + def bridge_now(self, prefix, bridge_name): + # https://wiki.archlinux.org/index.php/Network_bridge + # ip addr delete dev + if bridge_name is None: + bridge_name = prefix + self.name + + args = { + 'bridge': bridge_name, + 'parent': self.name, + } + + for o in self.options: + if o.startswith('vlan') or o.startswith('bond'): + continue + option = o.split() + if len(option) < 2: + args[option[0]] = "" + else: + args[option[0]] = option[1] + + addr = check_shell_cmd('ip -d addr show {parent}'.format(**args)) + flags = re.search('<(.*?)>', addr).group(1).split(',') + for exclude_flag in ['LOOPBACK', 'SLAVE']: + if exclude_flag in flags: + # Don't bridge the loopback interface or slaves of bonds. + return + + # Save routes + routes = check_shell_cmd('ip route show dev {parent}'.format(**args)) + + print_shell_cmd('ip link add name {bridge} type bridge'.format(**args)) + print_shell_cmd('ip link set {bridge} up'.format(**args)) + print_shell_cmd('ip link set {parent} master {bridge}'.format(**args)) + + if 'address' in args: + print_shell_cmd('ip addr delete dev {parent} {address}'.format(**args)) + + cmd = 'ip addr add dev {bridge} {address}' + if 'netmask' in args: + cmd += '/{netmask}' + + print_shell_cmd(cmd.format(**args)) + + for route in routes.splitlines(): + # ip route replace will add missing routes or update existing ones. + print_shell_cmd('ip route replace {} dev {bridge}'.format(route, **args)) + + # Returns an ordered set of stanzas to bridge this interface def bridge(self, prefix, bridge_name, add_auto_stanza): if bridge_name is None: bridge_name = prefix + self.name + # Note: the testing order here is significant. if not self.is_active or self.is_bridged: return self._bridge_unchanged(add_auto_stanza) elif self.is_alias: return self._bridge_alias(add_auto_stanza) elif self.is_vlan: - return self._bridge_vlan(prefix, bridge_name, add_auto_stanza) + return self._bridge_vlan(bridge_name, add_auto_stanza) elif self.is_bonded: - return self._bridge_bond(prefix, bridge_name, add_auto_stanza) + return self._bridge_bond(bridge_name, add_auto_stanza) else: - return self._bridge_device(prefix, bridge_name) + return self._bridge_device(bridge_name) - def _bridge_device(self, prefix, bridge_name): + def _bridge_device(self, bridge_name): s1 = IfaceStanza(self.name, self.family, "manual", []) s2 = AutoStanza(bridge_name) options = list(self.options) options.append("bridge_ports {}".format(self.name)) - options.append("bridge_stp off") - options.append("bridge_maxwait 0") s3 = IfaceStanza(bridge_name, self.family, self.method, options) return [s1, s2, s3] - def _bridge_vlan(self, prefix, bridge_name, add_auto_stanza): + def _bridge_vlan(self, bridge_name, add_auto_stanza): stanzas = [] s1 = IfaceStanza(self.name, self.family, "manual", self.options) stanzas.append(s1) @@ -107,8 +153,6 @@ stanzas.append(AutoStanza(bridge_name)) options = [x for x in self.options if not x.startswith("vlan")] options.append("bridge_ports {}".format(self.name)) - options.append("bridge_stp off") - options.append("bridge_maxwait 0") s3 = IfaceStanza(bridge_name, self.family, self.method, options) stanzas.append(s3) return stanzas @@ -121,7 +165,7 @@ stanzas.append(s1) return stanzas - def _bridge_bond(self, prefix, bridge_name, add_auto_stanza): + def _bridge_bond(self, bridge_name, add_auto_stanza): stanzas = [] if add_auto_stanza: stanzas.append(AutoStanza(self.name)) @@ -129,8 +173,6 @@ s2 = AutoStanza(bridge_name) options = [x for x in self.options if not x.startswith("bond")] options.append("bridge_ports {}".format(self.name)) - options.append("bridge_stp off") - options.append("bridge_maxwait 0") s3 = IfaceStanza(bridge_name, self.family, self.method, options) stanzas.extend([s1, s2, s3]) return stanzas @@ -329,17 +371,20 @@ # stanza types. The args.interface_to_bridge test is to bridge a # single interface only, which is only used for juju < 2.0. And if # that argument is specified then args.bridge_name takes - # precendence over any args.bridge_prefix. + # precedence over any args.bridge_prefix. for s in config_parser.stanzas(): if s.is_logical_interface: add_auto_stanza = s.iface.name in physical_interfaces + if args.interface_to_bridge and args.interface_to_bridge != s.iface.name: if add_auto_stanza: stanzas.append(AutoStanza(s.iface.name)) stanzas.append(s) else: - stanzas.extend(s.iface.bridge(args.bridge_prefix, args.bridge_name, add_auto_stanza)) + stanza = s.iface.bridge(args.bridge_prefix, args.bridge_name, add_auto_stanza) + stanzas.extend(stanza) + elif not s.is_physical_interface: stanzas.append(s) @@ -347,30 +392,29 @@ print_stanzas(stanzas) exit(0) + print("**** Original configuration") + print_shell_cmd("cat {}".format(args.filename)) + print_shell_cmd("ip -d addr show") + print_shell_cmd("ip route show") + + for s in config_parser.stanzas(): + if s.is_logical_interface: + if not(args.interface_to_bridge and args.interface_to_bridge != s.iface.name): + s.iface.bridge_now(args.bridge_prefix, args.bridge_name) + if args.one_time_backup: backup_file = "{}-before-add-juju-bridge".format(args.filename) if not os.path.isfile(backup_file): shutil.copy2(args.filename, backup_file) - ifquery = "$(ifquery --interfaces={} --exclude=lo --list)".format(args.filename) - - print("**** Original configuration") - print_shell_cmd("cat {}".format(args.filename)) - print_shell_cmd("ifconfig -a") - print_shell_cmd("ifdown --exclude=lo --interfaces={} {}".format(args.filename, ifquery)) - - print("**** Activating new configuration") - with open(args.filename, 'w') as f: print_stanzas(stanzas, f) f.close() + print("**** New configuration") print_shell_cmd("cat {}".format(args.filename)) - print_shell_cmd("ifup --exclude=lo --interfaces={} {}".format(args.filename, ifquery)) - print_shell_cmd("ip link show up") - print_shell_cmd("ifconfig -a") + print_shell_cmd("ip -d addr show") print_shell_cmd("ip route show") - print_shell_cmd("brctl show") # This script re-renders an interfaces(5) file to add a bridge to # either all active interfaces, or a specific interface. diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/bridgescript.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/bridgescript.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/bridgescript.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/bridgescript.go 2016-05-17 20:01:14.000000000 +0000 @@ -85,33 +85,79 @@ def __str__(self): return self.name - # Returns an ordered set of stanzas to bridge this interface. + def bridge_now(self, prefix, bridge_name): + # https://wiki.archlinux.org/index.php/Network_bridge + # ip addr delete dev + if bridge_name is None: + bridge_name = prefix + self.name + + args = { + 'bridge': bridge_name, + 'parent': self.name, + } + + for o in self.options: + if o.startswith('vlan') or o.startswith('bond'): + continue + option = o.split() + if len(option) < 2: + args[option[0]] = "" + else: + args[option[0]] = option[1] + + addr = check_shell_cmd('ip -d addr show {parent}'.format(**args)) + flags = re.search('<(.*?)>', addr).group(1).split(',') + for exclude_flag in ['LOOPBACK', 'SLAVE']: + if exclude_flag in flags: + # Don't bridge the loopback interface or slaves of bonds. + return + + # Save routes + routes = check_shell_cmd('ip route show dev {parent}'.format(**args)) + + print_shell_cmd('ip link add name {bridge} type bridge'.format(**args)) + print_shell_cmd('ip link set {bridge} up'.format(**args)) + print_shell_cmd('ip link set {parent} master {bridge}'.format(**args)) + + if 'address' in args: + print_shell_cmd('ip addr delete dev {parent} {address}'.format(**args)) + + cmd = 'ip addr add dev {bridge} {address}' + if 'netmask' in args: + cmd += '/{netmask}' + + print_shell_cmd(cmd.format(**args)) + + for route in routes.splitlines(): + # ip route replace will add missing routes or update existing ones. + print_shell_cmd('ip route replace {} dev {bridge}'.format(route, **args)) + + # Returns an ordered set of stanzas to bridge this interface def bridge(self, prefix, bridge_name, add_auto_stanza): if bridge_name is None: bridge_name = prefix + self.name + # Note: the testing order here is significant. if not self.is_active or self.is_bridged: return self._bridge_unchanged(add_auto_stanza) elif self.is_alias: return self._bridge_alias(add_auto_stanza) elif self.is_vlan: - return self._bridge_vlan(prefix, bridge_name, add_auto_stanza) + return self._bridge_vlan(bridge_name, add_auto_stanza) elif self.is_bonded: - return self._bridge_bond(prefix, bridge_name, add_auto_stanza) + return self._bridge_bond(bridge_name, add_auto_stanza) else: - return self._bridge_device(prefix, bridge_name) + return self._bridge_device(bridge_name) - def _bridge_device(self, prefix, bridge_name): + def _bridge_device(self, bridge_name): s1 = IfaceStanza(self.name, self.family, "manual", []) s2 = AutoStanza(bridge_name) options = list(self.options) options.append("bridge_ports {}".format(self.name)) - options.append("bridge_stp off") - options.append("bridge_maxwait 0") s3 = IfaceStanza(bridge_name, self.family, self.method, options) return [s1, s2, s3] - def _bridge_vlan(self, prefix, bridge_name, add_auto_stanza): + def _bridge_vlan(self, bridge_name, add_auto_stanza): stanzas = [] s1 = IfaceStanza(self.name, self.family, "manual", self.options) stanzas.append(s1) @@ -119,8 +165,6 @@ stanzas.append(AutoStanza(bridge_name)) options = [x for x in self.options if not x.startswith("vlan")] options.append("bridge_ports {}".format(self.name)) - options.append("bridge_stp off") - options.append("bridge_maxwait 0") s3 = IfaceStanza(bridge_name, self.family, self.method, options) stanzas.append(s3) return stanzas @@ -133,7 +177,7 @@ stanzas.append(s1) return stanzas - def _bridge_bond(self, prefix, bridge_name, add_auto_stanza): + def _bridge_bond(self, bridge_name, add_auto_stanza): stanzas = [] if add_auto_stanza: stanzas.append(AutoStanza(self.name)) @@ -141,8 +185,6 @@ s2 = AutoStanza(bridge_name) options = [x for x in self.options if not x.startswith("bond")] options.append("bridge_ports {}".format(self.name)) - options.append("bridge_stp off") - options.append("bridge_maxwait 0") s3 = IfaceStanza(bridge_name, self.family, self.method, options) stanzas.extend([s1, s2, s3]) return stanzas @@ -341,17 +383,20 @@ # stanza types. The args.interface_to_bridge test is to bridge a # single interface only, which is only used for juju < 2.0. And if # that argument is specified then args.bridge_name takes - # precendence over any args.bridge_prefix. + # precedence over any args.bridge_prefix. for s in config_parser.stanzas(): if s.is_logical_interface: add_auto_stanza = s.iface.name in physical_interfaces + if args.interface_to_bridge and args.interface_to_bridge != s.iface.name: if add_auto_stanza: stanzas.append(AutoStanza(s.iface.name)) stanzas.append(s) else: - stanzas.extend(s.iface.bridge(args.bridge_prefix, args.bridge_name, add_auto_stanza)) + stanza = s.iface.bridge(args.bridge_prefix, args.bridge_name, add_auto_stanza) + stanzas.extend(stanza) + elif not s.is_physical_interface: stanzas.append(s) @@ -359,30 +404,29 @@ print_stanzas(stanzas) exit(0) + print("**** Original configuration") + print_shell_cmd("cat {}".format(args.filename)) + print_shell_cmd("ip -d addr show") + print_shell_cmd("ip route show") + + for s in config_parser.stanzas(): + if s.is_logical_interface: + if not(args.interface_to_bridge and args.interface_to_bridge != s.iface.name): + s.iface.bridge_now(args.bridge_prefix, args.bridge_name) + if args.one_time_backup: backup_file = "{}-before-add-juju-bridge".format(args.filename) if not os.path.isfile(backup_file): shutil.copy2(args.filename, backup_file) - ifquery = "$(ifquery --interfaces={} --exclude=lo --list)".format(args.filename) - - print("**** Original configuration") - print_shell_cmd("cat {}".format(args.filename)) - print_shell_cmd("ifconfig -a") - print_shell_cmd("ifdown --exclude=lo --interfaces={} {}".format(args.filename, ifquery)) - - print("**** Activating new configuration") - with open(args.filename, 'w') as f: print_stanzas(stanzas, f) f.close() + print("**** New configuration") print_shell_cmd("cat {}".format(args.filename)) - print_shell_cmd("ifup --exclude=lo --interfaces={} {}".format(args.filename, ifquery)) - print_shell_cmd("ip link show up") - print_shell_cmd("ifconfig -a") + print_shell_cmd("ip -d addr show") print_shell_cmd("ip route show") - print_shell_cmd("brctl show") # This script re-renders an interfaces(5) file to add a bridge to # either all active interfaces, or a specific interface. diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/bridgescript_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/bridgescript_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/bridgescript_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/bridgescript_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -217,9 +217,7 @@ address 1.2.3.4 netmask 255.255.255.0 gateway 4.3.2.1 - bridge_ports eth0 - bridge_stp off - bridge_maxwait 0` + bridge_ports eth0` const networkDHCPInitial = `auto lo iface lo inet loopback @@ -234,9 +232,7 @@ auto test-br-eth0 iface test-br-eth0 inet dhcp - bridge_ports eth0 - bridge_stp off - bridge_maxwait 0` + bridge_ports eth0` const networkDualNICInitial = `auto lo iface lo inet loopback @@ -264,8 +260,6 @@ netmask 255.255.255.0 gateway 4.3.2.1 bridge_ports eth0 - bridge_stp off - bridge_maxwait 0 iface eth1 inet manual @@ -274,9 +268,7 @@ address 1.2.3.5 netmask 255.255.255.0 gateway 4.3.2.1 - bridge_ports eth1 - bridge_stp off - bridge_maxwait 0` + bridge_ports eth1` const networkWithAliasInitial = `auto lo iface lo inet loopback @@ -302,8 +294,6 @@ netmask 255.255.255.0 gateway 4.3.2.1 bridge_ports eth0 - bridge_stp off - bridge_maxwait 0 auto eth0:1 iface eth0:1 inet static @@ -337,8 +327,6 @@ gateway 10.14.0.1 address 10.14.0.102/24 bridge_ports eth0 - bridge_stp off - bridge_maxwait 0 auto eth0:1 iface eth0:1 inet static @@ -376,8 +364,6 @@ address 10.17.20.201/24 mtu 1500 bridge_ports eth0 - bridge_stp off - bridge_maxwait 0 auto eth0:1 iface eth0:1 inet static @@ -456,8 +442,6 @@ mtu 1500 hwaddress 52:54:00:1c:f1:5b bridge_ports bond0 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.17.20.200 dns-search maas19` @@ -491,16 +475,12 @@ auto test-br-eth0 iface test-br-eth0 inet dhcp bridge_ports eth0 - bridge_stp off - bridge_maxwait 0 iface eth1 inet manual auto test-br-eth1 iface test-br-eth1 inet dhcp bridge_ports eth1 - bridge_stp off - bridge_maxwait 0 iface eth10 inet manual @@ -510,8 +490,6 @@ address 10.17.20.201/24 mtu 1500 bridge_ports eth10 - bridge_stp off - bridge_maxwait 0 auto eth10:1 iface eth10:1 inet static @@ -663,8 +641,6 @@ address 10.17.20.202/24 mtu 1500 bridge_ports eth4 - bridge_stp off - bridge_maxwait 0 iface eth5 inet manual @@ -672,8 +648,6 @@ iface juju-br-eth5 inet dhcp mtu 1500 bridge_ports eth5 - bridge_stp off - bridge_maxwait 0 iface eth6 inet manual @@ -682,8 +656,6 @@ address 10.17.20.203/24 mtu 1500 bridge_ports eth6 - bridge_stp off - bridge_maxwait 0 auto eth6:1 iface eth6:1 inet static @@ -724,8 +696,6 @@ mtu 1500 hwaddress 52:54:00:6a:4f:fd bridge_ports bond0 - bridge_stp off - bridge_maxwait 0 auto bond1 iface bond1 inet manual @@ -744,8 +714,6 @@ mtu 1500 hwaddress 52:54:00:8e:6e:b0 bridge_ports bond1 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.17.20.200 dns-search maas19` @@ -784,8 +752,6 @@ address 10.17.20.212/24 mtu 1500 bridge_ports eth0 - bridge_stp off - bridge_maxwait 0 auto eth1 iface eth1 inet manual @@ -802,8 +768,6 @@ address 192.168.2.3/24 mtu 1500 bridge_ports eth0.2 - bridge_stp off - bridge_maxwait 0 iface eth1.3 inet manual address 192.168.3.3/24 @@ -818,8 +782,6 @@ address 192.168.3.3/24 mtu 1500 bridge_ports eth1.3 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.17.20.200 dns-search maas19` @@ -885,8 +847,6 @@ address 10.245.168.11/21 mtu 1500 bridge_ports eth0 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.245.168.2 auto eth1 @@ -913,8 +873,6 @@ address 10.245.184.2/24 mtu 1500 bridge_ports eth1.2667 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.245.168.2 iface eth1.2668 inet manual @@ -929,8 +887,6 @@ address 10.245.185.1/24 mtu 1500 bridge_ports eth1.2668 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.245.168.2 iface eth1.2669 inet manual @@ -945,8 +901,6 @@ address 10.245.186.1/24 mtu 1500 bridge_ports eth1.2669 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.245.168.2 iface eth1.2670 inet manual @@ -962,8 +916,6 @@ address 10.245.187.2/24 mtu 1500 bridge_ports eth1.2670 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.245.168.2 dns-search dellstack` @@ -1059,8 +1011,6 @@ mtu 1500 hwaddress 52:54:00:1c:f1:5b bridge_ports bond0 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.17.20.200 iface bond0.2 inet manual @@ -1074,8 +1024,6 @@ address 192.168.2.102/24 mtu 1500 bridge_ports bond0.2 - bridge_stp off - bridge_maxwait 0 iface bond0.3 inet manual address 192.168.3.101/24 @@ -1090,8 +1038,6 @@ address 192.168.3.101/24 mtu 1500 bridge_ports bond0.3 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.17.20.200 dns-search maas19` @@ -1124,8 +1070,6 @@ address 10.17.20.211/24 mtu 1500 bridge_ports eth0 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.17.20.200 auto eth1 @@ -1143,8 +1087,6 @@ iface br-eth1.2 inet dhcp mtu 1500 bridge_ports eth1.2 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.17.20.200 dns-search maas19` @@ -1177,8 +1119,6 @@ address 10.17.20.211/24 mtu 1500 bridge_ports eth0 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.17.20.200 iface eth1 inet manual @@ -1187,8 +1127,6 @@ iface br-eth1 inet dhcp mtu 1500 bridge_ports eth1 - bridge_stp off - bridge_maxwait 0 iface eth1.2 inet manual vlan-raw-device eth1 @@ -1201,8 +1139,6 @@ iface br-eth1.2 inet dhcp mtu 1500 bridge_ports eth1.2 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.17.20.200 dns-search maas19` @@ -1254,8 +1190,6 @@ address 10.245.168.11/21 mtu 1500 bridge_ports eth0 - bridge_stp off - bridge_maxwait 0 dns-nameservers 10.245.168.2 192.168.1.1 iface eth1 inet manual @@ -1266,8 +1200,6 @@ address 10.245.168.12/21 mtu 1500 bridge_ports eth1 - bridge_stp off - bridge_maxwait 0 dns-sortlist 192.168.1.0/24 10.245.168.0/21 iface eth2 inet manual @@ -1278,8 +1210,6 @@ address 10.245.168.13/21 mtu 1500 bridge_ports eth2 - bridge_stp off - bridge_maxwait 0 dns-search juju ubuntu dellstack iface eth3 inet manual @@ -1290,8 +1220,6 @@ address 10.245.168.14/21 mtu 1500 bridge_ports eth3 - bridge_stp off - bridge_maxwait 0 dns-nameservers 192.168.1.1 10.245.168.2 dns-search juju ubuntu dellstack dns-sortlist 192.168.1.0/24 10.245.168.0/21` @@ -1326,8 +1254,6 @@ address 10.245.168.11/21 mtu 1500 bridge_ports eth0 - bridge_stp off - bridge_maxwait 0 iface eth1 inet manual @@ -1336,9 +1262,7 @@ gateway 10.245.168.1 address 10.245.168.12/21 mtu 1500 - bridge_ports eth1 - bridge_stp off - bridge_maxwait 0` + bridge_ports eth1` const networkLP1532167Initial = `auto eth0 iface eth0 inet manual @@ -1505,8 +1429,6 @@ mtu 1500 hwaddress 44:a8:42:41:ab:37 bridge_ports bond0 - bridge_stp off - bridge_maxwait 0 auto bond1 iface bond1 inet manual @@ -1598,9 +1520,7 @@ address 1.2.3.4 netmask 255.255.255.0 gateway 4.3.2.1 - bridge_ports eth1 - bridge_stp off - bridge_maxwait 0` + bridge_ports eth1` const networkPartiallyBridgedInitial = `auto lo iface lo inet loopback @@ -1613,8 +1533,6 @@ netmask 255.255.255.0 gateway 4.3.2.1 bridge_ports eth0 - bridge_stp off - bridge_maxwait 0 auto eth1 iface eth1 inet static @@ -1633,8 +1551,6 @@ netmask 255.255.255.0 gateway 4.3.2.1 bridge_ports eth0 - bridge_stp off - bridge_maxwait 0 iface eth1 inet manual @@ -1643,6 +1559,4 @@ address 1.2.3.5 netmask 255.255.255.0 gateway 4.3.2.1 - bridge_ports eth1 - bridge_stp off - bridge_maxwait 0` + bridge_ports eth1` diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/devices.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/devices.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/devices.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/devices.go 2016-05-17 20:01:14.000000000 +0000 @@ -10,6 +10,7 @@ "strconv" "github.com/juju/errors" + "github.com/juju/gomaasapi" "github.com/juju/juju/instance" "github.com/juju/juju/network" @@ -242,6 +243,82 @@ } interfaceInfo = append(interfaceInfo, nicInfo) + } + } + logger.Debugf("device %q has interface info: %+v", deviceID, interfaceInfo) + return interfaceInfo, nil +} + +func (env *maasEnviron) deviceInterfaceInfo2(deviceID string, nameToParentName map[string]string) ([]network.InterfaceInfo, error) { + args := gomaasapi.DevicesArgs{SystemIDs: []string{deviceID}} + devices, err := env.maasController.Devices(args) + if err != nil { + return nil, errors.Trace(err) + } + if len(devices) != 1 { + return nil, errors.Errorf("unexpected response requesting device %v: %v", deviceID, devices) + } + interfaces := devices[0].InterfaceSet() + + interfaceInfo := make([]network.InterfaceInfo, 0, len(interfaces)) + for _, nic := range interfaces { + vlanId := 0 + vlanVid := 0 + vlan := nic.VLAN() + if vlan != nil { + vlanId = vlan.ID() + vlanVid = vlan.VID() + } + nicInfo := network.InterfaceInfo{ + InterfaceName: nic.Name(), + InterfaceType: network.EthernetInterface, + MACAddress: nic.MACAddress(), + MTU: nic.EffectiveMTU(), + VLANTag: vlanVid, + ProviderId: network.Id(strconv.Itoa(nic.ID())), + ProviderVLANId: network.Id(strconv.Itoa(vlanId)), + Disabled: !nic.Enabled(), + NoAutoStart: !nic.Enabled(), + ParentInterfaceName: nameToParentName[nic.Name()], + } + + if len(nic.Links()) == 0 { + logger.Debugf("device %q interface %q has no links", deviceID, nic.Name()) + interfaceInfo = append(interfaceInfo, nicInfo) + continue + } + + for _, link := range nic.Links() { + mode := maasLinkMode(link.Mode()) + switch mode { + case modeUnknown: + nicInfo.ConfigType = network.ConfigUnknown + case modeDHCP: + nicInfo.ConfigType = network.ConfigDHCP + case modeStatic, modeLinkUp: + nicInfo.ConfigType = network.ConfigStatic + default: + nicInfo.ConfigType = network.ConfigManual + } + + subnet := link.Subnet() + if link.IPAddress() == "" || subnet == nil { + logger.Debugf("device %q interface %q has no address", deviceID, nic.Name()) + continue + } + + nicInfo.CIDR = subnet.CIDR() + nicInfo.Address = network.NewAddressOnSpace(subnet.Space(), link.IPAddress()) + nicInfo.ProviderSubnetId = network.Id(strconv.Itoa(subnet.ID())) + nicInfo.ProviderAddressId = network.Id(strconv.Itoa(link.ID())) + if subnet.Gateway() != "" { + nicInfo.GatewayAddress = network.NewAddressOnSpace(subnet.Space(), subnet.Gateway()) + } + if len(subnet.DNSServers()) > 0 { + nicInfo.DNSServers = network.NewAddressesOnSpace(subnet.Space(), subnet.DNSServers()...) + } + + interfaceInfo = append(interfaceInfo, nicInfo) } } logger.Debugf("device %q has interface info: %+v", deviceID, interfaceInfo) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/environ.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/environ.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/environ.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/environ.go 2016-05-17 20:01:14.000000000 +0000 @@ -159,9 +159,6 @@ } func (env *maasEnviron) usingMAAS2() bool { - if !featureflag.Enabled(feature.MAAS2) { - return false - } return env.apiVersion == apiVersion2 } @@ -243,12 +240,9 @@ // and 2.0. MAAS 1.9 uses the 1.0 api version and 2.0 uses the 2.0 api // version. apiVersion := apiVersion2 - maas2Enabled := featureflag.Enabled(feature.MAAS2) controller, err := GetMAAS2Controller(ecfg.maasServer(), ecfg.maasOAuth()) switch { - case !maas2Enabled && err == nil: - return errors.NewNotSupported(nil, "MAAS 2 is not supported unless the 'maas2' feature flag is set") - case !maas2Enabled || gomaasapi.IsUnsupportedVersionError(err): + case gomaasapi.IsUnsupportedVersionError(err): apiVersion = apiVersion1 authClient, err := gomaasapi.NewAuthenticatedClient(ecfg.maasServer(), ecfg.maasOAuth(), apiVersion1) if err != nil { @@ -1878,11 +1872,10 @@ // Space name is not filled in as the provider doesn't know the juju name for // the space. func (environ *maasEnviron) Spaces() ([]network.SpaceInfo, error) { - if environ.usingMAAS2() { - return environ.spaces2() - } else { + if !environ.usingMAAS2() { return environ.spaces1() } + return environ.spaces2() } func (environ *maasEnviron) spaces1() ([]network.SpaceInfo, error) { @@ -2148,7 +2141,13 @@ return nil, errors.Errorf("no prepared info to allocate") } logger.Debugf("using prepared container info: %+v", preparedInfo) + if !env.usingMAAS2() { + return env.allocateContainerAddresses1(hostInstanceID, preparedInfo) + } + return env.allocateContainerAddresses2(hostInstanceID, preparedInfo) +} +func (env *maasEnviron) allocateContainerAddresses1(hostInstanceID instance.Id, preparedInfo []network.InterfaceInfo) ([]network.InterfaceInfo, error) { subnetCIDRToVLANID := make(map[string]string) subnetsAPI := env.getMAASClient().GetSubObject("subnets") result, err := subnetsAPI.CallGet("", nil) @@ -2234,6 +2233,103 @@ if err != nil { return nil, errors.Annotate(err, "cannot get device interfaces") } + logger.Debugf("allocated device interfaces: %+v", finalInterfaces) + return finalInterfaces, nil +} + +func (env *maasEnviron) allocateContainerAddresses2(hostInstanceID instance.Id, preparedInfo []network.InterfaceInfo) ([]network.InterfaceInfo, error) { + subnetCIDRToSubnet := make(map[string]gomaasapi.Subnet) + spaces, err := env.maasController.Spaces() + if err != nil { + return nil, errors.Trace(err) + } + for _, space := range spaces { + for _, subnet := range space.Subnets() { + subnetCIDRToSubnet[subnet.CIDR()] = subnet + } + } + + var primaryNICInfo network.InterfaceInfo + primaryNICName := "eth0" + for _, nic := range preparedInfo { + if nic.InterfaceName == primaryNICName { + primaryNICInfo = nic + break + } + } + if primaryNICInfo.InterfaceName == "" { + return nil, errors.Errorf("cannot find primary interface for container") + } + logger.Debugf("primary device NIC prepared info: %+v", primaryNICInfo) + + primaryNICSubnetCIDR := primaryNICInfo.CIDR + subnet, ok := subnetCIDRToSubnet[primaryNICSubnetCIDR] + if !ok { + return nil, errors.Errorf("primary NIC subnet %v not found", primaryNICSubnetCIDR) + } + primaryMACAddress := primaryNICInfo.MACAddress + args := gomaasapi.MachinesArgs{ + AgentName: env.ecfg().maasAgentName(), + SystemIDs: []string{string(hostInstanceID)}, + } + machines, err := env.maasController.Machines(args) + if err != nil { + return nil, errors.Trace(err) + } + if len(machines) != 1 { + return nil, errors.Errorf("unexpected response fetching machine %v: %v", hostInstanceID, machines) + } + machine := machines[0] + createDeviceArgs := gomaasapi.CreateMachineDeviceArgs{ + MACAddress: primaryMACAddress, + Subnet: subnet, + InterfaceName: primaryNICName, + } + device, err := machine.CreateDevice(createDeviceArgs) + if err != nil { + return nil, errors.Trace(err) + } + interface_set := device.InterfaceSet() + if len(interface_set) != 1 { + // Shouldn't be possible as machine.CreateDevice always returns us + // one interface. + return nil, errors.Errorf("unexpected number of interfaces inresponse from creating device: %v", interface_set) + } + + nameToParentName := make(map[string]string) + for _, nic := range preparedInfo { + nameToParentName[nic.InterfaceName] = nic.ParentInterfaceName + if nic.InterfaceName != primaryNICName { + subnet, ok := subnetCIDRToSubnet[nic.CIDR] + if !ok { + return nil, errors.Errorf("NIC %v subnet %v not found", nic.InterfaceName, nic.CIDR) + } + createdNIC, err := device.CreateInterface( + gomaasapi.CreateInterfaceArgs{ + Name: nic.InterfaceName, + MACAddress: nic.MACAddress, + VLAN: subnet.VLAN(), + }) + if err != nil { + return nil, errors.Annotate(err, "creating device interface") + } + logger.Debugf("created device interface: %+v", createdNIC) + + linkArgs := gomaasapi.LinkSubnetArgs{ + Mode: gomaasapi.LinkModeStatic, + Subnet: subnet, + } + err = createdNIC.LinkSubnet(linkArgs) + if err != nil { + return nil, errors.Annotate(err, "cannot link device interface to subnet") + } + logger.Debugf("linked device interface to subnet: %+v", createdNIC) + } + } + finalInterfaces, err := env.deviceInterfaceInfo2(device.SystemID(), nameToParentName) + if err != nil { + return nil, errors.Annotate(err, "cannot get device interfaces") + } logger.Debugf("allocated device interfaces: %+v", finalInterfaces) return finalInterfaces, nil } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/environ_whitebox_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/environ_whitebox_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/environ_whitebox_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/environ_whitebox_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -17,6 +17,7 @@ jc "github.com/juju/testing/checkers" "github.com/juju/utils" "github.com/juju/utils/arch" + "github.com/juju/utils/series" gc "gopkg.in/check.v1" goyaml "gopkg.in/yaml.v2" @@ -33,7 +34,6 @@ "github.com/juju/juju/network" "github.com/juju/juju/provider/common" "github.com/juju/juju/storage" - coretesting "github.com/juju/juju/testing" jujuversion "github.com/juju/juju/version" ) @@ -753,7 +753,7 @@ s.testMAASObject.TestServer.AddZone("zone1", "the grass is greener in zone1") env := s.makeEnviron() placement := "zone=zone1" - err := env.PrecheckInstance(coretesting.FakeDefaultSeries, constraints.Value{}, placement) + err := env.PrecheckInstance(series.LatestLts(), constraints.Value{}, placement) c.Assert(err, jc.ErrorIsNil) } @@ -761,26 +761,26 @@ s.testMAASObject.TestServer.AddZone("zone1", "the grass is greener in zone1") env := s.makeEnviron() placement := "zone=zone2" - err := env.PrecheckInstance(coretesting.FakeDefaultSeries, constraints.Value{}, placement) + err := env.PrecheckInstance(series.LatestLts(), constraints.Value{}, placement) c.Assert(err, gc.ErrorMatches, `invalid availability zone "zone2"`) } func (s *environSuite) TestPrecheckInstanceAvailZonesUnsupported(c *gc.C) { env := s.makeEnviron() placement := "zone=test-unknown" - err := env.PrecheckInstance(coretesting.FakeDefaultSeries, constraints.Value{}, placement) + err := env.PrecheckInstance(series.LatestLts(), constraints.Value{}, placement) c.Assert(err, jc.Satisfies, errors.IsNotImplemented) } func (s *environSuite) TestPrecheckInvalidPlacement(c *gc.C) { env := s.makeEnviron() - err := env.PrecheckInstance(coretesting.FakeDefaultSeries, constraints.Value{}, "notzone=anything") + err := env.PrecheckInstance(series.LatestLts(), constraints.Value{}, "notzone=anything") c.Assert(err, gc.ErrorMatches, "unknown placement directive: notzone=anything") } func (s *environSuite) TestPrecheckNodePlacement(c *gc.C) { env := s.makeEnviron() - err := env.PrecheckInstance(coretesting.FakeDefaultSeries, constraints.Value{}, "assumed_node_name") + err := env.PrecheckInstance(series.LatestLts(), constraints.Value{}, "assumed_node_name") c.Assert(err, jc.ErrorIsNil) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/interfaces.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/interfaces.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/interfaces.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/interfaces.go 2016-05-17 20:01:14.000000000 +0000 @@ -242,11 +242,15 @@ nicType = network.VLAN_8021QInterface } + vlanTag := 0 + if iface.VLAN() != nil { + vlanTag = iface.VLAN().VID() + } nicInfo := network.InterfaceInfo{ DeviceIndex: i, MACAddress: iface.MACAddress(), ProviderId: network.Id(fmt.Sprintf("%v", iface.ID())), - VLANTag: iface.VLAN().VID(), + VLANTag: vlanTag, InterfaceName: iface.Name(), InterfaceType: nicType, ParentInterfaceName: parentName, diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/interfaces_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/interfaces_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/interfaces_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/interfaces_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -813,6 +813,70 @@ c.Check(infos, jc.DeepEquals, expected) } +func (s *interfacesSuite) TestMAAS2InterfacesNilVLAN(c *gc.C) { + vlan0 := fakeVLAN{ + id: 5001, + vid: 0, + mtu: 1500, + } + + subnetPXE := fakeSubnet{ + id: 3, + space: "default", + vlan: vlan0, + gateway: "10.20.19.2", + cidr: "10.20.19.0/24", + dnsServers: []string{"10.20.19.2", "10.20.19.3"}, + } + + exampleInterfaces := []gomaasapi.Interface{ + &fakeInterface{ + id: 91, + name: "eth0", + type_: "physical", + enabled: true, + macAddress: "52:54:00:70:9b:fe", + vlan: nil, + links: []gomaasapi.Link{&fakeLink{ + id: 436, + subnet: &subnetPXE, + ipAddress: "10.20.19.103", + mode: "static", + }}, + parents: []string{}, + children: []string{"eth0.100", "eth0.250", "eth0.50"}, + }, + } + + instance := &maas2Instance{machine: &fakeMachine{interfaceSet: exampleInterfaces}} + + expected := []network.InterfaceInfo{{ + DeviceIndex: 0, + MACAddress: "52:54:00:70:9b:fe", + CIDR: "10.20.19.0/24", + ProviderId: "91", + ProviderSubnetId: "3", + AvailabilityZones: nil, + VLANTag: 0, + ProviderVLANId: "5001", + ProviderAddressId: "436", + InterfaceName: "eth0", + InterfaceType: "ethernet", + Disabled: false, + NoAutoStart: false, + ConfigType: "static", + Address: network.NewAddressOnSpace("default", "10.20.19.103"), + DNSServers: network.NewAddressesOnSpace("default", "10.20.19.2", "10.20.19.3"), + DNSSearchDomains: nil, + MTU: 1500, + GatewayAddress: network.NewAddressOnSpace("default", "10.20.19.2"), + }} + + infos, err := maas2NetworkInterfaces(instance, map[string]network.Id{}) + c.Assert(err, jc.ErrorIsNil) + c.Check(infos, jc.DeepEquals, expected) +} + const lshwXMLTemplate = ` diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/maas2_environ_whitebox_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/maas2_environ_whitebox_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/maas2_environ_whitebox_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/maas2_environ_whitebox_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,25 +4,32 @@ package maas import ( + "bytes" "fmt" "net/http" "github.com/juju/errors" "github.com/juju/gomaasapi" + "github.com/juju/testing" jc "github.com/juju/testing/checkers" "github.com/juju/utils/arch" "github.com/juju/utils/set" gc "gopkg.in/check.v1" + goyaml "gopkg.in/yaml.v2" + "github.com/juju/juju/cloudconfig/cloudinit" "github.com/juju/juju/constraints" "github.com/juju/juju/environs" "github.com/juju/juju/environs/bootstrap" "github.com/juju/juju/environs/config" - envtesting "github.com/juju/juju/environs/testing" + envjujutesting "github.com/juju/juju/environs/testing" + envtools "github.com/juju/juju/environs/tools" "github.com/juju/juju/instance" - "github.com/juju/juju/juju/testing" + jujutesting "github.com/juju/juju/juju/testing" "github.com/juju/juju/network" - coretesting "github.com/juju/juju/testing" + "github.com/juju/juju/provider/common" + corejujutesting "github.com/juju/juju/testing" + jujuversion "github.com/juju/juju/version" ) type maas2EnvironSuite struct { @@ -40,23 +47,17 @@ testServer.AddGetResponse("/api/1.0/version/", http.StatusOK, "") testServer.Start() suite.AddCleanup(func(*gc.C) { testServer.Close() }) - testAttrs := coretesting.Attrs{} + testAttrs := corejujutesting.Attrs{} for k, v := range maasEnvAttrs { testAttrs[k] = v } testAttrs["maas-server"] = testServer.Server.URL - attrs := coretesting.FakeConfig().Merge(testAttrs) + attrs := corejujutesting.FakeConfig().Merge(testAttrs) cfg, err := config.New(config.NoDefaults, attrs) c.Assert(err, jc.ErrorIsNil) return NewEnviron(cfg) } -func (suite *maas2EnvironSuite) TestNewEnvironWithoutFeatureFlag(c *gc.C) { - suite.SetFeatureFlags() - _, err := suite.getEnvWithServer(c) - c.Assert(err, jc.Satisfies, errors.IsNotSupported) -} - func (suite *maas2EnvironSuite) TestNewEnvironWithController(c *gc.C) { env, err := suite.getEnvWithServer(c) c.Assert(err, jc.ErrorIsNil) @@ -91,12 +92,9 @@ } controller := &fakeController{ allocateMachineArgsCheck: check, - allocateMachine: &fakeMachine{ - systemID: "Bruce Sterling", - architecture: arch.HostArch(), - }, + allocateMachine: newFakeMachine("Bruce Sterling", arch.HostArch(), ""), allocateMachineMatches: gomaasapi.ConstraintMatches{ - Storage: map[string]gomaasapi.BlockDevice{}, + Storage: map[string][]gomaasapi.BlockDevice{}, }, spaces: spaces, } @@ -328,7 +326,7 @@ env := suite.injectControllerWithSpacesAndCheck(c, nil, gomaasapi.AllocateMachineArgs{}) params := environs.StartInstanceParams{} - result, err := testing.StartInstanceWithParams(env, "1", params) + result, err := jujutesting.StartInstanceWithParams(env, "1", params) c.Assert(err, jc.ErrorIsNil) c.Assert(result.Instance.Id(), gc.Equals, instance.Id("Bruce Sterling")) } @@ -343,12 +341,9 @@ MinMemory: 8192, }) }, - allocateMachine: &fakeMachine{ - systemID: "Bruce Sterling", - architecture: arch.HostArch(), - }, + allocateMachine: newFakeMachine("Bruce Sterling", arch.HostArch(), ""), allocateMachineMatches: gomaasapi.ConstraintMatches{ - Storage: map[string]gomaasapi.BlockDevice{}, + Storage: map[string][]gomaasapi.BlockDevice{}, }, zones: []gomaasapi.Zone{&fakeZone{name: "foo"}}, }) @@ -358,7 +353,7 @@ Placement: "zone=foo", Constraints: constraints.MustParse("mem=8G"), } - result, err := testing.StartInstanceWithParams(env, "1", params) + result, err := jujutesting.StartInstanceWithParams(env, "1", params) c.Assert(err, jc.ErrorIsNil) c.Assert(result.Instance.Id(), gc.Equals, instance.Id("Bruce Sterling")) } @@ -674,40 +669,32 @@ } func (suite *maas2EnvironSuite) TestWaitForNodeDeploymentError(c *gc.C) { - machine := &fakeMachine{ - systemID: "Bruce Sterling", - architecture: arch.HostArch(), - } + machine := newFakeMachine("Bruce Sterling", arch.HostArch(), "") controller := newFakeController() controller.allocateMachine = machine controller.allocateMachineMatches = gomaasapi.ConstraintMatches{ - Storage: map[string]gomaasapi.BlockDevice{}, + Storage: map[string][]gomaasapi.BlockDevice{}, } controller.machines = []gomaasapi.Machine{machine} suite.injectController(controller) suite.setupFakeTools(c) env := suite.makeEnviron(c, nil) - err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) + err := bootstrap.Bootstrap(envjujutesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) c.Assert(err, gc.ErrorMatches, "bootstrap instance started but did not change to Deployed state.*") } func (suite *maas2EnvironSuite) TestWaitForNodeDeploymentSucceeds(c *gc.C) { - machine := &fakeMachine{ - systemID: "Bruce Sterling", - architecture: arch.HostArch(), - statusName: "Deployed", - } - + machine := newFakeMachine("Bruce Sterling", arch.HostArch(), "Deployed") controller := newFakeController() controller.allocateMachine = machine controller.allocateMachineMatches = gomaasapi.ConstraintMatches{ - Storage: map[string]gomaasapi.BlockDevice{}, + Storage: map[string][]gomaasapi.BlockDevice{}, } controller.machines = []gomaasapi.Machine{machine} suite.injectController(controller) suite.setupFakeTools(c) env := suite.makeEnviron(c, nil) - err := bootstrap.Bootstrap(envtesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) + err := bootstrap.Bootstrap(envjujutesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) c.Assert(err, jc.ErrorIsNil) } @@ -875,14 +862,12 @@ }, } var env *maasEnviron + machine := newFakeMachine("Bruce Sterling", arch.HostArch(), "") + machine.interfaceSet = exampleInterfaces controller := &fakeController{ - allocateMachine: &fakeMachine{ - systemID: "Bruce Sterling", - architecture: arch.HostArch(), - interfaceSet: exampleInterfaces, - }, + allocateMachine: machine, allocateMachineMatches: gomaasapi.ConstraintMatches{ - Storage: map[string]gomaasapi.BlockDevice{}, + Storage: map[string][]gomaasapi.BlockDevice{}, }, } suite.injectController(controller) @@ -890,7 +875,7 @@ env = suite.makeEnviron(c, nil) params := environs.StartInstanceParams{} - result, err := testing.StartInstanceWithParams(env, "1", params) + result, err := jujutesting.StartInstanceWithParams(env, "1", params) c.Assert(err, jc.ErrorIsNil) expected := []network.InterfaceInfo{{ DeviceIndex: 0, @@ -957,3 +942,717 @@ } c.Assert(result.NetworkInfo, jc.DeepEquals, expected) } + +func (suite *maas2EnvironSuite) TestAllocateContainerAddressesSingleNic(c *gc.C) { + vlan1 := fakeVLAN{ + id: 5001, + mtu: 1500, + } + vlan2 := fakeVLAN{ + id: 5002, + mtu: 1500, + } + subnet1 := fakeSubnet{ + id: 3, + space: "default", + vlan: vlan1, + gateway: "10.20.19.2", + cidr: "10.20.19.0/24", + dnsServers: []string{"10.20.19.2", "10.20.19.3"}, + } + subnet2 := fakeSubnet{ + id: 4, + space: "freckles", + vlan: vlan2, + gateway: "192.168.1.1", + cidr: "192.168.1.0/24", + dnsServers: []string{"10.20.19.2", "10.20.19.3"}, + } + + interfaces := []gomaasapi.Interface{ + &fakeInterface{ + id: 91, + name: "eth0", + type_: "physical", + enabled: true, + macAddress: "52:54:00:70:9b:fe", + vlan: vlan1, + links: []gomaasapi.Link{ + &fakeLink{ + id: 436, + subnet: &subnet1, + ipAddress: "10.20.19.103", + mode: "static", + }, + }, + parents: []string{}, + children: []string{"eth0.100", "eth0.250", "eth0.50"}, + }, + } + deviceInterfaces := []gomaasapi.Interface{ + &fakeInterface{ + id: 93, + name: "eth1", + type_: "physical", + enabled: true, + macAddress: "53:54:00:70:9b:ff", + vlan: vlan2, + links: []gomaasapi.Link{ + &fakeLink{ + id: 480, + subnet: &subnet2, + ipAddress: "192.168.1.127", + mode: "static", + }, + }, + parents: []string{}, + children: []string{"eth0.100", "eth0.250", "eth0.50"}, + }, + } + var env *maasEnviron + device := &fakeDevice{ + interfaceSet: deviceInterfaces, + systemID: "foo", + } + controller := &fakeController{ + machines: []gomaasapi.Machine{&fakeMachine{ + Stub: &testing.Stub{}, + systemID: "1", + architecture: arch.HostArch(), + interfaceSet: interfaces, + createDevice: device, + }}, + spaces: []gomaasapi.Space{ + fakeSpace{ + name: "freckles", + id: 4567, + subnets: []gomaasapi.Subnet{subnet1, subnet2}, + }, + }, + devices: []gomaasapi.Device{device}, + } + suite.injectController(controller) + suite.setupFakeTools(c) + env = suite.makeEnviron(c, nil) + + prepared := []network.InterfaceInfo{{ + MACAddress: "52:54:00:70:9b:fe", + CIDR: "10.20.19.0/24", + InterfaceName: "eth0", + }} + result, err := env.AllocateContainerAddresses(instance.Id("1"), prepared) + c.Assert(err, jc.ErrorIsNil) + expected := []network.InterfaceInfo{{ + DeviceIndex: 0, + MACAddress: "53:54:00:70:9b:ff", + CIDR: "192.168.1.0/24", + ProviderId: "93", + ProviderSubnetId: "4", + VLANTag: 0, + ProviderVLANId: "5002", + ProviderAddressId: "480", + InterfaceName: "eth1", + InterfaceType: "ethernet", + ConfigType: "static", + Address: network.NewAddressOnSpace("freckles", "192.168.1.127"), + DNSServers: network.NewAddressesOnSpace("freckles", "10.20.19.2", "10.20.19.3"), + MTU: 1500, + GatewayAddress: network.NewAddressOnSpace("freckles", "192.168.1.1"), + }} + c.Assert(result, jc.DeepEquals, expected) +} + +func (suite *maas2EnvironSuite) TestAllocateContainerAddressesDualNic(c *gc.C) { + vlan1 := fakeVLAN{ + id: 5001, + mtu: 1500, + } + vlan2 := fakeVLAN{ + id: 5002, + mtu: 1500, + } + subnet1 := fakeSubnet{ + id: 3, + space: "freckles", + vlan: vlan1, + gateway: "10.20.19.2", + cidr: "10.20.19.0/24", + dnsServers: []string{"10.20.19.2", "10.20.19.3"}, + } + subnet2 := fakeSubnet{ + id: 4, + space: "freckles", + vlan: vlan2, + gateway: "192.168.1.1", + cidr: "192.168.1.0/24", + dnsServers: []string{"10.20.19.2", "10.20.19.3"}, + } + + interfaces := []gomaasapi.Interface{ + &fakeInterface{ + id: 91, + name: "eth0", + type_: "physical", + enabled: true, + macAddress: "52:54:00:70:9b:fe", + vlan: vlan1, + links: []gomaasapi.Link{ + &fakeLink{ + id: 436, + subnet: &subnet1, + ipAddress: "10.20.19.103", + mode: "static", + }, + }, + parents: []string{}, + children: []string{"eth0.100", "eth0.250", "eth0.50"}, + }, + &fakeInterface{ + id: 92, + name: "eth1", + type_: "physical", + enabled: true, + macAddress: "52:54:00:70:9b:ff", + vlan: vlan2, + links: []gomaasapi.Link{ + &fakeLink{ + id: 437, + subnet: &subnet2, + ipAddress: "192.168.1.4", + mode: "static", + }, + }, + }, + } + deviceInterfaces := []gomaasapi.Interface{ + &fakeInterface{ + id: 93, + name: "eth0", + type_: "physical", + enabled: true, + macAddress: "53:54:00:70:9b:ff", + vlan: vlan1, + links: []gomaasapi.Link{ + &fakeLink{ + id: 480, + subnet: &subnet1, + ipAddress: "10.20.19.127", + mode: "static", + }, + }, + parents: []string{}, + children: []string{"eth0.100", "eth0.250", "eth0.50"}, + Stub: &testing.Stub{}, + }, + } + newInterface := &fakeInterface{ + id: 94, + name: "eth1", + type_: "physical", + enabled: true, + macAddress: "52:54:00:70:9b:f4", + vlan: vlan2, + links: []gomaasapi.Link{ + &fakeLink{ + id: 481, + subnet: &subnet2, + ipAddress: "192.168.1.127", + mode: "static", + }, + }, + Stub: &testing.Stub{}, + } + device := &fakeDevice{ + interfaceSet: deviceInterfaces, + systemID: "foo", + interface_: newInterface, + Stub: &testing.Stub{}, + } + controller := &fakeController{ + machines: []gomaasapi.Machine{&fakeMachine{ + Stub: &testing.Stub{}, + systemID: "1", + architecture: arch.HostArch(), + interfaceSet: interfaces, + createDevice: device, + }}, + spaces: []gomaasapi.Space{ + fakeSpace{ + name: "freckles", + id: 4567, + subnets: []gomaasapi.Subnet{subnet1, subnet2}, + }, + }, + devices: []gomaasapi.Device{device}, + } + suite.injectController(controller) + env := suite.makeEnviron(c, nil) + + prepared := []network.InterfaceInfo{{ + MACAddress: "53:54:00:70:9b:ff", + CIDR: "10.20.19.0/24", + InterfaceName: "eth0", + }, { + MACAddress: "52:54:00:70:9b:f4", + CIDR: "192.168.1.0/24", + InterfaceName: "eth1", + }} + expected := []network.InterfaceInfo{{ + DeviceIndex: 0, + MACAddress: "53:54:00:70:9b:ff", + CIDR: "10.20.19.0/24", + ProviderId: "93", + ProviderSubnetId: "3", + ProviderVLANId: "5001", + ProviderAddressId: "480", + InterfaceName: "eth0", + InterfaceType: "ethernet", + ConfigType: "static", + Address: network.NewAddressOnSpace("freckles", "10.20.19.127"), + DNSServers: network.NewAddressesOnSpace("freckles", "10.20.19.2", "10.20.19.3"), + MTU: 1500, + GatewayAddress: network.NewAddressOnSpace("freckles", "10.20.19.2"), + }, { + DeviceIndex: 0, + MACAddress: "52:54:00:70:9b:f4", + CIDR: "192.168.1.0/24", + ProviderId: "94", + ProviderSubnetId: "4", + ProviderVLANId: "5002", + ProviderAddressId: "481", + InterfaceName: "eth1", + InterfaceType: "ethernet", + ConfigType: "static", + Address: network.NewAddressOnSpace("freckles", "192.168.1.127"), + DNSServers: network.NewAddressesOnSpace("freckles", "10.20.19.2", "10.20.19.3"), + MTU: 1500, + GatewayAddress: network.NewAddressOnSpace("freckles", "192.168.1.1"), + }} + result, err := env.AllocateContainerAddresses(instance.Id("1"), prepared) + c.Assert(err, jc.ErrorIsNil) + c.Assert(result, jc.DeepEquals, expected) +} + +func (suite *maas2EnvironSuite) assertAllocateContainerAddressesFails(c *gc.C, controller *fakeController, prepared []network.InterfaceInfo, errorMatches string) { + if prepared == nil { + prepared = []network.InterfaceInfo{{}} + } + suite.injectController(controller) + env := suite.makeEnviron(c, nil) + _, err := env.AllocateContainerAddresses(instance.Id("1"), prepared) + c.Assert(err, gc.ErrorMatches, errorMatches) +} + +func (suite *maas2EnvironSuite) TestAllocateContainerAddressesSpacesError(c *gc.C) { + controller := &fakeController{spacesError: errors.New("boom")} + suite.assertAllocateContainerAddressesFails(c, controller, nil, "boom") +} + +func (suite *maas2EnvironSuite) TestAllocateContainerAddressesPrimaryInterfaceMissing(c *gc.C) { + controller := &fakeController{} + suite.assertAllocateContainerAddressesFails(c, controller, nil, "cannot find primary interface for container") +} + +func (suite *maas2EnvironSuite) TestAllocateContainerAddressesPrimaryInterfaceSubnetMissing(c *gc.C) { + controller := &fakeController{} + prepared := []network.InterfaceInfo{{InterfaceName: "eth0"}} + errorMatches := "primary NIC subnet not found" + suite.assertAllocateContainerAddressesFails(c, controller, prepared, errorMatches) +} + +func makeFakeSubnet(id int) fakeSubnet { + return fakeSubnet{ + id: id, + space: "freckles", + gateway: fmt.Sprintf("10.20.%d.2", 16+id), + cidr: fmt.Sprintf("10.20.%d.0/24", 16+id), + } +} +func (suite *maas2EnvironSuite) TestAllocateContainerAddressesMachinesError(c *gc.C) { + var env *maasEnviron + subnet := makeFakeSubnet(3) + checkMachinesArgs := func(args gomaasapi.MachinesArgs) { + expected := gomaasapi.MachinesArgs{ + AgentName: env.ecfg().maasAgentName(), + SystemIDs: []string{"1"}, + } + c.Assert(args, jc.DeepEquals, expected) + } + controller := &fakeController{ + machinesError: errors.New("boom"), + machinesArgsCheck: checkMachinesArgs, + spaces: []gomaasapi.Space{ + fakeSpace{ + name: "freckles", + id: 4567, + subnets: []gomaasapi.Subnet{subnet}, + }, + }, + } + suite.injectController(controller) + env = suite.makeEnviron(c, nil) + prepared := []network.InterfaceInfo{ + {InterfaceName: "eth0", CIDR: "10.20.19.0/24"}, + } + _, err := env.AllocateContainerAddresses(instance.Id("1"), prepared) + c.Assert(err, gc.ErrorMatches, "boom") +} + +func getArgs(c *gc.C, calls []testing.StubCall) interface{} { + c.Assert(calls, gc.HasLen, 1) + args := calls[0].Args + c.Assert(args, gc.HasLen, 1) + return args[0] +} + +func (suite *maas2EnvironSuite) TestAllocateContainerAddressesCreateDevicerror(c *gc.C) { + subnet := makeFakeSubnet(3) + var env *maasEnviron + machine := &fakeMachine{ + Stub: &testing.Stub{}, + systemID: "1", + } + machine.SetErrors(errors.New("boom")) + controller := &fakeController{ + machines: []gomaasapi.Machine{machine}, + spaces: []gomaasapi.Space{ + fakeSpace{ + name: "freckles", + id: 4567, + subnets: []gomaasapi.Subnet{subnet}, + }, + }, + } + suite.injectController(controller) + env = suite.makeEnviron(c, nil) + prepared := []network.InterfaceInfo{ + {InterfaceName: "eth0", CIDR: "10.20.19.0/24", MACAddress: "DEADBEEF"}, + } + _, err := env.AllocateContainerAddresses(instance.Id("1"), prepared) + c.Assert(err, gc.ErrorMatches, "boom") + args := getArgs(c, machine.Calls()) + maasArgs, ok := args.(gomaasapi.CreateMachineDeviceArgs) + c.Assert(ok, jc.IsTrue) + expected := gomaasapi.CreateMachineDeviceArgs{ + Subnet: subnet, + MACAddress: "DEADBEEF", + InterfaceName: "eth0", + } + c.Assert(maasArgs, jc.DeepEquals, expected) +} + +func (suite *maas2EnvironSuite) TestAllocateContainerAddressesSecondNICSubnetMissing(c *gc.C) { + subnet := makeFakeSubnet(3) + var env *maasEnviron + device := &fakeDevice{ + interfaceSet: []gomaasapi.Interface{&fakeInterface{}}, + systemID: "foo", + } + machine := &fakeMachine{ + Stub: &testing.Stub{}, + systemID: "1", + createDevice: device, + } + controller := &fakeController{ + machines: []gomaasapi.Machine{machine}, + spaces: []gomaasapi.Space{ + fakeSpace{ + name: "freckles", + id: 4567, + subnets: []gomaasapi.Subnet{subnet}, + }, + }, + } + suite.injectController(controller) + env = suite.makeEnviron(c, nil) + prepared := []network.InterfaceInfo{ + {InterfaceName: "eth0", CIDR: "10.20.19.0/24", MACAddress: "DEADBEEF"}, + {InterfaceName: "eth1", CIDR: "10.20.20.0/24", MACAddress: "DEADBEEE"}, + } + _, err := env.AllocateContainerAddresses(instance.Id("1"), prepared) + c.Assert(err, gc.ErrorMatches, "NIC eth1 subnet 10.20.20.0/24 not found") +} + +func (suite *maas2EnvironSuite) TestAllocateContainerAddressesCreateInterfaceError(c *gc.C) { + subnet := makeFakeSubnet(3) + subnet2 := makeFakeSubnet(4) + subnet2.vlan = fakeVLAN{vid: 66} + var env *maasEnviron + device := &fakeDevice{ + Stub: &testing.Stub{}, + interfaceSet: []gomaasapi.Interface{&fakeInterface{}}, + systemID: "foo", + } + device.SetErrors(errors.New("boom")) + machine := &fakeMachine{ + Stub: &testing.Stub{}, + systemID: "1", + createDevice: device, + } + controller := &fakeController{ + machines: []gomaasapi.Machine{machine}, + spaces: []gomaasapi.Space{ + fakeSpace{ + name: "freckles", + id: 4567, + subnets: []gomaasapi.Subnet{subnet, subnet2}, + }, + }, + } + suite.injectController(controller) + env = suite.makeEnviron(c, nil) + prepared := []network.InterfaceInfo{ + {InterfaceName: "eth0", CIDR: "10.20.19.0/24", MACAddress: "DEADBEEF"}, + {InterfaceName: "eth1", CIDR: "10.20.20.0/24", MACAddress: "DEADBEEE"}, + } + _, err := env.AllocateContainerAddresses(instance.Id("1"), prepared) + c.Assert(err, gc.ErrorMatches, "creating device interface: boom") + args := getArgs(c, device.Calls()) + maasArgs, ok := args.(gomaasapi.CreateInterfaceArgs) + c.Assert(ok, jc.IsTrue) + expected := gomaasapi.CreateInterfaceArgs{ + MACAddress: "DEADBEEE", + Name: "eth1", + VLAN: subnet2.VLAN(), + } + c.Assert(maasArgs, jc.DeepEquals, expected) +} + +func (suite *maas2EnvironSuite) TestAllocateContainerAddressesLinkSubnetError(c *gc.C) { + subnet := makeFakeSubnet(3) + subnet2 := makeFakeSubnet(4) + subnet2.vlan = fakeVLAN{vid: 66} + var env *maasEnviron + interface_ := &fakeInterface{Stub: &testing.Stub{}} + interface_.SetErrors(errors.New("boom")) + device := &fakeDevice{ + Stub: &testing.Stub{}, + interfaceSet: []gomaasapi.Interface{&fakeInterface{}}, + interface_: interface_, + systemID: "foo", + } + machine := &fakeMachine{ + Stub: &testing.Stub{}, + systemID: "1", + createDevice: device, + } + controller := &fakeController{ + machines: []gomaasapi.Machine{machine}, + spaces: []gomaasapi.Space{ + fakeSpace{ + name: "freckles", + id: 4567, + subnets: []gomaasapi.Subnet{subnet, subnet2}, + }, + }, + } + suite.injectController(controller) + env = suite.makeEnviron(c, nil) + prepared := []network.InterfaceInfo{ + {InterfaceName: "eth0", CIDR: "10.20.19.0/24", MACAddress: "DEADBEEF"}, + {InterfaceName: "eth1", CIDR: "10.20.20.0/24", MACAddress: "DEADBEEE"}, + } + _, err := env.AllocateContainerAddresses(instance.Id("1"), prepared) + c.Assert(err, gc.ErrorMatches, "cannot link device interface to subnet: boom") + args := getArgs(c, interface_.Calls()) + maasArgs, ok := args.(gomaasapi.LinkSubnetArgs) + c.Assert(ok, jc.IsTrue) + expected := gomaasapi.LinkSubnetArgs{ + Mode: gomaasapi.LinkModeStatic, + Subnet: subnet2, + } + c.Assert(maasArgs, jc.DeepEquals, expected) +} +func (suite *maas2EnvironSuite) TestStorageReturnsStorage(c *gc.C) { + controller := newFakeController() + env := suite.makeEnviron(c, controller) + stor := env.Storage() + c.Check(stor, gc.NotNil) + + // The Storage object is really a maas2Storage. + specificStorage := stor.(*maas2Storage) + + // Its environment pointer refers back to its environment. + c.Check(specificStorage.environ, gc.Equals, env) + c.Check(specificStorage.maasController, gc.Equals, controller) +} + +func (suite *maas2EnvironSuite) TestStartInstanceEndToEnd(c *gc.C) { + suite.setupFakeTools(c) + machine := newFakeMachine("gus", arch.HostArch(), "Deployed") + file := &fakeFile{name: "agent-prefix-provider-state"} + controller := newFakeControllerWithFiles(file) + controller.machines = []gomaasapi.Machine{machine} + controller.allocateMachine = machine + controller.allocateMachineMatches = gomaasapi.ConstraintMatches{ + Storage: make(map[string][]gomaasapi.BlockDevice), + } + + env := suite.makeEnviron(c, controller) + err := bootstrap.Bootstrap(envjujutesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) + c.Assert(err, jc.ErrorIsNil) + + machine.Stub.CheckCallNames(c, "Start") + controller.Stub.CheckCallNames(c, "GetFile", "AddFile") + addFileArgs, ok := controller.Stub.Calls()[1].Args[0].(gomaasapi.AddFileArgs) + c.Assert(ok, jc.IsTrue) + + // Make it look like the right state was written to the file. + buffer := new(bytes.Buffer) + buffer.ReadFrom(addFileArgs.Reader) + file.contents = buffer.Bytes() + c.Check(string(buffer.Bytes()), gc.Equals, "state-instances:\n- gus\n") + + // Test the instance id is correctly recorded for the bootstrap node. + // Check that ControllerInstances returns the id of the bootstrap machine. + instanceIds, err := env.ControllerInstances() + c.Assert(err, jc.ErrorIsNil) + c.Assert(instanceIds, gc.HasLen, 1) + insts, err := env.AllInstances() + c.Assert(err, jc.ErrorIsNil) + c.Assert(insts, gc.HasLen, 1) + c.Check(insts[0].Id(), gc.Equals, instanceIds[0]) + + node1 := newFakeMachine("victor", arch.HostArch(), "Deployed") + node1.hostname = "host1" + node1.cpuCount = 1 + node1.memory = 1024 + node1.zoneName = "test_zone" + controller.allocateMachine = node1 + + instance, hc := jujutesting.AssertStartInstance(c, env, "1") + c.Check(instance, gc.NotNil) + c.Assert(hc, gc.NotNil) + c.Check(hc.String(), gc.Equals, fmt.Sprintf("arch=%s cpu-cores=1 mem=1024M availability-zone=test_zone", arch.HostArch())) + + node1.Stub.CheckCallNames(c, "Start") + startArgs, ok := node1.Stub.Calls()[0].Args[0].(gomaasapi.StartArgs) + c.Assert(ok, jc.IsTrue) + + decodedUserData, err := decodeUserData(startArgs.UserData) + c.Assert(err, jc.ErrorIsNil) + info := machineInfo{"host1"} + cloudcfg, err := cloudinit.New("precise") + c.Assert(err, jc.ErrorIsNil) + cloudinitRunCmd, err := info.cloudinitRunCmd(cloudcfg) + c.Assert(err, jc.ErrorIsNil) + data, err := goyaml.Marshal(cloudinitRunCmd) + c.Assert(err, jc.ErrorIsNil) + c.Check(string(decodedUserData), jc.Contains, string(data)) + + // Trash the tools and try to start another instance. + suite.PatchValue(&envtools.DefaultBaseURL, "") + instance, _, _, err = jujutesting.StartInstance(env, "2") + c.Check(instance, gc.IsNil) + c.Check(err, jc.Satisfies, errors.IsNotFound) +} + +func (suite *maas2EnvironSuite) TestControllerInstances(c *gc.C) { + controller := newFakeControllerWithErrors(gomaasapi.NewNoMatchError("state")) + env := suite.makeEnviron(c, controller) + _, err := env.ControllerInstances() + c.Assert(err, gc.Equals, environs.ErrNotBootstrapped) + + tests := [][]instance.Id{{}, {"inst-0"}, {"inst-0", "inst-1"}} + for _, expected := range tests { + state, err := goyaml.Marshal(&common.BootstrapState{StateInstances: expected}) + c.Assert(err, jc.ErrorIsNil) + + controller.files = []gomaasapi.File{&fakeFile{ + name: "agent-prefix-provider-state", + contents: state, + }} + controllerInstances, err := env.ControllerInstances() + c.Assert(err, jc.ErrorIsNil) + c.Assert(controllerInstances, jc.SameContents, expected) + } +} + +func (suite *maas2EnvironSuite) TestControllerInstancesFailsIfNoStateInstances(c *gc.C) { + env := suite.makeEnviron(c, + newFakeControllerWithErrors(gomaasapi.NewNoMatchError("state"))) + _, err := env.ControllerInstances() + c.Check(err, gc.Equals, environs.ErrNotBootstrapped) +} + +func (suite *maas2EnvironSuite) TestDestroy(c *gc.C) { + file1 := &fakeFile{name: "agent-prefix-provider-state"} + file2 := &fakeFile{name: "agent-prefix-horace"} + controller := newFakeControllerWithFiles(file1, file2) + controller.machines = []gomaasapi.Machine{&fakeMachine{systemID: "pete"}} + env := suite.makeEnviron(c, controller) + err := env.Destroy() + c.Check(err, jc.ErrorIsNil) + + controller.Stub.CheckCallNames(c, "ReleaseMachines", "GetFile", "Files", "GetFile", "GetFile") + // Instances have been stopped. + controller.Stub.CheckCall(c, 0, "ReleaseMachines", gomaasapi.ReleaseMachinesArgs{ + SystemIDs: []string{"pete"}, + Comment: "Released by Juju MAAS provider", + }) + + // Files have been cleaned up. + c.Check(file1.deleted, jc.IsTrue) + c.Check(file2.deleted, jc.IsTrue) +} + +func (suite *maas2EnvironSuite) TestBootstrapFailsIfNoTools(c *gc.C) { + env := suite.makeEnviron(c, newFakeController()) + // Disable auto-uploading by setting the agent version. + cfg, err := env.Config().Apply(map[string]interface{}{ + "agent-version": jujuversion.Current.String(), + }) + c.Assert(err, jc.ErrorIsNil) + err = env.SetConfig(cfg) + c.Assert(err, jc.ErrorIsNil) + err = bootstrap.Bootstrap(envjujutesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) + c.Check(err, gc.ErrorMatches, "Juju cannot bootstrap because no tools are available for your model(.|\n)*") +} + +func (suite *maas2EnvironSuite) TestBootstrapFailsIfNoNodes(c *gc.C) { + suite.setupFakeTools(c) + controller := newFakeController() + controller.allocateMachineError = gomaasapi.NewNoMatchError("oops") + env := suite.makeEnviron(c, controller) + err := bootstrap.Bootstrap(envjujutesting.BootstrapContext(c), env, bootstrap.BootstrapParams{}) + // Since there are no nodes, the attempt to allocate one returns a + // 409: Conflict. + c.Check(err, gc.ErrorMatches, ".*cannot run instances.*") +} + +func (suite *maas2EnvironSuite) TestGetToolsMetadataSources(c *gc.C) { + // Add a dummy file to storage so we can use that to check the + // obtained source later. + env := suite.makeEnviron(c, newFakeControllerWithFiles( + &fakeFile{name: "agent-prefix-tools/filename", contents: makeRandomBytes(10)}, + )) + sources, err := envtools.GetMetadataSources(env) + c.Assert(err, jc.ErrorIsNil) + c.Assert(sources, gc.HasLen, 0) +} + +func (suite *maas2EnvironSuite) TestConstraintsValidator(c *gc.C) { + controller := newFakeController() + controller.bootResources = []gomaasapi.BootResource{&fakeBootResource{name: "trusty", architecture: "amd64"}} + env := suite.makeEnviron(c, controller) + validator, err := env.ConstraintsValidator() + c.Assert(err, jc.ErrorIsNil) + cons := constraints.MustParse("arch=amd64 cpu-power=10 instance-type=foo virt-type=kvm") + unsupported, err := validator.Validate(cons) + c.Assert(err, jc.ErrorIsNil) + c.Assert(unsupported, jc.SameContents, []string{"cpu-power", "instance-type", "virt-type"}) +} + +func (suite *maas2EnvironSuite) TestConstraintsValidatorVocab(c *gc.C) { + controller := newFakeController() + controller.bootResources = []gomaasapi.BootResource{ + &fakeBootResource{name: "trusty", architecture: "amd64"}, + &fakeBootResource{name: "precise", architecture: "armhf"}, + } + env := suite.makeEnviron(c, controller) + validator, err := env.ConstraintsValidator() + c.Assert(err, jc.ErrorIsNil) + cons := constraints.MustParse("arch=ppc64el") + _, err = validator.Validate(cons) + c.Assert(err, gc.ErrorMatches, "invalid constraint value: arch=ppc64el\nvalid values are: \\[amd64 armhf\\]") +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/maas2_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/maas2_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/maas2_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/maas2_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -12,7 +12,6 @@ gc "gopkg.in/check.v1" "github.com/juju/juju/environs/config" - "github.com/juju/juju/feature" coretesting "github.com/juju/juju/testing" "github.com/juju/juju/version" ) @@ -21,11 +20,6 @@ baseProviderSuite } -func (suite *maas2Suite) SetUpTest(c *gc.C) { - suite.baseProviderSuite.SetUpTest(c) - suite.SetFeatureFlags(feature.MAAS2) -} - func (suite *maas2Suite) injectController(controller gomaasapi.Controller) { mockGetController := func(maasServer, apiKey string) (gomaasapi.Controller, error) { return controller, nil @@ -74,6 +68,8 @@ allocateMachineArgsCheck func(gomaasapi.AllocateMachineArgs) files []gomaasapi.File + + devices []gomaasapi.Device } func newFakeController() *fakeController { @@ -90,6 +86,10 @@ return &fakeController{Stub: &testing.Stub{}, files: files} } +func (c *fakeController) Devices(gomaasapi.DevicesArgs) ([]gomaasapi.Device, error) { + return c.devices, nil +} + func (c *fakeController) Machines(args gomaasapi.MachinesArgs) ([]gomaasapi.Machine, error) { if c.machinesArgsCheck != nil { c.machinesArgsCheck(args) @@ -188,6 +188,8 @@ type fakeMachine struct { gomaasapi.Machine + *testing.Stub + zoneName string hostname string systemID string @@ -199,6 +201,16 @@ architecture string interfaceSet []gomaasapi.Interface tags []string + createDevice gomaasapi.Device +} + +func newFakeMachine(systemID, architecture, statusName string) *fakeMachine { + return &fakeMachine{ + Stub: &testing.Stub{}, + systemID: systemID, + architecture: architecture, + statusName: statusName, + } } func (m *fakeMachine) Tags() []string { @@ -246,7 +258,13 @@ } func (m *fakeMachine) Start(args gomaasapi.StartArgs) error { - return nil + m.MethodCall(m, "Start", args) + return m.NextErr() +} + +func (m *fakeMachine) CreateDevice(args gomaasapi.CreateMachineDeviceArgs) (gomaasapi.Device, error) { + m.MethodCall(m, "CreateDevice", args) + return m.createDevice, m.NextErr() } type fakeZone struct { @@ -332,6 +350,8 @@ type fakeInterface struct { gomaasapi.Interface + *testing.Stub + id int name string parents []string @@ -363,6 +383,10 @@ return v.type_ } +func (v *fakeInterface) EffectiveMTU() int { + return 1500 +} + func (v *fakeInterface) Enabled() bool { return v.enabled } @@ -379,6 +403,11 @@ return v.macAddress } +func (v *fakeInterface) LinkSubnet(args gomaasapi.LinkSubnetArgs) error { + v.MethodCall(v, "LinkSubnet", args) + return v.NextErr() +} + type fakeLink struct { gomaasapi.Link id int @@ -450,3 +479,26 @@ func (bd fakeBlockDevice) Size() uint64 { return bd.size } + +type fakeDevice struct { + gomaasapi.Device + *testing.Stub + + interfaceSet []gomaasapi.Interface + systemID string + interface_ gomaasapi.Interface +} + +func (d *fakeDevice) InterfaceSet() []gomaasapi.Interface { + return d.interfaceSet +} + +func (d *fakeDevice) SystemID() string { + return d.systemID +} + +func (d *fakeDevice) CreateInterface(args gomaasapi.CreateInterfaceArgs) (gomaasapi.Interface, error) { + d.MethodCall(d, "CreateInterface", args) + d.interfaceSet = append(d.interfaceSet, d.interface_) + return d.interface_, d.NextErr() +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/maas_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/maas_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/maas_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/maas_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -8,11 +8,13 @@ "encoding/json" "fmt" "net" + "path/filepath" "strconv" "time" "github.com/juju/gomaasapi" jc "github.com/juju/testing/checkers" + "github.com/juju/utils" "github.com/juju/utils/arch" "github.com/juju/utils/series" "github.com/juju/utils/set" @@ -40,7 +42,8 @@ func (suite *baseProviderSuite) setupFakeTools(c *gc.C) { suite.PatchValue(&juju.JujuPublicKey, sstesting.SignedMetadataPublicKey) storageDir := c.MkDir() - suite.PatchValue(&envtools.DefaultBaseURL, "file://"+storageDir+"/tools") + toolsDir := filepath.Join(storageDir, "tools") + suite.PatchValue(&envtools.DefaultBaseURL, utils.MakeFileURL(toolsDir)) suite.UploadFakeToolsToDirectory(c, storageDir, "released", "released") } @@ -62,7 +65,7 @@ s.ToolsFixture.SetUpTest(c) s.PatchValue(&jujuversion.Current, coretesting.FakeVersionNumber) s.PatchValue(&arch.HostArch, func() string { return arch.AMD64 }) - s.PatchValue(&series.HostSeries, func() string { return coretesting.FakeDefaultSeries }) + s.PatchValue(&series.HostSeries, func() string { return series.LatestLts() }) s.SetFeatureFlags(feature.AddressAllocation) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/util.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/util.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/util.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/util.go 2016-05-17 20:01:14.000000000 +0000 @@ -10,10 +10,10 @@ "github.com/juju/errors" "github.com/juju/utils" + "github.com/juju/utils/series" goyaml "gopkg.in/yaml.v2" "github.com/juju/juju/cloudconfig/cloudinit" - "github.com/juju/juju/environs/config" "github.com/juju/juju/instance" "github.com/juju/juju/juju/paths" ) @@ -48,7 +48,7 @@ Hostname string `yaml:",omitempty"` } -var maasDataDir = paths.MustSucceed(paths.DataDir(config.LatestLtsSeries())) +var maasDataDir = paths.MustSucceed(paths.DataDir(series.LatestLts())) var _MAASInstanceFilename = path.Join(maasDataDir, "MAASmachine.txt") // cloudinitRunCmd returns the shell command that, when run, will create the diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/volumes.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/volumes.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/volumes.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/volumes.go 2016-05-17 20:01:14.000000000 +0000 @@ -292,7 +292,7 @@ validVolumes.Add(v.Id()) } - for label, device := range mi.constraintMatches.Storage { + for label, devices := range mi.constraintMatches.Storage { // We don't explicitly allow the root volume to be specified yet. if label == rootDiskLabel { continue @@ -302,26 +302,28 @@ continue } - volumeTag := names.NewVolumeTag(label) - vol := storage.Volume{ - volumeTag, - storage.VolumeInfo{ - VolumeId: volumeTag.String(), - Size: uint64(device.Size() / humanize.MiByte), - Persistent: false, - }, - } - volumes = append(volumes, vol) + for _, device := range devices { + volumeTag := names.NewVolumeTag(label) + vol := storage.Volume{ + volumeTag, + storage.VolumeInfo{ + VolumeId: volumeTag.String(), + Size: uint64(device.Size() / humanize.MiByte), + Persistent: false, + }, + } + volumes = append(volumes, vol) - attachment := storage.VolumeAttachment{ - volumeTag, - mTag, - storage.VolumeAttachmentInfo{ - DeviceLink: device.Path(), - ReadOnly: false, - }, + attachment := storage.VolumeAttachment{ + volumeTag, + mTag, + storage.VolumeAttachmentInfo{ + DeviceLink: device.Path(), + ReadOnly: false, + }, + } + attachments = append(attachments, attachment) } - attachments = append(attachments, attachment) } return volumes, attachments, nil } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/volumes_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/volumes_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/maas/volumes_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/maas/volumes_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -78,12 +78,15 @@ instance := maas2Instance{ machine: &fakeMachine{}, constraintMatches: gomaasapi.ConstraintMatches{ - Storage: map[string]gomaasapi.BlockDevice{ - "root": &fakeBlockDevice{name: "sda", path: "/dev/disk/by-dname/sda", size: 250059350016}, - "1": &fakeBlockDevice{name: "sdb", path: "/dev/disk/by-dname/sdb", size: 500059350016}, - "2": &fakeBlockDevice{name: "sdc", path: "/dev/disk/by-dname/sdc", size: 250362438230}, - "3": &fakeBlockDevice{name: "sdd", path: "/dev/disk/by-dname/sdd", size: 250362438230}, - "4": &fakeBlockDevice{name: "sde", path: "/dev/disk/by-dname/sde", size: 250362438230}, + Storage: map[string][]gomaasapi.BlockDevice{ + "root": {&fakeBlockDevice{name: "sda", path: "/dev/disk/by-dname/sda", size: 250059350016}}, + "1": {&fakeBlockDevice{name: "sdb", path: "/dev/disk/by-dname/sdb", size: 500059350016}}, + "2": { + &fakeBlockDevice{name: "sdc", path: "/dev/disk/by-dname/sdc", size: 250362438230}, + &fakeBlockDevice{name: "sdf", path: "/dev/disk/by-dname/sdf", size: 280362438231}, + }, + "3": {&fakeBlockDevice{name: "sdd", path: "/dev/disk/by-dname/sdd", size: 250362438230}}, + "4": {&fakeBlockDevice{name: "sde", path: "/dev/disk/by-dname/sde", size: 250362438230}}, }, }, } @@ -93,9 +96,9 @@ names.NewVolumeTag("2"), }) c.Assert(err, jc.ErrorIsNil) - // Expect 2 volumes - root volume is ignored. - c.Assert(volumes, gc.HasLen, 2) - c.Assert(attachments, gc.HasLen, 2) + // Expect 3 volumes - root volume is ignored. + c.Assert(volumes, gc.HasLen, 3) + c.Assert(attachments, gc.HasLen, 3) c.Check(volumes, jc.SameContents, []storage.Volume{{ names.NewVolumeTag("1"), storage.VolumeInfo{ @@ -110,25 +113,36 @@ Size: 238764, Persistent: false, }, + }, { + names.NewVolumeTag("2"), + storage.VolumeInfo{ + VolumeId: "volume-2", + Size: 267374, + Persistent: false, + }, }}) - c.Assert(attachments, jc.SameContents, []storage.VolumeAttachment{ - { - names.NewVolumeTag("1"), - mTag, - storage.VolumeAttachmentInfo{ - DeviceLink: "/dev/disk/by-dname/sdb", - ReadOnly: false, - }, + c.Assert(attachments, jc.SameContents, []storage.VolumeAttachment{{ + names.NewVolumeTag("1"), + mTag, + storage.VolumeAttachmentInfo{ + DeviceLink: "/dev/disk/by-dname/sdb", + ReadOnly: false, }, - { - names.NewVolumeTag("2"), - mTag, - storage.VolumeAttachmentInfo{ - DeviceLink: "/dev/disk/by-dname/sdc", - ReadOnly: false, - }, + }, { + names.NewVolumeTag("2"), + mTag, + storage.VolumeAttachmentInfo{ + DeviceLink: "/dev/disk/by-dname/sdc", + ReadOnly: false, }, - }) + }, { + names.NewVolumeTag("2"), + mTag, + storage.VolumeAttachmentInfo{ + DeviceLink: "/dev/disk/by-dname/sdf", + ReadOnly: false, + }, + }}) } func (s *volumeSuite) TestInstanceVolumes(c *gc.C) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/openstack/cinder.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/openstack/cinder.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/openstack/cinder.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/openstack/cinder.go 2016-05-17 20:01:14.000000000 +0000 @@ -136,7 +136,7 @@ // "creating", in which case it will not have a size or status. Wait for // the volume to transition, so we can record its actual size. volumeId := cinderVolume.ID - cinderVolume, err = s.waitVolume(volumeId, func(v *cinder.Volume) (bool, error) { + cinderVolume, err = waitVolume(s.storageAdapter, volumeId, func(v *cinder.Volume) (bool, error) { return v.Status != "", nil }) if err != nil { @@ -151,19 +151,37 @@ // ListVolumes is specified on the storage.VolumeSource interface. func (s *cinderVolumeSource) ListVolumes() ([]string, error) { - cinderVolumes, err := s.storageAdapter.GetVolumesDetail() + volumes, err := listVolumes(s.storageAdapter, func(v *cinder.Volume) bool { + return v.Metadata[tags.JujuModel] == s.modelUUID + }) + if err != nil { + return nil, errors.Trace(err) + } + return volumeInfoToVolumeIds(volumes), nil +} + +func volumeInfoToVolumeIds(volumes []storage.VolumeInfo) []string { + volumeIds := make([]string, len(volumes)) + for i, volume := range volumes { + volumeIds[i] = volume.VolumeId + } + return volumeIds +} + +// listVolumes returns all of the volumes matching the given function. +func listVolumes(storageAdapter openstackStorage, match func(*cinder.Volume) bool) ([]storage.VolumeInfo, error) { + cinderVolumes, err := storageAdapter.GetVolumesDetail() if err != nil { return nil, err } - volumeIds := make([]string, 0, len(cinderVolumes)) + volumes := make([]storage.VolumeInfo, 0, len(cinderVolumes)) for _, volume := range cinderVolumes { - modelUUID, ok := volume.Metadata[tags.JujuModel] - if !ok || modelUUID != s.modelUUID { + if !match(&volume) { continue } - volumeIds = append(volumeIds, cinderToJujuVolumeInfo(&volume).VolumeId) + volumes = append(volumes, cinderToJujuVolumeInfo(&volume)) } - return volumeIds, nil + return volumes, nil } // DescribeVolumes implements storage.VolumeSource. @@ -193,26 +211,30 @@ // DestroyVolumes implements storage.VolumeSource. func (s *cinderVolumeSource) DestroyVolumes(volumeIds []string) ([]error, error) { + return destroyVolumes(s.storageAdapter, volumeIds), nil +} + +func destroyVolumes(storageAdapter openstackStorage, volumeIds []string) []error { var wg sync.WaitGroup wg.Add(len(volumeIds)) results := make([]error, len(volumeIds)) for i, volumeId := range volumeIds { go func(i int, volumeId string) { defer wg.Done() - results[i] = s.destroyVolume(volumeId) + results[i] = destroyVolume(storageAdapter, volumeId) }(i, volumeId) } wg.Wait() - return results, nil + return results } -func (s *cinderVolumeSource) destroyVolume(volumeId string) error { +func destroyVolume(storageAdapter openstackStorage, volumeId string) error { logger.Debugf("destroying volume %q", volumeId) // Volumes must not be in-use when destroying. A volume may // still be in-use when the instance it is attached to is // in the process of being terminated. var issuedDetach bool - volume, err := s.waitVolume(volumeId, func(v *cinder.Volume) (bool, error) { + volume, err := waitVolume(storageAdapter, volumeId, func(v *cinder.Volume) (bool, error) { switch v.Status { default: // Not ready for deletion; keep waiting. @@ -231,7 +253,7 @@ args[i].InstanceId = instance.Id(a.ServerId) } if len(args) > 0 { - results, err := s.DetachVolumes(args) + results, err := detachVolumes(storageAdapter, args) if err != nil { return false, errors.Trace(err) } @@ -252,7 +274,7 @@ // Already being deleted, nothing to do. return nil } - if err := s.storageAdapter.DeleteVolume(volumeId); err != nil { + if err := storageAdapter.DeleteVolume(volumeId); err != nil { return errors.Trace(err) } return nil @@ -286,7 +308,7 @@ novaAttachment := findAttachment(arg.VolumeId, existingAttachments) if novaAttachment == nil { // A volume must be "available" before it can be attached. - if _, err := s.waitVolume(arg.VolumeId, func(v *cinder.Volume) (bool, error) { + if _, err := waitVolume(s.storageAdapter, arg.VolumeId, func(v *cinder.Volume) (bool, error) { return v.Status == "available", nil }); err != nil { return nil, errors.Annotate(err, "waiting for volume to become available") @@ -309,12 +331,13 @@ }, nil } -func (s *cinderVolumeSource) waitVolume( +func waitVolume( + storageAdapter openstackStorage, volumeId string, pred func(*cinder.Volume) (bool, error), ) (*cinder.Volume, error) { for a := cinderAttempt.Start(); a.Next(); { - volume, err := s.storageAdapter.GetVolume(volumeId) + volume, err := storageAdapter.GetVolume(volumeId) if err != nil { return nil, errors.Annotate(err, "getting volume") } @@ -331,10 +354,14 @@ // DetachVolumes implements storage.VolumeSource. func (s *cinderVolumeSource) DetachVolumes(args []storage.VolumeAttachmentParams) ([]error, error) { + return detachVolumes(s.storageAdapter, args) +} + +func detachVolumes(storageAdapter openstackStorage, args []storage.VolumeAttachmentParams) ([]error, error) { results := make([]error, len(args)) for i, arg := range args { // Check to see if the volume is already detached. - attachments, err := s.storageAdapter.ListVolumeAttachments(string(arg.InstanceId)) + attachments, err := storageAdapter.ListVolumeAttachments(string(arg.InstanceId)) if err != nil { results[i] = errors.Annotate(err, "listing volume attachments") continue @@ -343,7 +370,7 @@ string(arg.InstanceId), arg.VolumeId, attachments, - s.storageAdapter, + storageAdapter, ); err != nil { results[i] = errors.Annotatef( err, "detaching volume %s from server %s", @@ -405,7 +432,7 @@ logger.Debugf(`endpoint "volumev2" not found for %q region, trying "volume"`, region) endpoint, ok = endpointMap["volume"] if !ok { - return nil, errors.Errorf(`endpoint "volume" not found for %q region`, region) + return nil, errors.NotFoundf(`endpoint "volume" in region %q`, region) } } return url.Parse(endpoint) @@ -425,6 +452,9 @@ endpointUrl, err := getVolumeEndpointURL(client, ecfg.region()) if err != nil { + if errors.IsNotFound(err) { + return nil, errors.NewNotSupported(err, "volumes not supported") + } return nil, errors.Annotate(err, "getting volume endpoint") } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/openstack/cinder_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/openstack/cinder_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/openstack/cinder_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/openstack/cinder_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -541,7 +541,8 @@ func (s *cinderVolumeSourceSuite) TestGetVolumeEndpointMissing(c *gc.C) { client := testEndpointResolver{} url, err := openstack.GetVolumeEndpointURL(client, "east") - c.Assert(err, gc.ErrorMatches, `endpoint "volume" not found for "east" region`) + c.Assert(err, gc.ErrorMatches, `endpoint "volume" in region "east" not found`) + c.Assert(err, jc.Satisfies, errors.IsNotFound) c.Assert(url, gc.IsNil) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/openstack/credentials_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/openstack/credentials_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/openstack/credentials_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/openstack/credentials_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -117,9 +117,11 @@ } home := utils.Home() dir := c.MkDir() - utils.SetHome(dir) + err := utils.SetHome(dir) + c.Assert(err, jc.ErrorIsNil) s.AddCleanup(func(*gc.C) { - utils.SetHome(home) + err := utils.SetHome(home) + c.Assert(err, jc.ErrorIsNil) }) content := ` @@ -130,7 +132,7 @@ OS_REGION_NAME=region `[1:] novarc := filepath.Join(dir, ".novarc") - err := ioutil.WriteFile(novarc, []byte(content), 0600) + err = ioutil.WriteFile(novarc, []byte(content), 0600) credentials, err := s.provider.DetectCredentials() c.Assert(err, jc.ErrorIsNil) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/openstack/export_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/openstack/export_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/openstack/export_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/openstack/export_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -107,6 +107,9 @@ "format": "products:1.0", "products": [ "com.ubuntu.cloud:server:16.04:s390x", + "com.ubuntu.cloud:server:16.04:amd64", + "com.ubuntu.cloud:server:16.04:arm64", + "com.ubuntu.cloud:server:16.04:ppc64el", "com.ubuntu.cloud:server:14.04:s390x", "com.ubuntu.cloud:server:14.04:amd64", "com.ubuntu.cloud:server:14.04:arm64", @@ -126,6 +129,81 @@ { "content_id": "com.ubuntu.cloud:released:openstack", "products": { + "com.ubuntu.cloud:server:16.04:amd64": { + "release": "trusty", + "version": "16.04", + "arch": "amd64", + "versions": { + "20121218": { + "items": { + "inst1": { + "root_store": "ebs", + "virt": "pv", + "region": "some-region", + "id": "1" + }, + "inst2": { + "root_store": "ebs", + "virt": "pv", + "region": "another-region", + "id": "2" + } + }, + "pubname": "ubuntu-trusty-16.04-amd64-server-20121218", + "label": "release" + }, + "20121111": { + "items": { + "inst3": { + "root_store": "ebs", + "virt": "pv", + "region": "some-region", + "id": "3" + } + }, + "pubname": "ubuntu-trusty-16.04-amd64-server-20121111", + "label": "release" + } + } + }, + "com.ubuntu.cloud:server:16.04:arm64": { + "release": "xenial", + "version": "16.04", + "arch": "arm64", + "versions": { + "20121111": { + "items": { + "inst1604arm64": { + "root_store": "ebs", + "virt": "pv", + "region": "some-region", + "id": "id-1604arm64" + } + }, + "pubname": "ubuntu-xenial-16.04-arm64-server-20121111", + "label": "release" + } + } + }, + "com.ubuntu.cloud:server:16.04:ppc64el": { + "release": "xenial", + "version": "16.04", + "arch": "ppc64el", + "versions": { + "20121111": { + "items": { + "inst1604ppc64el": { + "root_store": "ebs", + "virt": "pv", + "region": "some-region", + "id": "id-1604ppc64el" + } + }, + "pubname": "ubuntu-xenial-16.04-ppc64el-server-20121111", + "label": "release" + } + } + }, "com.ubuntu.cloud:server:14.04:amd64": { "release": "trusty", "version": "14.04", diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/openstack/firewaller.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/openstack/firewaller.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/openstack/firewaller.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/openstack/firewaller.go 2016-05-17 20:01:14.000000000 +0000 @@ -38,8 +38,11 @@ // Ports returns the port ranges opened for the whole environment. Ports() ([]network.PortRange, error) - // Implementations shoud delete all global security groups. - DeleteGlobalGroups() error + // Implementations are expected to delete all security groups for the + // environment. If the environment corresponds to a controller model, + // then the implementation should also delete security groups for the + // hosted models. + DeleteAllGroups() error // Implementations should return list of security groups, that belong to given instances. GetSecurityGroups(ids ...instance.Id) ([]string, error) @@ -224,20 +227,29 @@ return securityGroupNames, nil } -// DeleteGlobalGroups implements Firewaller interface. -func (c *defaultFirewaller) DeleteGlobalGroups() error { +// DeleteAllGroups implements Firewaller interface. +func (c *defaultFirewaller) DeleteAllGroups() error { novaClient := c.environ.nova() securityGroups, err := novaClient.ListSecurityGroups() if err != nil { return errors.Annotate(err, "cannot list security groups") } - re, err := regexp.Compile(fmt.Sprintf("^%s(-\\d+)?$", c.jujuGroupName())) + + var prefix string + if cfg := c.environ.Config(); cfg.UUID() == cfg.ControllerUUID() { + // Delete all security groups managed by the controller. + prefix = c.jujuControllerGroupPrefix() + } else { + // Delete all security groups for the model. + prefix = c.jujuModelGroupPrefix() + } + + re, err := regexp.Compile("^" + regexp.QuoteMeta(prefix)) if err != nil { return errors.Trace(err) } - globalGroupName := c.globalGroupName() for _, group := range securityGroups { - if re.MatchString(group.Name) || group.Name == globalGroupName { + if re.MatchString(group.Name) { deleteSecurityGroup(novaClient, group.Name, group.Id) } } @@ -421,6 +433,7 @@ network.SortPortRanges(portRanges) return portRanges, nil } + func (c *defaultFirewaller) globalGroupName() string { return fmt.Sprintf("%s-global", c.jujuGroupName()) } @@ -431,5 +444,14 @@ func (c *defaultFirewaller) jujuGroupName() string { cfg := c.environ.Config() - return fmt.Sprintf("juju-%v", cfg.UUID()) + return fmt.Sprintf("juju-%v-%v", cfg.ControllerUUID(), cfg.UUID()) +} + +func (c *defaultFirewaller) jujuModelGroupPrefix() string { + return c.jujuGroupName() +} + +func (c *defaultFirewaller) jujuControllerGroupPrefix() string { + cfg := c.environ.Config() + return fmt.Sprintf("juju-%v-", cfg.ControllerUUID()) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/openstack/local_test.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/openstack/local_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/openstack/local_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/openstack/local_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -19,6 +19,7 @@ jujuerrors "github.com/juju/errors" gitjujutesting "github.com/juju/testing" jc "github.com/juju/testing/checkers" + "github.com/juju/utils" "github.com/juju/utils/arch" "github.com/juju/utils/series" "github.com/juju/utils/ssh" @@ -518,6 +519,16 @@ } } +func assertInstanceIds(c *gc.C, env environs.Environ, expected ...instance.Id) { + insts, err := env.AllInstances() + c.Assert(err, jc.ErrorIsNil) + instIds := make([]instance.Id, len(insts)) + for i, inst := range insts { + instIds[i] = inst.Id() + } + c.Assert(instIds, jc.SameContents, expected) +} + func (s *localServerSuite) TestStopInstance(c *gc.C) { cfg, err := config.New(config.NoDefaults, s.TestConfig.Merge(coretesting.Attrs{ "firewall-mode": config.FwInstance})) @@ -529,12 +540,19 @@ // Openstack now has three security groups for the server, the default // group, one group for the entire environment, and another for the // new instance. - eUUID := env.Config().UUID() - assertSecurityGroups(c, env, []string{"default", fmt.Sprintf("juju-%v", eUUID), fmt.Sprintf("juju-%v-%v", eUUID, instanceName)}) + cUUID := env.Config().ControllerUUID() + modelUUID := env.Config().UUID() + allSecurityGroups := []string{ + "default", fmt.Sprintf("juju-%v-%v", cUUID, modelUUID), + fmt.Sprintf("juju-%v-%v-%v", cUUID, modelUUID, instanceName), + } + assertSecurityGroups(c, env, allSecurityGroups) err = env.StopInstances(inst.Id()) c.Assert(err, jc.ErrorIsNil) // The security group for this instance is now removed. - assertSecurityGroups(c, env, []string{"default", fmt.Sprintf("juju-%v", eUUID)}) + assertSecurityGroups(c, env, []string{ + "default", fmt.Sprintf("juju-%v-%v", cUUID, modelUUID), + }) } // Due to bug #1300755 it can happen that the security group intended for @@ -559,8 +577,12 @@ c.Assert(err, jc.ErrorIsNil) instanceName := "100" inst, _ := testing.AssertStartInstance(c, env, instanceName) - eUUID := env.Config().UUID() - allSecurityGroups := []string{"default", fmt.Sprintf("juju-%v", eUUID), fmt.Sprintf("juju-%v-%v", eUUID, instanceName)} + cUUID := env.Config().ControllerUUID() + modelUUID := env.Config().UUID() + allSecurityGroups := []string{ + "default", fmt.Sprintf("juju-%v-%v", cUUID, modelUUID), + fmt.Sprintf("juju-%v-%v-%v", cUUID, modelUUID, instanceName), + } assertSecurityGroups(c, env, allSecurityGroups) err = env.StopInstances(inst.Id()) c.Assert(err, jc.ErrorIsNil) @@ -575,8 +597,12 @@ c.Assert(err, jc.ErrorIsNil) instanceName := "100" testing.AssertStartInstance(c, env, instanceName) - eUUID := env.Config().UUID() - allSecurityGroups := []string{"default", fmt.Sprintf("juju-%v", eUUID), fmt.Sprintf("juju-%v-%v", eUUID, instanceName)} + cUUID := env.Config().ControllerUUID() + modelUUID := env.Config().UUID() + allSecurityGroups := []string{ + "default", fmt.Sprintf("juju-%v-%v", cUUID, modelUUID), + fmt.Sprintf("juju-%v-%v-%v", cUUID, modelUUID, instanceName), + } assertSecurityGroups(c, env, allSecurityGroups) err = env.Destroy() c.Check(err, jc.ErrorIsNil) @@ -591,14 +617,92 @@ c.Assert(err, jc.ErrorIsNil) instanceName := "100" testing.AssertStartInstance(c, env, instanceName) - eUUID := env.Config().UUID() - allSecurityGroups := []string{"default", fmt.Sprintf("juju-%v", eUUID), fmt.Sprintf("juju-%v-global", eUUID)} + cUUID := env.Config().ControllerUUID() + modelUUID := env.Config().UUID() + allSecurityGroups := []string{ + "default", fmt.Sprintf("juju-%v-%v", cUUID, modelUUID), + fmt.Sprintf("juju-%v-%v-global", cUUID, modelUUID), + } assertSecurityGroups(c, env, allSecurityGroups) err = env.Destroy() c.Check(err, jc.ErrorIsNil) assertSecurityGroups(c, env, []string{"default"}) } +func (s *localServerSuite) TestDestroyControllerModel(c *gc.C) { + cfg, err := config.New(config.NoDefaults, s.TestConfig.Merge(coretesting.Attrs{ + "uuid": utils.MustNewUUID().String(), + })) + c.Assert(err, jc.ErrorIsNil) + env, err := environs.New(cfg) + c.Assert(err, jc.ErrorIsNil) + controllerCfg, err := config.New(config.NoDefaults, s.TestConfig) + c.Assert(err, jc.ErrorIsNil) + controllerEnv, err := environs.New(controllerCfg) + c.Assert(err, jc.ErrorIsNil) + + controllerInstanceName := "100" + testing.AssertStartInstance(c, controllerEnv, controllerInstanceName) + hostedModelInstanceName := "200" + testing.AssertStartInstance(c, env, hostedModelInstanceName) + cUUID := env.Config().ControllerUUID() + modelUUID := env.Config().UUID() + allControllerSecurityGroups := []string{ + "default", fmt.Sprintf("juju-%v-%v", cUUID, cUUID), + fmt.Sprintf("juju-%v-%v-%v", cUUID, cUUID, controllerInstanceName), + } + allHostedModelSecurityGroups := []string{ + "default", fmt.Sprintf("juju-%v-%v", cUUID, modelUUID), + fmt.Sprintf("juju-%v-%v-%v", cUUID, modelUUID, hostedModelInstanceName), + } + assertSecurityGroups(c, controllerEnv, append( + allControllerSecurityGroups, allHostedModelSecurityGroups..., + )) + + err = controllerEnv.Destroy() + c.Check(err, jc.ErrorIsNil) + assertSecurityGroups(c, controllerEnv, []string{"default"}) + assertInstanceIds(c, env) + assertInstanceIds(c, controllerEnv) +} + +func (s *localServerSuite) TestDestroyHostedModel(c *gc.C) { + cfg, err := config.New(config.NoDefaults, s.TestConfig.Merge(coretesting.Attrs{ + "uuid": utils.MustNewUUID().String(), + })) + c.Assert(err, jc.ErrorIsNil) + env, err := environs.New(cfg) + c.Assert(err, jc.ErrorIsNil) + controllerCfg, err := config.New(config.NoDefaults, s.TestConfig) + c.Assert(err, jc.ErrorIsNil) + controllerEnv, err := environs.New(controllerCfg) + c.Assert(err, jc.ErrorIsNil) + + controllerInstanceName := "100" + controllerInstance, _ := testing.AssertStartInstance(c, controllerEnv, controllerInstanceName) + hostedModelInstanceName := "200" + testing.AssertStartInstance(c, env, hostedModelInstanceName) + cUUID := env.Config().ControllerUUID() + modelUUID := env.Config().UUID() + allControllerSecurityGroups := []string{ + "default", fmt.Sprintf("juju-%v-%v", cUUID, cUUID), + fmt.Sprintf("juju-%v-%v-%v", cUUID, cUUID, controllerInstanceName), + } + allHostedModelSecurityGroups := []string{ + "default", fmt.Sprintf("juju-%v-%v", cUUID, modelUUID), + fmt.Sprintf("juju-%v-%v-%v", cUUID, modelUUID, hostedModelInstanceName), + } + assertSecurityGroups(c, controllerEnv, append( + allControllerSecurityGroups, allHostedModelSecurityGroups..., + )) + + err = env.Destroy() + c.Check(err, jc.ErrorIsNil) + assertSecurityGroups(c, controllerEnv, allControllerSecurityGroups) + assertInstanceIds(c, env) + assertInstanceIds(c, controllerEnv, controllerInstance.Id()) +} + var instanceGathering = []struct { ids []instance.Id err error @@ -993,7 +1097,7 @@ }} spec, err := openstack.FindInstanceSpec( - env, coretesting.FakeDefaultSeries, "amd64", "instance-type=m1.tiny", + env, series.LatestLts(), "amd64", "instance-type=m1.tiny", imageMetadata, ) c.Assert(err, jc.ErrorIsNil) @@ -1010,7 +1114,7 @@ }} spec, err := openstack.FindInstanceSpec( - env, coretesting.FakeDefaultSeries, "amd64", "virt-type="+testVirtType, + env, series.LatestLts(), "amd64", "virt-type="+testVirtType, imageMetadata, ) c.Assert(err, jc.ErrorIsNil) @@ -1029,7 +1133,7 @@ }} spec, err := openstack.FindInstanceSpec( - env, coretesting.FakeDefaultSeries, "amd64", "", + env, series.LatestLts(), "amd64", "", imageMetadata, ) c.Assert(err, jc.ErrorIsNil) @@ -1046,7 +1150,7 @@ }} spec, err := openstack.FindInstanceSpec( - env, coretesting.FakeDefaultSeries, "amd64", "", + env, series.LatestLts(), "amd64", "", imageMetadata, ) c.Assert(err, jc.ErrorIsNil) @@ -1061,7 +1165,7 @@ Arch: "amd64", }} _, err := openstack.FindInstanceSpec( - env, coretesting.FakeDefaultSeries, "amd64", "instance-type=m1.large", + env, series.LatestLts(), "amd64", "instance-type=m1.large", imageMetadata, ) c.Assert(err, gc.ErrorMatches, `no instance types in some-region matching constraints "instance-type=m1.large"`) @@ -1071,7 +1175,7 @@ env := s.Open(c, s.env.Config()) cons := constraints.MustParse("instance-type=m1.small") placement := "" - err := env.PrecheckInstance(coretesting.FakeDefaultSeries, cons, placement) + err := env.PrecheckInstance(series.LatestLts(), cons, placement) c.Assert(err, jc.ErrorIsNil) } @@ -1079,32 +1183,32 @@ env := s.Open(c, s.env.Config()) cons := constraints.MustParse("instance-type=m1.large") placement := "" - err := env.PrecheckInstance(coretesting.FakeDefaultSeries, cons, placement) + err := env.PrecheckInstance(series.LatestLts(), cons, placement) c.Assert(err, gc.ErrorMatches, `invalid Openstack flavour "m1.large" specified`) } func (t *localServerSuite) TestPrecheckInstanceAvailZone(c *gc.C) { placement := "zone=test-available" - err := t.env.PrecheckInstance(coretesting.FakeDefaultSeries, constraints.Value{}, placement) + err := t.env.PrecheckInstance(series.LatestLts(), constraints.Value{}, placement) c.Assert(err, jc.ErrorIsNil) } func (t *localServerSuite) TestPrecheckInstanceAvailZoneUnavailable(c *gc.C) { placement := "zone=test-unavailable" - err := t.env.PrecheckInstance(coretesting.FakeDefaultSeries, constraints.Value{}, placement) + err := t.env.PrecheckInstance(series.LatestLts(), constraints.Value{}, placement) c.Assert(err, jc.ErrorIsNil) } func (t *localServerSuite) TestPrecheckInstanceAvailZoneUnknown(c *gc.C) { placement := "zone=test-unknown" - err := t.env.PrecheckInstance(coretesting.FakeDefaultSeries, constraints.Value{}, placement) + err := t.env.PrecheckInstance(series.LatestLts(), constraints.Value{}, placement) c.Assert(err, gc.ErrorMatches, `invalid availability zone "test-unknown"`) } func (t *localServerSuite) TestPrecheckInstanceAvailZonesUnsupported(c *gc.C) { t.srv.Nova.SetAvailabilityZones() // no availability zone support placement := "zone=test-unknown" - err := t.env.PrecheckInstance(coretesting.FakeDefaultSeries, constraints.Value{}, placement) + err := t.env.PrecheckInstance(series.LatestLts(), constraints.Value{}, placement) c.Assert(err, jc.Satisfies, jujuerrors.IsNotImplemented) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/openstack/provider.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/openstack/provider.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/openstack/provider.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/openstack/provider.go 2016-05-17 20:01:14.000000000 +0000 @@ -19,6 +19,7 @@ "github.com/juju/utils" "github.com/juju/utils/arch" "github.com/juju/version" + "gopkg.in/goose.v1/cinder" "gopkg.in/goose.v1/client" gooseerrors "gopkg.in/goose.v1/errors" "gopkg.in/goose.v1/identity" @@ -1204,17 +1205,35 @@ return insts, err } -func (e *Environ) AllInstances() (insts []instance.Instance, err error) { - servers, err := e.nova().ListServersDetail(e.machinesFilter()) +// AllInstances returns all instances in this environment. +func (e *Environ) AllInstances() ([]instance.Instance, error) { + filter := e.machinesFilter() + allInstances, err := e.allControllerManagedInstances(filter, e.ecfg().useFloatingIP()) + if err != nil { + return nil, errors.Trace(err) + } + modelUUID := e.Config().UUID() + matching := make([]instance.Instance, 0, len(allInstances)) + for _, inst := range allInstances { + if inst.(*openstackInstance).serverDetail.Metadata[tags.JujuModel] != modelUUID { + continue + } + matching = append(matching, inst) + } + return matching, nil +} + +// allControllerManagedInstances returns all instances managed by this +// environment's controller, matching the optionally specified filter. +func (e *Environ) allControllerManagedInstances(filter *nova.Filter, updateFloatingIPAddresses bool) ([]instance.Instance, error) { + servers, err := e.nova().ListServersDetail(filter) if err != nil { return nil, err } instsById := make(map[string]instance.Instance) - cfg := e.Config() - eUUID := cfg.UUID() + controllerUUID := e.Config().ControllerUUID() for _, server := range servers { - modelUUID, ok := server.Metadata[tags.JujuModel] - if !ok || modelUUID != eUUID { + if server.Metadata[tags.JujuController] != controllerUUID { continue } if e.isAliveServer(server) { @@ -1223,17 +1242,16 @@ instsById[s.Id] = &openstackInstance{e: e, serverDetail: &s} } } - - if e.ecfg().useFloatingIP() { + if updateFloatingIPAddresses { if err := e.updateFloatingIPAddresses(instsById); err != nil { return nil, err } } - + insts := make([]instance.Instance, 0, len(instsById)) for _, inst := range instsById { insts = append(insts, inst) } - return insts, err + return insts, nil } func (e *Environ) Destroy() error { @@ -1241,7 +1259,71 @@ if err != nil { return errors.Trace(err) } - return e.firewaller.DeleteGlobalGroups() + cfg := e.Config() + if cfg.UUID() == cfg.ControllerUUID() { + // In case any hosted environment hasn't been cleaned up yet, + // we also attempt to delete their resources when the controller + // environment is destroyed. + if err := e.destroyControllerManagedEnvirons(); err != nil { + return errors.Annotate(err, "destroying managed environs") + } + } + // Delete all security groups remaining in the model. + return e.firewaller.DeleteAllGroups() +} + +// destroyControllerManagedEnvirons destroys all environments managed by this +// environment's controller. +func (e *Environ) destroyControllerManagedEnvirons() error { + // Terminate all instances managed by the controller. + insts, err := e.allControllerManagedInstances(nil, false) + if err != nil { + return errors.Annotate(err, "listing instances") + } + instIds := make([]instance.Id, len(insts)) + for i, inst := range insts { + instIds[i] = inst.Id() + } + if err := e.terminateInstances(instIds); err != nil { + return errors.Annotate(err, "terminating instances") + } + + // Delete all volumes managed by the controller. + cfg := e.Config() + storageAdapter, err := newOpenstackStorageAdapter(cfg) + if err == nil { + volIds, err := allControllerManagedVolumes(storageAdapter, cfg.ControllerUUID()) + if err != nil { + return errors.Annotate(err, "listing volumes") + } + errs := destroyVolumes(storageAdapter, volIds) + for i, err := range errs { + if err == nil { + continue + } + return errors.Annotatef(err, "destroying volume %q", volIds[i], err) + } + } else if !errors.IsNotSupported(err) { + return errors.Trace(err) + } + + // Security groups for hosted models are destroyed by the + // DeleteAllGroups method call from Destroy(). + return nil +} + +func allControllerManagedVolumes(storageAdapter openstackStorage, controllerUUID string) ([]string, error) { + volumes, err := listVolumes(storageAdapter, func(v *cinder.Volume) bool { + return v.Metadata[tags.JujuController] == controllerUUID + }) + if err != nil { + return nil, errors.Trace(err) + } + volIds := make([]string, len(volumes)) + for i, v := range volumes { + volIds[i] = v.VolumeId + } + return volIds, nil } func resourceName(tag names.Tag, envName string) string { @@ -1251,8 +1333,8 @@ // machinesFilter returns a nova.Filter matching all machines in the environment. func (e *Environ) machinesFilter() *nova.Filter { filter := nova.NewFilter() - eUUID := e.Config().UUID() - filter.Set(nova.FilterServer, fmt.Sprintf("juju-%s-machine-\\d*", eUUID)) + modelUUID := e.Config().UUID() + filter.Set(nova.FilterServer, fmt.Sprintf("juju-%s-machine-\\d*", modelUUID)) return filter } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/provider/rackspace/firewaller.go juju-core-2.0~beta7/src/github.com/juju/juju/provider/rackspace/firewaller.go --- juju-core-2.0~beta6/src/github.com/juju/juju/provider/rackspace/firewaller.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/provider/rackspace/firewaller.go 2016-05-17 20:01:14.000000000 +0000 @@ -55,8 +55,8 @@ return nil, errors.NotSupportedf("Ports") } -// DeleteGlobalGroups implements OpenstackFirewaller interface. -func (c *rackspaceFirewaller) DeleteGlobalGroups() error { +// DeleteAllGroups implements OpenstackFirewaller interface. +func (c *rackspaceFirewaller) DeleteAllGroups() error { return nil } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/scripts/setup-lxd.sh juju-core-2.0~beta7/src/github.com/juju/juju/scripts/setup-lxd.sh --- juju-core-2.0~beta6/src/github.com/juju/juju/scripts/setup-lxd.sh 1970-01-01 00:00:00.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/scripts/setup-lxd.sh 2016-05-17 20:01:14.000000000 +0000 @@ -0,0 +1,27 @@ +#!/bin/sh +set -ex + +# Do the manual steps a user has to run on a fresh system to get an lxd +# bridge so the juju lxd provider can function. Taken from changes made +# to cloud-init to do approximately this. + +debconf-communicate << EOF +set lxd/setup-bridge true +set lxd/bridge-domain lxd +set lxd/bridge-name lxdbr0 +set lxd/bridge-ipv4 true +set lxd/bridge-ipv4-address 10.0.8.1 +set lxd/bridge-ipv4-dhcp-first 10.0.8.2 +set lxd/bridge-ipv4-dhcp-last 10.0.8.254 +set lxd/bridge-ipv4-dhcp-leases 252 +set lxd/bridge-ipv4-netmask 24 +set lxd/bridge-ipv4-nat true +set lxd/bridge-ipv6 false +EOF + +rm -rf /etc/default/lxd-bridge + +dpkg-reconfigure lxd --frontend=noninteractive + +# Must run a command for systemd socket activation to start the service +lxc finger \ No newline at end of file diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/scripts/win-installer/setup.iss juju-core-2.0~beta7/src/github.com/juju/juju/scripts/win-installer/setup.iss --- juju-core-2.0~beta6/src/github.com/juju/juju/scripts/win-installer/setup.iss 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/scripts/win-installer/setup.iss 2016-05-17 20:01:14.000000000 +0000 @@ -2,7 +2,7 @@ ; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! #define MyAppName "Juju" -#define MyAppVersion "2.0-beta6" +#define MyAppVersion "2.0-beta7" #define MyAppPublisher "Canonical, Ltd" #define MyAppURL "http://juju.ubuntu.com/" #define MyAppExeName "juju.exe" diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/address.go juju-core-2.0~beta7/src/github.com/juju/juju/state/address.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/address.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/address.go 2016-05-17 20:01:14.000000000 +0000 @@ -150,28 +150,6 @@ return networkHostsPorts(doc.APIHostPorts), nil } -type DeployerConnectionValues struct { - StateAddresses []string - APIAddresses []string -} - -// DeployerConnectionInfo returns the address information necessary for the deployer. -// The function does the expensive operations (getting stuff from mongo) just once. -func (st *State) DeployerConnectionInfo() (*DeployerConnectionValues, error) { - addrs, err := st.controllerAddresses() - if err != nil { - return nil, errors.Trace(err) - } - config, err := st.ModelConfig() - if err != nil { - return nil, errors.Trace(err) - } - return &DeployerConnectionValues{ - StateAddresses: appendPort(addrs, config.StatePort()), - APIAddresses: appendPort(addrs, config.APIPort()), - }, nil -} - // address represents the location of a machine, including metadata // about what kind of location the address describes. // diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/backups/backups_linux.go juju-core-2.0~beta7/src/github.com/juju/juju/state/backups/backups_linux.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/backups/backups_linux.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/backups/backups_linux.go 2016-05-17 20:01:14.000000000 +0000 @@ -197,18 +197,17 @@ if err != nil { return nil, errors.Trace(err) } - if err = updateAllMachines(args.PrivateAddress, machines); err != nil { + if err := updateAllMachines(args.PrivateAddress, machines); err != nil { return nil, errors.Annotate(err, "cannot update agents") } - info, err := st.RestoreInfoSetter() - if err != nil { - return nil, errors.Trace(err) - } - // Mark restoreInfo as Finished so upon restart of the apiserver // the client can reconnect and determine if we where succesful. + info := st.RestoreInfo() err = info.SetStatus(state.RestoreFinished) + if err != nil { + return nil, errors.Trace(err) + } return backupMachine, errors.Annotate(err, "failed to set status to finished") } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/backups/restore_test.go juju-core-2.0~beta7/src/github.com/juju/juju/state/backups/restore_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/backups/restore_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/backups/restore_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -24,6 +24,7 @@ "github.com/juju/juju/agent" "github.com/juju/juju/apiserver/params" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/state" statetesting "github.com/juju/juju/state/testing" coretesting "github.com/juju/juju/testing" @@ -263,7 +264,7 @@ st := statetesting.Initialize(c, names.NewLocalUserTag("test-admin"), nil, nil) c.Assert(st.Close(), jc.ErrorIsNil) - r.PatchValue(&mongoDefaultDialOpts, statetesting.NewDialOpts) + r.PatchValue(&mongoDefaultDialOpts, mongotest.DialOpts) r.PatchValue(&environsNewStatePolicy, func() state.Policy { return nil }) st, err = newStateConnection(st.ModelTag(), statetesting.NewMongoInfo()) c.Assert(err, jc.ErrorIsNil) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/cloudimagemetadata/image_test.go juju-core-2.0~beta7/src/github.com/juju/juju/state/cloudimagemetadata/image_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/cloudimagemetadata/image_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/cloudimagemetadata/image_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -286,15 +286,25 @@ c.Assert(err, jc.ErrorIsNil) } -func (s *cloudImageMetadataSuite) assertMetadataRecorded(c *gc.C, criteria cloudimagemetadata.MetadataAttributes, expected ...cloudimagemetadata.Metadata) { +func (s *cloudImageMetadataSuite) assertMetadataRecorded( + c *gc.C, + criteria cloudimagemetadata.MetadataAttributes, + expected ...cloudimagemetadata.Metadata, +) { metadata, err := s.storage.FindMetadata(buildAttributesFilter(criteria)) c.Assert(err, jc.ErrorIsNil) + // Collate expected into a map groups := make(map[string][]cloudimagemetadata.Metadata) - for _, one := range expected { - groups[one.Source] = append(groups[one.Source], one) + for _, expectedMetadata := range expected { + groups[expectedMetadata.Source] = append(groups[expectedMetadata.Source], expectedMetadata) + } + + // Compare maps by key; order of slices does not matter + c.Assert(groups, gc.HasLen, len(metadata)) + for source, expectedMetadata := range groups { + c.Assert(metadata[source], jc.SameContents, expectedMetadata) } - c.Assert(metadata, jc.DeepEquals, groups) } func (s *cloudImageMetadataSuite) TestSupportedArchitectures(c *gc.C) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/initialize_test.go juju-core-2.0~beta7/src/github.com/juju/juju/state/initialize_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/initialize_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/initialize_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -11,6 +11,7 @@ "github.com/juju/juju/constraints" "github.com/juju/juju/environs/config" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/state" statetesting "github.com/juju/juju/state/testing" "github.com/juju/juju/testing" @@ -43,7 +44,7 @@ st, err := state.Open( modelTag, statetesting.NewMongoInfo(), - statetesting.NewDialOpts(), + mongotest.DialOpts(), state.Policy(nil), ) c.Assert(err, jc.ErrorIsNil) @@ -64,7 +65,7 @@ uuid := cfg.UUID() initial := cfg.AllAttrs() owner := names.NewLocalUserTag("initialize-admin") - st, err := state.Initialize(owner, statetesting.NewMongoInfo(), cfg, statetesting.NewDialOpts(), nil) + st, err := state.Initialize(owner, statetesting.NewMongoInfo(), cfg, mongotest.DialOpts(), nil) c.Assert(err, jc.ErrorIsNil) c.Assert(st, gc.NotNil) modelTag := st.ModelTag() @@ -114,7 +115,7 @@ owner := names.NewLocalUserTag("initialize-admin") mgoInfo := statetesting.NewMongoInfo() - dialOpts := statetesting.NewDialOpts() + dialOpts := mongotest.DialOpts() st, err := state.Initialize(owner, mgoInfo, cfg, dialOpts, state.Policy(nil)) c.Assert(err, jc.ErrorIsNil) err = st.Close() @@ -135,7 +136,7 @@ bad, err := good.Apply(badUpdateAttrs) owner := names.NewLocalUserTag("initialize-admin") - _, err = state.Initialize(owner, statetesting.NewMongoInfo(), bad, statetesting.NewDialOpts(), state.Policy(nil)) + _, err = state.Initialize(owner, statetesting.NewMongoInfo(), bad, mongotest.DialOpts(), state.Policy(nil)) c.Assert(err, gc.ErrorMatches, "admin-secret should never be written to the state") // admin-secret blocks UpdateModelConfig. @@ -161,7 +162,7 @@ c.Assert(err, jc.ErrorIsNil) owner := names.NewLocalUserTag("initialize-admin") - _, err = state.Initialize(owner, statetesting.NewMongoInfo(), bad, statetesting.NewDialOpts(), state.Policy(nil)) + _, err = state.Initialize(owner, statetesting.NewMongoInfo(), bad, mongotest.DialOpts(), state.Policy(nil)) c.Assert(err, gc.ErrorMatches, "agent-version must always be set in state") st := statetesting.Initialize(c, owner, good, nil) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/internal_test.go juju-core-2.0~beta7/src/github.com/juju/juju/state/internal_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/internal_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/internal_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -10,6 +10,7 @@ gc "gopkg.in/check.v1" "github.com/juju/juju/mongo" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/testing" ) @@ -47,10 +48,7 @@ CACert: testing.CACert, }, } - // Copied from NewDialOpts (due to import loops). - dialopts := mongo.DialOpts{ - Timeout: testing.LongWait, - } + dialopts := mongotest.DialOpts() st, err := Initialize(s.owner, info, testing.ModelConfig(c), dialopts, nil) c.Assert(err, jc.ErrorIsNil) s.state = st diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/machine_test.go juju-core-2.0~beta7/src/github.com/juju/juju/state/machine_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/machine_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/machine_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -19,6 +19,7 @@ "github.com/juju/juju/constraints" "github.com/juju/juju/environs/config" "github.com/juju/juju/instance" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/network" "github.com/juju/juju/state" "github.com/juju/juju/state/testing" @@ -645,7 +646,7 @@ func (s *MachineSuite) TestSetMongoPassword(c *gc.C) { info := testing.NewMongoInfo() - st, err := state.Open(s.modelTag, info, testing.NewDialOpts(), state.Policy(nil)) + st, err := state.Open(s.modelTag, info, mongotest.DialOpts(), state.Policy(nil)) c.Assert(err, jc.ErrorIsNil) defer func() { // Remove the admin password so that the test harness can reset the state. @@ -676,7 +677,7 @@ // Check that we can log in with the correct password. info.Password = "foo" - st1, err := state.Open(s.modelTag, info, testing.NewDialOpts(), state.Policy(nil)) + st1, err := state.Open(s.modelTag, info, mongotest.DialOpts(), state.Policy(nil)) c.Assert(err, jc.ErrorIsNil) defer st1.Close() diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/migration_export_test.go juju-core-2.0~beta7/src/github.com/juju/juju/state/migration_export_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/migration_export_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/migration_export_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -37,10 +37,6 @@ ConnSuite } -type statusSetter interface { - SetStatus(status.Status, string, map[string]interface{}) error -} - func (s *MigrationSuite) setLatestTools(c *gc.C, latestTools version.Number) { dbModel, err := s.State.Model() c.Assert(err, jc.ErrorIsNil) @@ -61,11 +57,9 @@ } func (s *MigrationSuite) primeStatusHistory(c *gc.C, entity statusSetter, statusVal status.Status, count int) { - for i := 0; i < count; i++ { - c.Logf("setting status for %v", entity) - err := entity.SetStatus(statusVal, "", map[string]interface{}{"index": count - i}) - c.Assert(err, jc.ErrorIsNil) - } + primeStatusHistory(c, entity, statusVal, count, func(i int) map[string]interface{} { + return map[string]interface{}{"index": count - i} + }) } func (s *MigrationSuite) makeServiceWithLeader(c *gc.C, serviceName string, count int, leader int) { @@ -97,6 +91,7 @@ func (s *MigrationExportSuite) checkStatusHistory(c *gc.C, history []description.Status, statusVal status.Status) { for i, st := range history { + c.Logf("status history #%d: %s", i, st.Updated()) c.Check(st.Value(), gc.Equals, string(statusVal)) c.Check(st.Message(), gc.Equals, "") c.Check(st.Data(), jc.DeepEquals, map[string]interface{}{"index": i + 1}) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/open.go juju-core-2.0~beta7/src/github.com/juju/juju/state/open.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/open.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/open.go 2016-05-17 20:01:14.000000000 +0000 @@ -80,7 +80,7 @@ tag = ssInfo.ModelTag } - st, err := newState(tag, session, info, policy) + st, err := newState(tag, session, info, opts, policy) if err != nil { session.Close() return nil, errors.Trace(err) @@ -236,7 +236,7 @@ // Some unauthorized access errors have no error code, // just a simple error string; and some do have error codes // but are not of consistent types (LastError/QueryError). - for _, prefix := range []string{"auth fail", "not authorized"} { + for _, prefix := range []string{"auth fail", "not authorized", "server returned error on SASL authentication step: Authentication failed."} { if strings.HasPrefix(err.Error(), prefix) { return true } @@ -252,7 +252,7 @@ // newState creates an incomplete *State, with a configured watcher but no // pwatcher, leadershipManager, or controllerTag. You must start() the returned // *State before it will function correctly. -func newState(modelTag names.ModelTag, session *mgo.Session, mongoInfo *mongo.MongoInfo, policy Policy) (_ *State, resultErr error) { +func newState(modelTag names.ModelTag, session *mgo.Session, mongoInfo *mongo.MongoInfo, dialOpts mongo.DialOpts, policy Policy) (_ *State, resultErr error) { // Set up database. rawDB := session.DB(jujuDB) database, err := allCollections().Load(rawDB, modelTag.Id()) @@ -265,12 +265,13 @@ // Create State. return &State{ - modelTag: modelTag, - mongoInfo: mongoInfo, - session: session, - database: database, - policy: policy, - watcher: watcher.New(rawDB.C(txnLogC)), + modelTag: modelTag, + mongoInfo: mongoInfo, + mongoDialOpts: dialOpts, + session: session, + database: database, + policy: policy, + watcher: watcher.New(rawDB.C(txnLogC)), }, nil } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/restore.go juju-core-2.0~beta7/src/github.com/juju/juju/state/restore.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/restore.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/restore.go 2016-05-17 20:01:14.000000000 +0000 @@ -5,6 +5,7 @@ import ( "github.com/juju/errors" + jujutxn "github.com/juju/txn" "gopkg.in/mgo.v2" "gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/txn" @@ -13,82 +14,158 @@ // RestoreStatus is the type of the statuses type RestoreStatus string +// Validate returns an errors if status' value is not known. +func (status RestoreStatus) Validate() error { + switch status { + case RestorePending, RestoreInProgress, RestoreFinished: + case RestoreChecked, RestoreFailed, RestoreNotActive: + default: + return errors.Errorf("unknown restore status: %v", status) + } + return nil +} + const ( currentRestoreId = "current" - // UnknownRestoreStatus is the initial status for restoreInfoDoc. - UnknownRestoreStatus RestoreStatus = "UNKNOWN" - // RestorePending is a status to signal that a restore is about to start - // any change done in this status will be lost. + // RestoreNotActive is not persisted in the database, and is + // used to indicate the absence of a current restore doc. + RestoreNotActive RestoreStatus = "NOT-RESTORING" + + // RestorePending is a status to signal that a restore is about + // to start any change done in this status will be lost. RestorePending RestoreStatus = "PENDING" + // RestoreInProgress indicates that a Restore is in progress. RestoreInProgress RestoreStatus = "RESTORING" + // RestoreFinished it is set by restore upon a succesful run. RestoreFinished RestoreStatus = "RESTORED" - // RestoreChecked is set when the server comes up after a succesful restore. + + // RestoreChecked is set when the server comes up after a + // succesful restore. RestoreChecked RestoreStatus = "CHECKED" - // RestoreFailed indicates that the process failed in a recoverable step. + + // RestoreFailed indicates that the process failed in a + // recoverable step. RestoreFailed RestoreStatus = "FAILED" ) -type restoreInfoDoc struct { - Id string `bson:"_id"` - Status RestoreStatus `bson:"status"` +// RestoreInfo exposes restore status. +func (st *State) RestoreInfo() *RestoreInfo { + return &RestoreInfo{st: st} } -// RestoreInfo its used to syncronize Restore and machine agent +// RestoreInfo exposes restore status. type RestoreInfo struct { - st *State - doc restoreInfoDoc + st *State } // Status returns the current Restore doc status -func (info *RestoreInfo) Status() RestoreStatus { - return info.doc.Status +func (info *RestoreInfo) Status() (RestoreStatus, error) { + restoreInfo, closer := info.st.getCollection(restoreInfoC) + defer closer() + + var doc struct { + Status RestoreStatus `bson:"status"` + } + err := restoreInfo.FindId(currentRestoreId).One(&doc) + switch errors.Cause(err) { + case nil: + case mgo.ErrNotFound: + return RestoreNotActive, nil + default: + return "", errors.Annotate(err, "cannot read restore info") + } + + if err := doc.Status.Validate(); err != nil { + return "", errors.Trace(err) + } + return doc.Status, nil } // SetStatus sets the status of the current restore. Checks are made // to ensure that status changes are performed in the correct order. func (info *RestoreInfo) SetStatus(status RestoreStatus) error { - var assertSane bson.D + if err := status.Validate(); err != nil { + return errors.Trace(err) + } + buildTxn := func(_ int) ([]txn.Op, error) { + current, err := info.Status() + if err != nil { + return nil, errors.Annotate(err, "cannot read current status") + } + if current == status { + return nil, jujutxn.ErrNoOperations + } - if status == RestoreInProgress { - assertSane = bson.D{{"status", RestorePending}} + ops, err := setRestoreStatusOps(current, status) + if err != nil { + return nil, errors.Trace(err) + } + return ops, nil } - if status == RestoreChecked { - assertSane = bson.D{{"status", RestoreFinished}} + if err := info.st.run(buildTxn); err != nil { + return errors.Trace(err) } + return nil +} + +// setRestoreStatusOps checks the validity of the supplied transition, +// and returns either an error or a list of transaction operations that +// will apply the transition. +func setRestoreStatusOps(before, after RestoreStatus) ([]txn.Op, error) { + errInvalid := errors.Errorf("invalid restore transition: %s => %s", before, after) + switch after { + case RestorePending: + switch before { + case RestoreNotActive: + return createRestoreStatusPendingOps(), nil + case RestoreFailed, RestoreChecked: + default: + return nil, errInvalid + } + case RestoreFailed: + switch before { + case RestoreNotActive, RestoreChecked: + return nil, errInvalid + } + case RestoreInProgress: + if before != RestorePending { + return nil, errInvalid + } + case RestoreFinished: + if before != RestoreInProgress { + return nil, errInvalid + } + case RestoreChecked: + if before != RestoreFinished { + return nil, errInvalid + } + default: + return nil, errInvalid + } + return updateRestoreStatusChangeOps(before, after), nil +} - ops := []txn.Op{{ +// createRestoreStatusPendingOps is the only valid way to create a +// restore document. +func createRestoreStatusPendingOps() []txn.Op { + return []txn.Op{{ C: restoreInfoC, Id: currentRestoreId, - Assert: assertSane, - Update: bson.D{{"$set", bson.D{{"status", status}}}}, + Assert: txn.DocMissing, + Insert: bson.D{{"status", RestorePending}}, }} - err := info.st.runTransaction(ops) - if err == txn.ErrAborted { - return errors.Errorf("cannot set restore status to %q: Another "+ - "status change occurred concurrently", status) - } - return errors.Annotatef(err, "cannot set restore status to %q", status) } -// RestoreInfoSetter returns the current info doc, if it does not exists -// it creates it with UnknownRestoreStatus status -func (st *State) RestoreInfoSetter() (*RestoreInfo, error) { - doc := restoreInfoDoc{} - restoreInfo, closer := st.getCollection(restoreInfoC) - defer closer() - err := restoreInfo.Find(bson.M{"_id": currentRestoreId}).One(&doc) - switch errors.Cause(err) { - case nil: - case mgo.ErrNotFound: - doc = restoreInfoDoc{ - Id: currentRestoreId, - Status: UnknownRestoreStatus, - } - default: - return nil, errors.Annotate(err, "cannot read restore info") - } - return &RestoreInfo{st: st, doc: doc}, nil +// updateRestoreStatusChangeOps will set the restore doc status to +// after, so long as the doc's status is before. +func updateRestoreStatusChangeOps(before, after RestoreStatus) []txn.Op { + return []txn.Op{{ + C: restoreInfoC, + Id: currentRestoreId, + Assert: bson.D{{"status", before}}, + Update: bson.D{{"$set", bson.D{{"status", after}}}}, + }} } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/restore_test.go juju-core-2.0~beta7/src/github.com/juju/juju/state/restore_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/restore_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/restore_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,15 +4,14 @@ package state_test import ( - "sync" - "time" + "fmt" jc "github.com/juju/testing/checkers" + jujutxn "github.com/juju/txn" gc "gopkg.in/check.v1" "github.com/juju/juju/state" statetesting "github.com/juju/juju/state/testing" - coretesting "github.com/juju/juju/testing" ) // RestoreInfoSuite is *tremendously* incomplete: this test exists purely to @@ -25,45 +24,320 @@ // consistent with the other state code, but that's not for today. type RestoreInfoSuite struct { statetesting.StateSuite + info *state.RestoreInfo } var _ = gc.Suite(&RestoreInfoSuite{}) -func (s *RestoreInfoSuite) TestGetSetter(c *gc.C) { - setter, err := s.State.RestoreInfoSetter() - c.Assert(err, jc.ErrorIsNil) - checkStatus(c, setter, state.UnknownRestoreStatus) -} - -func (s *RestoreInfoSuite) TestGetSetterRace(c *gc.C) { - trigger := make(chan struct{}) - test := func() { - select { - case <-trigger: - setter, err := s.State.RestoreInfoSetter() - if c.Check(err, jc.ErrorIsNil) { - checkStatus(c, setter, state.UnknownRestoreStatus) - } - case <-time.After(coretesting.LongWait): - c.Errorf("test invoked but not triggered") - } - } +func (s *RestoreInfoSuite) SetUpTest(c *gc.C) { + s.StateSuite.SetUpTest(c) + s.info = s.State.RestoreInfo() +} - const count = 100 - wg := sync.WaitGroup{} - wg.Add(count) - for i := 0; i < count; i++ { - go func() { - defer wg.Done() - test() - }() - } - close(trigger) - wg.Wait() +func (s *RestoreInfoSuite) TestStartsNotActive(c *gc.C) { + s.checkStatus(c, state.RestoreNotActive) +} + +func (s *RestoreInfoSuite) TestSetBadStatus(c *gc.C) { + err := s.info.SetStatus(state.RestoreStatus("LOLLYGAGGING")) + c.Check(err, gc.ErrorMatches, "unknown restore status: LOLLYGAGGING") + s.checkStatus(c, state.RestoreNotActive) +} + +//-------------------------------------- +// Whitebox race tests to trigger different paths through the SetStatus +// code; use arbitrary sample transitions, full set of valid transitions +// are checked further down. +func (s *RestoreInfoSuite) TestInsertRaceHarmless(c *gc.C) { + defer state.SetBeforeHooks( + c, s.State, func() { + s.checkSetStatus(c, state.RestorePending) + }, + ).Check() + s.checkSetStatus(c, state.RestorePending) +} + +func (s *RestoreInfoSuite) TestInsertRaceFailure(c *gc.C) { + defer state.SetBeforeHooks( + c, s.State, func() { + s.checkSetStatus(c, state.RestorePending) + s.checkSetStatus(c, state.RestoreInProgress) + }, + ).Check() + s.checkBadSetStatus(c, state.RestorePending) + s.checkStatus(c, state.RestoreInProgress) +} + +func (s *RestoreInfoSuite) TestUpdateRaceHarmless(c *gc.C) { + s.setupInProgress(c) + defer state.SetBeforeHooks( + c, s.State, func() { + s.checkSetStatus(c, state.RestoreFinished) + }, + ).Check() + s.checkSetStatus(c, state.RestoreFinished) +} + +func (s *RestoreInfoSuite) TestUpdateRaceFailure(c *gc.C) { + s.setupInProgress(c) + defer state.SetBeforeHooks( + c, s.State, func() { + s.checkSetStatus(c, state.RestoreFailed) + }, + ).Check() + s.checkBadSetStatus(c, state.RestoreFinished) + s.checkStatus(c, state.RestoreFailed) } -func checkStatus(c *gc.C, setter *state.RestoreInfo, status state.RestoreStatus) { - if c.Check(setter, gc.NotNil) { - c.Check(setter.Status(), gc.Equals, status) +func (s *RestoreInfoSuite) TestUpdateRaceExhaustion(c *gc.C) { + s.setupPending(c) + perturb := jujutxn.TestHook{ + Before: func() { + s.checkSetStatus(c, state.RestoreFailed) + }, + After: func() { + s.checkSetStatus(c, state.RestorePending) + }, } + defer state.SetTestHooks( + c, s.State, + perturb, + perturb, + perturb, + ).Check() + err := s.info.SetStatus(state.RestoreInProgress) + c.Check(err, gc.ErrorMatches, "state changing too quickly; try again soon") +} + +//-------------------------------------- +// Test NotActive -> ? transitions +func (s *RestoreInfoSuite) TestNotActiveSetNotActive(c *gc.C) { + s.checkSetStatus(c, state.RestoreNotActive) +} + +func (s *RestoreInfoSuite) TestNotActiveSetPending(c *gc.C) { + s.checkSetStatus(c, state.RestorePending) +} + +func (s *RestoreInfoSuite) TestNotActiveSetInProgress(c *gc.C) { + s.checkBadSetStatus(c, state.RestoreFinished) +} + +func (s *RestoreInfoSuite) TestNotActiveSetFinished(c *gc.C) { + s.checkBadSetStatus(c, state.RestoreFinished) +} + +func (s *RestoreInfoSuite) TestNotActiveSetChecked(c *gc.C) { + s.checkBadSetStatus(c, state.RestoreChecked) +} + +func (s *RestoreInfoSuite) TestNotActiveSetFailed(c *gc.C) { + s.checkBadSetStatus(c, state.RestoreFailed) +} + +//-------------------------------------- +// Test Pending -> ? transitions +func (s *RestoreInfoSuite) setupPending(c *gc.C) { + s.checkSetStatus(c, state.RestorePending) +} + +func (s *RestoreInfoSuite) TestPendingSetNotActive(c *gc.C) { + s.setupPending(c) + s.checkBadSetStatus(c, state.RestoreNotActive) +} + +func (s *RestoreInfoSuite) TestPendingSetPending(c *gc.C) { + s.setupPending(c) + s.checkSetStatus(c, state.RestorePending) +} + +func (s *RestoreInfoSuite) TestPendingSetInProgress(c *gc.C) { + s.setupPending(c) + s.checkSetStatus(c, state.RestoreInProgress) +} + +func (s *RestoreInfoSuite) TestPendingSetFinished(c *gc.C) { + s.setupPending(c) + s.checkBadSetStatus(c, state.RestoreFinished) +} + +func (s *RestoreInfoSuite) TestPendingSetChecked(c *gc.C) { + s.setupPending(c) + s.checkBadSetStatus(c, state.RestoreChecked) +} + +func (s *RestoreInfoSuite) TestPendingSetFailed(c *gc.C) { + s.setupPending(c) + s.checkSetStatus(c, state.RestoreFailed) +} + +//-------------------------------------- +// Test InProgress -> ? transitions +func (s *RestoreInfoSuite) setupInProgress(c *gc.C) { + s.checkSetStatus(c, state.RestorePending) + s.checkSetStatus(c, state.RestoreInProgress) +} + +func (s *RestoreInfoSuite) TestInProgressSetNotActive(c *gc.C) { + s.setupInProgress(c) + s.checkBadSetStatus(c, state.RestoreNotActive) +} + +func (s *RestoreInfoSuite) TestInProgressSetPending(c *gc.C) { + s.setupInProgress(c) + s.checkBadSetStatus(c, state.RestorePending) +} + +func (s *RestoreInfoSuite) TestInProgressSetInProgress(c *gc.C) { + s.setupInProgress(c) + s.checkSetStatus(c, state.RestoreInProgress) +} + +func (s *RestoreInfoSuite) TestInProgressSetFinished(c *gc.C) { + s.setupInProgress(c) + s.checkSetStatus(c, state.RestoreFinished) +} + +func (s *RestoreInfoSuite) TestInProgressSetChecked(c *gc.C) { + s.setupInProgress(c) + s.checkBadSetStatus(c, state.RestoreChecked) +} + +func (s *RestoreInfoSuite) TestInProgressSetFailed(c *gc.C) { + s.setupInProgress(c) + s.checkSetStatus(c, state.RestoreFailed) +} + +//-------------------------------------- +// Test Finished -> ? transitions +func (s *RestoreInfoSuite) setupFinished(c *gc.C) { + s.checkSetStatus(c, state.RestorePending) + s.checkSetStatus(c, state.RestoreInProgress) + s.checkSetStatus(c, state.RestoreFinished) +} + +func (s *RestoreInfoSuite) TestFinishedSetNotActive(c *gc.C) { + s.setupFinished(c) + s.checkBadSetStatus(c, state.RestoreNotActive) +} + +func (s *RestoreInfoSuite) TestFinishedSetPending(c *gc.C) { + s.setupFinished(c) + s.checkBadSetStatus(c, state.RestorePending) +} + +func (s *RestoreInfoSuite) TestFinishedSetInProgress(c *gc.C) { + s.setupFinished(c) + s.checkBadSetStatus(c, state.RestoreInProgress) +} + +func (s *RestoreInfoSuite) TestFinishedSetFinished(c *gc.C) { + s.setupFinished(c) + s.checkSetStatus(c, state.RestoreFinished) +} + +func (s *RestoreInfoSuite) TestFinishedSetChecked(c *gc.C) { + s.setupFinished(c) + s.checkSetStatus(c, state.RestoreChecked) +} + +func (s *RestoreInfoSuite) TestFinishedSetFailed(c *gc.C) { + s.setupFinished(c) + s.checkSetStatus(c, state.RestoreFailed) +} + +//-------------------------------------- +// Test Checked -> ? transitions +func (s *RestoreInfoSuite) setupChecked(c *gc.C) { + s.checkSetStatus(c, state.RestorePending) + s.checkSetStatus(c, state.RestoreInProgress) + s.checkSetStatus(c, state.RestoreFinished) + s.checkSetStatus(c, state.RestoreChecked) +} + +func (s *RestoreInfoSuite) TestCheckedSetNotActive(c *gc.C) { + s.setupChecked(c) + s.checkBadSetStatus(c, state.RestoreNotActive) +} + +func (s *RestoreInfoSuite) TestCheckedSetPending(c *gc.C) { + s.setupChecked(c) + s.checkSetStatus(c, state.RestorePending) +} + +func (s *RestoreInfoSuite) TestCheckedSetInProgress(c *gc.C) { + s.setupChecked(c) + s.checkBadSetStatus(c, state.RestoreInProgress) +} + +func (s *RestoreInfoSuite) TestCheckedSetFinished(c *gc.C) { + s.setupChecked(c) + s.checkBadSetStatus(c, state.RestoreFinished) +} + +func (s *RestoreInfoSuite) TestCheckedSetChecked(c *gc.C) { + s.setupChecked(c) + s.checkSetStatus(c, state.RestoreChecked) +} + +func (s *RestoreInfoSuite) TestCheckedSetFailed(c *gc.C) { + s.setupChecked(c) + s.checkBadSetStatus(c, state.RestoreFailed) +} + +//-------------------------------------- +// Test Failed -> ? transitions +func (s *RestoreInfoSuite) setupFailed(c *gc.C) { + s.checkSetStatus(c, state.RestorePending) + s.checkSetStatus(c, state.RestoreFailed) +} + +func (s *RestoreInfoSuite) TestFailedSetNotActive(c *gc.C) { + s.setupFailed(c) + s.checkBadSetStatus(c, state.RestoreNotActive) +} + +func (s *RestoreInfoSuite) TestFailedSetPending(c *gc.C) { + s.setupFailed(c) + s.checkSetStatus(c, state.RestorePending) +} + +func (s *RestoreInfoSuite) TestFailedSetInProgress(c *gc.C) { + s.setupFailed(c) + s.checkBadSetStatus(c, state.RestoreInProgress) +} + +func (s *RestoreInfoSuite) TestFailedSetFinished(c *gc.C) { + s.setupFailed(c) + s.checkBadSetStatus(c, state.RestoreFinished) +} + +func (s *RestoreInfoSuite) TestFailedSetChecked(c *gc.C) { + s.setupFailed(c) + s.checkBadSetStatus(c, state.RestoreChecked) +} + +func (s *RestoreInfoSuite) TestFailedSetFailed(c *gc.C) { + s.setupFailed(c) + s.checkSetStatus(c, state.RestoreFailed) +} + +//-------------------- + +func (s *RestoreInfoSuite) checkStatus(c *gc.C, expect state.RestoreStatus) { + actual, err := s.info.Status() + c.Check(err, jc.ErrorIsNil) + c.Check(actual, gc.Equals, expect) +} + +func (s *RestoreInfoSuite) checkSetStatus(c *gc.C, status state.RestoreStatus) { + err := s.info.SetStatus(status) + c.Check(err, jc.ErrorIsNil) + s.checkStatus(c, status) +} + +func (s *RestoreInfoSuite) checkBadSetStatus(c *gc.C, status state.RestoreStatus) { + err := s.info.SetStatus(status) + expect := fmt.Sprintf("invalid restore transition: [-A-Z]+ => %s", status) + c.Check(err, gc.ErrorMatches, expect) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/state.go juju-core-2.0~beta7/src/github.com/juju/juju/state/state.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/state.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/state.go 2016-05-17 20:01:14.000000000 +0000 @@ -74,6 +74,7 @@ modelTag names.ModelTag controllerTag names.ModelTag mongoInfo *mongo.MongoInfo + mongoDialOpts mongo.DialOpts session *mgo.Session database Database policy Policy @@ -194,7 +195,7 @@ // ForModel returns a connection to mongo for the specified model. The // connection uses the same credentials and policy as the existing connection. func (st *State) ForModel(env names.ModelTag) (*State, error) { - newState, err := open(env, st.mongoInfo, mongo.DefaultDialOpts(), st.policy) + newState, err := open(env, st.mongoInfo, st.mongoDialOpts, st.policy) if err != nil { return nil, errors.Trace(err) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/state_test.go juju-core-2.0~beta7/src/github.com/juju/juju/state/state_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/state_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/state_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -33,6 +33,7 @@ "github.com/juju/juju/environs/config" "github.com/juju/juju/instance" "github.com/juju/juju/mongo" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/network" "github.com/juju/juju/state" "github.com/juju/juju/state/multiwatcher" @@ -133,14 +134,14 @@ func (s *StateSuite) TestDialAgain(c *gc.C) { // Ensure idempotent operations on Dial are working fine. for i := 0; i < 2; i++ { - st, err := state.Open(s.modelTag, statetesting.NewMongoInfo(), statetesting.NewDialOpts(), state.Policy(nil)) + st, err := state.Open(s.modelTag, statetesting.NewMongoInfo(), mongotest.DialOpts(), state.Policy(nil)) c.Assert(err, jc.ErrorIsNil) c.Assert(st.Close(), gc.IsNil) } } func (s *StateSuite) TestOpenAcceptsMissingModelTag(c *gc.C) { - st, err := state.Open(names.ModelTag{}, statetesting.NewMongoInfo(), statetesting.NewDialOpts(), state.Policy(nil)) + st, err := state.Open(names.ModelTag{}, statetesting.NewMongoInfo(), mongotest.DialOpts(), state.Policy(nil)) c.Assert(err, jc.ErrorIsNil) c.Check(st.ModelTag(), gc.Equals, s.modelTag) @@ -150,7 +151,7 @@ func (s *StateSuite) TestOpenRequiresExtantModelTag(c *gc.C) { uuid := utils.MustNewUUID() tag := names.NewModelTag(uuid.String()) - st, err := state.Open(tag, statetesting.NewMongoInfo(), statetesting.NewDialOpts(), state.Policy(nil)) + st, err := state.Open(tag, statetesting.NewMongoInfo(), mongotest.DialOpts(), state.Policy(nil)) if !c.Check(st, gc.IsNil) { c.Check(st.Close(), jc.ErrorIsNil) } @@ -159,7 +160,7 @@ } func (s *StateSuite) TestOpenSetsModelTag(c *gc.C) { - st, err := state.Open(s.modelTag, statetesting.NewMongoInfo(), statetesting.NewDialOpts(), state.Policy(nil)) + st, err := state.Open(s.modelTag, statetesting.NewMongoInfo(), mongotest.DialOpts(), state.Policy(nil)) c.Assert(err, jc.ErrorIsNil) defer st.Close() @@ -3170,7 +3171,7 @@ } func tryOpenState(modelTag names.ModelTag, info *mongo.MongoInfo) error { - st, err := state.Open(modelTag, info, statetesting.NewDialOpts(), state.Policy(nil)) + st, err := state.Open(modelTag, info, mongotest.DialOpts(), state.Policy(nil)) if err == nil { err = st.Close() } @@ -3884,7 +3885,7 @@ // interact with the closed state, causing it to return an // unexpected error (often "Closed explictly"). func testWatcherDiesWhenStateCloses(c *gc.C, modelTag names.ModelTag, startWatcher func(c *gc.C, st *state.State) waiter) { - st, err := state.Open(modelTag, statetesting.NewMongoInfo(), statetesting.NewDialOpts(), state.Policy(nil)) + st, err := state.Open(modelTag, statetesting.NewMongoInfo(), mongotest.DialOpts(), state.Policy(nil)) c.Assert(err, jc.ErrorIsNil) watcher := startWatcher(c, st) err = st.Close() @@ -3932,7 +3933,7 @@ c.Assert(err, jc.ErrorIsNil) c.Assert(info, jc.DeepEquals, expected) - st, err := state.Open(s.modelTag, statetesting.NewMongoInfo(), statetesting.NewDialOpts(), state.Policy(nil)) + st, err := state.Open(s.modelTag, statetesting.NewMongoInfo(), mongotest.DialOpts(), state.Policy(nil)) c.Assert(err, jc.ErrorIsNil) defer st.Close() @@ -4673,7 +4674,7 @@ }, } cfg := testing.ModelConfig(c) - st, err := state.Initialize(owner, mongoInfo, cfg, statetesting.NewDialOpts(), nil) + st, err := state.Initialize(owner, mongoInfo, cfg, mongotest.DialOpts(), nil) c.Assert(err, jc.ErrorIsNil) defer st.Close() diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/status_util_test.go juju-core-2.0~beta7/src/github.com/juju/juju/state/status_util_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/status_util_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/status_util_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,6 +4,9 @@ package state_test import ( + "runtime" + "time" + jc "github.com/juju/testing/checkers" gc "gopkg.in/check.v1" @@ -13,6 +16,24 @@ type statusHistoryFunc func(int) ([]status.StatusInfo, error) +type statusSetter interface { + SetStatus(status.Status, string, map[string]interface{}) error +} + +func primeStatusHistory(c *gc.C, entity statusSetter, statusVal status.Status, count int, nextData func(int) map[string]interface{}) { + info := "" + for i := 0; i < count; i++ { + c.Logf("setting status for %v", entity) + data := nextData(i) + err := entity.SetStatus(statusVal, info, data) + c.Assert(err, jc.ErrorIsNil) + if runtime.GOOS == "windows" { + // The default clock tick on Windows is 15.6 ms. + time.Sleep(20 * time.Millisecond) + } + } +} + func checkInitialWorkloadStatus(c *gc.C, statusInfo status.StatusInfo) { c.Check(statusInfo.Status, gc.Equals, status.StatusUnknown) c.Check(statusInfo.Message, gc.Equals, "Waiting for agent initialization to finish") @@ -21,10 +42,9 @@ } func primeUnitStatusHistory(c *gc.C, unit *state.Unit, count int) { - for i := 0; i < count; i++ { - err := unit.SetStatus(status.StatusActive, "", map[string]interface{}{"$foo": i}) - c.Assert(err, gc.IsNil) - } + primeStatusHistory(c, unit, status.StatusActive, count, func(i int) map[string]interface{} { + return map[string]interface{}{"$foo": i} + }) } func checkPrimedUnitStatus(c *gc.C, statusInfo status.StatusInfo, expect int) { @@ -42,10 +62,9 @@ } func primeUnitAgentStatusHistory(c *gc.C, agent *state.UnitAgent, count int) { - for i := 0; i < count; i++ { - err := agent.SetStatus(status.StatusExecuting, "", map[string]interface{}{"$bar": i}) - c.Assert(err, gc.IsNil) - } + primeStatusHistory(c, agent, status.StatusExecuting, count, func(i int) map[string]interface{} { + return map[string]interface{}{"$bar": i} + }) } func checkPrimedUnitAgentStatus(c *gc.C, statusInfo status.StatusInfo, expect int) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/testing/conn.go juju-core-2.0~beta7/src/github.com/juju/juju/state/testing/conn.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/testing/conn.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/testing/conn.go 2016-05-17 20:01:14.000000000 +0000 @@ -11,6 +11,7 @@ "github.com/juju/juju/environs/config" "github.com/juju/juju/mongo" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/state" "github.com/juju/juju/testing" ) @@ -23,7 +24,7 @@ cfg = testing.ModelConfig(c) } mgoInfo := NewMongoInfo() - dialOpts := NewDialOpts() + dialOpts := mongotest.DialOpts() st, err := state.Initialize(owner, mgoInfo, cfg, dialOpts, policy) c.Assert(err, jc.ErrorIsNil) @@ -41,14 +42,6 @@ } } -// NewDialOpts returns configuration parameters for -// connecting to the testing controller. -func NewDialOpts() mongo.DialOpts { - return mongo.DialOpts{ - Timeout: testing.LongWait, - } -} - // NewState initializes a new state with default values for testing and // returns it. func NewState(c *gc.C) *state.State { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/state/watcher/helpers.go juju-core-2.0~beta7/src/github.com/juju/juju/state/watcher/helpers.go --- juju-core-2.0~beta6/src/github.com/juju/juju/state/watcher/helpers.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/state/watcher/helpers.go 2016-05-17 20:01:14.000000000 +0000 @@ -37,9 +37,9 @@ func EnsureErr(w Errer) error { err := w.Err() if err == nil { - return errors.Errorf("expected an error from %#v, got nil", w) + return errors.Errorf("expected an error from %v, got nil", w) } else if err == tomb.ErrStillAlive { - return errors.Annotatef(err, "expected %#v to be stopped", w) + return errors.Annotatef(err, "expected %v to be stopped", w) } return errors.Trace(err) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/testing/base.go juju-core-2.0~beta7/src/github.com/juju/juju/testing/base.go --- juju-core-2.0~beta6/src/github.com/juju/juju/testing/base.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/testing/base.go 2016-05-17 20:01:14.000000000 +0000 @@ -12,10 +12,12 @@ "github.com/juju/loggo" "github.com/juju/testing" + jc "github.com/juju/testing/checkers" "github.com/juju/utils" "github.com/juju/utils/arch" "github.com/juju/utils/featureflag" jujuos "github.com/juju/utils/os" + "github.com/juju/utils/series" gc "gopkg.in/check.v1" "github.com/juju/juju/juju/osenv" @@ -55,7 +57,8 @@ } s.oldHomeEnv = utils.Home() s.oldJujuXDGDataHome = osenv.SetJujuXDGDataHome("") - utils.SetHome("") + err := utils.SetHome("") + c.Assert(err, jc.ErrorIsNil) // Update the feature flag set to be the requested initial set. // This works for both windows and unix, even though normally @@ -71,7 +74,8 @@ for name, value := range s.oldEnvironment { os.Setenv(name, value) } - utils.SetHome(s.oldHomeEnv) + err := utils.SetHome(s.oldHomeEnv) + c.Assert(err, jc.ErrorIsNil) osenv.SetJujuXDGDataHome(s.oldJujuXDGDataHome) } @@ -123,6 +127,7 @@ // NOTE: there will be many tests that fail when you try to change // to the IsolationSuite that rely on external things in PATH. type BaseSuite struct { + oldLtsForTesting string testing.CleanupSuite testing.LoggingSuite JujuOSEnvSuite @@ -134,10 +139,13 @@ s.LoggingSuite.SetUpSuite(c) // JujuOSEnvSuite does not have a suite setup. s.PatchValue(&utils.OutgoingAccessAllowed, false) + // LTS-dependent requires new entry upon new LTS release. + s.oldLtsForTesting = series.SetLatestLtsForTesting("xenial") } func (s *BaseSuite) TearDownSuite(c *gc.C) { // JujuOSEnvSuite does not have a suite teardown. + _ = series.SetLatestLtsForTesting(s.oldLtsForTesting) s.LoggingSuite.TearDownSuite(c) s.CleanupSuite.TearDownSuite(c) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/testing/base_test.go juju-core-2.0~beta7/src/github.com/juju/juju/testing/base_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/testing/base_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/testing/base_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -6,6 +6,7 @@ import ( "os" + jc "github.com/juju/testing/checkers" "github.com/juju/utils" gc "gopkg.in/check.v1" @@ -20,7 +21,8 @@ var _ = gc.Suite(&TestingBaseSuite{}) func (s *TestingBaseSuite) SetUpTest(c *gc.C) { - utils.SetHome(home) + err := utils.SetHome(home) + c.Assert(err, jc.ErrorIsNil) os.Setenv("JUJU_DATA", jujuXDGDataHome) osenv.SetJujuXDGDataHome(jujuXDGDataHome) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/testing/clock.go juju-core-2.0~beta7/src/github.com/juju/juju/testing/clock.go --- juju-core-2.0~beta6/src/github.com/juju/juju/testing/clock.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/testing/clock.go 2016-05-17 20:01:14.000000000 +0000 @@ -227,3 +227,22 @@ s.NextErr() // pop one off return s.ReturnAfterFunc } + +// AutoAdvancingClock wraps a clock.Clock, calling the Advance +// function whenever After or AfterFunc are called. +type AutoAdvancingClock struct { + clock.Clock + Advance func(time.Duration) +} + +func (c *AutoAdvancingClock) After(d time.Duration) <-chan time.Time { + ch := c.Clock.After(d) + c.Advance(d) + return ch +} + +func (c *AutoAdvancingClock) AfterFunc(d time.Duration, f func()) clock.Timer { + t := c.Clock.AfterFunc(d, f) + c.Advance(d) + return t +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/testing/environ.go juju-core-2.0~beta7/src/github.com/juju/juju/testing/environ.go --- juju-core-2.0~beta6/src/github.com/juju/juju/testing/environ.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/testing/environ.go 2016-05-17 20:01:14.000000000 +0000 @@ -10,6 +10,7 @@ gitjujutesting "github.com/juju/testing" jc "github.com/juju/testing/checkers" "github.com/juju/utils" + "github.com/juju/utils/series" "github.com/juju/utils/ssh" "github.com/juju/version" gc "gopkg.in/check.v1" @@ -30,8 +31,6 @@ } } -const FakeDefaultSeries = "trusty" - // FakeVersionNumber is a valid version number that can be used in testing. var FakeVersionNumber = version.MustParse("1.99.0") @@ -55,7 +54,7 @@ "development": false, "state-port": 19034, "api-port": 17777, - "default-series": FakeDefaultSeries, + "default-series": series.LatestLts(), } } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/testing/environ_test.go juju-core-2.0~beta7/src/github.com/juju/juju/testing/environ_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/testing/environ_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/testing/environ_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -23,7 +23,8 @@ var _ = gc.Suite(&fakeHomeSuite{}) func (s *fakeHomeSuite) SetUpTest(c *gc.C) { - utils.SetHome(home) + err := utils.SetHome(home) + c.Assert(err, jc.ErrorIsNil) os.Setenv("JUJU_DATA", jujuXDGDataHome) osenv.SetJujuXDGDataHome(jujuXDGDataHome) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/testing/factory/factory_test.go juju-core-2.0~beta7/src/github.com/juju/juju/testing/factory/factory_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/testing/factory/factory_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/testing/factory/factory_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -522,7 +522,7 @@ cfg, err := st.ModelConfig() c.Assert(err, jc.ErrorIsNil) - c.Assert(cfg.AllAttrs()["default-series"], gc.Equals, "trusty") + c.Assert(cfg.AllAttrs()["default-series"], gc.Equals, "xenial") } func (s *factorySuite) TestMakeModel(c *gc.C) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/tools/lxdclient/client_image_test.go juju-core-2.0~beta7/src/github.com/juju/juju/tools/lxdclient/client_image_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/tools/lxdclient/client_image_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/tools/lxdclient/client_image_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -13,6 +13,8 @@ "github.com/juju/testing" jc "github.com/juju/testing/checkers" gc "gopkg.in/check.v1" + + coretesting "github.com/juju/juju/testing" ) type imageSuite struct { @@ -277,9 +279,12 @@ } func (s *imageSuite) TestEnsureImageExistsCallbackIncludesSourceURL(c *gc.C) { - calls := make(chan string, 20) + calls := make(chan string, 1) callback := func(message string) { - calls <- message + select { + case calls <- message: + default: + } } connector := MakeConnector(s.Stub, s.remoteWithTrusty) raw := &stubClient{ @@ -297,7 +302,9 @@ select { case message := <-calls: c.Check(message, gc.Matches, "copying image for ubuntu-trusty from https://match: \\d+%") - default: + case <-time.After(coretesting.LongWait): + // The callbacks are made asynchronously, and so may not + // have happened by the time EnsureImageExists exits. c.Fatalf("no messages received") } } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/tools/lxdclient/client_test.go juju-core-2.0~beta7/src/github.com/juju/juju/tools/lxdclient/client_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/tools/lxdclient/client_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/tools/lxdclient/client_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -1,7 +1,7 @@ // Copyright 2015 Canonical Ltd. // Licensed under the AGPLv3, see LICENCE file for details. -// +build go1.3 +// +build go1.3,linux package lxdclient @@ -12,6 +12,7 @@ "github.com/juju/errors" "github.com/juju/testing" jc "github.com/juju/testing/checkers" + jujuos "github.com/juju/utils/os" "github.com/lxc/lxd" gc "gopkg.in/check.v1" ) @@ -22,6 +23,13 @@ var _ = gc.Suite(&ConnectSuite{}) +func (cs *ConnectSuite) SetUpSuite(c *gc.C) { + cs.IsolationSuite.SetUpSuite(c) + if jujuos.HostOS() != jujuos.Ubuntu { + c.Skip("lxd is only supported on Ubuntu at the moment") + } +} + func (cs *ConnectSuite) TestLocalConnectError(c *gc.C) { f, err := ioutil.TempFile("", "juju-lxd-remote-test") c.Assert(err, jc.ErrorIsNil) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/utils/stringforwarder/stringforwarder.go juju-core-2.0~beta7/src/github.com/juju/juju/utils/stringforwarder/stringforwarder.go --- juju-core-2.0~beta6/src/github.com/juju/juju/utils/stringforwarder/stringforwarder.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/utils/stringforwarder/stringforwarder.go 2016-05-17 20:01:14.000000000 +0000 @@ -3,88 +3,91 @@ package stringforwarder -import ( - "sync" - "sync/atomic" -) +import "sync" // StringForwarder is a goroutine-safe type that pipes messages from the -// its Forward() method, sending them to callback. The send is non-blocking and -// will discard messages if the last message has not finished processing. -// The number of discarded messages is tracked and returned when the forwarder -// is stopped. +// its Forward() method, sending them to callback. The send will not be +// blocked by the callback, but will instead discard messages if there +// is an incomplete callback in progress. The number of discarded messages +// is tracked and returned when the forwarder is stopped. type StringForwarder struct { - messages chan string - done chan struct{} + mu sync.Mutex + cond *sync.Cond + current *string + stopped bool discardCount uint64 - mu *sync.Mutex } // New returns a new StringForwarder that sends messages to the callback, -// function, dropping messages if the receiver is not ready. +// function, dropping messages if the receiver has not yet consumed the +// last message. func New(callback func(string)) *StringForwarder { if callback == nil { - // Nothing to forward to, so no need to start the loop(). We'll - // just count the discardCount. - return &StringForwarder{mu: &sync.Mutex{}} + // Nothing to forward to, so no need to start the loop(). + // We'll just count the discardCount. + return &StringForwarder{stopped: true} } - - messages := make(chan string) - done := make(chan struct{}) - forwarder := &StringForwarder{ - messages: messages, - done: done, - mu: &sync.Mutex{}, - discardCount: 0, - } - started := make(chan struct{}) - go forwarder.loop(started, callback) - <-started + forwarder := &StringForwarder{} + forwarder.cond = sync.NewCond(&forwarder.mu) + go forwarder.loop(callback) return forwarder } -// Forward makes a non-blocking send of the message to the callback function. -// If the message is not received, it will increment the count of discarded -// messages. Forward is safe to call from multiple goroutines at once. +// Forward sends the message to be processed by the callback function, +// discarding the message if another message is currently being processed. +// The number of discarded messages is recorded for reporting by the Stop +// method. +// +// Forward is safe to call from multiple goroutines at once. // Note that if this StringForwarder was created with a nil callback, all // messages will be discarded. func (f *StringForwarder) Forward(msg string) { - select { - case f.messages <- msg: - default: - atomic.AddUint64(&f.discardCount, 1) + f.mu.Lock() + if f.stopped || f.current != nil { + f.discardCount++ + } else { + f.current = &msg + f.cond.Signal() } + f.mu.Unlock() } // Stop cleans up the goroutine running behind StringForwarder and returns the // count of discarded messages. Stop is thread-safe and may be called multiple // times - after the first time, it simply returns the current discard count. func (f *StringForwarder) Stop() uint64 { + var count uint64 f.mu.Lock() - if f.done != nil { - close(f.done) - f.done = nil + if !f.stopped { + f.stopped = true + f.cond.Signal() } + count = f.discardCount f.mu.Unlock() - return atomic.LoadUint64(&f.discardCount) + return count } -// loop pipes messages from the messages channel into the callback function. It -// closes started to signal that it has begun, and will clean itself up when -// done is closed. -func (f *StringForwarder) loop(started chan struct{}, callback func(string)) { - // Grab a copy of done so we can notice it is closed, even though - // StringForwarder.Stop() will set it to nil. +// loop invokes forwarded messages with the given callback until stopped. +func (f *StringForwarder) loop(callback func(string)) { f.mu.Lock() - done := f.done - f.mu.Unlock() - close(started) + defer f.mu.Unlock() for { - select { - case msg := <-f.messages: - callback(msg) - case <-done: + for !f.stopped && f.current == nil { + f.cond.Wait() + } + if f.current == nil { return } + f.invokeCallback(callback, *f.current) + f.current = nil } } + +// invokeCallback invokes the given callback with a message, +// unlocking the forwarder's mutex for the duration of the +// callback. +func (f *StringForwarder) invokeCallback(callback func(string), msg string) { + f.mu.Unlock() + defer f.mu.Lock() + callback(msg) +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/utils/stringforwarder/stringforwarder_test.go juju-core-2.0~beta7/src/github.com/juju/juju/utils/stringforwarder/stringforwarder_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/utils/stringforwarder/stringforwarder_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/utils/stringforwarder/stringforwarder_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -132,3 +132,19 @@ count := forwarder.Stop() c.Check(count, jc.GreaterThan, uint64(0)) } + +func (*StringForwarderSuite) TestSchedulerSensitivity(c *gc.C) { + var wg sync.WaitGroup + f := func() { + defer wg.Done() + forwarder := stringforwarder.New(noopCallback) + forwarder.Forward("msg") + n := forwarder.Stop() + c.Check(n, gc.Equals, uint64(0)) + } + for i := 0; i < 1000; i++ { + wg.Add(1) + go f() + } + wg.Wait() +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/version/version.go juju-core-2.0~beta7/src/github.com/juju/juju/version/version.go --- juju-core-2.0~beta6/src/github.com/juju/juju/version/version.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/version/version.go 2016-05-17 20:01:14.000000000 +0000 @@ -19,7 +19,7 @@ // The presence and format of this constant is very important. // The debian/rules build recipe uses this value for the version // number of the release package. -const version = "2.0-beta6" +const version = "2.0-beta7" // The version that we switched over from old style numbering to new style. var switchOverVersion = semversion.MustParse("1.19.9") diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/instancepoller/aggregate_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/instancepoller/aggregate_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/instancepoller/aggregate_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/instancepoller/aggregate_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -188,6 +188,7 @@ } type batchingInstanceGetter struct { + sync.RWMutex testInstanceGetter wg sync.WaitGroup aggregator *aggregator @@ -215,6 +216,8 @@ func (g *batchingInstanceGetter) startRequest() { g.started++ go func() { + g.RLock() + defer g.RUnlock() _, err := g.aggregator.instanceInfo("foo") if err != nil { panic(err) @@ -226,6 +229,7 @@ func (s *aggregateSuite) TestBatching(c *gc.C) { s.PatchValue(&gatherTime, 10*time.Millisecond) var testGetter batchingInstanceGetter + testGetter.Lock() testGetter.aggregator = newAggregator(&testGetter) // We only need to inform the system about 1 instance, because all the // requests are for the same instance. @@ -238,6 +242,7 @@ // which should get aggregated into a single call to Instances, which // then should trigger another round of batchSize requests. testGetter.startRequest() + testGetter.Unlock() testGetter.wg.Wait() c.Assert(testGetter.counter, gc.Equals, int32(testGetter.totalCount/testGetter.batchSize)+1) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/metrics/collect/export_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/metrics/collect/export_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/metrics/collect/export_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/metrics/collect/export_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -34,7 +34,7 @@ type handlerSetterStopper interface { SetHandler(spool.ConnectionHandler) - Stop() + Stop() error } func NewSocketListenerFnc(listener handlerSetterStopper) func(string, spool.ConnectionHandler) (stopper, error) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/metrics/collect/handler_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/metrics/collect/handler_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/metrics/collect/handler_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/metrics/collect/handler_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -171,8 +171,9 @@ } // Stop implements the stopper interface. -func (l *mockListener) Stop() { +func (l *mockListener) Stop() error { l.AddCall("Stop") + return nil } func (l *mockListener) SetHandler(handler spool.ConnectionHandler) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/metrics/collect/manifold.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/metrics/collect/manifold.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/metrics/collect/manifold.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/metrics/collect/manifold.go 2016-05-17 20:01:14.000000000 +0000 @@ -79,7 +79,7 @@ ) type stopper interface { - Stop() + Stop() error } // ManifoldConfig identifies the resource names upon which the collect manifold diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/metrics/sender/sender.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/metrics/sender/sender.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/metrics/sender/sender.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/metrics/sender/sender.go 2016-05-17 20:01:14.000000000 +0000 @@ -24,7 +24,7 @@ ) type stopper interface { - Stop() + Stop() error } type sender struct { @@ -47,8 +47,7 @@ func (s *sender) sendMetrics(reader spool.MetricReader) error { batches, err := reader.Read() if err != nil { - logger.Warningf("failed to open the metric reader: %v", err) - return errors.Trace(err) + return errors.Annotate(err, "failed to open the metric reader") } var sendBatches []params.MetricBatchParam for _, batch := range batches { @@ -56,20 +55,19 @@ } results, err := s.client.AddMetricBatches(sendBatches) if err != nil { - logger.Warningf("could not send metrics: %v", err) - return errors.Trace(err) + return errors.Annotate(err, "could not send metrics") } for batchUUID, resultErr := range results { // if we fail to send any metric batch we log a warning with the assumption that // the unsent metric batches remain in the spool directory and will be sent to the // controller when the network partition is restored. if _, ok := resultErr.(*params.Error); ok || params.IsCodeAlreadyExists(resultErr) { - err = reader.Remove(batchUUID) + err := reader.Remove(batchUUID) if err != nil { - logger.Warningf("could not remove batch %q from spool: %v", batchUUID, err) + logger.Errorf("could not remove batch %q from spool: %v", batchUUID, err) } } else { - logger.Warningf("failed to send batch %q: %v", batchUUID, resultErr) + logger.Errorf("failed to send batch %q: %v", batchUUID, resultErr) } } return nil @@ -87,8 +85,7 @@ c.Close() }() // TODO(fwereade): 2016-03-17 lp:1558657 - err = c.SetDeadline(time.Now().Add(spool.DefaultTimeout)) - if err != nil { + if err := c.SetDeadline(time.Now().Add(spool.DefaultTimeout)); err != nil { return errors.Annotate(err, "failed to set the deadline") } reader, err := s.factory.Reader() diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/metrics/sender/sender_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/metrics/sender/sender_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/metrics/sender/sender_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/metrics/sender/sender_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -153,7 +153,7 @@ c.Assert(err, jc.ErrorIsNil) stopCh := make(chan struct{}) err = metricSender.Do(stopCh) - c.Assert(err, gc.ErrorMatches, "something went wrong") + c.Assert(err, gc.ErrorMatches, "could not send metrics: something went wrong") c.Assert(apiSender.batches, gc.HasLen, 1) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/metrics/spool/listener.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/metrics/spool/listener.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/metrics/spool/listener.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/metrics/spool/listener.go 2016-05-17 20:01:14.000000000 +0000 @@ -47,41 +47,27 @@ // Stop closes the listener and releases all resources // used by the socketListener. -func (l *socketListener) Stop() { +func (l *socketListener) Stop() error { l.t.Kill(nil) err := l.listener.Close() if err != nil { logger.Errorf("failed to close the collect-metrics listener: %v", err) } - err = l.t.Wait() - if err != nil { - logger.Errorf("failed waiting for all goroutines to finish: %v", err) - } + return l.t.Wait() } -func (l *socketListener) loop() (_err error) { - defer func() { - select { - case <-l.t.Dying(): - _err = nil - default: - } - }() +func (l *socketListener) loop() error { for { conn, err := l.listener.Accept() if err != nil { return errors.Trace(err) } - go func() error { - err := l.handler.Handle(conn) - if err != nil { - // log the error and continue + go func() { + if err := l.handler.Handle(conn); err != nil { logger.Errorf("request handling failed: %v", err) } - return nil }() } - return } // NewPeriodicWorker returns a periodic worker, that will call a stop function diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/metrics/spool/listener_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/metrics/spool/listener_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/metrics/spool/listener_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/metrics/spool/listener_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -20,7 +20,7 @@ var _ = gc.Suite(&listenerSuite{}) type stopper interface { - Stop() + Stop() error } type listenerSuite struct { diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/provisioner/container_initialisation_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/provisioner/container_initialisation_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/provisioner/container_initialisation_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/provisioner/container_initialisation_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -140,7 +140,7 @@ // make a container on the host machine template := state.MachineTemplate{ - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, } container, err := s.State.AddMachineInsideMachine(template, host.Id(), ctype) @@ -186,7 +186,7 @@ for _, ctype := range containerTypes { // create a machine to host the container. m, err := s.BackingState.AddOneMachine(state.MachineTemplate{ - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, Constraints: s.defaultConstraints, }) @@ -242,7 +242,7 @@ // create a machine to host the container. m, err := s.BackingState.AddOneMachine(state.MachineTemplate{ - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, Constraints: s.defaultConstraints, }) @@ -265,7 +265,7 @@ func (s *ContainerSetupSuite) TestLxcContainerUsesImageURL(c *gc.C) { // create a machine to host the container. m, err := s.BackingState.AddOneMachine(state.MachineTemplate{ - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, Constraints: s.defaultConstraints, }) @@ -393,7 +393,7 @@ func (s *ContainerSetupSuite) TestContainerInitLockError(c *gc.C) { m, err := s.BackingState.AddOneMachine(state.MachineTemplate{ - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, Constraints: s.defaultConstraints, }) @@ -613,7 +613,7 @@ func (s *LXCDefaultMTUSuite) TestDefaultMTUPropagatedToNewLXCBroker(c *gc.C) { // create a machine to host the container. m, err := s.BackingState.AddOneMachine(state.MachineTemplate{ - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, Constraints: s.defaultConstraints, }) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/provisioner/kvm-broker_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/provisioner/kvm-broker_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/provisioner/kvm-broker_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/provisioner/kvm-broker_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -16,6 +16,7 @@ gitjujutesting "github.com/juju/testing" jc "github.com/juju/testing/checkers" "github.com/juju/utils/arch" + "github.com/juju/utils/series" "github.com/juju/version" gc "gopkg.in/check.v1" @@ -386,7 +387,7 @@ defer stop(c, p) // Check that an instance is not provisioned when the machine is created. - _, err := s.State.AddMachine(coretesting.FakeDefaultSeries, state.JobHostUnits) + _, err := s.State.AddMachine(series.LatestLts(), state.JobHostUnits) c.Assert(err, jc.ErrorIsNil) s.expectNoEvents(c) @@ -403,7 +404,7 @@ func (s *kvmProvisionerSuite) addContainer(c *gc.C) *state.Machine { template := state.MachineTemplate{ - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, } container, err := s.State.AddMachineInsideMachine(template, "0", instance.KVM) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/provisioner/lxc-broker_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/provisioner/lxc-broker_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/provisioner/lxc-broker_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/provisioner/lxc-broker_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -18,6 +18,7 @@ gitjujutesting "github.com/juju/testing" jc "github.com/juju/testing/checkers" "github.com/juju/utils/arch" + "github.com/juju/utils/series" "github.com/juju/utils/set" "github.com/juju/version" gc "gopkg.in/check.v1" @@ -1143,7 +1144,7 @@ defer stop(c, p) // Check that an instance is not provisioned when the machine is created. - _, err := s.State.AddMachine(coretesting.FakeDefaultSeries, state.JobHostUnits) + _, err := s.State.AddMachine(series.LatestLts(), state.JobHostUnits) c.Assert(err, jc.ErrorIsNil) s.expectNoEvents(c) @@ -1160,7 +1161,7 @@ func (s *lxcProvisionerSuite) addContainer(c *gc.C) *state.Machine { template := state.MachineTemplate{ - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, } container, err := s.State.AddMachineInsideMachine(template, "0", instance.LXC) @@ -1183,7 +1184,7 @@ defaultTools := version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), } envtesting.AssertUploadFakeToolsVersions(c, stor, "devel", "devel", defaultTools) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/provisioner/provisioner_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/provisioner/provisioner_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/provisioner/provisioner_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/provisioner/provisioner_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -447,14 +447,14 @@ func (s *CommonProvisionerSuite) addMachineWithConstraints(cons constraints.Value) (*state.Machine, error) { return s.BackingState.AddOneMachine(state.MachineTemplate{ - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, Constraints: cons, }) } func (s *CommonProvisionerSuite) enableHA(c *gc.C, n int) []*state.Machine { - changes, err := s.BackingState.EnableHA(n, s.defaultConstraints, coretesting.FakeDefaultSeries, nil) + changes, err := s.BackingState.EnableHA(n, s.defaultConstraints, series.LatestLts(), nil) c.Assert(err, jc.ErrorIsNil) added := make([]*state.Machine, len(changes.Added)) for i, mid := range changes.Added { @@ -749,7 +749,7 @@ // make a container on the machine we just created template := state.MachineTemplate{ - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, } container, err := s.State.AddMachineInsideMachine(template, m.Id(), instance.LXC) @@ -777,7 +777,7 @@ // make a container on the machine we just created template := state.MachineTemplate{ - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, } container, err := s.State.AddMachineInsideMachine(template, m.Id(), instance.KVM) @@ -1062,7 +1062,7 @@ func (s *CommonProvisionerSuite) addMachineWithRequestedVolumes(volumes []state.MachineVolumeParams, cons constraints.Value) (*state.Machine, error) { return s.BackingState.AddOneMachine(state.MachineTemplate{ - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, Constraints: cons, Volumes: volumes, diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/reboot/reboot_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/reboot/reboot_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/reboot/reboot_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/reboot/reboot_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -6,6 +6,7 @@ jc "github.com/juju/testing/checkers" "github.com/juju/utils" "github.com/juju/utils/fslock" + "github.com/juju/utils/series" gc "gopkg.in/check.v1" "github.com/juju/juju/api" @@ -47,7 +48,7 @@ func (s *rebootSuite) SetUpTest(c *gc.C) { var err error template := state.MachineTemplate{ - Series: coretesting.FakeDefaultSeries, + Series: series.LatestLts(), Jobs: []state.MachineJob{state.JobHostUnits}, } s.JujuConnSuite.SetUpTest(c) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/charm/bundles.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/charm/bundles.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/charm/bundles.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/charm/bundles.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,7 +4,7 @@ package charm import ( - "fmt" + "net/url" "os" "path" @@ -15,15 +15,32 @@ "github.com/juju/juju/downloader" ) +// Download exposes the downloader.Download methods needed here. +type Downloader interface { + // Download starts a new charm archive download, waits for it to + // complete, and returns the local name of the file. + Download(req downloader.Request, abort <-chan struct{}) (string, error) +} + // BundlesDir is responsible for storing and retrieving charm bundles // identified by state charms. type BundlesDir struct { - path string + path string + downloader Downloader } // NewBundlesDir returns a new BundlesDir which uses path for storage. -func NewBundlesDir(path string) *BundlesDir { - return &BundlesDir{path} +func NewBundlesDir(path string, dlr Downloader) *BundlesDir { + if dlr == nil { + dlr = downloader.New(downloader.NewArgs{ + HostnameVerification: utils.NoVerifySSLHostnames, + }) + } + + return &BundlesDir{ + path: path, + downloader: dlr, + } } // Read returns a charm bundle from the directory. If no bundle exists yet, @@ -34,7 +51,8 @@ if _, err := os.Stat(path); err != nil { if !os.IsNotExist(err) { return nil, err - } else if err = d.download(info, abort); err != nil { + } + if err := d.download(info, path, abort); err != nil { return nil, err } } @@ -44,70 +62,33 @@ // download fetches the supplied charm and checks that it has the correct sha256 // hash, then copies it into the directory. If a value is received on abort, the // download will be stopped. -func (d *BundlesDir) download(info BundleInfo, abort <-chan struct{}) (err error) { - archiveURLs, err := info.ArchiveURLs() - if err != nil { - return errors.Annotatef(err, "failed to get download URLs for charm %q", info.URL()) - } - defer errors.DeferredAnnotatef(&err, "failed to download charm %q from %q", info.URL(), archiveURLs) - dir := d.downloadsPath() - if err := os.MkdirAll(dir, 0755); err != nil { - return err - } - var st downloader.Status - for _, archiveURL := range archiveURLs { - aurl := archiveURL.String() - logger.Infof("downloading %s from %s", info.URL(), aurl) - st, err = tryDownload(aurl, dir, abort) - if err == nil { - break - } - } +func (d *BundlesDir) download(info BundleInfo, target string, abort <-chan struct{}) (err error) { + // First download... + curl, err := url.Parse(info.URL().String()) if err != nil { - return err + return errors.Annotate(err, "could not parse charm URL") } - logger.Infof("download complete") - defer st.File.Close() - actualSha256, _, err := utils.ReadSHA256(st.File) - if err != nil { - return err + expectedSha256, err := info.ArchiveSha256() + req := downloader.Request{ + URL: curl, + TargetDir: d.downloadsPath(), + Verify: downloader.NewSha256Verifier(expectedSha256), } - archiveSha256, err := info.ArchiveSha256() + logger.Infof("downloading %s from API server", info.URL()) + filename, err := d.downloader.Download(req, abort) if err != nil { - return err - } - if actualSha256 != archiveSha256 { - return fmt.Errorf( - "expected sha256 %q, got %q", archiveSha256, actualSha256, - ) + return errors.Annotatef(err, "failed to download charm %q from API server", info.URL()) } - logger.Infof("download verified") + defer errors.DeferredAnnotatef(&err, "downloaded but failed to copy charm to %q from %q", target, filename) + + // ...then move the right location. if err := os.MkdirAll(d.path, 0755); err != nil { - return err + return errors.Trace(err) } - // Renaming an open file is not possible on Windows - st.File.Close() - return os.Rename(st.File.Name(), d.bundlePath(info)) -} - -func tryDownload(url, dir string, abort <-chan struct{}) (downloader.Status, error) { - // Downloads always go through the API server, which at - // present cannot be verified due to the certificates - // being inadequate. We always verify the SHA-256 hash, - // and the data transferred is not sensitive, so this - // does not pose a problem. - dl := downloader.New(url, dir, utils.NoVerifySSLHostnames) - defer dl.Stop() - select { - case <-abort: - logger.Infof("download aborted") - return downloader.Status{}, errors.New("aborted") - case st := <-dl.Done(): - if st.Err != nil { - return downloader.Status{}, st.Err - } - return st, nil + if err := os.Rename(filename, target); err != nil { + return errors.Trace(err) } + return nil } // bundlePath returns the path to the location where the verified charm diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/charm/bundles_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/charm/bundles_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/charm/bundles_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/charm/bundles_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,11 +4,6 @@ package charm_test import ( - "crypto/sha256" - "encoding/hex" - "fmt" - "io/ioutil" - "net/url" "os" "path/filepath" "regexp" @@ -77,72 +72,61 @@ s.HTTPSuite.TearDownTest(c) } -func (s *BundlesDirSuite) AddCharm(c *gc.C) (charm.BundleInfo, *state.Charm, []byte) { +func (s *BundlesDirSuite) AddCharm(c *gc.C) (charm.BundleInfo, *state.Charm) { curl := corecharm.MustParseURL("cs:quantal/dummy-1") - storagePath := "dummy-1" - bunpath := testcharms.Repo.CharmArchivePath(c.MkDir(), "dummy") - bun, err := corecharm.ReadCharmArchive(bunpath) - c.Assert(err, jc.ErrorIsNil) - bundata, hash := readHash(c, bunpath) - info := state.CharmInfo{ - Charm: bun, - ID: curl, - StoragePath: storagePath, - SHA256: hash, - } - sch, err := s.State.AddCharm(info) + bun := testcharms.Repo.CharmDir("dummy") + sch, err := testing.AddCharm(s.State, curl, bun) c.Assert(err, jc.ErrorIsNil) + apiCharm, err := s.uniter.Charm(sch.URL()) c.Assert(err, jc.ErrorIsNil) - surlBad, err := url.Parse(s.URL("/some/charm.bundle?bad")) - c.Assert(err, jc.ErrorIsNil) - surlGood, err := url.Parse(s.URL("/some/charm.bundle?good")) - c.Assert(err, jc.ErrorIsNil) - mock := &mockArchiveURLCharm{ - apiCharm, - []*url.URL{surlBad, surlGood}, - } - return mock, sch, bundata + return apiCharm, sch } -type mockArchiveURLCharm struct { +type fakeBundleInfo struct { charm.BundleInfo - archiveURLs []*url.URL + curl *corecharm.URL + sha256 string +} + +func (f fakeBundleInfo) URL() *corecharm.URL { + if f.curl == nil { + return f.BundleInfo.URL() + } + return f.curl } -func (i *mockArchiveURLCharm) ArchiveURLs() ([]*url.URL, error) { - return i.archiveURLs, nil +func (f fakeBundleInfo) ArchiveSha256() (string, error) { + if f.sha256 == "" { + return f.BundleInfo.ArchiveSha256() + } + return f.sha256, nil } func (s *BundlesDirSuite) TestGet(c *gc.C) { basedir := c.MkDir() bunsdir := filepath.Join(basedir, "random", "bundles") - d := charm.NewBundlesDir(bunsdir) + downloader := api.NewCharmDownloader(s.st.Client()) + d := charm.NewBundlesDir(bunsdir, downloader) // Check it doesn't get created until it's needed. _, err := os.Stat(bunsdir) c.Assert(err, jc.Satisfies, os.IsNotExist) // Add a charm to state that we can try to get. - apiCharm, sch, bundata := s.AddCharm(c) + apiCharm, sch := s.AddCharm(c) // Try to get the charm when the content doesn't match. - gitjujutesting.Server.Response(200, nil, []byte("roflcopter")) - archiveURLs, err := apiCharm.ArchiveURLs() - c.Assert(err, gc.IsNil) - _, err = d.Read(apiCharm, nil) - prefix := regexp.QuoteMeta(fmt.Sprintf(`failed to download charm "cs:quantal/dummy-1" from %q: `, archiveURLs)) - c.Assert(err, gc.ErrorMatches, prefix+fmt.Sprintf(`expected sha256 %q, got ".*"`, sch.BundleSha256())) + _, err = d.Read(&fakeBundleInfo{apiCharm, nil, "..."}, nil) + c.Assert(err, gc.ErrorMatches, regexp.QuoteMeta(`failed to download charm "cs:quantal/dummy-1" from API server: `)+`expected sha256 "...", got ".*"`) // Try to get a charm whose bundle doesn't exist. - gitjujutesting.Server.Responses(2, 404, nil, nil) - _, err = d.Read(apiCharm, nil) - c.Assert(err, gc.ErrorMatches, prefix+`.* 404 Not Found`) + otherURL := corecharm.MustParseURL("cs:quantal/spam-1") + _, err = d.Read(&fakeBundleInfo{apiCharm, otherURL, ""}, nil) + c.Assert(err, gc.ErrorMatches, regexp.QuoteMeta(`failed to download charm "cs:quantal/spam-1" from API server: `)+`.* not found`) // Get a charm whose bundle exists and whose content matches. - gitjujutesting.Server.Response(404, nil, nil) - gitjujutesting.Server.Response(200, nil, bundata) ch, err := d.Read(apiCharm, nil) c.Assert(err, jc.ErrorIsNil) assertCharm(c, ch, sch) @@ -160,7 +144,7 @@ go func() { ch, err := d.Read(apiCharm, abort) c.Assert(ch, gc.IsNil) - c.Assert(err, gc.ErrorMatches, prefix+"aborted") + c.Assert(err, gc.ErrorMatches, regexp.QuoteMeta(`failed to download charm "cs:quantal/dummy-1" from API server: aborted`)) close(done) }() close(abort) @@ -172,14 +156,6 @@ } } -func readHash(c *gc.C, path string) ([]byte, string) { - data, err := ioutil.ReadFile(path) - c.Assert(err, jc.ErrorIsNil) - hash := sha256.New() - hash.Write(data) - return data, hex.EncodeToString(hash.Sum(nil)) -} - func assertCharm(c *gc.C, bun charm.Bundle, sch *state.Charm) { actual := bun.(*corecharm.CharmArchive) c.Assert(actual.Revision(), gc.Equals, sch.Revision()) diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/charm/charm.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/charm/charm.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/charm/charm.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/charm/charm.go 2016-05-17 20:01:14.000000000 +0000 @@ -5,7 +5,6 @@ import ( "errors" - "net/url" "github.com/juju/loggo" "github.com/juju/utils" @@ -39,10 +38,6 @@ // URL returns the charm URL identifying the bundle. URL() *charm.URL - // ArchiveURLs returns the location(s) of the bundle data. ArchiveURLs - // may return multiple URLs; each should be tried until one succeeds. - ArchiveURLs() ([]*url.URL, error) - // ArchiveSha256 returns the hex-encoded SHA-256 digest of the bundle data. ArchiveSha256() (string, error) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/manifold.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/manifold.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/manifold.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/manifold.go 2016-05-17 20:01:14.000000000 +0000 @@ -10,7 +10,7 @@ "github.com/juju/utils/fslock" "github.com/juju/juju/agent" - "github.com/juju/juju/api/base" + "github.com/juju/juju/api" "github.com/juju/juju/api/uniter" "github.com/juju/juju/apiserver/params" "github.com/juju/juju/core/leadership" @@ -50,8 +50,8 @@ if err := context.Get(config.AgentName, &agent); err != nil { return nil, err } - var apiCaller base.APICaller - if err := context.Get(config.APICallerName, &apiCaller); err != nil { + var apiConn api.Connection + if err := context.Get(config.APICallerName, &apiConn); err != nil { // TODO(fwereade): absence of an APICaller shouldn't be the end of // the world -- we ought to return a type that can at least run the // leader-deposed hook -- but that's not done yet. @@ -75,6 +75,8 @@ return nil, err } + downloader := api.NewCharmDownloader(apiConn.Client()) + // Configure and start the uniter. config := agent.CurrentConfig() tag := config.Tag() @@ -82,12 +84,13 @@ if !ok { return nil, errors.Errorf("expected a unit tag, got %v", tag) } - uniterFacade := uniter.NewState(apiCaller, unitTag) + uniterFacade := uniter.NewState(apiConn, unitTag) uniter, err := NewUniter(&UniterParams{ UniterFacade: uniterFacade, UnitTag: unitTag, LeadershipTracker: leadershipTracker, DataDir: config.DataDir(), + Downloader: downloader, MachineLock: machineLock, CharmDirGuard: charmDirGuard, UpdateStatusSignal: NewUpdateStatusTimer(), diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/remotestate/watcher.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/remotestate/watcher.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/remotestate/watcher.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/remotestate/watcher.go 2016-05-17 20:01:14.000000000 +0000 @@ -109,7 +109,14 @@ snapshot := w.current snapshot.Relations = make(map[int]RelationSnapshot) for id, relationSnapshot := range w.current.Relations { - snapshot.Relations[id] = relationSnapshot + relationSnapshotCopy := RelationSnapshot{ + Life: relationSnapshot.Life, + Members: make(map[string]int64), + } + for name, version := range relationSnapshot.Members { + relationSnapshotCopy.Members[name] = version + } + snapshot.Relations[id] = relationSnapshotCopy } snapshot.Storage = make(map[names.StorageTag]StorageSnapshot) for tag, storageSnapshot := range w.current.Storage { @@ -411,13 +418,19 @@ return errors.Trace(err) } - case id := <-w.commandChannel: + case id, ok := <-w.commandChannel: + if !ok { + return errors.New("commandChannel closed") + } logger.Debugf("command enqueued: %v", id) if err := w.commandsChanged(id); err != nil { return err } - case <-w.retryHookChannel: + case _, ok := <-w.retryHookChannel: + if !ok { + return errors.New("retryHookChannel closed") + } logger.Debugf("retry hook timer triggered") if err := w.retryHookTimerTriggered(); err != nil { return err diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/remotestate/watcher_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/remotestate/watcher_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/remotestate/watcher_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/remotestate/watcher_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -499,6 +499,31 @@ ) } +func (s *WatcherSuite) TestRelationUnitsDontLeakReferences(c *gc.C) { + signalAll(s.st, s.leadership) + assertNotifyEvent(c, s.watcher.RemoteStateChanged(), "waiting for remote state change") + + relationTag := names.NewRelationTag("mysql:peer") + s.st.relations[relationTag] = &mockRelation{ + id: 123, life: params.Alive, + } + s.st.relationUnitsWatchers[relationTag] = newMockRelationUnitsWatcher() + + s.st.unit.service.relationsWatcher.changes <- []string{relationTag.Id()} + s.st.relationUnitsWatchers[relationTag].changes <- watcher.RelationUnitsChange{ + Changed: map[string]watcher.UnitSettings{"mysql/1": {1}}, + } + assertNotifyEvent(c, s.watcher.RemoteStateChanged(), "waiting for remote state change") + + snapshot := s.watcher.Snapshot() + snapshot.Relations[123].Members["pwned"] = 2600 + c.Assert( + s.watcher.Snapshot().Relations[123].Members, + jc.DeepEquals, + map[string]int64{"mysql/1": 1}, + ) +} + func (s *WatcherSuite) TestUpdateStatusTicker(c *gc.C) { signalAll(s.st, s.leadership) initial := s.watcher.Snapshot() diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/uniter.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/uniter.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/uniter.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/uniter.go 2016-05-17 20:01:14.000000000 +0000 @@ -98,6 +98,10 @@ // hookRetryStrategy represents configuration for hook retries hookRetryStrategy params.RetryStrategy + + // downloader is the downloader that should be used to get the charm + // archive. + downloader charm.Downloader } // UniterParams hold all the necessary parameters for a new Uniter. @@ -106,6 +110,7 @@ UnitTag names.UnitTag LeadershipTracker leadership.Tracker DataDir string + Downloader charm.Downloader MachineLock *fslock.Lock CharmDirGuard fortress.Guard UpdateStatusSignal func() <-chan time.Time @@ -135,6 +140,7 @@ newOperationExecutor: uniterParams.NewOperationExecutor, observer: uniterParams.Observer, clock: uniterParams.Clock, + downloader: uniterParams.Downloader, } err := catacomb.Invoke(catacomb.Plan{ Site: &u.catacomb, @@ -213,10 +219,9 @@ Clock: u.clock, }) defer func() { - // Stop any send that might be pending - // before closing the channel + // Whenever we exit the uniter we want to stop a potentially + // running timer so it doesn't trigger for nothing. retryHookTimer.Reset() - close(retryHookChan) }() restartWatcher := func() error { @@ -442,7 +447,7 @@ deployer, err := charm.NewDeployer( u.paths.State.CharmDir, u.paths.State.DeployerDir, - charm.NewBundlesDir(u.paths.State.BundlesDir), + charm.NewBundlesDir(u.paths.State.BundlesDir, u.downloader), ) if err != nil { return errors.Annotatef(err, "cannot create deployer") diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/uniter_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/uniter_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/uniter_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/uniter_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -173,7 +173,7 @@ createCharm{}, // don't serve charm createUniter{}, - waitUniterDead{err: `preparing operation "install cs:quantal/wordpress-0": failed to download charm .* 404 Not Found`}, + waitUniterDead{err: `preparing operation "install cs:quantal/wordpress-0": failed to download charm .* not found`}, ), }) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/util_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/util_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/uniter/util_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/uniter/util_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -31,6 +31,7 @@ corecharm "gopkg.in/juju/charm.v6-unstable" goyaml "gopkg.in/yaml.v2" + "github.com/juju/juju/api" apiuniter "github.com/juju/juju/api/uniter" "github.com/juju/juju/core/leadership" coreleadership "github.com/juju/juju/core/leadership" @@ -85,6 +86,7 @@ s *UniterSuite st *state.State api *apiuniter.State + apiConn api.Connection leaderClaimer coreleadership.Claimer leaderTracker *mockLeaderTracker charmDirGuard *mockCharmDirGuard @@ -150,12 +152,14 @@ c.Assert(err, jc.ErrorIsNil) err = ctx.unit.SetPassword(password) c.Assert(err, jc.ErrorIsNil) - st := ctx.s.OpenAPIAs(c, ctx.unit.Tag(), password) - c.Assert(st, gc.NotNil) + apiConn := ctx.s.OpenAPIAs(c, ctx.unit.Tag(), password) + c.Assert(apiConn, gc.NotNil) c.Logf("API: login as %q successful", ctx.unit.Tag()) - ctx.api, err = st.Uniter() + api, err := apiConn.Uniter() c.Assert(err, jc.ErrorIsNil) - c.Assert(ctx.api, gc.NotNil) + c.Assert(api, gc.NotNil) + ctx.api = api + ctx.apiConn = apiConn ctx.leaderClaimer = ctx.st.LeadershipClaimer() ctx.leaderTracker = newMockLeaderTracker(ctx) ctx.leaderTracker.setLeader(c, true) @@ -476,6 +480,7 @@ if err != nil { panic(err.Error()) } + downloader := api.NewCharmDownloader(ctx.apiConn.Client()) locksDir := filepath.Join(ctx.dataDir, "locks") lock, err := fslock.NewLock(locksDir, "uniter-hook-execution", fslock.Defaults()) c.Assert(err, jc.ErrorIsNil) @@ -490,6 +495,7 @@ LeadershipTracker: ctx.leaderTracker, CharmDirGuard: ctx.charmDirGuard, DataDir: ctx.dataDir, + Downloader: downloader, MachineLock: lock, UpdateStatusSignal: ctx.updateStatusHookTicker.ReturnTimer, NewOperationExecutor: operationExecutor, diff -Nru juju-core-2.0~beta6/src/github.com/juju/juju/worker/upgradesteps/worker_test.go juju-core-2.0~beta7/src/github.com/juju/juju/worker/upgradesteps/worker_test.go --- juju-core-2.0~beta6/src/github.com/juju/juju/worker/upgradesteps/worker_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/juju/worker/upgradesteps/worker_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -21,7 +21,7 @@ "github.com/juju/juju/constraints" "github.com/juju/juju/environs" "github.com/juju/juju/instance" - "github.com/juju/juju/mongo" + "github.com/juju/juju/mongo/mongotest" "github.com/juju/juju/state" "github.com/juju/juju/state/multiwatcher" statetesting "github.com/juju/juju/state/testing" @@ -409,7 +409,7 @@ func (s *UpgradeSuite) openStateForUpgrade() (*state.State, error) { mongoInfo := s.State.MongoConnectionInfo() - st, err := state.Open(s.State.ModelTag(), mongoInfo, mongo.DefaultDialOpts(), environs.NewStatePolicy()) + st, err := state.Open(s.State.ModelTag(), mongoInfo, mongotest.DialOpts(), environs.NewStatePolicy()) if err != nil { return nil, err } diff -Nru juju-core-2.0~beta6/src/github.com/juju/romulus/cmd/listplans/list_plans.go juju-core-2.0~beta7/src/github.com/juju/romulus/cmd/listplans/list_plans.go --- juju-core-2.0~beta6/src/github.com/juju/romulus/cmd/listplans/list_plans.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/romulus/cmd/listplans/list_plans.go 2016-05-17 20:01:14.000000000 +0000 @@ -54,7 +54,7 @@ } // NewListPlansCommand creates a new ListPlansCommand. -func NewListPlansCommand() cmd.Command { +func NewListPlansCommand() modelcmd.CommandBase { return &ListPlansCommand{ CharmResolver: rcmd.NewCharmStoreResolver(), } diff -Nru juju-core-2.0~beta6/src/github.com/juju/romulus/cmd/setplan/set_plan.go juju-core-2.0~beta7/src/github.com/juju/romulus/cmd/setplan/set_plan.go --- juju-core-2.0~beta6/src/github.com/juju/romulus/cmd/setplan/set_plan.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/romulus/cmd/setplan/set_plan.go 2016-05-17 20:01:14.000000000 +0000 @@ -71,7 +71,7 @@ // Init implements cmd.Command. func (c *setPlanCommand) Init(args []string) error { if len(args) < 2 { - return errors.New("need to specify plan uuid and service name") + return errors.New("need to specify service name and plan url") } serviceName := args[0] diff -Nru juju-core-2.0~beta6/src/github.com/juju/romulus/cmd/setplan/set_plan_test.go juju-core-2.0~beta7/src/github.com/juju/romulus/cmd/setplan/set_plan_test.go --- juju-core-2.0~beta6/src/github.com/juju/romulus/cmd/setplan/set_plan_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/romulus/cmd/setplan/set_plan_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -127,6 +127,11 @@ } } +func (s *setPlanCommandSuite) TestNoArgs(c *gc.C) { + _, err := cmdtesting.RunCommand(c, setplan.NewSetPlanCommand()) + c.Assert(err, gc.ErrorMatches, "need to specify service name and plan url") +} + func newMockAPI() (*mockapi, error) { kp, err := bakery.GenerateKey() if err != nil { diff -Nru juju-core-2.0~beta6/src/github.com/juju/testing/cmd.go juju-core-2.0~beta7/src/github.com/juju/testing/cmd.go --- juju-core-2.0~beta6/src/github.com/juju/testing/cmd.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/testing/cmd.go 2016-05-17 20:01:14.000000000 +0000 @@ -14,8 +14,9 @@ "strings" "github.com/juju/utils" - gc "gopkg.in/check.v1" + + jc "github.com/juju/testing/checkers" ) var HookChannelSize = 10 @@ -127,6 +128,7 @@ } } +// CleanupPatcher represents a value that can patch values for tests. type CleanupPatcher interface { PatchEnvironment(name, value string) AddCleanup(cleanup func(*gc.C)) @@ -141,7 +143,7 @@ setlocal enabledelayedexpansion echo failing exit /b %d - REM see %ERRORLEVEL% for last exit code like $? on linux + REM see %%ERRORLEVEL%% for last exit code like $? on linux `, exitCode) PatchExecutable(c, patcher, execName, script) default: @@ -197,3 +199,142 @@ content = []byte(strings.Join(lines[1:], "\n")) err = ioutil.WriteFile(execName+".out", content, 0644) // or just call this filename somewhere, once. } + +// PatchExecHelper is a type that helps you patch out calls to executables by +// patching out the exec.Command function that creates the exec.Cmd to call +// them. This is very similar to PatchExecutable above, except it works on +// windows exe files, is a lot easier to control stderr and stdout, doesn't +// require arcane bash and batch scripting, and lets you control both the output +// *and* test the arguments, all without requiring writing any garbage files to +// disk. +// +// PatchExecHelper *must* be embedded in your test suite in order to function. +// It adds a test to your testsuite which by default simply does nothing. When +// the patched exec.Command function is called (returned by GetExecCommand), +// instead of running the requested executable, we call the test executable with +// -check.f to rnu only TestExecSuiteHelperProcess, which acts as a configurable +// main function. +type PatchExecHelper struct{} + +// PatchExecConfig holds the arguments for PatchExecHelper.GetExecCommand. +type PatchExecConfig struct { + // Stderr is the value you'd like written to stderr. + Stderr string + // Stdout is the value you'd like written to stdout. + Stdout string + // ExitCode controls the exit code of the patched executable. + ExitCode int + // Args is a channel that will be sent the args passed to the patched + // execCommand function. It should be a channel with a buffer equal to the + // number of executions you expect to be run (often just 1). Do not use an + // unbuffered channel unless you're reading the channel from another + // goroutine, or you will almost certainly block your tests indefinitely. + Args chan<- []string +} + +// GetExecCommand returns a function that can be used to patch out a use of +// exec.Command. See PatchExecConfig for details about the arguments. +func (PatchExecHelper) GetExecCommand(cfg PatchExecConfig) func(string, ...string) *exec.Cmd { + // This method doesn't technically need to be a method on PatchExecHelper, + // but serves as a reminder to embed PatchExecHelper. + return func(command string, args ...string) *exec.Cmd { + // We redirect the command to call the test executable, telling it to + // run the TestExecSuiteHelperProcess test that got embedded into the + // test suite, and pass the original args at the end of our args. + // + // Note that we don't need to include the suite name in check.f, because + // even if you have more than one suite embedding PatchExecHelper, all + // the tests have the same imlpementation, and the first instance of the + // test to run calls os.Exit, and therefore none of the other tests will + // run. + cs := []string{"-check.f=TestExecSuiteHelperProcess", "--", command} + cs = append(cs, args...) + cmd := exec.Command(os.Args[0], cs...) + + cmd.Env = append( + // We must preserve os.Environ() on Windows, + // or the subprocess will fail in weird and + // wonderful ways. + os.Environ(), + "JUJU_WANT_HELPER_PROCESS=1", + "JUJU_HELPER_PROCESS_STDERR="+cfg.Stderr, + "JUJU_HELPER_PROCESS_STDOUT="+cfg.Stdout, + fmt.Sprintf("JUJU_HELPER_PROCESS_EXITCODE=%d", cfg.ExitCode), + ) + + // Pass the args back on the arg channel. This is why the channel needs + // to be buffered, so this won't block. + if cfg.Args != nil { + cfg.Args <- append([]string{command}, args...) + } + return cmd + } +} + +// TestExecSuiteHelperProcess is a fake test which is added to your test suite +// (because you remembered to embed PatchExecHelper in your suite, right?). It +// allows us to use the test executable as a helper process to get expected +// output for tests. When run normally during tests, this test simply does +// nothing (and passes). The above patched exec.Command runs the test +// executable with -check.f, it runs this test and enables the configurable +// behavior. Because the test exits with os.Exit, no additional test output is +// written. +func (PatchExecHelper) TestExecSuiteHelperProcess(c *gc.C) { + if os.Getenv("JUJU_WANT_HELPER_PROCESS") == "" { + return + } + if stderr := os.Getenv("JUJU_HELPER_PROCESS_STDERR"); stderr != "" { + fmt.Fprintln(os.Stderr, stderr) + } + if stdout := os.Getenv("JUJU_HELPER_PROCESS_STDOUT"); stdout != "" { + fmt.Fprintln(os.Stdout, stdout) + } + code := os.Getenv("JUJU_HELPER_PROCESS_EXITCODE") + if code == "" { + os.Exit(0) + } + exit, err := strconv.Atoi(code) + if err != nil { + // This should be impossible, since we set this with an int above. + panic(err) + } + os.Exit(exit) + +} + +// CaptureOutput runs the given function and captures anything written +// to Stderr or Stdout during f's execution. +func CaptureOutput(c *gc.C, f func()) (stdout []byte, stderr []byte) { + dir := c.MkDir() + stderrf, err := os.OpenFile(filepath.Join(dir, "stderr"), os.O_RDWR|os.O_CREATE, 0600) + c.Assert(err, jc.ErrorIsNil) + defer stderrf.Close() + + stdoutf, err := os.OpenFile(filepath.Join(dir, "stdout"), os.O_RDWR|os.O_CREATE, 0600) + c.Assert(err, jc.ErrorIsNil) + defer stdoutf.Close() + + // make a sub-functions so those defers go off ASAP. + func() { + origErr := os.Stderr + defer func() { os.Stderr = origErr }() + origOut := os.Stdout + defer func() { os.Stdout = origOut }() + os.Stderr = stderrf + os.Stdout = stdoutf + + f() + }() + + _, err = stderrf.Seek(0, 0) + c.Assert(err, jc.ErrorIsNil) + stderr, err = ioutil.ReadAll(stderrf) + c.Assert(err, jc.ErrorIsNil) + + _, err = stdoutf.Seek(0, 0) + c.Assert(err, jc.ErrorIsNil) + stdout, err = ioutil.ReadAll(stdoutf) + c.Assert(err, jc.ErrorIsNil) + + return stdout, stderr +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/testing/cmd_test.go juju-core-2.0~beta7/src/github.com/juju/testing/cmd_test.go --- juju-core-2.0~beta6/src/github.com/juju/testing/cmd_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/testing/cmd_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,6 +4,9 @@ package testing_test import ( + "bytes" + "fmt" + "os" "os/exec" "strings" @@ -70,9 +73,92 @@ c.Assert(output, gc.Equals, "failing") } +func (s *cmdSuite) TestCaptureOutput(c *gc.C) { + f := func() { + _, err := fmt.Fprint(os.Stderr, "this is stderr") + c.Assert(err, jc.ErrorIsNil) + _, err = fmt.Fprint(os.Stdout, "this is stdout") + c.Assert(err, jc.ErrorIsNil) + } + stdout, stderr := testing.CaptureOutput(c, f) + c.Check(string(stdout), gc.Equals, "this is stdout") + c.Check(string(stderr), gc.Equals, "this is stderr") +} + +var _ = gc.Suite(&ExecHelperSuite{}) + +type ExecHelperSuite struct { + testing.PatchExecHelper +} + +func (s *ExecHelperSuite) TestExecHelperError(c *gc.C) { + argChan := make(chan []string, 1) + + cfg := testing.PatchExecConfig{ + Stdout: "Hellooooo stdout!", + Stderr: "Hellooooo stderr!", + ExitCode: 55, + Args: argChan, + } + + f := s.GetExecCommand(cfg) + + stderr := &bytes.Buffer{} + stdout := &bytes.Buffer{} + cmd := f("echo", "hello world!") + cmd.Stderr = stderr + cmd.Stdout = stdout + err := cmd.Run() + c.Assert(err, gc.NotNil) + _, ok := err.(*exec.ExitError) + if !ok { + c.Errorf("Expected *exec.ExitError, but got %T", err) + } else { + c.Check(err.Error(), gc.Equals, "exit status 55") + } + c.Check(stderr.String(), gc.Equals, cfg.Stderr+"\n") + c.Check(stdout.String(), gc.Equals, cfg.Stdout+"\n") + + select { + case args := <-argChan: + c.Assert(args, gc.DeepEquals, []string{"echo", "hello world!"}) + default: + c.Fatalf("No arguments passed to output channel") + } +} + +func (s *ExecHelperSuite) TestExecHelper(c *gc.C) { + argChan := make(chan []string, 1) + + cfg := testing.PatchExecConfig{ + Stdout: "Hellooooo stdout!", + Stderr: "Hellooooo stderr!", + Args: argChan, + } + + f := s.GetExecCommand(cfg) + + stderr := &bytes.Buffer{} + stdout := &bytes.Buffer{} + cmd := f("echo", "hello world!") + cmd.Stderr = stderr + cmd.Stdout = stdout + err := cmd.Run() + c.Assert(err, jc.ErrorIsNil) + c.Check(stderr.String(), gc.Equals, cfg.Stderr+"\n") + c.Check(stdout.String(), gc.Equals, cfg.Stdout+"\n") + + select { + case args := <-argChan: + c.Assert(args, gc.DeepEquals, []string{"echo", "hello world!"}) + default: + c.Fatalf("No arguments passed to output channel") + } +} + func runCommand(c *gc.C, command string, args ...string) string { cmd := exec.Command(command, args...) out, err := cmd.CombinedOutput() - c.Assert(err, gc.IsNil) + c.Assert(err, jc.ErrorIsNil) return string(out) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/testing/home.go juju-core-2.0~beta7/src/github.com/juju/testing/home.go --- juju-core-2.0~beta6/src/github.com/juju/testing/home.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/testing/home.go 2016-05-17 20:01:14.000000000 +0000 @@ -10,6 +10,8 @@ "github.com/juju/utils" gc "gopkg.in/check.v1" + + jc "github.com/juju/testing/checkers" ) type TestFile struct { @@ -25,10 +27,11 @@ func MakeFakeHome(c *gc.C) *FakeHome { fakeHome := c.MkDir() - utils.SetHome(fakeHome) + err := utils.SetHome(fakeHome) + c.Assert(err, jc.ErrorIsNil) sshPath := filepath.Join(fakeHome, ".ssh") - err := os.Mkdir(sshPath, 0777) + err = os.Mkdir(sshPath, 0777) c.Assert(err, gc.IsNil) err = ioutil.WriteFile(filepath.Join(sshPath, "id_rsa"), []byte("private auth key\n"), 0600) c.Assert(err, gc.IsNil) @@ -114,7 +117,8 @@ home := utils.Home() s.Home = MakeFakeHome(c) s.AddCleanup(func(*gc.C) { - utils.SetHome(home) + err := utils.SetHome(home) + c.Assert(err, jc.ErrorIsNil) }) } diff -Nru juju-core-2.0~beta6/src/github.com/juju/testing/home_test.go juju-core-2.0~beta7/src/github.com/juju/testing/home_test.go --- juju-core-2.0~beta6/src/github.com/juju/testing/home_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/testing/home_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -30,7 +30,8 @@ func (s *fakeHomeSuite) SetUpTest(c *gc.C) { s.IsolationSuite.SetUpTest(c) - utils.SetHome("/tmp/tests") + err := utils.SetHome("/tmp/tests") + c.Assert(err, jc.ErrorIsNil) } func (s *fakeHomeSuite) TearDownSuite(c *gc.C) { diff -Nru juju-core-2.0~beta6/src/github.com/juju/utils/cache/cache.go juju-core-2.0~beta7/src/github.com/juju/utils/cache/cache.go --- juju-core-2.0~beta6/src/github.com/juju/utils/cache/cache.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/utils/cache/cache.go 2016-05-17 20:01:14.000000000 +0000 @@ -43,15 +43,9 @@ } // New returns a new Cache that will cache items for -// at most maxAge. +// at most maxAge. If maxAge is zero, items will +// never be cached. func New(maxAge time.Duration) *Cache { - // A maxAge is < 2ns then the expiry code will panic because the - // actual expiry time will be maxAge - a random value in the - // interval [0, maxAge/2). If maxAge is < 2ns then this requires - // a random interval in [0, 0) which causes a panic. - if maxAge < 2*time.Nanosecond { - maxAge = 2 * time.Nanosecond - } // The returned cache will have a zero-valued expire // time, so will expire immediately, causing the new // map to be created. @@ -105,6 +99,17 @@ // TODO consider caching cache misses. return nil, errgo.Mask(err, errgo.Any) } + if c.maxAge < 2*time.Nanosecond { + // If maxAge is < 2ns then the expiry code will panic because the + // actual expiry time will be maxAge - a random value in the + // interval [0, maxAge/2). If maxAge is < 2ns then this requires + // a random interval in [0, 0) which causes a panic. + // + // This value is so small that there's no need to cache anyway, + // which makes tests more obviously deterministic when using + // a zero expiry time. + return val, nil + } c.mu.Lock() defer c.mu.Unlock() // Add the new cache entry. Because it's quite likely that a diff -Nru juju-core-2.0~beta6/src/github.com/juju/utils/series/series_linux.go juju-core-2.0~beta7/src/github.com/juju/utils/series/series_linux.go --- juju-core-2.0~beta6/src/github.com/juju/utils/series/series_linux.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/utils/series/series_linux.go 2016-05-17 20:01:14.000000000 +0000 @@ -108,7 +108,9 @@ seriesInfo := strings.Split(parts[0], " ") seriesVersions[series] = seriesInfo[0] ubuntuSeries[series] = seriesInfo[0] + if len(seriesInfo) == 2 && seriesInfo[1] == "LTS" { + ubuntuLts[series] = true + } } - updateVersionSeries() return nil } diff -Nru juju-core-2.0~beta6/src/github.com/juju/utils/series/supportedseries.go juju-core-2.0~beta7/src/github.com/juju/utils/series/supportedseries.go --- juju-core-2.0~beta6/src/github.com/juju/utils/series/supportedseries.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/utils/series/supportedseries.go 2016-05-17 20:01:14.000000000 +0000 @@ -4,6 +4,7 @@ package series import ( + "sort" "sync" "github.com/juju/errors" @@ -103,6 +104,17 @@ "xenial": "16.04", } +// ubuntuLts provides a lookup for current LTS series. Like seriesVersions, +// the values here are current at the time of writing. On Ubuntu systems this +// map is updated by updateDistroInfo, using data from +// /usr/share/distro-info/ubuntu.csv to ensure we have the latest values. On +// non-Ubuntu systems, these values provide a nice fallback option. +var ubuntuLts = map[string]bool{ + "precise": true, + "trusty": true, + "xenial": true, +} + // Windows versions come in various flavors: // Standard, Datacenter, etc. We use string prefix match them to one // of the following. Specify the longest name in a particular series first @@ -237,6 +249,58 @@ return "", errors.Trace(unknownVersionSeriesError(version)) } +// SupportedLts are the current supported LTS series in ascending order. +func SupportedLts() []string { + seriesVersionsMutex.Lock() + defer seriesVersionsMutex.Unlock() + updateSeriesVersionsOnce() + + versions := []string{} + for k := range ubuntuLts { + versions = append(versions, ubuntuSeries[k]) + } + sort.Strings(versions) + sorted := []string{} + for _, v := range versions { + sorted = append(sorted, versionSeries[v]) + } + return sorted +} + +// latestLtsSeries is used to ensure we only do +// the work to determine the latest lts series once. +var latestLtsSeries string + +// LatestLts returns the LatestLtsSeries found in distro-info +func LatestLts() string { + seriesVersionsMutex.Lock() + defer seriesVersionsMutex.Unlock() + updateSeriesVersionsOnce() + + if latestLtsSeries != "" { + return latestLtsSeries + } + + var latest string + for k := range ubuntuLts { + if ubuntuSeries[k] > ubuntuSeries[latest] { + latest = k + } + } + latestLtsSeries = latest + return latest +} + +// SetLatestLtsForTesting is provided to allow tests to override the lts series +// used and decouple the tests from the host by avoiding calling out to +// distro-info. It returns the previous setting so that it may be set back to +// the original value by the caller. +func SetLatestLtsForTesting(series string) string { + old := latestLtsSeries + latestLtsSeries = series + return old +} + func updateVersionSeries() { versionSeries = reverseSeriesVersion() } @@ -282,7 +346,13 @@ func UpdateSeriesVersions() error { seriesVersionsMutex.Lock() defer seriesVersionsMutex.Unlock() - return updateLocalSeriesVersions() + err := updateLocalSeriesVersions() + if err != nil { + return err + } + updateVersionSeries() + latestLtsSeries = "" + return nil } var updatedseriesVersions bool @@ -292,6 +362,7 @@ if err := updateLocalSeriesVersions(); err != nil { logger.Warningf("failed to update distro info: %v", err) } + updateVersionSeries() updatedseriesVersions = true } } diff -Nru juju-core-2.0~beta6/src/github.com/juju/utils/series/supportedseries_test.go juju-core-2.0~beta7/src/github.com/juju/utils/series/supportedseries_test.go --- juju-core-2.0~beta6/src/github.com/juju/utils/series/supportedseries_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/utils/series/supportedseries_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -134,3 +134,34 @@ c.Assert(series.IsWindowsNano(t.series), gc.Equals, t.expected) } } + +func (s *supportedSeriesSuite) TestLatestLts(c *gc.C) { + table := []struct { + latest, want string + }{ + {"testseries", "testseries"}, + {"", "xenial"}, + } + for _, test := range table { + series.SetLatestLtsForTesting(test.latest) + got := series.LatestLts() + c.Assert(got, gc.Equals, test.want) + } +} +func (s *supportedSeriesSuite) TestSetLatestLtsForTesting(c *gc.C) { + table := []struct { + value, want string + }{ + {"1", "xenial"}, {"2", "1"}, {"3", "2"}, {"4", "3"}, + } + for _, test := range table { + got := series.SetLatestLtsForTesting(test.value) + c.Assert(got, gc.Equals, test.want) + } +} + +func (s *supportedSeriesSuite) TestSupportedLts(c *gc.C) { + got := series.SupportedLts() + want := []string{"precise", "trusty", "xenial"} + c.Assert(got, gc.DeepEquals, want) +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/utils/ssh/ssh.go juju-core-2.0~beta7/src/github.com/juju/utils/ssh/ssh.go --- juju-core-2.0~beta6/src/github.com/juju/utils/ssh/ssh.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/utils/ssh/ssh.go 2016-05-17 20:01:14.000000000 +0000 @@ -36,6 +36,9 @@ // knownHostsFile is a path to a file in which to save the host's // fingerprint. knownHostsFile string + // strictHostKeyChecking sets that the host being connected to must + // exist in the known_hosts file, and with a matching public key. + strictHostKeyChecking bool } // SetProxyCommand sets a command to execute to proxy traffic through. @@ -63,6 +66,13 @@ o.knownHostsFile = file } +// EnableStrictHostKeyChecking requires that the host being connected +// to must exist in the known_hosts file, and with a matching public +// key. +func (o *Options) EnableStrictHostKeyChecking() { + o.strictHostKeyChecking = true +} + // AllowPasswordAuthentication allows the SSH // client to prompt the user for a password. // diff -Nru juju-core-2.0~beta6/src/github.com/juju/utils/ssh/ssh_openssh.go juju-core-2.0~beta7/src/github.com/juju/utils/ssh/ssh_openssh.go --- juju-core-2.0~beta6/src/github.com/juju/utils/ssh/ssh_openssh.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/utils/ssh/ssh_openssh.go 2016-05-17 20:01:14.000000000 +0000 @@ -15,8 +15,6 @@ "github.com/juju/utils" ) -var opensshCommonOptions = []string{"-o", "StrictHostKeyChecking no"} - // default identities will not be attempted if // -i is specified and they are not explcitly // included. @@ -65,10 +63,12 @@ } func opensshOptions(options *Options, commandKind opensshCommandKind) []string { - args := append([]string{}, opensshCommonOptions...) if options == nil { options = &Options{} } + var args []string + + args = append(args, "-o", "StrictHostKeyChecking "+yesNo(options.strictHostKeyChecking)) if len(options.proxyCommand) > 0 { args = append(args, "-o", "ProxyCommand "+utils.CommandString(options.proxyCommand...)) } @@ -195,3 +195,10 @@ } return c.Process.Kill() } + +func yesNo(v bool) string { + if v { + return "yes" + } + return "no" +} diff -Nru juju-core-2.0~beta6/src/github.com/juju/utils/ssh/ssh_test.go juju-core-2.0~beta7/src/github.com/juju/utils/ssh/ssh_test.go --- juju-core-2.0~beta6/src/github.com/juju/utils/ssh/ssh_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/utils/ssh/ssh_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -122,6 +122,15 @@ ) } +func (s *SSHCommandSuite) TestCommandStrictHostKeyChecking(c *gc.C) { + var opts ssh.Options + opts.EnableStrictHostKeyChecking() + s.assertCommandArgs(c, s.commandOptions([]string{echoCommand, "123"}, &opts), + fmt.Sprintf("%s -o StrictHostKeyChecking yes -o PasswordAuthentication no -o ServerAliveInterval 30 localhost %s 123", + s.fakessh, echoCommand), + ) +} + func (s *SSHCommandSuite) TestCommandAllowPasswordAuthentication(c *gc.C) { var opts ssh.Options opts.AllowPasswordAuthentication() diff -Nru juju-core-2.0~beta6/src/github.com/juju/utils/tls_transport_go13.go juju-core-2.0~beta7/src/github.com/juju/utils/tls_transport_go13.go --- juju-core-2.0~beta6/src/github.com/juju/utils/tls_transport_go13.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/github.com/juju/utils/tls_transport_go13.go 2016-05-17 20:01:14.000000000 +0000 @@ -27,3 +27,34 @@ registerFileProtocol(transport) return transport } + +// knownGoodCipherSuites contains the list of secure cipher suites to use +// with tls.Config. This list currently differs from the list in crypto/tls by +// excluding all RC4 implementations, due to known security vulnerabilities in +// RC4 - CVE-2013-2566, CVE-2015-2808. We also exclude ciphersuites which do +// not provide forward secrecy. +var knownGoodCipherSuites = []uint16{ + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, +} + +// SecureTLSConfig returns a tls.Config that conforms to Juju's security +// standards, so as to avoid known security vulnerabilities in certain +// configurations. +// +// Currently it excludes RC4 implementations from the available ciphersuites, +// requires ciphersuites that provide forward secrecy, and sets the minimum TLS +// version to 1.2. +func SecureTLSConfig() *tls.Config { + return &tls.Config{ + CipherSuites: knownGoodCipherSuites, + MinVersion: tls.VersionTLS12, + } +} diff -Nru juju-core-2.0~beta6/src/gopkg.in/amz.v3/ec2/ec2test/instances.go juju-core-2.0~beta7/src/gopkg.in/amz.v3/ec2/ec2test/instances.go --- juju-core-2.0~beta6/src/gopkg.in/amz.v3/ec2/ec2test/instances.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/gopkg.in/amz.v3/ec2/ec2test/instances.go 2016-05-17 20:01:14.000000000 +0000 @@ -160,12 +160,7 @@ func (inst *Instance) matchAttr(attr, value string) (ok bool, err error) { if strings.HasPrefix(attr, "tag:") && len(attr) > 4 { filterTag := attr[4:] - for _, t := range inst.tags { - if filterTag == t.Key && t.Value == value { - return true, nil - } - } - return false, nil + return matchTag(inst.tags, filterTag, value), nil } switch attr { case "architecture": diff -Nru juju-core-2.0~beta6/src/gopkg.in/amz.v3/ec2/ec2test/reservations.go juju-core-2.0~beta7/src/gopkg.in/amz.v3/ec2/ec2test/reservations.go --- juju-core-2.0~beta6/src/gopkg.in/amz.v3/ec2/ec2test/reservations.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/gopkg.in/amz.v3/ec2/ec2test/reservations.go 2016-05-17 20:01:14.000000000 +0000 @@ -32,7 +32,14 @@ func (r *reservation) hasRunningMachine() bool { for _, inst := range r.instances { - if inst.state.Code != ShuttingDown.Code && inst.state.Code != Terminated.Code { + if inst.state == ShuttingDown { + // The instance is shutting down: tell the client that + // it's still running, but transition it to terminated + // so another query will not find it running. + inst.state = Terminated + return true + } + if inst.state != Terminated { return true } } diff -Nru juju-core-2.0~beta6/src/gopkg.in/amz.v3/ec2/ec2test/securty_groups.go juju-core-2.0~beta7/src/gopkg.in/amz.v3/ec2/ec2test/securty_groups.go --- juju-core-2.0~beta6/src/gopkg.in/amz.v3/ec2/ec2test/securty_groups.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/gopkg.in/amz.v3/ec2/ec2test/securty_groups.go 2016-05-17 20:01:14.000000000 +0000 @@ -33,6 +33,7 @@ vpcId string perms map[permKey]bool + tags []ec2.Tag } // securityGroupInfo is almost the same as ec2.SecurityGroupInfo, but @@ -131,6 +132,10 @@ case "vpc-id": return g.vpcId == value, nil } + if strings.HasPrefix(attr, "tag:") { + key := attr[len("tag:"):] + return matchTag(g.tags, key, value), nil + } return false, fmt.Errorf("unknown attribute %q", attr) } diff -Nru juju-core-2.0~beta6/src/gopkg.in/amz.v3/ec2/ec2test/tags.go juju-core-2.0~beta7/src/gopkg.in/amz.v3/ec2/ec2test/tags.go --- juju-core-2.0~beta6/src/gopkg.in/amz.v3/ec2/ec2test/tags.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/gopkg.in/amz.v3/ec2/ec2test/tags.go 2016-05-17 20:01:14.000000000 +0000 @@ -98,6 +98,10 @@ if inst, ok := srv.instances[id]; ok { return &inst.tags } + case "sg": + if group, ok := srv.groups[id]; ok { + return &group.tags + } case "vol": if vol, ok := srv.volumes[id]; ok { return &vol.Tags diff -Nru juju-core-2.0~beta6/src/gopkg.in/juju/charm.v6-unstable/actions.go juju-core-2.0~beta7/src/gopkg.in/juju/charm.v6-unstable/actions.go --- juju-core-2.0~beta6/src/gopkg.in/juju/charm.v6-unstable/actions.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/gopkg.in/juju/charm.v6-unstable/actions.go 2016-05-17 20:01:14.000000000 +0000 @@ -109,6 +109,12 @@ if valid := actionNameRule.MatchString(name); !valid { return nil, fmt.Errorf("bad action name %s", name) } + if reserved, reason := reservedName(name); reserved { + return nil, fmt.Errorf( + "cannot use action name %s: %s", + name, reason, + ) + } desc := "No description" thisActionSchema := map[string]interface{}{ diff -Nru juju-core-2.0~beta6/src/gopkg.in/juju/charm.v6-unstable/actions_test.go juju-core-2.0~beta7/src/gopkg.in/juju/charm.v6-unstable/actions_test.go --- juju-core-2.0~beta6/src/gopkg.in/juju/charm.v6-unstable/actions_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/gopkg.in/juju/charm.v6-unstable/actions_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -573,6 +573,20 @@ expectedError: "bad action name Snapshot", }, { + description: `Reserved Action Name: "juju".`, + yaml: ` +juju: + description: A reserved action. +`, + expectedError: `cannot use action name juju: "juju" is a reserved name`, + }, { + description: `Reserved Action Name: "juju-run".`, + yaml: ` +juju-run: + description: A reserved action. +`, + expectedError: `cannot use action name juju-run: the "juju-" prefix is reserved`, + }, { description: "A non-string description fails to parse", yaml: ` snapshot: diff -Nru juju-core-2.0~beta6/src/gopkg.in/juju/charm.v6-unstable/internal/test-charm-repo/quantal/terms/metadata.yaml juju-core-2.0~beta7/src/gopkg.in/juju/charm.v6-unstable/internal/test-charm-repo/quantal/terms/metadata.yaml --- juju-core-2.0~beta6/src/gopkg.in/juju/charm.v6-unstable/internal/test-charm-repo/quantal/terms/metadata.yaml 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/gopkg.in/juju/charm.v6-unstable/internal/test-charm-repo/quantal/terms/metadata.yaml 2016-05-17 20:01:14.000000000 +0000 @@ -2,4 +2,4 @@ summary: "Sample charm with terms and conditions" description: | That's a boring charm that requires certain terms. -terms: ["term1", "term2"] +terms: ["term1/1", "term2"] diff -Nru juju-core-2.0~beta6/src/gopkg.in/juju/charm.v6-unstable/meta.go juju-core-2.0~beta7/src/gopkg.in/juju/charm.v6-unstable/meta.go --- juju-core-2.0~beta6/src/gopkg.in/juju/charm.v6-unstable/meta.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/gopkg.in/juju/charm.v6-unstable/meta.go 2016-05-17 20:01:14.000000000 +0000 @@ -243,7 +243,7 @@ return result } -var termNameRE = regexp.MustCompile("^[a-z]+([a-z0-9-]+)/[0-9]+?$") +var termNameRE = regexp.MustCompile("^[a-z]+([a-z0-9-]+)(/[0-9]+)?$") func checkTerm(s string) error { match := termNameRE.FindStringSubmatch(s) @@ -463,12 +463,12 @@ // Container-scoped require relations on subordinates are allowed // to use the otherwise-reserved juju-* namespace. if !meta.Subordinate || role != RoleRequirer || rel.Scope != ScopeContainer { - if reservedName(name) { + if reserved, _ := reservedName(name); reserved { return fmt.Errorf("charm %q using a reserved relation name: %q", meta.Name, name) } } if role != RoleRequirer { - if reservedName(rel.Interface) { + if reserved, _ := reservedName(rel.Interface); reserved { return fmt.Errorf("charm %q relation %q using a reserved interface: %q", meta.Name, name, rel.Interface) } } @@ -552,15 +552,21 @@ for _, term := range meta.Terms { if terr := checkTerm(term); terr != nil { - return terr + return errors.Trace(terr) } } return nil } -func reservedName(name string) bool { - return name == "juju" || strings.HasPrefix(name, "juju-") +func reservedName(name string) (reserved bool, reason string) { + if name == "juju" { + return true, `"juju" is a reserved name` + } + if strings.HasPrefix(name, "juju-") { + return true, `the "juju-" prefix is reserved` + } + return false, "" } func parseRelations(relations interface{}, role RelationRole) map[string]Relation { diff -Nru juju-core-2.0~beta6/src/gopkg.in/juju/charm.v6-unstable/meta_test.go juju-core-2.0~beta7/src/gopkg.in/juju/charm.v6-unstable/meta_test.go --- juju-core-2.0~beta6/src/gopkg.in/juju/charm.v6-unstable/meta_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/gopkg.in/juju/charm.v6-unstable/meta_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -64,16 +64,16 @@ expectError string }{{ about: "valid terms", - terms: []string{"term/1", "term/2"}, - }, { - about: "missing revision number", - terms: []string{"term/1", "term"}, - expectError: "invalid term name \"term\": must match.*", + terms: []string{"term/1", "term/2", "term-without-revision"}, }, { about: "revision not a number", terms: []string{"term/1", "term/a"}, expectError: "invalid term name \"term/a\": must match.*", }, { + about: "negative revision", + terms: []string{"term/-1"}, + expectError: "invalid term name \"term/-1\": must match.*", + }, { about: "wrong format", terms: []string{"term/1", "term/a/1"}, expectError: "invalid term name \"term/a/1\": must match.*", @@ -111,8 +111,10 @@ func (s *MetaSuite) TestReadTerms(c *gc.C) { meta, err := charm.ReadMeta(repoMeta(c, "terms")) - c.Assert(err, gc.IsNil) - c.Assert(meta.Terms, jc.DeepEquals, []string{"term1", "term2"}) + c.Assert(err, jc.ErrorIsNil) + err = meta.Check() + c.Assert(err, jc.ErrorIsNil) + c.Assert(meta.Terms, jc.DeepEquals, []string{"term1/1", "term2"}) } func (s *MetaSuite) TestReadTags(c *gc.C) { diff -Nru juju-core-2.0~beta6/src/gopkg.in/macaroon-bakery.v1/bakery/checkers/checkers.go juju-core-2.0~beta7/src/gopkg.in/macaroon-bakery.v1/bakery/checkers/checkers.go --- juju-core-2.0~beta6/src/gopkg.in/macaroon-bakery.v1/bakery/checkers/checkers.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/gopkg.in/macaroon-bakery.v1/bakery/checkers/checkers.go 2016-05-17 20:01:14.000000000 +0000 @@ -273,7 +273,43 @@ return firstParty(cond, strings.Join(op, " ")) } -// OperationChecker checks any allow or deny caveats ensuring they do not +// OperationsChecker checks any allow or deny caveats +// with respect to all the named operations in the slice. +// An allow caveat must allow all the operations in the +// slice; a deny caveat will fail if it denies any operation in the +// slice. +type OperationsChecker []string + +// Condition implements Checker.Condition. +func (OperationsChecker) Condition() string { + return "" +} + +// Check implements Checker.Check. +func (os OperationsChecker) Check(cond, arg string) error { + if len(os) == 0 { + switch cond { + case CondDeny: + return nil + case CondAllow: + f := strings.Fields(arg) + if len(f) == 0 { + return errgo.New("no operations allowed") + } + return errgo.Newf("%s not allowed", f[0]) + default: + return ErrCaveatNotRecognized + } + } + for _, o := range os { + if err := OperationChecker(o).Check(cond, arg); err != nil { + return errgo.Mask(err, errgo.Is(ErrCaveatNotRecognized)) + } + } + return nil +} + +// OperationChecker checks any allow or deny caveats, ensuring they do not // prohibit the named operation. type OperationChecker string diff -Nru juju-core-2.0~beta6/src/gopkg.in/macaroon-bakery.v1/bakery/checkers/checkers_test.go juju-core-2.0~beta7/src/gopkg.in/macaroon-bakery.v1/bakery/checkers/checkers_test.go --- juju-core-2.0~beta6/src/gopkg.in/macaroon-bakery.v1/bakery/checkers/checkers_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/gopkg.in/macaroon-bakery.v1/bakery/checkers/checkers_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -479,6 +479,62 @@ } } +var operationsCheckerTests = []struct { + about string + caveat checkers.Caveat + oc checkers.OperationsChecker + expectError string +}{{ + about: "all allowed", + caveat: checkers.AllowCaveat("op1", "op2", "op4", "op3"), + oc: checkers.OperationsChecker{"op1", "op3", "op2"}, +}, { + about: "none denied", + caveat: checkers.DenyCaveat("op1", "op2"), + oc: checkers.OperationsChecker{"op3", "op4"}, +}, { + about: "one not allowed", + caveat: checkers.AllowCaveat("op1", "op2"), + oc: checkers.OperationsChecker{"op1", "op3"}, + expectError: `op3 not allowed`, +}, { + about: "one denied", + caveat: checkers.DenyCaveat("op1", "op2"), + oc: checkers.OperationsChecker{"op4", "op5", "op2"}, + expectError: `op2 not allowed`, +}, { + about: "no operations, allow caveat", + caveat: checkers.AllowCaveat("op1"), + oc: checkers.OperationsChecker{}, + expectError: `op1 not allowed`, +}, { + about: "no operations, deny caveat", + caveat: checkers.DenyCaveat("op1"), + oc: checkers.OperationsChecker{}, +}, { + about: "no operations, empty allow caveat", + caveat: checkers.Caveat{ + Condition: checkers.CondAllow, + }, + oc: checkers.OperationsChecker{}, + expectError: `no operations allowed`, +}} + +func (*CheckersSuite) TestOperationsChecker(c *gc.C) { + for i, test := range operationsCheckerTests { + c.Logf("%d: %s", i, test.about) + cond, arg, err := checkers.ParseCaveat(test.caveat.Condition) + c.Assert(err, gc.IsNil) + c.Assert(test.oc.Condition(), gc.Equals, "") + err = test.oc.Check(cond, arg) + if test.expectError == "" { + c.Assert(err, gc.IsNil) + continue + } + c.Assert(err, gc.ErrorMatches, test.expectError) + } +} + var operationErrorCaveatTests = []struct { about string caveat checkers.Caveat diff -Nru juju-core-2.0~beta6/src/gopkg.in/macaroon-bakery.v1/httpbakery/client.go juju-core-2.0~beta7/src/gopkg.in/macaroon-bakery.v1/httpbakery/client.go --- juju-core-2.0~beta6/src/gopkg.in/macaroon-bakery.v1/httpbakery/client.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/gopkg.in/macaroon-bakery.v1/httpbakery/client.go 2016-05-17 20:01:14.000000000 +0000 @@ -260,6 +260,14 @@ if err := c.setRequestBody(req, body); err != nil { return nil, errgo.Mask(err) } + // Ensure that the request body (which will always be *readStopper) is + // closed before doWithBody returns. This means that even when + // the net/http code continues to read from the body after + // the Do returns, it'll be thwarted by our readStopper so + // allowing the caller to close the body without a race. + // See http://golang.org/issue/12796. + defer c.closeRequestBody(req) + req.Header.Set(BakeryProtocolHeader, fmt.Sprint(latestVersion)) httpResp, err := c.Client.Do(req) if err != nil { @@ -286,6 +294,12 @@ return hresp, nil } +func (c *Client) closeRequestBody(req *http.Request) { + if req.Body != nil { + req.Body.Close() + } +} + // HandleError tries to resolve the given error, which should be a // response to the given URL, by discharging any macaroon contained in // it. That is, if the error cause is an *Error and its code is @@ -372,6 +386,7 @@ return nil } if req.Body != nil { + // Close the old readStopper. req.Body.Close() if _, err := body.Seek(0, 0); err != nil { return errgo.Notef(err, "cannot seek to start of request body") @@ -403,7 +418,13 @@ r.mu.Lock() defer r.mu.Unlock() if r.r == nil { - return 0, errClosed + // Note: we have to use io.EOF here because otherwise + // another connection can (in rare circumstances) be + // polluted by the error returned here. Although this + // means the file may appear truncated to the server, + // that shouldn't matter because the body will only + // be closed after the server has replied. + return 0, io.EOF } return r.r.Read(buf) } diff -Nru juju-core-2.0~beta6/src/gopkg.in/macaroon-bakery.v1/httpbakery/client_test.go juju-core-2.0~beta7/src/gopkg.in/macaroon-bakery.v1/httpbakery/client_test.go --- juju-core-2.0~beta6/src/gopkg.in/macaroon-bakery.v1/httpbakery/client_test.go 2016-04-26 16:05:18.000000000 +0000 +++ juju-core-2.0~beta7/src/gopkg.in/macaroon-bakery.v1/httpbakery/client_test.go 2016-05-17 20:01:14.000000000 +0000 @@ -119,8 +119,9 @@ svc := newService("loc", d) ts := httptest.NewServer(serverHandler(serverHandlerParams{ - service: svc, - authLocation: d.Location(), + service: svc, + authLocation: d.Location(), + alwaysReadBody: true, })) defer ts.Close() @@ -176,8 +177,12 @@ req, err := http.NewRequest("POST", ts.URL+"/no-body", nil) c.Assert(err, gc.IsNil) - resp, err := httpbakery.NewClient().DoWithBody(req, &largeReader{total: 3 * 1024 * 1024}) + body := &largeReader{total: 3 * 1024 * 1024} + resp, err := httpbakery.NewClient().DoWithBody(req, body) c.Assert(err, gc.IsNil) + resp.Body.Close() + body.Close() + c.Assert(resp.StatusCode, gc.Equals, http.StatusOK) } @@ -204,6 +209,15 @@ return 0, nil } +func (r *largeReader) Close() error { + // By setting n to zero, we ensure that if there's + // a concurrent read, it will also read from n + // and so the race detector should pick up the + // problem. + r.n = 0 + return nil +} + func (s *ClientSuite) TestDoWithBodyFailsWithBodyInRequest(c *gc.C) { body := strings.NewReader("foo") // Create a client request. @@ -1017,6 +1031,10 @@ // If caveats is non-nil, it is called to get caveats to // add to the returned macaroon. caveats func() []checkers.Caveat + + // alwaysReadBody specifies whether the handler should always read + // the entire request body before returning. + alwaysReadBody bool } // serverHandler returns an HTTP handler that checks macaroon authorization @@ -1028,6 +1046,9 @@ hp.checker = isChecker("something") } h := handleErrors(func(p httprequest.Params) error { + if hp.alwaysReadBody { + defer ioutil.ReadAll(p.Request.Body) + } if _, checkErr := httpbakery.CheckRequest(hp.service, p.Request, nil, hp.checker); checkErr != nil { return newDischargeRequiredError(hp, checkErr, p.Request) }