backend/azurerm: upgrading the SDK / support for proxies (#19414)
* vendor updates - updating to v21.3.0 of github.com/Azure/azure-sdk-for-go - updating to v10.15.4 of github.com/Azure/go-autorest - vendoring github.com/hashicorp/go-azure-helpers @ 0.1.1 * backend/azurerm: refactoring to use the new auth package - refactoring the backend to use a shared client via the new auth package - adding tests covering both Service Principal and Access Key auth - support for authenticating using a proxy - rewriting the backend documentation to include examples of both authentication types * switching to use the build-in logging function * documenting it's also possible to retrieve the access key from an env var
This commit is contained in:
parent
7d5db9522f
commit
0ec109bdc0
|
@ -0,0 +1,131 @@
|
|||
package azure
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/profiles/2017-03-09/resources/mgmt/resources"
|
||||
armStorage "github.com/Azure/azure-sdk-for-go/profiles/2017-03-09/storage/mgmt/storage"
|
||||
"github.com/Azure/azure-sdk-for-go/storage"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/hashicorp/go-azure-helpers/authentication"
|
||||
"github.com/hashicorp/terraform/httpclient"
|
||||
)
|
||||
|
||||
type ArmClient struct {
|
||||
// These Clients are only initialized if an Access Key isn't provided
|
||||
groupsClient *resources.GroupsClient
|
||||
storageAccountsClient *armStorage.AccountsClient
|
||||
|
||||
accessKey string
|
||||
environment azure.Environment
|
||||
resourceGroupName string
|
||||
storageAccountName string
|
||||
}
|
||||
|
||||
func buildArmClient(config BackendConfig) (*ArmClient, error) {
|
||||
env, err := authentication.DetermineEnvironment(config.Environment)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client := ArmClient{
|
||||
environment: *env,
|
||||
resourceGroupName: config.ResourceGroupName,
|
||||
storageAccountName: config.StorageAccountName,
|
||||
}
|
||||
|
||||
// if we have an Access Key - we don't need the other clients
|
||||
if config.AccessKey != "" {
|
||||
client.accessKey = config.AccessKey
|
||||
return &client, nil
|
||||
}
|
||||
|
||||
builder := authentication.Builder{
|
||||
ClientID: config.ClientID,
|
||||
ClientSecret: config.ClientSecret,
|
||||
SubscriptionID: config.SubscriptionID,
|
||||
TenantID: config.TenantID,
|
||||
Environment: config.Environment,
|
||||
|
||||
// Feature Toggles
|
||||
SupportsClientSecretAuth: true,
|
||||
// TODO: support for Azure CLI / Client Certificate / MSI
|
||||
}
|
||||
armConfig, err := builder.Build()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error building ARM Config: %+v", err)
|
||||
}
|
||||
|
||||
oauthConfig, err := adal.NewOAuthConfig(env.ActiveDirectoryEndpoint, armConfig.TenantID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
auth, err := armConfig.GetAuthorizationToken(oauthConfig, env.ResourceManagerEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
accountsClient := armStorage.NewAccountsClientWithBaseURI(env.ResourceManagerEndpoint, armConfig.SubscriptionID)
|
||||
client.configureClient(&accountsClient.Client, auth)
|
||||
client.storageAccountsClient = &accountsClient
|
||||
|
||||
groupsClient := resources.NewGroupsClientWithBaseURI(env.ResourceManagerEndpoint, armConfig.SubscriptionID)
|
||||
client.configureClient(&groupsClient.Client, auth)
|
||||
client.groupsClient = &groupsClient
|
||||
|
||||
return &client, nil
|
||||
}
|
||||
|
||||
func (c ArmClient) getBlobClient(ctx context.Context) (*storage.BlobStorageClient, error) {
|
||||
if c.accessKey != "" {
|
||||
storageClient, err := storage.NewBasicClientOnSovereignCloud(c.storageAccountName, c.accessKey, c.environment)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error creating storage client for storage account %q: %s", c.storageAccountName, err)
|
||||
}
|
||||
client := storageClient.GetBlobService()
|
||||
return &client, nil
|
||||
}
|
||||
|
||||
keys, err := c.storageAccountsClient.ListKeys(ctx, c.resourceGroupName, c.storageAccountName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error retrieving keys for Storage Account %q: %s", c.storageAccountName, err)
|
||||
}
|
||||
|
||||
if keys.Keys == nil {
|
||||
return nil, fmt.Errorf("Nil key returned for storage account %q", c.storageAccountName)
|
||||
}
|
||||
|
||||
accessKeys := *keys.Keys
|
||||
accessKey := accessKeys[0].Value
|
||||
|
||||
storageClient, err := storage.NewBasicClientOnSovereignCloud(c.storageAccountName, *accessKey, c.environment)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error creating storage client for storage account %q: %s", c.storageAccountName, err)
|
||||
}
|
||||
client := storageClient.GetBlobService()
|
||||
return &client, nil
|
||||
}
|
||||
|
||||
func (c *ArmClient) configureClient(client *autorest.Client, auth autorest.Authorizer) {
|
||||
client.UserAgent = buildUserAgent()
|
||||
client.Authorizer = auth
|
||||
client.Sender = buildSender()
|
||||
client.SkipResourceProviderRegistration = false
|
||||
client.PollingDuration = 60 * time.Minute
|
||||
}
|
||||
|
||||
func buildUserAgent() string {
|
||||
userAgent := httpclient.UserAgentString()
|
||||
|
||||
// append the CloudShell version to the user agent if it exists
|
||||
if azureAgent := os.Getenv("AZURE_HTTP_USER_AGENT"); azureAgent != "" {
|
||||
userAgent = fmt.Sprintf("%s %s", userAgent, azureAgent)
|
||||
}
|
||||
|
||||
return userAgent
|
||||
}
|
|
@ -4,17 +4,11 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
armStorage "github.com/Azure/azure-sdk-for-go/arm/storage"
|
||||
"github.com/Azure/azure-sdk-for-go/storage"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
|
||||
"github.com/hashicorp/terraform/backend"
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
)
|
||||
|
||||
// New creates a new backend for S3 remote state.
|
||||
// New creates a new backend for Azure remote state.
|
||||
func New() backend.Backend {
|
||||
s := &schema.Backend{
|
||||
Schema: map[string]*schema.Schema{
|
||||
|
@ -40,7 +34,7 @@ func New() backend.Backend {
|
|||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "The Azure cloud environment.",
|
||||
DefaultFunc: schema.EnvDefaultFunc("ARM_ENVIRONMENT", ""),
|
||||
DefaultFunc: schema.EnvDefaultFunc("ARM_ENVIRONMENT", "public"),
|
||||
},
|
||||
|
||||
"access_key": {
|
||||
|
@ -83,6 +77,9 @@ func New() backend.Backend {
|
|||
Description: "The Tenant ID.",
|
||||
DefaultFunc: schema.EnvDefaultFunc("ARM_TENANT_ID", ""),
|
||||
},
|
||||
|
||||
// TODO: rename these fields
|
||||
// TODO: support for custom resource manager endpoints
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -95,22 +92,23 @@ type Backend struct {
|
|||
*schema.Backend
|
||||
|
||||
// The fields below are set from configure
|
||||
blobClient storage.BlobStorageClient
|
||||
|
||||
armClient *ArmClient
|
||||
containerName string
|
||||
keyName string
|
||||
leaseID string
|
||||
}
|
||||
|
||||
type BackendConfig struct {
|
||||
AccessKey string
|
||||
Environment string
|
||||
ClientID string
|
||||
ClientSecret string
|
||||
ResourceGroupName string
|
||||
// Required
|
||||
StorageAccountName string
|
||||
SubscriptionID string
|
||||
TenantID string
|
||||
|
||||
// Optional
|
||||
AccessKey string
|
||||
ClientID string
|
||||
ClientSecret string
|
||||
Environment string
|
||||
ResourceGroupName string
|
||||
SubscriptionID string
|
||||
TenantID string
|
||||
}
|
||||
|
||||
func (b *Backend) configure(ctx context.Context) error {
|
||||
|
@ -135,92 +133,15 @@ func (b *Backend) configure(ctx context.Context) error {
|
|||
TenantID: data.Get("arm_tenant_id").(string),
|
||||
}
|
||||
|
||||
blobClient, err := getBlobClient(config)
|
||||
armClient, err := buildArmClient(config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.blobClient = blobClient
|
||||
|
||||
if config.AccessKey == "" && config.ResourceGroupName == "" {
|
||||
return fmt.Errorf("Either an Access Key or the Resource Group for the Storage Account must be specified")
|
||||
}
|
||||
|
||||
b.armClient = armClient
|
||||
return nil
|
||||
}
|
||||
|
||||
func getBlobClient(config BackendConfig) (storage.BlobStorageClient, error) {
|
||||
var client storage.BlobStorageClient
|
||||
|
||||
env, err := getAzureEnvironment(config.Environment)
|
||||
if err != nil {
|
||||
return client, err
|
||||
}
|
||||
|
||||
accessKey, err := getAccessKey(config, env)
|
||||
if err != nil {
|
||||
return client, err
|
||||
}
|
||||
|
||||
storageClient, err := storage.NewClient(config.StorageAccountName, accessKey, env.StorageEndpointSuffix,
|
||||
storage.DefaultAPIVersion, true)
|
||||
if err != nil {
|
||||
return client, fmt.Errorf("Error creating storage client for storage account %q: %s", config.StorageAccountName, err)
|
||||
}
|
||||
|
||||
client = storageClient.GetBlobService()
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func getAccessKey(config BackendConfig, env azure.Environment) (string, error) {
|
||||
if config.AccessKey != "" {
|
||||
return config.AccessKey, nil
|
||||
}
|
||||
|
||||
rgOk := config.ResourceGroupName != ""
|
||||
subOk := config.SubscriptionID != ""
|
||||
clientIDOk := config.ClientID != ""
|
||||
clientSecretOK := config.ClientSecret != ""
|
||||
tenantIDOk := config.TenantID != ""
|
||||
if !rgOk || !subOk || !clientIDOk || !clientSecretOK || !tenantIDOk {
|
||||
return "", fmt.Errorf("resource_group_name and credentials must be provided when access_key is absent")
|
||||
}
|
||||
|
||||
oauthConfig, err := adal.NewOAuthConfig(env.ActiveDirectoryEndpoint, config.TenantID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
spt, err := adal.NewServicePrincipalToken(*oauthConfig, config.ClientID, config.ClientSecret, env.ResourceManagerEndpoint)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
accountsClient := armStorage.NewAccountsClientWithBaseURI(env.ResourceManagerEndpoint, config.SubscriptionID)
|
||||
accountsClient.Authorizer = autorest.NewBearerAuthorizer(spt)
|
||||
|
||||
keys, err := accountsClient.ListKeys(config.ResourceGroupName, config.StorageAccountName)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Error retrieving keys for storage account %q: %s", config.StorageAccountName, err)
|
||||
}
|
||||
|
||||
if keys.Keys == nil {
|
||||
return "", fmt.Errorf("Nil key returned for storage account %q", config.StorageAccountName)
|
||||
}
|
||||
|
||||
accessKeys := *keys.Keys
|
||||
return *accessKeys[0].Value, nil
|
||||
}
|
||||
|
||||
func getAzureEnvironment(environment string) (azure.Environment, error) {
|
||||
if environment == "" {
|
||||
return azure.PublicCloud, nil
|
||||
}
|
||||
|
||||
env, err := azure.EnvironmentFromName(environment)
|
||||
if err != nil {
|
||||
// try again with wrapped value to support readable values like german instead of AZUREGERMANCLOUD
|
||||
var innerErr error
|
||||
env, innerErr = azure.EnvironmentFromName(fmt.Sprintf("AZURE%sCLOUD", environment))
|
||||
if innerErr != nil {
|
||||
return env, fmt.Errorf("invalid 'environment' configuration: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
return env, nil
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package azure
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/storage"
|
||||
|
||||
"github.com/hashicorp/terraform/backend"
|
||||
"github.com/hashicorp/terraform/state"
|
||||
"github.com/hashicorp/terraform/state/remote"
|
||||
|
@ -25,7 +25,12 @@ func (b *Backend) Workspaces() ([]string, error) {
|
|||
Prefix: prefix,
|
||||
}
|
||||
|
||||
container := b.blobClient.GetContainerReference(b.containerName)
|
||||
ctx := context.TODO()
|
||||
client, err := b.armClient.getBlobClient(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
container := client.GetContainerReference(b.containerName)
|
||||
resp, err := container.ListBlobs(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -58,7 +63,13 @@ func (b *Backend) DeleteWorkspace(name string) error {
|
|||
return fmt.Errorf("can't delete default state")
|
||||
}
|
||||
|
||||
containerReference := b.blobClient.GetContainerReference(b.containerName)
|
||||
ctx := context.TODO()
|
||||
client, err := b.armClient.getBlobClient(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
containerReference := client.GetContainerReference(b.containerName)
|
||||
blobReference := containerReference.GetBlobReference(b.path(name))
|
||||
options := &storage.DeleteBlobOptions{}
|
||||
|
||||
|
@ -66,8 +77,14 @@ func (b *Backend) DeleteWorkspace(name string) error {
|
|||
}
|
||||
|
||||
func (b *Backend) StateMgr(name string) (state.State, error) {
|
||||
ctx := context.TODO()
|
||||
blobClient, err := b.armClient.getBlobClient(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := &RemoteClient{
|
||||
blobClient: b.blobClient,
|
||||
blobClient: *blobClient,
|
||||
containerName: b.containerName,
|
||||
keyName: b.path(name),
|
||||
}
|
||||
|
|
|
@ -1,29 +1,14 @@
|
|||
package azure
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/arm/resources/resources"
|
||||
armStorage "github.com/Azure/azure-sdk-for-go/arm/storage"
|
||||
"github.com/Azure/azure-sdk-for-go/storage"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/hashicorp/terraform/backend"
|
||||
"github.com/hashicorp/terraform/helper/acctest"
|
||||
)
|
||||
|
||||
// verify that we are doing ACC tests or the Azure tests specifically
|
||||
func testACC(t *testing.T) {
|
||||
skip := os.Getenv("TF_ACC") == "" && os.Getenv("TF_AZURE_TEST") == ""
|
||||
if skip {
|
||||
t.Log("azure backend tests require setting TF_ACC or TF_AZURE_TEST")
|
||||
t.Skip()
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackend_impl(t *testing.T) {
|
||||
var _ backend.Backend = new(Backend)
|
||||
}
|
||||
|
@ -50,183 +35,129 @@ func TestBackendConfig(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBackend(t *testing.T) {
|
||||
testACC(t)
|
||||
func TestBackendAccessKeyBasic(t *testing.T) {
|
||||
testAccAzureBackend(t)
|
||||
rs := acctest.RandString(4)
|
||||
res := testResourceNames(rs, "testState")
|
||||
armClient := buildTestClient(t, res)
|
||||
|
||||
keyName := "testState"
|
||||
res := setupResources(t, keyName)
|
||||
defer destroyResources(t, res.resourceGroupName)
|
||||
ctx := context.TODO()
|
||||
err := armClient.buildTestResources(ctx, &res)
|
||||
if err != nil {
|
||||
armClient.destroyTestResources(ctx, res)
|
||||
t.Fatalf("Error creating Test Resources: %q", err)
|
||||
}
|
||||
defer armClient.destroyTestResources(ctx, res)
|
||||
|
||||
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||
"storage_account_name": res.storageAccountName,
|
||||
"container_name": res.containerName,
|
||||
"key": keyName,
|
||||
"access_key": res.accessKey,
|
||||
"container_name": res.storageContainerName,
|
||||
"key": res.storageKeyName,
|
||||
"access_key": res.storageAccountAccessKey,
|
||||
})).(*Backend)
|
||||
|
||||
backend.TestBackendStates(t, b)
|
||||
}
|
||||
|
||||
func TestBackendLocked(t *testing.T) {
|
||||
testACC(t)
|
||||
func TestBackendServicePrincipalBasic(t *testing.T) {
|
||||
testAccAzureBackend(t)
|
||||
rs := acctest.RandString(4)
|
||||
res := testResourceNames(rs, "testState")
|
||||
armClient := buildTestClient(t, res)
|
||||
|
||||
keyName := "testState"
|
||||
res := setupResources(t, keyName)
|
||||
defer destroyResources(t, res.resourceGroupName)
|
||||
ctx := context.TODO()
|
||||
err := armClient.buildTestResources(ctx, &res)
|
||||
if err != nil {
|
||||
armClient.destroyTestResources(ctx, res)
|
||||
t.Fatalf("Error creating Test Resources: %q", err)
|
||||
}
|
||||
defer armClient.destroyTestResources(ctx, res)
|
||||
|
||||
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||
"storage_account_name": res.storageAccountName,
|
||||
"container_name": res.storageContainerName,
|
||||
"key": res.storageKeyName,
|
||||
"resource_group_name": res.resourceGroup,
|
||||
"arm_subscription_id": os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
"arm_tenant_id": os.Getenv("ARM_TENANT_ID"),
|
||||
"arm_client_id": os.Getenv("ARM_CLIENT_ID"),
|
||||
"arm_client_secret": os.Getenv("ARM_CLIENT_SECRET"),
|
||||
"environment": os.Getenv("ARM_ENVIRONMENT"),
|
||||
})).(*Backend)
|
||||
|
||||
backend.TestBackendStates(t, b)
|
||||
}
|
||||
|
||||
func TestBackendAccessKeyLocked(t *testing.T) {
|
||||
testAccAzureBackend(t)
|
||||
rs := acctest.RandString(4)
|
||||
res := testResourceNames(rs, "testState")
|
||||
armClient := buildTestClient(t, res)
|
||||
|
||||
ctx := context.TODO()
|
||||
err := armClient.buildTestResources(ctx, &res)
|
||||
if err != nil {
|
||||
armClient.destroyTestResources(ctx, res)
|
||||
t.Fatalf("Error creating Test Resources: %q", err)
|
||||
}
|
||||
defer armClient.destroyTestResources(ctx, res)
|
||||
|
||||
b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||
"storage_account_name": res.storageAccountName,
|
||||
"container_name": res.containerName,
|
||||
"key": keyName,
|
||||
"access_key": res.accessKey,
|
||||
"container_name": res.storageContainerName,
|
||||
"key": res.storageKeyName,
|
||||
"access_key": res.storageAccountAccessKey,
|
||||
})).(*Backend)
|
||||
|
||||
b2 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||
"storage_account_name": res.storageAccountName,
|
||||
"container_name": res.containerName,
|
||||
"key": keyName,
|
||||
"access_key": res.accessKey,
|
||||
"container_name": res.storageContainerName,
|
||||
"key": res.storageKeyName,
|
||||
"access_key": res.storageAccountAccessKey,
|
||||
})).(*Backend)
|
||||
|
||||
backend.TestBackendStateLocks(t, b1, b2)
|
||||
backend.TestBackendStateForceUnlock(t, b1, b2)
|
||||
}
|
||||
|
||||
type testResources struct {
|
||||
resourceGroupName string
|
||||
storageAccountName string
|
||||
containerName string
|
||||
keyName string
|
||||
accessKey string
|
||||
}
|
||||
|
||||
func setupResources(t *testing.T, keyName string) testResources {
|
||||
clients := getTestClient(t)
|
||||
|
||||
ri := acctest.RandInt()
|
||||
func TestBackendServicePrincipalLocked(t *testing.T) {
|
||||
testAccAzureBackend(t)
|
||||
rs := acctest.RandString(4)
|
||||
res := testResources{
|
||||
resourceGroupName: fmt.Sprintf("terraform-backend-testing-%d", ri),
|
||||
storageAccountName: fmt.Sprintf("tfbackendtesting%s", rs),
|
||||
containerName: "terraform",
|
||||
keyName: keyName,
|
||||
}
|
||||
res := testResourceNames(rs, "testState")
|
||||
armClient := buildTestClient(t, res)
|
||||
|
||||
location := os.Getenv("ARM_LOCATION")
|
||||
if location == "" {
|
||||
location = "westus"
|
||||
}
|
||||
|
||||
t.Logf("creating resource group %s", res.resourceGroupName)
|
||||
_, err := clients.groupsClient.CreateOrUpdate(res.resourceGroupName, resources.Group{Location: &location})
|
||||
ctx := context.TODO()
|
||||
err := armClient.buildTestResources(ctx, &res)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create test resource group: %s", err)
|
||||
armClient.destroyTestResources(ctx, res)
|
||||
t.Fatalf("Error creating Test Resources: %q", err)
|
||||
}
|
||||
defer armClient.destroyTestResources(ctx, res)
|
||||
|
||||
t.Logf("creating storage account %s", res.storageAccountName)
|
||||
_, createError := clients.storageAccountsClient.Create(res.resourceGroupName, res.storageAccountName, armStorage.AccountCreateParameters{
|
||||
Sku: &armStorage.Sku{
|
||||
Name: armStorage.StandardLRS,
|
||||
Tier: armStorage.Standard,
|
||||
},
|
||||
Location: &location,
|
||||
}, make(chan struct{}))
|
||||
createErr := <-createError
|
||||
if createErr != nil {
|
||||
destroyResources(t, res.resourceGroupName)
|
||||
t.Fatalf("failed to create test storage account: %s", err)
|
||||
}
|
||||
b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||
"storage_account_name": res.storageAccountName,
|
||||
"container_name": res.storageContainerName,
|
||||
"key": res.storageKeyName,
|
||||
"access_key": res.storageAccountAccessKey,
|
||||
"arm_subscription_id": os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
"arm_tenant_id": os.Getenv("ARM_TENANT_ID"),
|
||||
"arm_client_id": os.Getenv("ARM_CLIENT_ID"),
|
||||
"arm_client_secret": os.Getenv("ARM_CLIENT_SECRET"),
|
||||
"environment": os.Getenv("ARM_ENVIRONMENT"),
|
||||
})).(*Backend)
|
||||
|
||||
t.Log("fetching access key for storage account")
|
||||
resp, err := clients.storageAccountsClient.ListKeys(res.resourceGroupName, res.storageAccountName)
|
||||
if err != nil {
|
||||
destroyResources(t, res.resourceGroupName)
|
||||
t.Fatalf("failed to list storage account keys %s:", err)
|
||||
}
|
||||
b2 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||
"storage_account_name": res.storageAccountName,
|
||||
"container_name": res.storageContainerName,
|
||||
"key": res.storageKeyName,
|
||||
"access_key": res.storageAccountAccessKey,
|
||||
"arm_subscription_id": os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
"arm_tenant_id": os.Getenv("ARM_TENANT_ID"),
|
||||
"arm_client_id": os.Getenv("ARM_CLIENT_ID"),
|
||||
"arm_client_secret": os.Getenv("ARM_CLIENT_SECRET"),
|
||||
"environment": os.Getenv("ARM_ENVIRONMENT"),
|
||||
})).(*Backend)
|
||||
|
||||
keys := *resp.Keys
|
||||
res.accessKey = *keys[0].Value
|
||||
|
||||
storageClient, err := storage.NewClient(res.storageAccountName, res.accessKey,
|
||||
clients.environment.StorageEndpointSuffix, storage.DefaultAPIVersion, true)
|
||||
if err != nil {
|
||||
destroyResources(t, res.resourceGroupName)
|
||||
t.Fatalf("failed to list storage account keys %s:", err)
|
||||
}
|
||||
|
||||
t.Logf("creating container %s", res.containerName)
|
||||
blobService := storageClient.GetBlobService()
|
||||
container := blobService.GetContainerReference(res.containerName)
|
||||
err = container.Create(&storage.CreateContainerOptions{})
|
||||
if err != nil {
|
||||
destroyResources(t, res.resourceGroupName)
|
||||
t.Fatalf("failed to create storage container: %s", err)
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func destroyResources(t *testing.T, resourceGroupName string) {
|
||||
warning := "WARNING: Failed to delete the test Azure resources. They may incur charges. (error was %s)"
|
||||
|
||||
clients := getTestClient(t)
|
||||
|
||||
t.Log("destroying created resources")
|
||||
|
||||
// destroying is simple as deleting the resource group will destroy everything else
|
||||
_, deleteErr := clients.groupsClient.Delete(resourceGroupName, make(chan struct{}))
|
||||
err := <-deleteErr
|
||||
if err != nil {
|
||||
t.Logf(warning, err)
|
||||
return
|
||||
}
|
||||
|
||||
t.Log("Azure resources destroyed")
|
||||
}
|
||||
|
||||
type testClient struct {
|
||||
subscriptionID string
|
||||
tenantID string
|
||||
clientID string
|
||||
clientSecret string
|
||||
environment azure.Environment
|
||||
groupsClient resources.GroupsClient
|
||||
storageAccountsClient armStorage.AccountsClient
|
||||
}
|
||||
|
||||
func getTestClient(t *testing.T) testClient {
|
||||
client := testClient{
|
||||
subscriptionID: os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
tenantID: os.Getenv("ARM_TENANT_ID"),
|
||||
clientID: os.Getenv("ARM_CLIENT_ID"),
|
||||
clientSecret: os.Getenv("ARM_CLIENT_SECRET"),
|
||||
}
|
||||
|
||||
if client.subscriptionID == "" || client.tenantID == "" || client.clientID == "" || client.clientSecret == "" {
|
||||
t.Fatal("Azure credentials missing or incomplete")
|
||||
}
|
||||
|
||||
env, err := getAzureEnvironment(os.Getenv("ARM_ENVIRONMENT"))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to detect Azure environment from ARM_ENVIRONMENT value: %s", os.Getenv("ARM_ENVIRONMENT"))
|
||||
}
|
||||
client.environment = env
|
||||
|
||||
oauthConfig, err := adal.NewOAuthConfig(env.ActiveDirectoryEndpoint, client.tenantID)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to get OAuth config: %s", err)
|
||||
}
|
||||
|
||||
spt, err := adal.NewServicePrincipalToken(*oauthConfig, client.clientID, client.clientSecret, env.ResourceManagerEndpoint)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create Service Principal Token: %s", err)
|
||||
}
|
||||
|
||||
client.groupsClient = resources.NewGroupsClientWithBaseURI(env.ResourceManagerEndpoint, client.subscriptionID)
|
||||
client.groupsClient.Authorizer = autorest.NewBearerAuthorizer(spt)
|
||||
|
||||
client.storageAccountsClient = armStorage.NewAccountsClientWithBaseURI(env.ResourceManagerEndpoint, client.subscriptionID)
|
||||
client.storageAccountsClient.Authorizer = autorest.NewBearerAuthorizer(spt)
|
||||
|
||||
return client
|
||||
backend.TestBackendStateLocks(t, b1, b2)
|
||||
backend.TestBackendStateForceUnlock(t, b1, b2)
|
||||
}
|
||||
|
|
|
@ -9,9 +9,8 @@ import (
|
|||
"log"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/storage"
|
||||
multierror "github.com/hashicorp/go-multierror"
|
||||
uuid "github.com/hashicorp/go-uuid"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/hashicorp/go-uuid"
|
||||
"github.com/hashicorp/terraform/state"
|
||||
"github.com/hashicorp/terraform/state/remote"
|
||||
"github.com/hashicorp/terraform/states"
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package azure
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/storage"
|
||||
|
@ -14,18 +16,25 @@ func TestRemoteClient_impl(t *testing.T) {
|
|||
var _ remote.ClientLocker = new(RemoteClient)
|
||||
}
|
||||
|
||||
func TestRemoteClient(t *testing.T) {
|
||||
testACC(t)
|
||||
func TestRemoteClientAccessKeyBasic(t *testing.T) {
|
||||
testAccAzureBackend(t)
|
||||
rs := acctest.RandString(4)
|
||||
res := testResourceNames(rs, "testState")
|
||||
armClient := buildTestClient(t, res)
|
||||
|
||||
keyName := "testState"
|
||||
res := setupResources(t, keyName)
|
||||
defer destroyResources(t, res.resourceGroupName)
|
||||
ctx := context.TODO()
|
||||
err := armClient.buildTestResources(ctx, &res)
|
||||
if err != nil {
|
||||
armClient.destroyTestResources(ctx, res)
|
||||
t.Fatalf("Error creating Test Resources: %q", err)
|
||||
}
|
||||
defer armClient.destroyTestResources(ctx, res)
|
||||
|
||||
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||
"storage_account_name": res.storageAccountName,
|
||||
"container_name": res.containerName,
|
||||
"key": keyName,
|
||||
"access_key": res.accessKey,
|
||||
"container_name": res.storageContainerName,
|
||||
"key": res.storageKeyName,
|
||||
"access_key": res.storageAccountAccessKey,
|
||||
})).(*Backend)
|
||||
|
||||
state, err := b.StateMgr(backend.DefaultStateName)
|
||||
|
@ -36,25 +45,117 @@ func TestRemoteClient(t *testing.T) {
|
|||
remote.TestClient(t, state.(*remote.State).Client)
|
||||
}
|
||||
|
||||
func TestRemoteClientLocks(t *testing.T) {
|
||||
testACC(t)
|
||||
func TestRemoteClientServicePrincipalBasic(t *testing.T) {
|
||||
testAccAzureBackend(t)
|
||||
rs := acctest.RandString(4)
|
||||
res := testResourceNames(rs, "testState")
|
||||
armClient := buildTestClient(t, res)
|
||||
|
||||
keyName := "testState"
|
||||
res := setupResources(t, keyName)
|
||||
defer destroyResources(t, res.resourceGroupName)
|
||||
ctx := context.TODO()
|
||||
err := armClient.buildTestResources(ctx, &res)
|
||||
if err != nil {
|
||||
armClient.destroyTestResources(ctx, res)
|
||||
t.Fatalf("Error creating Test Resources: %q", err)
|
||||
}
|
||||
defer armClient.destroyTestResources(ctx, res)
|
||||
|
||||
b := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||
"storage_account_name": res.storageAccountName,
|
||||
"container_name": res.storageContainerName,
|
||||
"key": res.storageKeyName,
|
||||
"resource_group_name": res.resourceGroup,
|
||||
"arm_subscription_id": os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
"arm_tenant_id": os.Getenv("ARM_TENANT_ID"),
|
||||
"arm_client_id": os.Getenv("ARM_CLIENT_ID"),
|
||||
"arm_client_secret": os.Getenv("ARM_CLIENT_SECRET"),
|
||||
"environment": os.Getenv("ARM_ENVIRONMENT"),
|
||||
})).(*Backend)
|
||||
|
||||
state, err := b.StateMgr(backend.DefaultStateName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
remote.TestClient(t, state.(*remote.State).Client)
|
||||
}
|
||||
|
||||
func TestRemoteClientAccessKeyLocks(t *testing.T) {
|
||||
testAccAzureBackend(t)
|
||||
rs := acctest.RandString(4)
|
||||
res := testResourceNames(rs, "testState")
|
||||
armClient := buildTestClient(t, res)
|
||||
|
||||
ctx := context.TODO()
|
||||
err := armClient.buildTestResources(ctx, &res)
|
||||
if err != nil {
|
||||
armClient.destroyTestResources(ctx, res)
|
||||
t.Fatalf("Error creating Test Resources: %q", err)
|
||||
}
|
||||
defer armClient.destroyTestResources(ctx, res)
|
||||
|
||||
b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||
"storage_account_name": res.storageAccountName,
|
||||
"container_name": res.containerName,
|
||||
"key": keyName,
|
||||
"access_key": res.accessKey,
|
||||
"container_name": res.storageContainerName,
|
||||
"key": res.storageKeyName,
|
||||
"access_key": res.storageAccountAccessKey,
|
||||
})).(*Backend)
|
||||
|
||||
b2 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||
"storage_account_name": res.storageAccountName,
|
||||
"container_name": res.containerName,
|
||||
"key": keyName,
|
||||
"access_key": res.accessKey,
|
||||
"container_name": res.storageContainerName,
|
||||
"key": res.storageKeyName,
|
||||
"access_key": res.storageAccountAccessKey,
|
||||
})).(*Backend)
|
||||
|
||||
s1, err := b1.StateMgr(backend.DefaultStateName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
s2, err := b2.StateMgr(backend.DefaultStateName)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
remote.TestRemoteLocks(t, s1.(*remote.State).Client, s2.(*remote.State).Client)
|
||||
}
|
||||
|
||||
func TestRemoteClientServicePrincipalLocks(t *testing.T) {
|
||||
testAccAzureBackend(t)
|
||||
rs := acctest.RandString(4)
|
||||
res := testResourceNames(rs, "testState")
|
||||
armClient := buildTestClient(t, res)
|
||||
|
||||
ctx := context.TODO()
|
||||
err := armClient.buildTestResources(ctx, &res)
|
||||
if err != nil {
|
||||
armClient.destroyTestResources(ctx, res)
|
||||
t.Fatalf("Error creating Test Resources: %q", err)
|
||||
}
|
||||
defer armClient.destroyTestResources(ctx, res)
|
||||
|
||||
b1 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||
"storage_account_name": res.storageAccountName,
|
||||
"container_name": res.storageContainerName,
|
||||
"key": res.storageKeyName,
|
||||
"resource_group_name": res.resourceGroup,
|
||||
"arm_subscription_id": os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
"arm_tenant_id": os.Getenv("ARM_TENANT_ID"),
|
||||
"arm_client_id": os.Getenv("ARM_CLIENT_ID"),
|
||||
"arm_client_secret": os.Getenv("ARM_CLIENT_SECRET"),
|
||||
"environment": os.Getenv("ARM_ENVIRONMENT"),
|
||||
})).(*Backend)
|
||||
|
||||
b2 := backend.TestBackendConfig(t, New(), backend.TestWrapConfig(map[string]interface{}{
|
||||
"storage_account_name": res.storageAccountName,
|
||||
"container_name": res.storageContainerName,
|
||||
"key": res.storageKeyName,
|
||||
"resource_group_name": res.resourceGroup,
|
||||
"arm_subscription_id": os.Getenv("ARM_SUBSCRIPTION_ID"),
|
||||
"arm_tenant_id": os.Getenv("ARM_TENANT_ID"),
|
||||
"arm_client_id": os.Getenv("ARM_CLIENT_ID"),
|
||||
"arm_client_secret": os.Getenv("ARM_CLIENT_SECRET"),
|
||||
"environment": os.Getenv("ARM_ENVIRONMENT"),
|
||||
})).(*Backend)
|
||||
|
||||
s1, err := b1.StateMgr(backend.DefaultStateName)
|
||||
|
@ -71,22 +172,28 @@ func TestRemoteClientLocks(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestPutMaintainsMetaData(t *testing.T) {
|
||||
testACC(t)
|
||||
testAccAzureBackend(t)
|
||||
rs := acctest.RandString(4)
|
||||
res := testResourceNames(rs, "testState")
|
||||
armClient := buildTestClient(t, res)
|
||||
|
||||
ctx := context.TODO()
|
||||
err := armClient.buildTestResources(ctx, &res)
|
||||
if err != nil {
|
||||
armClient.destroyTestResources(ctx, res)
|
||||
t.Fatalf("Error creating Test Resources: %q", err)
|
||||
}
|
||||
defer armClient.destroyTestResources(ctx, res)
|
||||
|
||||
keyName := "testState"
|
||||
headerName := "acceptancetest"
|
||||
expectedValue := "f3b56bad-33ad-4b93-a600-7a66e9cbd1eb"
|
||||
res := setupResources(t, keyName)
|
||||
defer destroyResources(t, res.resourceGroupName)
|
||||
|
||||
config := getBackendConfig(t, res)
|
||||
blobClient, err := getBlobClient(config)
|
||||
client, err := armClient.getBlobClient(ctx)
|
||||
if err != nil {
|
||||
t.Fatalf("Error getting Blob Client: %+v", err)
|
||||
t.Fatalf("Error building Blob Client: %+v", err)
|
||||
}
|
||||
|
||||
containerReference := blobClient.GetContainerReference(res.containerName)
|
||||
blobReference := containerReference.GetBlobReference(keyName)
|
||||
containerReference := client.GetContainerReference(res.storageContainerName)
|
||||
blobReference := containerReference.GetBlobReference(res.storageKeyName)
|
||||
|
||||
err = blobReference.CreateBlockBlob(&storage.PutBlobOptions{})
|
||||
if err != nil {
|
||||
|
@ -106,9 +213,10 @@ func TestPutMaintainsMetaData(t *testing.T) {
|
|||
|
||||
// update the metadata using the Backend
|
||||
remoteClient := RemoteClient{
|
||||
keyName: res.keyName,
|
||||
containerName: res.containerName,
|
||||
blobClient: blobClient,
|
||||
keyName: res.storageKeyName,
|
||||
containerName: res.storageContainerName,
|
||||
|
||||
blobClient: *client,
|
||||
}
|
||||
|
||||
bytes := []byte(acctest.RandString(20))
|
||||
|
@ -127,17 +235,3 @@ func TestPutMaintainsMetaData(t *testing.T) {
|
|||
t.Fatalf("%q was not set to %q in the MetaData: %+v", headerName, expectedValue, blobReference.Metadata)
|
||||
}
|
||||
}
|
||||
|
||||
func getBackendConfig(t *testing.T, res testResources) BackendConfig {
|
||||
clients := getTestClient(t)
|
||||
return BackendConfig{
|
||||
ClientID: clients.clientID,
|
||||
ClientSecret: clients.clientSecret,
|
||||
Environment: clients.environment.Name,
|
||||
SubscriptionID: clients.subscriptionID,
|
||||
TenantID: clients.tenantID,
|
||||
|
||||
ResourceGroupName: res.resourceGroupName,
|
||||
StorageAccountName: res.storageAccountName,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
package azure
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/profiles/2017-03-09/resources/mgmt/resources"
|
||||
armStorage "github.com/Azure/azure-sdk-for-go/profiles/2017-03-09/storage/mgmt/storage"
|
||||
"github.com/Azure/azure-sdk-for-go/storage"
|
||||
)
|
||||
|
||||
// verify that we are doing ACC tests or the Azure tests specifically
|
||||
func testAccAzureBackend(t *testing.T) {
|
||||
skip := os.Getenv("TF_ACC") == "" && os.Getenv("TF_AZURE_TEST") == ""
|
||||
if skip {
|
||||
t.Log("azure backend tests require setting TF_ACC or TF_AZURE_TEST")
|
||||
t.Skip()
|
||||
}
|
||||
}
|
||||
|
||||
func buildTestClient(t *testing.T, res resourceNames) *ArmClient {
|
||||
subscriptionID := os.Getenv("ARM_SUBSCRIPTION_ID")
|
||||
tenantID := os.Getenv("ARM_TENANT_ID")
|
||||
clientID := os.Getenv("ARM_CLIENT_ID")
|
||||
clientSecret := os.Getenv("ARM_CLIENT_SECRET")
|
||||
environment := os.Getenv("ARM_ENVIRONMENT")
|
||||
|
||||
// location isn't used in this method, but is in the other test methods
|
||||
location := os.Getenv("ARM_LOCATION")
|
||||
|
||||
if subscriptionID == "" || tenantID == "" || clientID == "" || clientSecret == "" || environment == "" || location == "" {
|
||||
t.Fatal("Azure credentials missing or incomplete")
|
||||
}
|
||||
|
||||
armClient, err := buildArmClient(BackendConfig{
|
||||
SubscriptionID: subscriptionID,
|
||||
TenantID: tenantID,
|
||||
ClientID: clientID,
|
||||
ClientSecret: clientSecret,
|
||||
Environment: environment,
|
||||
ResourceGroupName: res.resourceGroup,
|
||||
StorageAccountName: res.storageAccountName,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to build ArmClient: %+v", err)
|
||||
}
|
||||
|
||||
return armClient
|
||||
}
|
||||
|
||||
type resourceNames struct {
|
||||
resourceGroup string
|
||||
location string
|
||||
storageAccountName string
|
||||
storageContainerName string
|
||||
storageKeyName string
|
||||
storageAccountAccessKey string
|
||||
}
|
||||
|
||||
func testResourceNames(rString string, keyName string) resourceNames {
|
||||
return resourceNames{
|
||||
resourceGroup: fmt.Sprintf("acctestrg-backend-%s", rString),
|
||||
location: os.Getenv("ARM_LOCATION"),
|
||||
storageAccountName: fmt.Sprintf("acctestsa%s", rString),
|
||||
storageContainerName: "acctestcont",
|
||||
storageKeyName: keyName,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ArmClient) buildTestResources(ctx context.Context, names *resourceNames) error {
|
||||
log.Printf("Creating Resource Group %q", names.resourceGroup)
|
||||
_, err := c.groupsClient.CreateOrUpdate(ctx, names.resourceGroup, resources.Group{Location: &names.location})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create test resource group: %s", err)
|
||||
}
|
||||
|
||||
log.Printf("Creating Storage Account %q in Resource Group %q", names.storageAccountName, names.resourceGroup)
|
||||
future, err := c.storageAccountsClient.Create(ctx, names.resourceGroup, names.storageAccountName, armStorage.AccountCreateParameters{
|
||||
Sku: &armStorage.Sku{
|
||||
Name: armStorage.StandardLRS,
|
||||
Tier: armStorage.Standard,
|
||||
},
|
||||
Location: &names.location,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create test storage account: %s", err)
|
||||
}
|
||||
|
||||
err = future.WaitForCompletionRef(ctx, c.storageAccountsClient.Client)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed waiting for the creation of storage account: %s", err)
|
||||
}
|
||||
|
||||
log.Printf("fetching access key for storage account")
|
||||
resp, err := c.storageAccountsClient.ListKeys(ctx, names.resourceGroup, names.storageAccountName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list storage account keys %s:", err)
|
||||
}
|
||||
|
||||
keys := *resp.Keys
|
||||
accessKey := *keys[0].Value
|
||||
names.storageAccountAccessKey = accessKey
|
||||
|
||||
storageClient, err := storage.NewBasicClientOnSovereignCloud(names.storageAccountName, accessKey, c.environment)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list storage account keys %s:", err)
|
||||
}
|
||||
|
||||
log.Printf("Creating Container %q in Storage Account %q (Resource Group %q)", names.storageContainerName, names.storageAccountName, names.resourceGroup)
|
||||
blobService := storageClient.GetBlobService()
|
||||
container := blobService.GetContainerReference(names.storageContainerName)
|
||||
err = container.Create(&storage.CreateContainerOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create storage container: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c ArmClient) destroyTestResources(ctx context.Context, resources resourceNames) error {
|
||||
log.Printf("[DEBUG] Deleting Resource Group %q..", resources.resourceGroup)
|
||||
future, err := c.groupsClient.Delete(ctx, resources.resourceGroup)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error deleting Resource Group: %+v", err)
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] Waiting for deletion of Resource Group %q..", resources.resourceGroup)
|
||||
err = future.WaitForCompletionRef(ctx, c.groupsClient.Client)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error waiting for the deletion of Resource Group: %+v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package azure
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/hashicorp/terraform/helper/logging"
|
||||
)
|
||||
|
||||
func buildSender() autorest.Sender {
|
||||
return autorest.DecorateSender(&http.Client{
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
},
|
||||
}, withRequestLogging())
|
||||
}
|
||||
|
||||
func withRequestLogging() autorest.SendDecorator {
|
||||
return func(s autorest.Sender) autorest.Sender {
|
||||
return autorest.SenderFunc(func(r *http.Request) (*http.Response, error) {
|
||||
// only log if logging's enabled
|
||||
logLevel := logging.LogLevel()
|
||||
if logLevel == "" {
|
||||
return s.Do(r)
|
||||
}
|
||||
|
||||
// strip the authorization header prior to printing
|
||||
authHeaderName := "Authorization"
|
||||
auth := r.Header.Get(authHeaderName)
|
||||
if auth != "" {
|
||||
r.Header.Del(authHeaderName)
|
||||
}
|
||||
|
||||
// dump request to wire format
|
||||
if dump, err := httputil.DumpRequestOut(r, true); err == nil {
|
||||
log.Printf("[DEBUG] Azure Backend Request: \n%s\n", dump)
|
||||
} else {
|
||||
// fallback to basic message
|
||||
log.Printf("[DEBUG] Azure Backend Request: %s to %s\n", r.Method, r.URL)
|
||||
}
|
||||
|
||||
// add the auth header back
|
||||
if auth != "" {
|
||||
r.Header.Add(authHeaderName, auth)
|
||||
}
|
||||
|
||||
resp, err := s.Do(r)
|
||||
if resp != nil {
|
||||
// dump response to wire format
|
||||
if dump, err2 := httputil.DumpResponse(resp, true); err2 == nil {
|
||||
log.Printf("[DEBUG] Azure Backend Response for %s: \n%s\n", r.URL, dump)
|
||||
} else {
|
||||
// fallback to basic message
|
||||
log.Printf("[DEBUG] Azure Backend Response: %s for %s\n", resp.Status, r.URL)
|
||||
}
|
||||
} else {
|
||||
log.Printf("[DEBUG] Request to %s completed with no response", r.URL)
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
}
|
9
go.mod
9
go.mod
|
@ -2,8 +2,8 @@ module github.com/hashicorp/terraform
|
|||
|
||||
require (
|
||||
cloud.google.com/go v0.15.0
|
||||
github.com/Azure/azure-sdk-for-go v10.3.0-beta+incompatible
|
||||
github.com/Azure/go-autorest v8.3.1+incompatible
|
||||
github.com/Azure/azure-sdk-for-go v21.3.0+incompatible
|
||||
github.com/Azure/go-autorest v10.15.4+incompatible
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20170803034930-c92175d54006 // indirect
|
||||
github.com/ChrisTrenkamp/goxpath v0.0.0-20170625215350-4fe035839290 // indirect
|
||||
github.com/Unknwon/com v0.0.0-20151008135407-28b053d5a292 // indirect
|
||||
|
@ -33,6 +33,7 @@ require (
|
|||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/dgrijalva/jwt-go v0.0.0-20160617170158-f0777076321a // indirect
|
||||
github.com/dimchansky/utfbom v1.0.0 // indirect
|
||||
github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31 // indirect
|
||||
github.com/dylanmei/iso8601 v0.1.0 // indirect
|
||||
github.com/dylanmei/winrmtest v0.0.0-20170819153634-c2fbb09e6c08
|
||||
|
@ -54,6 +55,7 @@ require (
|
|||
github.com/grpc-ecosystem/grpc-gateway v1.5.1 // indirect
|
||||
github.com/hashicorp/consul v0.0.0-20171026175957-610f3c86a089
|
||||
github.com/hashicorp/errwrap v1.0.0
|
||||
github.com/hashicorp/go-azure-helpers v0.0.0-20181120094008-dd1e326c8888
|
||||
github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0
|
||||
github.com/hashicorp/go-getter v0.0.0-20180327010114-90bb99a48d86
|
||||
|
@ -86,6 +88,7 @@ require (
|
|||
github.com/kardianos/osext v0.0.0-20160811001526-c2c54e542fb7
|
||||
github.com/keybase/go-crypto v0.0.0-20161004153544-93f5b35093ba // indirect
|
||||
github.com/lusis/go-artifactory v0.0.0-20160115162124-7e4ce345df82
|
||||
github.com/marstr/guid v1.1.0 // indirect
|
||||
github.com/masterzen/azure-sdk-for-go v0.0.0-20161014135628-ee4f0065d00c // indirect
|
||||
github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9 // indirect
|
||||
github.com/masterzen/winrm v0.0.0-20180224160350-7e40f93ae939
|
||||
|
@ -135,7 +138,7 @@ require (
|
|||
go.uber.org/atomic v1.3.2 // indirect
|
||||
go.uber.org/multierr v1.1.0 // indirect
|
||||
go.uber.org/zap v1.9.1 // indirect
|
||||
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b
|
||||
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869
|
||||
golang.org/x/net v0.0.0-20181017193950-04a2e542c03f
|
||||
golang.org/x/oauth2 v0.0.0-20181003184128-c57b0facaced
|
||||
golang.org/x/sys v0.0.0-20180925112736-b09afc3d579e // indirect
|
||||
|
|
17
go.sum
17
go.sum
|
@ -1,10 +1,11 @@
|
|||
cloud.google.com/go v0.15.0 h1:/e2wXYguItvFu4fJCvhMRPIwwrimuUxI+aCVx/ahLjg=
|
||||
cloud.google.com/go v0.15.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
github.com/Azure/azure-sdk-for-go v10.3.0-beta+incompatible h1:TP+nmGmOP7psi7CvIq/1pCliRBRj73vmMTDjaPrTnr8=
|
||||
github.com/Azure/azure-sdk-for-go v10.3.0-beta+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-autorest v8.3.1+incompatible h1:1+jMCOJcCh3GmI7FGJVOo8AlfPWDyjS7fLbbkZGzEGY=
|
||||
github.com/Azure/go-autorest v8.3.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/azure-sdk-for-go v21.3.0+incompatible h1:YFvAka2WKAl2xnJkYV1e1b7E2z88AgFszDzWU18ejMY=
|
||||
github.com/Azure/azure-sdk-for-go v21.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v22.2.2+incompatible h1:dnM65i68vx79S5ugocLMoJB6As2U1IXxa995LdjIQ28=
|
||||
github.com/Azure/go-autorest v10.15.4+incompatible h1:q+DRrRdbCnkY7f2WxQBx58TwCGkEdMAK/hkZ10g0Pzk=
|
||||
github.com/Azure/go-autorest v10.15.4+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20170803034930-c92175d54006 h1:dVyNL14dq1500JomYVzJTVi0XEcZFCYwwiNpDeCfoes=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20170803034930-c92175d54006/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/ChrisTrenkamp/goxpath v0.0.0-20170625215350-4fe035839290 h1:K9I21XUHNbYD3GNMmJBN0UKJCpdP+glftwNZ7Bo8kqY=
|
||||
|
@ -69,6 +70,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v0.0.0-20160617170158-f0777076321a h1:pzKxqfSfp4kqrm6jfyVYYkWhf+e1hPRt3rX+Yj/3UBU=
|
||||
github.com/dgrijalva/jwt-go v0.0.0-20160617170158-f0777076321a/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dimchansky/utfbom v1.0.0 h1:fGC2kkf4qOoKqZ4q7iIh+Vef4ubC1c38UDsEyZynZPc=
|
||||
github.com/dimchansky/utfbom v1.0.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
|
||||
github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31 h1:Dzuw9GtbmllUqEcoHfScT9YpKFUssSiZ5PgZkIGf/YQ=
|
||||
github.com/dnaeon/go-vcr v0.0.0-20180920040454-5637cf3d8a31/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/dylanmei/iso8601 v0.1.0 h1:812NGQDBcqquTfH5Yeo7lwR0nzx/cKdsmf3qMjPURUI=
|
||||
|
@ -119,6 +122,8 @@ github.com/hashicorp/errwrap v0.0.0-20180715044906-d6c0cd880357 h1:Rem2+U35z1QtP
|
|||
github.com/hashicorp/errwrap v0.0.0-20180715044906-d6c0cd880357/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-azure-helpers v0.0.0-20181120094008-dd1e326c8888 h1:QdenIfqH8llhlVDlGQWVUhg+L8pDT9VteOlMstWRl+w=
|
||||
github.com/hashicorp/go-azure-helpers v0.0.0-20181120094008-dd1e326c8888/go.mod h1:e+GPy2nvD+spqsdjUyw5tbo73rBbu955QBaV9GZoBEA=
|
||||
github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de h1:XDCSythtg8aWSRSO29uwhgh7b127fWr+m5SemqjSUL8=
|
||||
github.com/hashicorp/go-checkpoint v0.0.0-20171009173528-1545e56e46de/go.mod h1:xIwEieBHERyEvaeKF/TcHh1Hu+lxPM+n2vT1+g9I4m4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
|
||||
|
@ -197,6 +202,8 @@ github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3v
|
|||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/lusis/go-artifactory v0.0.0-20160115162124-7e4ce345df82 h1:wnfcqULT+N2seWf6y4yHzmi7GD2kNx4Ute0qArktD48=
|
||||
github.com/lusis/go-artifactory v0.0.0-20160115162124-7e4ce345df82/go.mod h1:y54tfGmO3NKssKveTEFFzH8C/akrSOy/iW9qEAUDV84=
|
||||
github.com/marstr/guid v1.1.0 h1:/M4H/1G4avsieL6BbUwCOBzulmoeKVP5ux/3mQNnbyI=
|
||||
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||
github.com/masterzen/azure-sdk-for-go v0.0.0-20161014135628-ee4f0065d00c h1:FMUOnVGy8nWk1cvlMCAoftRItQGMxI0vzJ3dQjeZTCE=
|
||||
github.com/masterzen/azure-sdk-for-go v0.0.0-20161014135628-ee4f0065d00c/go.mod h1:mf8fjOu33zCqxUjuiU3I8S1lJMyEAlH+0F2+M5xl3hE=
|
||||
github.com/masterzen/simplexml v0.0.0-20160608183007-4572e39b1ab9 h1:SmVbOZFWAlyQshuMfOkiAx1f5oUTsOGG5IXplAEYeeM=
|
||||
|
@ -325,6 +332,8 @@ golang.org/x/crypto v0.0.0-20180816225734-aabede6cba87/go.mod h1:6SG95UA2DQfeDnf
|
|||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b h1:2b9XGzhjiYsYPnKXoEfL7klWZQIt8IfyRCz62gCqqlQ=
|
||||
golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869 h1:kkXA53yGe04D0adEYJwEVQjeBppL01Exg+fnMjfUraU=
|
||||
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180811021610-c39426892332 h1:efGso+ep0DjyCBJPjvoz0HI6UldX4Md2F1rZFe1ir0E=
|
||||
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
Microsoft Azure-SDK-for-Go
|
||||
Copyright 2014-2017 Microsoft
|
||||
|
||||
This product includes software developed at
|
||||
the Microsoft Corporation (https://www.microsoft.com).
|
|
@ -1,457 +0,0 @@
|
|||
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 1.0.1.0
|
||||
// Changes may cause incorrect behavior and will be lost if the code is
|
||||
// regenerated.
|
||||
|
||||
import (
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/date"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// DeploymentMode enumerates the values for deployment mode.
|
||||
type DeploymentMode string
|
||||
|
||||
const (
|
||||
// Complete specifies the complete state for deployment mode.
|
||||
Complete DeploymentMode = "Complete"
|
||||
// Incremental specifies the incremental state for deployment mode.
|
||||
Incremental DeploymentMode = "Incremental"
|
||||
)
|
||||
|
||||
// ResourceIdentityType enumerates the values for resource identity type.
|
||||
type ResourceIdentityType string
|
||||
|
||||
const (
|
||||
// SystemAssigned specifies the system assigned state for resource identity
|
||||
// type.
|
||||
SystemAssigned ResourceIdentityType = "SystemAssigned"
|
||||
)
|
||||
|
||||
// AliasPathType is the type of the paths for alias.
|
||||
type AliasPathType struct {
|
||||
Path *string `json:"path,omitempty"`
|
||||
APIVersions *[]string `json:"apiVersions,omitempty"`
|
||||
}
|
||||
|
||||
// AliasType is the alias type.
|
||||
type AliasType struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Paths *[]AliasPathType `json:"paths,omitempty"`
|
||||
}
|
||||
|
||||
// BasicDependency is deployment dependency information.
|
||||
type BasicDependency struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
ResourceType *string `json:"resourceType,omitempty"`
|
||||
ResourceName *string `json:"resourceName,omitempty"`
|
||||
}
|
||||
|
||||
// DebugSetting is
|
||||
type DebugSetting struct {
|
||||
DetailLevel *string `json:"detailLevel,omitempty"`
|
||||
}
|
||||
|
||||
// Dependency is deployment dependency information.
|
||||
type Dependency struct {
|
||||
DependsOn *[]BasicDependency `json:"dependsOn,omitempty"`
|
||||
ID *string `json:"id,omitempty"`
|
||||
ResourceType *string `json:"resourceType,omitempty"`
|
||||
ResourceName *string `json:"resourceName,omitempty"`
|
||||
}
|
||||
|
||||
// Deployment is deployment operation parameters.
|
||||
type Deployment struct {
|
||||
Properties *DeploymentProperties `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentExportResult is the deployment export result.
|
||||
type DeploymentExportResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
Template *map[string]interface{} `json:"template,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentExtended is deployment information.
|
||||
type DeploymentExtended struct {
|
||||
autorest.Response `json:"-"`
|
||||
ID *string `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Properties *DeploymentPropertiesExtended `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentExtendedFilter is deployment filter.
|
||||
type DeploymentExtendedFilter struct {
|
||||
ProvisioningState *string `json:"provisioningState,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentListResult is list of deployments.
|
||||
type DeploymentListResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
Value *[]DeploymentExtended `json:"value,omitempty"`
|
||||
NextLink *string `json:"nextLink,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentListResultPreparer prepares a request to retrieve the next set of results. It returns
|
||||
// nil if no more results exist.
|
||||
func (client DeploymentListResult) DeploymentListResultPreparer() (*http.Request, error) {
|
||||
if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return autorest.Prepare(&http.Request{},
|
||||
autorest.AsJSON(),
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(to.String(client.NextLink)))
|
||||
}
|
||||
|
||||
// DeploymentOperation is deployment operation information.
|
||||
type DeploymentOperation struct {
|
||||
autorest.Response `json:"-"`
|
||||
ID *string `json:"id,omitempty"`
|
||||
OperationID *string `json:"operationId,omitempty"`
|
||||
Properties *DeploymentOperationProperties `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentOperationProperties is deployment operation properties.
|
||||
type DeploymentOperationProperties struct {
|
||||
ProvisioningState *string `json:"provisioningState,omitempty"`
|
||||
Timestamp *date.Time `json:"timestamp,omitempty"`
|
||||
ServiceRequestID *string `json:"serviceRequestId,omitempty"`
|
||||
StatusCode *string `json:"statusCode,omitempty"`
|
||||
StatusMessage *map[string]interface{} `json:"statusMessage,omitempty"`
|
||||
TargetResource *TargetResource `json:"targetResource,omitempty"`
|
||||
Request *HTTPMessage `json:"request,omitempty"`
|
||||
Response *HTTPMessage `json:"response,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentOperationsListResult is list of deployment operations.
|
||||
type DeploymentOperationsListResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
Value *[]DeploymentOperation `json:"value,omitempty"`
|
||||
NextLink *string `json:"nextLink,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentOperationsListResultPreparer prepares a request to retrieve the next set of results. It returns
|
||||
// nil if no more results exist.
|
||||
func (client DeploymentOperationsListResult) DeploymentOperationsListResultPreparer() (*http.Request, error) {
|
||||
if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return autorest.Prepare(&http.Request{},
|
||||
autorest.AsJSON(),
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(to.String(client.NextLink)))
|
||||
}
|
||||
|
||||
// DeploymentProperties is deployment properties.
|
||||
type DeploymentProperties struct {
|
||||
Template *map[string]interface{} `json:"template,omitempty"`
|
||||
TemplateLink *TemplateLink `json:"templateLink,omitempty"`
|
||||
Parameters *map[string]interface{} `json:"parameters,omitempty"`
|
||||
ParametersLink *ParametersLink `json:"parametersLink,omitempty"`
|
||||
Mode DeploymentMode `json:"mode,omitempty"`
|
||||
DebugSetting *DebugSetting `json:"debugSetting,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentPropertiesExtended is deployment properties with additional
|
||||
// details.
|
||||
type DeploymentPropertiesExtended struct {
|
||||
ProvisioningState *string `json:"provisioningState,omitempty"`
|
||||
CorrelationID *string `json:"correlationId,omitempty"`
|
||||
Timestamp *date.Time `json:"timestamp,omitempty"`
|
||||
Outputs *map[string]interface{} `json:"outputs,omitempty"`
|
||||
Providers *[]Provider `json:"providers,omitempty"`
|
||||
Dependencies *[]Dependency `json:"dependencies,omitempty"`
|
||||
Template *map[string]interface{} `json:"template,omitempty"`
|
||||
TemplateLink *TemplateLink `json:"templateLink,omitempty"`
|
||||
Parameters *map[string]interface{} `json:"parameters,omitempty"`
|
||||
ParametersLink *ParametersLink `json:"parametersLink,omitempty"`
|
||||
Mode DeploymentMode `json:"mode,omitempty"`
|
||||
DebugSetting *DebugSetting `json:"debugSetting,omitempty"`
|
||||
}
|
||||
|
||||
// DeploymentValidateResult is information from validate template deployment
|
||||
// response.
|
||||
type DeploymentValidateResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
Error *ManagementErrorWithDetails `json:"error,omitempty"`
|
||||
Properties *DeploymentPropertiesExtended `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// ExportTemplateRequest is export resource group template request parameters.
|
||||
type ExportTemplateRequest struct {
|
||||
ResourcesProperty *[]string `json:"resources,omitempty"`
|
||||
Options *string `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
// GenericResource is resource information.
|
||||
type GenericResource struct {
|
||||
autorest.Response `json:"-"`
|
||||
ID *string `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Type *string `json:"type,omitempty"`
|
||||
Location *string `json:"location,omitempty"`
|
||||
Tags *map[string]*string `json:"tags,omitempty"`
|
||||
Plan *Plan `json:"plan,omitempty"`
|
||||
Properties *map[string]interface{} `json:"properties,omitempty"`
|
||||
Kind *string `json:"kind,omitempty"`
|
||||
ManagedBy *string `json:"managedBy,omitempty"`
|
||||
Sku *Sku `json:"sku,omitempty"`
|
||||
Identity *Identity `json:"identity,omitempty"`
|
||||
}
|
||||
|
||||
// GenericResourceFilter is resource filter.
|
||||
type GenericResourceFilter struct {
|
||||
ResourceType *string `json:"resourceType,omitempty"`
|
||||
Tagname *string `json:"tagname,omitempty"`
|
||||
Tagvalue *string `json:"tagvalue,omitempty"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
ManagedBy *string `json:"managedBy,omitempty"`
|
||||
Tags *map[string]*string `json:"tags,omitempty"`
|
||||
}
|
||||
|
||||
// GroupExportResult is
|
||||
type GroupExportResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
Template *map[string]interface{} `json:"template,omitempty"`
|
||||
Error *ManagementErrorWithDetails `json:"error,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"`
|
||||
}
|
||||
|
||||
// HTTPMessage is
|
||||
type HTTPMessage struct {
|
||||
Content *map[string]interface{} `json:"content,omitempty"`
|
||||
}
|
||||
|
||||
// Identity is identity for the resource.
|
||||
type Identity struct {
|
||||
PrincipalID *string `json:"principalId,omitempty"`
|
||||
TenantID *string `json:"tenantId,omitempty"`
|
||||
Type ResourceIdentityType `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// 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)))
|
||||
}
|
||||
|
||||
// ManagementErrorWithDetails is
|
||||
type ManagementErrorWithDetails struct {
|
||||
Code *string `json:"code,omitempty"`
|
||||
Message *string `json:"message,omitempty"`
|
||||
Target *string `json:"target,omitempty"`
|
||||
Details *[]ManagementErrorWithDetails `json:"details,omitempty"`
|
||||
}
|
||||
|
||||
// MoveInfo is parameters of move resources.
|
||||
type MoveInfo struct {
|
||||
ResourcesProperty *[]string `json:"resources,omitempty"`
|
||||
TargetResourceGroup *string `json:"targetResourceGroup,omitempty"`
|
||||
}
|
||||
|
||||
// ParametersLink is entity representing the reference to the deployment
|
||||
// paramaters.
|
||||
type ParametersLink struct {
|
||||
URI *string `json:"uri,omitempty"`
|
||||
ContentVersion *string `json:"contentVersion,omitempty"`
|
||||
}
|
||||
|
||||
// Plan is plan for the resource.
|
||||
type Plan struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Publisher *string `json:"publisher,omitempty"`
|
||||
Product *string `json:"product,omitempty"`
|
||||
PromotionCode *string `json:"promotionCode,omitempty"`
|
||||
}
|
||||
|
||||
// Provider is resource provider information.
|
||||
type Provider struct {
|
||||
autorest.Response `json:"-"`
|
||||
ID *string `json:"id,omitempty"`
|
||||
Namespace *string `json:"namespace,omitempty"`
|
||||
RegistrationState *string `json:"registrationState,omitempty"`
|
||||
ResourceTypes *[]ProviderResourceType `json:"resourceTypes,omitempty"`
|
||||
}
|
||||
|
||||
// ProviderListResult is list of resource providers.
|
||||
type ProviderListResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
Value *[]Provider `json:"value,omitempty"`
|
||||
NextLink *string `json:"nextLink,omitempty"`
|
||||
}
|
||||
|
||||
// ProviderListResultPreparer prepares a request to retrieve the next set of results. It returns
|
||||
// nil if no more results exist.
|
||||
func (client ProviderListResult) ProviderListResultPreparer() (*http.Request, error) {
|
||||
if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return autorest.Prepare(&http.Request{},
|
||||
autorest.AsJSON(),
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(to.String(client.NextLink)))
|
||||
}
|
||||
|
||||
// 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"`
|
||||
}
|
||||
|
||||
// ProviderResourceType is resource type managed by the resource provider.
|
||||
type ProviderResourceType struct {
|
||||
ResourceType *string `json:"resourceType,omitempty"`
|
||||
Locations *[]string `json:"locations,omitempty"`
|
||||
Aliases *[]AliasType `json:"aliases,omitempty"`
|
||||
APIVersions *[]string `json:"apiVersions,omitempty"`
|
||||
Properties *map[string]*string `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// Resource is
|
||||
type Resource struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Type *string `json:"type,omitempty"`
|
||||
Location *string `json:"location,omitempty"`
|
||||
Tags *map[string]*string `json:"tags,omitempty"`
|
||||
}
|
||||
|
||||
// Sku is sKU for the resource.
|
||||
type Sku struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Tier *string `json:"tier,omitempty"`
|
||||
Size *string `json:"size,omitempty"`
|
||||
Family *string `json:"family,omitempty"`
|
||||
Model *string `json:"model,omitempty"`
|
||||
Capacity *int32 `json:"capacity,omitempty"`
|
||||
}
|
||||
|
||||
// SubResource is
|
||||
type SubResource struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
// TagCount is tag count.
|
||||
type TagCount struct {
|
||||
Type *string `json:"type,omitempty"`
|
||||
Value *int32 `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// TagDetails is tag details.
|
||||
type TagDetails struct {
|
||||
autorest.Response `json:"-"`
|
||||
ID *string `json:"id,omitempty"`
|
||||
TagName *string `json:"tagName,omitempty"`
|
||||
Count *TagCount `json:"count,omitempty"`
|
||||
Values *[]TagValue `json:"values,omitempty"`
|
||||
}
|
||||
|
||||
// TagsListResult is list of subscription tags.
|
||||
type TagsListResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
Value *[]TagDetails `json:"value,omitempty"`
|
||||
NextLink *string `json:"nextLink,omitempty"`
|
||||
}
|
||||
|
||||
// TagsListResultPreparer prepares a request to retrieve the next set of results. It returns
|
||||
// nil if no more results exist.
|
||||
func (client TagsListResult) TagsListResultPreparer() (*http.Request, error) {
|
||||
if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 {
|
||||
return nil, nil
|
||||
}
|
||||
return autorest.Prepare(&http.Request{},
|
||||
autorest.AsJSON(),
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(to.String(client.NextLink)))
|
||||
}
|
||||
|
||||
// TagValue is tag information.
|
||||
type TagValue struct {
|
||||
autorest.Response `json:"-"`
|
||||
ID *string `json:"id,omitempty"`
|
||||
TagValue *string `json:"tagValue,omitempty"`
|
||||
Count *TagCount `json:"count,omitempty"`
|
||||
}
|
||||
|
||||
// TargetResource is target resource.
|
||||
type TargetResource struct {
|
||||
ID *string `json:"id,omitempty"`
|
||||
ResourceName *string `json:"resourceName,omitempty"`
|
||||
ResourceType *string `json:"resourceType,omitempty"`
|
||||
}
|
||||
|
||||
// TemplateLink is entity representing the reference to the template.
|
||||
type TemplateLink struct {
|
||||
URI *string `json:"uri,omitempty"`
|
||||
ContentVersion *string `json:"contentVersion,omitempty"`
|
||||
}
|
898
vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/resourcesgroup.go
generated
vendored
898
vendor/github.com/Azure/azure-sdk-for-go/arm/resources/resources/resourcesgroup.go
generated
vendored
|
@ -1,898 +0,0 @@
|
|||
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 1.0.1.0
|
||||
// Changes may cause incorrect behavior and will be lost if the code is
|
||||
// regenerated.
|
||||
|
||||
import (
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/validation"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// GroupClient is the provides operations for working with resources and
|
||||
// resource groups.
|
||||
type GroupClient struct {
|
||||
ManagementClient
|
||||
}
|
||||
|
||||
// NewGroupClient creates an instance of the GroupClient client.
|
||||
func NewGroupClient(subscriptionID string) GroupClient {
|
||||
return NewGroupClientWithBaseURI(DefaultBaseURI, subscriptionID)
|
||||
}
|
||||
|
||||
// NewGroupClientWithBaseURI creates an instance of the GroupClient client.
|
||||
func NewGroupClientWithBaseURI(baseURI string, subscriptionID string) GroupClient {
|
||||
return GroupClient{NewWithBaseURI(baseURI, subscriptionID)}
|
||||
}
|
||||
|
||||
// CheckExistence checks whether a resource exists.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group containing the resource
|
||||
// to check. The name is case insensitive. resourceProviderNamespace is the
|
||||
// resource provider of the resource to check. parentResourcePath is the parent
|
||||
// resource identity. resourceType is the resource type. resourceName is the
|
||||
// name of the resource to check whether it exists.
|
||||
func (client GroupClient) CheckExistence(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (result autorest.Response, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.GroupClient", "CheckExistence")
|
||||
}
|
||||
|
||||
req, err := client.CheckExistencePreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "CheckExistence", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.CheckExistenceSender(req)
|
||||
if err != nil {
|
||||
result.Response = resp
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "CheckExistence", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.CheckExistenceResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "CheckExistence", resp, "Failure responding to request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CheckExistencePreparer prepares the CheckExistence request.
|
||||
func (client GroupClient) CheckExistencePreparer(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"parentResourcePath": parentResourcePath,
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"resourceName": autorest.Encode("path", resourceName),
|
||||
"resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace),
|
||||
"resourceType": resourceType,
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsHead(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
}
|
||||
|
||||
// CheckExistenceSender sends the CheckExistence request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupClient) CheckExistenceSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
}
|
||||
|
||||
// CheckExistenceResponder handles the response to the CheckExistence request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client GroupClient) CheckExistenceResponder(resp *http.Response) (result autorest.Response, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusNotFound),
|
||||
autorest.ByClosing())
|
||||
result.Response = resp
|
||||
return
|
||||
}
|
||||
|
||||
// CheckExistenceByID checks by ID whether a resource exists.
|
||||
//
|
||||
// resourceID is the fully qualified ID of the resource, including the resource
|
||||
// name and resource type. Use the format,
|
||||
// /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name}
|
||||
func (client GroupClient) CheckExistenceByID(resourceID string) (result autorest.Response, err error) {
|
||||
req, err := client.CheckExistenceByIDPreparer(resourceID)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "CheckExistenceByID", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.CheckExistenceByIDSender(req)
|
||||
if err != nil {
|
||||
result.Response = resp
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "CheckExistenceByID", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.CheckExistenceByIDResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "CheckExistenceByID", resp, "Failure responding to request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CheckExistenceByIDPreparer prepares the CheckExistenceByID request.
|
||||
func (client GroupClient) CheckExistenceByIDPreparer(resourceID string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceId": resourceID,
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsHead(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/{resourceId}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
}
|
||||
|
||||
// CheckExistenceByIDSender sends the CheckExistenceByID request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupClient) CheckExistenceByIDSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
}
|
||||
|
||||
// CheckExistenceByIDResponder handles the response to the CheckExistenceByID request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client GroupClient) CheckExistenceByIDResponder(resp *http.Response) (result autorest.Response, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusNotFound),
|
||||
autorest.ByClosing())
|
||||
result.Response = resp
|
||||
return
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates a resource. This method may poll for completion.
|
||||
// Polling can be canceled by passing the cancel channel argument. The channel
|
||||
// will be used to cancel polling and any outstanding HTTP requests.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group for the resource. The
|
||||
// name is case insensitive. resourceProviderNamespace is the namespace of the
|
||||
// resource provider. parentResourcePath is the parent resource identity.
|
||||
// resourceType is the resource type of the resource to create. resourceName is
|
||||
// the name of the resource to create. parameters is parameters for creating or
|
||||
// updating the resource.
|
||||
func (client GroupClient) CreateOrUpdate(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, parameters GenericResource, cancel <-chan struct{}) (<-chan GenericResource, <-chan error) {
|
||||
resultChan := make(chan GenericResource, 1)
|
||||
errChan := make(chan error, 1)
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: parameters,
|
||||
Constraints: []validation.Constraint{{Target: "parameters.Kind", Name: validation.Null, Rule: false,
|
||||
Chain: []validation.Constraint{{Target: "parameters.Kind", Name: validation.Pattern, Rule: `^[-\w\._,\(\)]+$`, Chain: nil}}}}}}); err != nil {
|
||||
errChan <- validation.NewErrorWithValidationError(err, "resources.GroupClient", "CreateOrUpdate")
|
||||
close(errChan)
|
||||
close(resultChan)
|
||||
return resultChan, errChan
|
||||
}
|
||||
|
||||
go func() {
|
||||
var err error
|
||||
var result GenericResource
|
||||
defer func() {
|
||||
resultChan <- result
|
||||
errChan <- err
|
||||
close(resultChan)
|
||||
close(errChan)
|
||||
}()
|
||||
req, err := client.CreateOrUpdatePreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, parameters, cancel)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "CreateOrUpdate", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.CreateOrUpdateSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "CreateOrUpdate", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.CreateOrUpdateResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "CreateOrUpdate", resp, "Failure responding to request")
|
||||
}
|
||||
}()
|
||||
return resultChan, errChan
|
||||
}
|
||||
|
||||
// CreateOrUpdatePreparer prepares the CreateOrUpdate request.
|
||||
func (client GroupClient) CreateOrUpdatePreparer(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, parameters GenericResource, cancel <-chan struct{}) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"parentResourcePath": parentResourcePath,
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"resourceName": autorest.Encode("path", resourceName),
|
||||
"resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace),
|
||||
"resourceType": resourceType,
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsJSON(),
|
||||
autorest.AsPut(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{Cancel: cancel})
|
||||
}
|
||||
|
||||
// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client,
|
||||
req,
|
||||
azure.DoPollForAsynchronous(client.PollingDelay))
|
||||
}
|
||||
|
||||
// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client GroupClient) CreateOrUpdateResponder(resp *http.Response) (result GenericResource, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK, http.StatusAccepted),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// CreateOrUpdateByID create a resource by ID. This method may poll for
|
||||
// completion. Polling can be canceled by passing the cancel channel argument.
|
||||
// The channel will be used to cancel polling and any outstanding HTTP
|
||||
// requests.
|
||||
//
|
||||
// resourceID is the fully qualified ID of the resource, including the resource
|
||||
// name and resource type. Use the format,
|
||||
// /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name}
|
||||
// parameters is create or update resource parameters.
|
||||
func (client GroupClient) CreateOrUpdateByID(resourceID string, parameters GenericResource, cancel <-chan struct{}) (<-chan GenericResource, <-chan error) {
|
||||
resultChan := make(chan GenericResource, 1)
|
||||
errChan := make(chan error, 1)
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: parameters,
|
||||
Constraints: []validation.Constraint{{Target: "parameters.Kind", Name: validation.Null, Rule: false,
|
||||
Chain: []validation.Constraint{{Target: "parameters.Kind", Name: validation.Pattern, Rule: `^[-\w\._,\(\)]+$`, Chain: nil}}}}}}); err != nil {
|
||||
errChan <- validation.NewErrorWithValidationError(err, "resources.GroupClient", "CreateOrUpdateByID")
|
||||
close(errChan)
|
||||
close(resultChan)
|
||||
return resultChan, errChan
|
||||
}
|
||||
|
||||
go func() {
|
||||
var err error
|
||||
var result GenericResource
|
||||
defer func() {
|
||||
resultChan <- result
|
||||
errChan <- err
|
||||
close(resultChan)
|
||||
close(errChan)
|
||||
}()
|
||||
req, err := client.CreateOrUpdateByIDPreparer(resourceID, parameters, cancel)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "CreateOrUpdateByID", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.CreateOrUpdateByIDSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "CreateOrUpdateByID", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.CreateOrUpdateByIDResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "CreateOrUpdateByID", resp, "Failure responding to request")
|
||||
}
|
||||
}()
|
||||
return resultChan, errChan
|
||||
}
|
||||
|
||||
// CreateOrUpdateByIDPreparer prepares the CreateOrUpdateByID request.
|
||||
func (client GroupClient) CreateOrUpdateByIDPreparer(resourceID string, parameters GenericResource, cancel <-chan struct{}) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceId": resourceID,
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsJSON(),
|
||||
autorest.AsPut(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/{resourceId}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{Cancel: cancel})
|
||||
}
|
||||
|
||||
// CreateOrUpdateByIDSender sends the CreateOrUpdateByID request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupClient) CreateOrUpdateByIDSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client,
|
||||
req,
|
||||
azure.DoPollForAsynchronous(client.PollingDelay))
|
||||
}
|
||||
|
||||
// CreateOrUpdateByIDResponder handles the response to the CreateOrUpdateByID request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client GroupClient) CreateOrUpdateByIDResponder(resp *http.Response) (result GenericResource, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK, http.StatusAccepted),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// Delete deletes a resource. This method may poll for completion. Polling can
|
||||
// be canceled by passing the cancel channel argument. The channel will be used
|
||||
// to cancel polling and any outstanding HTTP requests.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group that contains the
|
||||
// resource to delete. The name is case insensitive. resourceProviderNamespace
|
||||
// is the namespace of the resource provider. parentResourcePath is the parent
|
||||
// resource identity. resourceType is the resource type. resourceName is the
|
||||
// name of the resource to delete.
|
||||
func (client GroupClient) Delete(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, cancel <-chan struct{}) (<-chan autorest.Response, <-chan error) {
|
||||
resultChan := make(chan autorest.Response, 1)
|
||||
errChan := make(chan error, 1)
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
errChan <- validation.NewErrorWithValidationError(err, "resources.GroupClient", "Delete")
|
||||
close(errChan)
|
||||
close(resultChan)
|
||||
return resultChan, errChan
|
||||
}
|
||||
|
||||
go func() {
|
||||
var err error
|
||||
var result autorest.Response
|
||||
defer func() {
|
||||
resultChan <- result
|
||||
errChan <- err
|
||||
close(resultChan)
|
||||
close(errChan)
|
||||
}()
|
||||
req, err := client.DeletePreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, cancel)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "Delete", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.DeleteSender(req)
|
||||
if err != nil {
|
||||
result.Response = resp
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "Delete", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.DeleteResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "Delete", resp, "Failure responding to request")
|
||||
}
|
||||
}()
|
||||
return resultChan, errChan
|
||||
}
|
||||
|
||||
// DeletePreparer prepares the Delete request.
|
||||
func (client GroupClient) DeletePreparer(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, cancel <-chan struct{}) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"parentResourcePath": parentResourcePath,
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"resourceName": autorest.Encode("path", resourceName),
|
||||
"resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace),
|
||||
"resourceType": resourceType,
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsDelete(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{Cancel: cancel})
|
||||
}
|
||||
|
||||
// DeleteSender sends the Delete request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupClient) DeleteSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client,
|
||||
req,
|
||||
azure.DoPollForAsynchronous(client.PollingDelay))
|
||||
}
|
||||
|
||||
// DeleteResponder handles the response to the Delete request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client GroupClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusAccepted),
|
||||
autorest.ByClosing())
|
||||
result.Response = resp
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteByID deletes a resource by ID. This method may poll for completion.
|
||||
// Polling can be canceled by passing the cancel channel argument. The channel
|
||||
// will be used to cancel polling and any outstanding HTTP requests.
|
||||
//
|
||||
// resourceID is the fully qualified ID of the resource, including the resource
|
||||
// name and resource type. Use the format,
|
||||
// /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name}
|
||||
func (client GroupClient) DeleteByID(resourceID string, cancel <-chan struct{}) (<-chan autorest.Response, <-chan error) {
|
||||
resultChan := make(chan autorest.Response, 1)
|
||||
errChan := make(chan error, 1)
|
||||
go func() {
|
||||
var err error
|
||||
var result autorest.Response
|
||||
defer func() {
|
||||
resultChan <- result
|
||||
errChan <- err
|
||||
close(resultChan)
|
||||
close(errChan)
|
||||
}()
|
||||
req, err := client.DeleteByIDPreparer(resourceID, cancel)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "DeleteByID", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.DeleteByIDSender(req)
|
||||
if err != nil {
|
||||
result.Response = resp
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "DeleteByID", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.DeleteByIDResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "DeleteByID", resp, "Failure responding to request")
|
||||
}
|
||||
}()
|
||||
return resultChan, errChan
|
||||
}
|
||||
|
||||
// DeleteByIDPreparer prepares the DeleteByID request.
|
||||
func (client GroupClient) DeleteByIDPreparer(resourceID string, cancel <-chan struct{}) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceId": resourceID,
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsDelete(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/{resourceId}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{Cancel: cancel})
|
||||
}
|
||||
|
||||
// DeleteByIDSender sends the DeleteByID request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupClient) DeleteByIDSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client,
|
||||
req,
|
||||
azure.DoPollForAsynchronous(client.PollingDelay))
|
||||
}
|
||||
|
||||
// DeleteByIDResponder handles the response to the DeleteByID request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client GroupClient) DeleteByIDResponder(resp *http.Response) (result autorest.Response, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusAccepted),
|
||||
autorest.ByClosing())
|
||||
result.Response = resp
|
||||
return
|
||||
}
|
||||
|
||||
// Get gets a resource.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group containing the resource
|
||||
// to get. The name is case insensitive. resourceProviderNamespace is the
|
||||
// namespace of the resource provider. parentResourcePath is the parent
|
||||
// resource identity. resourceType is the resource type of the resource.
|
||||
// resourceName is the name of the resource to get.
|
||||
func (client GroupClient) Get(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (result GenericResource, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.GroupClient", "Get")
|
||||
}
|
||||
|
||||
req, err := client.GetPreparer(resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "Get", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.GetSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "Get", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.GetResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "Get", resp, "Failure responding to request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetPreparer prepares the Get request.
|
||||
func (client GroupClient) GetPreparer(resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"parentResourcePath": parentResourcePath,
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"resourceName": autorest.Encode("path", resourceName),
|
||||
"resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace),
|
||||
"resourceType": resourceType,
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
}
|
||||
|
||||
// GetSender sends the Get request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupClient) GetSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
}
|
||||
|
||||
// GetResponder handles the response to the Get request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client GroupClient) GetResponder(resp *http.Response) (result GenericResource, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// GetByID gets a resource by ID.
|
||||
//
|
||||
// resourceID is the fully qualified ID of the resource, including the resource
|
||||
// name and resource type. Use the format,
|
||||
// /subscriptions/{guid}/resourceGroups/{resource-group-name}/{resource-provider-namespace}/{resource-type}/{resource-name}
|
||||
func (client GroupClient) GetByID(resourceID string) (result GenericResource, err error) {
|
||||
req, err := client.GetByIDPreparer(resourceID)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "GetByID", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.GetByIDSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "GetByID", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.GetByIDResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "GetByID", resp, "Failure responding to request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetByIDPreparer prepares the GetByID request.
|
||||
func (client GroupClient) GetByIDPreparer(resourceID string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceId": resourceID,
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/{resourceId}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
}
|
||||
|
||||
// GetByIDSender sends the GetByID request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupClient) GetByIDSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
}
|
||||
|
||||
// GetByIDResponder handles the response to the GetByID request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client GroupClient) GetByIDResponder(resp *http.Response) (result GenericResource, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// List get all the resources in a subscription.
|
||||
//
|
||||
// filter is the filter to apply on the operation. expand is the $expand query
|
||||
// parameter. top is the number of results to return. If null is passed,
|
||||
// returns all resource groups.
|
||||
func (client GroupClient) List(filter string, expand string, top *int32) (result ListResult, err error) {
|
||||
req, err := client.ListPreparer(filter, expand, top)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "List", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "List", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "List", resp, "Failure responding to request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ListPreparer prepares the List request.
|
||||
func (client GroupClient) ListPreparer(filter string, expand string, top *int32) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
if len(filter) > 0 {
|
||||
queryParameters["$filter"] = autorest.Encode("query", filter)
|
||||
}
|
||||
if len(expand) > 0 {
|
||||
queryParameters["$expand"] = autorest.Encode("query", expand)
|
||||
}
|
||||
if top != nil {
|
||||
queryParameters["$top"] = autorest.Encode("query", *top)
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resources", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
}
|
||||
|
||||
// ListSender sends the List request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupClient) ListSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
}
|
||||
|
||||
// ListResponder handles the response to the List request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client GroupClient) ListResponder(resp *http.Response) (result ListResult, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// ListNextResults retrieves the next set of results, if any.
|
||||
func (client GroupClient) ListNextResults(lastResults ListResult) (result ListResult, err error) {
|
||||
req, err := lastResults.ListResultPreparer()
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "resources.GroupClient", "List", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(err, "resources.GroupClient", "List", resp, "Failure sending next results request")
|
||||
}
|
||||
|
||||
result, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "List", resp, "Failure responding to next results request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// MoveResources the resources to move must be in the same source resource
|
||||
// group. The target resource group may be in a different subscription. When
|
||||
// moving resources, both the source group and the target group are locked for
|
||||
// the duration of the operation. Write and delete operations are blocked on
|
||||
// the groups until the move completes. This method may poll for completion.
|
||||
// Polling can be canceled by passing the cancel channel argument. The channel
|
||||
// will be used to cancel polling and any outstanding HTTP requests.
|
||||
//
|
||||
// sourceResourceGroupName is the name of the resource group containing the
|
||||
// rsources to move. parameters is parameters for moving resources.
|
||||
func (client GroupClient) MoveResources(sourceResourceGroupName string, parameters MoveInfo, cancel <-chan struct{}) (<-chan autorest.Response, <-chan error) {
|
||||
resultChan := make(chan autorest.Response, 1)
|
||||
errChan := make(chan error, 1)
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: sourceResourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "sourceResourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "sourceResourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "sourceResourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
errChan <- validation.NewErrorWithValidationError(err, "resources.GroupClient", "MoveResources")
|
||||
close(errChan)
|
||||
close(resultChan)
|
||||
return resultChan, errChan
|
||||
}
|
||||
|
||||
go func() {
|
||||
var err error
|
||||
var result autorest.Response
|
||||
defer func() {
|
||||
resultChan <- result
|
||||
errChan <- err
|
||||
close(resultChan)
|
||||
close(errChan)
|
||||
}()
|
||||
req, err := client.MoveResourcesPreparer(sourceResourceGroupName, parameters, cancel)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "MoveResources", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.MoveResourcesSender(req)
|
||||
if err != nil {
|
||||
result.Response = resp
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "MoveResources", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.MoveResourcesResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupClient", "MoveResources", resp, "Failure responding to request")
|
||||
}
|
||||
}()
|
||||
return resultChan, errChan
|
||||
}
|
||||
|
||||
// MoveResourcesPreparer prepares the MoveResources request.
|
||||
func (client GroupClient) MoveResourcesPreparer(sourceResourceGroupName string, parameters MoveInfo, cancel <-chan struct{}) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"sourceResourceGroupName": autorest.Encode("path", sourceResourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsJSON(),
|
||||
autorest.AsPost(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{sourceResourceGroupName}/moveResources", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{Cancel: cancel})
|
||||
}
|
||||
|
||||
// MoveResourcesSender sends the MoveResources request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupClient) MoveResourcesSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client,
|
||||
req,
|
||||
azure.DoPollForAsynchronous(client.PollingDelay))
|
||||
}
|
||||
|
||||
// MoveResourcesResponder handles the response to the MoveResources request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client GroupClient) MoveResourcesResponder(resp *http.Response) (result autorest.Response, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent),
|
||||
autorest.ByClosing())
|
||||
result.Response = resp
|
||||
return
|
||||
}
|
|
@ -1,452 +0,0 @@
|
|||
package storage
|
||||
|
||||
// Copyright (c) Microsoft and contributors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
|
||||
// Changes may cause incorrect behavior and will be lost if the code is
|
||||
// regenerated.
|
||||
|
||||
import (
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/date"
|
||||
)
|
||||
|
||||
// AccessTier enumerates the values for access tier.
|
||||
type AccessTier string
|
||||
|
||||
const (
|
||||
// Cool specifies the cool state for access tier.
|
||||
Cool AccessTier = "Cool"
|
||||
// Hot specifies the hot state for access tier.
|
||||
Hot AccessTier = "Hot"
|
||||
)
|
||||
|
||||
// AccountStatus enumerates the values for account status.
|
||||
type AccountStatus string
|
||||
|
||||
const (
|
||||
// Available specifies the available state for account status.
|
||||
Available AccountStatus = "available"
|
||||
// Unavailable specifies the unavailable state for account status.
|
||||
Unavailable AccountStatus = "unavailable"
|
||||
)
|
||||
|
||||
// HTTPProtocol enumerates the values for http protocol.
|
||||
type HTTPProtocol string
|
||||
|
||||
const (
|
||||
// HTTPS specifies the https state for http protocol.
|
||||
HTTPS HTTPProtocol = "https"
|
||||
// Httpshttp specifies the httpshttp state for http protocol.
|
||||
Httpshttp HTTPProtocol = "https,http"
|
||||
)
|
||||
|
||||
// KeyPermission enumerates the values for key permission.
|
||||
type KeyPermission string
|
||||
|
||||
const (
|
||||
// Full specifies the full state for key permission.
|
||||
Full KeyPermission = "Full"
|
||||
// Read specifies the read state for key permission.
|
||||
Read KeyPermission = "Read"
|
||||
)
|
||||
|
||||
// Kind enumerates the values for kind.
|
||||
type Kind string
|
||||
|
||||
const (
|
||||
// BlobStorage specifies the blob storage state for kind.
|
||||
BlobStorage Kind = "BlobStorage"
|
||||
// Storage specifies the storage state for kind.
|
||||
Storage Kind = "Storage"
|
||||
)
|
||||
|
||||
// Permissions enumerates the values for permissions.
|
||||
type Permissions string
|
||||
|
||||
const (
|
||||
// A specifies the a state for permissions.
|
||||
A Permissions = "a"
|
||||
// C specifies the c state for permissions.
|
||||
C Permissions = "c"
|
||||
// D specifies the d state for permissions.
|
||||
D Permissions = "d"
|
||||
// L specifies the l state for permissions.
|
||||
L Permissions = "l"
|
||||
// P specifies the p state for permissions.
|
||||
P Permissions = "p"
|
||||
// R specifies the r state for permissions.
|
||||
R Permissions = "r"
|
||||
// U specifies the u state for permissions.
|
||||
U Permissions = "u"
|
||||
// W specifies the w state for permissions.
|
||||
W Permissions = "w"
|
||||
)
|
||||
|
||||
// Permissions1 enumerates the values for permissions 1.
|
||||
type Permissions1 string
|
||||
|
||||
const (
|
||||
// Permissions1A specifies the permissions 1a state for permissions 1.
|
||||
Permissions1A Permissions1 = "a"
|
||||
// Permissions1C specifies the permissions 1c state for permissions 1.
|
||||
Permissions1C Permissions1 = "c"
|
||||
// Permissions1D specifies the permissions 1d state for permissions 1.
|
||||
Permissions1D Permissions1 = "d"
|
||||
// Permissions1L specifies the permissions 1l state for permissions 1.
|
||||
Permissions1L Permissions1 = "l"
|
||||
// Permissions1P specifies the permissions 1p state for permissions 1.
|
||||
Permissions1P Permissions1 = "p"
|
||||
// Permissions1R specifies the permissions 1r state for permissions 1.
|
||||
Permissions1R Permissions1 = "r"
|
||||
// Permissions1U specifies the permissions 1u state for permissions 1.
|
||||
Permissions1U Permissions1 = "u"
|
||||
// Permissions1W specifies the permissions 1w state for permissions 1.
|
||||
Permissions1W Permissions1 = "w"
|
||||
)
|
||||
|
||||
// ProvisioningState enumerates the values for provisioning state.
|
||||
type ProvisioningState string
|
||||
|
||||
const (
|
||||
// Creating specifies the creating state for provisioning state.
|
||||
Creating ProvisioningState = "Creating"
|
||||
// ResolvingDNS specifies the resolving dns state for provisioning state.
|
||||
ResolvingDNS ProvisioningState = "ResolvingDNS"
|
||||
// Succeeded specifies the succeeded state for provisioning state.
|
||||
Succeeded ProvisioningState = "Succeeded"
|
||||
)
|
||||
|
||||
// Reason enumerates the values for reason.
|
||||
type Reason string
|
||||
|
||||
const (
|
||||
// AccountNameInvalid specifies the account name invalid state for reason.
|
||||
AccountNameInvalid Reason = "AccountNameInvalid"
|
||||
// AlreadyExists specifies the already exists state for reason.
|
||||
AlreadyExists Reason = "AlreadyExists"
|
||||
)
|
||||
|
||||
// ResourceEnum enumerates the values for resource enum.
|
||||
type ResourceEnum string
|
||||
|
||||
const (
|
||||
// ResourceEnumB specifies the resource enum b state for resource enum.
|
||||
ResourceEnumB ResourceEnum = "b"
|
||||
// ResourceEnumC specifies the resource enum c state for resource enum.
|
||||
ResourceEnumC ResourceEnum = "c"
|
||||
// ResourceEnumF specifies the resource enum f state for resource enum.
|
||||
ResourceEnumF ResourceEnum = "f"
|
||||
// ResourceEnumS specifies the resource enum s state for resource enum.
|
||||
ResourceEnumS ResourceEnum = "s"
|
||||
)
|
||||
|
||||
// ResourceTypes enumerates the values for resource types.
|
||||
type ResourceTypes string
|
||||
|
||||
const (
|
||||
// ResourceTypesC specifies the resource types c state for resource types.
|
||||
ResourceTypesC ResourceTypes = "c"
|
||||
// ResourceTypesO specifies the resource types o state for resource types.
|
||||
ResourceTypesO ResourceTypes = "o"
|
||||
// ResourceTypesS specifies the resource types s state for resource types.
|
||||
ResourceTypesS ResourceTypes = "s"
|
||||
)
|
||||
|
||||
// Services enumerates the values for services.
|
||||
type Services string
|
||||
|
||||
const (
|
||||
// B specifies the b state for services.
|
||||
B Services = "b"
|
||||
// F specifies the f state for services.
|
||||
F Services = "f"
|
||||
// Q specifies the q state for services.
|
||||
Q Services = "q"
|
||||
// T specifies the t state for services.
|
||||
T Services = "t"
|
||||
)
|
||||
|
||||
// SkuName enumerates the values for sku name.
|
||||
type SkuName string
|
||||
|
||||
const (
|
||||
// PremiumLRS specifies the premium lrs state for sku name.
|
||||
PremiumLRS SkuName = "Premium_LRS"
|
||||
// StandardGRS specifies the standard grs state for sku name.
|
||||
StandardGRS SkuName = "Standard_GRS"
|
||||
// StandardLRS specifies the standard lrs state for sku name.
|
||||
StandardLRS SkuName = "Standard_LRS"
|
||||
// StandardRAGRS specifies the standard ragrs state for sku name.
|
||||
StandardRAGRS SkuName = "Standard_RAGRS"
|
||||
// StandardZRS specifies the standard zrs state for sku name.
|
||||
StandardZRS SkuName = "Standard_ZRS"
|
||||
)
|
||||
|
||||
// SkuTier enumerates the values for sku tier.
|
||||
type SkuTier string
|
||||
|
||||
const (
|
||||
// Premium specifies the premium state for sku tier.
|
||||
Premium SkuTier = "Premium"
|
||||
// Standard specifies the standard state for sku tier.
|
||||
Standard SkuTier = "Standard"
|
||||
)
|
||||
|
||||
// UsageUnit enumerates the values for usage unit.
|
||||
type UsageUnit string
|
||||
|
||||
const (
|
||||
// Bytes specifies the bytes state for usage unit.
|
||||
Bytes UsageUnit = "Bytes"
|
||||
// BytesPerSecond specifies the bytes per second state for usage unit.
|
||||
BytesPerSecond UsageUnit = "BytesPerSecond"
|
||||
// Count specifies the count state for usage unit.
|
||||
Count UsageUnit = "Count"
|
||||
// CountsPerSecond specifies the counts per second state for usage unit.
|
||||
CountsPerSecond UsageUnit = "CountsPerSecond"
|
||||
// Percent specifies the percent state for usage unit.
|
||||
Percent UsageUnit = "Percent"
|
||||
// Seconds specifies the seconds state for usage unit.
|
||||
Seconds UsageUnit = "Seconds"
|
||||
)
|
||||
|
||||
// Account is the storage account.
|
||||
type Account struct {
|
||||
autorest.Response `json:"-"`
|
||||
ID *string `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Type *string `json:"type,omitempty"`
|
||||
Location *string `json:"location,omitempty"`
|
||||
Tags *map[string]*string `json:"tags,omitempty"`
|
||||
Sku *Sku `json:"sku,omitempty"`
|
||||
Kind Kind `json:"kind,omitempty"`
|
||||
*AccountProperties `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// AccountCheckNameAvailabilityParameters is the parameters used to check the
|
||||
// availabity of the storage account name.
|
||||
type AccountCheckNameAvailabilityParameters struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Type *string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// AccountCreateParameters is the parameters used when creating a storage
|
||||
// account.
|
||||
type AccountCreateParameters struct {
|
||||
Sku *Sku `json:"sku,omitempty"`
|
||||
Kind Kind `json:"kind,omitempty"`
|
||||
Location *string `json:"location,omitempty"`
|
||||
Tags *map[string]*string `json:"tags,omitempty"`
|
||||
*AccountPropertiesCreateParameters `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// AccountKey is an access key for the storage account.
|
||||
type AccountKey struct {
|
||||
KeyName *string `json:"keyName,omitempty"`
|
||||
Value *string `json:"value,omitempty"`
|
||||
Permissions KeyPermission `json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
// AccountListKeysResult is the response from the ListKeys operation.
|
||||
type AccountListKeysResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
Keys *[]AccountKey `json:"keys,omitempty"`
|
||||
}
|
||||
|
||||
// AccountListResult is the response from the List Storage Accounts operation.
|
||||
type AccountListResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
Value *[]Account `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// AccountProperties is properties of the storage account.
|
||||
type AccountProperties struct {
|
||||
ProvisioningState ProvisioningState `json:"provisioningState,omitempty"`
|
||||
PrimaryEndpoints *Endpoints `json:"primaryEndpoints,omitempty"`
|
||||
PrimaryLocation *string `json:"primaryLocation,omitempty"`
|
||||
StatusOfPrimary AccountStatus `json:"statusOfPrimary,omitempty"`
|
||||
LastGeoFailoverTime *date.Time `json:"lastGeoFailoverTime,omitempty"`
|
||||
SecondaryLocation *string `json:"secondaryLocation,omitempty"`
|
||||
StatusOfSecondary AccountStatus `json:"statusOfSecondary,omitempty"`
|
||||
CreationTime *date.Time `json:"creationTime,omitempty"`
|
||||
CustomDomain *CustomDomain `json:"customDomain,omitempty"`
|
||||
SecondaryEndpoints *Endpoints `json:"secondaryEndpoints,omitempty"`
|
||||
Encryption *Encryption `json:"encryption,omitempty"`
|
||||
AccessTier AccessTier `json:"accessTier,omitempty"`
|
||||
EnableHTTPSTrafficOnly *bool `json:"supportsHttpsTrafficOnly,omitempty"`
|
||||
}
|
||||
|
||||
// AccountPropertiesCreateParameters is the parameters used to create the
|
||||
// storage account.
|
||||
type AccountPropertiesCreateParameters struct {
|
||||
CustomDomain *CustomDomain `json:"customDomain,omitempty"`
|
||||
Encryption *Encryption `json:"encryption,omitempty"`
|
||||
AccessTier AccessTier `json:"accessTier,omitempty"`
|
||||
EnableHTTPSTrafficOnly *bool `json:"supportsHttpsTrafficOnly,omitempty"`
|
||||
}
|
||||
|
||||
// AccountPropertiesUpdateParameters is the parameters used when updating a
|
||||
// storage account.
|
||||
type AccountPropertiesUpdateParameters struct {
|
||||
CustomDomain *CustomDomain `json:"customDomain,omitempty"`
|
||||
Encryption *Encryption `json:"encryption,omitempty"`
|
||||
AccessTier AccessTier `json:"accessTier,omitempty"`
|
||||
EnableHTTPSTrafficOnly *bool `json:"supportsHttpsTrafficOnly,omitempty"`
|
||||
}
|
||||
|
||||
// AccountRegenerateKeyParameters is the parameters used to regenerate the
|
||||
// storage account key.
|
||||
type AccountRegenerateKeyParameters struct {
|
||||
KeyName *string `json:"keyName,omitempty"`
|
||||
}
|
||||
|
||||
// AccountSasParameters is the parameters to list SAS credentials of a storage
|
||||
// account.
|
||||
type AccountSasParameters struct {
|
||||
Services Services `json:"signedServices,omitempty"`
|
||||
ResourceTypes ResourceTypes `json:"signedResourceTypes,omitempty"`
|
||||
Permissions Permissions `json:"signedPermission,omitempty"`
|
||||
IPAddressOrRange *string `json:"signedIp,omitempty"`
|
||||
Protocols HTTPProtocol `json:"signedProtocol,omitempty"`
|
||||
SharedAccessStartTime *date.Time `json:"signedStart,omitempty"`
|
||||
SharedAccessExpiryTime *date.Time `json:"signedExpiry,omitempty"`
|
||||
KeyToSign *string `json:"keyToSign,omitempty"`
|
||||
}
|
||||
|
||||
// AccountUpdateParameters is the parameters that can be provided when updating
|
||||
// the storage account properties.
|
||||
type AccountUpdateParameters struct {
|
||||
Sku *Sku `json:"sku,omitempty"`
|
||||
Tags *map[string]*string `json:"tags,omitempty"`
|
||||
*AccountPropertiesUpdateParameters `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// CheckNameAvailabilityResult is the CheckNameAvailability operation response.
|
||||
type CheckNameAvailabilityResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
NameAvailable *bool `json:"nameAvailable,omitempty"`
|
||||
Reason Reason `json:"reason,omitempty"`
|
||||
Message *string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// CustomDomain is the custom domain assigned to this storage account. This can
|
||||
// be set via Update.
|
||||
type CustomDomain struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
UseSubDomain *bool `json:"useSubDomain,omitempty"`
|
||||
}
|
||||
|
||||
// Encryption is the encryption settings on the storage account.
|
||||
type Encryption struct {
|
||||
Services *EncryptionServices `json:"services,omitempty"`
|
||||
KeySource *string `json:"keySource,omitempty"`
|
||||
}
|
||||
|
||||
// EncryptionService is a service that allows server-side encryption to be
|
||||
// used.
|
||||
type EncryptionService struct {
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
LastEnabledTime *date.Time `json:"lastEnabledTime,omitempty"`
|
||||
}
|
||||
|
||||
// EncryptionServices is a list of services that support encryption.
|
||||
type EncryptionServices struct {
|
||||
Blob *EncryptionService `json:"blob,omitempty"`
|
||||
File *EncryptionService `json:"file,omitempty"`
|
||||
Table *EncryptionService `json:"table,omitempty"`
|
||||
Queue *EncryptionService `json:"queue,omitempty"`
|
||||
}
|
||||
|
||||
// Endpoints is the URIs that are used to perform a retrieval of a public blob,
|
||||
// queue, or table object.
|
||||
type Endpoints struct {
|
||||
Blob *string `json:"blob,omitempty"`
|
||||
Queue *string `json:"queue,omitempty"`
|
||||
Table *string `json:"table,omitempty"`
|
||||
File *string `json:"file,omitempty"`
|
||||
}
|
||||
|
||||
// ListAccountSasResponse is the List SAS credentials operation response.
|
||||
type ListAccountSasResponse struct {
|
||||
autorest.Response `json:"-"`
|
||||
AccountSasToken *string `json:"accountSasToken,omitempty"`
|
||||
}
|
||||
|
||||
// ListServiceSasResponse is the List service SAS credentials operation
|
||||
// response.
|
||||
type ListServiceSasResponse struct {
|
||||
autorest.Response `json:"-"`
|
||||
ServiceSasToken *string `json:"serviceSasToken,omitempty"`
|
||||
}
|
||||
|
||||
// Resource is describes a storage resource.
|
||||
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"`
|
||||
}
|
||||
|
||||
// ServiceSasParameters is the parameters to list service SAS credentials of a
|
||||
// speicific resource.
|
||||
type ServiceSasParameters struct {
|
||||
CanonicalizedResource *string `json:"canonicalizedResource,omitempty"`
|
||||
Resource Resource `json:"signedResource,omitempty"`
|
||||
Permissions Permissions `json:"signedPermission,omitempty"`
|
||||
IPAddressOrRange *string `json:"signedIp,omitempty"`
|
||||
Protocols HTTPProtocol `json:"signedProtocol,omitempty"`
|
||||
SharedAccessStartTime *date.Time `json:"signedStart,omitempty"`
|
||||
SharedAccessExpiryTime *date.Time `json:"signedExpiry,omitempty"`
|
||||
Identifier *string `json:"signedIdentifier,omitempty"`
|
||||
PartitionKeyStart *string `json:"startPk,omitempty"`
|
||||
PartitionKeyEnd *string `json:"endPk,omitempty"`
|
||||
RowKeyStart *string `json:"startRk,omitempty"`
|
||||
RowKeyEnd *string `json:"endRk,omitempty"`
|
||||
KeyToSign *string `json:"keyToSign,omitempty"`
|
||||
CacheControl *string `json:"rscc,omitempty"`
|
||||
ContentDisposition *string `json:"rscd,omitempty"`
|
||||
ContentEncoding *string `json:"rsce,omitempty"`
|
||||
ContentLanguage *string `json:"rscl,omitempty"`
|
||||
ContentType *string `json:"rsct,omitempty"`
|
||||
}
|
||||
|
||||
// Sku is the SKU of the storage account.
|
||||
type Sku struct {
|
||||
Name SkuName `json:"name,omitempty"`
|
||||
Tier SkuTier `json:"tier,omitempty"`
|
||||
}
|
||||
|
||||
// Usage is describes Storage Resource Usage.
|
||||
type Usage struct {
|
||||
Unit UsageUnit `json:"unit,omitempty"`
|
||||
CurrentValue *int32 `json:"currentValue,omitempty"`
|
||||
Limit *int32 `json:"limit,omitempty"`
|
||||
Name *UsageName `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// UsageListResult is the response from the List Usages operation.
|
||||
type UsageListResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
Value *[]Usage `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// UsageName is the usage names that can be used; currently limited to
|
||||
// StorageAccount.
|
||||
type UsageName struct {
|
||||
Value *string `json:"value,omitempty"`
|
||||
LocalizedValue *string `json:"localizedValue,omitempty"`
|
||||
}
|
163
vendor/github.com/Azure/azure-sdk-for-go/profiles/2017-03-09/resources/mgmt/resources/models.go
generated
vendored
Normal file
163
vendor/github.com/Azure/azure-sdk-for-go/profiles/2017-03-09/resources/mgmt/resources/models.go
generated
vendored
Normal file
|
@ -0,0 +1,163 @@
|
|||
// +build go1.9
|
||||
|
||||
// Copyright 2018 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.
|
||||
|
||||
// This code was auto-generated by:
|
||||
// github.com/Azure/azure-sdk-for-go/tools/profileBuilder
|
||||
|
||||
package resources
|
||||
|
||||
import original "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-02-01/resources"
|
||||
|
||||
const (
|
||||
DefaultBaseURI = original.DefaultBaseURI
|
||||
)
|
||||
|
||||
type BaseClient = original.BaseClient
|
||||
type DeploymentOperationsClient = original.DeploymentOperationsClient
|
||||
type DeploymentsClient = original.DeploymentsClient
|
||||
type GroupsClient = original.GroupsClient
|
||||
type DeploymentMode = original.DeploymentMode
|
||||
|
||||
const (
|
||||
Complete DeploymentMode = original.Complete
|
||||
Incremental DeploymentMode = original.Incremental
|
||||
)
|
||||
|
||||
type ResourceIdentityType = original.ResourceIdentityType
|
||||
|
||||
const (
|
||||
SystemAssigned ResourceIdentityType = original.SystemAssigned
|
||||
)
|
||||
|
||||
type AliasPathType = original.AliasPathType
|
||||
type AliasType = original.AliasType
|
||||
type BasicDependency = original.BasicDependency
|
||||
type DebugSetting = original.DebugSetting
|
||||
type Dependency = original.Dependency
|
||||
type Deployment = original.Deployment
|
||||
type DeploymentExportResult = original.DeploymentExportResult
|
||||
type DeploymentExtended = original.DeploymentExtended
|
||||
type DeploymentExtendedFilter = original.DeploymentExtendedFilter
|
||||
type DeploymentListResult = original.DeploymentListResult
|
||||
type DeploymentListResultIterator = original.DeploymentListResultIterator
|
||||
type DeploymentListResultPage = original.DeploymentListResultPage
|
||||
type DeploymentOperation = original.DeploymentOperation
|
||||
type DeploymentOperationProperties = original.DeploymentOperationProperties
|
||||
type DeploymentOperationsListResult = original.DeploymentOperationsListResult
|
||||
type DeploymentOperationsListResultIterator = original.DeploymentOperationsListResultIterator
|
||||
type DeploymentOperationsListResultPage = original.DeploymentOperationsListResultPage
|
||||
type DeploymentProperties = original.DeploymentProperties
|
||||
type DeploymentPropertiesExtended = original.DeploymentPropertiesExtended
|
||||
type DeploymentsCreateOrUpdateFuture = original.DeploymentsCreateOrUpdateFuture
|
||||
type DeploymentsDeleteFuture = original.DeploymentsDeleteFuture
|
||||
type DeploymentValidateResult = original.DeploymentValidateResult
|
||||
type ExportTemplateRequest = original.ExportTemplateRequest
|
||||
type GenericResource = original.GenericResource
|
||||
type GenericResourceFilter = original.GenericResourceFilter
|
||||
type Group = original.Group
|
||||
type GroupExportResult = original.GroupExportResult
|
||||
type GroupFilter = original.GroupFilter
|
||||
type GroupListResult = original.GroupListResult
|
||||
type GroupListResultIterator = original.GroupListResultIterator
|
||||
type GroupListResultPage = original.GroupListResultPage
|
||||
type GroupProperties = original.GroupProperties
|
||||
type GroupsDeleteFuture = original.GroupsDeleteFuture
|
||||
type HTTPMessage = original.HTTPMessage
|
||||
type Identity = original.Identity
|
||||
type ListResult = original.ListResult
|
||||
type ListResultIterator = original.ListResultIterator
|
||||
type ListResultPage = original.ListResultPage
|
||||
type ManagementErrorWithDetails = original.ManagementErrorWithDetails
|
||||
type MoveInfo = original.MoveInfo
|
||||
type MoveResourcesFuture = original.MoveResourcesFuture
|
||||
type ParametersLink = original.ParametersLink
|
||||
type Plan = original.Plan
|
||||
type Provider = original.Provider
|
||||
type ProviderListResult = original.ProviderListResult
|
||||
type ProviderListResultIterator = original.ProviderListResultIterator
|
||||
type ProviderListResultPage = original.ProviderListResultPage
|
||||
type ProviderOperationDisplayProperties = original.ProviderOperationDisplayProperties
|
||||
type ProviderResourceType = original.ProviderResourceType
|
||||
type Resource = original.Resource
|
||||
type Sku = original.Sku
|
||||
type SubResource = original.SubResource
|
||||
type TagCount = original.TagCount
|
||||
type TagDetails = original.TagDetails
|
||||
type TagsListResult = original.TagsListResult
|
||||
type TagsListResultIterator = original.TagsListResultIterator
|
||||
type TagsListResultPage = original.TagsListResultPage
|
||||
type TagValue = original.TagValue
|
||||
type TargetResource = original.TargetResource
|
||||
type TemplateLink = original.TemplateLink
|
||||
type UpdateFuture = original.UpdateFuture
|
||||
type ProvidersClient = original.ProvidersClient
|
||||
type Client = original.Client
|
||||
type TagsClient = original.TagsClient
|
||||
|
||||
func New(subscriptionID string) BaseClient {
|
||||
return original.New(subscriptionID)
|
||||
}
|
||||
func NewWithBaseURI(baseURI string, subscriptionID string) BaseClient {
|
||||
return original.NewWithBaseURI(baseURI, subscriptionID)
|
||||
}
|
||||
func NewDeploymentOperationsClient(subscriptionID string) DeploymentOperationsClient {
|
||||
return original.NewDeploymentOperationsClient(subscriptionID)
|
||||
}
|
||||
func NewDeploymentOperationsClientWithBaseURI(baseURI string, subscriptionID string) DeploymentOperationsClient {
|
||||
return original.NewDeploymentOperationsClientWithBaseURI(baseURI, subscriptionID)
|
||||
}
|
||||
func NewDeploymentsClient(subscriptionID string) DeploymentsClient {
|
||||
return original.NewDeploymentsClient(subscriptionID)
|
||||
}
|
||||
func NewDeploymentsClientWithBaseURI(baseURI string, subscriptionID string) DeploymentsClient {
|
||||
return original.NewDeploymentsClientWithBaseURI(baseURI, subscriptionID)
|
||||
}
|
||||
func NewGroupsClient(subscriptionID string) GroupsClient {
|
||||
return original.NewGroupsClient(subscriptionID)
|
||||
}
|
||||
func NewGroupsClientWithBaseURI(baseURI string, subscriptionID string) GroupsClient {
|
||||
return original.NewGroupsClientWithBaseURI(baseURI, subscriptionID)
|
||||
}
|
||||
func PossibleDeploymentModeValues() []DeploymentMode {
|
||||
return original.PossibleDeploymentModeValues()
|
||||
}
|
||||
func PossibleResourceIdentityTypeValues() []ResourceIdentityType {
|
||||
return original.PossibleResourceIdentityTypeValues()
|
||||
}
|
||||
func NewProvidersClient(subscriptionID string) ProvidersClient {
|
||||
return original.NewProvidersClient(subscriptionID)
|
||||
}
|
||||
func NewProvidersClientWithBaseURI(baseURI string, subscriptionID string) ProvidersClient {
|
||||
return original.NewProvidersClientWithBaseURI(baseURI, subscriptionID)
|
||||
}
|
||||
func NewClient(subscriptionID string) Client {
|
||||
return original.NewClient(subscriptionID)
|
||||
}
|
||||
func NewClientWithBaseURI(baseURI string, subscriptionID string) Client {
|
||||
return original.NewClientWithBaseURI(baseURI, subscriptionID)
|
||||
}
|
||||
func NewTagsClient(subscriptionID string) TagsClient {
|
||||
return original.NewTagsClient(subscriptionID)
|
||||
}
|
||||
func NewTagsClientWithBaseURI(baseURI string, subscriptionID string) TagsClient {
|
||||
return original.NewTagsClientWithBaseURI(baseURI, subscriptionID)
|
||||
}
|
||||
func UserAgent() string {
|
||||
return original.UserAgent() + " profiles/2017-03-09"
|
||||
}
|
||||
func Version() string {
|
||||
return original.Version()
|
||||
}
|
177
vendor/github.com/Azure/azure-sdk-for-go/profiles/2017-03-09/storage/mgmt/storage/models.go
generated
vendored
Normal file
177
vendor/github.com/Azure/azure-sdk-for-go/profiles/2017-03-09/storage/mgmt/storage/models.go
generated
vendored
Normal file
|
@ -0,0 +1,177 @@
|
|||
// +build go1.9
|
||||
|
||||
// Copyright 2018 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.
|
||||
|
||||
// This code was auto-generated by:
|
||||
// github.com/Azure/azure-sdk-for-go/tools/profileBuilder
|
||||
|
||||
package storage
|
||||
|
||||
import original "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2016-01-01/storage"
|
||||
|
||||
type AccountsClient = original.AccountsClient
|
||||
|
||||
const (
|
||||
DefaultBaseURI = original.DefaultBaseURI
|
||||
)
|
||||
|
||||
type BaseClient = original.BaseClient
|
||||
type AccessTier = original.AccessTier
|
||||
|
||||
const (
|
||||
Cool AccessTier = original.Cool
|
||||
Hot AccessTier = original.Hot
|
||||
)
|
||||
|
||||
type AccountStatus = original.AccountStatus
|
||||
|
||||
const (
|
||||
Available AccountStatus = original.Available
|
||||
Unavailable AccountStatus = original.Unavailable
|
||||
)
|
||||
|
||||
type KeyPermission = original.KeyPermission
|
||||
|
||||
const (
|
||||
FULL KeyPermission = original.FULL
|
||||
READ KeyPermission = original.READ
|
||||
)
|
||||
|
||||
type Kind = original.Kind
|
||||
|
||||
const (
|
||||
BlobStorage Kind = original.BlobStorage
|
||||
Storage Kind = original.Storage
|
||||
)
|
||||
|
||||
type ProvisioningState = original.ProvisioningState
|
||||
|
||||
const (
|
||||
Creating ProvisioningState = original.Creating
|
||||
ResolvingDNS ProvisioningState = original.ResolvingDNS
|
||||
Succeeded ProvisioningState = original.Succeeded
|
||||
)
|
||||
|
||||
type Reason = original.Reason
|
||||
|
||||
const (
|
||||
AccountNameInvalid Reason = original.AccountNameInvalid
|
||||
AlreadyExists Reason = original.AlreadyExists
|
||||
)
|
||||
|
||||
type SkuName = original.SkuName
|
||||
|
||||
const (
|
||||
PremiumLRS SkuName = original.PremiumLRS
|
||||
StandardGRS SkuName = original.StandardGRS
|
||||
StandardLRS SkuName = original.StandardLRS
|
||||
StandardRAGRS SkuName = original.StandardRAGRS
|
||||
StandardZRS SkuName = original.StandardZRS
|
||||
)
|
||||
|
||||
type SkuTier = original.SkuTier
|
||||
|
||||
const (
|
||||
Premium SkuTier = original.Premium
|
||||
Standard SkuTier = original.Standard
|
||||
)
|
||||
|
||||
type UsageUnit = original.UsageUnit
|
||||
|
||||
const (
|
||||
Bytes UsageUnit = original.Bytes
|
||||
BytesPerSecond UsageUnit = original.BytesPerSecond
|
||||
Count UsageUnit = original.Count
|
||||
CountsPerSecond UsageUnit = original.CountsPerSecond
|
||||
Percent UsageUnit = original.Percent
|
||||
Seconds UsageUnit = original.Seconds
|
||||
)
|
||||
|
||||
type Account = original.Account
|
||||
type AccountCheckNameAvailabilityParameters = original.AccountCheckNameAvailabilityParameters
|
||||
type AccountCreateParameters = original.AccountCreateParameters
|
||||
type AccountKey = original.AccountKey
|
||||
type AccountListKeysResult = original.AccountListKeysResult
|
||||
type AccountListResult = original.AccountListResult
|
||||
type AccountProperties = original.AccountProperties
|
||||
type AccountPropertiesCreateParameters = original.AccountPropertiesCreateParameters
|
||||
type AccountPropertiesUpdateParameters = original.AccountPropertiesUpdateParameters
|
||||
type AccountRegenerateKeyParameters = original.AccountRegenerateKeyParameters
|
||||
type AccountsCreateFuture = original.AccountsCreateFuture
|
||||
type AccountUpdateParameters = original.AccountUpdateParameters
|
||||
type CheckNameAvailabilityResult = original.CheckNameAvailabilityResult
|
||||
type CustomDomain = original.CustomDomain
|
||||
type Encryption = original.Encryption
|
||||
type EncryptionService = original.EncryptionService
|
||||
type EncryptionServices = original.EncryptionServices
|
||||
type Endpoints = original.Endpoints
|
||||
type Resource = original.Resource
|
||||
type Sku = original.Sku
|
||||
type Usage = original.Usage
|
||||
type UsageListResult = original.UsageListResult
|
||||
type UsageName = original.UsageName
|
||||
type UsageClient = original.UsageClient
|
||||
|
||||
func NewAccountsClient(subscriptionID string) AccountsClient {
|
||||
return original.NewAccountsClient(subscriptionID)
|
||||
}
|
||||
func NewAccountsClientWithBaseURI(baseURI string, subscriptionID string) AccountsClient {
|
||||
return original.NewAccountsClientWithBaseURI(baseURI, subscriptionID)
|
||||
}
|
||||
func New(subscriptionID string) BaseClient {
|
||||
return original.New(subscriptionID)
|
||||
}
|
||||
func NewWithBaseURI(baseURI string, subscriptionID string) BaseClient {
|
||||
return original.NewWithBaseURI(baseURI, subscriptionID)
|
||||
}
|
||||
func PossibleAccessTierValues() []AccessTier {
|
||||
return original.PossibleAccessTierValues()
|
||||
}
|
||||
func PossibleAccountStatusValues() []AccountStatus {
|
||||
return original.PossibleAccountStatusValues()
|
||||
}
|
||||
func PossibleKeyPermissionValues() []KeyPermission {
|
||||
return original.PossibleKeyPermissionValues()
|
||||
}
|
||||
func PossibleKindValues() []Kind {
|
||||
return original.PossibleKindValues()
|
||||
}
|
||||
func PossibleProvisioningStateValues() []ProvisioningState {
|
||||
return original.PossibleProvisioningStateValues()
|
||||
}
|
||||
func PossibleReasonValues() []Reason {
|
||||
return original.PossibleReasonValues()
|
||||
}
|
||||
func PossibleSkuNameValues() []SkuName {
|
||||
return original.PossibleSkuNameValues()
|
||||
}
|
||||
func PossibleSkuTierValues() []SkuTier {
|
||||
return original.PossibleSkuTierValues()
|
||||
}
|
||||
func PossibleUsageUnitValues() []UsageUnit {
|
||||
return original.PossibleUsageUnitValues()
|
||||
}
|
||||
func NewUsageClient(subscriptionID string) UsageClient {
|
||||
return original.NewUsageClient(subscriptionID)
|
||||
}
|
||||
func NewUsageClientWithBaseURI(baseURI string, subscriptionID string) UsageClient {
|
||||
return original.NewUsageClientWithBaseURI(baseURI, subscriptionID)
|
||||
}
|
||||
func UserAgent() string {
|
||||
return original.UserAgent() + " profiles/2017-03-09"
|
||||
}
|
||||
func Version() string {
|
||||
return original.Version()
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
// Package resources implements the Azure ARM Resources service API version
|
||||
// 2016-09-01.
|
||||
// Package resources implements the Azure ARM Resources service API version 2016-02-01.
|
||||
//
|
||||
//
|
||||
// Provides operations for working with resources and resource groups.
|
||||
package resources
|
||||
|
||||
// Copyright (c) Microsoft and contributors. All rights reserved.
|
||||
|
@ -18,9 +17,8 @@ package resources
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
|
||||
// Changes may cause incorrect behavior and will be lost if the code is
|
||||
// regenerated.
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
|
@ -31,21 +29,21 @@ const (
|
|||
DefaultBaseURI = "https://management.azure.com"
|
||||
)
|
||||
|
||||
// ManagementClient is the base client for Resources.
|
||||
type ManagementClient struct {
|
||||
// BaseClient is the base client for Resources.
|
||||
type BaseClient struct {
|
||||
autorest.Client
|
||||
BaseURI string
|
||||
SubscriptionID string
|
||||
}
|
||||
|
||||
// New creates an instance of the ManagementClient client.
|
||||
func New(subscriptionID string) ManagementClient {
|
||||
// New creates an instance of the BaseClient client.
|
||||
func New(subscriptionID string) BaseClient {
|
||||
return NewWithBaseURI(DefaultBaseURI, subscriptionID)
|
||||
}
|
||||
|
||||
// NewWithBaseURI creates an instance of the ManagementClient client.
|
||||
func NewWithBaseURI(baseURI string, subscriptionID string) ManagementClient {
|
||||
return ManagementClient{
|
||||
// NewWithBaseURI creates an instance of the BaseClient client.
|
||||
func NewWithBaseURI(baseURI string, subscriptionID string) BaseClient {
|
||||
return BaseClient{
|
||||
Client: autorest.NewClientWithUserAgent(UserAgent()),
|
||||
BaseURI: baseURI,
|
||||
SubscriptionID: subscriptionID,
|
|
@ -14,54 +14,47 @@ package resources
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
|
||||
// Changes may cause incorrect behavior and will be lost if the code is
|
||||
// regenerated.
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/validation"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// DeploymentOperationsClient is the provides operations for working with
|
||||
// resources and resource groups.
|
||||
// DeploymentOperationsClient is the client for the DeploymentOperations methods of the Resources service.
|
||||
type DeploymentOperationsClient struct {
|
||||
ManagementClient
|
||||
BaseClient
|
||||
}
|
||||
|
||||
// NewDeploymentOperationsClient creates an instance of the
|
||||
// DeploymentOperationsClient client.
|
||||
// NewDeploymentOperationsClient creates an instance of the DeploymentOperationsClient client.
|
||||
func NewDeploymentOperationsClient(subscriptionID string) DeploymentOperationsClient {
|
||||
return NewDeploymentOperationsClientWithBaseURI(DefaultBaseURI, subscriptionID)
|
||||
}
|
||||
|
||||
// NewDeploymentOperationsClientWithBaseURI creates an instance of the
|
||||
// DeploymentOperationsClient client.
|
||||
// NewDeploymentOperationsClientWithBaseURI creates an instance of the DeploymentOperationsClient client.
|
||||
func NewDeploymentOperationsClientWithBaseURI(baseURI string, subscriptionID string) DeploymentOperationsClient {
|
||||
return DeploymentOperationsClient{NewWithBaseURI(baseURI, subscriptionID)}
|
||||
}
|
||||
|
||||
// Get gets a deployments operation.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group. The name is case
|
||||
// insensitive. deploymentName is the name of the deployment. operationID is
|
||||
// the ID of the operation to get.
|
||||
func (client DeploymentOperationsClient) Get(resourceGroupName string, deploymentName string, operationID string) (result DeploymentOperation, err error) {
|
||||
// Get get a list of deployments operations.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group. The name is case insensitive.
|
||||
// deploymentName - the name of the deployment.
|
||||
// operationID - operation Id.
|
||||
func (client DeploymentOperationsClient) Get(ctx context.Context, resourceGroupName string, deploymentName string, operationID string) (result DeploymentOperation, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: deploymentName,
|
||||
Constraints: []validation.Constraint{{Target: "deploymentName", Name: validation.MaxLength, Rule: 64, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.DeploymentOperationsClient", "Get")
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewError("resources.DeploymentOperationsClient", "Get", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.GetPreparer(resourceGroupName, deploymentName, operationID)
|
||||
req, err := client.GetPreparer(ctx, resourceGroupName, deploymentName, operationID)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "Get", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -83,7 +76,7 @@ func (client DeploymentOperationsClient) Get(resourceGroupName string, deploymen
|
|||
}
|
||||
|
||||
// GetPreparer prepares the Get request.
|
||||
func (client DeploymentOperationsClient) GetPreparer(resourceGroupName string, deploymentName string, operationID string) (*http.Request, error) {
|
||||
func (client DeploymentOperationsClient) GetPreparer(ctx context.Context, resourceGroupName string, deploymentName string, operationID string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"deploymentName": autorest.Encode("path", deploymentName),
|
||||
"operationId": autorest.Encode("path", operationID),
|
||||
|
@ -91,7 +84,7 @@ func (client DeploymentOperationsClient) GetPreparer(resourceGroupName string, d
|
|||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -101,13 +94,14 @@ func (client DeploymentOperationsClient) GetPreparer(resourceGroupName string, d
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/deployments/{deploymentName}/operations/{operationId}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// GetSender sends the Get request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client DeploymentOperationsClient) GetSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// GetResponder handles the response to the Get request. The method always
|
||||
|
@ -123,25 +117,22 @@ func (client DeploymentOperationsClient) GetResponder(resp *http.Response) (resu
|
|||
return
|
||||
}
|
||||
|
||||
// List gets all deployments operations for a deployment.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group. The name is case
|
||||
// insensitive. deploymentName is the name of the deployment with the operation
|
||||
// to get. top is the number of results to return.
|
||||
func (client DeploymentOperationsClient) List(resourceGroupName string, deploymentName string, top *int32) (result DeploymentOperationsListResult, err error) {
|
||||
// List gets a list of deployments operations.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group. The name is case insensitive.
|
||||
// deploymentName - the name of the deployment.
|
||||
// top - query parameters.
|
||||
func (client DeploymentOperationsClient) List(ctx context.Context, resourceGroupName string, deploymentName string, top *int32) (result DeploymentOperationsListResultPage, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: deploymentName,
|
||||
Constraints: []validation.Constraint{{Target: "deploymentName", Name: validation.MaxLength, Rule: 64, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.DeploymentOperationsClient", "List")
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewError("resources.DeploymentOperationsClient", "List", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.ListPreparer(resourceGroupName, deploymentName, top)
|
||||
result.fn = client.listNextResults
|
||||
req, err := client.ListPreparer(ctx, resourceGroupName, deploymentName, top)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "List", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -149,12 +140,12 @@ func (client DeploymentOperationsClient) List(resourceGroupName string, deployme
|
|||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
result.dolr.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "List", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.ListResponder(resp)
|
||||
result.dolr, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "List", resp, "Failure responding to request")
|
||||
}
|
||||
|
@ -163,14 +154,14 @@ func (client DeploymentOperationsClient) List(resourceGroupName string, deployme
|
|||
}
|
||||
|
||||
// ListPreparer prepares the List request.
|
||||
func (client DeploymentOperationsClient) ListPreparer(resourceGroupName string, deploymentName string, top *int32) (*http.Request, error) {
|
||||
func (client DeploymentOperationsClient) ListPreparer(ctx context.Context, resourceGroupName string, deploymentName string, top *int32) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"deploymentName": autorest.Encode("path", deploymentName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -183,13 +174,14 @@ func (client DeploymentOperationsClient) ListPreparer(resourceGroupName string,
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/deployments/{deploymentName}/operations", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListSender sends the List request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client DeploymentOperationsClient) ListSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListResponder handles the response to the List request. The method always
|
||||
|
@ -205,26 +197,29 @@ func (client DeploymentOperationsClient) ListResponder(resp *http.Response) (res
|
|||
return
|
||||
}
|
||||
|
||||
// ListNextResults retrieves the next set of results, if any.
|
||||
func (client DeploymentOperationsClient) ListNextResults(lastResults DeploymentOperationsListResult) (result DeploymentOperationsListResult, err error) {
|
||||
req, err := lastResults.DeploymentOperationsListResultPreparer()
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (client DeploymentOperationsClient) listNextResults(lastResults DeploymentOperationsListResult) (result DeploymentOperationsListResult, err error) {
|
||||
req, err := lastResults.deploymentOperationsListResultPreparer()
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "List", nil, "Failure preparing next results request")
|
||||
return result, autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "List", resp, "Failure sending next results request")
|
||||
return result, autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
|
||||
result, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "List", resp, "Failure responding to next results request")
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentOperationsClient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ListComplete enumerates all values, automatically crossing page boundaries as required.
|
||||
func (client DeploymentOperationsClient) ListComplete(ctx context.Context, resourceGroupName string, deploymentName string, top *int32) (result DeploymentOperationsListResultIterator, err error) {
|
||||
result.page, err = client.List(ctx, resourceGroupName, deploymentName, top)
|
||||
return
|
||||
}
|
|
@ -14,21 +14,20 @@ package resources
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
|
||||
// Changes may cause incorrect behavior and will be lost if the code is
|
||||
// regenerated.
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/validation"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// DeploymentsClient is the provides operations for working with resources and
|
||||
// resource groups.
|
||||
// DeploymentsClient is the client for the Deployments methods of the Resources service.
|
||||
type DeploymentsClient struct {
|
||||
ManagementClient
|
||||
BaseClient
|
||||
}
|
||||
|
||||
// NewDeploymentsClient creates an instance of the DeploymentsClient client.
|
||||
|
@ -36,33 +35,25 @@ func NewDeploymentsClient(subscriptionID string) DeploymentsClient {
|
|||
return NewDeploymentsClientWithBaseURI(DefaultBaseURI, subscriptionID)
|
||||
}
|
||||
|
||||
// NewDeploymentsClientWithBaseURI creates an instance of the DeploymentsClient
|
||||
// client.
|
||||
// NewDeploymentsClientWithBaseURI creates an instance of the DeploymentsClient client.
|
||||
func NewDeploymentsClientWithBaseURI(baseURI string, subscriptionID string) DeploymentsClient {
|
||||
return DeploymentsClient{NewWithBaseURI(baseURI, subscriptionID)}
|
||||
}
|
||||
|
||||
// Cancel you can cancel a deployment only if the provisioningState is Accepted
|
||||
// or Running. After the deployment is canceled, the provisioningState is set
|
||||
// to Canceled. Canceling a template deployment stops the currently running
|
||||
// template deployment and leaves the resource group partially deployed.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group. The name is case
|
||||
// insensitive. deploymentName is the name of the deployment to cancel.
|
||||
func (client DeploymentsClient) Cancel(resourceGroupName string, deploymentName string) (result autorest.Response, err error) {
|
||||
// Cancel cancel a currently running template deployment.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group. The name is case insensitive.
|
||||
// deploymentName - the name of the deployment.
|
||||
func (client DeploymentsClient) Cancel(ctx context.Context, resourceGroupName string, deploymentName string) (result autorest.Response, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: deploymentName,
|
||||
Constraints: []validation.Constraint{{Target: "deploymentName", Name: validation.MaxLength, Rule: 64, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "Cancel")
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewError("resources.DeploymentsClient", "Cancel", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.CancelPreparer(resourceGroupName, deploymentName)
|
||||
req, err := client.CancelPreparer(ctx, resourceGroupName, deploymentName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Cancel", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -84,14 +75,14 @@ func (client DeploymentsClient) Cancel(resourceGroupName string, deploymentName
|
|||
}
|
||||
|
||||
// CancelPreparer prepares the Cancel request.
|
||||
func (client DeploymentsClient) CancelPreparer(resourceGroupName string, deploymentName string) (*http.Request, error) {
|
||||
func (client DeploymentsClient) CancelPreparer(ctx context.Context, resourceGroupName string, deploymentName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"deploymentName": autorest.Encode("path", deploymentName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -101,13 +92,14 @@ func (client DeploymentsClient) CancelPreparer(resourceGroupName string, deploym
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/cancel", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// CancelSender sends the Cancel request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client DeploymentsClient) CancelSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// CancelResponder handles the response to the Cancel request. The method always
|
||||
|
@ -122,25 +114,20 @@ func (client DeploymentsClient) CancelResponder(resp *http.Response) (result aut
|
|||
return
|
||||
}
|
||||
|
||||
// CheckExistence checks whether the deployment exists.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group with the deployment to
|
||||
// check. The name is case insensitive. deploymentName is the name of the
|
||||
// deployment to check.
|
||||
func (client DeploymentsClient) CheckExistence(resourceGroupName string, deploymentName string) (result autorest.Response, err error) {
|
||||
// CheckExistence checks whether deployment exists.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group to check. The name is case insensitive.
|
||||
// deploymentName - the name of the deployment.
|
||||
func (client DeploymentsClient) CheckExistence(ctx context.Context, resourceGroupName string, deploymentName string) (result autorest.Response, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: deploymentName,
|
||||
Constraints: []validation.Constraint{{Target: "deploymentName", Name: validation.MaxLength, Rule: 64, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "CheckExistence")
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewError("resources.DeploymentsClient", "CheckExistence", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.CheckExistencePreparer(resourceGroupName, deploymentName)
|
||||
req, err := client.CheckExistencePreparer(ctx, resourceGroupName, deploymentName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "CheckExistence", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -162,14 +149,14 @@ func (client DeploymentsClient) CheckExistence(resourceGroupName string, deploym
|
|||
}
|
||||
|
||||
// CheckExistencePreparer prepares the CheckExistence request.
|
||||
func (client DeploymentsClient) CheckExistencePreparer(resourceGroupName string, deploymentName string) (*http.Request, error) {
|
||||
func (client DeploymentsClient) CheckExistencePreparer(ctx context.Context, resourceGroupName string, deploymentName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"deploymentName": autorest.Encode("path", deploymentName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -179,13 +166,14 @@ func (client DeploymentsClient) CheckExistencePreparer(resourceGroupName string,
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// CheckExistenceSender sends the CheckExistence request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client DeploymentsClient) CheckExistenceSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// CheckExistenceResponder handles the response to the CheckExistence request. The method always
|
||||
|
@ -200,99 +188,76 @@ func (client DeploymentsClient) CheckExistenceResponder(resp *http.Response) (re
|
|||
return
|
||||
}
|
||||
|
||||
// CreateOrUpdate you can provide the template and parameters directly in the
|
||||
// request or link to JSON files. This method may poll for completion. Polling
|
||||
// can be canceled by passing the cancel channel argument. The channel will be
|
||||
// used to cancel polling and any outstanding HTTP requests.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group to deploy the resources
|
||||
// to. The name is case insensitive. The resource group must already exist.
|
||||
// deploymentName is the name of the deployment. parameters is additional
|
||||
// parameters supplied to the operation.
|
||||
func (client DeploymentsClient) CreateOrUpdate(resourceGroupName string, deploymentName string, parameters Deployment, cancel <-chan struct{}) (<-chan DeploymentExtended, <-chan error) {
|
||||
resultChan := make(chan DeploymentExtended, 1)
|
||||
errChan := make(chan error, 1)
|
||||
// CreateOrUpdate create a named template deployment using a template.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group. The name is case insensitive.
|
||||
// deploymentName - the name of the deployment.
|
||||
// parameters - additional parameters supplied to the operation.
|
||||
func (client DeploymentsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, deploymentName string, parameters Deployment) (result DeploymentsCreateOrUpdateFuture, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: deploymentName,
|
||||
Constraints: []validation.Constraint{{Target: "deploymentName", Name: validation.MaxLength, Rule: 64, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: parameters,
|
||||
Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: true,
|
||||
Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false,
|
||||
Chain: []validation.Constraint{{Target: "parameters.Properties.TemplateLink", Name: validation.Null, Rule: false,
|
||||
Chain: []validation.Constraint{{Target: "parameters.Properties.TemplateLink.URI", Name: validation.Null, Rule: true, Chain: nil}}},
|
||||
{Target: "parameters.Properties.ParametersLink", Name: validation.Null, Rule: false,
|
||||
Chain: []validation.Constraint{{Target: "parameters.Properties.ParametersLink.URI", Name: validation.Null, Rule: true, Chain: nil}}},
|
||||
}}}}}); err != nil {
|
||||
errChan <- validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "CreateOrUpdate")
|
||||
close(errChan)
|
||||
close(resultChan)
|
||||
return resultChan, errChan
|
||||
return result, validation.NewError("resources.DeploymentsClient", "CreateOrUpdate", err.Error())
|
||||
}
|
||||
|
||||
go func() {
|
||||
var err error
|
||||
var result DeploymentExtended
|
||||
defer func() {
|
||||
resultChan <- result
|
||||
errChan <- err
|
||||
close(resultChan)
|
||||
close(errChan)
|
||||
}()
|
||||
req, err := client.CreateOrUpdatePreparer(resourceGroupName, deploymentName, parameters, cancel)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "CreateOrUpdate", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, deploymentName, parameters)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "CreateOrUpdate", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.CreateOrUpdateSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "CreateOrUpdate", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
result, err = client.CreateOrUpdateSender(req)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "CreateOrUpdate", result.Response(), "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.CreateOrUpdateResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "CreateOrUpdate", resp, "Failure responding to request")
|
||||
}
|
||||
}()
|
||||
return resultChan, errChan
|
||||
return
|
||||
}
|
||||
|
||||
// CreateOrUpdatePreparer prepares the CreateOrUpdate request.
|
||||
func (client DeploymentsClient) CreateOrUpdatePreparer(resourceGroupName string, deploymentName string, parameters Deployment, cancel <-chan struct{}) (*http.Request, error) {
|
||||
func (client DeploymentsClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, deploymentName string, parameters Deployment) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"deploymentName": autorest.Encode("path", deploymentName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsJSON(),
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{Cancel: cancel})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client DeploymentsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client,
|
||||
req,
|
||||
azure.DoPollForAsynchronous(client.PollingDelay))
|
||||
func (client DeploymentsClient) CreateOrUpdateSender(req *http.Request) (future DeploymentsCreateOrUpdateFuture, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
future.Future, err = azure.NewFutureFromResponse(resp)
|
||||
return
|
||||
}
|
||||
|
||||
// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always
|
||||
|
@ -308,80 +273,43 @@ func (client DeploymentsClient) CreateOrUpdateResponder(resp *http.Response) (re
|
|||
return
|
||||
}
|
||||
|
||||
// Delete a template deployment that is currently running cannot be deleted.
|
||||
// Deleting a template deployment removes the associated deployment operations.
|
||||
// Deleting a template deployment does not affect the state of the resource
|
||||
// group. This is an asynchronous operation that returns a status of 202 until
|
||||
// the template deployment is successfully deleted. The Location response
|
||||
// header contains the URI that is used to obtain the status of the process.
|
||||
// While the process is running, a call to the URI in the Location header
|
||||
// returns a status of 202. When the process finishes, the URI in the Location
|
||||
// header returns a status of 204 on success. If the asynchronous request
|
||||
// failed, the URI in the Location header returns an error-level status code.
|
||||
// This method may poll for completion. Polling can be canceled by passing the
|
||||
// cancel channel argument. The channel will be used to cancel polling and any
|
||||
// outstanding HTTP requests.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group with the deployment to
|
||||
// delete. The name is case insensitive. deploymentName is the name of the
|
||||
// deployment to delete.
|
||||
func (client DeploymentsClient) Delete(resourceGroupName string, deploymentName string, cancel <-chan struct{}) (<-chan autorest.Response, <-chan error) {
|
||||
resultChan := make(chan autorest.Response, 1)
|
||||
errChan := make(chan error, 1)
|
||||
// Delete delete deployment.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group. The name is case insensitive.
|
||||
// deploymentName - the name of the deployment to be deleted.
|
||||
func (client DeploymentsClient) Delete(ctx context.Context, resourceGroupName string, deploymentName string) (result DeploymentsDeleteFuture, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: deploymentName,
|
||||
Constraints: []validation.Constraint{{Target: "deploymentName", Name: validation.MaxLength, Rule: 64, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
errChan <- validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "Delete")
|
||||
close(errChan)
|
||||
close(resultChan)
|
||||
return resultChan, errChan
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewError("resources.DeploymentsClient", "Delete", err.Error())
|
||||
}
|
||||
|
||||
go func() {
|
||||
var err error
|
||||
var result autorest.Response
|
||||
defer func() {
|
||||
resultChan <- result
|
||||
errChan <- err
|
||||
close(resultChan)
|
||||
close(errChan)
|
||||
}()
|
||||
req, err := client.DeletePreparer(resourceGroupName, deploymentName, cancel)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Delete", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
req, err := client.DeletePreparer(ctx, resourceGroupName, deploymentName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Delete", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.DeleteSender(req)
|
||||
if err != nil {
|
||||
result.Response = resp
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Delete", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
result, err = client.DeleteSender(req)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Delete", result.Response(), "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.DeleteResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Delete", resp, "Failure responding to request")
|
||||
}
|
||||
}()
|
||||
return resultChan, errChan
|
||||
return
|
||||
}
|
||||
|
||||
// DeletePreparer prepares the Delete request.
|
||||
func (client DeploymentsClient) DeletePreparer(resourceGroupName string, deploymentName string, cancel <-chan struct{}) (*http.Request, error) {
|
||||
func (client DeploymentsClient) DeletePreparer(ctx context.Context, resourceGroupName string, deploymentName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"deploymentName": autorest.Encode("path", deploymentName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -391,15 +319,20 @@ func (client DeploymentsClient) DeletePreparer(resourceGroupName string, deploym
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{Cancel: cancel})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// DeleteSender sends the Delete request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client DeploymentsClient) DeleteSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client,
|
||||
req,
|
||||
azure.DoPollForAsynchronous(client.PollingDelay))
|
||||
func (client DeploymentsClient) DeleteSender(req *http.Request) (future DeploymentsDeleteFuture, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
future.Future, err = azure.NewFutureFromResponse(resp)
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteResponder handles the response to the Delete request. The method always
|
||||
|
@ -414,25 +347,20 @@ func (client DeploymentsClient) DeleteResponder(resp *http.Response) (result aut
|
|||
return
|
||||
}
|
||||
|
||||
// ExportTemplate exports the template used for specified deployment.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group. The name is case
|
||||
// insensitive. deploymentName is the name of the deployment from which to get
|
||||
// the template.
|
||||
func (client DeploymentsClient) ExportTemplate(resourceGroupName string, deploymentName string) (result DeploymentExportResult, err error) {
|
||||
// ExportTemplate exports a deployment template.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group. The name is case insensitive.
|
||||
// deploymentName - the name of the deployment.
|
||||
func (client DeploymentsClient) ExportTemplate(ctx context.Context, resourceGroupName string, deploymentName string) (result DeploymentExportResult, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: deploymentName,
|
||||
Constraints: []validation.Constraint{{Target: "deploymentName", Name: validation.MaxLength, Rule: 64, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "ExportTemplate")
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewError("resources.DeploymentsClient", "ExportTemplate", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.ExportTemplatePreparer(resourceGroupName, deploymentName)
|
||||
req, err := client.ExportTemplatePreparer(ctx, resourceGroupName, deploymentName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "ExportTemplate", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -454,14 +382,14 @@ func (client DeploymentsClient) ExportTemplate(resourceGroupName string, deploym
|
|||
}
|
||||
|
||||
// ExportTemplatePreparer prepares the ExportTemplate request.
|
||||
func (client DeploymentsClient) ExportTemplatePreparer(resourceGroupName string, deploymentName string) (*http.Request, error) {
|
||||
func (client DeploymentsClient) ExportTemplatePreparer(ctx context.Context, resourceGroupName string, deploymentName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"deploymentName": autorest.Encode("path", deploymentName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -471,13 +399,14 @@ func (client DeploymentsClient) ExportTemplatePreparer(resourceGroupName string,
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/exportTemplate", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ExportTemplateSender sends the ExportTemplate request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client DeploymentsClient) ExportTemplateSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ExportTemplateResponder handles the response to the ExportTemplate request. The method always
|
||||
|
@ -493,24 +422,20 @@ func (client DeploymentsClient) ExportTemplateResponder(resp *http.Response) (re
|
|||
return
|
||||
}
|
||||
|
||||
// Get gets a deployment.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group. The name is case
|
||||
// insensitive. deploymentName is the name of the deployment to get.
|
||||
func (client DeploymentsClient) Get(resourceGroupName string, deploymentName string) (result DeploymentExtended, err error) {
|
||||
// Get get a deployment.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group to get. The name is case insensitive.
|
||||
// deploymentName - the name of the deployment.
|
||||
func (client DeploymentsClient) Get(ctx context.Context, resourceGroupName string, deploymentName string) (result DeploymentExtended, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: deploymentName,
|
||||
Constraints: []validation.Constraint{{Target: "deploymentName", Name: validation.MaxLength, Rule: 64, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "Get")
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewError("resources.DeploymentsClient", "Get", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.GetPreparer(resourceGroupName, deploymentName)
|
||||
req, err := client.GetPreparer(ctx, resourceGroupName, deploymentName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Get", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -532,14 +457,14 @@ func (client DeploymentsClient) Get(resourceGroupName string, deploymentName str
|
|||
}
|
||||
|
||||
// GetPreparer prepares the Get request.
|
||||
func (client DeploymentsClient) GetPreparer(resourceGroupName string, deploymentName string) (*http.Request, error) {
|
||||
func (client DeploymentsClient) GetPreparer(ctx context.Context, resourceGroupName string, deploymentName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"deploymentName": autorest.Encode("path", deploymentName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -549,13 +474,14 @@ func (client DeploymentsClient) GetPreparer(resourceGroupName string, deployment
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// GetSender sends the Get request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client DeploymentsClient) GetSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// GetResponder handles the response to the Get request. The method always
|
||||
|
@ -571,23 +497,22 @@ func (client DeploymentsClient) GetResponder(resp *http.Response) (result Deploy
|
|||
return
|
||||
}
|
||||
|
||||
// List get all the deployments for a resource group.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group with the deployments to
|
||||
// get. The name is case insensitive. filter is the filter to apply on the
|
||||
// operation. For example, you can use $filter=provisioningState eq '{state}'.
|
||||
// top is the number of results to get. If null is passed, returns all
|
||||
// deployments.
|
||||
func (client DeploymentsClient) List(resourceGroupName string, filter string, top *int32) (result DeploymentListResult, err error) {
|
||||
// List get a list of deployments.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group to filter by. The name is case insensitive.
|
||||
// filter - the filter to apply on the operation.
|
||||
// top - query parameters. If null is passed returns all deployments.
|
||||
func (client DeploymentsClient) List(ctx context.Context, resourceGroupName string, filter string, top *int32) (result DeploymentListResultPage, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "List")
|
||||
return result, validation.NewError("resources.DeploymentsClient", "List", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.ListPreparer(resourceGroupName, filter, top)
|
||||
result.fn = client.listNextResults
|
||||
req, err := client.ListPreparer(ctx, resourceGroupName, filter, top)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "List", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -595,12 +520,12 @@ func (client DeploymentsClient) List(resourceGroupName string, filter string, to
|
|||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
result.dlr.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "List", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.ListResponder(resp)
|
||||
result.dlr, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "List", resp, "Failure responding to request")
|
||||
}
|
||||
|
@ -609,13 +534,13 @@ func (client DeploymentsClient) List(resourceGroupName string, filter string, to
|
|||
}
|
||||
|
||||
// ListPreparer prepares the List request.
|
||||
func (client DeploymentsClient) ListPreparer(resourceGroupName string, filter string, top *int32) (*http.Request, error) {
|
||||
func (client DeploymentsClient) ListPreparer(ctx context.Context, resourceGroupName string, filter string, top *int32) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -631,13 +556,14 @@ func (client DeploymentsClient) ListPreparer(resourceGroupName string, filter st
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListSender sends the List request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client DeploymentsClient) ListSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListResponder handles the response to the List request. The method always
|
||||
|
@ -653,57 +579,55 @@ func (client DeploymentsClient) ListResponder(resp *http.Response) (result Deplo
|
|||
return
|
||||
}
|
||||
|
||||
// ListNextResults retrieves the next set of results, if any.
|
||||
func (client DeploymentsClient) ListNextResults(lastResults DeploymentListResult) (result DeploymentListResult, err error) {
|
||||
req, err := lastResults.DeploymentListResultPreparer()
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (client DeploymentsClient) listNextResults(lastResults DeploymentListResult) (result DeploymentListResult, err error) {
|
||||
req, err := lastResults.deploymentListResultPreparer()
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "List", nil, "Failure preparing next results request")
|
||||
return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "List", resp, "Failure sending next results request")
|
||||
return result, autorest.NewErrorWithError(err, "resources.DeploymentsClient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
|
||||
result, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "List", resp, "Failure responding to next results request")
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Validate validates whether the specified template is syntactically correct
|
||||
// and will be accepted by Azure Resource Manager..
|
||||
//
|
||||
// resourceGroupName is the name of the resource group the template will be
|
||||
// deployed to. The name is case insensitive. deploymentName is the name of the
|
||||
// deployment. parameters is parameters to validate.
|
||||
func (client DeploymentsClient) Validate(resourceGroupName string, deploymentName string, parameters Deployment) (result DeploymentValidateResult, err error) {
|
||||
// ListComplete enumerates all values, automatically crossing page boundaries as required.
|
||||
func (client DeploymentsClient) ListComplete(ctx context.Context, resourceGroupName string, filter string, top *int32) (result DeploymentListResultIterator, err error) {
|
||||
result.page, err = client.List(ctx, resourceGroupName, filter, top)
|
||||
return
|
||||
}
|
||||
|
||||
// Validate validate a deployment template.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group. The name is case insensitive.
|
||||
// deploymentName - the name of the deployment.
|
||||
// parameters - deployment to validate.
|
||||
func (client DeploymentsClient) Validate(ctx context.Context, resourceGroupName string, deploymentName string, parameters Deployment) (result DeploymentValidateResult, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: deploymentName,
|
||||
Constraints: []validation.Constraint{{Target: "deploymentName", Name: validation.MaxLength, Rule: 64, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "deploymentName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: parameters,
|
||||
Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: true,
|
||||
Constraints: []validation.Constraint{{Target: "parameters.Properties", Name: validation.Null, Rule: false,
|
||||
Chain: []validation.Constraint{{Target: "parameters.Properties.TemplateLink", Name: validation.Null, Rule: false,
|
||||
Chain: []validation.Constraint{{Target: "parameters.Properties.TemplateLink.URI", Name: validation.Null, Rule: true, Chain: nil}}},
|
||||
{Target: "parameters.Properties.ParametersLink", Name: validation.Null, Rule: false,
|
||||
Chain: []validation.Constraint{{Target: "parameters.Properties.ParametersLink.URI", Name: validation.Null, Rule: true, Chain: nil}}},
|
||||
}}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.DeploymentsClient", "Validate")
|
||||
return result, validation.NewError("resources.DeploymentsClient", "Validate", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.ValidatePreparer(resourceGroupName, deploymentName, parameters)
|
||||
req, err := client.ValidatePreparer(ctx, resourceGroupName, deploymentName, parameters)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.DeploymentsClient", "Validate", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -725,32 +649,33 @@ func (client DeploymentsClient) Validate(resourceGroupName string, deploymentNam
|
|||
}
|
||||
|
||||
// ValidatePreparer prepares the Validate request.
|
||||
func (client DeploymentsClient) ValidatePreparer(resourceGroupName string, deploymentName string, parameters Deployment) (*http.Request, error) {
|
||||
func (client DeploymentsClient) ValidatePreparer(ctx context.Context, resourceGroupName string, deploymentName string, parameters Deployment) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"deploymentName": autorest.Encode("path", deploymentName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsJSON(),
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPost(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}/validate", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ValidateSender sends the Validate request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client DeploymentsClient) ValidateSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ValidateResponder handles the response to the Validate request. The method always
|
|
@ -14,21 +14,20 @@ package resources
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
|
||||
// Changes may cause incorrect behavior and will be lost if the code is
|
||||
// regenerated.
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/validation"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// GroupsClient is the provides operations for working with resources and
|
||||
// resource groups.
|
||||
// GroupsClient is the client for the Groups methods of the Resources service.
|
||||
type GroupsClient struct {
|
||||
ManagementClient
|
||||
BaseClient
|
||||
}
|
||||
|
||||
// NewGroupsClient creates an instance of the GroupsClient client.
|
||||
|
@ -41,20 +40,19 @@ func NewGroupsClientWithBaseURI(baseURI string, subscriptionID string) GroupsCli
|
|||
return GroupsClient{NewWithBaseURI(baseURI, subscriptionID)}
|
||||
}
|
||||
|
||||
// CheckExistence checks whether a resource group exists.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group to check. The name is
|
||||
// case insensitive.
|
||||
func (client GroupsClient) CheckExistence(resourceGroupName string) (result autorest.Response, err error) {
|
||||
// CheckExistence checks whether resource group exists.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group to check. The name is case insensitive.
|
||||
func (client GroupsClient) CheckExistence(ctx context.Context, resourceGroupName string) (result autorest.Response, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.GroupsClient", "CheckExistence")
|
||||
return result, validation.NewError("resources.GroupsClient", "CheckExistence", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.CheckExistencePreparer(resourceGroupName)
|
||||
req, err := client.CheckExistencePreparer(ctx, resourceGroupName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "CheckExistence", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -76,13 +74,13 @@ func (client GroupsClient) CheckExistence(resourceGroupName string) (result auto
|
|||
}
|
||||
|
||||
// CheckExistencePreparer prepares the CheckExistence request.
|
||||
func (client GroupsClient) CheckExistencePreparer(resourceGroupName string) (*http.Request, error) {
|
||||
func (client GroupsClient) CheckExistencePreparer(ctx context.Context, resourceGroupName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -92,13 +90,14 @@ func (client GroupsClient) CheckExistencePreparer(resourceGroupName string) (*ht
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// CheckExistenceSender sends the CheckExistence request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupsClient) CheckExistenceSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// CheckExistenceResponder handles the response to the CheckExistence request. The method always
|
||||
|
@ -113,11 +112,11 @@ func (client GroupsClient) CheckExistenceResponder(resp *http.Response) (result
|
|||
return
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates a resource group.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group to create or update.
|
||||
// parameters is parameters supplied to the create or update a resource group.
|
||||
func (client GroupsClient) CreateOrUpdate(resourceGroupName string, parameters Group) (result Group, err error) {
|
||||
// CreateOrUpdate create a resource group.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group to be created or updated.
|
||||
// parameters - parameters supplied to the create or update resource group service operation.
|
||||
func (client GroupsClient) CreateOrUpdate(ctx context.Context, resourceGroupName string, parameters Group) (result Group, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
|
@ -125,10 +124,10 @@ func (client GroupsClient) CreateOrUpdate(resourceGroupName string, parameters G
|
|||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: parameters,
|
||||
Constraints: []validation.Constraint{{Target: "parameters.Location", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.GroupsClient", "CreateOrUpdate")
|
||||
return result, validation.NewError("resources.GroupsClient", "CreateOrUpdate", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.CreateOrUpdatePreparer(resourceGroupName, parameters)
|
||||
req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, parameters)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "CreateOrUpdate", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -150,31 +149,32 @@ func (client GroupsClient) CreateOrUpdate(resourceGroupName string, parameters G
|
|||
}
|
||||
|
||||
// CreateOrUpdatePreparer prepares the CreateOrUpdate request.
|
||||
func (client GroupsClient) CreateOrUpdatePreparer(resourceGroupName string, parameters Group) (*http.Request, error) {
|
||||
func (client GroupsClient) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, parameters Group) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsJSON(),
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always
|
||||
|
@ -183,73 +183,48 @@ func (client GroupsClient) CreateOrUpdateResponder(resp *http.Response) (result
|
|||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// Delete when you delete a resource group, all of its resources are also
|
||||
// deleted. Deleting a resource group deletes all of its template deployments
|
||||
// and currently stored operations. This method may poll for completion.
|
||||
// Polling can be canceled by passing the cancel channel argument. The channel
|
||||
// will be used to cancel polling and any outstanding HTTP requests.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group to delete. The name is
|
||||
// case insensitive.
|
||||
func (client GroupsClient) Delete(resourceGroupName string, cancel <-chan struct{}) (<-chan autorest.Response, <-chan error) {
|
||||
resultChan := make(chan autorest.Response, 1)
|
||||
errChan := make(chan error, 1)
|
||||
// Delete delete resource group.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group to be deleted. The name is case insensitive.
|
||||
func (client GroupsClient) Delete(ctx context.Context, resourceGroupName string) (result GroupsDeleteFuture, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
errChan <- validation.NewErrorWithValidationError(err, "resources.GroupsClient", "Delete")
|
||||
close(errChan)
|
||||
close(resultChan)
|
||||
return resultChan, errChan
|
||||
return result, validation.NewError("resources.GroupsClient", "Delete", err.Error())
|
||||
}
|
||||
|
||||
go func() {
|
||||
var err error
|
||||
var result autorest.Response
|
||||
defer func() {
|
||||
resultChan <- result
|
||||
errChan <- err
|
||||
close(resultChan)
|
||||
close(errChan)
|
||||
}()
|
||||
req, err := client.DeletePreparer(resourceGroupName, cancel)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "Delete", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
req, err := client.DeletePreparer(ctx, resourceGroupName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "Delete", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.DeleteSender(req)
|
||||
if err != nil {
|
||||
result.Response = resp
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "Delete", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
result, err = client.DeleteSender(req)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "Delete", result.Response(), "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.DeleteResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "Delete", resp, "Failure responding to request")
|
||||
}
|
||||
}()
|
||||
return resultChan, errChan
|
||||
return
|
||||
}
|
||||
|
||||
// DeletePreparer prepares the Delete request.
|
||||
func (client GroupsClient) DeletePreparer(resourceGroupName string, cancel <-chan struct{}) (*http.Request, error) {
|
||||
func (client GroupsClient) DeletePreparer(ctx context.Context, resourceGroupName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -259,15 +234,20 @@ func (client GroupsClient) DeletePreparer(resourceGroupName string, cancel <-cha
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{Cancel: cancel})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// DeleteSender sends the Delete request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupsClient) DeleteSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client,
|
||||
req,
|
||||
azure.DoPollForAsynchronous(client.PollingDelay))
|
||||
func (client GroupsClient) DeleteSender(req *http.Request) (future GroupsDeleteFuture, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
future.Future, err = azure.NewFutureFromResponse(resp)
|
||||
return
|
||||
}
|
||||
|
||||
// DeleteResponder handles the response to the Delete request. The method always
|
||||
|
@ -276,26 +256,26 @@ func (client GroupsClient) DeleteResponder(resp *http.Response) (result autorest
|
|||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusAccepted, http.StatusOK),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted),
|
||||
autorest.ByClosing())
|
||||
result.Response = resp
|
||||
return
|
||||
}
|
||||
|
||||
// ExportTemplate captures the specified resource group as a template.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group to export as a template.
|
||||
// parameters is parameters for exporting the template.
|
||||
func (client GroupsClient) ExportTemplate(resourceGroupName string, parameters ExportTemplateRequest) (result GroupExportResult, err error) {
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group to be created or updated.
|
||||
// parameters - parameters supplied to the export template resource group operation.
|
||||
func (client GroupsClient) ExportTemplate(ctx context.Context, resourceGroupName string, parameters ExportTemplateRequest) (result GroupExportResult, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.GroupsClient", "ExportTemplate")
|
||||
return result, validation.NewError("resources.GroupsClient", "ExportTemplate", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.ExportTemplatePreparer(resourceGroupName, parameters)
|
||||
req, err := client.ExportTemplatePreparer(ctx, resourceGroupName, parameters)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "ExportTemplate", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -317,31 +297,32 @@ func (client GroupsClient) ExportTemplate(resourceGroupName string, parameters E
|
|||
}
|
||||
|
||||
// ExportTemplatePreparer prepares the ExportTemplate request.
|
||||
func (client GroupsClient) ExportTemplatePreparer(resourceGroupName string, parameters ExportTemplateRequest) (*http.Request, error) {
|
||||
func (client GroupsClient) ExportTemplatePreparer(ctx context.Context, resourceGroupName string, parameters ExportTemplateRequest) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsJSON(),
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPost(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/exportTemplate", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ExportTemplateSender sends the ExportTemplate request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupsClient) ExportTemplateSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ExportTemplateResponder handles the response to the ExportTemplate request. The method always
|
||||
|
@ -357,20 +338,19 @@ func (client GroupsClient) ExportTemplateResponder(resp *http.Response) (result
|
|||
return
|
||||
}
|
||||
|
||||
// Get gets a resource group.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group to get. The name is case
|
||||
// insensitive.
|
||||
func (client GroupsClient) Get(resourceGroupName string) (result Group, err error) {
|
||||
// Get get a resource group.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group to get. The name is case insensitive.
|
||||
func (client GroupsClient) Get(ctx context.Context, resourceGroupName string) (result Group, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.GroupsClient", "Get")
|
||||
return result, validation.NewError("resources.GroupsClient", "Get", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.GetPreparer(resourceGroupName)
|
||||
req, err := client.GetPreparer(ctx, resourceGroupName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "Get", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -392,13 +372,13 @@ func (client GroupsClient) Get(resourceGroupName string) (result Group, err erro
|
|||
}
|
||||
|
||||
// GetPreparer prepares the Get request.
|
||||
func (client GroupsClient) GetPreparer(resourceGroupName string) (*http.Request, error) {
|
||||
func (client GroupsClient) GetPreparer(ctx context.Context, resourceGroupName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -408,13 +388,14 @@ func (client GroupsClient) GetPreparer(resourceGroupName string) (*http.Request,
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// GetSender sends the Get request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupsClient) GetSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// GetResponder handles the response to the Get request. The method always
|
||||
|
@ -430,12 +411,13 @@ func (client GroupsClient) GetResponder(resp *http.Response) (result Group, err
|
|||
return
|
||||
}
|
||||
|
||||
// List gets all the resource groups for a subscription.
|
||||
//
|
||||
// filter is the filter to apply on the operation. top is the number of results
|
||||
// to return. If null is passed, returns all resource groups.
|
||||
func (client GroupsClient) List(filter string, top *int32) (result GroupListResult, err error) {
|
||||
req, err := client.ListPreparer(filter, top)
|
||||
// List gets a collection of resource groups.
|
||||
// Parameters:
|
||||
// filter - the filter to apply on the operation.
|
||||
// top - query parameters. If null is passed returns all resource groups.
|
||||
func (client GroupsClient) List(ctx context.Context, filter string, top *int32) (result GroupListResultPage, err error) {
|
||||
result.fn = client.listNextResults
|
||||
req, err := client.ListPreparer(ctx, filter, top)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "List", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -443,12 +425,12 @@ func (client GroupsClient) List(filter string, top *int32) (result GroupListResu
|
|||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
result.glr.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "List", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.ListResponder(resp)
|
||||
result.glr, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "List", resp, "Failure responding to request")
|
||||
}
|
||||
|
@ -457,12 +439,12 @@ func (client GroupsClient) List(filter string, top *int32) (result GroupListResu
|
|||
}
|
||||
|
||||
// ListPreparer prepares the List request.
|
||||
func (client GroupsClient) ListPreparer(filter string, top *int32) (*http.Request, error) {
|
||||
func (client GroupsClient) ListPreparer(ctx context.Context, filter string, top *int32) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -478,13 +460,14 @@ func (client GroupsClient) ListPreparer(filter string, top *int32) (*http.Reques
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListSender sends the List request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupsClient) ListSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListResponder handles the response to the List request. The method always
|
||||
|
@ -500,46 +483,50 @@ func (client GroupsClient) ListResponder(resp *http.Response) (result GroupListR
|
|||
return
|
||||
}
|
||||
|
||||
// ListNextResults retrieves the next set of results, if any.
|
||||
func (client GroupsClient) ListNextResults(lastResults GroupListResult) (result GroupListResult, err error) {
|
||||
req, err := lastResults.GroupListResultPreparer()
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (client GroupsClient) listNextResults(lastResults GroupListResult) (result GroupListResult, err error) {
|
||||
req, err := lastResults.groupListResultPreparer()
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "List", nil, "Failure preparing next results request")
|
||||
return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "List", resp, "Failure sending next results request")
|
||||
return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
|
||||
result, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "List", resp, "Failure responding to next results request")
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ListResources get all the resources for a resource group.
|
||||
//
|
||||
// resourceGroupName is the resource group with the resources to get. filter is
|
||||
// the filter to apply on the operation. expand is the $expand query parameter
|
||||
// top is the number of results to return. If null is passed, returns all
|
||||
// resources.
|
||||
func (client GroupsClient) ListResources(resourceGroupName string, filter string, expand string, top *int32) (result ListResult, err error) {
|
||||
// ListComplete enumerates all values, automatically crossing page boundaries as required.
|
||||
func (client GroupsClient) ListComplete(ctx context.Context, filter string, top *int32) (result GroupListResultIterator, err error) {
|
||||
result.page, err = client.List(ctx, filter, top)
|
||||
return
|
||||
}
|
||||
|
||||
// ListResources get all of the resources under a subscription.
|
||||
// Parameters:
|
||||
// resourceGroupName - query parameters. If null is passed returns all resource groups.
|
||||
// filter - the filter to apply on the operation.
|
||||
// expand - the $expand query parameter
|
||||
// top - query parameters. If null is passed returns all resource groups.
|
||||
func (client GroupsClient) ListResources(ctx context.Context, resourceGroupName string, filter string, expand string, top *int32) (result ListResultPage, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.GroupsClient", "ListResources")
|
||||
return result, validation.NewError("resources.GroupsClient", "ListResources", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.ListResourcesPreparer(resourceGroupName, filter, expand, top)
|
||||
result.fn = client.listResourcesNextResults
|
||||
req, err := client.ListResourcesPreparer(ctx, resourceGroupName, filter, expand, top)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "ListResources", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -547,12 +534,12 @@ func (client GroupsClient) ListResources(resourceGroupName string, filter string
|
|||
|
||||
resp, err := client.ListResourcesSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
result.lr.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "ListResources", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.ListResourcesResponder(resp)
|
||||
result.lr, err = client.ListResourcesResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "ListResources", resp, "Failure responding to request")
|
||||
}
|
||||
|
@ -561,13 +548,13 @@ func (client GroupsClient) ListResources(resourceGroupName string, filter string
|
|||
}
|
||||
|
||||
// ListResourcesPreparer prepares the ListResources request.
|
||||
func (client GroupsClient) ListResourcesPreparer(resourceGroupName string, filter string, expand string, top *int32) (*http.Request, error) {
|
||||
func (client GroupsClient) ListResourcesPreparer(ctx context.Context, resourceGroupName string, filter string, expand string, top *int32) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -586,13 +573,14 @@ func (client GroupsClient) ListResourcesPreparer(resourceGroupName string, filte
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/resources", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListResourcesSender sends the ListResources request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupsClient) ListResourcesSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListResourcesResponder handles the response to the ListResources request. The method always
|
||||
|
@ -608,47 +596,49 @@ func (client GroupsClient) ListResourcesResponder(resp *http.Response) (result L
|
|||
return
|
||||
}
|
||||
|
||||
// ListResourcesNextResults retrieves the next set of results, if any.
|
||||
func (client GroupsClient) ListResourcesNextResults(lastResults ListResult) (result ListResult, err error) {
|
||||
req, err := lastResults.ListResultPreparer()
|
||||
// listResourcesNextResults retrieves the next set of results, if any.
|
||||
func (client GroupsClient) listResourcesNextResults(lastResults ListResult) (result ListResult, err error) {
|
||||
req, err := lastResults.listResultPreparer()
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "ListResources", nil, "Failure preparing next results request")
|
||||
return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "listResourcesNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListResourcesSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "ListResources", resp, "Failure sending next results request")
|
||||
return result, autorest.NewErrorWithError(err, "resources.GroupsClient", "listResourcesNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
|
||||
result, err = client.ListResourcesResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "ListResources", resp, "Failure responding to next results request")
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "listResourcesNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Patch resource groups can be updated through a simple PATCH operation to a
|
||||
// group address. The format of the request is the same as that for creating a
|
||||
// resource group. If a field is unspecified, the current value is retained.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group to update. The name is
|
||||
// case insensitive. parameters is parameters supplied to update a resource
|
||||
// group.
|
||||
func (client GroupsClient) Patch(resourceGroupName string, parameters Group) (result Group, err error) {
|
||||
// ListResourcesComplete enumerates all values, automatically crossing page boundaries as required.
|
||||
func (client GroupsClient) ListResourcesComplete(ctx context.Context, resourceGroupName string, filter string, expand string, top *int32) (result ListResultIterator, err error) {
|
||||
result.page, err = client.ListResources(ctx, resourceGroupName, filter, expand, top)
|
||||
return
|
||||
}
|
||||
|
||||
// Patch resource groups can be updated through a simple PATCH operation to a group address. The format of the request
|
||||
// is the same as that for creating a resource groups, though if a field is unspecified current value will be carried
|
||||
// over.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group to be created or updated. The name is case insensitive.
|
||||
// parameters - parameters supplied to the update state resource group service operation.
|
||||
func (client GroupsClient) Patch(ctx context.Context, resourceGroupName string, parameters Group) (result Group, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "resources.GroupsClient", "Patch")
|
||||
return result, validation.NewError("resources.GroupsClient", "Patch", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.PatchPreparer(resourceGroupName, parameters)
|
||||
req, err := client.PatchPreparer(ctx, resourceGroupName, parameters)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.GroupsClient", "Patch", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -670,31 +660,32 @@ func (client GroupsClient) Patch(resourceGroupName string, parameters Group) (re
|
|||
}
|
||||
|
||||
// PatchPreparer prepares the Patch request.
|
||||
func (client GroupsClient) PatchPreparer(resourceGroupName string, parameters Group) (*http.Request, error) {
|
||||
func (client GroupsClient) PatchPreparer(ctx context.Context, resourceGroupName string, parameters Group) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsJSON(),
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPatch(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// PatchSender sends the Patch request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client GroupsClient) PatchSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// PatchResponder handles the response to the Patch request. The method always
|
1313
vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-02-01/resources/models.go
generated
vendored
Normal file
1313
vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-02-01/resources/models.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -14,20 +14,19 @@ package resources
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
|
||||
// Changes may cause incorrect behavior and will be lost if the code is
|
||||
// regenerated.
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// ProvidersClient is the provides operations for working with resources and
|
||||
// resource groups.
|
||||
// ProvidersClient is the client for the Providers methods of the Resources service.
|
||||
type ProvidersClient struct {
|
||||
ManagementClient
|
||||
BaseClient
|
||||
}
|
||||
|
||||
// NewProvidersClient creates an instance of the ProvidersClient client.
|
||||
|
@ -35,19 +34,18 @@ func NewProvidersClient(subscriptionID string) ProvidersClient {
|
|||
return NewProvidersClientWithBaseURI(DefaultBaseURI, subscriptionID)
|
||||
}
|
||||
|
||||
// NewProvidersClientWithBaseURI creates an instance of the ProvidersClient
|
||||
// client.
|
||||
// NewProvidersClientWithBaseURI creates an instance of the ProvidersClient client.
|
||||
func NewProvidersClientWithBaseURI(baseURI string, subscriptionID string) ProvidersClient {
|
||||
return ProvidersClient{NewWithBaseURI(baseURI, subscriptionID)}
|
||||
}
|
||||
|
||||
// Get gets the specified resource provider.
|
||||
//
|
||||
// resourceProviderNamespace is the namespace of the resource provider. expand
|
||||
// is the $expand query parameter. For example, to include property aliases in
|
||||
// response, use $expand=resourceTypes/aliases.
|
||||
func (client ProvidersClient) Get(resourceProviderNamespace string, expand string) (result Provider, err error) {
|
||||
req, err := client.GetPreparer(resourceProviderNamespace, expand)
|
||||
// Get gets a resource provider.
|
||||
// Parameters:
|
||||
// resourceProviderNamespace - namespace of the resource provider.
|
||||
// expand - the $expand query parameter. e.g. To include property aliases in response, use
|
||||
// $expand=resourceTypes/aliases.
|
||||
func (client ProvidersClient) Get(ctx context.Context, resourceProviderNamespace string, expand string) (result Provider, err error) {
|
||||
req, err := client.GetPreparer(ctx, resourceProviderNamespace, expand)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.ProvidersClient", "Get", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -69,13 +67,13 @@ func (client ProvidersClient) Get(resourceProviderNamespace string, expand strin
|
|||
}
|
||||
|
||||
// GetPreparer prepares the Get request.
|
||||
func (client ProvidersClient) GetPreparer(resourceProviderNamespace string, expand string) (*http.Request, error) {
|
||||
func (client ProvidersClient) GetPreparer(ctx context.Context, resourceProviderNamespace string, expand string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -88,13 +86,14 @@ func (client ProvidersClient) GetPreparer(resourceProviderNamespace string, expa
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// GetSender sends the Get request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client ProvidersClient) GetSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// GetResponder handles the response to the Get request. The method always
|
||||
|
@ -110,15 +109,14 @@ func (client ProvidersClient) GetResponder(resp *http.Response) (result Provider
|
|||
return
|
||||
}
|
||||
|
||||
// List gets all resource providers for a subscription.
|
||||
//
|
||||
// top is the number of results to return. If null is passed returns all
|
||||
// deployments. expand is the properties to include in the results. For
|
||||
// example, use &$expand=metadata in the query string to retrieve resource
|
||||
// provider metadata. To include property aliases in response, use
|
||||
// List gets a list of resource providers.
|
||||
// Parameters:
|
||||
// top - query parameters. If null is passed returns all deployments.
|
||||
// expand - the $expand query parameter. e.g. To include property aliases in response, use
|
||||
// $expand=resourceTypes/aliases.
|
||||
func (client ProvidersClient) List(top *int32, expand string) (result ProviderListResult, err error) {
|
||||
req, err := client.ListPreparer(top, expand)
|
||||
func (client ProvidersClient) List(ctx context.Context, top *int32, expand string) (result ProviderListResultPage, err error) {
|
||||
result.fn = client.listNextResults
|
||||
req, err := client.ListPreparer(ctx, top, expand)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.ProvidersClient", "List", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -126,12 +124,12 @@ func (client ProvidersClient) List(top *int32, expand string) (result ProviderLi
|
|||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
result.plr.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.ProvidersClient", "List", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.ListResponder(resp)
|
||||
result.plr, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.ProvidersClient", "List", resp, "Failure responding to request")
|
||||
}
|
||||
|
@ -140,12 +138,12 @@ func (client ProvidersClient) List(top *int32, expand string) (result ProviderLi
|
|||
}
|
||||
|
||||
// ListPreparer prepares the List request.
|
||||
func (client ProvidersClient) ListPreparer(top *int32, expand string) (*http.Request, error) {
|
||||
func (client ProvidersClient) ListPreparer(ctx context.Context, top *int32, expand string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -161,13 +159,14 @@ func (client ProvidersClient) ListPreparer(top *int32, expand string) (*http.Req
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListSender sends the List request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client ProvidersClient) ListSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListResponder handles the response to the List request. The method always
|
||||
|
@ -183,36 +182,38 @@ func (client ProvidersClient) ListResponder(resp *http.Response) (result Provide
|
|||
return
|
||||
}
|
||||
|
||||
// ListNextResults retrieves the next set of results, if any.
|
||||
func (client ProvidersClient) ListNextResults(lastResults ProviderListResult) (result ProviderListResult, err error) {
|
||||
req, err := lastResults.ProviderListResultPreparer()
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (client ProvidersClient) listNextResults(lastResults ProviderListResult) (result ProviderListResult, err error) {
|
||||
req, err := lastResults.providerListResultPreparer()
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "resources.ProvidersClient", "List", nil, "Failure preparing next results request")
|
||||
return result, autorest.NewErrorWithError(err, "resources.ProvidersClient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(err, "resources.ProvidersClient", "List", resp, "Failure sending next results request")
|
||||
return result, autorest.NewErrorWithError(err, "resources.ProvidersClient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
|
||||
result, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.ProvidersClient", "List", resp, "Failure responding to next results request")
|
||||
err = autorest.NewErrorWithError(err, "resources.ProvidersClient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Register registers a subscription with a resource provider.
|
||||
//
|
||||
// resourceProviderNamespace is the namespace of the resource provider to
|
||||
// register.
|
||||
func (client ProvidersClient) Register(resourceProviderNamespace string) (result Provider, err error) {
|
||||
req, err := client.RegisterPreparer(resourceProviderNamespace)
|
||||
// ListComplete enumerates all values, automatically crossing page boundaries as required.
|
||||
func (client ProvidersClient) ListComplete(ctx context.Context, top *int32, expand string) (result ProviderListResultIterator, err error) {
|
||||
result.page, err = client.List(ctx, top, expand)
|
||||
return
|
||||
}
|
||||
|
||||
// Register registers provider to be used with a subscription.
|
||||
// Parameters:
|
||||
// resourceProviderNamespace - namespace of the resource provider.
|
||||
func (client ProvidersClient) Register(ctx context.Context, resourceProviderNamespace string) (result Provider, err error) {
|
||||
req, err := client.RegisterPreparer(ctx, resourceProviderNamespace)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.ProvidersClient", "Register", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -234,13 +235,13 @@ func (client ProvidersClient) Register(resourceProviderNamespace string) (result
|
|||
}
|
||||
|
||||
// RegisterPreparer prepares the Register request.
|
||||
func (client ProvidersClient) RegisterPreparer(resourceProviderNamespace string) (*http.Request, error) {
|
||||
func (client ProvidersClient) RegisterPreparer(ctx context.Context, resourceProviderNamespace string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -250,13 +251,14 @@ func (client ProvidersClient) RegisterPreparer(resourceProviderNamespace string)
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// RegisterSender sends the Register request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client ProvidersClient) RegisterSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// RegisterResponder handles the response to the Register request. The method always
|
||||
|
@ -272,12 +274,11 @@ func (client ProvidersClient) RegisterResponder(resp *http.Response) (result Pro
|
|||
return
|
||||
}
|
||||
|
||||
// Unregister unregisters a subscription from a resource provider.
|
||||
//
|
||||
// resourceProviderNamespace is the namespace of the resource provider to
|
||||
// unregister.
|
||||
func (client ProvidersClient) Unregister(resourceProviderNamespace string) (result Provider, err error) {
|
||||
req, err := client.UnregisterPreparer(resourceProviderNamespace)
|
||||
// Unregister unregisters provider from a subscription.
|
||||
// Parameters:
|
||||
// resourceProviderNamespace - namespace of the resource provider.
|
||||
func (client ProvidersClient) Unregister(ctx context.Context, resourceProviderNamespace string) (result Provider, err error) {
|
||||
req, err := client.UnregisterPreparer(ctx, resourceProviderNamespace)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.ProvidersClient", "Unregister", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -299,13 +300,13 @@ func (client ProvidersClient) Unregister(resourceProviderNamespace string) (resu
|
|||
}
|
||||
|
||||
// UnregisterPreparer prepares the Unregister request.
|
||||
func (client ProvidersClient) UnregisterPreparer(resourceProviderNamespace string) (*http.Request, error) {
|
||||
func (client ProvidersClient) UnregisterPreparer(ctx context.Context, resourceProviderNamespace string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -315,13 +316,14 @@ func (client ProvidersClient) UnregisterPreparer(resourceProviderNamespace strin
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/unregister", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// UnregisterSender sends the Unregister request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client ProvidersClient) UnregisterSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// UnregisterResponder handles the response to the Unregister request. The method always
|
629
vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-02-01/resources/resources.go
generated
vendored
Normal file
629
vendor/github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2016-02-01/resources/resources.go
generated
vendored
Normal file
|
@ -0,0 +1,629 @@
|
|||
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.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/validation"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// Client is the client for the Resources methods of the Resources service.
|
||||
type Client struct {
|
||||
BaseClient
|
||||
}
|
||||
|
||||
// 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.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group. The name is case insensitive.
|
||||
// resourceProviderNamespace - resource identity.
|
||||
// parentResourcePath - resource identity.
|
||||
// resourceType - resource identity.
|
||||
// resourceName - resource identity.
|
||||
func (client Client) CheckExistence(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (result autorest.Response, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewError("resources.Client", "CheckExistence", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.CheckExistencePreparer(ctx, resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "CheckExistence", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.CheckExistenceSender(req)
|
||||
if err != nil {
|
||||
result.Response = resp
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "CheckExistence", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.CheckExistenceResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "CheckExistence", resp, "Failure responding to request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CheckExistencePreparer prepares the CheckExistence request.
|
||||
func (client Client) CheckExistencePreparer(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"parentResourcePath": parentResourcePath,
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"resourceName": autorest.Encode("path", resourceName),
|
||||
"resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace),
|
||||
"resourceType": resourceType,
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsHead(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// CheckExistenceSender sends the CheckExistence request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client Client) CheckExistenceSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// CheckExistenceResponder handles the response to the CheckExistence request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client Client) CheckExistenceResponder(resp *http.Response) (result autorest.Response, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent, http.StatusNotFound),
|
||||
autorest.ByClosing())
|
||||
result.Response = resp
|
||||
return
|
||||
}
|
||||
|
||||
// CreateOrUpdate create a resource.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group. The name is case insensitive.
|
||||
// resourceProviderNamespace - resource identity.
|
||||
// parentResourcePath - resource identity.
|
||||
// resourceType - resource identity.
|
||||
// resourceName - resource identity.
|
||||
// parameters - create or update resource parameters.
|
||||
func (client Client) CreateOrUpdate(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, parameters GenericResource) (result GenericResource, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewError("resources.Client", "CreateOrUpdate", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.CreateOrUpdatePreparer(ctx, resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, parameters)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "CreateOrUpdate", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.CreateOrUpdateSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "CreateOrUpdate", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.CreateOrUpdateResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "CreateOrUpdate", resp, "Failure responding to request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CreateOrUpdatePreparer prepares the CreateOrUpdate request.
|
||||
func (client Client) CreateOrUpdatePreparer(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, parameters GenericResource) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"parentResourcePath": parentResourcePath,
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"resourceName": autorest.Encode("path", resourceName),
|
||||
"resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace),
|
||||
"resourceType": resourceType,
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client Client) CreateOrUpdateSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client Client) CreateOrUpdateResponder(resp *http.Response) (result GenericResource, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// Delete delete resource and all of its resources.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group. The name is case insensitive.
|
||||
// resourceProviderNamespace - resource identity.
|
||||
// parentResourcePath - resource identity.
|
||||
// resourceType - resource identity.
|
||||
// resourceName - resource identity.
|
||||
func (client Client) Delete(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (result autorest.Response, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewError("resources.Client", "Delete", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.DeletePreparer(ctx, resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "Delete", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.DeleteSender(req)
|
||||
if err != nil {
|
||||
result.Response = resp
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "Delete", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.DeleteResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "Delete", resp, "Failure responding to request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// DeletePreparer prepares the Delete request.
|
||||
func (client Client) DeletePreparer(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"parentResourcePath": parentResourcePath,
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"resourceName": autorest.Encode("path", resourceName),
|
||||
"resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace),
|
||||
"resourceType": resourceType,
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsDelete(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// DeleteSender sends the Delete request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client Client) DeleteSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// DeleteResponder handles the response to the Delete request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client Client) DeleteResponder(resp *http.Response) (result autorest.Response, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent),
|
||||
autorest.ByClosing())
|
||||
result.Response = resp
|
||||
return
|
||||
}
|
||||
|
||||
// Get returns a resource belonging to a resource group.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group. The name is case insensitive.
|
||||
// resourceProviderNamespace - resource identity.
|
||||
// parentResourcePath - resource identity.
|
||||
// resourceType - resource identity.
|
||||
// resourceName - resource identity.
|
||||
func (client Client) Get(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (result GenericResource, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewError("resources.Client", "Get", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.GetPreparer(ctx, resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "Get", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.GetSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "Get", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.GetResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "Get", resp, "Failure responding to request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// GetPreparer prepares the Get request.
|
||||
func (client Client) GetPreparer(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"parentResourcePath": parentResourcePath,
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"resourceName": autorest.Encode("path", resourceName),
|
||||
"resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace),
|
||||
"resourceType": resourceType,
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// GetSender sends the Get request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client Client) GetSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// GetResponder handles the response to the Get request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client Client) GetResponder(resp *http.Response) (result GenericResource, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// List get all of the resources under a subscription.
|
||||
// Parameters:
|
||||
// filter - the filter to apply on the operation.
|
||||
// expand - the $expand query parameter.
|
||||
// top - query parameters. If null is passed returns all resource groups.
|
||||
func (client Client) List(ctx context.Context, filter string, expand string, top *int32) (result ListResultPage, err error) {
|
||||
result.fn = client.listNextResults
|
||||
req, err := client.ListPreparer(ctx, filter, expand, top)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "List", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.lr.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "List", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result.lr, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "List", resp, "Failure responding to request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ListPreparer prepares the List request.
|
||||
func (client Client) ListPreparer(ctx context.Context, filter string, expand string, top *int32) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
if len(filter) > 0 {
|
||||
queryParameters["$filter"] = autorest.Encode("query", filter)
|
||||
}
|
||||
if len(expand) > 0 {
|
||||
queryParameters["$expand"] = autorest.Encode("query", expand)
|
||||
}
|
||||
if top != nil {
|
||||
queryParameters["$top"] = autorest.Encode("query", *top)
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resources", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListSender sends the List request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client Client) ListSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// 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(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (client Client) listNextResults(lastResults ListResult) (result ListResult, err error) {
|
||||
req, err := lastResults.listResultPreparer()
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "resources.Client", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(err, "resources.Client", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
result, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// ListComplete enumerates all values, automatically crossing page boundaries as required.
|
||||
func (client Client) ListComplete(ctx context.Context, filter string, expand string, top *int32) (result ListResultIterator, err error) {
|
||||
result.page, err = client.List(ctx, filter, expand, top)
|
||||
return
|
||||
}
|
||||
|
||||
// MoveResources move resources from one resource group to another. The resources being moved should all be in the same
|
||||
// resource group.
|
||||
// Parameters:
|
||||
// sourceResourceGroupName - source resource group name.
|
||||
// parameters - move resources' parameters.
|
||||
func (client Client) MoveResources(ctx context.Context, sourceResourceGroupName string, parameters MoveInfo) (result MoveResourcesFuture, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: sourceResourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "sourceResourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "sourceResourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "sourceResourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewError("resources.Client", "MoveResources", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.MoveResourcesPreparer(ctx, sourceResourceGroupName, parameters)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "MoveResources", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.MoveResourcesSender(req)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "MoveResources", result.Response(), "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// MoveResourcesPreparer prepares the MoveResources request.
|
||||
func (client Client) MoveResourcesPreparer(ctx context.Context, sourceResourceGroupName string, parameters MoveInfo) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"sourceResourceGroupName": autorest.Encode("path", sourceResourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPost(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{sourceResourceGroupName}/moveResources", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// 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) (future MoveResourcesFuture, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
future.Future, err = azure.NewFutureFromResponse(resp)
|
||||
return
|
||||
}
|
||||
|
||||
// MoveResourcesResponder handles the response to the MoveResources request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client Client) MoveResourcesResponder(resp *http.Response) (result autorest.Response, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent),
|
||||
autorest.ByClosing())
|
||||
result.Response = resp
|
||||
return
|
||||
}
|
||||
|
||||
// Update updates a resource.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group for the resource. The name is case insensitive.
|
||||
// resourceProviderNamespace - the namespace of the resource provider.
|
||||
// parentResourcePath - the parent resource identity.
|
||||
// resourceType - the resource type of the resource to update.
|
||||
// resourceName - the name of the resource to update.
|
||||
// parameters - parameters for updating the resource.
|
||||
func (client Client) Update(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, parameters GenericResource) (result UpdateFuture, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewError("resources.Client", "Update", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.UpdatePreparer(ctx, resourceGroupName, resourceProviderNamespace, parentResourcePath, resourceType, resourceName, parameters)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "Update", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.UpdateSender(req)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.Client", "Update", result.Response(), "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// UpdatePreparer prepares the Update request.
|
||||
func (client Client) UpdatePreparer(ctx context.Context, resourceGroupName string, resourceProviderNamespace string, parentResourcePath string, resourceType string, resourceName string, parameters GenericResource) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"parentResourcePath": parentResourcePath,
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"resourceName": autorest.Encode("path", resourceName),
|
||||
"resourceProviderNamespace": autorest.Encode("path", resourceProviderNamespace),
|
||||
"resourceType": resourceType,
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPatch(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{parentResourcePath}/{resourceType}/{resourceName}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// UpdateSender sends the Update request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client Client) UpdateSender(req *http.Request) (future UpdateFuture, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
future.Future, err = azure.NewFutureFromResponse(resp)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateResponder handles the response to the Update request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client Client) UpdateResponder(resp *http.Response) (result GenericResource, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
|
@ -14,20 +14,19 @@ package resources
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
|
||||
// Changes may cause incorrect behavior and will be lost if the code is
|
||||
// regenerated.
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// TagsClient is the provides operations for working with resources and
|
||||
// resource groups.
|
||||
// TagsClient is the client for the Tags methods of the Resources service.
|
||||
type TagsClient struct {
|
||||
ManagementClient
|
||||
BaseClient
|
||||
}
|
||||
|
||||
// NewTagsClient creates an instance of the TagsClient client.
|
||||
|
@ -40,13 +39,11 @@ func NewTagsClientWithBaseURI(baseURI string, subscriptionID string) TagsClient
|
|||
return TagsClient{NewWithBaseURI(baseURI, subscriptionID)}
|
||||
}
|
||||
|
||||
// CreateOrUpdate the tag name can have a maximum of 512 characters and is case
|
||||
// insensitive. Tag names created by Azure have prefixes of microsoft, azure,
|
||||
// or windows. You cannot create tags with one of these prefixes.
|
||||
//
|
||||
// tagName is the name of the tag to create.
|
||||
func (client TagsClient) CreateOrUpdate(tagName string) (result TagDetails, err error) {
|
||||
req, err := client.CreateOrUpdatePreparer(tagName)
|
||||
// CreateOrUpdate create a subscription resource tag.
|
||||
// Parameters:
|
||||
// tagName - the name of the tag.
|
||||
func (client TagsClient) CreateOrUpdate(ctx context.Context, tagName string) (result TagDetails, err error) {
|
||||
req, err := client.CreateOrUpdatePreparer(ctx, tagName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.TagsClient", "CreateOrUpdate", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -68,13 +65,13 @@ func (client TagsClient) CreateOrUpdate(tagName string) (result TagDetails, err
|
|||
}
|
||||
|
||||
// CreateOrUpdatePreparer prepares the CreateOrUpdate request.
|
||||
func (client TagsClient) CreateOrUpdatePreparer(tagName string) (*http.Request, error) {
|
||||
func (client TagsClient) CreateOrUpdatePreparer(ctx context.Context, tagName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
"tagName": autorest.Encode("path", tagName),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -84,13 +81,14 @@ func (client TagsClient) CreateOrUpdatePreparer(tagName string) (*http.Request,
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/tagNames/{tagName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client TagsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always
|
||||
|
@ -106,12 +104,12 @@ func (client TagsClient) CreateOrUpdateResponder(resp *http.Response) (result Ta
|
|||
return
|
||||
}
|
||||
|
||||
// CreateOrUpdateValue creates a tag value. The name of the tag must already
|
||||
// exist.
|
||||
//
|
||||
// tagName is the name of the tag. tagValue is the value of the tag to create.
|
||||
func (client TagsClient) CreateOrUpdateValue(tagName string, tagValue string) (result TagValue, err error) {
|
||||
req, err := client.CreateOrUpdateValuePreparer(tagName, tagValue)
|
||||
// CreateOrUpdateValue create a subscription resource tag value.
|
||||
// Parameters:
|
||||
// tagName - the name of the tag.
|
||||
// tagValue - the value of the tag.
|
||||
func (client TagsClient) CreateOrUpdateValue(ctx context.Context, tagName string, tagValue string) (result TagValue, err error) {
|
||||
req, err := client.CreateOrUpdateValuePreparer(ctx, tagName, tagValue)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.TagsClient", "CreateOrUpdateValue", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -133,14 +131,14 @@ func (client TagsClient) CreateOrUpdateValue(tagName string, tagValue string) (r
|
|||
}
|
||||
|
||||
// CreateOrUpdateValuePreparer prepares the CreateOrUpdateValue request.
|
||||
func (client TagsClient) CreateOrUpdateValuePreparer(tagName string, tagValue string) (*http.Request, error) {
|
||||
func (client TagsClient) CreateOrUpdateValuePreparer(ctx context.Context, tagName string, tagValue string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
"tagName": autorest.Encode("path", tagName),
|
||||
"tagValue": autorest.Encode("path", tagValue),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -150,13 +148,14 @@ func (client TagsClient) CreateOrUpdateValuePreparer(tagName string, tagValue st
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/tagNames/{tagName}/tagValues/{tagValue}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// CreateOrUpdateValueSender sends the CreateOrUpdateValue request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client TagsClient) CreateOrUpdateValueSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// CreateOrUpdateValueResponder handles the response to the CreateOrUpdateValue request. The method always
|
||||
|
@ -172,12 +171,11 @@ func (client TagsClient) CreateOrUpdateValueResponder(resp *http.Response) (resu
|
|||
return
|
||||
}
|
||||
|
||||
// Delete you must remove all values from a resource tag before you can delete
|
||||
// it.
|
||||
//
|
||||
// tagName is the name of the tag.
|
||||
func (client TagsClient) Delete(tagName string) (result autorest.Response, err error) {
|
||||
req, err := client.DeletePreparer(tagName)
|
||||
// Delete delete a subscription resource tag.
|
||||
// Parameters:
|
||||
// tagName - the name of the tag.
|
||||
func (client TagsClient) Delete(ctx context.Context, tagName string) (result autorest.Response, err error) {
|
||||
req, err := client.DeletePreparer(ctx, tagName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.TagsClient", "Delete", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -199,13 +197,13 @@ func (client TagsClient) Delete(tagName string) (result autorest.Response, err e
|
|||
}
|
||||
|
||||
// DeletePreparer prepares the Delete request.
|
||||
func (client TagsClient) DeletePreparer(tagName string) (*http.Request, error) {
|
||||
func (client TagsClient) DeletePreparer(ctx context.Context, tagName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
"tagName": autorest.Encode("path", tagName),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -215,13 +213,14 @@ func (client TagsClient) DeletePreparer(tagName string) (*http.Request, error) {
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/tagNames/{tagName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// DeleteSender sends the Delete request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client TagsClient) DeleteSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// DeleteResponder handles the response to the Delete request. The method always
|
||||
|
@ -236,11 +235,12 @@ func (client TagsClient) DeleteResponder(resp *http.Response) (result autorest.R
|
|||
return
|
||||
}
|
||||
|
||||
// DeleteValue deletes a tag value.
|
||||
//
|
||||
// tagName is the name of the tag. tagValue is the value of the tag to delete.
|
||||
func (client TagsClient) DeleteValue(tagName string, tagValue string) (result autorest.Response, err error) {
|
||||
req, err := client.DeleteValuePreparer(tagName, tagValue)
|
||||
// DeleteValue delete a subscription resource tag value.
|
||||
// Parameters:
|
||||
// tagName - the name of the tag.
|
||||
// tagValue - the value of the tag.
|
||||
func (client TagsClient) DeleteValue(ctx context.Context, tagName string, tagValue string) (result autorest.Response, err error) {
|
||||
req, err := client.DeleteValuePreparer(ctx, tagName, tagValue)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.TagsClient", "DeleteValue", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -262,14 +262,14 @@ func (client TagsClient) DeleteValue(tagName string, tagValue string) (result au
|
|||
}
|
||||
|
||||
// DeleteValuePreparer prepares the DeleteValue request.
|
||||
func (client TagsClient) DeleteValuePreparer(tagName string, tagValue string) (*http.Request, error) {
|
||||
func (client TagsClient) DeleteValuePreparer(ctx context.Context, tagName string, tagValue string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
"tagName": autorest.Encode("path", tagName),
|
||||
"tagValue": autorest.Encode("path", tagValue),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -279,13 +279,14 @@ func (client TagsClient) DeleteValuePreparer(tagName string, tagValue string) (*
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/tagNames/{tagName}/tagValues/{tagValue}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// DeleteValueSender sends the DeleteValue request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client TagsClient) DeleteValueSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// DeleteValueResponder handles the response to the DeleteValue request. The method always
|
||||
|
@ -300,10 +301,10 @@ func (client TagsClient) DeleteValueResponder(resp *http.Response) (result autor
|
|||
return
|
||||
}
|
||||
|
||||
// List gets the names and values of all resource tags that are defined in a
|
||||
// subscription.
|
||||
func (client TagsClient) List() (result TagsListResult, err error) {
|
||||
req, err := client.ListPreparer()
|
||||
// List get a list of subscription resource tags.
|
||||
func (client TagsClient) List(ctx context.Context) (result TagsListResultPage, err error) {
|
||||
result.fn = client.listNextResults
|
||||
req, err := client.ListPreparer(ctx)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.TagsClient", "List", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -311,12 +312,12 @@ func (client TagsClient) List() (result TagsListResult, err error) {
|
|||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
result.tlr.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "resources.TagsClient", "List", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.ListResponder(resp)
|
||||
result.tlr, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.TagsClient", "List", resp, "Failure responding to request")
|
||||
}
|
||||
|
@ -325,12 +326,12 @@ func (client TagsClient) List() (result TagsListResult, err error) {
|
|||
}
|
||||
|
||||
// ListPreparer prepares the List request.
|
||||
func (client TagsClient) ListPreparer() (*http.Request, error) {
|
||||
func (client TagsClient) ListPreparer(ctx context.Context) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
const APIVersion = "2016-02-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -340,13 +341,14 @@ func (client TagsClient) ListPreparer() (*http.Request, error) {
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/tagNames", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListSender sends the List request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client TagsClient) ListSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListResponder handles the response to the List request. The method always
|
||||
|
@ -362,26 +364,29 @@ func (client TagsClient) ListResponder(resp *http.Response) (result TagsListResu
|
|||
return
|
||||
}
|
||||
|
||||
// ListNextResults retrieves the next set of results, if any.
|
||||
func (client TagsClient) ListNextResults(lastResults TagsListResult) (result TagsListResult, err error) {
|
||||
req, err := lastResults.TagsListResultPreparer()
|
||||
// listNextResults retrieves the next set of results, if any.
|
||||
func (client TagsClient) listNextResults(lastResults TagsListResult) (result TagsListResult, err error) {
|
||||
req, err := lastResults.tagsListResultPreparer()
|
||||
if err != nil {
|
||||
return result, autorest.NewErrorWithError(err, "resources.TagsClient", "List", nil, "Failure preparing next results request")
|
||||
return result, autorest.NewErrorWithError(err, "resources.TagsClient", "listNextResults", nil, "Failure preparing next results request")
|
||||
}
|
||||
if req == nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return result, autorest.NewErrorWithError(err, "resources.TagsClient", "List", resp, "Failure sending next results request")
|
||||
return result, autorest.NewErrorWithError(err, "resources.TagsClient", "listNextResults", resp, "Failure sending next results request")
|
||||
}
|
||||
|
||||
result, err = client.ListResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "resources.TagsClient", "List", resp, "Failure responding to next results request")
|
||||
err = autorest.NewErrorWithError(err, "resources.TagsClient", "listNextResults", resp, "Failure responding to next results request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ListComplete enumerates all values, automatically crossing page boundaries as required.
|
||||
func (client TagsClient) ListComplete(ctx context.Context) (result TagsListResultIterator, err error) {
|
||||
result.page, err = client.List(ctx)
|
||||
return
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package resources
|
||||
|
||||
import "github.com/Azure/azure-sdk-for-go/version"
|
||||
|
||||
// Copyright (c) Microsoft and contributors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -14,15 +16,15 @@ package resources
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator 1.2.2.0
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
// UserAgent returns the UserAgent string to use when sending http.Requests.
|
||||
func UserAgent() string {
|
||||
return "Azure-SDK-For-Go/v10.3.0-beta arm-resources/2017-05-10"
|
||||
return "Azure-SDK-For-Go/" + version.Number + " resources/2016-02-01"
|
||||
}
|
||||
|
||||
// Version returns the semantic version (see http://semver.org) of the client.
|
||||
func Version() string {
|
||||
return "v10.3.0-beta"
|
||||
return version.Number
|
||||
}
|
|
@ -14,20 +14,20 @@ package storage
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
|
||||
// Changes may cause incorrect behavior and will be lost if the code is
|
||||
// regenerated.
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/validation"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// AccountsClient is the the Azure Storage Management API.
|
||||
// AccountsClient is the the Storage Management Client.
|
||||
type AccountsClient struct {
|
||||
ManagementClient
|
||||
BaseClient
|
||||
}
|
||||
|
||||
// NewAccountsClient creates an instance of the AccountsClient client.
|
||||
|
@ -35,27 +35,24 @@ func NewAccountsClient(subscriptionID string) AccountsClient {
|
|||
return NewAccountsClientWithBaseURI(DefaultBaseURI, subscriptionID)
|
||||
}
|
||||
|
||||
// NewAccountsClientWithBaseURI creates an instance of the AccountsClient
|
||||
// client.
|
||||
// NewAccountsClientWithBaseURI creates an instance of the AccountsClient client.
|
||||
func NewAccountsClientWithBaseURI(baseURI string, subscriptionID string) AccountsClient {
|
||||
return AccountsClient{NewWithBaseURI(baseURI, subscriptionID)}
|
||||
}
|
||||
|
||||
// CheckNameAvailability checks that the storage account name is valid and is
|
||||
// not already in use.
|
||||
//
|
||||
// accountName is the name of the storage account within the specified resource
|
||||
// group. Storage account names must be between 3 and 24 characters in length
|
||||
// and use numbers and lower-case letters only.
|
||||
func (client AccountsClient) CheckNameAvailability(accountName AccountCheckNameAvailabilityParameters) (result CheckNameAvailabilityResult, err error) {
|
||||
// CheckNameAvailability checks that the storage account name is valid and is not already in use.
|
||||
// Parameters:
|
||||
// accountName - the name of the storage account within the specified resource group. Storage account names
|
||||
// must be between 3 and 24 characters in length and use numbers and lower-case letters only.
|
||||
func (client AccountsClient) CheckNameAvailability(ctx context.Context, accountName AccountCheckNameAvailabilityParameters) (result CheckNameAvailabilityResult, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: accountName,
|
||||
Constraints: []validation.Constraint{{Target: "accountName.Name", Name: validation.Null, Rule: true, Chain: nil},
|
||||
{Target: "accountName.Type", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "CheckNameAvailability")
|
||||
return result, validation.NewError("storage.AccountsClient", "CheckNameAvailability", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.CheckNameAvailabilityPreparer(accountName)
|
||||
req, err := client.CheckNameAvailabilityPreparer(ctx, accountName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "CheckNameAvailability", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -77,30 +74,31 @@ func (client AccountsClient) CheckNameAvailability(accountName AccountCheckNameA
|
|||
}
|
||||
|
||||
// CheckNameAvailabilityPreparer prepares the CheckNameAvailability request.
|
||||
func (client AccountsClient) CheckNameAvailabilityPreparer(accountName AccountCheckNameAvailabilityParameters) (*http.Request, error) {
|
||||
func (client AccountsClient) CheckNameAvailabilityPreparer(ctx context.Context, accountName AccountCheckNameAvailabilityParameters) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-12-01"
|
||||
const APIVersion = "2016-01-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsJSON(),
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPost(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Storage/checkNameAvailability", pathParameters),
|
||||
autorest.WithJSON(accountName),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// CheckNameAvailabilitySender sends the CheckNameAvailability request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client AccountsClient) CheckNameAvailabilitySender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// CheckNameAvailabilityResponder handles the response to the CheckNameAvailability request. The method always
|
||||
|
@ -116,29 +114,17 @@ func (client AccountsClient) CheckNameAvailabilityResponder(resp *http.Response)
|
|||
return
|
||||
}
|
||||
|
||||
// Create asynchronously creates a new storage account with the specified
|
||||
// parameters. If an account is already created and a subsequent create request
|
||||
// is issued with different properties, the account properties will be updated.
|
||||
// If an account is already created and a subsequent create or update request
|
||||
// is issued with the exact same set of properties, the request will succeed.
|
||||
// This method may poll for completion. Polling can be canceled by passing the
|
||||
// cancel channel argument. The channel will be used to cancel polling and any
|
||||
// outstanding HTTP requests.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group within the user's
|
||||
// subscription. The name is case insensitive. accountName is the name of the
|
||||
// storage account within the specified resource group. Storage account names
|
||||
// must be between 3 and 24 characters in length and use numbers and lower-case
|
||||
// letters only. parameters is the parameters to provide for the created
|
||||
// account.
|
||||
func (client AccountsClient) Create(resourceGroupName string, accountName string, parameters AccountCreateParameters, cancel <-chan struct{}) (<-chan Account, <-chan error) {
|
||||
resultChan := make(chan Account, 1)
|
||||
errChan := make(chan error, 1)
|
||||
// Create asynchronously creates a new storage account with the specified parameters. If an account is already created
|
||||
// and a subsequent create request is issued with different properties, the account properties will be updated. If an
|
||||
// account is already created and a subsequent create or update request is issued with the exact same set of
|
||||
// properties, the request will succeed.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group within the user's subscription.
|
||||
// accountName - the name of the storage account within the specified resource group. Storage account names
|
||||
// must be between 3 and 24 characters in length and use numbers and lower-case letters only.
|
||||
// parameters - the parameters to provide for the created account.
|
||||
func (client AccountsClient) Create(ctx context.Context, resourceGroupName string, accountName string, parameters AccountCreateParameters) (result AccountsCreateFuture, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: accountName,
|
||||
Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil},
|
||||
{Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}},
|
||||
|
@ -151,71 +137,62 @@ func (client AccountsClient) Create(resourceGroupName string, accountName string
|
|||
{Target: "parameters.AccountPropertiesCreateParameters.Encryption", Name: validation.Null, Rule: false,
|
||||
Chain: []validation.Constraint{{Target: "parameters.AccountPropertiesCreateParameters.Encryption.KeySource", Name: validation.Null, Rule: true, Chain: nil}}},
|
||||
}}}}}); err != nil {
|
||||
errChan <- validation.NewErrorWithValidationError(err, "storage.AccountsClient", "Create")
|
||||
close(errChan)
|
||||
close(resultChan)
|
||||
return resultChan, errChan
|
||||
return result, validation.NewError("storage.AccountsClient", "Create", err.Error())
|
||||
}
|
||||
|
||||
go func() {
|
||||
var err error
|
||||
var result Account
|
||||
defer func() {
|
||||
resultChan <- result
|
||||
errChan <- err
|
||||
close(resultChan)
|
||||
close(errChan)
|
||||
}()
|
||||
req, err := client.CreatePreparer(resourceGroupName, accountName, parameters, cancel)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "Create", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
req, err := client.CreatePreparer(ctx, resourceGroupName, accountName, parameters)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "Create", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.CreateSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "Create", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
result, err = client.CreateSender(req)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "Create", result.Response(), "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.CreateResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "Create", resp, "Failure responding to request")
|
||||
}
|
||||
}()
|
||||
return resultChan, errChan
|
||||
return
|
||||
}
|
||||
|
||||
// CreatePreparer prepares the Create request.
|
||||
func (client AccountsClient) CreatePreparer(resourceGroupName string, accountName string, parameters AccountCreateParameters, cancel <-chan struct{}) (*http.Request, error) {
|
||||
func (client AccountsClient) CreatePreparer(ctx context.Context, resourceGroupName string, accountName string, parameters AccountCreateParameters) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"accountName": autorest.Encode("path", accountName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-12-01"
|
||||
const APIVersion = "2016-01-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsJSON(),
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPut(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{Cancel: cancel})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// CreateSender sends the Create request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client AccountsClient) CreateSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client,
|
||||
req,
|
||||
azure.DoPollForAsynchronous(client.PollingDelay))
|
||||
func (client AccountsClient) CreateSender(req *http.Request) (future AccountsCreateFuture, err error) {
|
||||
var resp *http.Response
|
||||
resp, err = autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = autorest.Respond(resp, azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
future.Future, err = azure.NewFutureFromResponse(resp)
|
||||
return
|
||||
}
|
||||
|
||||
// CreateResponder handles the response to the Create request. The method always
|
||||
|
@ -232,25 +209,19 @@ func (client AccountsClient) CreateResponder(resp *http.Response) (result Accoun
|
|||
}
|
||||
|
||||
// Delete deletes a storage account in Microsoft Azure.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group within the user's
|
||||
// subscription. The name is case insensitive. accountName is the name of the
|
||||
// storage account within the specified resource group. Storage account names
|
||||
// must be between 3 and 24 characters in length and use numbers and lower-case
|
||||
// letters only.
|
||||
func (client AccountsClient) Delete(resourceGroupName string, accountName string) (result autorest.Response, err error) {
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group within the user's subscription.
|
||||
// accountName - the name of the storage account within the specified resource group. Storage account names
|
||||
// must be between 3 and 24 characters in length and use numbers and lower-case letters only.
|
||||
func (client AccountsClient) Delete(ctx context.Context, resourceGroupName string, accountName string) (result autorest.Response, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: accountName,
|
||||
Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil},
|
||||
{Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "Delete")
|
||||
return result, validation.NewError("storage.AccountsClient", "Delete", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.DeletePreparer(resourceGroupName, accountName)
|
||||
req, err := client.DeletePreparer(ctx, resourceGroupName, accountName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "Delete", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -272,14 +243,14 @@ func (client AccountsClient) Delete(resourceGroupName string, accountName string
|
|||
}
|
||||
|
||||
// DeletePreparer prepares the Delete request.
|
||||
func (client AccountsClient) DeletePreparer(resourceGroupName string, accountName string) (*http.Request, error) {
|
||||
func (client AccountsClient) DeletePreparer(ctx context.Context, resourceGroupName string, accountName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"accountName": autorest.Encode("path", accountName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-12-01"
|
||||
const APIVersion = "2016-01-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -289,13 +260,14 @@ func (client AccountsClient) DeletePreparer(resourceGroupName string, accountNam
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// DeleteSender sends the Delete request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client AccountsClient) DeleteSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// DeleteResponder handles the response to the Delete request. The method always
|
||||
|
@ -310,28 +282,21 @@ func (client AccountsClient) DeleteResponder(resp *http.Response) (result autore
|
|||
return
|
||||
}
|
||||
|
||||
// GetProperties returns the properties for the specified storage account
|
||||
// including but not limited to name, SKU name, location, and account status.
|
||||
// The ListKeys operation should be used to retrieve storage keys.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group within the user's
|
||||
// subscription. The name is case insensitive. accountName is the name of the
|
||||
// storage account within the specified resource group. Storage account names
|
||||
// must be between 3 and 24 characters in length and use numbers and lower-case
|
||||
// letters only.
|
||||
func (client AccountsClient) GetProperties(resourceGroupName string, accountName string) (result Account, err error) {
|
||||
// GetProperties returns the properties for the specified storage account including but not limited to name, SKU name,
|
||||
// location, and account status. The ListKeys operation should be used to retrieve storage keys.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group within the user's subscription.
|
||||
// accountName - the name of the storage account within the specified resource group. Storage account names
|
||||
// must be between 3 and 24 characters in length and use numbers and lower-case letters only.
|
||||
func (client AccountsClient) GetProperties(ctx context.Context, resourceGroupName string, accountName string) (result Account, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: accountName,
|
||||
Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil},
|
||||
{Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "GetProperties")
|
||||
return result, validation.NewError("storage.AccountsClient", "GetProperties", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.GetPropertiesPreparer(resourceGroupName, accountName)
|
||||
req, err := client.GetPropertiesPreparer(ctx, resourceGroupName, accountName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "GetProperties", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -353,14 +318,14 @@ func (client AccountsClient) GetProperties(resourceGroupName string, accountName
|
|||
}
|
||||
|
||||
// GetPropertiesPreparer prepares the GetProperties request.
|
||||
func (client AccountsClient) GetPropertiesPreparer(resourceGroupName string, accountName string) (*http.Request, error) {
|
||||
func (client AccountsClient) GetPropertiesPreparer(ctx context.Context, resourceGroupName string, accountName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"accountName": autorest.Encode("path", accountName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-12-01"
|
||||
const APIVersion = "2016-01-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -370,13 +335,14 @@ func (client AccountsClient) GetPropertiesPreparer(resourceGroupName string, acc
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// GetPropertiesSender sends the GetProperties request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client AccountsClient) GetPropertiesSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// GetPropertiesResponder handles the response to the GetProperties request. The method always
|
||||
|
@ -392,10 +358,10 @@ func (client AccountsClient) GetPropertiesResponder(resp *http.Response) (result
|
|||
return
|
||||
}
|
||||
|
||||
// List lists all the storage accounts available under the subscription. Note
|
||||
// that storage keys are not returned; use the ListKeys operation for this.
|
||||
func (client AccountsClient) List() (result AccountListResult, err error) {
|
||||
req, err := client.ListPreparer()
|
||||
// List lists all the storage accounts available under the subscription. Note that storage keys are not returned; use
|
||||
// the ListKeys operation for this.
|
||||
func (client AccountsClient) List(ctx context.Context) (result AccountListResult, err error) {
|
||||
req, err := client.ListPreparer(ctx)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "List", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -417,12 +383,12 @@ func (client AccountsClient) List() (result AccountListResult, err error) {
|
|||
}
|
||||
|
||||
// ListPreparer prepares the List request.
|
||||
func (client AccountsClient) ListPreparer() (*http.Request, error) {
|
||||
func (client AccountsClient) ListPreparer(ctx context.Context) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-12-01"
|
||||
const APIVersion = "2016-01-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -432,13 +398,14 @@ func (client AccountsClient) ListPreparer() (*http.Request, error) {
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Storage/storageAccounts", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListSender sends the List request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client AccountsClient) ListSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListResponder handles the response to the List request. The method always
|
||||
|
@ -454,107 +421,12 @@ func (client AccountsClient) ListResponder(resp *http.Response) (result AccountL
|
|||
return
|
||||
}
|
||||
|
||||
// ListAccountSAS list SAS credentials of a storage account.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group within the user's
|
||||
// subscription. The name is case insensitive. accountName is the name of the
|
||||
// storage account within the specified resource group. Storage account names
|
||||
// must be between 3 and 24 characters in length and use numbers and lower-case
|
||||
// letters only. parameters is the parameters to provide to list SAS
|
||||
// credentials for the storage account.
|
||||
func (client AccountsClient) ListAccountSAS(resourceGroupName string, accountName string, parameters AccountSasParameters) (result ListAccountSasResponse, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: accountName,
|
||||
Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil},
|
||||
{Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}},
|
||||
{TargetValue: parameters,
|
||||
Constraints: []validation.Constraint{{Target: "parameters.SharedAccessExpiryTime", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "ListAccountSAS")
|
||||
}
|
||||
|
||||
req, err := client.ListAccountSASPreparer(resourceGroupName, accountName, parameters)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "ListAccountSAS", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListAccountSASSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "ListAccountSAS", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.ListAccountSASResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "ListAccountSAS", resp, "Failure responding to request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ListAccountSASPreparer prepares the ListAccountSAS request.
|
||||
func (client AccountsClient) ListAccountSASPreparer(resourceGroupName string, accountName string, parameters AccountSasParameters) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"accountName": autorest.Encode("path", accountName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-12-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsJSON(),
|
||||
autorest.AsPost(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/ListAccountSas", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
}
|
||||
|
||||
// ListAccountSASSender sends the ListAccountSAS request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client AccountsClient) ListAccountSASSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
}
|
||||
|
||||
// ListAccountSASResponder handles the response to the ListAccountSAS request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client AccountsClient) ListAccountSASResponder(resp *http.Response) (result ListAccountSasResponse, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// ListByResourceGroup lists all the storage accounts available under the given
|
||||
// resource group. Note that storage keys are not returned; use the ListKeys
|
||||
// operation for this.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group within the user's
|
||||
// subscription. The name is case insensitive.
|
||||
func (client AccountsClient) ListByResourceGroup(resourceGroupName string) (result AccountListResult, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "ListByResourceGroup")
|
||||
}
|
||||
|
||||
req, err := client.ListByResourceGroupPreparer(resourceGroupName)
|
||||
// ListByResourceGroup lists all the storage accounts available under the given resource group. Note that storage keys
|
||||
// are not returned; use the ListKeys operation for this.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group within the user's subscription.
|
||||
func (client AccountsClient) ListByResourceGroup(ctx context.Context, resourceGroupName string) (result AccountListResult, err error) {
|
||||
req, err := client.ListByResourceGroupPreparer(ctx, resourceGroupName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "ListByResourceGroup", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -576,13 +448,13 @@ func (client AccountsClient) ListByResourceGroup(resourceGroupName string) (resu
|
|||
}
|
||||
|
||||
// ListByResourceGroupPreparer prepares the ListByResourceGroup request.
|
||||
func (client AccountsClient) ListByResourceGroupPreparer(resourceGroupName string) (*http.Request, error) {
|
||||
func (client AccountsClient) ListByResourceGroupPreparer(ctx context.Context, resourceGroupName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-12-01"
|
||||
const APIVersion = "2016-01-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -592,13 +464,14 @@ func (client AccountsClient) ListByResourceGroupPreparer(resourceGroupName strin
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client AccountsClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always
|
||||
|
@ -615,25 +488,19 @@ func (client AccountsClient) ListByResourceGroupResponder(resp *http.Response) (
|
|||
}
|
||||
|
||||
// ListKeys lists the access keys for the specified storage account.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group within the user's
|
||||
// subscription. The name is case insensitive. accountName is the name of the
|
||||
// storage account within the specified resource group. Storage account names
|
||||
// must be between 3 and 24 characters in length and use numbers and lower-case
|
||||
// letters only.
|
||||
func (client AccountsClient) ListKeys(resourceGroupName string, accountName string) (result AccountListKeysResult, err error) {
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group within the user's subscription.
|
||||
// accountName - the name of the storage account within the specified resource group. Storage account names
|
||||
// must be between 3 and 24 characters in length and use numbers and lower-case letters only.
|
||||
func (client AccountsClient) ListKeys(ctx context.Context, resourceGroupName string, accountName string) (result AccountListKeysResult, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: accountName,
|
||||
Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil},
|
||||
{Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "ListKeys")
|
||||
return result, validation.NewError("storage.AccountsClient", "ListKeys", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.ListKeysPreparer(resourceGroupName, accountName)
|
||||
req, err := client.ListKeysPreparer(ctx, resourceGroupName, accountName)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "ListKeys", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -655,14 +522,14 @@ func (client AccountsClient) ListKeys(resourceGroupName string, accountName stri
|
|||
}
|
||||
|
||||
// ListKeysPreparer prepares the ListKeys request.
|
||||
func (client AccountsClient) ListKeysPreparer(resourceGroupName string, accountName string) (*http.Request, error) {
|
||||
func (client AccountsClient) ListKeysPreparer(ctx context.Context, resourceGroupName string, accountName string) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"accountName": autorest.Encode("path", accountName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-12-01"
|
||||
const APIVersion = "2016-01-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -672,13 +539,14 @@ func (client AccountsClient) ListKeysPreparer(resourceGroupName string, accountN
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/listKeys", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListKeysSender sends the ListKeys request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client AccountsClient) ListKeysSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListKeysResponder handles the response to the ListKeys request. The method always
|
||||
|
@ -694,117 +562,23 @@ func (client AccountsClient) ListKeysResponder(resp *http.Response) (result Acco
|
|||
return
|
||||
}
|
||||
|
||||
// ListServiceSAS list service SAS credentials of a specific resource.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group within the user's
|
||||
// subscription. The name is case insensitive. accountName is the name of the
|
||||
// storage account within the specified resource group. Storage account names
|
||||
// must be between 3 and 24 characters in length and use numbers and lower-case
|
||||
// letters only. parameters is the parameters to provide to list service SAS
|
||||
// credentials.
|
||||
func (client AccountsClient) ListServiceSAS(resourceGroupName string, accountName string, parameters ServiceSasParameters) (result ListServiceSasResponse, err error) {
|
||||
// RegenerateKey regenerates one of the access keys for the specified storage account.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group within the user's subscription.
|
||||
// accountName - 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 - specifies name of the key which should be regenerated -- key1 or key2.
|
||||
func (client AccountsClient) RegenerateKey(ctx context.Context, resourceGroupName string, accountName string, regenerateKey AccountRegenerateKeyParameters) (result AccountListKeysResult, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: accountName,
|
||||
Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil},
|
||||
{Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}},
|
||||
{TargetValue: parameters,
|
||||
Constraints: []validation.Constraint{{Target: "parameters.CanonicalizedResource", Name: validation.Null, Rule: true, Chain: nil},
|
||||
{Target: "parameters.Identifier", Name: validation.Null, Rule: false,
|
||||
Chain: []validation.Constraint{{Target: "parameters.Identifier", Name: validation.MaxLength, Rule: 64, Chain: nil}}}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "ListServiceSAS")
|
||||
}
|
||||
|
||||
req, err := client.ListServiceSASPreparer(resourceGroupName, accountName, parameters)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "ListServiceSAS", nil, "Failure preparing request")
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.ListServiceSASSender(req)
|
||||
if err != nil {
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "ListServiceSAS", resp, "Failure sending request")
|
||||
return
|
||||
}
|
||||
|
||||
result, err = client.ListServiceSASResponder(resp)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "ListServiceSAS", resp, "Failure responding to request")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ListServiceSASPreparer prepares the ListServiceSAS request.
|
||||
func (client AccountsClient) ListServiceSASPreparer(resourceGroupName string, accountName string, parameters ServiceSasParameters) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"accountName": autorest.Encode("path", accountName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-12-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsJSON(),
|
||||
autorest.AsPost(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/ListServiceSas", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
}
|
||||
|
||||
// ListServiceSASSender sends the ListServiceSAS request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client AccountsClient) ListServiceSASSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
}
|
||||
|
||||
// ListServiceSASResponder handles the response to the ListServiceSAS request. The method always
|
||||
// closes the http.Response Body.
|
||||
func (client AccountsClient) ListServiceSASResponder(resp *http.Response) (result ListServiceSasResponse, err error) {
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
client.ByInspecting(),
|
||||
azure.WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&result),
|
||||
autorest.ByClosing())
|
||||
result.Response = autorest.Response{Response: resp}
|
||||
return
|
||||
}
|
||||
|
||||
// RegenerateKey regenerates one of the access keys for the specified storage
|
||||
// account.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group within the user's
|
||||
// subscription. The name is case insensitive. 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.
|
||||
func (client AccountsClient) RegenerateKey(resourceGroupName string, accountName string, regenerateKey AccountRegenerateKeyParameters) (result AccountListKeysResult, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: accountName,
|
||||
Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil},
|
||||
{Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}},
|
||||
{TargetValue: regenerateKey,
|
||||
Constraints: []validation.Constraint{{Target: "regenerateKey.KeyName", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "RegenerateKey")
|
||||
return result, validation.NewError("storage.AccountsClient", "RegenerateKey", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.RegenerateKeyPreparer(resourceGroupName, accountName, regenerateKey)
|
||||
req, err := client.RegenerateKeyPreparer(ctx, resourceGroupName, accountName, regenerateKey)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "RegenerateKey", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -826,32 +600,33 @@ func (client AccountsClient) RegenerateKey(resourceGroupName string, accountName
|
|||
}
|
||||
|
||||
// RegenerateKeyPreparer prepares the RegenerateKey request.
|
||||
func (client AccountsClient) RegenerateKeyPreparer(resourceGroupName string, accountName string, regenerateKey AccountRegenerateKeyParameters) (*http.Request, error) {
|
||||
func (client AccountsClient) RegenerateKeyPreparer(ctx context.Context, resourceGroupName string, accountName string, regenerateKey AccountRegenerateKeyParameters) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"accountName": autorest.Encode("path", accountName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-12-01"
|
||||
const APIVersion = "2016-01-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsJSON(),
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPost(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}/regenerateKey", pathParameters),
|
||||
autorest.WithJSON(regenerateKey),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// RegenerateKeySender sends the RegenerateKey request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client AccountsClient) RegenerateKeySender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// RegenerateKeyResponder handles the response to the RegenerateKey request. The method always
|
||||
|
@ -867,36 +642,26 @@ func (client AccountsClient) RegenerateKeyResponder(resp *http.Response) (result
|
|||
return
|
||||
}
|
||||
|
||||
// Update the update operation can be used to update the SKU, encryption,
|
||||
// access tier, or tags for a storage account. It can also be used to map the
|
||||
// account to a custom domain. Only one custom domain is supported per storage
|
||||
// account; the replacement/change of custom domain is not supported. In order
|
||||
// to replace an old custom domain, the old value must be cleared/unregistered
|
||||
// before a new value can be set. The update of multiple properties is
|
||||
// supported. This call does not change the storage keys for the account. If
|
||||
// you want to change the storage account keys, use the regenerate keys
|
||||
// operation. The location and name of the storage account cannot be changed
|
||||
// after creation.
|
||||
//
|
||||
// resourceGroupName is the name of the resource group within the user's
|
||||
// subscription. The name is case insensitive. accountName is the name of the
|
||||
// storage account within the specified resource group. Storage account names
|
||||
// must be between 3 and 24 characters in length and use numbers and lower-case
|
||||
// letters only. parameters is the parameters to provide for the updated
|
||||
// account.
|
||||
func (client AccountsClient) Update(resourceGroupName string, accountName string, parameters AccountUpdateParameters) (result Account, err error) {
|
||||
// Update the update operation can be used to update the SKU, encryption, access tier, or tags for a storage account.
|
||||
// It can also be used to map the account to a custom domain. Only one custom domain is supported per storage account;
|
||||
// the replacement/change of custom domain is not supported. In order to replace an old custom domain, the old value
|
||||
// must be cleared/unregistered before a new value can be set. The update of multiple properties is supported. This
|
||||
// call does not change the storage keys for the account. If you want to change the storage account keys, use the
|
||||
// regenerate keys operation. The location and name of the storage account cannot be changed after creation.
|
||||
// Parameters:
|
||||
// resourceGroupName - the name of the resource group within the user's subscription.
|
||||
// accountName - the name of the storage account within the specified resource group. Storage account names
|
||||
// must be between 3 and 24 characters in length and use numbers and lower-case letters only.
|
||||
// parameters - the parameters to provide for the updated account.
|
||||
func (client AccountsClient) Update(ctx context.Context, resourceGroupName string, accountName string, parameters AccountUpdateParameters) (result Account, err error) {
|
||||
if err := validation.Validate([]validation.Validation{
|
||||
{TargetValue: resourceGroupName,
|
||||
Constraints: []validation.Constraint{{Target: "resourceGroupName", Name: validation.MaxLength, Rule: 90, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.MinLength, Rule: 1, Chain: nil},
|
||||
{Target: "resourceGroupName", Name: validation.Pattern, Rule: `^[-\w\._\(\)]+$`, Chain: nil}}},
|
||||
{TargetValue: accountName,
|
||||
Constraints: []validation.Constraint{{Target: "accountName", Name: validation.MaxLength, Rule: 24, Chain: nil},
|
||||
{Target: "accountName", Name: validation.MinLength, Rule: 3, Chain: nil}}}}); err != nil {
|
||||
return result, validation.NewErrorWithValidationError(err, "storage.AccountsClient", "Update")
|
||||
return result, validation.NewError("storage.AccountsClient", "Update", err.Error())
|
||||
}
|
||||
|
||||
req, err := client.UpdatePreparer(resourceGroupName, accountName, parameters)
|
||||
req, err := client.UpdatePreparer(ctx, resourceGroupName, accountName, parameters)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsClient", "Update", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -918,32 +683,33 @@ func (client AccountsClient) Update(resourceGroupName string, accountName string
|
|||
}
|
||||
|
||||
// UpdatePreparer prepares the Update request.
|
||||
func (client AccountsClient) UpdatePreparer(resourceGroupName string, accountName string, parameters AccountUpdateParameters) (*http.Request, error) {
|
||||
func (client AccountsClient) UpdatePreparer(ctx context.Context, resourceGroupName string, accountName string, parameters AccountUpdateParameters) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"accountName": autorest.Encode("path", accountName),
|
||||
"resourceGroupName": autorest.Encode("path", resourceGroupName),
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-12-01"
|
||||
const APIVersion = "2016-01-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsJSON(),
|
||||
autorest.AsContentType("application/json; charset=utf-8"),
|
||||
autorest.AsPatch(),
|
||||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Storage/storageAccounts/{accountName}", pathParameters),
|
||||
autorest.WithJSON(parameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// UpdateSender sends the Update request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client AccountsClient) UpdateSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// UpdateResponder handles the response to the Update request. The method always
|
|
@ -1,7 +1,6 @@
|
|||
// Package storage implements the Azure ARM Storage service API version
|
||||
// 2016-12-01.
|
||||
// Package storage implements the Azure ARM Storage service API version 2016-01-01.
|
||||
//
|
||||
// The Azure Storage Management API.
|
||||
// The Storage Management Client.
|
||||
package storage
|
||||
|
||||
// Copyright (c) Microsoft and contributors. All rights reserved.
|
||||
|
@ -18,9 +17,8 @@ package storage
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
|
||||
// Changes may cause incorrect behavior and will be lost if the code is
|
||||
// regenerated.
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
|
@ -31,21 +29,21 @@ const (
|
|||
DefaultBaseURI = "https://management.azure.com"
|
||||
)
|
||||
|
||||
// ManagementClient is the base client for Storage.
|
||||
type ManagementClient struct {
|
||||
// BaseClient is the base client for Storage.
|
||||
type BaseClient struct {
|
||||
autorest.Client
|
||||
BaseURI string
|
||||
SubscriptionID string
|
||||
}
|
||||
|
||||
// New creates an instance of the ManagementClient client.
|
||||
func New(subscriptionID string) ManagementClient {
|
||||
// New creates an instance of the BaseClient client.
|
||||
func New(subscriptionID string) BaseClient {
|
||||
return NewWithBaseURI(DefaultBaseURI, subscriptionID)
|
||||
}
|
||||
|
||||
// NewWithBaseURI creates an instance of the ManagementClient client.
|
||||
func NewWithBaseURI(baseURI string, subscriptionID string) ManagementClient {
|
||||
return ManagementClient{
|
||||
// NewWithBaseURI creates an instance of the BaseClient client.
|
||||
func NewWithBaseURI(baseURI string, subscriptionID string) BaseClient {
|
||||
return BaseClient{
|
||||
Client: autorest.NewClientWithUserAgent(UserAgent()),
|
||||
BaseURI: baseURI,
|
||||
SubscriptionID: subscriptionID,
|
708
vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2016-01-01/storage/models.go
generated
vendored
Normal file
708
vendor/github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2016-01-01/storage/models.go
generated
vendored
Normal file
|
@ -0,0 +1,708 @@
|
|||
package storage
|
||||
|
||||
// Copyright (c) Microsoft and contributors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
//
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"github.com/Azure/go-autorest/autorest/date"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// AccessTier enumerates the values for access tier.
|
||||
type AccessTier string
|
||||
|
||||
const (
|
||||
// Cool ...
|
||||
Cool AccessTier = "Cool"
|
||||
// Hot ...
|
||||
Hot AccessTier = "Hot"
|
||||
)
|
||||
|
||||
// PossibleAccessTierValues returns an array of possible values for the AccessTier const type.
|
||||
func PossibleAccessTierValues() []AccessTier {
|
||||
return []AccessTier{Cool, Hot}
|
||||
}
|
||||
|
||||
// AccountStatus enumerates the values for account status.
|
||||
type AccountStatus string
|
||||
|
||||
const (
|
||||
// Available ...
|
||||
Available AccountStatus = "Available"
|
||||
// Unavailable ...
|
||||
Unavailable AccountStatus = "Unavailable"
|
||||
)
|
||||
|
||||
// PossibleAccountStatusValues returns an array of possible values for the AccountStatus const type.
|
||||
func PossibleAccountStatusValues() []AccountStatus {
|
||||
return []AccountStatus{Available, Unavailable}
|
||||
}
|
||||
|
||||
// KeyPermission enumerates the values for key permission.
|
||||
type KeyPermission string
|
||||
|
||||
const (
|
||||
// FULL ...
|
||||
FULL KeyPermission = "FULL"
|
||||
// READ ...
|
||||
READ KeyPermission = "READ"
|
||||
)
|
||||
|
||||
// PossibleKeyPermissionValues returns an array of possible values for the KeyPermission const type.
|
||||
func PossibleKeyPermissionValues() []KeyPermission {
|
||||
return []KeyPermission{FULL, READ}
|
||||
}
|
||||
|
||||
// Kind enumerates the values for kind.
|
||||
type Kind string
|
||||
|
||||
const (
|
||||
// BlobStorage ...
|
||||
BlobStorage Kind = "BlobStorage"
|
||||
// Storage ...
|
||||
Storage Kind = "Storage"
|
||||
)
|
||||
|
||||
// PossibleKindValues returns an array of possible values for the Kind const type.
|
||||
func PossibleKindValues() []Kind {
|
||||
return []Kind{BlobStorage, Storage}
|
||||
}
|
||||
|
||||
// ProvisioningState enumerates the values for provisioning state.
|
||||
type ProvisioningState string
|
||||
|
||||
const (
|
||||
// Creating ...
|
||||
Creating ProvisioningState = "Creating"
|
||||
// ResolvingDNS ...
|
||||
ResolvingDNS ProvisioningState = "ResolvingDNS"
|
||||
// Succeeded ...
|
||||
Succeeded ProvisioningState = "Succeeded"
|
||||
)
|
||||
|
||||
// PossibleProvisioningStateValues returns an array of possible values for the ProvisioningState const type.
|
||||
func PossibleProvisioningStateValues() []ProvisioningState {
|
||||
return []ProvisioningState{Creating, ResolvingDNS, Succeeded}
|
||||
}
|
||||
|
||||
// Reason enumerates the values for reason.
|
||||
type Reason string
|
||||
|
||||
const (
|
||||
// AccountNameInvalid ...
|
||||
AccountNameInvalid Reason = "AccountNameInvalid"
|
||||
// AlreadyExists ...
|
||||
AlreadyExists Reason = "AlreadyExists"
|
||||
)
|
||||
|
||||
// PossibleReasonValues returns an array of possible values for the Reason const type.
|
||||
func PossibleReasonValues() []Reason {
|
||||
return []Reason{AccountNameInvalid, AlreadyExists}
|
||||
}
|
||||
|
||||
// SkuName enumerates the values for sku name.
|
||||
type SkuName string
|
||||
|
||||
const (
|
||||
// PremiumLRS ...
|
||||
PremiumLRS SkuName = "Premium_LRS"
|
||||
// StandardGRS ...
|
||||
StandardGRS SkuName = "Standard_GRS"
|
||||
// StandardLRS ...
|
||||
StandardLRS SkuName = "Standard_LRS"
|
||||
// StandardRAGRS ...
|
||||
StandardRAGRS SkuName = "Standard_RAGRS"
|
||||
// StandardZRS ...
|
||||
StandardZRS SkuName = "Standard_ZRS"
|
||||
)
|
||||
|
||||
// PossibleSkuNameValues returns an array of possible values for the SkuName const type.
|
||||
func PossibleSkuNameValues() []SkuName {
|
||||
return []SkuName{PremiumLRS, StandardGRS, StandardLRS, StandardRAGRS, StandardZRS}
|
||||
}
|
||||
|
||||
// SkuTier enumerates the values for sku tier.
|
||||
type SkuTier string
|
||||
|
||||
const (
|
||||
// Premium ...
|
||||
Premium SkuTier = "Premium"
|
||||
// Standard ...
|
||||
Standard SkuTier = "Standard"
|
||||
)
|
||||
|
||||
// PossibleSkuTierValues returns an array of possible values for the SkuTier const type.
|
||||
func PossibleSkuTierValues() []SkuTier {
|
||||
return []SkuTier{Premium, Standard}
|
||||
}
|
||||
|
||||
// UsageUnit enumerates the values for usage unit.
|
||||
type UsageUnit string
|
||||
|
||||
const (
|
||||
// Bytes ...
|
||||
Bytes UsageUnit = "Bytes"
|
||||
// BytesPerSecond ...
|
||||
BytesPerSecond UsageUnit = "BytesPerSecond"
|
||||
// Count ...
|
||||
Count UsageUnit = "Count"
|
||||
// CountsPerSecond ...
|
||||
CountsPerSecond UsageUnit = "CountsPerSecond"
|
||||
// Percent ...
|
||||
Percent UsageUnit = "Percent"
|
||||
// Seconds ...
|
||||
Seconds UsageUnit = "Seconds"
|
||||
)
|
||||
|
||||
// PossibleUsageUnitValues returns an array of possible values for the UsageUnit const type.
|
||||
func PossibleUsageUnitValues() []UsageUnit {
|
||||
return []UsageUnit{Bytes, BytesPerSecond, Count, CountsPerSecond, Percent, Seconds}
|
||||
}
|
||||
|
||||
// Account the storage account.
|
||||
type Account struct {
|
||||
autorest.Response `json:"-"`
|
||||
// Sku - Gets the SKU.
|
||||
Sku *Sku `json:"sku,omitempty"`
|
||||
// Kind - Gets the Kind. Possible values include: 'Storage', 'BlobStorage'
|
||||
Kind Kind `json:"kind,omitempty"`
|
||||
*AccountProperties `json:"properties,omitempty"`
|
||||
// ID - Resource Id
|
||||
ID *string `json:"id,omitempty"`
|
||||
// Name - Resource name
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Type - Resource type
|
||||
Type *string `json:"type,omitempty"`
|
||||
// Location - Resource location
|
||||
Location *string `json:"location,omitempty"`
|
||||
// Tags - Tags assigned to a resource; can be used for viewing and grouping a resource (across resource groups).
|
||||
Tags map[string]*string `json:"tags"`
|
||||
}
|
||||
|
||||
// MarshalJSON is the custom marshaler for Account.
|
||||
func (a Account) MarshalJSON() ([]byte, error) {
|
||||
objectMap := make(map[string]interface{})
|
||||
if a.Sku != nil {
|
||||
objectMap["sku"] = a.Sku
|
||||
}
|
||||
if a.Kind != "" {
|
||||
objectMap["kind"] = a.Kind
|
||||
}
|
||||
if a.AccountProperties != nil {
|
||||
objectMap["properties"] = a.AccountProperties
|
||||
}
|
||||
if a.ID != nil {
|
||||
objectMap["id"] = a.ID
|
||||
}
|
||||
if a.Name != nil {
|
||||
objectMap["name"] = a.Name
|
||||
}
|
||||
if a.Type != nil {
|
||||
objectMap["type"] = a.Type
|
||||
}
|
||||
if a.Location != nil {
|
||||
objectMap["location"] = a.Location
|
||||
}
|
||||
if a.Tags != nil {
|
||||
objectMap["tags"] = a.Tags
|
||||
}
|
||||
return json.Marshal(objectMap)
|
||||
}
|
||||
|
||||
// UnmarshalJSON is the custom unmarshaler for Account struct.
|
||||
func (a *Account) UnmarshalJSON(body []byte) error {
|
||||
var m map[string]*json.RawMessage
|
||||
err := json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for k, v := range m {
|
||||
switch k {
|
||||
case "sku":
|
||||
if v != nil {
|
||||
var sku Sku
|
||||
err = json.Unmarshal(*v, &sku)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.Sku = &sku
|
||||
}
|
||||
case "kind":
|
||||
if v != nil {
|
||||
var kind Kind
|
||||
err = json.Unmarshal(*v, &kind)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.Kind = kind
|
||||
}
|
||||
case "properties":
|
||||
if v != nil {
|
||||
var accountProperties AccountProperties
|
||||
err = json.Unmarshal(*v, &accountProperties)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.AccountProperties = &accountProperties
|
||||
}
|
||||
case "id":
|
||||
if v != nil {
|
||||
var ID string
|
||||
err = json.Unmarshal(*v, &ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.ID = &ID
|
||||
}
|
||||
case "name":
|
||||
if v != nil {
|
||||
var name string
|
||||
err = json.Unmarshal(*v, &name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.Name = &name
|
||||
}
|
||||
case "type":
|
||||
if v != nil {
|
||||
var typeVar string
|
||||
err = json.Unmarshal(*v, &typeVar)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.Type = &typeVar
|
||||
}
|
||||
case "location":
|
||||
if v != nil {
|
||||
var location string
|
||||
err = json.Unmarshal(*v, &location)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.Location = &location
|
||||
}
|
||||
case "tags":
|
||||
if v != nil {
|
||||
var tags map[string]*string
|
||||
err = json.Unmarshal(*v, &tags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.Tags = tags
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AccountCheckNameAvailabilityParameters ...
|
||||
type AccountCheckNameAvailabilityParameters struct {
|
||||
Name *string `json:"name,omitempty"`
|
||||
Type *string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// AccountCreateParameters the parameters used when creating a storage account.
|
||||
type AccountCreateParameters struct {
|
||||
// Sku - Required. Gets or sets the sku name.
|
||||
Sku *Sku `json:"sku,omitempty"`
|
||||
// Kind - Required. Indicates the type of storage account. Possible values include: 'Storage', 'BlobStorage'
|
||||
Kind Kind `json:"kind,omitempty"`
|
||||
// Location - Required. Gets or sets the location of the resource. This will be one of the supported and registered Azure Geo Regions (e.g. West US, East US, Southeast Asia, etc.). The geo region of a resource cannot be changed once it is created, but if an identical geo region is specified on update, the request will succeed.
|
||||
Location *string `json:"location,omitempty"`
|
||||
// Tags - Gets or sets a list of key value pairs that describe the resource. These tags can be used for viewing and grouping this resource (across resource groups). A maximum of 15 tags can be provided for a resource. Each tag must have a key with a length no greater than 128 characters and a value with a length no greater than 256 characters.
|
||||
Tags map[string]*string `json:"tags"`
|
||||
*AccountPropertiesCreateParameters `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON is the custom marshaler for AccountCreateParameters.
|
||||
func (acp AccountCreateParameters) MarshalJSON() ([]byte, error) {
|
||||
objectMap := make(map[string]interface{})
|
||||
if acp.Sku != nil {
|
||||
objectMap["sku"] = acp.Sku
|
||||
}
|
||||
if acp.Kind != "" {
|
||||
objectMap["kind"] = acp.Kind
|
||||
}
|
||||
if acp.Location != nil {
|
||||
objectMap["location"] = acp.Location
|
||||
}
|
||||
if acp.Tags != nil {
|
||||
objectMap["tags"] = acp.Tags
|
||||
}
|
||||
if acp.AccountPropertiesCreateParameters != nil {
|
||||
objectMap["properties"] = acp.AccountPropertiesCreateParameters
|
||||
}
|
||||
return json.Marshal(objectMap)
|
||||
}
|
||||
|
||||
// UnmarshalJSON is the custom unmarshaler for AccountCreateParameters struct.
|
||||
func (acp *AccountCreateParameters) UnmarshalJSON(body []byte) error {
|
||||
var m map[string]*json.RawMessage
|
||||
err := json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for k, v := range m {
|
||||
switch k {
|
||||
case "sku":
|
||||
if v != nil {
|
||||
var sku Sku
|
||||
err = json.Unmarshal(*v, &sku)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
acp.Sku = &sku
|
||||
}
|
||||
case "kind":
|
||||
if v != nil {
|
||||
var kind Kind
|
||||
err = json.Unmarshal(*v, &kind)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
acp.Kind = kind
|
||||
}
|
||||
case "location":
|
||||
if v != nil {
|
||||
var location string
|
||||
err = json.Unmarshal(*v, &location)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
acp.Location = &location
|
||||
}
|
||||
case "tags":
|
||||
if v != nil {
|
||||
var tags map[string]*string
|
||||
err = json.Unmarshal(*v, &tags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
acp.Tags = tags
|
||||
}
|
||||
case "properties":
|
||||
if v != nil {
|
||||
var accountPropertiesCreateParameters AccountPropertiesCreateParameters
|
||||
err = json.Unmarshal(*v, &accountPropertiesCreateParameters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
acp.AccountPropertiesCreateParameters = &accountPropertiesCreateParameters
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AccountKey an access key for the storage account.
|
||||
type AccountKey struct {
|
||||
// KeyName - Name of the key.
|
||||
KeyName *string `json:"keyName,omitempty"`
|
||||
// Value - Base 64-encoded value of the key.
|
||||
Value *string `json:"value,omitempty"`
|
||||
// Permissions - Permissions for the key -- read-only or full permissions. Possible values include: 'READ', 'FULL'
|
||||
Permissions KeyPermission `json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
// AccountListKeysResult the response from the ListKeys operation.
|
||||
type AccountListKeysResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
// Keys - Gets the list of storage account keys and their properties for the specified storage account.
|
||||
Keys *[]AccountKey `json:"keys,omitempty"`
|
||||
}
|
||||
|
||||
// AccountListResult the response from the List Storage Accounts operation.
|
||||
type AccountListResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
// Value - Gets the list of storage accounts and their properties.
|
||||
Value *[]Account `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// AccountProperties ...
|
||||
type AccountProperties struct {
|
||||
// ProvisioningState - Gets the status of the storage account at the time the operation was called. Possible values include: 'Creating', 'ResolvingDNS', 'Succeeded'
|
||||
ProvisioningState ProvisioningState `json:"provisioningState,omitempty"`
|
||||
// PrimaryEndpoints - Gets the URLs that are used to perform a retrieval of a public blob, queue, or table object. Note that Standard_ZRS and Premium_LRS accounts only return the blob endpoint.
|
||||
PrimaryEndpoints *Endpoints `json:"primaryEndpoints,omitempty"`
|
||||
// PrimaryLocation - Gets the location of the primary data center for the storage account.
|
||||
PrimaryLocation *string `json:"primaryLocation,omitempty"`
|
||||
// StatusOfPrimary - Gets the status indicating whether the primary location of the storage account is available or unavailable. Possible values include: 'Available', 'Unavailable'
|
||||
StatusOfPrimary AccountStatus `json:"statusOfPrimary,omitempty"`
|
||||
// LastGeoFailoverTime - Gets the timestamp of the most recent instance of a failover to the secondary location. Only the most recent timestamp is retained. This element is not returned if there has never been a failover instance. Only available if the accountType is Standard_GRS or Standard_RAGRS.
|
||||
LastGeoFailoverTime *date.Time `json:"lastGeoFailoverTime,omitempty"`
|
||||
// SecondaryLocation - Gets the location of the geo-replicated secondary for the storage account. Only available if the accountType is Standard_GRS or Standard_RAGRS.
|
||||
SecondaryLocation *string `json:"secondaryLocation,omitempty"`
|
||||
// StatusOfSecondary - Gets the status indicating whether the secondary location of the storage account is available or unavailable. Only available if the SKU name is Standard_GRS or Standard_RAGRS. Possible values include: 'Available', 'Unavailable'
|
||||
StatusOfSecondary AccountStatus `json:"statusOfSecondary,omitempty"`
|
||||
// CreationTime - Gets the creation date and time of the storage account in UTC.
|
||||
CreationTime *date.Time `json:"creationTime,omitempty"`
|
||||
// CustomDomain - Gets the custom domain the user assigned to this storage account.
|
||||
CustomDomain *CustomDomain `json:"customDomain,omitempty"`
|
||||
// SecondaryEndpoints - Gets the URLs that are used to perform a retrieval of a public blob, queue, or table object from the secondary location of the storage account. Only available if the SKU name is Standard_RAGRS.
|
||||
SecondaryEndpoints *Endpoints `json:"secondaryEndpoints,omitempty"`
|
||||
// Encryption - Gets the encryption settings on the account. If unspecified, the account is unencrypted.
|
||||
Encryption *Encryption `json:"encryption,omitempty"`
|
||||
// AccessTier - Required for storage accounts where kind = BlobStorage. The access tier used for billing. Possible values include: 'Hot', 'Cool'
|
||||
AccessTier AccessTier `json:"accessTier,omitempty"`
|
||||
}
|
||||
|
||||
// AccountPropertiesCreateParameters ...
|
||||
type AccountPropertiesCreateParameters struct {
|
||||
// CustomDomain - User domain assigned to the storage account. Name is the CNAME source. Only one custom domain is supported per storage account at this time. To clear the existing custom domain, use an empty string for the custom domain name property.
|
||||
CustomDomain *CustomDomain `json:"customDomain,omitempty"`
|
||||
// Encryption - Provides the encryption settings on the account. If left unspecified the account encryption settings will remain the same. The default setting is unencrypted.
|
||||
Encryption *Encryption `json:"encryption,omitempty"`
|
||||
// AccessTier - Required for storage accounts where kind = BlobStorage. The access tier used for billing. Possible values include: 'Hot', 'Cool'
|
||||
AccessTier AccessTier `json:"accessTier,omitempty"`
|
||||
}
|
||||
|
||||
// AccountPropertiesUpdateParameters ...
|
||||
type AccountPropertiesUpdateParameters struct {
|
||||
// CustomDomain - Custom domain assigned to the storage account by the user. Name is the CNAME source. Only one custom domain is supported per storage account at this time. To clear the existing custom domain, use an empty string for the custom domain name property.
|
||||
CustomDomain *CustomDomain `json:"customDomain,omitempty"`
|
||||
// Encryption - Provides the encryption settings on the account. The default setting is unencrypted.
|
||||
Encryption *Encryption `json:"encryption,omitempty"`
|
||||
// AccessTier - Required for storage accounts where kind = BlobStorage. The access tier used for billing. Possible values include: 'Hot', 'Cool'
|
||||
AccessTier AccessTier `json:"accessTier,omitempty"`
|
||||
}
|
||||
|
||||
// AccountRegenerateKeyParameters ...
|
||||
type AccountRegenerateKeyParameters struct {
|
||||
KeyName *string `json:"keyName,omitempty"`
|
||||
}
|
||||
|
||||
// AccountsCreateFuture an abstraction for monitoring and retrieving the results of a long-running operation.
|
||||
type AccountsCreateFuture struct {
|
||||
azure.Future
|
||||
}
|
||||
|
||||
// Result returns the result of the asynchronous operation.
|
||||
// If the operation has not completed it will return an error.
|
||||
func (future *AccountsCreateFuture) Result(client AccountsClient) (a Account, err error) {
|
||||
var done bool
|
||||
done, err = future.Done(client)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsCreateFuture", "Result", future.Response(), "Polling failure")
|
||||
return
|
||||
}
|
||||
if !done {
|
||||
err = azure.NewAsyncOpIncompleteError("storage.AccountsCreateFuture")
|
||||
return
|
||||
}
|
||||
sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
|
||||
if a.Response.Response, err = future.GetResult(sender); err == nil && a.Response.Response.StatusCode != http.StatusNoContent {
|
||||
a, err = client.CreateResponder(a.Response.Response)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.AccountsCreateFuture", "Result", a.Response.Response, "Failure responding to request")
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AccountUpdateParameters the parameters that can be provided when updating the storage account properties.
|
||||
type AccountUpdateParameters struct {
|
||||
// Sku - Gets or sets the SKU name. Note that the SKU name cannot be updated to Standard_ZRS or Premium_LRS, nor can accounts of those sku names be updated to any other value.
|
||||
Sku *Sku `json:"sku,omitempty"`
|
||||
// Tags - Gets or sets a list of key value pairs that describe the resource. These tags can be used in viewing and grouping this resource (across resource groups). A maximum of 15 tags can be provided for a resource. Each tag must have a key no greater in length than 128 characters and a value no greater in length than 256 characters.
|
||||
Tags map[string]*string `json:"tags"`
|
||||
*AccountPropertiesUpdateParameters `json:"properties,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON is the custom marshaler for AccountUpdateParameters.
|
||||
func (aup AccountUpdateParameters) MarshalJSON() ([]byte, error) {
|
||||
objectMap := make(map[string]interface{})
|
||||
if aup.Sku != nil {
|
||||
objectMap["sku"] = aup.Sku
|
||||
}
|
||||
if aup.Tags != nil {
|
||||
objectMap["tags"] = aup.Tags
|
||||
}
|
||||
if aup.AccountPropertiesUpdateParameters != nil {
|
||||
objectMap["properties"] = aup.AccountPropertiesUpdateParameters
|
||||
}
|
||||
return json.Marshal(objectMap)
|
||||
}
|
||||
|
||||
// UnmarshalJSON is the custom unmarshaler for AccountUpdateParameters struct.
|
||||
func (aup *AccountUpdateParameters) UnmarshalJSON(body []byte) error {
|
||||
var m map[string]*json.RawMessage
|
||||
err := json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for k, v := range m {
|
||||
switch k {
|
||||
case "sku":
|
||||
if v != nil {
|
||||
var sku Sku
|
||||
err = json.Unmarshal(*v, &sku)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
aup.Sku = &sku
|
||||
}
|
||||
case "tags":
|
||||
if v != nil {
|
||||
var tags map[string]*string
|
||||
err = json.Unmarshal(*v, &tags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
aup.Tags = tags
|
||||
}
|
||||
case "properties":
|
||||
if v != nil {
|
||||
var accountPropertiesUpdateParameters AccountPropertiesUpdateParameters
|
||||
err = json.Unmarshal(*v, &accountPropertiesUpdateParameters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
aup.AccountPropertiesUpdateParameters = &accountPropertiesUpdateParameters
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckNameAvailabilityResult the CheckNameAvailability operation response.
|
||||
type CheckNameAvailabilityResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
// NameAvailable - Gets a boolean value that indicates whether the name is available for you to use. If true, the name is available. If false, the name has already been taken or is invalid and cannot be used.
|
||||
NameAvailable *bool `json:"nameAvailable,omitempty"`
|
||||
// Reason - Gets the reason that a storage account name could not be used. The Reason element is only returned if NameAvailable is false. Possible values include: 'AccountNameInvalid', 'AlreadyExists'
|
||||
Reason Reason `json:"reason,omitempty"`
|
||||
// Message - Gets an error message explaining the Reason value in more detail.
|
||||
Message *string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// CustomDomain the custom domain assigned to this storage account. This can be set via Update.
|
||||
type CustomDomain struct {
|
||||
// Name - Gets or sets the custom domain name assigned to the storage account. Name is the CNAME source.
|
||||
Name *string `json:"name,omitempty"`
|
||||
// UseSubDomain - Indicates whether indirect CName validation is enabled. Default value is false. This should only be set on updates.
|
||||
UseSubDomain *bool `json:"useSubDomain,omitempty"`
|
||||
}
|
||||
|
||||
// Encryption the encryption settings on the storage account.
|
||||
type Encryption struct {
|
||||
// Services - List of services which support encryption.
|
||||
Services *EncryptionServices `json:"services,omitempty"`
|
||||
// KeySource - The encryption keySource (provider). Possible values (case-insensitive): Microsoft.Storage
|
||||
KeySource *string `json:"keySource,omitempty"`
|
||||
}
|
||||
|
||||
// EncryptionService a service that allows server-side encryption to be used.
|
||||
type EncryptionService struct {
|
||||
// Enabled - A boolean indicating whether or not the service encrypts the data as it is stored.
|
||||
Enabled *bool `json:"enabled,omitempty"`
|
||||
// LastEnabledTime - Gets a rough estimate of the date/time when the encryption was last enabled by the user. Only returned when encryption is enabled. There might be some unencrypted blobs which were written after this time, as it is just a rough estimate.
|
||||
LastEnabledTime *date.Time `json:"lastEnabledTime,omitempty"`
|
||||
}
|
||||
|
||||
// EncryptionServices a list of services that support encryption.
|
||||
type EncryptionServices struct {
|
||||
// Blob - The encryption function of the blob storage service.
|
||||
Blob *EncryptionService `json:"blob,omitempty"`
|
||||
}
|
||||
|
||||
// Endpoints the URIs that are used to perform a retrieval of a public blob, queue, or table object.
|
||||
type Endpoints struct {
|
||||
// Blob - Gets the blob endpoint.
|
||||
Blob *string `json:"blob,omitempty"`
|
||||
// Queue - Gets the queue endpoint.
|
||||
Queue *string `json:"queue,omitempty"`
|
||||
// Table - Gets the table endpoint.
|
||||
Table *string `json:"table,omitempty"`
|
||||
// File - Gets the file endpoint.
|
||||
File *string `json:"file,omitempty"`
|
||||
}
|
||||
|
||||
// Resource ...
|
||||
type Resource struct {
|
||||
// ID - Resource Id
|
||||
ID *string `json:"id,omitempty"`
|
||||
// Name - Resource name
|
||||
Name *string `json:"name,omitempty"`
|
||||
// Type - Resource type
|
||||
Type *string `json:"type,omitempty"`
|
||||
// Location - Resource location
|
||||
Location *string `json:"location,omitempty"`
|
||||
// Tags - Tags assigned to a resource; can be used for viewing and grouping a resource (across resource groups).
|
||||
Tags map[string]*string `json:"tags"`
|
||||
}
|
||||
|
||||
// MarshalJSON is the custom marshaler for Resource.
|
||||
func (r Resource) MarshalJSON() ([]byte, error) {
|
||||
objectMap := make(map[string]interface{})
|
||||
if r.ID != nil {
|
||||
objectMap["id"] = r.ID
|
||||
}
|
||||
if r.Name != nil {
|
||||
objectMap["name"] = r.Name
|
||||
}
|
||||
if r.Type != nil {
|
||||
objectMap["type"] = r.Type
|
||||
}
|
||||
if r.Location != nil {
|
||||
objectMap["location"] = r.Location
|
||||
}
|
||||
if r.Tags != nil {
|
||||
objectMap["tags"] = r.Tags
|
||||
}
|
||||
return json.Marshal(objectMap)
|
||||
}
|
||||
|
||||
// Sku the SKU of the storage account.
|
||||
type Sku struct {
|
||||
// Name - Gets or sets the sku name. Required for account creation; optional for update. Note that in older versions, sku name was called accountType. Possible values include: 'StandardLRS', 'StandardGRS', 'StandardRAGRS', 'StandardZRS', 'PremiumLRS'
|
||||
Name SkuName `json:"name,omitempty"`
|
||||
// Tier - Gets the sku tier. This is based on the SKU name. Possible values include: 'Standard', 'Premium'
|
||||
Tier SkuTier `json:"tier,omitempty"`
|
||||
}
|
||||
|
||||
// Usage describes Storage Resource Usage.
|
||||
type Usage struct {
|
||||
// Unit - Gets the unit of measurement. Possible values include: 'Count', 'Bytes', 'Seconds', 'Percent', 'CountsPerSecond', 'BytesPerSecond'
|
||||
Unit UsageUnit `json:"unit,omitempty"`
|
||||
// CurrentValue - Gets the current count of the allocated resources in the subscription.
|
||||
CurrentValue *int32 `json:"currentValue,omitempty"`
|
||||
// Limit - Gets the maximum count of the resources that can be allocated in the subscription.
|
||||
Limit *int32 `json:"limit,omitempty"`
|
||||
// Name - Gets the name of the type of usage.
|
||||
Name *UsageName `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// UsageListResult the response from the List Usages operation.
|
||||
type UsageListResult struct {
|
||||
autorest.Response `json:"-"`
|
||||
// Value - Gets or sets the list of Storage Resource Usages.
|
||||
Value *[]Usage `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// UsageName the usage names that can be used; currently limited to StorageAccount.
|
||||
type UsageName struct {
|
||||
// Value - Gets a string describing the resource name.
|
||||
Value *string `json:"value,omitempty"`
|
||||
// LocalizedValue - Gets a localized string describing the resource name.
|
||||
LocalizedValue *string `json:"localizedValue,omitempty"`
|
||||
}
|
|
@ -14,19 +14,19 @@ package storage
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator 1.0.1.0
|
||||
// Changes may cause incorrect behavior and will be lost if the code is
|
||||
// regenerated.
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// UsageClient is the the Azure Storage Management API.
|
||||
// UsageClient is the the Storage Management Client.
|
||||
type UsageClient struct {
|
||||
ManagementClient
|
||||
BaseClient
|
||||
}
|
||||
|
||||
// NewUsageClient creates an instance of the UsageClient client.
|
||||
|
@ -39,10 +39,9 @@ func NewUsageClientWithBaseURI(baseURI string, subscriptionID string) UsageClien
|
|||
return UsageClient{NewWithBaseURI(baseURI, subscriptionID)}
|
||||
}
|
||||
|
||||
// List gets the current usage count and the limit for the resources under the
|
||||
// subscription.
|
||||
func (client UsageClient) List() (result UsageListResult, err error) {
|
||||
req, err := client.ListPreparer()
|
||||
// List gets the current usage count and the limit for the resources under the subscription.
|
||||
func (client UsageClient) List(ctx context.Context) (result UsageListResult, err error) {
|
||||
req, err := client.ListPreparer(ctx)
|
||||
if err != nil {
|
||||
err = autorest.NewErrorWithError(err, "storage.UsageClient", "List", nil, "Failure preparing request")
|
||||
return
|
||||
|
@ -64,12 +63,12 @@ func (client UsageClient) List() (result UsageListResult, err error) {
|
|||
}
|
||||
|
||||
// ListPreparer prepares the List request.
|
||||
func (client UsageClient) ListPreparer() (*http.Request, error) {
|
||||
func (client UsageClient) ListPreparer(ctx context.Context) (*http.Request, error) {
|
||||
pathParameters := map[string]interface{}{
|
||||
"subscriptionId": autorest.Encode("path", client.SubscriptionID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-12-01"
|
||||
const APIVersion = "2016-01-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
@ -79,13 +78,14 @@ func (client UsageClient) ListPreparer() (*http.Request, error) {
|
|||
autorest.WithBaseURL(client.BaseURI),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.Storage/usages", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters))
|
||||
return preparer.Prepare(&http.Request{})
|
||||
return preparer.Prepare((&http.Request{}).WithContext(ctx))
|
||||
}
|
||||
|
||||
// ListSender sends the List request. The method will close the
|
||||
// http.Response Body if it receives an error.
|
||||
func (client UsageClient) ListSender(req *http.Request) (*http.Response, error) {
|
||||
return autorest.SendWithSender(client, req)
|
||||
return autorest.SendWithSender(client, req,
|
||||
azure.DoRetryWithRegistration(client.Client))
|
||||
}
|
||||
|
||||
// ListResponder handles the response to the List request. The method always
|
|
@ -1,5 +1,7 @@
|
|||
package storage
|
||||
|
||||
import "github.com/Azure/azure-sdk-for-go/version"
|
||||
|
||||
// Copyright (c) Microsoft and contributors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -14,15 +16,15 @@ package storage
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator 1.2.2.0
|
||||
// Code generated by Microsoft (R) AutoRest Code Generator.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
// UserAgent returns the UserAgent string to use when sending http.Requests.
|
||||
func UserAgent() string {
|
||||
return "Azure-SDK-For-Go/v10.3.0-beta arm-storage/2017-06-01"
|
||||
return "Azure-SDK-For-Go/" + version.Number + " storage/2016-01-01"
|
||||
}
|
||||
|
||||
// Version returns the semantic version (see http://semver.org) of the client.
|
||||
func Version() string {
|
||||
return "v10.3.0-beta"
|
||||
return version.Number
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
# Azure Storage SDK for Go (Preview)
|
||||
|
||||
:exclamation: IMPORTANT: This package is in maintenance only and will be deprecated in the
|
||||
future. Please use one of the following packages instead.
|
||||
|
||||
| Service | Import Path/Repo |
|
||||
|---------|------------------|
|
||||
| Storage - Blobs | [github.com/Azure/azure-storage-blob-go](https://github.com/Azure/azure-storage-blob-go) |
|
||||
| Storage - Files | [github.com/Azure/azure-storage-file-go](https://github.com/Azure/azure-storage-file-go) |
|
||||
| Storage - Queues | [github.com/Azure/azure-storage-queue-go](https://github.com/Azure/azure-storage-queue-go) |
|
||||
|
||||
The `github.com/Azure/azure-sdk-for-go/storage` package is used to manage
|
||||
[Azure Storage](https://docs.microsoft.com/en-us/azure/storage/) data plane
|
||||
resources: containers, blobs, tables, and queues.
|
||||
|
||||
To manage storage *accounts* use Azure Resource Manager (ARM) via the packages
|
||||
at [github.com/Azure/azure-sdk-for-go/services/storage](https://github.com/Azure/azure-sdk-for-go/tree/master/services/storage).
|
||||
|
||||
This package also supports the [Azure Storage
|
||||
Emulator](https://azure.microsoft.com/documentation/articles/storage-use-emulator/)
|
||||
(Windows only).
|
||||
|
|
@ -1,7 +1,23 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
@ -31,8 +47,7 @@ func (b *Blob) PutAppendBlob(options *PutBlobOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
return b.respondCreation(resp, BlobTypeAppend)
|
||||
}
|
||||
|
||||
// AppendBlockOptions includes the options for an append block operation
|
||||
|
@ -46,6 +61,7 @@ type AppendBlockOptions struct {
|
|||
IfMatch string `header:"If-Match"`
|
||||
IfNoneMatch string `header:"If-None-Match"`
|
||||
RequestID string `header:"x-ms-client-request-id"`
|
||||
ContentMD5 bool
|
||||
}
|
||||
|
||||
// AppendBlock appends a block to an append blob.
|
||||
|
@ -60,6 +76,10 @@ func (b *Blob) AppendBlock(chunk []byte, options *AppendBlockOptions) error {
|
|||
if options != nil {
|
||||
params = addTimeout(params, options.Timeout)
|
||||
headers = mergeHeaders(headers, headersFromStruct(*options))
|
||||
if options.ContentMD5 {
|
||||
md5sum := md5.Sum(chunk)
|
||||
headers[headerContentMD5] = base64.StdEncoding.EncodeToString(md5sum[:])
|
||||
}
|
||||
}
|
||||
uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params)
|
||||
|
||||
|
@ -67,6 +87,5 @@ func (b *Blob) AppendBlock(chunk []byte, options *AppendBlockOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
return b.respondCreation(resp, BlobTypeAppend)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
// Package storage provides clients for Microsoft Azure Storage Services.
|
||||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
@ -41,16 +55,18 @@ const (
|
|||
)
|
||||
|
||||
func (c *Client) addAuthorizationHeader(verb, url string, headers map[string]string, auth authentication) (map[string]string, error) {
|
||||
authHeader, err := c.getSharedKey(verb, url, headers, auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if !c.sasClient {
|
||||
authHeader, err := c.getSharedKey(verb, url, headers, auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
headers[headerAuthorization] = authHeader
|
||||
}
|
||||
headers[headerAuthorization] = authHeader
|
||||
return headers, nil
|
||||
}
|
||||
|
||||
func (c *Client) getSharedKey(verb, url string, headers map[string]string, auth authentication) (string, error) {
|
||||
canRes, err := c.buildCanonicalizedResource(url, auth)
|
||||
canRes, err := c.buildCanonicalizedResource(url, auth, false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -62,15 +78,18 @@ func (c *Client) getSharedKey(verb, url string, headers map[string]string, auth
|
|||
return c.createAuthorizationHeader(canString, auth), nil
|
||||
}
|
||||
|
||||
func (c *Client) buildCanonicalizedResource(uri string, auth authentication) (string, error) {
|
||||
func (c *Client) buildCanonicalizedResource(uri string, auth authentication, sas bool) (string, error) {
|
||||
errMsg := "buildCanonicalizedResource error: %s"
|
||||
u, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf(errMsg, err.Error())
|
||||
}
|
||||
|
||||
cr := bytes.NewBufferString("/")
|
||||
cr.WriteString(c.getCanonicalizedAccountName())
|
||||
cr := bytes.NewBufferString("")
|
||||
if c.accountName != StorageEmulatorAccountName || !sas {
|
||||
cr.WriteString("/")
|
||||
cr.WriteString(c.getCanonicalizedAccountName())
|
||||
}
|
||||
|
||||
if len(u.Path) > 0 {
|
||||
// Any portion of the CanonicalizedResource string that is derived from
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
|
@ -90,7 +104,7 @@ type BlobProperties struct {
|
|||
CacheControl string `xml:"Cache-Control" header:"x-ms-blob-cache-control"`
|
||||
ContentLanguage string `xml:"Cache-Language" header:"x-ms-blob-content-language"`
|
||||
ContentDisposition string `xml:"Content-Disposition" header:"x-ms-blob-content-disposition"`
|
||||
BlobType BlobType `xml:"x-ms-blob-blob-type"`
|
||||
BlobType BlobType `xml:"BlobType"`
|
||||
SequenceNumber int64 `xml:"x-ms-blob-sequence-number"`
|
||||
CopyID string `xml:"CopyId"`
|
||||
CopyStatus string `xml:"CopyStatus"`
|
||||
|
@ -126,17 +140,16 @@ func (b *Blob) Exists() (bool, error) {
|
|||
headers := b.Container.bsc.client.getStandardHeaders()
|
||||
resp, err := b.Container.bsc.client.exec(http.MethodHead, uri, headers, nil, b.Container.bsc.auth)
|
||||
if resp != nil {
|
||||
defer readAndCloseBody(resp.body)
|
||||
if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound {
|
||||
return resp.statusCode == http.StatusOK, nil
|
||||
defer drainRespBody(resp)
|
||||
if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNotFound {
|
||||
return resp.StatusCode == http.StatusOK, nil
|
||||
}
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
// GetURL gets the canonical URL to the blob with the specified name in the
|
||||
// specified container. If name is not specified, the canonical URL for the entire
|
||||
// container is obtained.
|
||||
// specified container.
|
||||
// This method does not create a publicly accessible URL if the blob or container
|
||||
// is private and this method does not check if the blob exists.
|
||||
func (b *Blob) GetURL() string {
|
||||
|
@ -195,13 +208,13 @@ func (b *Blob) Get(options *GetBlobOptions) (io.ReadCloser, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
if err := checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := b.writeProperties(resp.headers, true); err != nil {
|
||||
return resp.body, err
|
||||
if err := b.writeProperties(resp.Header, true); err != nil {
|
||||
return resp.Body, err
|
||||
}
|
||||
return resp.body, nil
|
||||
return resp.Body, nil
|
||||
}
|
||||
|
||||
// GetRange reads the specified range of a blob to a stream. The bytesRange
|
||||
|
@ -215,18 +228,18 @@ func (b *Blob) GetRange(options *GetBlobRangeOptions) (io.ReadCloser, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusPartialContent}); err != nil {
|
||||
if err := checkRespCode(resp, []int{http.StatusPartialContent}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Content-Length header should not be updated, as the service returns the range length
|
||||
// (which is not alwys the full blob length)
|
||||
if err := b.writeProperties(resp.headers, false); err != nil {
|
||||
return resp.body, err
|
||||
if err := b.writeProperties(resp.Header, false); err != nil {
|
||||
return resp.Body, err
|
||||
}
|
||||
return resp.body, nil
|
||||
return resp.Body, nil
|
||||
}
|
||||
|
||||
func (b *Blob) getRange(options *GetBlobRangeOptions) (*storageResponse, error) {
|
||||
func (b *Blob) getRange(options *GetBlobRangeOptions) (*http.Response, error) {
|
||||
params := url.Values{}
|
||||
headers := b.Container.bsc.client.getStandardHeaders()
|
||||
|
||||
|
@ -280,13 +293,13 @@ func (b *Blob) CreateSnapshot(options *SnapshotOptions) (snapshotTimestamp *time
|
|||
if err != nil || resp == nil {
|
||||
return nil, err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusCreated}); err != nil {
|
||||
if err := checkRespCode(resp, []int{http.StatusCreated}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
snapshotResponse := resp.headers.Get(http.CanonicalHeaderKey("x-ms-snapshot"))
|
||||
snapshotResponse := resp.Header.Get(http.CanonicalHeaderKey("x-ms-snapshot"))
|
||||
if snapshotResponse != "" {
|
||||
snapshotTimestamp, err := time.Parse(time.RFC3339, snapshotResponse)
|
||||
if err != nil {
|
||||
|
@ -327,12 +340,12 @@ func (b *Blob) GetProperties(options *GetBlobPropertiesOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
if err = checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
return err
|
||||
}
|
||||
return b.writeProperties(resp.headers, true)
|
||||
return b.writeProperties(resp.Header, true)
|
||||
}
|
||||
|
||||
func (b *Blob) writeProperties(h http.Header, includeContentLen bool) error {
|
||||
|
@ -437,8 +450,8 @@ func (b *Blob) SetProperties(options *SetBlobPropertiesOptions) error {
|
|||
uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params)
|
||||
|
||||
if b.Properties.BlobType == BlobTypePage {
|
||||
headers = addToHeaders(headers, "x-ms-blob-content-length", fmt.Sprintf("byte %v", b.Properties.ContentLength))
|
||||
if options != nil || options.SequenceNumberAction != nil {
|
||||
headers = addToHeaders(headers, "x-ms-blob-content-length", fmt.Sprintf("%v", b.Properties.ContentLength))
|
||||
if options != nil && options.SequenceNumberAction != nil {
|
||||
headers = addToHeaders(headers, "x-ms-sequence-number-action", string(*options.SequenceNumberAction))
|
||||
if *options.SequenceNumberAction != SequenceNumberActionIncrement {
|
||||
headers = addToHeaders(headers, "x-ms-blob-sequence-number", fmt.Sprintf("%v", b.Properties.SequenceNumber))
|
||||
|
@ -450,8 +463,8 @@ func (b *Blob) SetProperties(options *SetBlobPropertiesOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusOK})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusOK})
|
||||
}
|
||||
|
||||
// SetBlobMetadataOptions includes the options for a set blob metadata operation
|
||||
|
@ -488,8 +501,8 @@ func (b *Blob) SetMetadata(options *SetBlobMetadataOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusOK})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusOK})
|
||||
}
|
||||
|
||||
// GetBlobMetadataOptions includes the options for a get blob metadata operation
|
||||
|
@ -525,38 +538,18 @@ func (b *Blob) GetMetadata(options *GetBlobMetadataOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
if err := checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b.writeMetadata(resp.headers)
|
||||
b.writeMetadata(resp.Header)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Blob) writeMetadata(h http.Header) {
|
||||
metadata := make(map[string]string)
|
||||
for k, v := range h {
|
||||
// Can't trust CanonicalHeaderKey() to munge case
|
||||
// reliably. "_" is allowed in identifiers:
|
||||
// https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx
|
||||
// https://msdn.microsoft.com/library/aa664670(VS.71).aspx
|
||||
// http://tools.ietf.org/html/rfc7230#section-3.2
|
||||
// ...but "_" is considered invalid by
|
||||
// CanonicalMIMEHeaderKey in
|
||||
// https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542
|
||||
// so k can be "X-Ms-Meta-Lol" or "x-ms-meta-lol_rofl".
|
||||
k = strings.ToLower(k)
|
||||
if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) {
|
||||
continue
|
||||
}
|
||||
// metadata["lol"] = content of the last X-Ms-Meta-Lol header
|
||||
k = k[len(userDefinedMetadataHeaderPrefix):]
|
||||
metadata[k] = v[len(v)-1]
|
||||
}
|
||||
|
||||
b.Metadata = BlobMetadata(metadata)
|
||||
b.Metadata = BlobMetadata(writeMetadata(h))
|
||||
}
|
||||
|
||||
// DeleteBlobOptions includes the options for a delete blob operation
|
||||
|
@ -581,8 +574,8 @@ func (b *Blob) Delete(options *DeleteBlobOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusAccepted})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusAccepted})
|
||||
}
|
||||
|
||||
// DeleteIfExists deletes the given blob from the specified container If the
|
||||
|
@ -592,15 +585,15 @@ func (b *Blob) Delete(options *DeleteBlobOptions) error {
|
|||
func (b *Blob) DeleteIfExists(options *DeleteBlobOptions) (bool, error) {
|
||||
resp, err := b.delete(options)
|
||||
if resp != nil {
|
||||
defer readAndCloseBody(resp.body)
|
||||
if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound {
|
||||
return resp.statusCode == http.StatusAccepted, nil
|
||||
defer drainRespBody(resp)
|
||||
if resp.StatusCode == http.StatusAccepted || resp.StatusCode == http.StatusNotFound {
|
||||
return resp.StatusCode == http.StatusAccepted, nil
|
||||
}
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
func (b *Blob) delete(options *DeleteBlobOptions) (*storageResponse, error) {
|
||||
func (b *Blob) delete(options *DeleteBlobOptions) (*http.Response, error) {
|
||||
params := url.Values{}
|
||||
headers := b.Container.bsc.client.getStandardHeaders()
|
||||
|
||||
|
@ -627,3 +620,13 @@ func pathForResource(container, name string) string {
|
|||
}
|
||||
return fmt.Sprintf("/%s", container)
|
||||
}
|
||||
|
||||
func (b *Blob) respondCreation(resp *http.Response, bt BlobType) error {
|
||||
defer drainRespBody(resp)
|
||||
err := checkRespCode(resp, []int{http.StatusCreated})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
b.Properties.BlobType = bt
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -8,68 +22,126 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
// GetSASURIWithSignedIPAndProtocol creates an URL to the specified blob which contains the Shared
|
||||
// Access Signature with specified permissions and expiration time. Also includes signedIPRange and allowed protocols.
|
||||
// If old API version is used but no signedIP is passed (ie empty string) then this should still work.
|
||||
// We only populate the signedIP when it non-empty.
|
||||
// OverrideHeaders defines overridable response heaedrs in
|
||||
// a request using a SAS URI.
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
type OverrideHeaders struct {
|
||||
CacheControl string
|
||||
ContentDisposition string
|
||||
ContentEncoding string
|
||||
ContentLanguage string
|
||||
ContentType string
|
||||
}
|
||||
|
||||
// BlobSASOptions are options to construct a blob SAS
|
||||
// URI.
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
type BlobSASOptions struct {
|
||||
BlobServiceSASPermissions
|
||||
OverrideHeaders
|
||||
SASOptions
|
||||
}
|
||||
|
||||
// BlobServiceSASPermissions includes the available permissions for
|
||||
// blob service SAS URI.
|
||||
type BlobServiceSASPermissions struct {
|
||||
Read bool
|
||||
Add bool
|
||||
Create bool
|
||||
Write bool
|
||||
Delete bool
|
||||
}
|
||||
|
||||
func (p BlobServiceSASPermissions) buildString() string {
|
||||
permissions := ""
|
||||
if p.Read {
|
||||
permissions += "r"
|
||||
}
|
||||
if p.Add {
|
||||
permissions += "a"
|
||||
}
|
||||
if p.Create {
|
||||
permissions += "c"
|
||||
}
|
||||
if p.Write {
|
||||
permissions += "w"
|
||||
}
|
||||
if p.Delete {
|
||||
permissions += "d"
|
||||
}
|
||||
return permissions
|
||||
}
|
||||
|
||||
// GetSASURI creates an URL to the blob which contains the Shared
|
||||
// Access Signature with the specified options.
|
||||
//
|
||||
// See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx
|
||||
func (b *Blob) GetSASURIWithSignedIPAndProtocol(expiry time.Time, permissions string, signedIPRange string, HTTPSOnly bool) (string, error) {
|
||||
var (
|
||||
signedPermissions = permissions
|
||||
blobURL = b.GetURL()
|
||||
)
|
||||
canonicalizedResource, err := b.Container.bsc.client.buildCanonicalizedResource(blobURL, b.Container.bsc.auth)
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
func (b *Blob) GetSASURI(options BlobSASOptions) (string, error) {
|
||||
uri := b.GetURL()
|
||||
signedResource := "b"
|
||||
canonicalizedResource, err := b.Container.bsc.client.buildCanonicalizedResource(uri, b.Container.bsc.auth, true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// "The canonicalizedresouce portion of the string is a canonical path to the signed resource.
|
||||
// It must include the service name (blob, table, queue or file) for version 2015-02-21 or
|
||||
// later, the storage account name, and the resource name, and must be URL-decoded.
|
||||
// -- https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx
|
||||
permissions := options.BlobServiceSASPermissions.buildString()
|
||||
return b.Container.bsc.client.blobAndFileSASURI(options.SASOptions, uri, permissions, canonicalizedResource, signedResource, options.OverrideHeaders)
|
||||
}
|
||||
|
||||
func (c *Client) blobAndFileSASURI(options SASOptions, uri, permissions, canonicalizedResource, signedResource string, headers OverrideHeaders) (string, error) {
|
||||
start := ""
|
||||
if options.Start != (time.Time{}) {
|
||||
start = options.Start.UTC().Format(time.RFC3339)
|
||||
}
|
||||
|
||||
expiry := options.Expiry.UTC().Format(time.RFC3339)
|
||||
|
||||
// We need to replace + with %2b first to avoid being treated as a space (which is correct for query strings, but not the path component).
|
||||
canonicalizedResource = strings.Replace(canonicalizedResource, "+", "%2b", -1)
|
||||
canonicalizedResource, err = url.QueryUnescape(canonicalizedResource)
|
||||
canonicalizedResource, err := url.QueryUnescape(canonicalizedResource)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
signedExpiry := expiry.UTC().Format(time.RFC3339)
|
||||
|
||||
//If blob name is missing, resource is a container
|
||||
signedResource := "c"
|
||||
if len(b.Name) > 0 {
|
||||
signedResource = "b"
|
||||
}
|
||||
|
||||
protocols := "https,http"
|
||||
if HTTPSOnly {
|
||||
protocols := ""
|
||||
if options.UseHTTPS {
|
||||
protocols = "https"
|
||||
}
|
||||
stringToSign, err := blobSASStringToSign(b.Container.bsc.client.apiVersion, canonicalizedResource, signedExpiry, signedPermissions, signedIPRange, protocols)
|
||||
stringToSign, err := blobSASStringToSign(permissions, start, expiry, canonicalizedResource, options.Identifier, options.IP, protocols, c.apiVersion, headers)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sig := b.Container.bsc.client.computeHmac256(stringToSign)
|
||||
sig := c.computeHmac256(stringToSign)
|
||||
sasParams := url.Values{
|
||||
"sv": {b.Container.bsc.client.apiVersion},
|
||||
"se": {signedExpiry},
|
||||
"sv": {c.apiVersion},
|
||||
"se": {expiry},
|
||||
"sr": {signedResource},
|
||||
"sp": {signedPermissions},
|
||||
"sp": {permissions},
|
||||
"sig": {sig},
|
||||
}
|
||||
|
||||
if b.Container.bsc.client.apiVersion >= "2015-04-05" {
|
||||
sasParams.Add("spr", protocols)
|
||||
if signedIPRange != "" {
|
||||
sasParams.Add("sip", signedIPRange)
|
||||
if start != "" {
|
||||
sasParams.Add("st", start)
|
||||
}
|
||||
|
||||
if c.apiVersion >= "2015-04-05" {
|
||||
if protocols != "" {
|
||||
sasParams.Add("spr", protocols)
|
||||
}
|
||||
if options.IP != "" {
|
||||
sasParams.Add("sip", options.IP)
|
||||
}
|
||||
}
|
||||
|
||||
sasURL, err := url.Parse(blobURL)
|
||||
// Add override response hedaers
|
||||
addQueryParameter(sasParams, "rscc", headers.CacheControl)
|
||||
addQueryParameter(sasParams, "rscd", headers.ContentDisposition)
|
||||
addQueryParameter(sasParams, "rsce", headers.ContentEncoding)
|
||||
addQueryParameter(sasParams, "rscl", headers.ContentLanguage)
|
||||
addQueryParameter(sasParams, "rsct", headers.ContentType)
|
||||
|
||||
sasURL, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -77,16 +149,12 @@ func (b *Blob) GetSASURIWithSignedIPAndProtocol(expiry time.Time, permissions st
|
|||
return sasURL.String(), nil
|
||||
}
|
||||
|
||||
// GetSASURI creates an URL to the specified blob which contains the Shared
|
||||
// Access Signature with specified permissions and expiration time.
|
||||
//
|
||||
// See https://msdn.microsoft.com/en-us/library/azure/ee395415.aspx
|
||||
func (b *Blob) GetSASURI(expiry time.Time, permissions string) (string, error) {
|
||||
return b.GetSASURIWithSignedIPAndProtocol(expiry, permissions, "", false)
|
||||
}
|
||||
|
||||
func blobSASStringToSign(signedVersion, canonicalizedResource, signedExpiry, signedPermissions string, signedIP string, protocols string) (string, error) {
|
||||
var signedStart, signedIdentifier, rscc, rscd, rsce, rscl, rsct string
|
||||
func blobSASStringToSign(signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedIP, protocols, signedVersion string, headers OverrideHeaders) (string, error) {
|
||||
rscc := headers.CacheControl
|
||||
rscd := headers.ContentDisposition
|
||||
rsce := headers.ContentEncoding
|
||||
rscl := headers.ContentLanguage
|
||||
rsct := headers.ContentType
|
||||
|
||||
if signedVersion >= "2015-02-21" {
|
||||
canonicalizedResource = "/blob" + canonicalizedResource
|
||||
|
|
|
@ -1,9 +1,26 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// BlobStorageClient contains operations for Microsoft Azure Blob Storage
|
||||
|
@ -45,6 +62,25 @@ func (b *BlobStorageClient) GetContainerReference(name string) *Container {
|
|||
}
|
||||
}
|
||||
|
||||
// GetContainerReferenceFromSASURI returns a Container object for the specified
|
||||
// container SASURI
|
||||
func GetContainerReferenceFromSASURI(sasuri url.URL) (*Container, error) {
|
||||
path := strings.Split(sasuri.Path, "/")
|
||||
if len(path) <= 1 {
|
||||
return nil, fmt.Errorf("could not find a container in URI: %s", sasuri.String())
|
||||
}
|
||||
c, err := newSASClientFromURL(&sasuri)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cli := c.GetBlobService()
|
||||
return &Container{
|
||||
bsc: &cli,
|
||||
Name: path[1],
|
||||
sasuri: sasuri,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ListContainers returns the list of containers in a storage account along with
|
||||
// pagination token and other response details.
|
||||
//
|
||||
|
@ -54,21 +90,53 @@ func (b BlobStorageClient) ListContainers(params ListContainersParameters) (*Con
|
|||
uri := b.client.getEndpoint(blobServiceName, "", q)
|
||||
headers := b.client.getStandardHeaders()
|
||||
|
||||
var out ContainerListResponse
|
||||
type ContainerAlias struct {
|
||||
bsc *BlobStorageClient
|
||||
Name string `xml:"Name"`
|
||||
Properties ContainerProperties `xml:"Properties"`
|
||||
Metadata BlobMetadata
|
||||
sasuri url.URL
|
||||
}
|
||||
type ContainerListResponseAlias struct {
|
||||
XMLName xml.Name `xml:"EnumerationResults"`
|
||||
Xmlns string `xml:"xmlns,attr"`
|
||||
Prefix string `xml:"Prefix"`
|
||||
Marker string `xml:"Marker"`
|
||||
NextMarker string `xml:"NextMarker"`
|
||||
MaxResults int64 `xml:"MaxResults"`
|
||||
Containers []ContainerAlias `xml:"Containers>Container"`
|
||||
}
|
||||
|
||||
var outAlias ContainerListResponseAlias
|
||||
resp, err := b.client.exec(http.MethodGet, uri, headers, nil, b.auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.body.Close()
|
||||
err = xmlUnmarshal(resp.body, &out)
|
||||
defer resp.Body.Close()
|
||||
err = xmlUnmarshal(resp.Body, &outAlias)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// assign our client to the newly created Container objects
|
||||
for i := range out.Containers {
|
||||
out.Containers[i].bsc = &b
|
||||
out := ContainerListResponse{
|
||||
XMLName: outAlias.XMLName,
|
||||
Xmlns: outAlias.Xmlns,
|
||||
Prefix: outAlias.Prefix,
|
||||
Marker: outAlias.Marker,
|
||||
NextMarker: outAlias.NextMarker,
|
||||
MaxResults: outAlias.MaxResults,
|
||||
Containers: make([]Container, len(outAlias.Containers)),
|
||||
}
|
||||
for i, cnt := range outAlias.Containers {
|
||||
out.Containers[i] = Container{
|
||||
bsc: &b,
|
||||
Name: cnt.Name,
|
||||
Properties: cnt.Properties,
|
||||
Metadata: map[string]string(cnt.Metadata),
|
||||
sasuri: cnt.sasuri,
|
||||
}
|
||||
}
|
||||
|
||||
return &out, err
|
||||
}
|
||||
|
||||
|
@ -93,3 +161,26 @@ func (p ListContainersParameters) getParameters() url.Values {
|
|||
|
||||
return out
|
||||
}
|
||||
|
||||
func writeMetadata(h http.Header) map[string]string {
|
||||
metadata := make(map[string]string)
|
||||
for k, v := range h {
|
||||
// Can't trust CanonicalHeaderKey() to munge case
|
||||
// reliably. "_" is allowed in identifiers:
|
||||
// https://msdn.microsoft.com/en-us/library/azure/dd179414.aspx
|
||||
// https://msdn.microsoft.com/library/aa664670(VS.71).aspx
|
||||
// http://tools.ietf.org/html/rfc7230#section-3.2
|
||||
// ...but "_" is considered invalid by
|
||||
// CanonicalMIMEHeaderKey in
|
||||
// https://golang.org/src/net/textproto/reader.go?s=14615:14659#L542
|
||||
// so k can be "X-Ms-Meta-Lol" or "x-ms-meta-lol_rofl".
|
||||
k = strings.ToLower(k)
|
||||
if len(v) == 0 || !strings.HasPrefix(k, strings.ToLower(userDefinedMetadataHeaderPrefix)) {
|
||||
continue
|
||||
}
|
||||
// metadata["lol"] = content of the last X-Ms-Meta-Lol header
|
||||
k = k[len(userDefinedMetadataHeaderPrefix):]
|
||||
metadata[k] = v[len(v)-1]
|
||||
}
|
||||
return metadata
|
||||
}
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/xml"
|
||||
|
@ -132,8 +146,7 @@ func (b *Blob) CreateBlockBlobFromReader(blob io.Reader, options *PutBlobOptions
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
return b.respondCreation(resp, BlobTypeBlock)
|
||||
}
|
||||
|
||||
// PutBlockOptions includes the options for a put block operation
|
||||
|
@ -181,8 +194,7 @@ func (b *Blob) PutBlockWithLength(blockID string, size uint64, blob io.Reader, o
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
return b.respondCreation(resp, BlobTypeBlock)
|
||||
}
|
||||
|
||||
// PutBlockListOptions includes the options for a put block list operation
|
||||
|
@ -217,8 +229,8 @@ func (b *Blob) PutBlockList(blocks []Block, options *PutBlockListOptions) error
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusCreated})
|
||||
}
|
||||
|
||||
// GetBlockListOptions includes the options for a get block list operation
|
||||
|
@ -251,8 +263,8 @@ func (b *Blob) GetBlockList(blockType BlockListType, options *GetBlockListOption
|
|||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
defer resp.body.Close()
|
||||
defer resp.Body.Close()
|
||||
|
||||
err = xmlUnmarshal(resp.body, &out)
|
||||
err = xmlUnmarshal(resp.Body, &out)
|
||||
return out, err
|
||||
}
|
||||
|
|
|
@ -1,9 +1,22 @@
|
|||
// Package storage provides clients for Microsoft Azure Storage Services.
|
||||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
|
@ -17,9 +30,11 @@ import (
|
|||
"net/url"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/version"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/azure"
|
||||
)
|
||||
|
@ -33,7 +48,9 @@ const (
|
|||
// basic client is created.
|
||||
DefaultAPIVersion = "2016-05-31"
|
||||
|
||||
defaultUseHTTPS = true
|
||||
defaultUseHTTPS = true
|
||||
defaultRetryAttempts = 5
|
||||
defaultRetryDuration = time.Second * 5
|
||||
|
||||
// StorageEmulatorAccountName is the fixed storage account used by Azure Storage Emulator
|
||||
StorageEmulatorAccountName = "devstoreaccount1"
|
||||
|
@ -53,10 +70,28 @@ const (
|
|||
userAgentHeader = "User-Agent"
|
||||
|
||||
userDefinedMetadataHeaderPrefix = "x-ms-meta-"
|
||||
|
||||
connectionStringAccountName = "accountname"
|
||||
connectionStringAccountKey = "accountkey"
|
||||
connectionStringEndpointSuffix = "endpointsuffix"
|
||||
connectionStringEndpointProtocol = "defaultendpointsprotocol"
|
||||
|
||||
connectionStringBlobEndpoint = "blobendpoint"
|
||||
connectionStringFileEndpoint = "fileendpoint"
|
||||
connectionStringQueueEndpoint = "queueendpoint"
|
||||
connectionStringTableEndpoint = "tableendpoint"
|
||||
connectionStringSAS = "sharedaccesssignature"
|
||||
)
|
||||
|
||||
var (
|
||||
validStorageAccount = regexp.MustCompile("^[0-9a-z]{3,24}$")
|
||||
validStorageAccount = regexp.MustCompile("^[0-9a-z]{3,24}$")
|
||||
defaultValidStatusCodes = []int{
|
||||
http.StatusRequestTimeout, // 408
|
||||
http.StatusInternalServerError, // 500
|
||||
http.StatusBadGateway, // 502
|
||||
http.StatusServiceUnavailable, // 503
|
||||
http.StatusGatewayTimeout, // 504
|
||||
}
|
||||
)
|
||||
|
||||
// Sender sends a request
|
||||
|
@ -85,6 +120,7 @@ func (ds *DefaultSender) Send(c *Client, req *http.Request) (resp *http.Response
|
|||
if err != nil || !autorest.ResponseHasStatusCode(resp, ds.ValidStatusCodes...) {
|
||||
return resp, err
|
||||
}
|
||||
drainRespBody(resp)
|
||||
autorest.DelayForBackoff(ds.RetryDuration, attempts, req.Cancel)
|
||||
ds.attempts = attempts
|
||||
}
|
||||
|
@ -112,16 +148,12 @@ type Client struct {
|
|||
baseURL string
|
||||
apiVersion string
|
||||
userAgent string
|
||||
}
|
||||
|
||||
type storageResponse struct {
|
||||
statusCode int
|
||||
headers http.Header
|
||||
body io.ReadCloser
|
||||
sasClient bool
|
||||
accountSASToken url.Values
|
||||
}
|
||||
|
||||
type odataResponse struct {
|
||||
storageResponse
|
||||
resp *http.Response
|
||||
odata odataErrorWrapper
|
||||
}
|
||||
|
||||
|
@ -161,6 +193,7 @@ type odataErrorWrapper struct {
|
|||
type UnexpectedStatusCodeError struct {
|
||||
allowed []int
|
||||
got int
|
||||
inner error
|
||||
}
|
||||
|
||||
func (e UnexpectedStatusCodeError) Error() string {
|
||||
|
@ -171,7 +204,7 @@ func (e UnexpectedStatusCodeError) Error() string {
|
|||
for _, v := range e.allowed {
|
||||
expected = append(expected, s(v))
|
||||
}
|
||||
return fmt.Sprintf("storage: status code from service response is %s; was expecting %s", got, strings.Join(expected, " or "))
|
||||
return fmt.Sprintf("storage: status code from service response is %s; was expecting %s. Inner error: %+v", got, strings.Join(expected, " or "), e.inner)
|
||||
}
|
||||
|
||||
// Got is the actual status code returned by Azure.
|
||||
|
@ -179,6 +212,60 @@ func (e UnexpectedStatusCodeError) Got() int {
|
|||
return e.got
|
||||
}
|
||||
|
||||
// Inner returns any inner error info.
|
||||
func (e UnexpectedStatusCodeError) Inner() error {
|
||||
return e.inner
|
||||
}
|
||||
|
||||
// NewClientFromConnectionString creates a Client from the connection string.
|
||||
func NewClientFromConnectionString(input string) (Client, error) {
|
||||
// build a map of connection string key/value pairs
|
||||
parts := map[string]string{}
|
||||
for _, pair := range strings.Split(input, ";") {
|
||||
if pair == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
equalDex := strings.IndexByte(pair, '=')
|
||||
if equalDex <= 0 {
|
||||
return Client{}, fmt.Errorf("Invalid connection segment %q", pair)
|
||||
}
|
||||
|
||||
value := strings.TrimSpace(pair[equalDex+1:])
|
||||
key := strings.TrimSpace(strings.ToLower(pair[:equalDex]))
|
||||
parts[key] = value
|
||||
}
|
||||
|
||||
// TODO: validate parameter sets?
|
||||
|
||||
if parts[connectionStringAccountName] == StorageEmulatorAccountName {
|
||||
return NewEmulatorClient()
|
||||
}
|
||||
|
||||
if parts[connectionStringSAS] != "" {
|
||||
endpoint := ""
|
||||
if parts[connectionStringBlobEndpoint] != "" {
|
||||
endpoint = parts[connectionStringBlobEndpoint]
|
||||
} else if parts[connectionStringFileEndpoint] != "" {
|
||||
endpoint = parts[connectionStringFileEndpoint]
|
||||
} else if parts[connectionStringQueueEndpoint] != "" {
|
||||
endpoint = parts[connectionStringQueueEndpoint]
|
||||
} else {
|
||||
endpoint = parts[connectionStringTableEndpoint]
|
||||
}
|
||||
|
||||
return NewAccountSASClientFromEndpointToken(endpoint, parts[connectionStringSAS])
|
||||
}
|
||||
|
||||
useHTTPS := defaultUseHTTPS
|
||||
if parts[connectionStringEndpointProtocol] != "" {
|
||||
useHTTPS = parts[connectionStringEndpointProtocol] == "https"
|
||||
}
|
||||
|
||||
return NewClient(parts[connectionStringAccountName], parts[connectionStringAccountKey],
|
||||
parts[connectionStringEndpointSuffix], DefaultAPIVersion, useHTTPS)
|
||||
}
|
||||
|
||||
// NewBasicClient constructs a Client with given storage service name and
|
||||
// key.
|
||||
func NewBasicClient(accountName, accountKey string) (Client, error) {
|
||||
|
@ -206,13 +293,13 @@ func NewEmulatorClient() (Client, error) {
|
|||
// NewClient constructs a Client. This should be used if the caller wants
|
||||
// to specify whether to use HTTPS, a specific REST API version or a custom
|
||||
// storage endpoint than Azure Public Cloud.
|
||||
func NewClient(accountName, accountKey, blobServiceBaseURL, apiVersion string, useHTTPS bool) (Client, error) {
|
||||
func NewClient(accountName, accountKey, serviceBaseURL, apiVersion string, useHTTPS bool) (Client, error) {
|
||||
var c Client
|
||||
if !IsValidStorageAccount(accountName) {
|
||||
return c, fmt.Errorf("azure: account name is not valid: it must be between 3 and 24 characters, and only may contain numbers and lowercase letters: %v", accountName)
|
||||
} else if accountKey == "" {
|
||||
return c, fmt.Errorf("azure: account key required")
|
||||
} else if blobServiceBaseURL == "" {
|
||||
} else if serviceBaseURL == "" {
|
||||
return c, fmt.Errorf("azure: base storage service url required")
|
||||
}
|
||||
|
||||
|
@ -226,19 +313,14 @@ func NewClient(accountName, accountKey, blobServiceBaseURL, apiVersion string, u
|
|||
accountName: accountName,
|
||||
accountKey: key,
|
||||
useHTTPS: useHTTPS,
|
||||
baseURL: blobServiceBaseURL,
|
||||
baseURL: serviceBaseURL,
|
||||
apiVersion: apiVersion,
|
||||
sasClient: false,
|
||||
UseSharedKeyLite: false,
|
||||
Sender: &DefaultSender{
|
||||
RetryAttempts: 5,
|
||||
ValidStatusCodes: []int{
|
||||
http.StatusRequestTimeout, // 408
|
||||
http.StatusInternalServerError, // 500
|
||||
http.StatusBadGateway, // 502
|
||||
http.StatusServiceUnavailable, // 503
|
||||
http.StatusGatewayTimeout, // 504
|
||||
},
|
||||
RetryDuration: time.Second * 5,
|
||||
RetryAttempts: defaultRetryAttempts,
|
||||
ValidStatusCodes: defaultValidStatusCodes,
|
||||
RetryDuration: defaultRetryDuration,
|
||||
},
|
||||
}
|
||||
c.userAgent = c.getDefaultUserAgent()
|
||||
|
@ -251,12 +333,89 @@ func IsValidStorageAccount(account string) bool {
|
|||
return validStorageAccount.MatchString(account)
|
||||
}
|
||||
|
||||
// NewAccountSASClient contructs a client that uses accountSAS authorization
|
||||
// for its operations.
|
||||
func NewAccountSASClient(account string, token url.Values, env azure.Environment) Client {
|
||||
return newSASClient(account, env.StorageEndpointSuffix, token)
|
||||
}
|
||||
|
||||
// NewAccountSASClientFromEndpointToken constructs a client that uses accountSAS authorization
|
||||
// for its operations using the specified endpoint and SAS token.
|
||||
func NewAccountSASClientFromEndpointToken(endpoint string, sasToken string) (Client, error) {
|
||||
u, err := url.Parse(endpoint)
|
||||
if err != nil {
|
||||
return Client{}, err
|
||||
}
|
||||
_, err = url.ParseQuery(sasToken)
|
||||
if err != nil {
|
||||
return Client{}, err
|
||||
}
|
||||
u.RawQuery = sasToken
|
||||
return newSASClientFromURL(u)
|
||||
}
|
||||
|
||||
func newSASClient(accountName, baseURL string, sasToken url.Values) Client {
|
||||
c := Client{
|
||||
HTTPClient: http.DefaultClient,
|
||||
apiVersion: DefaultAPIVersion,
|
||||
sasClient: true,
|
||||
Sender: &DefaultSender{
|
||||
RetryAttempts: defaultRetryAttempts,
|
||||
ValidStatusCodes: defaultValidStatusCodes,
|
||||
RetryDuration: defaultRetryDuration,
|
||||
},
|
||||
accountName: accountName,
|
||||
baseURL: baseURL,
|
||||
accountSASToken: sasToken,
|
||||
}
|
||||
c.userAgent = c.getDefaultUserAgent()
|
||||
// Get API version and protocol from token
|
||||
c.apiVersion = sasToken.Get("sv")
|
||||
c.useHTTPS = sasToken.Get("spr") == "https"
|
||||
return c
|
||||
}
|
||||
|
||||
func newSASClientFromURL(u *url.URL) (Client, error) {
|
||||
// the host name will look something like this
|
||||
// - foo.blob.core.windows.net
|
||||
// "foo" is the account name
|
||||
// "core.windows.net" is the baseURL
|
||||
|
||||
// find the first dot to get account name
|
||||
i1 := strings.IndexByte(u.Host, '.')
|
||||
if i1 < 0 {
|
||||
return Client{}, fmt.Errorf("failed to find '.' in %s", u.Host)
|
||||
}
|
||||
|
||||
// now find the second dot to get the base URL
|
||||
i2 := strings.IndexByte(u.Host[i1+1:], '.')
|
||||
if i2 < 0 {
|
||||
return Client{}, fmt.Errorf("failed to find '.' in %s", u.Host[i1+1:])
|
||||
}
|
||||
|
||||
sasToken := u.Query()
|
||||
c := newSASClient(u.Host[:i1], u.Host[i1+i2+2:], sasToken)
|
||||
if spr := sasToken.Get("spr"); spr == "" {
|
||||
// infer from URL if not in the query params set
|
||||
c.useHTTPS = u.Scheme == "https"
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (c Client) isServiceSASClient() bool {
|
||||
return c.sasClient && c.accountSASToken == nil
|
||||
}
|
||||
|
||||
func (c Client) isAccountSASClient() bool {
|
||||
return c.sasClient && c.accountSASToken != nil
|
||||
}
|
||||
|
||||
func (c Client) getDefaultUserAgent() string {
|
||||
return fmt.Sprintf("Go/%s (%s-%s) azure-storage-go/%s api-version/%s",
|
||||
runtime.Version(),
|
||||
runtime.GOARCH,
|
||||
runtime.GOOS,
|
||||
sdkVersion,
|
||||
version.Number,
|
||||
c.apiVersion,
|
||||
)
|
||||
}
|
||||
|
@ -323,6 +482,160 @@ func (c Client) getEndpoint(service, path string, params url.Values) string {
|
|||
return u.String()
|
||||
}
|
||||
|
||||
// AccountSASTokenOptions includes options for constructing
|
||||
// an account SAS token.
|
||||
// https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas
|
||||
type AccountSASTokenOptions struct {
|
||||
APIVersion string
|
||||
Services Services
|
||||
ResourceTypes ResourceTypes
|
||||
Permissions Permissions
|
||||
Start time.Time
|
||||
Expiry time.Time
|
||||
IP string
|
||||
UseHTTPS bool
|
||||
}
|
||||
|
||||
// Services specify services accessible with an account SAS.
|
||||
type Services struct {
|
||||
Blob bool
|
||||
Queue bool
|
||||
Table bool
|
||||
File bool
|
||||
}
|
||||
|
||||
// ResourceTypes specify the resources accesible with an
|
||||
// account SAS.
|
||||
type ResourceTypes struct {
|
||||
Service bool
|
||||
Container bool
|
||||
Object bool
|
||||
}
|
||||
|
||||
// Permissions specifies permissions for an accountSAS.
|
||||
type Permissions struct {
|
||||
Read bool
|
||||
Write bool
|
||||
Delete bool
|
||||
List bool
|
||||
Add bool
|
||||
Create bool
|
||||
Update bool
|
||||
Process bool
|
||||
}
|
||||
|
||||
// GetAccountSASToken creates an account SAS token
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-an-account-sas
|
||||
func (c Client) GetAccountSASToken(options AccountSASTokenOptions) (url.Values, error) {
|
||||
if options.APIVersion == "" {
|
||||
options.APIVersion = c.apiVersion
|
||||
}
|
||||
|
||||
if options.APIVersion < "2015-04-05" {
|
||||
return url.Values{}, fmt.Errorf("account SAS does not support API versions prior to 2015-04-05. API version : %s", options.APIVersion)
|
||||
}
|
||||
|
||||
// build services string
|
||||
services := ""
|
||||
if options.Services.Blob {
|
||||
services += "b"
|
||||
}
|
||||
if options.Services.Queue {
|
||||
services += "q"
|
||||
}
|
||||
if options.Services.Table {
|
||||
services += "t"
|
||||
}
|
||||
if options.Services.File {
|
||||
services += "f"
|
||||
}
|
||||
|
||||
// build resources string
|
||||
resources := ""
|
||||
if options.ResourceTypes.Service {
|
||||
resources += "s"
|
||||
}
|
||||
if options.ResourceTypes.Container {
|
||||
resources += "c"
|
||||
}
|
||||
if options.ResourceTypes.Object {
|
||||
resources += "o"
|
||||
}
|
||||
|
||||
// build permissions string
|
||||
permissions := ""
|
||||
if options.Permissions.Read {
|
||||
permissions += "r"
|
||||
}
|
||||
if options.Permissions.Write {
|
||||
permissions += "w"
|
||||
}
|
||||
if options.Permissions.Delete {
|
||||
permissions += "d"
|
||||
}
|
||||
if options.Permissions.List {
|
||||
permissions += "l"
|
||||
}
|
||||
if options.Permissions.Add {
|
||||
permissions += "a"
|
||||
}
|
||||
if options.Permissions.Create {
|
||||
permissions += "c"
|
||||
}
|
||||
if options.Permissions.Update {
|
||||
permissions += "u"
|
||||
}
|
||||
if options.Permissions.Process {
|
||||
permissions += "p"
|
||||
}
|
||||
|
||||
// build start time, if exists
|
||||
start := ""
|
||||
if options.Start != (time.Time{}) {
|
||||
start = options.Start.UTC().Format(time.RFC3339)
|
||||
}
|
||||
|
||||
// build expiry time
|
||||
expiry := options.Expiry.UTC().Format(time.RFC3339)
|
||||
|
||||
protocol := "https,http"
|
||||
if options.UseHTTPS {
|
||||
protocol = "https"
|
||||
}
|
||||
|
||||
stringToSign := strings.Join([]string{
|
||||
c.accountName,
|
||||
permissions,
|
||||
services,
|
||||
resources,
|
||||
start,
|
||||
expiry,
|
||||
options.IP,
|
||||
protocol,
|
||||
options.APIVersion,
|
||||
"",
|
||||
}, "\n")
|
||||
signature := c.computeHmac256(stringToSign)
|
||||
|
||||
sasParams := url.Values{
|
||||
"sv": {options.APIVersion},
|
||||
"ss": {services},
|
||||
"srt": {resources},
|
||||
"sp": {permissions},
|
||||
"se": {expiry},
|
||||
"spr": {protocol},
|
||||
"sig": {signature},
|
||||
}
|
||||
if start != "" {
|
||||
sasParams.Add("st", start)
|
||||
}
|
||||
if options.IP != "" {
|
||||
sasParams.Add("sip", options.IP)
|
||||
}
|
||||
|
||||
return sasParams, nil
|
||||
}
|
||||
|
||||
// GetBlobService returns a BlobStorageClient which can operate on the blob
|
||||
// service of the storage account.
|
||||
func (c Client) GetBlobService() BlobStorageClient {
|
||||
|
@ -387,7 +700,7 @@ func (c Client) getStandardHeaders() map[string]string {
|
|||
}
|
||||
}
|
||||
|
||||
func (c Client) exec(verb, url string, headers map[string]string, body io.Reader, auth authentication) (*storageResponse, error) {
|
||||
func (c Client) exec(verb, url string, headers map[string]string, body io.Reader, auth authentication) (*http.Response, error) {
|
||||
headers, err := c.addAuthorizationHeader(verb, url, headers, auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -398,12 +711,13 @@ func (c Client) exec(verb, url string, headers map[string]string, body io.Reader
|
|||
return nil, errors.New("azure/storage: error creating request: " + err.Error())
|
||||
}
|
||||
|
||||
// if a body was provided ensure that the content length was set.
|
||||
// http.NewRequest() will automatically do this for a handful of types
|
||||
// and for those that it doesn't we will handle here.
|
||||
if body != nil && req.ContentLength < 1 {
|
||||
if lr, ok := body.(*io.LimitedReader); ok {
|
||||
setContentLengthFromLimitedReader(req, lr)
|
||||
// http.NewRequest() will automatically set req.ContentLength for a handful of types
|
||||
// otherwise we will handle here.
|
||||
if req.ContentLength < 1 {
|
||||
if clstr, ok := headers["Content-Length"]; ok {
|
||||
if cl, err := strconv.ParseInt(clstr, 10, 64); err == nil {
|
||||
req.ContentLength = cl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -411,54 +725,23 @@ func (c Client) exec(verb, url string, headers map[string]string, body io.Reader
|
|||
req.Header[k] = append(req.Header[k], v) // Must bypass case munging present in `Add` by using map functions directly. See https://github.com/Azure/azure-sdk-for-go/issues/645
|
||||
}
|
||||
|
||||
if c.isAccountSASClient() {
|
||||
// append the SAS token to the query params
|
||||
v := req.URL.Query()
|
||||
v = mergeParams(v, c.accountSASToken)
|
||||
req.URL.RawQuery = v.Encode()
|
||||
}
|
||||
|
||||
resp, err := c.Sender.Send(&c, req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode >= 400 && resp.StatusCode <= 505 {
|
||||
var respBody []byte
|
||||
respBody, err = readAndCloseBody(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
requestID, date, version := getDebugHeaders(resp.Header)
|
||||
if len(respBody) == 0 {
|
||||
// no error in response body, might happen in HEAD requests
|
||||
err = serviceErrFromStatusCode(resp.StatusCode, resp.Status, requestID, date, version)
|
||||
} else {
|
||||
storageErr := AzureStorageServiceError{
|
||||
StatusCode: resp.StatusCode,
|
||||
RequestID: requestID,
|
||||
Date: date,
|
||||
APIVersion: version,
|
||||
}
|
||||
// response contains storage service error object, unmarshal
|
||||
if resp.Header.Get("Content-Type") == "application/xml" {
|
||||
errIn := serviceErrFromXML(respBody, &storageErr)
|
||||
if err != nil { // error unmarshaling the error response
|
||||
err = errIn
|
||||
}
|
||||
} else {
|
||||
errIn := serviceErrFromJSON(respBody, &storageErr)
|
||||
if err != nil { // error unmarshaling the error response
|
||||
err = errIn
|
||||
}
|
||||
}
|
||||
err = storageErr
|
||||
}
|
||||
return &storageResponse{
|
||||
statusCode: resp.StatusCode,
|
||||
headers: resp.Header,
|
||||
body: ioutil.NopCloser(bytes.NewReader(respBody)), /* restore the body */
|
||||
}, err
|
||||
return resp, getErrorFromResponse(resp)
|
||||
}
|
||||
|
||||
return &storageResponse{
|
||||
statusCode: resp.StatusCode,
|
||||
headers: resp.Header,
|
||||
body: resp.Body}, nil
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
func (c Client) execInternalJSONCommon(verb, url string, headers map[string]string, body io.Reader, auth authentication) (*odataResponse, *http.Request, *http.Response, error) {
|
||||
|
@ -477,10 +760,7 @@ func (c Client) execInternalJSONCommon(verb, url string, headers map[string]stri
|
|||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
respToRet := &odataResponse{}
|
||||
respToRet.body = resp.Body
|
||||
respToRet.statusCode = resp.StatusCode
|
||||
respToRet.headers = resp.Header
|
||||
respToRet := &odataResponse{resp: resp}
|
||||
|
||||
statusCode := resp.StatusCode
|
||||
if statusCode >= 400 && statusCode <= 505 {
|
||||
|
@ -565,7 +845,7 @@ func genChangesetReader(req *http.Request, respToRet *odataResponse, batchPartBu
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
respToRet.statusCode = changesetResp.StatusCode
|
||||
respToRet.resp = changesetResp
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -600,6 +880,12 @@ func readAndCloseBody(body io.ReadCloser) ([]byte, error) {
|
|||
return out, err
|
||||
}
|
||||
|
||||
// reads the response body then closes it
|
||||
func drainRespBody(resp *http.Response) {
|
||||
io.Copy(ioutil.Discard, resp.Body)
|
||||
resp.Body.Close()
|
||||
}
|
||||
|
||||
func serviceErrFromXML(body []byte, storageErr *AzureStorageServiceError) error {
|
||||
if err := xml.Unmarshal(body, storageErr); err != nil {
|
||||
storageErr.Message = fmt.Sprintf("Response body could no be unmarshaled: %v. Body: %v.", err, string(body))
|
||||
|
@ -638,13 +924,18 @@ func (e AzureStorageServiceError) Error() string {
|
|||
|
||||
// checkRespCode returns UnexpectedStatusError if the given response code is not
|
||||
// one of the allowed status codes; otherwise nil.
|
||||
func checkRespCode(respCode int, allowed []int) error {
|
||||
func checkRespCode(resp *http.Response, allowed []int) error {
|
||||
for _, v := range allowed {
|
||||
if respCode == v {
|
||||
if resp.StatusCode == v {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return UnexpectedStatusCodeError{allowed, respCode}
|
||||
err := getErrorFromResponse(resp)
|
||||
return UnexpectedStatusCodeError{
|
||||
allowed: allowed,
|
||||
got: resp.StatusCode,
|
||||
inner: err,
|
||||
}
|
||||
}
|
||||
|
||||
func (c Client) addMetadataToHeaders(h map[string]string, metadata map[string]string) map[string]string {
|
||||
|
@ -661,3 +952,37 @@ func getDebugHeaders(h http.Header) (requestID, date, version string) {
|
|||
date = h.Get("Date")
|
||||
return
|
||||
}
|
||||
|
||||
func getErrorFromResponse(resp *http.Response) error {
|
||||
respBody, err := readAndCloseBody(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
requestID, date, version := getDebugHeaders(resp.Header)
|
||||
if len(respBody) == 0 {
|
||||
// no error in response body, might happen in HEAD requests
|
||||
err = serviceErrFromStatusCode(resp.StatusCode, resp.Status, requestID, date, version)
|
||||
} else {
|
||||
storageErr := AzureStorageServiceError{
|
||||
StatusCode: resp.StatusCode,
|
||||
RequestID: requestID,
|
||||
Date: date,
|
||||
APIVersion: version,
|
||||
}
|
||||
// response contains storage service error object, unmarshal
|
||||
if resp.Header.Get("Content-Type") == "application/xml" {
|
||||
errIn := serviceErrFromXML(respBody, &storageErr)
|
||||
if err != nil { // error unmarshaling the error response
|
||||
err = errIn
|
||||
}
|
||||
} else {
|
||||
errIn := serviceErrFromJSON(respBody, &storageErr)
|
||||
if err != nil { // error unmarshaling the error response
|
||||
err = errIn
|
||||
}
|
||||
}
|
||||
err = storageErr
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SASOptions includes options used by SAS URIs for different
|
||||
// services and resources.
|
||||
type SASOptions struct {
|
||||
APIVersion string
|
||||
Start time.Time
|
||||
Expiry time.Time
|
||||
IP string
|
||||
UseHTTPS bool
|
||||
Identifier string
|
||||
}
|
||||
|
||||
func addQueryParameter(query url.Values, key, value string) url.Values {
|
||||
if value != "" {
|
||||
query.Add(key, value)
|
||||
}
|
||||
return query
|
||||
}
|
|
@ -1,8 +1,21 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
@ -18,20 +31,75 @@ type Container struct {
|
|||
Name string `xml:"Name"`
|
||||
Properties ContainerProperties `xml:"Properties"`
|
||||
Metadata map[string]string
|
||||
sasuri url.URL
|
||||
}
|
||||
|
||||
// Client returns the HTTP client used by the Container reference.
|
||||
func (c *Container) Client() *Client {
|
||||
return &c.bsc.client
|
||||
}
|
||||
|
||||
func (c *Container) buildPath() string {
|
||||
return fmt.Sprintf("/%s", c.Name)
|
||||
}
|
||||
|
||||
// GetURL gets the canonical URL to the container.
|
||||
// This method does not create a publicly accessible URL if the container
|
||||
// is private and this method does not check if the blob exists.
|
||||
func (c *Container) GetURL() string {
|
||||
container := c.Name
|
||||
if container == "" {
|
||||
container = "$root"
|
||||
}
|
||||
return c.bsc.client.getEndpoint(blobServiceName, pathForResource(container, ""), nil)
|
||||
}
|
||||
|
||||
// ContainerSASOptions are options to construct a container SAS
|
||||
// URI.
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
type ContainerSASOptions struct {
|
||||
ContainerSASPermissions
|
||||
OverrideHeaders
|
||||
SASOptions
|
||||
}
|
||||
|
||||
// ContainerSASPermissions includes the available permissions for
|
||||
// a container SAS URI.
|
||||
type ContainerSASPermissions struct {
|
||||
BlobServiceSASPermissions
|
||||
List bool
|
||||
}
|
||||
|
||||
// GetSASURI creates an URL to the container which contains the Shared
|
||||
// Access Signature with the specified options.
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
func (c *Container) GetSASURI(options ContainerSASOptions) (string, error) {
|
||||
uri := c.GetURL()
|
||||
signedResource := "c"
|
||||
canonicalizedResource, err := c.bsc.client.buildCanonicalizedResource(uri, c.bsc.auth, true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// build permissions string
|
||||
permissions := options.BlobServiceSASPermissions.buildString()
|
||||
if options.List {
|
||||
permissions += "l"
|
||||
}
|
||||
|
||||
return c.bsc.client.blobAndFileSASURI(options.SASOptions, uri, permissions, canonicalizedResource, signedResource, options.OverrideHeaders)
|
||||
}
|
||||
|
||||
// ContainerProperties contains various properties of a container returned from
|
||||
// various endpoints like ListContainers.
|
||||
type ContainerProperties struct {
|
||||
LastModified string `xml:"Last-Modified"`
|
||||
Etag string `xml:"Etag"`
|
||||
LeaseStatus string `xml:"LeaseStatus"`
|
||||
LeaseState string `xml:"LeaseState"`
|
||||
LeaseDuration string `xml:"LeaseDuration"`
|
||||
LastModified string `xml:"Last-Modified"`
|
||||
Etag string `xml:"Etag"`
|
||||
LeaseStatus string `xml:"LeaseStatus"`
|
||||
LeaseState string `xml:"LeaseState"`
|
||||
LeaseDuration string `xml:"LeaseDuration"`
|
||||
PublicAccess ContainerAccessType `xml:"PublicAccess"`
|
||||
}
|
||||
|
||||
// ContainerListResponse contains the response fields from
|
||||
|
@ -190,8 +258,8 @@ func (c *Container) Create(options *CreateContainerOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusCreated})
|
||||
}
|
||||
|
||||
// CreateIfNotExists creates a blob container if it does not exist. Returns
|
||||
|
@ -199,15 +267,15 @@ func (c *Container) Create(options *CreateContainerOptions) error {
|
|||
func (c *Container) CreateIfNotExists(options *CreateContainerOptions) (bool, error) {
|
||||
resp, err := c.create(options)
|
||||
if resp != nil {
|
||||
defer readAndCloseBody(resp.body)
|
||||
if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict {
|
||||
return resp.statusCode == http.StatusCreated, nil
|
||||
defer drainRespBody(resp)
|
||||
if resp.StatusCode == http.StatusCreated || resp.StatusCode == http.StatusConflict {
|
||||
return resp.StatusCode == http.StatusCreated, nil
|
||||
}
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
func (c *Container) create(options *CreateContainerOptions) (*storageResponse, error) {
|
||||
func (c *Container) create(options *CreateContainerOptions) (*http.Response, error) {
|
||||
query := url.Values{"restype": {"container"}}
|
||||
headers := c.bsc.client.getStandardHeaders()
|
||||
headers = c.bsc.client.addMetadataToHeaders(headers, c.Metadata)
|
||||
|
@ -224,14 +292,24 @@ func (c *Container) create(options *CreateContainerOptions) (*storageResponse, e
|
|||
// Exists returns true if a container with given name exists
|
||||
// on the storage account, otherwise returns false.
|
||||
func (c *Container) Exists() (bool, error) {
|
||||
uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), url.Values{"restype": {"container"}})
|
||||
q := url.Values{"restype": {"container"}}
|
||||
var uri string
|
||||
if c.bsc.client.isServiceSASClient() {
|
||||
q = mergeParams(q, c.sasuri.Query())
|
||||
newURI := c.sasuri
|
||||
newURI.RawQuery = q.Encode()
|
||||
uri = newURI.String()
|
||||
|
||||
} else {
|
||||
uri = c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), q)
|
||||
}
|
||||
headers := c.bsc.client.getStandardHeaders()
|
||||
|
||||
resp, err := c.bsc.client.exec(http.MethodHead, uri, headers, nil, c.bsc.auth)
|
||||
if resp != nil {
|
||||
defer readAndCloseBody(resp.body)
|
||||
if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound {
|
||||
return resp.statusCode == http.StatusOK, nil
|
||||
defer drainRespBody(resp)
|
||||
if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNotFound {
|
||||
return resp.StatusCode == http.StatusOK, nil
|
||||
}
|
||||
}
|
||||
return false, err
|
||||
|
@ -271,13 +349,8 @@ func (c *Container) SetPermissions(permissions ContainerPermissions, options *Se
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
return errors.New("Unable to set permissions")
|
||||
}
|
||||
|
||||
return nil
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusOK})
|
||||
}
|
||||
|
||||
// GetContainerPermissionOptions includes options for a get container permissions operation
|
||||
|
@ -307,14 +380,14 @@ func (c *Container) GetPermissions(options *GetContainerPermissionOptions) (*Con
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.body.Close()
|
||||
defer resp.Body.Close()
|
||||
|
||||
var ap AccessPolicy
|
||||
err = xmlUnmarshal(resp.body, &ap.SignedIdentifiersList)
|
||||
err = xmlUnmarshal(resp.Body, &ap.SignedIdentifiersList)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buildAccessPolicy(ap, &resp.headers), nil
|
||||
return buildAccessPolicy(ap, &resp.Header), nil
|
||||
}
|
||||
|
||||
func buildAccessPolicy(ap AccessPolicy, headers *http.Header) *ContainerPermissions {
|
||||
|
@ -358,8 +431,8 @@ func (c *Container) Delete(options *DeleteContainerOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusAccepted})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusAccepted})
|
||||
}
|
||||
|
||||
// DeleteIfExists deletes the container with given name on the storage
|
||||
|
@ -371,15 +444,15 @@ func (c *Container) Delete(options *DeleteContainerOptions) error {
|
|||
func (c *Container) DeleteIfExists(options *DeleteContainerOptions) (bool, error) {
|
||||
resp, err := c.delete(options)
|
||||
if resp != nil {
|
||||
defer readAndCloseBody(resp.body)
|
||||
if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound {
|
||||
return resp.statusCode == http.StatusAccepted, nil
|
||||
defer drainRespBody(resp)
|
||||
if resp.StatusCode == http.StatusAccepted || resp.StatusCode == http.StatusNotFound {
|
||||
return resp.StatusCode == http.StatusAccepted, nil
|
||||
}
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
func (c *Container) delete(options *DeleteContainerOptions) (*storageResponse, error) {
|
||||
func (c *Container) delete(options *DeleteContainerOptions) (*http.Response, error) {
|
||||
query := url.Values{"restype": {"container"}}
|
||||
headers := c.bsc.client.getStandardHeaders()
|
||||
|
||||
|
@ -399,9 +472,17 @@ func (c *Container) delete(options *DeleteContainerOptions) (*storageResponse, e
|
|||
func (c *Container) ListBlobs(params ListBlobsParameters) (BlobListResponse, error) {
|
||||
q := mergeParams(params.getParameters(), url.Values{
|
||||
"restype": {"container"},
|
||||
"comp": {"list"}},
|
||||
)
|
||||
uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), q)
|
||||
"comp": {"list"},
|
||||
})
|
||||
var uri string
|
||||
if c.bsc.client.isServiceSASClient() {
|
||||
q = mergeParams(q, c.sasuri.Query())
|
||||
newURI := c.sasuri
|
||||
newURI.RawQuery = q.Encode()
|
||||
uri = newURI.String()
|
||||
} else {
|
||||
uri = c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), q)
|
||||
}
|
||||
|
||||
headers := c.bsc.client.getStandardHeaders()
|
||||
headers = addToHeaders(headers, "x-ms-client-request-id", params.RequestID)
|
||||
|
@ -411,15 +492,90 @@ func (c *Container) ListBlobs(params ListBlobsParameters) (BlobListResponse, err
|
|||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
defer resp.body.Close()
|
||||
defer resp.Body.Close()
|
||||
|
||||
err = xmlUnmarshal(resp.body, &out)
|
||||
err = xmlUnmarshal(resp.Body, &out)
|
||||
for i := range out.Blobs {
|
||||
out.Blobs[i].Container = c
|
||||
}
|
||||
return out, err
|
||||
}
|
||||
|
||||
// ContainerMetadataOptions includes options for container metadata operations
|
||||
type ContainerMetadataOptions struct {
|
||||
Timeout uint
|
||||
LeaseID string `header:"x-ms-lease-id"`
|
||||
RequestID string `header:"x-ms-client-request-id"`
|
||||
}
|
||||
|
||||
// SetMetadata replaces the metadata for the specified container.
|
||||
//
|
||||
// Some keys may be converted to Camel-Case before sending. All keys
|
||||
// are returned in lower case by GetBlobMetadata. HTTP header names
|
||||
// are case-insensitive so case munging should not matter to other
|
||||
// applications either.
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/set-container-metadata
|
||||
func (c *Container) SetMetadata(options *ContainerMetadataOptions) error {
|
||||
params := url.Values{
|
||||
"comp": {"metadata"},
|
||||
"restype": {"container"},
|
||||
}
|
||||
headers := c.bsc.client.getStandardHeaders()
|
||||
headers = c.bsc.client.addMetadataToHeaders(headers, c.Metadata)
|
||||
|
||||
if options != nil {
|
||||
params = addTimeout(params, options.Timeout)
|
||||
headers = mergeHeaders(headers, headersFromStruct(*options))
|
||||
}
|
||||
|
||||
uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params)
|
||||
|
||||
resp, err := c.bsc.client.exec(http.MethodPut, uri, headers, nil, c.bsc.auth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusOK})
|
||||
}
|
||||
|
||||
// GetMetadata returns all user-defined metadata for the specified container.
|
||||
//
|
||||
// All metadata keys will be returned in lower case. (HTTP header
|
||||
// names are case-insensitive.)
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/get-container-metadata
|
||||
func (c *Container) GetMetadata(options *ContainerMetadataOptions) error {
|
||||
params := url.Values{
|
||||
"comp": {"metadata"},
|
||||
"restype": {"container"},
|
||||
}
|
||||
headers := c.bsc.client.getStandardHeaders()
|
||||
|
||||
if options != nil {
|
||||
params = addTimeout(params, options.Timeout)
|
||||
headers = mergeHeaders(headers, headersFromStruct(*options))
|
||||
}
|
||||
|
||||
uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params)
|
||||
|
||||
resp, err := c.bsc.client.exec(http.MethodGet, uri, headers, nil, c.bsc.auth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer drainRespBody(resp)
|
||||
if err := checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.writeMetadata(resp.Header)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) writeMetadata(h http.Header) {
|
||||
c.Metadata = writeMetadata(h)
|
||||
}
|
||||
|
||||
func generateContainerACLpayload(policies []ContainerAccessPolicy) (io.Reader, int, error) {
|
||||
sil := SignedIdentifiers{
|
||||
SignedIdentifiers: []SignedIdentifier{},
|
||||
|
@ -451,3 +607,34 @@ func (capd *ContainerAccessPolicy) generateContainerPermissions() (permissions s
|
|||
|
||||
return permissions
|
||||
}
|
||||
|
||||
// GetProperties updated the properties of the container.
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/get-container-properties
|
||||
func (c *Container) GetProperties() error {
|
||||
params := url.Values{
|
||||
"restype": {"container"},
|
||||
}
|
||||
headers := c.bsc.client.getStandardHeaders()
|
||||
|
||||
uri := c.bsc.client.getEndpoint(blobServiceName, c.buildPath(), params)
|
||||
|
||||
resp, err := c.bsc.client.exec(http.MethodGet, uri, headers, nil, c.bsc.auth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if err := checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update properties
|
||||
c.Properties.Etag = resp.Header.Get(headerEtag)
|
||||
c.Properties.LeaseStatus = resp.Header.Get("x-ms-lease-status")
|
||||
c.Properties.LeaseState = resp.Header.Get("x-ms-lease-state")
|
||||
c.Properties.LeaseDuration = resp.Header.Get("x-ms-lease-duration")
|
||||
c.Properties.LastModified = resp.Header.Get("Last-Modified")
|
||||
c.Properties.PublicAccess = ContainerAccessType(resp.Header.Get(ContainerAccessHeader))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -96,13 +110,13 @@ func (b *Blob) StartCopy(sourceBlob string, options *CopyOptions) (string, error
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusAccepted, http.StatusCreated}); err != nil {
|
||||
if err := checkRespCode(resp, []int{http.StatusAccepted, http.StatusCreated}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
copyID := resp.headers.Get("x-ms-copy-id")
|
||||
copyID := resp.Header.Get("x-ms-copy-id")
|
||||
if copyID == "" {
|
||||
return "", errors.New("Got empty copy id header")
|
||||
}
|
||||
|
@ -138,8 +152,8 @@ func (b *Blob) AbortCopy(copyID string, options *AbortCopyOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusNoContent})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusNoContent})
|
||||
}
|
||||
|
||||
// WaitForCopy loops until a BlobCopy operation is completed (or fails with error)
|
||||
|
@ -209,13 +223,13 @@ func (b *Blob) IncrementalCopyBlob(sourceBlobURL string, snapshotTime time.Time,
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusAccepted}); err != nil {
|
||||
if err := checkRespCode(resp, []int{http.StatusAccepted}); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
copyID := resp.headers.Get("x-ms-copy-id")
|
||||
copyID := resp.Header.Get("x-ms-copy-id")
|
||||
if copyID == "" {
|
||||
return "", errors.New("Got empty copy id header")
|
||||
}
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"net/http"
|
||||
|
@ -93,10 +107,10 @@ func (d *Directory) CreateIfNotExists(options *FileRequestOptions) (bool, error)
|
|||
params := prepareOptions(options)
|
||||
resp, err := d.fsc.createResourceNoClose(d.buildPath(), resourceDirectory, params, nil)
|
||||
if resp != nil {
|
||||
defer readAndCloseBody(resp.body)
|
||||
if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict {
|
||||
if resp.statusCode == http.StatusCreated {
|
||||
d.updateEtagAndLastModified(resp.headers)
|
||||
defer drainRespBody(resp)
|
||||
if resp.StatusCode == http.StatusCreated || resp.StatusCode == http.StatusConflict {
|
||||
if resp.StatusCode == http.StatusCreated {
|
||||
d.updateEtagAndLastModified(resp.Header)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
|
@ -121,9 +135,9 @@ func (d *Directory) Delete(options *FileRequestOptions) error {
|
|||
func (d *Directory) DeleteIfExists(options *FileRequestOptions) (bool, error) {
|
||||
resp, err := d.fsc.deleteResourceNoClose(d.buildPath(), resourceDirectory, options)
|
||||
if resp != nil {
|
||||
defer readAndCloseBody(resp.body)
|
||||
if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound {
|
||||
return resp.statusCode == http.StatusAccepted, nil
|
||||
defer drainRespBody(resp)
|
||||
if resp.StatusCode == http.StatusAccepted || resp.StatusCode == http.StatusNotFound {
|
||||
return resp.StatusCode == http.StatusAccepted, nil
|
||||
}
|
||||
}
|
||||
return false, err
|
||||
|
@ -186,9 +200,9 @@ func (d *Directory) ListDirsAndFiles(params ListDirsAndFilesParameters) (*DirsAn
|
|||
return nil, err
|
||||
}
|
||||
|
||||
defer resp.body.Close()
|
||||
defer resp.Body.Close()
|
||||
var out DirsAndFilesListResponse
|
||||
err = xmlUnmarshal(resp.body, &out)
|
||||
err = xmlUnmarshal(resp.Body, &out)
|
||||
return &out, err
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,22 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -12,7 +27,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/satori/uuid"
|
||||
"github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
// Annotating as secure for gas scanning
|
||||
|
@ -97,13 +112,13 @@ func (e *Entity) Get(timeout uint, ml MetadataLevel, options *GetEntityOptions)
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
if err = checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
respBody, err := ioutil.ReadAll(resp.body)
|
||||
respBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -139,22 +154,21 @@ func (e *Entity) Insert(ml MetadataLevel, options *EntityOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.body.Close()
|
||||
|
||||
data, err := ioutil.ReadAll(resp.body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if ml != EmptyPayload {
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusCreated}); err != nil {
|
||||
if err = checkRespCode(resp, []int{http.StatusCreated}); err != nil {
|
||||
return err
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = e.UnmarshalJSON(data); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil {
|
||||
if err = checkRespCode(resp, []int{http.StatusNoContent}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -193,18 +207,18 @@ func (e *Entity) Delete(force bool, options *EntityOptions) error {
|
|||
uri := e.Table.tsc.client.getEndpoint(tableServiceName, e.buildPath(), query)
|
||||
resp, err := e.Table.tsc.client.exec(http.MethodDelete, uri, headers, nil, e.Table.tsc.auth)
|
||||
if err != nil {
|
||||
if resp.statusCode == http.StatusPreconditionFailed {
|
||||
if resp.StatusCode == http.StatusPreconditionFailed {
|
||||
return fmt.Errorf(etagErrorTemplate, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil {
|
||||
if err = checkRespCode(resp, []int{http.StatusNoContent}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return e.updateTimestamp(resp.headers)
|
||||
return e.updateTimestamp(resp.Header)
|
||||
}
|
||||
|
||||
// InsertOrReplace inserts an entity or replaces the existing one.
|
||||
|
@ -233,7 +247,7 @@ func (e *Entity) MarshalJSON() ([]byte, error) {
|
|||
switch t := v.(type) {
|
||||
case []byte:
|
||||
completeMap[typeKey] = OdataBinary
|
||||
completeMap[k] = string(t)
|
||||
completeMap[k] = t
|
||||
case time.Time:
|
||||
completeMap[typeKey] = OdataDateTime
|
||||
completeMap[k] = t.Format(time.RFC3339Nano)
|
||||
|
@ -307,7 +321,10 @@ func (e *Entity) UnmarshalJSON(data []byte) error {
|
|||
}
|
||||
switch v {
|
||||
case OdataBinary:
|
||||
props[valueKey] = []byte(str)
|
||||
props[valueKey], err = base64.StdEncoding.DecodeString(str)
|
||||
if err != nil {
|
||||
return fmt.Errorf(errorTemplate, err)
|
||||
}
|
||||
case OdataDateTime:
|
||||
t, err := time.Parse("2006-01-02T15:04:05Z", str)
|
||||
if err != nil {
|
||||
|
@ -382,13 +399,13 @@ func (e *Entity) insertOr(verb string, options *EntityOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil {
|
||||
if err = checkRespCode(resp, []int{http.StatusNoContent}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return e.updateEtagAndTimestamp(resp.headers)
|
||||
return e.updateEtagAndTimestamp(resp.Header)
|
||||
}
|
||||
|
||||
func (e *Entity) updateMerge(force bool, verb string, options *EntityOptions) error {
|
||||
|
@ -406,18 +423,18 @@ func (e *Entity) updateMerge(force bool, verb string, options *EntityOptions) er
|
|||
uri := e.Table.tsc.client.getEndpoint(tableServiceName, e.buildPath(), query)
|
||||
resp, err := e.Table.tsc.client.exec(verb, uri, headers, bytes.NewReader(body), e.Table.tsc.auth)
|
||||
if err != nil {
|
||||
if resp.statusCode == http.StatusPreconditionFailed {
|
||||
if resp.StatusCode == http.StatusPreconditionFailed {
|
||||
return fmt.Errorf(etagErrorTemplate, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil {
|
||||
if err = checkRespCode(resp, []int{http.StatusNoContent}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return e.updateEtagAndTimestamp(resp.headers)
|
||||
return e.updateEtagAndTimestamp(resp.Header)
|
||||
}
|
||||
|
||||
func stringFromMap(props map[string]interface{}, key string) string {
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -14,6 +28,10 @@ import (
|
|||
const fourMB = uint64(4194304)
|
||||
const oneTB = uint64(1099511627776)
|
||||
|
||||
// Export maximum range and file sizes
|
||||
const MaxRangeSize = fourMB
|
||||
const MaxFileSize = oneTB
|
||||
|
||||
// File represents a file on a share.
|
||||
type File struct {
|
||||
fsc *FileServiceClient
|
||||
|
@ -169,9 +187,9 @@ func (f *File) Delete(options *FileRequestOptions) error {
|
|||
func (f *File) DeleteIfExists(options *FileRequestOptions) (bool, error) {
|
||||
resp, err := f.fsc.deleteResourceNoClose(f.buildPath(), resourceFile, options)
|
||||
if resp != nil {
|
||||
defer readAndCloseBody(resp.body)
|
||||
if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound {
|
||||
return resp.statusCode == http.StatusAccepted, nil
|
||||
defer drainRespBody(resp)
|
||||
if resp.StatusCode == http.StatusAccepted || resp.StatusCode == http.StatusNotFound {
|
||||
return resp.StatusCode == http.StatusAccepted, nil
|
||||
}
|
||||
}
|
||||
return false, err
|
||||
|
@ -193,11 +211,11 @@ func (f *File) DownloadToStream(options *FileRequestOptions) (io.ReadCloser, err
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
readAndCloseBody(resp.body)
|
||||
if err = checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
drainRespBody(resp)
|
||||
return nil, err
|
||||
}
|
||||
return resp.body, nil
|
||||
return resp.Body, nil
|
||||
}
|
||||
|
||||
// DownloadRangeToStream operation downloads the specified range of this file with optional MD5 hash.
|
||||
|
@ -223,14 +241,14 @@ func (f *File) DownloadRangeToStream(fileRange FileRange, options *GetFileOption
|
|||
return fs, err
|
||||
}
|
||||
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusOK, http.StatusPartialContent}); err != nil {
|
||||
readAndCloseBody(resp.body)
|
||||
if err = checkRespCode(resp, []int{http.StatusOK, http.StatusPartialContent}); err != nil {
|
||||
drainRespBody(resp)
|
||||
return fs, err
|
||||
}
|
||||
|
||||
fs.Body = resp.body
|
||||
fs.Body = resp.Body
|
||||
if options != nil && options.GetContentMD5 {
|
||||
fs.ContentMD5 = resp.headers.Get("Content-MD5")
|
||||
fs.ContentMD5 = resp.Header.Get("Content-MD5")
|
||||
}
|
||||
return fs, nil
|
||||
}
|
||||
|
@ -296,20 +314,20 @@ func (f *File) ListRanges(options *ListRangesOptions) (*FileRanges, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
defer resp.body.Close()
|
||||
defer resp.Body.Close()
|
||||
var cl uint64
|
||||
cl, err = strconv.ParseUint(resp.headers.Get("x-ms-content-length"), 10, 64)
|
||||
cl, err = strconv.ParseUint(resp.Header.Get("x-ms-content-length"), 10, 64)
|
||||
if err != nil {
|
||||
ioutil.ReadAll(resp.body)
|
||||
ioutil.ReadAll(resp.Body)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var out FileRanges
|
||||
out.ContentLength = cl
|
||||
out.ETag = resp.headers.Get("ETag")
|
||||
out.LastModified = resp.headers.Get("Last-Modified")
|
||||
out.ETag = resp.Header.Get("ETag")
|
||||
out.LastModified = resp.Header.Get("Last-Modified")
|
||||
|
||||
err = xmlUnmarshal(resp.body, &out)
|
||||
err = xmlUnmarshal(resp.Body, &out)
|
||||
return &out, err
|
||||
}
|
||||
|
||||
|
@ -357,8 +375,8 @@ func (f *File) modifyRange(bytes io.Reader, fileRange FileRange, timeout *uint,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
return resp.headers, checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
defer drainRespBody(resp)
|
||||
return resp.Header, checkRespCode(resp, []int{http.StatusCreated})
|
||||
}
|
||||
|
||||
// SetMetadata replaces the metadata for this file.
|
||||
|
@ -426,7 +444,7 @@ func (f *File) URL() string {
|
|||
return f.fsc.client.getEndpoint(fileServiceName, f.buildPath(), nil)
|
||||
}
|
||||
|
||||
// WriteRangeOptions includes opptions for a write file range operation
|
||||
// WriteRangeOptions includes options for a write file range operation
|
||||
type WriteRangeOptions struct {
|
||||
Timeout uint
|
||||
ContentMD5 string
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
|
@ -140,8 +154,8 @@ func (f FileServiceClient) ListShares(params ListSharesParameters) (*ShareListRe
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.body.Close()
|
||||
err = xmlUnmarshal(resp.body, &out)
|
||||
defer resp.Body.Close()
|
||||
err = xmlUnmarshal(resp.Body, &out)
|
||||
|
||||
// assign our client to the newly created Share objects
|
||||
for i := range out.Shares {
|
||||
|
@ -165,7 +179,7 @@ func (f *FileServiceClient) SetServiceProperties(props ServiceProperties) error
|
|||
}
|
||||
|
||||
// retrieves directory or share content
|
||||
func (f FileServiceClient) listContent(path string, params url.Values, extraHeaders map[string]string) (*storageResponse, error) {
|
||||
func (f FileServiceClient) listContent(path string, params url.Values, extraHeaders map[string]string) (*http.Response, error) {
|
||||
if err := f.checkForStorageEmulator(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -179,8 +193,8 @@ func (f FileServiceClient) listContent(path string, params url.Values, extraHead
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
readAndCloseBody(resp.body)
|
||||
if err = checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
drainRespBody(resp)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
@ -198,9 +212,9 @@ func (f FileServiceClient) resourceExists(path string, res resourceType) (bool,
|
|||
|
||||
resp, err := f.client.exec(http.MethodHead, uri, headers, nil, f.auth)
|
||||
if resp != nil {
|
||||
defer readAndCloseBody(resp.body)
|
||||
if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound {
|
||||
return resp.statusCode == http.StatusOK, resp.headers, nil
|
||||
defer drainRespBody(resp)
|
||||
if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNotFound {
|
||||
return resp.StatusCode == http.StatusOK, resp.Header, nil
|
||||
}
|
||||
}
|
||||
return false, nil, err
|
||||
|
@ -212,12 +226,12 @@ func (f FileServiceClient) createResource(path string, res resourceType, urlPara
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
return resp.headers, checkRespCode(resp.statusCode, expectedResponseCodes)
|
||||
defer drainRespBody(resp)
|
||||
return resp.Header, checkRespCode(resp, expectedResponseCodes)
|
||||
}
|
||||
|
||||
// creates a resource depending on the specified resource type, doesn't close the response body
|
||||
func (f FileServiceClient) createResourceNoClose(path string, res resourceType, urlParams url.Values, extraHeaders map[string]string) (*storageResponse, error) {
|
||||
func (f FileServiceClient) createResourceNoClose(path string, res resourceType, urlParams url.Values, extraHeaders map[string]string) (*http.Response, error) {
|
||||
if err := f.checkForStorageEmulator(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -237,17 +251,17 @@ func (f FileServiceClient) getResourceHeaders(path string, comp compType, res re
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
if err = checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.headers, nil
|
||||
return resp.Header, nil
|
||||
}
|
||||
|
||||
// gets the specified resource, doesn't close the response body
|
||||
func (f FileServiceClient) getResourceNoClose(path string, comp compType, res resourceType, params url.Values, verb string, extraHeaders map[string]string) (*storageResponse, error) {
|
||||
func (f FileServiceClient) getResourceNoClose(path string, comp compType, res resourceType, params url.Values, verb string, extraHeaders map[string]string) (*http.Response, error) {
|
||||
if err := f.checkForStorageEmulator(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -265,12 +279,12 @@ func (f FileServiceClient) deleteResource(path string, res resourceType, options
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusAccepted})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusAccepted})
|
||||
}
|
||||
|
||||
// deletes the resource and returns the response, doesn't close the response body
|
||||
func (f FileServiceClient) deleteResourceNoClose(path string, res resourceType, options *FileRequestOptions) (*storageResponse, error) {
|
||||
func (f FileServiceClient) deleteResourceNoClose(path string, res resourceType, options *FileRequestOptions) (*http.Response, error) {
|
||||
if err := f.checkForStorageEmulator(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -309,9 +323,9 @@ func (f FileServiceClient) setResourceHeaders(path string, comp compType, res re
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
return resp.headers, checkRespCode(resp.statusCode, []int{http.StatusOK})
|
||||
return resp.Header, checkRespCode(resp, []int{http.StatusOK})
|
||||
}
|
||||
|
||||
//checkForStorageEmulator determines if the client is setup for use with
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
@ -39,13 +53,13 @@ func (b *Blob) leaseCommonPut(headers map[string]string, expectedStatus int, opt
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{expectedStatus}); err != nil {
|
||||
if err := checkRespCode(resp, []int{expectedStatus}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return resp.headers, nil
|
||||
return resp.Header, nil
|
||||
}
|
||||
|
||||
// LeaseOptions includes options for all operations regarding leasing blobs
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
|
@ -64,13 +78,16 @@ func (m *Message) Put(options *PutMessageOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
|
||||
err = xmlUnmarshal(resp.body, m)
|
||||
defer drainRespBody(resp)
|
||||
err = checkRespCode(resp, []int{http.StatusCreated})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
err = xmlUnmarshal(resp.Body, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateMessageOptions is the set of options can be specified for Update Messsage
|
||||
|
@ -97,7 +114,8 @@ func (m *Message) Update(options *UpdateMessageOptions) error {
|
|||
return err
|
||||
}
|
||||
headers["Content-Length"] = strconv.Itoa(nn)
|
||||
|
||||
// visibilitytimeout is required for Update (zero or greater) so set the default here
|
||||
query.Set("visibilitytimeout", "0")
|
||||
if options != nil {
|
||||
if options.VisibilityTimeout != 0 {
|
||||
query.Set("visibilitytimeout", strconv.Itoa(options.VisibilityTimeout))
|
||||
|
@ -111,10 +129,10 @@ func (m *Message) Update(options *UpdateMessageOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
m.PopReceipt = resp.headers.Get("x-ms-popreceipt")
|
||||
nextTimeStr := resp.headers.Get("x-ms-time-next-visible")
|
||||
m.PopReceipt = resp.Header.Get("x-ms-popreceipt")
|
||||
nextTimeStr := resp.Header.Get("x-ms-time-next-visible")
|
||||
if nextTimeStr != "" {
|
||||
nextTime, err := time.Parse(time.RFC1123, nextTimeStr)
|
||||
if err != nil {
|
||||
|
@ -123,7 +141,7 @@ func (m *Message) Update(options *UpdateMessageOptions) error {
|
|||
m.NextVisible = TimeRFC1123(nextTime)
|
||||
}
|
||||
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusNoContent})
|
||||
return checkRespCode(resp, []int{http.StatusNoContent})
|
||||
}
|
||||
|
||||
// Delete operation deletes the specified message.
|
||||
|
@ -143,8 +161,8 @@ func (m *Message) Delete(options *QueueServiceOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusNoContent})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusNoContent})
|
||||
}
|
||||
|
||||
type putMessageRequest struct {
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
// MetadataLevel determines if operations should return a paylod,
|
||||
// and it level of detail.
|
||||
type MetadataLevel string
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
|
@ -73,10 +87,10 @@ func (b *Blob) modifyRange(blobRange BlobRange, bytes io.Reader, options *PutPag
|
|||
return errors.New("the value for rangeEnd must be greater than or equal to rangeStart")
|
||||
}
|
||||
if blobRange.Start%512 != 0 {
|
||||
return errors.New("the value for rangeStart must be a modulus of 512")
|
||||
return errors.New("the value for rangeStart must be a multiple of 512")
|
||||
}
|
||||
if blobRange.End%512 != 511 {
|
||||
return errors.New("the value for rangeEnd must be a modulus of 511")
|
||||
return errors.New("the value for rangeEnd must be a multiple of 512 - 1")
|
||||
}
|
||||
|
||||
params := url.Values{"comp": {"page"}}
|
||||
|
@ -107,9 +121,8 @@ func (b *Blob) modifyRange(blobRange BlobRange, bytes io.Reader, options *PutPag
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusCreated})
|
||||
}
|
||||
|
||||
// GetPageRangesOptions includes the options for a get page ranges operation
|
||||
|
@ -133,7 +146,7 @@ func (b *Blob) GetPageRanges(options *GetPageRangesOptions) (GetPageRangesRespon
|
|||
params = addTimeout(params, options.Timeout)
|
||||
params = addSnapshot(params, options.Snapshot)
|
||||
if options.PreviousSnapshot != nil {
|
||||
params.Add("prevsnapshot", timeRfc1123Formatted(*options.PreviousSnapshot))
|
||||
params.Add("prevsnapshot", timeRFC3339Formatted(*options.PreviousSnapshot))
|
||||
}
|
||||
if options.Range != nil {
|
||||
headers["Range"] = options.Range.String()
|
||||
|
@ -147,12 +160,12 @@ func (b *Blob) GetPageRanges(options *GetPageRangesOptions) (GetPageRangesRespon
|
|||
if err != nil {
|
||||
return out, err
|
||||
}
|
||||
defer resp.body.Close()
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
if err = checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
return out, err
|
||||
}
|
||||
err = xmlUnmarshal(resp.body, &out)
|
||||
err = xmlUnmarshal(resp.Body, &out)
|
||||
return out, err
|
||||
}
|
||||
|
||||
|
@ -186,6 +199,5 @@ func (b *Blob) PutPageBlob(options *PutBlobOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
return b.respondCreation(resp, BlobTypePage)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,21 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
@ -78,8 +91,8 @@ func (q *Queue) Create(options *QueueServiceOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusCreated})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusCreated})
|
||||
}
|
||||
|
||||
// Delete operation permanently deletes the specified queue.
|
||||
|
@ -98,8 +111,8 @@ func (q *Queue) Delete(options *QueueServiceOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusNoContent})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusNoContent})
|
||||
}
|
||||
|
||||
// Exists returns true if a queue with given name exists.
|
||||
|
@ -107,10 +120,11 @@ func (q *Queue) Exists() (bool, error) {
|
|||
uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), url.Values{"comp": {"metadata"}})
|
||||
resp, err := q.qsc.client.exec(http.MethodGet, uri, q.qsc.client.getStandardHeaders(), nil, q.qsc.auth)
|
||||
if resp != nil {
|
||||
defer readAndCloseBody(resp.body)
|
||||
if resp.statusCode == http.StatusOK || resp.statusCode == http.StatusNotFound {
|
||||
return resp.statusCode == http.StatusOK, nil
|
||||
defer drainRespBody(resp)
|
||||
if resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNotFound {
|
||||
return resp.StatusCode == http.StatusOK, nil
|
||||
}
|
||||
err = getErrorFromResponse(resp)
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
@ -134,8 +148,8 @@ func (q *Queue) SetMetadata(options *QueueServiceOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusNoContent})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusNoContent})
|
||||
}
|
||||
|
||||
// GetMetadata operation retrieves user-defined metadata and queue
|
||||
|
@ -155,19 +169,19 @@ func (q *Queue) GetMetadata(options *QueueServiceOptions) error {
|
|||
params = addTimeout(params, options.Timeout)
|
||||
headers = mergeHeaders(headers, headersFromStruct(*options))
|
||||
}
|
||||
uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), url.Values{"comp": {"metadata"}})
|
||||
uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), params)
|
||||
|
||||
resp, err := q.qsc.client.exec(http.MethodGet, uri, headers, nil, q.qsc.auth)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
if err := checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
aproxMessagesStr := resp.headers.Get(http.CanonicalHeaderKey(approximateMessagesCountHeader))
|
||||
aproxMessagesStr := resp.Header.Get(http.CanonicalHeaderKey(approximateMessagesCountHeader))
|
||||
if aproxMessagesStr != "" {
|
||||
aproxMessages, err := strconv.ParseUint(aproxMessagesStr, 10, 64)
|
||||
if err != nil {
|
||||
|
@ -176,7 +190,7 @@ func (q *Queue) GetMetadata(options *QueueServiceOptions) error {
|
|||
q.AproxMessageCount = aproxMessages
|
||||
}
|
||||
|
||||
q.Metadata = getMetadataFromHeaders(resp.headers)
|
||||
q.Metadata = getMetadataFromHeaders(resp.Header)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -227,10 +241,10 @@ func (q *Queue) GetMessages(options *GetMessagesOptions) ([]Message, error) {
|
|||
if err != nil {
|
||||
return []Message{}, err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer resp.Body.Close()
|
||||
|
||||
var out messages
|
||||
err = xmlUnmarshal(resp.body, &out)
|
||||
err = xmlUnmarshal(resp.Body, &out)
|
||||
if err != nil {
|
||||
return []Message{}, err
|
||||
}
|
||||
|
@ -270,10 +284,10 @@ func (q *Queue) PeekMessages(options *PeekMessagesOptions) ([]Message, error) {
|
|||
if err != nil {
|
||||
return []Message{}, err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer resp.Body.Close()
|
||||
|
||||
var out messages
|
||||
err = xmlUnmarshal(resp.body, &out)
|
||||
err = xmlUnmarshal(resp.Body, &out)
|
||||
if err != nil {
|
||||
return []Message{}, err
|
||||
}
|
||||
|
@ -300,8 +314,8 @@ func (q *Queue) ClearMessages(options *QueueServiceOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusNoContent})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusNoContent})
|
||||
}
|
||||
|
||||
// SetPermissions sets up queue permissions
|
||||
|
@ -327,13 +341,8 @@ func (q *Queue) SetPermissions(permissions QueuePermissions, options *SetQueuePe
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil {
|
||||
return errors.New("Unable to set permissions")
|
||||
}
|
||||
|
||||
return nil
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusNoContent})
|
||||
}
|
||||
|
||||
func generateQueueACLpayload(policies []QueueAccessPolicy) (io.Reader, int, error) {
|
||||
|
@ -395,14 +404,14 @@ func (q *Queue) GetPermissions(options *GetQueuePermissionOptions) (*QueuePermis
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.body.Close()
|
||||
defer resp.Body.Close()
|
||||
|
||||
var ap AccessPolicy
|
||||
err = xmlUnmarshal(resp.body, &ap.SignedIdentifiersList)
|
||||
err = xmlUnmarshal(resp.Body, &ap.SignedIdentifiersList)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buildQueueAccessPolicy(ap, &resp.headers), nil
|
||||
return buildQueueAccessPolicy(ap, &resp.Header), nil
|
||||
}
|
||||
|
||||
func buildQueueAccessPolicy(ap AccessPolicy, headers *http.Header) *QueuePermissions {
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// QueueSASOptions are options to construct a blob SAS
|
||||
// URI.
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
type QueueSASOptions struct {
|
||||
QueueSASPermissions
|
||||
SASOptions
|
||||
}
|
||||
|
||||
// QueueSASPermissions includes the available permissions for
|
||||
// a queue SAS URI.
|
||||
type QueueSASPermissions struct {
|
||||
Read bool
|
||||
Add bool
|
||||
Update bool
|
||||
Process bool
|
||||
}
|
||||
|
||||
func (q QueueSASPermissions) buildString() string {
|
||||
permissions := ""
|
||||
|
||||
if q.Read {
|
||||
permissions += "r"
|
||||
}
|
||||
if q.Add {
|
||||
permissions += "a"
|
||||
}
|
||||
if q.Update {
|
||||
permissions += "u"
|
||||
}
|
||||
if q.Process {
|
||||
permissions += "p"
|
||||
}
|
||||
return permissions
|
||||
}
|
||||
|
||||
// GetSASURI creates an URL to the specified queue which contains the Shared
|
||||
// Access Signature with specified permissions and expiration time.
|
||||
//
|
||||
// See https://docs.microsoft.com/en-us/rest/api/storageservices/constructing-a-service-sas
|
||||
func (q *Queue) GetSASURI(options QueueSASOptions) (string, error) {
|
||||
canonicalizedResource, err := q.qsc.client.buildCanonicalizedResource(q.buildPath(), q.qsc.auth, true)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// "The canonicalizedresouce portion of the string is a canonical path to the signed resource.
|
||||
// It must include the service name (blob, table, queue or file) for version 2015-02-21 or
|
||||
// later, the storage account name, and the resource name, and must be URL-decoded.
|
||||
// -- https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx
|
||||
// We need to replace + with %2b first to avoid being treated as a space (which is correct for query strings, but not the path component).
|
||||
canonicalizedResource = strings.Replace(canonicalizedResource, "+", "%2b", -1)
|
||||
canonicalizedResource, err = url.QueryUnescape(canonicalizedResource)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
signedStart := ""
|
||||
if options.Start != (time.Time{}) {
|
||||
signedStart = options.Start.UTC().Format(time.RFC3339)
|
||||
}
|
||||
signedExpiry := options.Expiry.UTC().Format(time.RFC3339)
|
||||
|
||||
protocols := "https,http"
|
||||
if options.UseHTTPS {
|
||||
protocols = "https"
|
||||
}
|
||||
|
||||
permissions := options.QueueSASPermissions.buildString()
|
||||
stringToSign, err := queueSASStringToSign(q.qsc.client.apiVersion, canonicalizedResource, signedStart, signedExpiry, options.IP, permissions, protocols, options.Identifier)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sig := q.qsc.client.computeHmac256(stringToSign)
|
||||
sasParams := url.Values{
|
||||
"sv": {q.qsc.client.apiVersion},
|
||||
"se": {signedExpiry},
|
||||
"sp": {permissions},
|
||||
"sig": {sig},
|
||||
}
|
||||
|
||||
if q.qsc.client.apiVersion >= "2015-04-05" {
|
||||
sasParams.Add("spr", protocols)
|
||||
addQueryParameter(sasParams, "sip", options.IP)
|
||||
}
|
||||
|
||||
uri := q.qsc.client.getEndpoint(queueServiceName, q.buildPath(), nil)
|
||||
sasURL, err := url.Parse(uri)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sasURL.RawQuery = sasParams.Encode()
|
||||
return sasURL.String(), nil
|
||||
}
|
||||
|
||||
func queueSASStringToSign(signedVersion, canonicalizedResource, signedStart, signedExpiry, signedIP, signedPermissions, protocols, signedIdentifier string) (string, error) {
|
||||
|
||||
if signedVersion >= "2015-02-21" {
|
||||
canonicalizedResource = "/queue" + canonicalizedResource
|
||||
}
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/azure/dn140255.aspx#Anchor_12
|
||||
if signedVersion >= "2015-04-05" {
|
||||
return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s",
|
||||
signedPermissions,
|
||||
signedStart,
|
||||
signedExpiry,
|
||||
canonicalizedResource,
|
||||
signedIdentifier,
|
||||
signedIP,
|
||||
protocols,
|
||||
signedVersion), nil
|
||||
|
||||
}
|
||||
|
||||
// reference: http://msdn.microsoft.com/en-us/library/azure/dn140255.aspx
|
||||
if signedVersion >= "2013-08-15" {
|
||||
return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s", signedPermissions, signedStart, signedExpiry, canonicalizedResource, signedIdentifier, signedVersion), nil
|
||||
}
|
||||
|
||||
return "", errors.New("storage: not implemented SAS for versions earlier than 2013-08-15")
|
||||
}
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
// QueueServiceClient contains operations for Microsoft Azure Queue Storage
|
||||
// Service.
|
||||
type QueueServiceClient struct {
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
@ -61,10 +75,10 @@ func (s *Share) CreateIfNotExists(options *FileRequestOptions) (bool, error) {
|
|||
params := prepareOptions(options)
|
||||
resp, err := s.fsc.createResourceNoClose(s.buildPath(), resourceShare, params, extraheaders)
|
||||
if resp != nil {
|
||||
defer readAndCloseBody(resp.body)
|
||||
if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict {
|
||||
if resp.statusCode == http.StatusCreated {
|
||||
s.updateEtagAndLastModified(resp.headers)
|
||||
defer drainRespBody(resp)
|
||||
if resp.StatusCode == http.StatusCreated || resp.StatusCode == http.StatusConflict {
|
||||
if resp.StatusCode == http.StatusCreated {
|
||||
s.updateEtagAndLastModified(resp.Header)
|
||||
return true, nil
|
||||
}
|
||||
return false, s.FetchAttributes(nil)
|
||||
|
@ -89,9 +103,9 @@ func (s *Share) Delete(options *FileRequestOptions) error {
|
|||
func (s *Share) DeleteIfExists(options *FileRequestOptions) (bool, error) {
|
||||
resp, err := s.fsc.deleteResourceNoClose(s.buildPath(), resourceShare, options)
|
||||
if resp != nil {
|
||||
defer readAndCloseBody(resp.body)
|
||||
if resp.statusCode == http.StatusAccepted || resp.statusCode == http.StatusNotFound {
|
||||
return resp.statusCode == http.StatusAccepted, nil
|
||||
defer drainRespBody(resp)
|
||||
if resp.StatusCode == http.StatusAccepted || resp.StatusCode == http.StatusNotFound {
|
||||
return resp.StatusCode == http.StatusAccepted, nil
|
||||
}
|
||||
}
|
||||
return false, err
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
@ -63,14 +77,14 @@ func (c Client) getServiceProperties(service string, auth authentication) (*Serv
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.body.Close()
|
||||
defer resp.Body.Close()
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
if err := checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var out ServiceProperties
|
||||
err = xmlUnmarshal(resp.body, &out)
|
||||
err = xmlUnmarshal(resp.Body, &out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -112,6 +126,6 @@ func (c Client) setServiceProperties(props ServiceProperties, service string, au
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
readAndCloseBody(resp.body)
|
||||
return checkRespCode(resp.statusCode, []int{http.StatusAccepted})
|
||||
defer drainRespBody(resp)
|
||||
return checkRespCode(resp, []int{http.StatusAccepted})
|
||||
}
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
@ -83,13 +97,13 @@ func (t *Table) Get(timeout uint, ml MetadataLevel) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer resp.Body.Close()
|
||||
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
if err = checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
respBody, err := ioutil.ReadAll(resp.body)
|
||||
respBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -129,20 +143,20 @@ func (t *Table) Create(timeout uint, ml MetadataLevel, options *TableOptions) er
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer resp.Body.Close()
|
||||
|
||||
if ml == EmptyPayload {
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil {
|
||||
if err := checkRespCode(resp, []int{http.StatusNoContent}); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusCreated}); err != nil {
|
||||
if err := checkRespCode(resp, []int{http.StatusCreated}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if ml != EmptyPayload {
|
||||
data, err := ioutil.ReadAll(resp.body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -172,13 +186,9 @@ func (t *Table) Delete(timeout uint, options *TableOptions) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil {
|
||||
return err
|
||||
|
||||
}
|
||||
return nil
|
||||
return checkRespCode(resp, []int{http.StatusNoContent})
|
||||
}
|
||||
|
||||
// QueryOptions includes options for a query entities operation.
|
||||
|
@ -259,12 +269,9 @@ func (t *Table) SetPermissions(tap []TableAccessPolicy, timeout uint, options *T
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer readAndCloseBody(resp.body)
|
||||
defer drainRespBody(resp)
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusNoContent}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return checkRespCode(resp, []int{http.StatusNoContent})
|
||||
}
|
||||
|
||||
func generateTableACLPayload(policies []TableAccessPolicy) (io.Reader, int, error) {
|
||||
|
@ -294,14 +301,14 @@ func (t *Table) GetPermissions(timeout int, options *TableOptions) ([]TableAcces
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.body.Close()
|
||||
defer resp.Body.Close()
|
||||
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
if err = checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var ap AccessPolicy
|
||||
err = xmlUnmarshal(resp.body, &ap.SignedIdentifiersList)
|
||||
err = xmlUnmarshal(resp.Body, &ap.SignedIdentifiersList)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -318,13 +325,13 @@ func (t *Table) queryEntities(uri string, headers map[string]string, ml Metadata
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.body.Close()
|
||||
defer resp.Body.Close()
|
||||
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
if err = checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
data, err := ioutil.ReadAll(resp.body)
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -339,7 +346,7 @@ func (t *Table) queryEntities(uri string, headers map[string]string, ml Metadata
|
|||
}
|
||||
entities.table = t
|
||||
|
||||
contToken := extractContinuationTokenFromHeaders(resp.headers)
|
||||
contToken := extractContinuationTokenFromHeaders(resp.Header)
|
||||
if contToken == nil {
|
||||
entities.NextLink = nil
|
||||
} else {
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
@ -12,7 +26,7 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/satori/uuid"
|
||||
"github.com/marstr/guid"
|
||||
)
|
||||
|
||||
// Operation type. Insert, Delete, Replace etc.
|
||||
|
@ -117,14 +131,26 @@ func (t *TableBatch) MergeEntity(entity *Entity) {
|
|||
// the changesets.
|
||||
// As per document https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/performing-entity-group-transactions
|
||||
func (t *TableBatch) ExecuteBatch() error {
|
||||
changesetBoundary := fmt.Sprintf("changeset_%s", uuid.NewV1())
|
||||
|
||||
// Using `github.com/marstr/guid` is in response to issue #947 (https://github.com/Azure/azure-sdk-for-go/issues/947).
|
||||
id, err := guid.NewGUIDs(guid.CreationStrategyVersion1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
changesetBoundary := fmt.Sprintf("changeset_%s", id.String())
|
||||
uri := t.Table.tsc.client.getEndpoint(tableServiceName, "$batch", nil)
|
||||
changesetBody, err := t.generateChangesetBody(changesetBoundary)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
boundary := fmt.Sprintf("batch_%s", uuid.NewV1())
|
||||
id, err = guid.NewGUIDs(guid.CreationStrategyVersion1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
boundary := fmt.Sprintf("batch_%s", id.String())
|
||||
body, err := generateBody(changesetBody, changesetBoundary, boundary)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -137,15 +163,15 @@ func (t *TableBatch) ExecuteBatch() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.body.Close()
|
||||
defer drainRespBody(resp.resp)
|
||||
|
||||
if err = checkRespCode(resp.statusCode, []int{http.StatusAccepted}); err != nil {
|
||||
if err = checkRespCode(resp.resp, []int{http.StatusAccepted}); err != nil {
|
||||
|
||||
// check which batch failed.
|
||||
operationFailedMessage := t.getFailedOperation(resp.odata.Err.Message.Value)
|
||||
requestID, date, version := getDebugHeaders(resp.headers)
|
||||
requestID, date, version := getDebugHeaders(resp.resp.Header)
|
||||
return AzureStorageServiceError{
|
||||
StatusCode: resp.statusCode,
|
||||
StatusCode: resp.resp.StatusCode,
|
||||
Code: resp.odata.Err.Code,
|
||||
RequestID: requestID,
|
||||
Date: date,
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
@ -131,13 +145,13 @@ func (t *TableServiceClient) queryTables(uri string, headers map[string]string,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.body.Close()
|
||||
defer resp.Body.Close()
|
||||
|
||||
if err := checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
|
||||
if err := checkRespCode(resp, []int{http.StatusOK}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
respBody, err := ioutil.ReadAll(resp.body)
|
||||
respBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -152,7 +166,7 @@ func (t *TableServiceClient) queryTables(uri string, headers map[string]string,
|
|||
}
|
||||
out.tsc = t
|
||||
|
||||
nextLink := resp.headers.Get(http.CanonicalHeaderKey(headerXmsContinuation))
|
||||
nextLink := resp.Header.Get(http.CanonicalHeaderKey(headerXmsContinuation))
|
||||
if nextLink == "" {
|
||||
out.NextLink = nil
|
||||
} else {
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package storage
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/hmac"
|
||||
|
@ -18,7 +32,29 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
fixedTime = time.Date(2050, time.December, 20, 21, 55, 0, 0, time.FixedZone("GMT", -6))
|
||||
fixedTime = time.Date(2050, time.December, 20, 21, 55, 0, 0, time.FixedZone("GMT", -6))
|
||||
accountSASOptions = AccountSASTokenOptions{
|
||||
Services: Services{
|
||||
Blob: true,
|
||||
},
|
||||
ResourceTypes: ResourceTypes{
|
||||
Service: true,
|
||||
Container: true,
|
||||
Object: true,
|
||||
},
|
||||
Permissions: Permissions{
|
||||
Read: true,
|
||||
Write: true,
|
||||
Delete: true,
|
||||
List: true,
|
||||
Add: true,
|
||||
Create: true,
|
||||
Update: true,
|
||||
Process: true,
|
||||
},
|
||||
Expiry: fixedTime,
|
||||
UseHTTPS: true,
|
||||
}
|
||||
)
|
||||
|
||||
func (c Client) computeHmac256(message string) string {
|
||||
|
@ -35,6 +71,10 @@ func timeRfc1123Formatted(t time.Time) string {
|
|||
return t.Format(http.TimeFormat)
|
||||
}
|
||||
|
||||
func timeRFC3339Formatted(t time.Time) string {
|
||||
return t.Format("2006-01-02T15:04:05.0000000Z")
|
||||
}
|
||||
|
||||
func mergeParams(v1, v2 url.Values) url.Values {
|
||||
out := url.Values{}
|
||||
for k, v := range v1 {
|
||||
|
@ -136,7 +176,7 @@ func addTimeout(params url.Values, timeout uint) url.Values {
|
|||
|
||||
func addSnapshot(params url.Values, snapshot *time.Time) url.Values {
|
||||
if snapshot != nil {
|
||||
params.Add("snapshot", snapshot.Format("2006-01-02T15:04:05.0000000Z"))
|
||||
params.Add("snapshot", timeRFC3339Formatted(*snapshot))
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
@ -169,6 +209,11 @@ func (t *TimeRFC1123) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
|
|||
return nil
|
||||
}
|
||||
|
||||
// MarshalXML marshals using time.RFC1123.
|
||||
func (t *TimeRFC1123) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||
return e.EncodeElement(time.Time(*t).Format(time.RFC1123), start)
|
||||
}
|
||||
|
||||
// returns a map of custom metadata values from the specified HTTP header
|
||||
func getMetadataFromHeaders(header http.Header) map[string]string {
|
||||
metadata := make(map[string]string)
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
// +build !go1.8
|
||||
|
||||
package storage
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func setContentLengthFromLimitedReader(req *http.Request, lr *io.LimitedReader) {
|
||||
req.ContentLength = lr.N
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
// +build go1.8
|
||||
|
||||
package storage
|
||||
|
||||
import (
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func setContentLengthFromLimitedReader(req *http.Request, lr *io.LimitedReader) {
|
||||
req.ContentLength = lr.N
|
||||
snapshot := *lr
|
||||
req.GetBody = func() (io.ReadCloser, error) {
|
||||
r := snapshot
|
||||
return ioutil.NopCloser(&r), nil
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package storage
|
||||
|
||||
var (
|
||||
sdkVersion = "10.0.2"
|
||||
)
|
|
@ -0,0 +1,21 @@
|
|||
package version
|
||||
|
||||
// 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.
|
||||
// Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
||||
|
||||
// Number contains the semantic version of this SDK.
|
||||
const Number = "v21.3.0"
|
|
@ -1,19 +1,24 @@
|
|||
# Azure Active Directory library for Go
|
||||
# Azure Active Directory authentication for Go
|
||||
|
||||
This project provides a stand alone Azure Active Directory library for Go. The code was extracted
|
||||
from [go-autorest](https://github.com/Azure/go-autorest/) project, which is used as a base for
|
||||
[azure-sdk-for-go](https://github.com/Azure/azure-sdk-for-go).
|
||||
This is a standalone package for authenticating with Azure Active
|
||||
Directory from other Go libraries and applications, in particular the [Azure SDK
|
||||
for Go](https://github.com/Azure/azure-sdk-for-go).
|
||||
|
||||
Note: Despite the package's name it is not related to other "ADAL" libraries
|
||||
maintained in the [github.com/AzureAD](https://github.com/AzureAD) org. Issues
|
||||
should be opened in [this repo's](https://github.com/Azure/go-autorest/issues)
|
||||
or [the SDK's](https://github.com/Azure/azure-sdk-for-go/issues) issue
|
||||
trackers.
|
||||
|
||||
## Installation
|
||||
## Install
|
||||
|
||||
```
|
||||
```bash
|
||||
go get -u github.com/Azure/go-autorest/autorest/adal
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
An Active Directory application is required in order to use this library. An application can be registered in the [Azure Portal](https://portal.azure.com/) follow these [guidelines](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications) or using the [Azure CLI](https://github.com/Azure/azure-cli).
|
||||
An Active Directory application is required in order to use this library. An application can be registered in the [Azure Portal](https://portal.azure.com/) by following these [guidelines](https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-integrating-applications) or using the [Azure CLI](https://github.com/Azure/azure-cli).
|
||||
|
||||
### Register an Azure AD Application with secret
|
||||
|
||||
|
@ -218,6 +223,40 @@ if (err == nil) {
|
|||
}
|
||||
```
|
||||
|
||||
#### Username password authenticate
|
||||
|
||||
```Go
|
||||
spt, err := adal.NewServicePrincipalTokenFromUsernamePassword(
|
||||
oauthConfig,
|
||||
applicationID,
|
||||
username,
|
||||
password,
|
||||
resource,
|
||||
callbacks...)
|
||||
|
||||
if (err == nil) {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
#### Authorization code authenticate
|
||||
|
||||
``` Go
|
||||
spt, err := adal.NewServicePrincipalTokenFromAuthorizationCode(
|
||||
oauthConfig,
|
||||
applicationID,
|
||||
clientSecret,
|
||||
authorizationCode,
|
||||
redirectURI,
|
||||
resource,
|
||||
callbacks...)
|
||||
|
||||
err = spt.Refresh()
|
||||
if (err == nil) {
|
||||
token := spt.Token
|
||||
}
|
||||
```
|
||||
|
||||
### Command Line Tool
|
||||
|
||||
A command line tool is available in `cmd/adal.go` that can acquire a token for a given resource. It supports all flows mentioned above.
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package adal
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
@ -12,14 +26,30 @@ const (
|
|||
// OAuthConfig represents the endpoints needed
|
||||
// in OAuth operations
|
||||
type OAuthConfig struct {
|
||||
AuthorityEndpoint url.URL
|
||||
AuthorizeEndpoint url.URL
|
||||
TokenEndpoint url.URL
|
||||
DeviceCodeEndpoint url.URL
|
||||
AuthorityEndpoint url.URL `json:"authorityEndpoint"`
|
||||
AuthorizeEndpoint url.URL `json:"authorizeEndpoint"`
|
||||
TokenEndpoint url.URL `json:"tokenEndpoint"`
|
||||
DeviceCodeEndpoint url.URL `json:"deviceCodeEndpoint"`
|
||||
}
|
||||
|
||||
// IsZero returns true if the OAuthConfig object is zero-initialized.
|
||||
func (oac OAuthConfig) IsZero() bool {
|
||||
return oac == OAuthConfig{}
|
||||
}
|
||||
|
||||
func validateStringParam(param, name string) error {
|
||||
if len(param) == 0 {
|
||||
return fmt.Errorf("parameter '" + name + "' cannot be empty")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewOAuthConfig returns an OAuthConfig with tenant specific urls
|
||||
func NewOAuthConfig(activeDirectoryEndpoint, tenantID string) (*OAuthConfig, error) {
|
||||
if err := validateStringParam(activeDirectoryEndpoint, "activeDirectoryEndpoint"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// it's legal for tenantID to be empty so don't validate it
|
||||
const activeDirectoryEndpointTemplate = "%s/oauth2/%s?api-version=%s"
|
||||
u, err := url.Parse(activeDirectoryEndpoint)
|
||||
if err != nil {
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package adal
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
/*
|
||||
This file is largely based on rjw57/oauth2device's code, with the follow differences:
|
||||
* scope -> resource, and only allow a single one
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package adal
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package adal
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
|
|
@ -1,26 +1,46 @@
|
|||
package adal
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/sha1"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/date"
|
||||
"github.com/Azure/go-autorest/version"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultRefresh = 5 * time.Minute
|
||||
tokenBaseDate = "1970-01-01T00:00:00Z"
|
||||
|
||||
// OAuthGrantTypeDeviceCode is the "grant_type" identifier used in device flow
|
||||
OAuthGrantTypeDeviceCode = "device_code"
|
||||
|
@ -28,27 +48,36 @@ const (
|
|||
// OAuthGrantTypeClientCredentials is the "grant_type" identifier used in credential flows
|
||||
OAuthGrantTypeClientCredentials = "client_credentials"
|
||||
|
||||
// OAuthGrantTypeUserPass is the "grant_type" identifier used in username and password auth flows
|
||||
OAuthGrantTypeUserPass = "password"
|
||||
|
||||
// OAuthGrantTypeRefreshToken is the "grant_type" identifier used in refresh token flows
|
||||
OAuthGrantTypeRefreshToken = "refresh_token"
|
||||
|
||||
// managedIdentitySettingsPath is the path to the MSI Extension settings file (to discover the endpoint)
|
||||
managedIdentitySettingsPath = "/var/lib/waagent/ManagedIdentity-Settings"
|
||||
// OAuthGrantTypeAuthorizationCode is the "grant_type" identifier used in authorization code flows
|
||||
OAuthGrantTypeAuthorizationCode = "authorization_code"
|
||||
|
||||
// metadataHeader is the header required by MSI extension
|
||||
metadataHeader = "Metadata"
|
||||
|
||||
// msiEndpoint is the well known endpoint for getting MSI authentications tokens
|
||||
msiEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token"
|
||||
|
||||
// the default number of attempts to refresh an MSI authentication token
|
||||
defaultMaxMSIRefreshAttempts = 5
|
||||
)
|
||||
|
||||
var expirationBase time.Time
|
||||
|
||||
func init() {
|
||||
expirationBase, _ = time.Parse(time.RFC3339, tokenBaseDate)
|
||||
}
|
||||
|
||||
// OAuthTokenProvider is an interface which should be implemented by an access token retriever
|
||||
type OAuthTokenProvider interface {
|
||||
OAuthToken() string
|
||||
}
|
||||
|
||||
// TokenRefreshError is an interface used by errors returned during token refresh.
|
||||
type TokenRefreshError interface {
|
||||
error
|
||||
Response() *http.Response
|
||||
}
|
||||
|
||||
// Refresher is an interface for token refresh functionality
|
||||
type Refresher interface {
|
||||
Refresh() error
|
||||
|
@ -56,6 +85,13 @@ type Refresher interface {
|
|||
EnsureFresh() error
|
||||
}
|
||||
|
||||
// RefresherWithContext is an interface for token refresh functionality
|
||||
type RefresherWithContext interface {
|
||||
RefreshWithContext(ctx context.Context) error
|
||||
RefreshExchangeWithContext(ctx context.Context, resource string) error
|
||||
EnsureFreshWithContext(ctx context.Context) error
|
||||
}
|
||||
|
||||
// TokenRefreshCallback is the type representing callbacks that will be called after
|
||||
// a successful token refresh
|
||||
type TokenRefreshCallback func(Token) error
|
||||
|
@ -73,13 +109,21 @@ type Token struct {
|
|||
Type string `json:"token_type"`
|
||||
}
|
||||
|
||||
// IsZero returns true if the token object is zero-initialized.
|
||||
func (t Token) IsZero() bool {
|
||||
return t == Token{}
|
||||
}
|
||||
|
||||
// Expires returns the time.Time when the Token expires.
|
||||
func (t Token) Expires() time.Time {
|
||||
s, err := strconv.Atoi(t.ExpiresOn)
|
||||
if err != nil {
|
||||
s = -3600
|
||||
}
|
||||
return expirationBase.Add(time.Duration(s) * time.Second).UTC()
|
||||
|
||||
expiration := date.NewUnixTimeFromSeconds(float64(s))
|
||||
|
||||
return time.Time(expiration).UTC()
|
||||
}
|
||||
|
||||
// IsExpired returns true if the Token is expired, false otherwise.
|
||||
|
@ -98,6 +142,12 @@ func (t *Token) OAuthToken() string {
|
|||
return t.AccessToken
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// ServicePrincipalNoSecret represents a secret type that contains no secret
|
||||
// meaning it is not valid for fetching a fresh token. This is used by Manual
|
||||
type ServicePrincipalNoSecret struct {
|
||||
|
@ -109,15 +159,19 @@ func (noSecret *ServicePrincipalNoSecret) SetAuthenticationValues(spt *ServicePr
|
|||
return fmt.Errorf("Manually created ServicePrincipalToken does not contain secret material to retrieve a new access token")
|
||||
}
|
||||
|
||||
// ServicePrincipalSecret is an interface that allows various secret mechanism to fill the form
|
||||
// that is submitted when acquiring an oAuth token.
|
||||
type ServicePrincipalSecret interface {
|
||||
SetAuthenticationValues(spt *ServicePrincipalToken, values *url.Values) error
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (noSecret ServicePrincipalNoSecret) MarshalJSON() ([]byte, error) {
|
||||
type tokenType struct {
|
||||
Type string `json:"type"`
|
||||
}
|
||||
return json.Marshal(tokenType{
|
||||
Type: "ServicePrincipalNoSecret",
|
||||
})
|
||||
}
|
||||
|
||||
// ServicePrincipalTokenSecret implements ServicePrincipalSecret for client_secret type authorization.
|
||||
type ServicePrincipalTokenSecret struct {
|
||||
ClientSecret string
|
||||
ClientSecret string `json:"value"`
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
|
@ -127,23 +181,24 @@ func (tokenSecret *ServicePrincipalTokenSecret) SetAuthenticationValues(spt *Ser
|
|||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (tokenSecret ServicePrincipalTokenSecret) MarshalJSON() ([]byte, error) {
|
||||
type tokenType struct {
|
||||
Type string `json:"type"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
return json.Marshal(tokenType{
|
||||
Type: "ServicePrincipalTokenSecret",
|
||||
Value: tokenSecret.ClientSecret,
|
||||
})
|
||||
}
|
||||
|
||||
// ServicePrincipalCertificateSecret implements ServicePrincipalSecret for generic RSA cert auth with signed JWTs.
|
||||
type ServicePrincipalCertificateSecret struct {
|
||||
Certificate *x509.Certificate
|
||||
PrivateKey *rsa.PrivateKey
|
||||
}
|
||||
|
||||
// ServicePrincipalMSISecret implements ServicePrincipalSecret for machines running the MSI Extension.
|
||||
type ServicePrincipalMSISecret struct {
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
// MSI extension requires the authority field to be set to the real tenant authority endpoint
|
||||
func (msiSecret *ServicePrincipalMSISecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||
v.Set("authority", spt.oauthConfig.AuthorityEndpoint.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
// SignJwt returns the JWT signed with the certificate's private key.
|
||||
func (secret *ServicePrincipalCertificateSecret) SignJwt(spt *ServicePrincipalToken) (string, error) {
|
||||
hasher := sha1.New()
|
||||
|
@ -164,9 +219,9 @@ func (secret *ServicePrincipalCertificateSecret) SignJwt(spt *ServicePrincipalTo
|
|||
token := jwt.New(jwt.SigningMethodRS256)
|
||||
token.Header["x5t"] = thumbprint
|
||||
token.Claims = jwt.MapClaims{
|
||||
"aud": spt.oauthConfig.TokenEndpoint.String(),
|
||||
"iss": spt.clientID,
|
||||
"sub": spt.clientID,
|
||||
"aud": spt.inner.OauthConfig.TokenEndpoint.String(),
|
||||
"iss": spt.inner.ClientID,
|
||||
"sub": spt.inner.ClientID,
|
||||
"jti": base64.URLEncoding.EncodeToString(jti),
|
||||
"nbf": time.Now().Unix(),
|
||||
"exp": time.Now().Add(time.Hour * 24).Unix(),
|
||||
|
@ -189,30 +244,184 @@ func (secret *ServicePrincipalCertificateSecret) SetAuthenticationValues(spt *Se
|
|||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (secret ServicePrincipalCertificateSecret) MarshalJSON() ([]byte, error) {
|
||||
return nil, errors.New("marshalling ServicePrincipalCertificateSecret is not supported")
|
||||
}
|
||||
|
||||
// ServicePrincipalMSISecret implements ServicePrincipalSecret for machines running the MSI Extension.
|
||||
type ServicePrincipalMSISecret struct {
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
func (msiSecret *ServicePrincipalMSISecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (msiSecret ServicePrincipalMSISecret) MarshalJSON() ([]byte, error) {
|
||||
return nil, errors.New("marshalling ServicePrincipalMSISecret is not supported")
|
||||
}
|
||||
|
||||
// ServicePrincipalUsernamePasswordSecret implements ServicePrincipalSecret for username and password auth.
|
||||
type ServicePrincipalUsernamePasswordSecret struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
func (secret *ServicePrincipalUsernamePasswordSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||
v.Set("username", secret.Username)
|
||||
v.Set("password", secret.Password)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (secret ServicePrincipalUsernamePasswordSecret) MarshalJSON() ([]byte, error) {
|
||||
type tokenType struct {
|
||||
Type string `json:"type"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
return json.Marshal(tokenType{
|
||||
Type: "ServicePrincipalUsernamePasswordSecret",
|
||||
Username: secret.Username,
|
||||
Password: secret.Password,
|
||||
})
|
||||
}
|
||||
|
||||
// ServicePrincipalAuthorizationCodeSecret implements ServicePrincipalSecret for authorization code auth.
|
||||
type ServicePrincipalAuthorizationCodeSecret struct {
|
||||
ClientSecret string `json:"value"`
|
||||
AuthorizationCode string `json:"authCode"`
|
||||
RedirectURI string `json:"redirect"`
|
||||
}
|
||||
|
||||
// SetAuthenticationValues is a method of the interface ServicePrincipalSecret.
|
||||
func (secret *ServicePrincipalAuthorizationCodeSecret) SetAuthenticationValues(spt *ServicePrincipalToken, v *url.Values) error {
|
||||
v.Set("code", secret.AuthorizationCode)
|
||||
v.Set("client_secret", secret.ClientSecret)
|
||||
v.Set("redirect_uri", secret.RedirectURI)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (secret ServicePrincipalAuthorizationCodeSecret) MarshalJSON() ([]byte, error) {
|
||||
type tokenType struct {
|
||||
Type string `json:"type"`
|
||||
Value string `json:"value"`
|
||||
AuthCode string `json:"authCode"`
|
||||
Redirect string `json:"redirect"`
|
||||
}
|
||||
return json.Marshal(tokenType{
|
||||
Type: "ServicePrincipalAuthorizationCodeSecret",
|
||||
Value: secret.ClientSecret,
|
||||
AuthCode: secret.AuthorizationCode,
|
||||
Redirect: secret.RedirectURI,
|
||||
})
|
||||
}
|
||||
|
||||
// ServicePrincipalToken encapsulates a Token created for a Service Principal.
|
||||
type ServicePrincipalToken struct {
|
||||
Token
|
||||
|
||||
secret ServicePrincipalSecret
|
||||
oauthConfig OAuthConfig
|
||||
clientID string
|
||||
resource string
|
||||
autoRefresh bool
|
||||
refreshWithin time.Duration
|
||||
sender Sender
|
||||
|
||||
inner servicePrincipalToken
|
||||
refreshLock *sync.RWMutex
|
||||
sender Sender
|
||||
refreshCallbacks []TokenRefreshCallback
|
||||
// MaxMSIRefreshAttempts is the maximum number of attempts to refresh an MSI token.
|
||||
MaxMSIRefreshAttempts int
|
||||
}
|
||||
|
||||
// MarshalTokenJSON returns the marshalled inner token.
|
||||
func (spt ServicePrincipalToken) MarshalTokenJSON() ([]byte, error) {
|
||||
return json.Marshal(spt.inner.Token)
|
||||
}
|
||||
|
||||
// SetRefreshCallbacks replaces any existing refresh callbacks with the specified callbacks.
|
||||
func (spt *ServicePrincipalToken) SetRefreshCallbacks(callbacks []TokenRefreshCallback) {
|
||||
spt.refreshCallbacks = callbacks
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (spt ServicePrincipalToken) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(spt.inner)
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (spt *ServicePrincipalToken) UnmarshalJSON(data []byte) error {
|
||||
// need to determine the token type
|
||||
raw := map[string]interface{}{}
|
||||
err := json.Unmarshal(data, &raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
secret := raw["secret"].(map[string]interface{})
|
||||
switch secret["type"] {
|
||||
case "ServicePrincipalNoSecret":
|
||||
spt.inner.Secret = &ServicePrincipalNoSecret{}
|
||||
case "ServicePrincipalTokenSecret":
|
||||
spt.inner.Secret = &ServicePrincipalTokenSecret{}
|
||||
case "ServicePrincipalCertificateSecret":
|
||||
return errors.New("unmarshalling ServicePrincipalCertificateSecret is not supported")
|
||||
case "ServicePrincipalMSISecret":
|
||||
return errors.New("unmarshalling ServicePrincipalMSISecret is not supported")
|
||||
case "ServicePrincipalUsernamePasswordSecret":
|
||||
spt.inner.Secret = &ServicePrincipalUsernamePasswordSecret{}
|
||||
case "ServicePrincipalAuthorizationCodeSecret":
|
||||
spt.inner.Secret = &ServicePrincipalAuthorizationCodeSecret{}
|
||||
default:
|
||||
return fmt.Errorf("unrecognized token type '%s'", secret["type"])
|
||||
}
|
||||
err = json.Unmarshal(data, &spt.inner)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
spt.refreshLock = &sync.RWMutex{}
|
||||
spt.sender = &http.Client{}
|
||||
return nil
|
||||
}
|
||||
|
||||
// internal type used for marshalling/unmarshalling
|
||||
type servicePrincipalToken struct {
|
||||
Token Token `json:"token"`
|
||||
Secret ServicePrincipalSecret `json:"secret"`
|
||||
OauthConfig OAuthConfig `json:"oauth"`
|
||||
ClientID string `json:"clientID"`
|
||||
Resource string `json:"resource"`
|
||||
AutoRefresh bool `json:"autoRefresh"`
|
||||
RefreshWithin time.Duration `json:"refreshWithin"`
|
||||
}
|
||||
|
||||
func validateOAuthConfig(oac OAuthConfig) error {
|
||||
if oac.IsZero() {
|
||||
return fmt.Errorf("parameter 'oauthConfig' cannot be zero-initialized")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenWithSecret create a ServicePrincipalToken using the supplied ServicePrincipalSecret implementation.
|
||||
func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, resource string, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(id, "id"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil {
|
||||
return nil, fmt.Errorf("parameter 'secret' cannot be nil")
|
||||
}
|
||||
spt := &ServicePrincipalToken{
|
||||
oauthConfig: oauthConfig,
|
||||
secret: secret,
|
||||
clientID: id,
|
||||
resource: resource,
|
||||
autoRefresh: true,
|
||||
refreshWithin: defaultRefresh,
|
||||
inner: servicePrincipalToken{
|
||||
OauthConfig: oauthConfig,
|
||||
Secret: secret,
|
||||
ClientID: id,
|
||||
Resource: resource,
|
||||
AutoRefresh: true,
|
||||
RefreshWithin: defaultRefresh,
|
||||
},
|
||||
refreshLock: &sync.RWMutex{},
|
||||
sender: &http.Client{},
|
||||
refreshCallbacks: callbacks,
|
||||
}
|
||||
|
@ -221,6 +430,18 @@ func NewServicePrincipalTokenWithSecret(oauthConfig OAuthConfig, id string, reso
|
|||
|
||||
// NewServicePrincipalTokenFromManualToken creates a ServicePrincipalToken using the supplied token
|
||||
func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID string, resource string, token Token, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if token.IsZero() {
|
||||
return nil, fmt.Errorf("parameter 'token' cannot be zero-initialized")
|
||||
}
|
||||
spt, err := NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
|
@ -231,7 +452,39 @@ func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID s
|
|||
return nil, err
|
||||
}
|
||||
|
||||
spt.Token = token
|
||||
spt.inner.Token = token
|
||||
|
||||
return spt, nil
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromManualTokenSecret creates a ServicePrincipalToken using the supplied token and secret
|
||||
func NewServicePrincipalTokenFromManualTokenSecret(oauthConfig OAuthConfig, clientID string, resource string, token Token, secret ServicePrincipalSecret, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if secret == nil {
|
||||
return nil, fmt.Errorf("parameter 'secret' cannot be nil")
|
||||
}
|
||||
if token.IsZero() {
|
||||
return nil, fmt.Errorf("parameter 'token' cannot be zero-initialized")
|
||||
}
|
||||
spt, err := NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
resource,
|
||||
secret,
|
||||
callbacks...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
spt.inner.Token = token
|
||||
|
||||
return spt, nil
|
||||
}
|
||||
|
@ -239,6 +492,18 @@ func NewServicePrincipalTokenFromManualToken(oauthConfig OAuthConfig, clientID s
|
|||
// NewServicePrincipalToken creates a ServicePrincipalToken from the supplied Service Principal
|
||||
// credentials scoped to the named resource.
|
||||
func NewServicePrincipalToken(oauthConfig OAuthConfig, clientID string, secret string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(secret, "secret"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
|
@ -250,8 +515,23 @@ func NewServicePrincipalToken(oauthConfig OAuthConfig, clientID string, secret s
|
|||
)
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromCertificate create a ServicePrincipalToken from the supplied pkcs12 bytes.
|
||||
// NewServicePrincipalTokenFromCertificate creates a ServicePrincipalToken from the supplied pkcs12 bytes.
|
||||
func NewServicePrincipalTokenFromCertificate(oauthConfig OAuthConfig, clientID string, certificate *x509.Certificate, privateKey *rsa.PrivateKey, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if certificate == nil {
|
||||
return nil, fmt.Errorf("parameter 'certificate' cannot be nil")
|
||||
}
|
||||
if privateKey == nil {
|
||||
return nil, fmt.Errorf("parameter 'privateKey' cannot be nil")
|
||||
}
|
||||
return NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
|
@ -264,57 +544,172 @@ func NewServicePrincipalTokenFromCertificate(oauthConfig OAuthConfig, clientID s
|
|||
)
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension.
|
||||
func NewServicePrincipalTokenFromMSI(oauthConfig OAuthConfig, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
return newServicePrincipalTokenFromMSI(oauthConfig, resource, managedIdentitySettingsPath, callbacks...)
|
||||
// NewServicePrincipalTokenFromUsernamePassword creates a ServicePrincipalToken from the username and password.
|
||||
func NewServicePrincipalTokenFromUsernamePassword(oauthConfig OAuthConfig, clientID string, username string, password string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(username, "username"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(password, "password"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
resource,
|
||||
&ServicePrincipalUsernamePasswordSecret{
|
||||
Username: username,
|
||||
Password: password,
|
||||
},
|
||||
callbacks...,
|
||||
)
|
||||
}
|
||||
|
||||
func newServicePrincipalTokenFromMSI(oauthConfig OAuthConfig, resource, settingsPath string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
// Read MSI settings
|
||||
bytes, err := ioutil.ReadFile(settingsPath)
|
||||
if err != nil {
|
||||
// NewServicePrincipalTokenFromAuthorizationCode creates a ServicePrincipalToken from the
|
||||
func NewServicePrincipalTokenFromAuthorizationCode(oauthConfig OAuthConfig, clientID string, clientSecret string, authorizationCode string, redirectURI string, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
|
||||
if err := validateOAuthConfig(oauthConfig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msiSettings := struct {
|
||||
URL string `json:"url"`
|
||||
}{}
|
||||
err = json.Unmarshal(bytes, &msiSettings)
|
||||
if err != nil {
|
||||
if err := validateStringParam(clientID, "clientID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(clientSecret, "clientSecret"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(authorizationCode, "authorizationCode"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(redirectURI, "redirectURI"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return NewServicePrincipalTokenWithSecret(
|
||||
oauthConfig,
|
||||
clientID,
|
||||
resource,
|
||||
&ServicePrincipalAuthorizationCodeSecret{
|
||||
ClientSecret: clientSecret,
|
||||
AuthorizationCode: authorizationCode,
|
||||
RedirectURI: redirectURI,
|
||||
},
|
||||
callbacks...,
|
||||
)
|
||||
}
|
||||
|
||||
// GetMSIVMEndpoint gets the MSI endpoint on Virtual Machines.
|
||||
func GetMSIVMEndpoint() (string, error) {
|
||||
return msiEndpoint, nil
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromMSI creates a ServicePrincipalToken via the MSI VM Extension.
|
||||
// It will use the system assigned identity when creating the token.
|
||||
func NewServicePrincipalTokenFromMSI(msiEndpoint, resource string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
return newServicePrincipalTokenFromMSI(msiEndpoint, resource, nil, callbacks...)
|
||||
}
|
||||
|
||||
// NewServicePrincipalTokenFromMSIWithUserAssignedID creates a ServicePrincipalToken via the MSI VM Extension.
|
||||
// It will use the specified user assigned identity when creating the token.
|
||||
func NewServicePrincipalTokenFromMSIWithUserAssignedID(msiEndpoint, resource string, userAssignedID string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
return newServicePrincipalTokenFromMSI(msiEndpoint, resource, &userAssignedID, callbacks...)
|
||||
}
|
||||
|
||||
func newServicePrincipalTokenFromMSI(msiEndpoint, resource string, userAssignedID *string, callbacks ...TokenRefreshCallback) (*ServicePrincipalToken, error) {
|
||||
if err := validateStringParam(msiEndpoint, "msiEndpoint"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := validateStringParam(resource, "resource"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if userAssignedID != nil {
|
||||
if err := validateStringParam(*userAssignedID, "userAssignedID"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// We set the oauth config token endpoint to be MSI's endpoint
|
||||
// We leave the authority as-is so MSI can POST it with the token request
|
||||
msiEndpointURL, err := url.Parse(msiSettings.URL)
|
||||
msiEndpointURL, err := url.Parse(msiEndpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
msiTokenEndpointURL, err := msiEndpointURL.Parse("/oauth2/token")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
v := url.Values{}
|
||||
v.Set("resource", resource)
|
||||
v.Set("api-version", "2018-02-01")
|
||||
if userAssignedID != nil {
|
||||
v.Set("client_id", *userAssignedID)
|
||||
}
|
||||
|
||||
oauthConfig.TokenEndpoint = *msiTokenEndpointURL
|
||||
msiEndpointURL.RawQuery = v.Encode()
|
||||
|
||||
spt := &ServicePrincipalToken{
|
||||
oauthConfig: oauthConfig,
|
||||
secret: &ServicePrincipalMSISecret{},
|
||||
resource: resource,
|
||||
autoRefresh: true,
|
||||
refreshWithin: defaultRefresh,
|
||||
sender: &http.Client{},
|
||||
refreshCallbacks: callbacks,
|
||||
inner: servicePrincipalToken{
|
||||
OauthConfig: OAuthConfig{
|
||||
TokenEndpoint: *msiEndpointURL,
|
||||
},
|
||||
Secret: &ServicePrincipalMSISecret{},
|
||||
Resource: resource,
|
||||
AutoRefresh: true,
|
||||
RefreshWithin: defaultRefresh,
|
||||
},
|
||||
refreshLock: &sync.RWMutex{},
|
||||
sender: &http.Client{},
|
||||
refreshCallbacks: callbacks,
|
||||
MaxMSIRefreshAttempts: defaultMaxMSIRefreshAttempts,
|
||||
}
|
||||
|
||||
if userAssignedID != nil {
|
||||
spt.inner.ClientID = *userAssignedID
|
||||
}
|
||||
|
||||
return spt, nil
|
||||
}
|
||||
|
||||
// internal type that implements TokenRefreshError
|
||||
type tokenRefreshError struct {
|
||||
message string
|
||||
resp *http.Response
|
||||
}
|
||||
|
||||
// Error implements the error interface which is part of the TokenRefreshError interface.
|
||||
func (tre tokenRefreshError) Error() string {
|
||||
return tre.message
|
||||
}
|
||||
|
||||
// Response implements the TokenRefreshError interface, it returns the raw HTTP response from the refresh operation.
|
||||
func (tre tokenRefreshError) Response() *http.Response {
|
||||
return tre.resp
|
||||
}
|
||||
|
||||
func newTokenRefreshError(message string, resp *http.Response) TokenRefreshError {
|
||||
return tokenRefreshError{message: message, resp: resp}
|
||||
}
|
||||
|
||||
// EnsureFresh will refresh the token if it will expire within the refresh window (as set by
|
||||
// RefreshWithin) and autoRefresh flag is on.
|
||||
// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use.
|
||||
func (spt *ServicePrincipalToken) EnsureFresh() error {
|
||||
if spt.autoRefresh && spt.WillExpireIn(spt.refreshWithin) {
|
||||
return spt.Refresh()
|
||||
return spt.EnsureFreshWithContext(context.Background())
|
||||
}
|
||||
|
||||
// EnsureFreshWithContext will refresh the token if it will expire within the refresh window (as set by
|
||||
// RefreshWithin) and autoRefresh flag is on. This method is safe for concurrent use.
|
||||
func (spt *ServicePrincipalToken) EnsureFreshWithContext(ctx context.Context) error {
|
||||
if spt.inner.AutoRefresh && spt.inner.Token.WillExpireIn(spt.inner.RefreshWithin) {
|
||||
// take the write lock then check to see if the token was already refreshed
|
||||
spt.refreshLock.Lock()
|
||||
defer spt.refreshLock.Unlock()
|
||||
if spt.inner.Token.WillExpireIn(spt.inner.RefreshWithin) {
|
||||
return spt.refreshInternal(ctx, spt.inner.Resource)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -323,7 +718,7 @@ func (spt *ServicePrincipalToken) EnsureFresh() error {
|
|||
func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error {
|
||||
if spt.refreshCallbacks != nil {
|
||||
for _, callback := range spt.refreshCallbacks {
|
||||
err := callback(spt.Token)
|
||||
err := callback(spt.inner.Token)
|
||||
if err != nil {
|
||||
return fmt.Errorf("adal: TokenRefreshCallback handler failed. Error = '%v'", err)
|
||||
}
|
||||
|
@ -333,53 +728,119 @@ func (spt *ServicePrincipalToken) InvokeRefreshCallbacks(token Token) error {
|
|||
}
|
||||
|
||||
// Refresh obtains a fresh token for the Service Principal.
|
||||
// This method is not safe for concurrent use and should be syncrhonized.
|
||||
func (spt *ServicePrincipalToken) Refresh() error {
|
||||
return spt.refreshInternal(spt.resource)
|
||||
return spt.RefreshWithContext(context.Background())
|
||||
}
|
||||
|
||||
// RefreshWithContext obtains a fresh token for the Service Principal.
|
||||
// This method is not safe for concurrent use and should be syncrhonized.
|
||||
func (spt *ServicePrincipalToken) RefreshWithContext(ctx context.Context) error {
|
||||
spt.refreshLock.Lock()
|
||||
defer spt.refreshLock.Unlock()
|
||||
return spt.refreshInternal(ctx, spt.inner.Resource)
|
||||
}
|
||||
|
||||
// RefreshExchange refreshes the token, but for a different resource.
|
||||
// This method is not safe for concurrent use and should be syncrhonized.
|
||||
func (spt *ServicePrincipalToken) RefreshExchange(resource string) error {
|
||||
return spt.refreshInternal(resource)
|
||||
return spt.RefreshExchangeWithContext(context.Background(), resource)
|
||||
}
|
||||
|
||||
func (spt *ServicePrincipalToken) refreshInternal(resource string) error {
|
||||
v := url.Values{}
|
||||
v.Set("client_id", spt.clientID)
|
||||
v.Set("resource", resource)
|
||||
// RefreshExchangeWithContext refreshes the token, but for a different resource.
|
||||
// This method is not safe for concurrent use and should be syncrhonized.
|
||||
func (spt *ServicePrincipalToken) RefreshExchangeWithContext(ctx context.Context, resource string) error {
|
||||
spt.refreshLock.Lock()
|
||||
defer spt.refreshLock.Unlock()
|
||||
return spt.refreshInternal(ctx, resource)
|
||||
}
|
||||
|
||||
if spt.RefreshToken != "" {
|
||||
v.Set("grant_type", OAuthGrantTypeRefreshToken)
|
||||
v.Set("refresh_token", spt.RefreshToken)
|
||||
} else {
|
||||
v.Set("grant_type", OAuthGrantTypeClientCredentials)
|
||||
err := spt.secret.SetAuthenticationValues(spt, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func (spt *ServicePrincipalToken) getGrantType() string {
|
||||
switch spt.inner.Secret.(type) {
|
||||
case *ServicePrincipalUsernamePasswordSecret:
|
||||
return OAuthGrantTypeUserPass
|
||||
case *ServicePrincipalAuthorizationCodeSecret:
|
||||
return OAuthGrantTypeAuthorizationCode
|
||||
default:
|
||||
return OAuthGrantTypeClientCredentials
|
||||
}
|
||||
}
|
||||
|
||||
s := v.Encode()
|
||||
body := ioutil.NopCloser(strings.NewReader(s))
|
||||
req, err := http.NewRequest(http.MethodPost, spt.oauthConfig.TokenEndpoint.String(), body)
|
||||
func isIMDS(u url.URL) bool {
|
||||
imds, err := url.Parse(msiEndpoint)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return u.Host == imds.Host && u.Path == imds.Path
|
||||
}
|
||||
|
||||
func (spt *ServicePrincipalToken) refreshInternal(ctx context.Context, resource string) error {
|
||||
req, err := http.NewRequest(http.MethodPost, spt.inner.OauthConfig.TokenEndpoint.String(), nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("adal: Failed to build the refresh request. Error = '%v'", err)
|
||||
}
|
||||
req.Header.Add("User-Agent", version.UserAgent())
|
||||
req = req.WithContext(ctx)
|
||||
if !isIMDS(spt.inner.OauthConfig.TokenEndpoint) {
|
||||
v := url.Values{}
|
||||
v.Set("client_id", spt.inner.ClientID)
|
||||
v.Set("resource", resource)
|
||||
|
||||
req.ContentLength = int64(len(s))
|
||||
req.Header.Set(contentType, mimeTypeFormPost)
|
||||
if _, ok := spt.secret.(*ServicePrincipalMSISecret); ok {
|
||||
if spt.inner.Token.RefreshToken != "" {
|
||||
v.Set("grant_type", OAuthGrantTypeRefreshToken)
|
||||
v.Set("refresh_token", spt.inner.Token.RefreshToken)
|
||||
// web apps must specify client_secret when refreshing tokens
|
||||
// see https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code#refreshing-the-access-tokens
|
||||
if spt.getGrantType() == OAuthGrantTypeAuthorizationCode {
|
||||
err := spt.inner.Secret.SetAuthenticationValues(spt, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
v.Set("grant_type", spt.getGrantType())
|
||||
err := spt.inner.Secret.SetAuthenticationValues(spt, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
s := v.Encode()
|
||||
body := ioutil.NopCloser(strings.NewReader(s))
|
||||
req.ContentLength = int64(len(s))
|
||||
req.Header.Set(contentType, mimeTypeFormPost)
|
||||
req.Body = body
|
||||
}
|
||||
|
||||
if _, ok := spt.inner.Secret.(*ServicePrincipalMSISecret); ok {
|
||||
req.Method = http.MethodGet
|
||||
req.Header.Set(metadataHeader, "true")
|
||||
}
|
||||
resp, err := spt.sender.Do(req)
|
||||
if err != nil {
|
||||
return fmt.Errorf("adal: Failed to execute the refresh request. Error = '%v'", err)
|
||||
|
||||
var resp *http.Response
|
||||
if isIMDS(spt.inner.OauthConfig.TokenEndpoint) {
|
||||
resp, err = retryForIMDS(spt.sender, req, spt.MaxMSIRefreshAttempts)
|
||||
} else {
|
||||
resp, err = spt.sender.Do(req)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("adal: Refresh request failed. Status Code = '%d'", resp.StatusCode)
|
||||
if err != nil {
|
||||
return newTokenRefreshError(fmt.Sprintf("adal: Failed to execute the refresh request. Error = '%v'", err), nil)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
rb, err := ioutil.ReadAll(resp.Body)
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
if err != nil {
|
||||
return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Failed reading response body: %v", resp.StatusCode, err), resp)
|
||||
}
|
||||
return newTokenRefreshError(fmt.Sprintf("adal: Refresh request failed. Status Code = '%d'. Response body: %s", resp.StatusCode, string(rb)), resp)
|
||||
}
|
||||
|
||||
// for the following error cases don't return a TokenRefreshError. the operation succeeded
|
||||
// but some transient failure happened during deserialization. by returning a generic error
|
||||
// the retry logic will kick in (we don't retry on TokenRefreshError).
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("adal: Failed to read a new service principal token during refresh. Error = '%v'", err)
|
||||
}
|
||||
|
@ -392,23 +853,116 @@ func (spt *ServicePrincipalToken) refreshInternal(resource string) error {
|
|||
return fmt.Errorf("adal: Failed to unmarshal the service principal token during refresh. Error = '%v' JSON = '%s'", err, string(rb))
|
||||
}
|
||||
|
||||
spt.Token = token
|
||||
spt.inner.Token = token
|
||||
|
||||
return spt.InvokeRefreshCallbacks(token)
|
||||
}
|
||||
|
||||
// retry logic specific to retrieving a token from the IMDS endpoint
|
||||
func retryForIMDS(sender Sender, req *http.Request, maxAttempts int) (resp *http.Response, err error) {
|
||||
// copied from client.go due to circular dependency
|
||||
retries := []int{
|
||||
http.StatusRequestTimeout, // 408
|
||||
http.StatusTooManyRequests, // 429
|
||||
http.StatusInternalServerError, // 500
|
||||
http.StatusBadGateway, // 502
|
||||
http.StatusServiceUnavailable, // 503
|
||||
http.StatusGatewayTimeout, // 504
|
||||
}
|
||||
// extra retry status codes specific to IMDS
|
||||
retries = append(retries,
|
||||
http.StatusNotFound,
|
||||
http.StatusGone,
|
||||
// all remaining 5xx
|
||||
http.StatusNotImplemented,
|
||||
http.StatusHTTPVersionNotSupported,
|
||||
http.StatusVariantAlsoNegotiates,
|
||||
http.StatusInsufficientStorage,
|
||||
http.StatusLoopDetected,
|
||||
http.StatusNotExtended,
|
||||
http.StatusNetworkAuthenticationRequired)
|
||||
|
||||
// see https://docs.microsoft.com/en-us/azure/active-directory/managed-service-identity/how-to-use-vm-token#retry-guidance
|
||||
|
||||
const maxDelay time.Duration = 60 * time.Second
|
||||
|
||||
attempt := 0
|
||||
delay := time.Duration(0)
|
||||
|
||||
for attempt < maxAttempts {
|
||||
resp, err = sender.Do(req)
|
||||
// retry on temporary network errors, e.g. transient network failures.
|
||||
// if we don't receive a response then assume we can't connect to the
|
||||
// endpoint so we're likely not running on an Azure VM so don't retry.
|
||||
if (err != nil && !isTemporaryNetworkError(err)) || resp == nil || resp.StatusCode == http.StatusOK || !containsInt(retries, resp.StatusCode) {
|
||||
return
|
||||
}
|
||||
|
||||
// perform exponential backoff with a cap.
|
||||
// must increment attempt before calculating delay.
|
||||
attempt++
|
||||
// the base value of 2 is the "delta backoff" as specified in the guidance doc
|
||||
delay += (time.Duration(math.Pow(2, float64(attempt))) * time.Second)
|
||||
if delay > maxDelay {
|
||||
delay = maxDelay
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(delay):
|
||||
// intentionally left blank
|
||||
case <-req.Context().Done():
|
||||
err = req.Context().Err()
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// returns true if the specified error is a temporary network error or false if it's not.
|
||||
// if the error doesn't implement the net.Error interface the return value is true.
|
||||
func isTemporaryNetworkError(err error) bool {
|
||||
if netErr, ok := err.(net.Error); !ok || (ok && netErr.Temporary()) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// returns true if slice ints contains the value n
|
||||
func containsInt(ints []int, n int) bool {
|
||||
for _, i := range ints {
|
||||
if i == n {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SetAutoRefresh enables or disables automatic refreshing of stale tokens.
|
||||
func (spt *ServicePrincipalToken) SetAutoRefresh(autoRefresh bool) {
|
||||
spt.autoRefresh = autoRefresh
|
||||
spt.inner.AutoRefresh = autoRefresh
|
||||
}
|
||||
|
||||
// SetRefreshWithin sets the interval within which if the token will expire, EnsureFresh will
|
||||
// refresh the token.
|
||||
func (spt *ServicePrincipalToken) SetRefreshWithin(d time.Duration) {
|
||||
spt.refreshWithin = d
|
||||
spt.inner.RefreshWithin = d
|
||||
return
|
||||
}
|
||||
|
||||
// SetSender sets the http.Client used when obtaining the Service Principal token. An
|
||||
// undecorated http.Client is used by default.
|
||||
func (spt *ServicePrincipalToken) SetSender(s Sender) { spt.sender = s }
|
||||
|
||||
// OAuthToken implements the OAuthTokenProvider interface. It returns the current access token.
|
||||
func (spt *ServicePrincipalToken) OAuthToken() string {
|
||||
spt.refreshLock.RLock()
|
||||
defer spt.refreshLock.RUnlock()
|
||||
return spt.inner.Token.OAuthToken()
|
||||
}
|
||||
|
||||
// Token returns a copy of the current token.
|
||||
func (spt *ServicePrincipalToken) Token() Token {
|
||||
spt.refreshLock.RLock()
|
||||
defer spt.refreshLock.RUnlock()
|
||||
return spt.inner.Token
|
||||
}
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
@ -10,9 +24,12 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
bearerChallengeHeader = "Www-Authenticate"
|
||||
bearer = "Bearer"
|
||||
tenantID = "tenantID"
|
||||
bearerChallengeHeader = "Www-Authenticate"
|
||||
bearer = "Bearer"
|
||||
tenantID = "tenantID"
|
||||
apiKeyAuthorizerHeader = "Ocp-Apim-Subscription-Key"
|
||||
bingAPISdkHeader = "X-BingApis-SDK-Client"
|
||||
golangBingAPISdkHeaderValue = "Go-SDK"
|
||||
)
|
||||
|
||||
// Authorizer is the interface that provides a PrepareDecorator used to supply request
|
||||
|
@ -30,6 +47,53 @@ func (na NullAuthorizer) WithAuthorization() PrepareDecorator {
|
|||
return WithNothing()
|
||||
}
|
||||
|
||||
// APIKeyAuthorizer implements API Key authorization.
|
||||
type APIKeyAuthorizer struct {
|
||||
headers map[string]interface{}
|
||||
queryParameters map[string]interface{}
|
||||
}
|
||||
|
||||
// NewAPIKeyAuthorizerWithHeaders creates an ApiKeyAuthorizer with headers.
|
||||
func NewAPIKeyAuthorizerWithHeaders(headers map[string]interface{}) *APIKeyAuthorizer {
|
||||
return NewAPIKeyAuthorizer(headers, nil)
|
||||
}
|
||||
|
||||
// NewAPIKeyAuthorizerWithQueryParameters creates an ApiKeyAuthorizer with query parameters.
|
||||
func NewAPIKeyAuthorizerWithQueryParameters(queryParameters map[string]interface{}) *APIKeyAuthorizer {
|
||||
return NewAPIKeyAuthorizer(nil, queryParameters)
|
||||
}
|
||||
|
||||
// NewAPIKeyAuthorizer creates an ApiKeyAuthorizer with headers.
|
||||
func NewAPIKeyAuthorizer(headers map[string]interface{}, queryParameters map[string]interface{}) *APIKeyAuthorizer {
|
||||
return &APIKeyAuthorizer{headers: headers, queryParameters: queryParameters}
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP headers and Query Paramaters
|
||||
func (aka *APIKeyAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return DecoratePreparer(p, WithHeaders(aka.headers), WithQueryParameters(aka.queryParameters))
|
||||
}
|
||||
}
|
||||
|
||||
// CognitiveServicesAuthorizer implements authorization for Cognitive Services.
|
||||
type CognitiveServicesAuthorizer struct {
|
||||
subscriptionKey string
|
||||
}
|
||||
|
||||
// NewCognitiveServicesAuthorizer is
|
||||
func NewCognitiveServicesAuthorizer(subscriptionKey string) *CognitiveServicesAuthorizer {
|
||||
return &CognitiveServicesAuthorizer{subscriptionKey: subscriptionKey}
|
||||
}
|
||||
|
||||
// WithAuthorization is
|
||||
func (csa *CognitiveServicesAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
headers := make(map[string]interface{})
|
||||
headers[apiKeyAuthorizerHeader] = csa.subscriptionKey
|
||||
headers[bingAPISdkHeader] = golangBingAPISdkHeaderValue
|
||||
|
||||
return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
|
||||
}
|
||||
|
||||
// BearerAuthorizer implements the bearer authorization
|
||||
type BearerAuthorizer struct {
|
||||
tokenProvider adal.OAuthTokenProvider
|
||||
|
@ -40,10 +104,6 @@ func NewBearerAuthorizer(tp adal.OAuthTokenProvider) *BearerAuthorizer {
|
|||
return &BearerAuthorizer{tokenProvider: tp}
|
||||
}
|
||||
|
||||
func (ba *BearerAuthorizer) withBearerAuthorization() PrepareDecorator {
|
||||
return WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", ba.tokenProvider.OAuthToken()))
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
|
||||
// value is "Bearer " followed by the token.
|
||||
//
|
||||
|
@ -51,15 +111,25 @@ func (ba *BearerAuthorizer) withBearerAuthorization() PrepareDecorator {
|
|||
func (ba *BearerAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
refresher, ok := ba.tokenProvider.(adal.Refresher)
|
||||
if ok {
|
||||
err := refresher.EnsureFresh()
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
// the ordering is important here, prefer RefresherWithContext if available
|
||||
if refresher, ok := ba.tokenProvider.(adal.RefresherWithContext); ok {
|
||||
err = refresher.EnsureFreshWithContext(r.Context())
|
||||
} else if refresher, ok := ba.tokenProvider.(adal.Refresher); ok {
|
||||
err = refresher.EnsureFresh()
|
||||
}
|
||||
if err != nil {
|
||||
return r, NewErrorWithError(err, "azure.BearerAuthorizer", "WithAuthorization", nil,
|
||||
var resp *http.Response
|
||||
if tokError, ok := err.(adal.TokenRefreshError); ok {
|
||||
resp = tokError.Response()
|
||||
}
|
||||
return r, NewErrorWithError(err, "azure.BearerAuthorizer", "WithAuthorization", resp,
|
||||
"Failed to refresh the Token for request to %s", r.URL)
|
||||
}
|
||||
return Prepare(r, WithHeader(headerAuthorization, fmt.Sprintf("Bearer %s", ba.tokenProvider.OAuthToken())))
|
||||
}
|
||||
return (ba.withBearerAuthorization()(p)).Prepare(r)
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -89,25 +159,28 @@ func NewBearerAuthorizerCallback(sender Sender, callback BearerAuthorizerCallbac
|
|||
func (bacb *BearerAuthorizerCallback) WithAuthorization() PrepareDecorator {
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
// make a copy of the request and remove the body as it's not
|
||||
// required and avoids us having to create a copy of it.
|
||||
rCopy := *r
|
||||
removeRequestBody(&rCopy)
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
// make a copy of the request and remove the body as it's not
|
||||
// required and avoids us having to create a copy of it.
|
||||
rCopy := *r
|
||||
removeRequestBody(&rCopy)
|
||||
|
||||
resp, err := bacb.sender.Do(&rCopy)
|
||||
if err == nil && resp.StatusCode == 401 {
|
||||
defer resp.Body.Close()
|
||||
if hasBearerChallenge(resp) {
|
||||
bc, err := newBearerChallenge(resp)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
if bacb.callback != nil {
|
||||
ba, err := bacb.callback(bc.values[tenantID], bc.values["resource"])
|
||||
resp, err := bacb.sender.Do(&rCopy)
|
||||
if err == nil && resp.StatusCode == 401 {
|
||||
defer resp.Body.Close()
|
||||
if hasBearerChallenge(resp) {
|
||||
bc, err := newBearerChallenge(resp)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
return ba.WithAuthorization()(p).Prepare(r)
|
||||
if bacb.callback != nil {
|
||||
ba, err := bacb.callback(bc.values[tenantID], bc.values["resource"])
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
return Prepare(r, ba.WithAuthorization())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -165,3 +238,22 @@ func newBearerChallenge(resp *http.Response) (bc bearerChallenge, err error) {
|
|||
|
||||
return bc, err
|
||||
}
|
||||
|
||||
// EventGridKeyAuthorizer implements authorization for event grid using key authentication.
|
||||
type EventGridKeyAuthorizer struct {
|
||||
topicKey string
|
||||
}
|
||||
|
||||
// NewEventGridKeyAuthorizer creates a new EventGridKeyAuthorizer
|
||||
// with the specified topic key.
|
||||
func NewEventGridKeyAuthorizer(topicKey string) EventGridKeyAuthorizer {
|
||||
return EventGridKeyAuthorizer{topicKey: topicKey}
|
||||
}
|
||||
|
||||
// WithAuthorization returns a PrepareDecorator that adds the aeg-sas-key authentication header.
|
||||
func (egta EventGridKeyAuthorizer) WithAuthorization() PrepareDecorator {
|
||||
headers := map[string]interface{}{
|
||||
"aeg-sas-key": egta.topicKey,
|
||||
}
|
||||
return NewAPIKeyAuthorizerWithHeaders(headers).WithAuthorization()
|
||||
}
|
||||
|
|
|
@ -57,7 +57,22 @@ generated clients, see the Client described below.
|
|||
*/
|
||||
package autorest
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
@ -73,6 +88,9 @@ const (
|
|||
// ResponseHasStatusCode returns true if the status code in the HTTP Response is in the passed set
|
||||
// and false otherwise.
|
||||
func ResponseHasStatusCode(resp *http.Response, codes ...int) bool {
|
||||
if resp == nil {
|
||||
return false
|
||||
}
|
||||
return containsInt(codes, resp.StatusCode)
|
||||
}
|
||||
|
||||
|
@ -113,3 +131,20 @@ func NewPollingRequest(resp *http.Response, cancel <-chan struct{}) (*http.Reque
|
|||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// NewPollingRequestWithContext allocates and returns a new http.Request with the specified context to poll for the passed response.
|
||||
func NewPollingRequestWithContext(ctx context.Context, resp *http.Response) (*http.Request, error) {
|
||||
location := GetLocation(resp)
|
||||
if location == "" {
|
||||
return nil, NewErrorWithResponse("autorest", "NewPollingRequestWithContext", resp, "Location header missing from response that requires polling")
|
||||
}
|
||||
|
||||
req, err := Prepare((&http.Request{}).WithContext(ctx),
|
||||
AsGet(),
|
||||
WithBaseURL(location))
|
||||
if err != nil {
|
||||
return nil, NewErrorWithError(err, "autorest", "NewPollingRequestWithContext", nil, "Failure creating poll request to %s", location)
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,16 +1,29 @@
|
|||
/*
|
||||
Package azure provides Azure-specific implementations used with AutoRest.
|
||||
|
||||
See the included examples for more detail.
|
||||
*/
|
||||
// Package azure provides Azure-specific implementations used with AutoRest.
|
||||
// See the included examples for more detail.
|
||||
package azure
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
)
|
||||
|
@ -29,21 +42,100 @@ const (
|
|||
)
|
||||
|
||||
// ServiceError encapsulates the error response from an Azure service.
|
||||
// It adhears to the OData v4 specification for error responses.
|
||||
type ServiceError struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Details *[]interface{} `json:"details"`
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Target *string `json:"target"`
|
||||
Details []map[string]interface{} `json:"details"`
|
||||
InnerError map[string]interface{} `json:"innererror"`
|
||||
AdditionalInfo []map[string]interface{} `json:"additionalInfo"`
|
||||
}
|
||||
|
||||
func (se ServiceError) Error() string {
|
||||
if se.Details != nil {
|
||||
d, err := json.Marshal(*(se.Details))
|
||||
if err != nil {
|
||||
return fmt.Sprintf("Code=%q Message=%q Details=%v", se.Code, se.Message, *se.Details)
|
||||
}
|
||||
return fmt.Sprintf("Code=%q Message=%q Details=%v", se.Code, se.Message, string(d))
|
||||
result := fmt.Sprintf("Code=%q Message=%q", se.Code, se.Message)
|
||||
|
||||
if se.Target != nil {
|
||||
result += fmt.Sprintf(" Target=%q", *se.Target)
|
||||
}
|
||||
return fmt.Sprintf("Code=%q Message=%q", se.Code, se.Message)
|
||||
|
||||
if se.Details != nil {
|
||||
d, err := json.Marshal(se.Details)
|
||||
if err != nil {
|
||||
result += fmt.Sprintf(" Details=%v", se.Details)
|
||||
}
|
||||
result += fmt.Sprintf(" Details=%v", string(d))
|
||||
}
|
||||
|
||||
if se.InnerError != nil {
|
||||
d, err := json.Marshal(se.InnerError)
|
||||
if err != nil {
|
||||
result += fmt.Sprintf(" InnerError=%v", se.InnerError)
|
||||
}
|
||||
result += fmt.Sprintf(" InnerError=%v", string(d))
|
||||
}
|
||||
|
||||
if se.AdditionalInfo != nil {
|
||||
d, err := json.Marshal(se.AdditionalInfo)
|
||||
if err != nil {
|
||||
result += fmt.Sprintf(" AdditionalInfo=%v", se.AdditionalInfo)
|
||||
}
|
||||
result += fmt.Sprintf(" AdditionalInfo=%v", string(d))
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface for the ServiceError type.
|
||||
func (se *ServiceError) UnmarshalJSON(b []byte) error {
|
||||
// per the OData v4 spec the details field must be an array of JSON objects.
|
||||
// unfortunately not all services adhear to the spec and just return a single
|
||||
// object instead of an array with one object. so we have to perform some
|
||||
// shenanigans to accommodate both cases.
|
||||
// http://docs.oasis-open.org/odata/odata-json-format/v4.0/os/odata-json-format-v4.0-os.html#_Toc372793091
|
||||
|
||||
type serviceError1 struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Target *string `json:"target"`
|
||||
Details []map[string]interface{} `json:"details"`
|
||||
InnerError map[string]interface{} `json:"innererror"`
|
||||
AdditionalInfo []map[string]interface{} `json:"additionalInfo"`
|
||||
}
|
||||
|
||||
type serviceError2 struct {
|
||||
Code string `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Target *string `json:"target"`
|
||||
Details map[string]interface{} `json:"details"`
|
||||
InnerError map[string]interface{} `json:"innererror"`
|
||||
AdditionalInfo []map[string]interface{} `json:"additionalInfo"`
|
||||
}
|
||||
|
||||
se1 := serviceError1{}
|
||||
err := json.Unmarshal(b, &se1)
|
||||
if err == nil {
|
||||
se.populate(se1.Code, se1.Message, se1.Target, se1.Details, se1.InnerError, se1.AdditionalInfo)
|
||||
return nil
|
||||
}
|
||||
|
||||
se2 := serviceError2{}
|
||||
err = json.Unmarshal(b, &se2)
|
||||
if err == nil {
|
||||
se.populate(se2.Code, se2.Message, se2.Target, nil, se2.InnerError, se2.AdditionalInfo)
|
||||
se.Details = append(se.Details, se2.Details)
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (se *ServiceError) populate(code, message string, target *string, details []map[string]interface{}, inner map[string]interface{}, additional []map[string]interface{}) {
|
||||
se.Code = code
|
||||
se.Message = message
|
||||
se.Target = target
|
||||
se.Details = details
|
||||
se.InnerError = inner
|
||||
se.AdditionalInfo = additional
|
||||
}
|
||||
|
||||
// RequestError describes an error response returned by Azure service.
|
||||
|
@ -69,6 +161,41 @@ func IsAzureError(e error) bool {
|
|||
return ok
|
||||
}
|
||||
|
||||
// Resource contains details about an Azure resource.
|
||||
type Resource struct {
|
||||
SubscriptionID string
|
||||
ResourceGroup string
|
||||
Provider string
|
||||
ResourceType string
|
||||
ResourceName string
|
||||
}
|
||||
|
||||
// ParseResourceID parses a resource ID into a ResourceDetails struct.
|
||||
// See https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-template-functions-resource#return-value-4.
|
||||
func ParseResourceID(resourceID string) (Resource, error) {
|
||||
|
||||
const resourceIDPatternText = `(?i)subscriptions/(.+)/resourceGroups/(.+)/providers/(.+?)/(.+?)/(.+)`
|
||||
resourceIDPattern := regexp.MustCompile(resourceIDPatternText)
|
||||
match := resourceIDPattern.FindStringSubmatch(resourceID)
|
||||
|
||||
if len(match) == 0 {
|
||||
return Resource{}, fmt.Errorf("parsing failed for %s. Invalid resource Id format", resourceID)
|
||||
}
|
||||
|
||||
v := strings.Split(match[5], "/")
|
||||
resourceName := v[len(v)-1]
|
||||
|
||||
result := Resource{
|
||||
SubscriptionID: match[1],
|
||||
ResourceGroup: match[2],
|
||||
Provider: match[3],
|
||||
ResourceType: match[4],
|
||||
ResourceName: resourceName,
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// NewErrorWithError creates a new Error conforming object from the
|
||||
// passed packageType, method, statusCode of the given resp (UndefinedStatusCode
|
||||
// if resp is nil), message, and original error. message is treated as a format
|
||||
|
@ -164,10 +291,29 @@ func WithErrorUnlessStatusCode(codes ...int) autorest.RespondDecorator {
|
|||
resp.Body = ioutil.NopCloser(&b)
|
||||
if decodeErr != nil {
|
||||
return fmt.Errorf("autorest/azure: error response cannot be parsed: %q error: %v", b.String(), decodeErr)
|
||||
} else if e.ServiceError == nil {
|
||||
e.ServiceError = &ServiceError{Code: "Unknown", Message: "Unknown service error"}
|
||||
}
|
||||
|
||||
if e.ServiceError == nil {
|
||||
// Check if error is unwrapped ServiceError
|
||||
if err := json.Unmarshal(b.Bytes(), &e.ServiceError); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if e.ServiceError.Message == "" {
|
||||
// if we're here it means the returned error wasn't OData v4 compliant.
|
||||
// try to unmarshal the body as raw JSON in hopes of getting something.
|
||||
rawBody := map[string]interface{}{}
|
||||
if err := json.Unmarshal(b.Bytes(), &rawBody); err != nil {
|
||||
return err
|
||||
}
|
||||
e.ServiceError = &ServiceError{
|
||||
Code: "Unknown",
|
||||
Message: "Unknown service error",
|
||||
}
|
||||
if len(rawBody) > 0 {
|
||||
e.ServiceError.Details = []map[string]interface{}{rawBody}
|
||||
}
|
||||
}
|
||||
e.Response = resp
|
||||
e.RequestID = ExtractRequestID(resp)
|
||||
if e.StatusCode == nil {
|
||||
e.StatusCode = resp.StatusCode
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
package cli
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/dimchansky/utfbom"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
// Profile represents a Profile from the Azure CLI
|
||||
type Profile struct {
|
||||
InstallationID string `json:"installationId"`
|
||||
Subscriptions []Subscription `json:"subscriptions"`
|
||||
}
|
||||
|
||||
// Subscription represents a Subscription from the Azure CLI
|
||||
type Subscription struct {
|
||||
EnvironmentName string `json:"environmentName"`
|
||||
ID string `json:"id"`
|
||||
IsDefault bool `json:"isDefault"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
TenantID string `json:"tenantId"`
|
||||
User *User `json:"user"`
|
||||
}
|
||||
|
||||
// User represents a User from the Azure CLI
|
||||
type User struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// ProfilePath returns the path where the Azure Profile is stored from the Azure CLI
|
||||
func ProfilePath() (string, error) {
|
||||
return homedir.Expand("~/.azure/azureProfile.json")
|
||||
}
|
||||
|
||||
// LoadProfile restores a Profile object from a file located at 'path'.
|
||||
func LoadProfile(path string) (result Profile, err error) {
|
||||
var contents []byte
|
||||
contents, err = ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("failed to open file (%s) while loading token: %v", path, err)
|
||||
return
|
||||
}
|
||||
reader := utfbom.SkipOnly(bytes.NewReader(contents))
|
||||
|
||||
dec := json.NewDecoder(reader)
|
||||
if err = dec.Decode(&result); err != nil {
|
||||
err = fmt.Errorf("failed to decode contents of file (%s) into a Profile representation: %v", path, err)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
package cli
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
"github.com/Azure/go-autorest/autorest/date"
|
||||
"github.com/mitchellh/go-homedir"
|
||||
)
|
||||
|
||||
// Token represents an AccessToken from the Azure CLI
|
||||
type Token struct {
|
||||
AccessToken string `json:"accessToken"`
|
||||
Authority string `json:"_authority"`
|
||||
ClientID string `json:"_clientId"`
|
||||
ExpiresOn string `json:"expiresOn"`
|
||||
IdentityProvider string `json:"identityProvider"`
|
||||
IsMRRT bool `json:"isMRRT"`
|
||||
RefreshToken string `json:"refreshToken"`
|
||||
Resource string `json:"resource"`
|
||||
TokenType string `json:"tokenType"`
|
||||
UserID string `json:"userId"`
|
||||
}
|
||||
|
||||
// ToADALToken converts an Azure CLI `Token`` to an `adal.Token``
|
||||
func (t Token) ToADALToken() (converted adal.Token, err error) {
|
||||
tokenExpirationDate, err := ParseExpirationDate(t.ExpiresOn)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Error parsing Token Expiration Date %q: %+v", t.ExpiresOn, err)
|
||||
return
|
||||
}
|
||||
|
||||
difference := tokenExpirationDate.Sub(date.UnixEpoch())
|
||||
|
||||
converted = adal.Token{
|
||||
AccessToken: t.AccessToken,
|
||||
Type: t.TokenType,
|
||||
ExpiresIn: "3600",
|
||||
ExpiresOn: strconv.Itoa(int(difference.Seconds())),
|
||||
RefreshToken: t.RefreshToken,
|
||||
Resource: t.Resource,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// AccessTokensPath returns the path where access tokens are stored from the Azure CLI
|
||||
// TODO(#199): add unit test.
|
||||
func AccessTokensPath() (string, error) {
|
||||
// Azure-CLI allows user to customize the path of access tokens thorugh environment variable.
|
||||
var accessTokenPath = os.Getenv("AZURE_ACCESS_TOKEN_FILE")
|
||||
var err error
|
||||
|
||||
// Fallback logic to default path on non-cloud-shell environment.
|
||||
// TODO(#200): remove the dependency on hard-coding path.
|
||||
if accessTokenPath == "" {
|
||||
accessTokenPath, err = homedir.Expand("~/.azure/accessTokens.json")
|
||||
}
|
||||
|
||||
return accessTokenPath, err
|
||||
}
|
||||
|
||||
// ParseExpirationDate parses either a Azure CLI or CloudShell date into a time object
|
||||
func ParseExpirationDate(input string) (*time.Time, error) {
|
||||
// CloudShell (and potentially the Azure CLI in future)
|
||||
expirationDate, cloudShellErr := time.Parse(time.RFC3339, input)
|
||||
if cloudShellErr != nil {
|
||||
// Azure CLI (Python) e.g. 2017-08-31 19:48:57.998857 (plus the local timezone)
|
||||
const cliFormat = "2006-01-02 15:04:05.999999"
|
||||
expirationDate, cliErr := time.ParseInLocation(cliFormat, input, time.Local)
|
||||
if cliErr == nil {
|
||||
return &expirationDate, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("Error parsing expiration date %q.\n\nCloudShell Error: \n%+v\n\nCLI Error:\n%+v", input, cloudShellErr, cliErr)
|
||||
}
|
||||
|
||||
return &expirationDate, nil
|
||||
}
|
||||
|
||||
// LoadTokens restores a set of Token objects from a file located at 'path'.
|
||||
func LoadTokens(path string) ([]Token, error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open file (%s) while loading token: %v", path, err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
var tokens []Token
|
||||
|
||||
dec := json.NewDecoder(file)
|
||||
if err = dec.Decode(&tokens); err != nil {
|
||||
return nil, fmt.Errorf("failed to decode contents of file (%s) into a `cli.Token` representation: %v", path, err)
|
||||
}
|
||||
|
||||
return tokens, nil
|
||||
}
|
|
@ -1,10 +1,31 @@
|
|||
package azure
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// EnvironmentFilepathName captures the name of the environment variable containing the path to the file
|
||||
// to be used while populating the Azure Environment.
|
||||
const EnvironmentFilepathName = "AZURE_ENVIRONMENT_FILEPATH"
|
||||
|
||||
var environments = map[string]Environment{
|
||||
"AZURECHINACLOUD": ChinaCloud,
|
||||
"AZUREGERMANCLOUD": GermanCloud,
|
||||
|
@ -23,6 +44,8 @@ type Environment struct {
|
|||
GalleryEndpoint string `json:"galleryEndpoint"`
|
||||
KeyVaultEndpoint string `json:"keyVaultEndpoint"`
|
||||
GraphEndpoint string `json:"graphEndpoint"`
|
||||
ServiceBusEndpoint string `json:"serviceBusEndpoint"`
|
||||
BatchManagementEndpoint string `json:"batchManagementEndpoint"`
|
||||
StorageEndpointSuffix string `json:"storageEndpointSuffix"`
|
||||
SQLDatabaseDNSSuffix string `json:"sqlDatabaseDNSSuffix"`
|
||||
TrafficManagerDNSSuffix string `json:"trafficManagerDNSSuffix"`
|
||||
|
@ -31,6 +54,7 @@ type Environment struct {
|
|||
ServiceManagementVMDNSSuffix string `json:"serviceManagementVMDNSSuffix"`
|
||||
ResourceManagerVMDNSSuffix string `json:"resourceManagerVMDNSSuffix"`
|
||||
ContainerRegistryDNSSuffix string `json:"containerRegistryDNSSuffix"`
|
||||
TokenAudience string `json:"tokenAudience"`
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -45,14 +69,17 @@ var (
|
|||
GalleryEndpoint: "https://gallery.azure.com/",
|
||||
KeyVaultEndpoint: "https://vault.azure.net/",
|
||||
GraphEndpoint: "https://graph.windows.net/",
|
||||
ServiceBusEndpoint: "https://servicebus.windows.net/",
|
||||
BatchManagementEndpoint: "https://batch.core.windows.net/",
|
||||
StorageEndpointSuffix: "core.windows.net",
|
||||
SQLDatabaseDNSSuffix: "database.windows.net",
|
||||
TrafficManagerDNSSuffix: "trafficmanager.net",
|
||||
KeyVaultDNSSuffix: "vault.azure.net",
|
||||
ServiceBusEndpointSuffix: "servicebus.azure.com",
|
||||
ServiceBusEndpointSuffix: "servicebus.windows.net",
|
||||
ServiceManagementVMDNSSuffix: "cloudapp.net",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.azure.com",
|
||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
||||
TokenAudience: "https://management.azure.com/",
|
||||
}
|
||||
|
||||
// USGovernmentCloud is the cloud environment for the US Government
|
||||
|
@ -62,10 +89,12 @@ var (
|
|||
PublishSettingsURL: "https://manage.windowsazure.us/publishsettings/index",
|
||||
ServiceManagementEndpoint: "https://management.core.usgovcloudapi.net/",
|
||||
ResourceManagerEndpoint: "https://management.usgovcloudapi.net/",
|
||||
ActiveDirectoryEndpoint: "https://login.microsoftonline.com/",
|
||||
ActiveDirectoryEndpoint: "https://login.microsoftonline.us/",
|
||||
GalleryEndpoint: "https://gallery.usgovcloudapi.net/",
|
||||
KeyVaultEndpoint: "https://vault.usgovcloudapi.net/",
|
||||
GraphEndpoint: "https://graph.usgovcloudapi.net/",
|
||||
GraphEndpoint: "https://graph.windows.net/",
|
||||
ServiceBusEndpoint: "https://servicebus.usgovcloudapi.net/",
|
||||
BatchManagementEndpoint: "https://batch.core.usgovcloudapi.net/",
|
||||
StorageEndpointSuffix: "core.usgovcloudapi.net",
|
||||
SQLDatabaseDNSSuffix: "database.usgovcloudapi.net",
|
||||
TrafficManagerDNSSuffix: "usgovtrafficmanager.net",
|
||||
|
@ -74,6 +103,7 @@ var (
|
|||
ServiceManagementVMDNSSuffix: "usgovcloudapp.net",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.windowsazure.us",
|
||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
||||
TokenAudience: "https://management.usgovcloudapi.net/",
|
||||
}
|
||||
|
||||
// ChinaCloud is the cloud environment operated in China
|
||||
|
@ -87,14 +117,17 @@ var (
|
|||
GalleryEndpoint: "https://gallery.chinacloudapi.cn/",
|
||||
KeyVaultEndpoint: "https://vault.azure.cn/",
|
||||
GraphEndpoint: "https://graph.chinacloudapi.cn/",
|
||||
ServiceBusEndpoint: "https://servicebus.chinacloudapi.cn/",
|
||||
BatchManagementEndpoint: "https://batch.chinacloudapi.cn/",
|
||||
StorageEndpointSuffix: "core.chinacloudapi.cn",
|
||||
SQLDatabaseDNSSuffix: "database.chinacloudapi.cn",
|
||||
TrafficManagerDNSSuffix: "trafficmanager.cn",
|
||||
KeyVaultDNSSuffix: "vault.azure.cn",
|
||||
ServiceBusEndpointSuffix: "servicebus.chinacloudapi.net",
|
||||
ServiceBusEndpointSuffix: "servicebus.chinacloudapi.cn",
|
||||
ServiceManagementVMDNSSuffix: "chinacloudapp.cn",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.azure.cn",
|
||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
||||
TokenAudience: "https://management.chinacloudapi.cn/",
|
||||
}
|
||||
|
||||
// GermanCloud is the cloud environment operated in Germany
|
||||
|
@ -108,6 +141,8 @@ var (
|
|||
GalleryEndpoint: "https://gallery.cloudapi.de/",
|
||||
KeyVaultEndpoint: "https://vault.microsoftazure.de/",
|
||||
GraphEndpoint: "https://graph.cloudapi.de/",
|
||||
ServiceBusEndpoint: "https://servicebus.cloudapi.de/",
|
||||
BatchManagementEndpoint: "https://batch.cloudapi.de/",
|
||||
StorageEndpointSuffix: "core.cloudapi.de",
|
||||
SQLDatabaseDNSSuffix: "database.cloudapi.de",
|
||||
TrafficManagerDNSSuffix: "azuretrafficmanager.de",
|
||||
|
@ -116,15 +151,41 @@ var (
|
|||
ServiceManagementVMDNSSuffix: "azurecloudapp.de",
|
||||
ResourceManagerVMDNSSuffix: "cloudapp.microsoftazure.de",
|
||||
ContainerRegistryDNSSuffix: "azurecr.io",
|
||||
TokenAudience: "https://management.microsoftazure.de/",
|
||||
}
|
||||
)
|
||||
|
||||
// EnvironmentFromName returns an Environment based on the common name specified
|
||||
// EnvironmentFromName returns an Environment based on the common name specified.
|
||||
func EnvironmentFromName(name string) (Environment, error) {
|
||||
// IMPORTANT
|
||||
// As per @radhikagupta5:
|
||||
// This is technical debt, fundamentally here because Kubernetes is not currently accepting
|
||||
// contributions to the providers. Once that is an option, the provider should be updated to
|
||||
// directly call `EnvironmentFromFile`. Until then, we rely on dispatching Azure Stack environment creation
|
||||
// from this method based on the name that is provided to us.
|
||||
if strings.EqualFold(name, "AZURESTACKCLOUD") {
|
||||
return EnvironmentFromFile(os.Getenv(EnvironmentFilepathName))
|
||||
}
|
||||
|
||||
name = strings.ToUpper(name)
|
||||
env, ok := environments[name]
|
||||
if !ok {
|
||||
return env, fmt.Errorf("autorest/azure: There is no cloud environment matching the name %q", name)
|
||||
}
|
||||
|
||||
return env, nil
|
||||
}
|
||||
|
||||
// EnvironmentFromFile loads an Environment from a configuration file available on disk.
|
||||
// This function is particularly useful in the Hybrid Cloud model, where one must define their own
|
||||
// endpoints.
|
||||
func EnvironmentFromFile(location string) (unmarshaled Environment, err error) {
|
||||
fileContents, err := ioutil.ReadFile(location)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(fileContents, &unmarshaled)
|
||||
|
||||
return
|
||||
}
|
||||
|
|
245
vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go
generated
vendored
Normal file
245
vendor/github.com/Azure/go-autorest/autorest/azure/metadata_environment.go
generated
vendored
Normal file
|
@ -0,0 +1,245 @@
|
|||
package azure
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
)
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
type audience []string
|
||||
|
||||
type authentication struct {
|
||||
LoginEndpoint string `json:"loginEndpoint"`
|
||||
Audiences audience `json:"audiences"`
|
||||
}
|
||||
|
||||
type environmentMetadataInfo struct {
|
||||
GalleryEndpoint string `json:"galleryEndpoint"`
|
||||
GraphEndpoint string `json:"graphEndpoint"`
|
||||
PortalEndpoint string `json:"portalEndpoint"`
|
||||
Authentication authentication `json:"authentication"`
|
||||
}
|
||||
|
||||
// EnvironmentProperty represent property names that clients can override
|
||||
type EnvironmentProperty string
|
||||
|
||||
const (
|
||||
// EnvironmentName ...
|
||||
EnvironmentName EnvironmentProperty = "name"
|
||||
// EnvironmentManagementPortalURL ..
|
||||
EnvironmentManagementPortalURL EnvironmentProperty = "managementPortalURL"
|
||||
// EnvironmentPublishSettingsURL ...
|
||||
EnvironmentPublishSettingsURL EnvironmentProperty = "publishSettingsURL"
|
||||
// EnvironmentServiceManagementEndpoint ...
|
||||
EnvironmentServiceManagementEndpoint EnvironmentProperty = "serviceManagementEndpoint"
|
||||
// EnvironmentResourceManagerEndpoint ...
|
||||
EnvironmentResourceManagerEndpoint EnvironmentProperty = "resourceManagerEndpoint"
|
||||
// EnvironmentActiveDirectoryEndpoint ...
|
||||
EnvironmentActiveDirectoryEndpoint EnvironmentProperty = "activeDirectoryEndpoint"
|
||||
// EnvironmentGalleryEndpoint ...
|
||||
EnvironmentGalleryEndpoint EnvironmentProperty = "galleryEndpoint"
|
||||
// EnvironmentKeyVaultEndpoint ...
|
||||
EnvironmentKeyVaultEndpoint EnvironmentProperty = "keyVaultEndpoint"
|
||||
// EnvironmentGraphEndpoint ...
|
||||
EnvironmentGraphEndpoint EnvironmentProperty = "graphEndpoint"
|
||||
// EnvironmentServiceBusEndpoint ...
|
||||
EnvironmentServiceBusEndpoint EnvironmentProperty = "serviceBusEndpoint"
|
||||
// EnvironmentBatchManagementEndpoint ...
|
||||
EnvironmentBatchManagementEndpoint EnvironmentProperty = "batchManagementEndpoint"
|
||||
// EnvironmentStorageEndpointSuffix ...
|
||||
EnvironmentStorageEndpointSuffix EnvironmentProperty = "storageEndpointSuffix"
|
||||
// EnvironmentSQLDatabaseDNSSuffix ...
|
||||
EnvironmentSQLDatabaseDNSSuffix EnvironmentProperty = "sqlDatabaseDNSSuffix"
|
||||
// EnvironmentTrafficManagerDNSSuffix ...
|
||||
EnvironmentTrafficManagerDNSSuffix EnvironmentProperty = "trafficManagerDNSSuffix"
|
||||
// EnvironmentKeyVaultDNSSuffix ...
|
||||
EnvironmentKeyVaultDNSSuffix EnvironmentProperty = "keyVaultDNSSuffix"
|
||||
// EnvironmentServiceBusEndpointSuffix ...
|
||||
EnvironmentServiceBusEndpointSuffix EnvironmentProperty = "serviceBusEndpointSuffix"
|
||||
// EnvironmentServiceManagementVMDNSSuffix ...
|
||||
EnvironmentServiceManagementVMDNSSuffix EnvironmentProperty = "serviceManagementVMDNSSuffix"
|
||||
// EnvironmentResourceManagerVMDNSSuffix ...
|
||||
EnvironmentResourceManagerVMDNSSuffix EnvironmentProperty = "resourceManagerVMDNSSuffix"
|
||||
// EnvironmentContainerRegistryDNSSuffix ...
|
||||
EnvironmentContainerRegistryDNSSuffix EnvironmentProperty = "containerRegistryDNSSuffix"
|
||||
// EnvironmentTokenAudience ...
|
||||
EnvironmentTokenAudience EnvironmentProperty = "tokenAudience"
|
||||
)
|
||||
|
||||
// OverrideProperty represents property name and value that clients can override
|
||||
type OverrideProperty struct {
|
||||
Key EnvironmentProperty
|
||||
Value string
|
||||
}
|
||||
|
||||
// EnvironmentFromURL loads an Environment from a URL
|
||||
// This function is particularly useful in the Hybrid Cloud model, where one may define their own
|
||||
// endpoints.
|
||||
func EnvironmentFromURL(resourceManagerEndpoint string, properties ...OverrideProperty) (environment Environment, err error) {
|
||||
var metadataEnvProperties environmentMetadataInfo
|
||||
|
||||
if resourceManagerEndpoint == "" {
|
||||
return environment, fmt.Errorf("Metadata resource manager endpoint is empty")
|
||||
}
|
||||
|
||||
if metadataEnvProperties, err = retrieveMetadataEnvironment(resourceManagerEndpoint); err != nil {
|
||||
return environment, err
|
||||
}
|
||||
|
||||
// Give priority to user's override values
|
||||
overrideProperties(&environment, properties)
|
||||
|
||||
if environment.Name == "" {
|
||||
environment.Name = "HybridEnvironment"
|
||||
}
|
||||
stampDNSSuffix := environment.StorageEndpointSuffix
|
||||
if stampDNSSuffix == "" {
|
||||
stampDNSSuffix = strings.TrimSuffix(strings.TrimPrefix(strings.Replace(resourceManagerEndpoint, strings.Split(resourceManagerEndpoint, ".")[0], "", 1), "."), "/")
|
||||
environment.StorageEndpointSuffix = stampDNSSuffix
|
||||
}
|
||||
if environment.KeyVaultDNSSuffix == "" {
|
||||
environment.KeyVaultDNSSuffix = fmt.Sprintf("%s.%s", "vault", stampDNSSuffix)
|
||||
}
|
||||
if environment.KeyVaultEndpoint == "" {
|
||||
environment.KeyVaultEndpoint = fmt.Sprintf("%s%s", "https://", environment.KeyVaultDNSSuffix)
|
||||
}
|
||||
if environment.TokenAudience == "" {
|
||||
environment.TokenAudience = metadataEnvProperties.Authentication.Audiences[0]
|
||||
}
|
||||
if environment.ActiveDirectoryEndpoint == "" {
|
||||
environment.ActiveDirectoryEndpoint = metadataEnvProperties.Authentication.LoginEndpoint
|
||||
}
|
||||
if environment.ResourceManagerEndpoint == "" {
|
||||
environment.ResourceManagerEndpoint = resourceManagerEndpoint
|
||||
}
|
||||
if environment.GalleryEndpoint == "" {
|
||||
environment.GalleryEndpoint = metadataEnvProperties.GalleryEndpoint
|
||||
}
|
||||
if environment.GraphEndpoint == "" {
|
||||
environment.GraphEndpoint = metadataEnvProperties.GraphEndpoint
|
||||
}
|
||||
|
||||
return environment, nil
|
||||
}
|
||||
|
||||
func overrideProperties(environment *Environment, properties []OverrideProperty) {
|
||||
for _, property := range properties {
|
||||
switch property.Key {
|
||||
case EnvironmentName:
|
||||
{
|
||||
environment.Name = property.Value
|
||||
}
|
||||
case EnvironmentManagementPortalURL:
|
||||
{
|
||||
environment.ManagementPortalURL = property.Value
|
||||
}
|
||||
case EnvironmentPublishSettingsURL:
|
||||
{
|
||||
environment.PublishSettingsURL = property.Value
|
||||
}
|
||||
case EnvironmentServiceManagementEndpoint:
|
||||
{
|
||||
environment.ServiceManagementEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentResourceManagerEndpoint:
|
||||
{
|
||||
environment.ResourceManagerEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentActiveDirectoryEndpoint:
|
||||
{
|
||||
environment.ActiveDirectoryEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentGalleryEndpoint:
|
||||
{
|
||||
environment.GalleryEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentKeyVaultEndpoint:
|
||||
{
|
||||
environment.KeyVaultEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentGraphEndpoint:
|
||||
{
|
||||
environment.GraphEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentServiceBusEndpoint:
|
||||
{
|
||||
environment.ServiceBusEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentBatchManagementEndpoint:
|
||||
{
|
||||
environment.BatchManagementEndpoint = property.Value
|
||||
}
|
||||
case EnvironmentStorageEndpointSuffix:
|
||||
{
|
||||
environment.StorageEndpointSuffix = property.Value
|
||||
}
|
||||
case EnvironmentSQLDatabaseDNSSuffix:
|
||||
{
|
||||
environment.SQLDatabaseDNSSuffix = property.Value
|
||||
}
|
||||
case EnvironmentTrafficManagerDNSSuffix:
|
||||
{
|
||||
environment.TrafficManagerDNSSuffix = property.Value
|
||||
}
|
||||
case EnvironmentKeyVaultDNSSuffix:
|
||||
{
|
||||
environment.KeyVaultDNSSuffix = property.Value
|
||||
}
|
||||
case EnvironmentServiceBusEndpointSuffix:
|
||||
{
|
||||
environment.ServiceBusEndpointSuffix = property.Value
|
||||
}
|
||||
case EnvironmentServiceManagementVMDNSSuffix:
|
||||
{
|
||||
environment.ServiceManagementVMDNSSuffix = property.Value
|
||||
}
|
||||
case EnvironmentResourceManagerVMDNSSuffix:
|
||||
{
|
||||
environment.ResourceManagerVMDNSSuffix = property.Value
|
||||
}
|
||||
case EnvironmentContainerRegistryDNSSuffix:
|
||||
{
|
||||
environment.ContainerRegistryDNSSuffix = property.Value
|
||||
}
|
||||
case EnvironmentTokenAudience:
|
||||
{
|
||||
environment.TokenAudience = property.Value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func retrieveMetadataEnvironment(endpoint string) (environment environmentMetadataInfo, err error) {
|
||||
client := autorest.NewClientWithUserAgent("")
|
||||
managementEndpoint := fmt.Sprintf("%s%s", strings.TrimSuffix(endpoint, "/"), "/metadata/endpoints?api-version=1.0")
|
||||
req, _ := http.NewRequest("GET", managementEndpoint, nil)
|
||||
response, err := client.Do(req)
|
||||
if err != nil {
|
||||
return environment, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
jsonResponse, err := ioutil.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
return environment, err
|
||||
}
|
||||
err = json.Unmarshal(jsonResponse, &environment)
|
||||
return environment, err
|
||||
}
|
|
@ -0,0 +1,200 @@
|
|||
// Copyright 2017 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.
|
||||
|
||||
package azure
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
)
|
||||
|
||||
// DoRetryWithRegistration tries to register the resource provider in case it is unregistered.
|
||||
// It also handles request retries
|
||||
func DoRetryWithRegistration(client autorest.Client) autorest.SendDecorator {
|
||||
return func(s autorest.Sender) autorest.Sender {
|
||||
return autorest.SenderFunc(func(r *http.Request) (resp *http.Response, err error) {
|
||||
rr := autorest.NewRetriableRequest(r)
|
||||
for currentAttempt := 0; currentAttempt < client.RetryAttempts; currentAttempt++ {
|
||||
err = rr.Prepare()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
resp, err = autorest.SendWithSender(s, rr.Request(),
|
||||
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
||||
)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusConflict || client.SkipResourceProviderRegistration {
|
||||
return resp, err
|
||||
}
|
||||
var re RequestError
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
autorest.ByUnmarshallingJSON(&re),
|
||||
)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
err = re
|
||||
|
||||
if re.ServiceError != nil && re.ServiceError.Code == "MissingSubscriptionRegistration" {
|
||||
regErr := register(client, r, re)
|
||||
if regErr != nil {
|
||||
return resp, fmt.Errorf("failed auto registering Resource Provider: %s. Original error: %s", regErr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func getProvider(re RequestError) (string, error) {
|
||||
if re.ServiceError != nil && len(re.ServiceError.Details) > 0 {
|
||||
return re.ServiceError.Details[0]["target"].(string), nil
|
||||
}
|
||||
return "", errors.New("provider was not found in the response")
|
||||
}
|
||||
|
||||
func register(client autorest.Client, originalReq *http.Request, re RequestError) error {
|
||||
subID := getSubscription(originalReq.URL.Path)
|
||||
if subID == "" {
|
||||
return errors.New("missing parameter subscriptionID to register resource provider")
|
||||
}
|
||||
providerName, err := getProvider(re)
|
||||
if err != nil {
|
||||
return fmt.Errorf("missing parameter provider to register resource provider: %s", err)
|
||||
}
|
||||
newURL := url.URL{
|
||||
Scheme: originalReq.URL.Scheme,
|
||||
Host: originalReq.URL.Host,
|
||||
}
|
||||
|
||||
// taken from the resources SDK
|
||||
// with almost identical code, this sections are easier to mantain
|
||||
// It is also not a good idea to import the SDK here
|
||||
// https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L252
|
||||
pathParameters := map[string]interface{}{
|
||||
"resourceProviderNamespace": autorest.Encode("path", providerName),
|
||||
"subscriptionId": autorest.Encode("path", subID),
|
||||
}
|
||||
|
||||
const APIVersion = "2016-09-01"
|
||||
queryParameters := map[string]interface{}{
|
||||
"api-version": APIVersion,
|
||||
}
|
||||
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsPost(),
|
||||
autorest.WithBaseURL(newURL.String()),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}/register", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters),
|
||||
)
|
||||
|
||||
req, err := preparer.Prepare(&http.Request{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req = req.WithContext(originalReq.Context())
|
||||
|
||||
resp, err := autorest.SendWithSender(client, req,
|
||||
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
type Provider struct {
|
||||
RegistrationState *string `json:"registrationState,omitempty"`
|
||||
}
|
||||
var provider Provider
|
||||
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&provider),
|
||||
autorest.ByClosing(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// poll for registered provisioning state
|
||||
now := time.Now()
|
||||
for err == nil && time.Since(now) < client.PollingDuration {
|
||||
// taken from the resources SDK
|
||||
// https://github.com/Azure/azure-sdk-for-go/blob/9f366792afa3e0ddaecdc860e793ba9d75e76c27/arm/resources/resources/providers.go#L45
|
||||
preparer := autorest.CreatePreparer(
|
||||
autorest.AsGet(),
|
||||
autorest.WithBaseURL(newURL.String()),
|
||||
autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/{resourceProviderNamespace}", pathParameters),
|
||||
autorest.WithQueryParameters(queryParameters),
|
||||
)
|
||||
req, err = preparer.Prepare(&http.Request{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req = req.WithContext(originalReq.Context())
|
||||
|
||||
resp, err := autorest.SendWithSender(client, req,
|
||||
autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = autorest.Respond(
|
||||
resp,
|
||||
WithErrorUnlessStatusCode(http.StatusOK),
|
||||
autorest.ByUnmarshallingJSON(&provider),
|
||||
autorest.ByClosing(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if provider.RegistrationState != nil &&
|
||||
*provider.RegistrationState == "Registered" {
|
||||
break
|
||||
}
|
||||
|
||||
delayed := autorest.DelayWithRetryAfter(resp, originalReq.Context().Done())
|
||||
if !delayed && !autorest.DelayForBackoff(client.PollingDelay, 0, originalReq.Context().Done()) {
|
||||
return originalReq.Context().Err()
|
||||
}
|
||||
}
|
||||
if !(time.Since(now) < client.PollingDuration) {
|
||||
return errors.New("polling for resource provider registration has exceeded the polling duration")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func getSubscription(path string) string {
|
||||
parts := strings.Split(path, "/")
|
||||
for i, v := range parts {
|
||||
if v == "subscriptions" && (i+1) < len(parts) {
|
||||
return parts[i+1]
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
@ -8,8 +22,11 @@ import (
|
|||
"log"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/logger"
|
||||
"github.com/Azure/go-autorest/version"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -21,19 +38,14 @@ const (
|
|||
|
||||
// DefaultRetryAttempts is number of attempts for retry status codes (5xx).
|
||||
DefaultRetryAttempts = 3
|
||||
|
||||
// DefaultRetryDuration is the duration to wait between retries.
|
||||
DefaultRetryDuration = 30 * time.Second
|
||||
)
|
||||
|
||||
var (
|
||||
// defaultUserAgent builds a string containing the Go version, system archityecture and OS,
|
||||
// and the go-autorest version.
|
||||
defaultUserAgent = fmt.Sprintf("Go/%s (%s-%s) go-autorest/%s",
|
||||
runtime.Version(),
|
||||
runtime.GOARCH,
|
||||
runtime.GOOS,
|
||||
Version(),
|
||||
)
|
||||
|
||||
statusCodesForRetry = []int{
|
||||
// StatusCodesForRetry are a defined group of status code for which the client will retry
|
||||
StatusCodesForRetry = []int{
|
||||
http.StatusRequestTimeout, // 408
|
||||
http.StatusTooManyRequests, // 429
|
||||
http.StatusInternalServerError, // 500
|
||||
|
@ -148,6 +160,9 @@ type Client struct {
|
|||
UserAgent string
|
||||
|
||||
Jar http.CookieJar
|
||||
|
||||
// Set to true to skip attempted registration of resource providers (false by default).
|
||||
SkipResourceProviderRegistration bool
|
||||
}
|
||||
|
||||
// NewClientWithUserAgent returns an instance of a Client with the UserAgent set to the passed
|
||||
|
@ -157,9 +172,10 @@ func NewClientWithUserAgent(ua string) Client {
|
|||
PollingDelay: DefaultPollingDelay,
|
||||
PollingDuration: DefaultPollingDuration,
|
||||
RetryAttempts: DefaultRetryAttempts,
|
||||
RetryDuration: 30 * time.Second,
|
||||
UserAgent: defaultUserAgent,
|
||||
RetryDuration: DefaultRetryDuration,
|
||||
UserAgent: version.UserAgent(),
|
||||
}
|
||||
c.Sender = c.sender()
|
||||
c.AddToUserAgent(ua)
|
||||
return c
|
||||
}
|
||||
|
@ -181,16 +197,31 @@ func (c Client) Do(r *http.Request) (*http.Response, error) {
|
|||
r, _ = Prepare(r,
|
||||
WithUserAgent(c.UserAgent))
|
||||
}
|
||||
// NOTE: c.WithInspection() must be last in the list so that it can inspect all preceding operations
|
||||
r, err := Prepare(r,
|
||||
c.WithInspection(),
|
||||
c.WithAuthorization())
|
||||
c.WithAuthorization(),
|
||||
c.WithInspection())
|
||||
if err != nil {
|
||||
return nil, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed")
|
||||
var resp *http.Response
|
||||
if detErr, ok := err.(DetailedError); ok {
|
||||
// if the authorization failed (e.g. invalid credentials) there will
|
||||
// be a response associated with the error, be sure to return it.
|
||||
resp = detErr.Response
|
||||
}
|
||||
return resp, NewErrorWithError(err, "autorest/Client", "Do", nil, "Preparing request failed")
|
||||
}
|
||||
resp, err := SendWithSender(c.sender(), r,
|
||||
DoRetryForStatusCodes(c.RetryAttempts, c.RetryDuration, statusCodesForRetry...))
|
||||
Respond(resp,
|
||||
c.ByInspecting())
|
||||
logger.Instance.WriteRequest(r, logger.Filter{
|
||||
Header: func(k string, v []string) (bool, []string) {
|
||||
// remove the auth token from the log
|
||||
if strings.EqualFold(k, "Authorization") || strings.EqualFold(k, "Ocp-Apim-Subscription-Key") {
|
||||
v = []string{"**REDACTED**"}
|
||||
}
|
||||
return true, v
|
||||
},
|
||||
})
|
||||
resp, err := SendWithSender(c.sender(), r)
|
||||
logger.Instance.WriteResponse(resp, logger.Filter{})
|
||||
Respond(resp, c.ByInspecting())
|
||||
return resp, err
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,20 @@ time.Time types. And both convert to time.Time through a ToTime method.
|
|||
*/
|
||||
package date
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package date
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"time"
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package date
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package date
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package date
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
@ -13,8 +27,9 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
mimeTypeJSON = "application/json"
|
||||
mimeTypeFormPost = "application/x-www-form-urlencoded"
|
||||
mimeTypeJSON = "application/json"
|
||||
mimeTypeOctetStream = "application/octet-stream"
|
||||
mimeTypeFormPost = "application/x-www-form-urlencoded"
|
||||
|
||||
headerAuthorization = "Authorization"
|
||||
headerContentType = "Content-Type"
|
||||
|
@ -98,6 +113,28 @@ func WithHeader(header string, value string) PrepareDecorator {
|
|||
}
|
||||
}
|
||||
|
||||
// WithHeaders returns a PrepareDecorator that sets the specified HTTP headers of the http.Request to
|
||||
// the passed value. It canonicalizes the passed headers name (via http.CanonicalHeaderKey) before
|
||||
// adding them.
|
||||
func WithHeaders(headers map[string]interface{}) PrepareDecorator {
|
||||
h := ensureValueStrings(headers)
|
||||
return func(p Preparer) Preparer {
|
||||
return PreparerFunc(func(r *http.Request) (*http.Request, error) {
|
||||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
if r.Header == nil {
|
||||
r.Header = make(http.Header)
|
||||
}
|
||||
|
||||
for name, value := range h {
|
||||
r.Header.Set(http.CanonicalHeaderKey(name), value)
|
||||
}
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// WithBearerAuthorization returns a PrepareDecorator that adds an HTTP Authorization header whose
|
||||
// value is "Bearer " followed by the supplied token.
|
||||
func WithBearerAuthorization(token string) PrepareDecorator {
|
||||
|
@ -128,6 +165,11 @@ func AsJSON() PrepareDecorator {
|
|||
return AsContentType(mimeTypeJSON)
|
||||
}
|
||||
|
||||
// AsOctetStream returns a PrepareDecorator that adds the "application/octet-stream" Content-Type header.
|
||||
func AsOctetStream() PrepareDecorator {
|
||||
return AsContentType(mimeTypeOctetStream)
|
||||
}
|
||||
|
||||
// WithMethod returns a PrepareDecorator that sets the HTTP method of the passed request. The
|
||||
// decorator does not validate that the passed method string is a known HTTP method.
|
||||
func WithMethod(method string) PrepareDecorator {
|
||||
|
@ -201,6 +243,11 @@ func WithFormData(v url.Values) PrepareDecorator {
|
|||
r, err := p.Prepare(r)
|
||||
if err == nil {
|
||||
s := v.Encode()
|
||||
|
||||
if r.Header == nil {
|
||||
r.Header = make(http.Header)
|
||||
}
|
||||
r.Header.Set(http.CanonicalHeaderKey(headerContentType), mimeTypeFormPost)
|
||||
r.ContentLength = int64(len(s))
|
||||
r.Body = ioutil.NopCloser(strings.NewReader(s))
|
||||
}
|
||||
|
@ -416,11 +463,16 @@ func WithQueryParameters(queryParameters map[string]interface{}) PrepareDecorato
|
|||
if r.URL == nil {
|
||||
return r, NewError("autorest", "WithQueryParameters", "Invoked with a nil URL")
|
||||
}
|
||||
|
||||
v := r.URL.Query()
|
||||
for key, value := range parameters {
|
||||
v.Add(key, value)
|
||||
d, err := url.QueryUnescape(value)
|
||||
if err != nil {
|
||||
return r, err
|
||||
}
|
||||
v.Add(key, d)
|
||||
}
|
||||
r.URL.RawQuery = createQuery(v)
|
||||
r.URL.RawQuery = v.Encode()
|
||||
}
|
||||
return r, err
|
||||
})
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
|
|
@ -1,17 +1,31 @@
|
|||
// +build !go1.8
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
package autorest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// RetriableRequest provides facilities for retrying an HTTP request.
|
||||
type RetriableRequest struct {
|
||||
req *http.Request
|
||||
br *bytes.Reader
|
||||
reset bool
|
||||
req *http.Request
|
||||
br *bytes.Reader
|
||||
}
|
||||
|
||||
// Prepare signals that the request is about to be sent.
|
||||
|
@ -19,21 +33,17 @@ func (rr *RetriableRequest) Prepare() (err error) {
|
|||
// preserve the request body; this is to support retry logic as
|
||||
// the underlying transport will always close the reqeust body
|
||||
if rr.req.Body != nil {
|
||||
if rr.reset {
|
||||
if rr.br != nil {
|
||||
_, err = rr.br.Seek(0, 0 /*io.SeekStart*/)
|
||||
}
|
||||
rr.reset = false
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rr.br != nil {
|
||||
_, err = rr.br.Seek(0, 0 /*io.SeekStart*/)
|
||||
rr.req.Body = ioutil.NopCloser(rr.br)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rr.br == nil {
|
||||
// fall back to making a copy (only do this once)
|
||||
err = rr.prepareFromByteReader()
|
||||
}
|
||||
// indicates that the request body needs to be reset
|
||||
rr.reset = true
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,19 +1,33 @@
|
|||
// +build go1.8
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
package autorest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// RetriableRequest provides facilities for retrying an HTTP request.
|
||||
type RetriableRequest struct {
|
||||
req *http.Request
|
||||
rc io.ReadCloser
|
||||
br *bytes.Reader
|
||||
reset bool
|
||||
req *http.Request
|
||||
rc io.ReadCloser
|
||||
br *bytes.Reader
|
||||
}
|
||||
|
||||
// Prepare signals that the request is about to be sent.
|
||||
|
@ -21,16 +35,14 @@ func (rr *RetriableRequest) Prepare() (err error) {
|
|||
// preserve the request body; this is to support retry logic as
|
||||
// the underlying transport will always close the reqeust body
|
||||
if rr.req.Body != nil {
|
||||
if rr.reset {
|
||||
if rr.rc != nil {
|
||||
rr.req.Body = rr.rc
|
||||
} else if rr.br != nil {
|
||||
_, err = rr.br.Seek(0, io.SeekStart)
|
||||
}
|
||||
rr.reset = false
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rr.rc != nil {
|
||||
rr.req.Body = rr.rc
|
||||
} else if rr.br != nil {
|
||||
_, err = rr.br.Seek(0, io.SeekStart)
|
||||
rr.req.Body = ioutil.NopCloser(rr.br)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rr.req.GetBody != nil {
|
||||
// this will allow us to preserve the body without having to
|
||||
|
@ -43,8 +55,6 @@ func (rr *RetriableRequest) Prepare() (err error) {
|
|||
// fall back to making a copy (only do this once)
|
||||
err = rr.prepareFromByteReader()
|
||||
}
|
||||
// indicates that the request body needs to be reset
|
||||
rr.reset = true
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,5 +1,19 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
@ -72,7 +86,7 @@ func SendWithSender(s Sender, r *http.Request, decorators ...SendDecorator) (*ht
|
|||
func AfterDelay(d time.Duration) SendDecorator {
|
||||
return func(s Sender) Sender {
|
||||
return SenderFunc(func(r *http.Request) (*http.Response, error) {
|
||||
if !DelayForBackoff(d, 0, r.Cancel) {
|
||||
if !DelayForBackoff(d, 0, r.Context().Done()) {
|
||||
return nil, fmt.Errorf("autorest: AfterDelay canceled before full delay")
|
||||
}
|
||||
return s.Do(r)
|
||||
|
@ -151,7 +165,7 @@ func DoPollForStatusCodes(duration time.Duration, delay time.Duration, codes ...
|
|||
resp, err = s.Do(r)
|
||||
|
||||
if err == nil && ResponseHasStatusCode(resp, codes...) {
|
||||
r, err = NewPollingRequest(resp, r.Cancel)
|
||||
r, err = NewPollingRequestWithContext(r.Context(), resp)
|
||||
|
||||
for err == nil && ResponseHasStatusCode(resp, codes...) {
|
||||
Respond(resp,
|
||||
|
@ -184,7 +198,9 @@ func DoRetryForAttempts(attempts int, backoff time.Duration) SendDecorator {
|
|||
if err == nil {
|
||||
return resp, err
|
||||
}
|
||||
DelayForBackoff(backoff, attempt, r.Cancel)
|
||||
if !DelayForBackoff(backoff, attempt, r.Context().Done()) {
|
||||
return nil, r.Context().Err()
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
|
@ -201,18 +217,29 @@ func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) Se
|
|||
rr := NewRetriableRequest(r)
|
||||
// Increment to add the first call (attempts denotes number of retries)
|
||||
attempts++
|
||||
for attempt := 0; attempt < attempts; attempt++ {
|
||||
for attempt := 0; attempt < attempts; {
|
||||
err = rr.Prepare()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
resp, err = s.Do(rr.Request())
|
||||
if err != nil || !ResponseHasStatusCode(resp, codes...) {
|
||||
// if the error isn't temporary don't bother retrying
|
||||
if err != nil && !IsTemporaryNetworkError(err) {
|
||||
return nil, err
|
||||
}
|
||||
// we want to retry if err is not nil (e.g. transient network failure). note that for failed authentication
|
||||
// resp and err will both have a value, so in this case we don't want to retry as it will never succeed.
|
||||
if err == nil && !ResponseHasStatusCode(resp, codes...) || IsTokenRefreshError(err) {
|
||||
return resp, err
|
||||
}
|
||||
delayed := DelayWithRetryAfter(resp, r.Cancel)
|
||||
if !delayed {
|
||||
DelayForBackoff(backoff, attempt, r.Cancel)
|
||||
delayed := DelayWithRetryAfter(resp, r.Context().Done())
|
||||
if !delayed && !DelayForBackoff(backoff, attempt, r.Context().Done()) {
|
||||
return nil, r.Context().Err()
|
||||
}
|
||||
// don't count a 429 against the number of attempts
|
||||
// so that we continue to retry until it succeeds
|
||||
if resp == nil || resp.StatusCode != http.StatusTooManyRequests {
|
||||
attempt++
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
|
@ -223,6 +250,9 @@ func DoRetryForStatusCodes(attempts int, backoff time.Duration, codes ...int) Se
|
|||
// DelayWithRetryAfter invokes time.After for the duration specified in the "Retry-After" header in
|
||||
// responses with status code 429
|
||||
func DelayWithRetryAfter(resp *http.Response, cancel <-chan struct{}) bool {
|
||||
if resp == nil {
|
||||
return false
|
||||
}
|
||||
retryAfter, _ := strconv.Atoi(resp.Header.Get("Retry-After"))
|
||||
if resp.StatusCode == http.StatusTooManyRequests && retryAfter > 0 {
|
||||
select {
|
||||
|
@ -253,7 +283,9 @@ func DoRetryForDuration(d time.Duration, backoff time.Duration) SendDecorator {
|
|||
if err == nil {
|
||||
return resp, err
|
||||
}
|
||||
DelayForBackoff(backoff, attempt, r.Cancel)
|
||||
if !DelayForBackoff(backoff, attempt, r.Context().Done()) {
|
||||
return nil, r.Context().Err()
|
||||
}
|
||||
}
|
||||
return resp, err
|
||||
})
|
||||
|
|
|
@ -3,6 +3,20 @@ Package to provides helpers to ease working with pointer values of marshalled st
|
|||
*/
|
||||
package to
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
// String returns a string value for the passed string pointer. It returns the empty string if the
|
||||
// pointer is nil.
|
||||
func String(s *string) string {
|
||||
|
|
|
@ -1,15 +1,32 @@
|
|||
package autorest
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
)
|
||||
|
||||
// EncodedAs is a series of constants specifying various data encodings
|
||||
|
@ -123,13 +140,38 @@ func MapToValues(m map[string]interface{}) url.Values {
|
|||
return v
|
||||
}
|
||||
|
||||
// String method converts interface v to string. If interface is a list, it
|
||||
// joins list elements using separator.
|
||||
func String(v interface{}, sep ...string) string {
|
||||
if len(sep) > 0 {
|
||||
return ensureValueString(strings.Join(v.([]string), sep[0]))
|
||||
// AsStringSlice method converts interface{} to []string. This expects a
|
||||
//that the parameter passed to be a slice or array of a type that has the underlying
|
||||
//type a string.
|
||||
func AsStringSlice(s interface{}) ([]string, error) {
|
||||
v := reflect.ValueOf(s)
|
||||
if v.Kind() != reflect.Slice && v.Kind() != reflect.Array {
|
||||
return nil, NewError("autorest", "AsStringSlice", "the value's type is not an array.")
|
||||
}
|
||||
return ensureValueString(v)
|
||||
stringSlice := make([]string, 0, v.Len())
|
||||
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
stringSlice = append(stringSlice, v.Index(i).String())
|
||||
}
|
||||
return stringSlice, nil
|
||||
}
|
||||
|
||||
// String method converts interface v to string. If interface is a list, it
|
||||
// joins list elements using the seperator. Note that only sep[0] will be used for
|
||||
// joining if any separator is specified.
|
||||
func String(v interface{}, sep ...string) string {
|
||||
if len(sep) == 0 {
|
||||
return ensureValueString(v)
|
||||
}
|
||||
stringSlice, ok := v.([]string)
|
||||
if ok == false {
|
||||
var err error
|
||||
stringSlice, err = AsStringSlice(v)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("autorest: Couldn't convert value to a string %s.", err))
|
||||
}
|
||||
}
|
||||
return ensureValueString(strings.Join(stringSlice, sep[0]))
|
||||
}
|
||||
|
||||
// Encode method encodes url path and query parameters.
|
||||
|
@ -153,26 +195,34 @@ func queryEscape(s string) string {
|
|||
return url.QueryEscape(s)
|
||||
}
|
||||
|
||||
// This method is same as Encode() method of "net/url" go package,
|
||||
// except it does not encode the query parameters because they
|
||||
// already come encoded. It formats values map in query format (bar=foo&a=b).
|
||||
func createQuery(v url.Values) string {
|
||||
var buf bytes.Buffer
|
||||
keys := make([]string, 0, len(v))
|
||||
for k := range v {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
vs := v[k]
|
||||
prefix := url.QueryEscape(k) + "="
|
||||
for _, v := range vs {
|
||||
if buf.Len() > 0 {
|
||||
buf.WriteByte('&')
|
||||
}
|
||||
buf.WriteString(prefix)
|
||||
buf.WriteString(v)
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
// ChangeToGet turns the specified http.Request into a GET (it assumes it wasn't).
|
||||
// This is mainly useful for long-running operations that use the Azure-AsyncOperation
|
||||
// header, so we change the initial PUT into a GET to retrieve the final result.
|
||||
func ChangeToGet(req *http.Request) *http.Request {
|
||||
req.Method = "GET"
|
||||
req.Body = nil
|
||||
req.ContentLength = 0
|
||||
req.Header.Del("Content-Length")
|
||||
return req
|
||||
}
|
||||
|
||||
// IsTokenRefreshError returns true if the specified error implements the TokenRefreshError
|
||||
// interface. If err is a DetailedError it will walk the chain of Original errors.
|
||||
func IsTokenRefreshError(err error) bool {
|
||||
if _, ok := err.(adal.TokenRefreshError); ok {
|
||||
return true
|
||||
}
|
||||
if de, ok := err.(DetailedError); ok {
|
||||
return IsTokenRefreshError(de.Original)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsTemporaryNetworkError returns true if the specified error is a temporary network error or false
|
||||
// if it's not. If the error doesn't implement the net.Error interface the return value is true.
|
||||
func IsTemporaryNetworkError(err error) bool {
|
||||
if netErr, ok := err.(net.Error); !ok || (ok && netErr.Temporary()) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
package validation
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Error is the type that's returned when the validation of an APIs arguments constraints fails.
|
||||
type Error struct {
|
||||
// PackageType is the package type of the object emitting the error. For types, the value
|
||||
// matches that produced the the '%T' format specifier of the fmt package. For other elements,
|
||||
// such as functions, it is just the package name (e.g., "autorest").
|
||||
PackageType string
|
||||
|
||||
// Method is the name of the method raising the error.
|
||||
Method string
|
||||
|
||||
// Message is the error message.
|
||||
Message string
|
||||
}
|
||||
|
||||
// Error returns a string containing the details of the validation failure.
|
||||
func (e Error) Error() string {
|
||||
return fmt.Sprintf("%s#%s: Invalid input: %s", e.PackageType, e.Method, e.Message)
|
||||
}
|
||||
|
||||
// NewError creates a new Error object with the specified parameters.
|
||||
// message is treated as a format string to which the optional args apply.
|
||||
func NewError(packageType string, method string, message string, args ...interface{}) Error {
|
||||
return Error{
|
||||
PackageType: packageType,
|
||||
Method: method,
|
||||
Message: fmt.Sprintf(message, args...),
|
||||
}
|
||||
}
|
|
@ -3,6 +3,20 @@ Package validation provides methods for validating parameter value using reflect
|
|||
*/
|
||||
package validation
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
@ -91,15 +105,12 @@ func validateStruct(x reflect.Value, v Constraint, name ...string) error {
|
|||
return createError(x, v, fmt.Sprintf("field %q doesn't exist", v.Target))
|
||||
}
|
||||
|
||||
if err := Validate([]Validation{
|
||||
return Validate([]Validation{
|
||||
{
|
||||
TargetValue: getInterfaceValue(f),
|
||||
Constraints: []Constraint{v},
|
||||
},
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func validatePtr(x reflect.Value, v Constraint) error {
|
||||
|
@ -125,29 +136,29 @@ func validatePtr(x reflect.Value, v Constraint) error {
|
|||
|
||||
func validateInt(x reflect.Value, v Constraint) error {
|
||||
i := x.Int()
|
||||
r, ok := v.Rule.(int)
|
||||
r, ok := toInt64(v.Rule)
|
||||
if !ok {
|
||||
return createError(x, v, fmt.Sprintf("rule must be integer value for %v constraint; got: %v", v.Name, v.Rule))
|
||||
}
|
||||
switch v.Name {
|
||||
case MultipleOf:
|
||||
if i%int64(r) != 0 {
|
||||
if i%r != 0 {
|
||||
return createError(x, v, fmt.Sprintf("value must be a multiple of %v", r))
|
||||
}
|
||||
case ExclusiveMinimum:
|
||||
if i <= int64(r) {
|
||||
if i <= r {
|
||||
return createError(x, v, fmt.Sprintf("value must be greater than %v", r))
|
||||
}
|
||||
case ExclusiveMaximum:
|
||||
if i >= int64(r) {
|
||||
if i >= r {
|
||||
return createError(x, v, fmt.Sprintf("value must be less than %v", r))
|
||||
}
|
||||
case InclusiveMinimum:
|
||||
if i < int64(r) {
|
||||
if i < r {
|
||||
return createError(x, v, fmt.Sprintf("value must be greater than or equal to %v", r))
|
||||
}
|
||||
case InclusiveMaximum:
|
||||
if i > int64(r) {
|
||||
if i > r {
|
||||
return createError(x, v, fmt.Sprintf("value must be less than or equal to %v", r))
|
||||
}
|
||||
default:
|
||||
|
@ -377,8 +388,21 @@ func createError(x reflect.Value, v Constraint, err string) error {
|
|||
v.Target, v.Name, getInterfaceValue(x), err)
|
||||
}
|
||||
|
||||
func toInt64(v interface{}) (int64, bool) {
|
||||
if i64, ok := v.(int64); ok {
|
||||
return i64, true
|
||||
}
|
||||
// older generators emit max constants as int, so if int64 fails fall back to int
|
||||
if i32, ok := v.(int); ok {
|
||||
return int64(i32), true
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// NewErrorWithValidationError appends package type and method name in
|
||||
// validation error.
|
||||
//
|
||||
// Deprecated: Please use validation.NewError() instead.
|
||||
func NewErrorWithValidationError(err error, packageType, method string) error {
|
||||
return fmt.Errorf("%s#%s: Invalid input: %v", packageType, method, err)
|
||||
return NewError(packageType, method, err.Error())
|
||||
}
|
||||
|
|
|
@ -1,35 +1,22 @@
|
|||
package autorest
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
import "github.com/Azure/go-autorest/version"
|
||||
|
||||
const (
|
||||
major = 8
|
||||
minor = 0
|
||||
patch = 0
|
||||
tag = ""
|
||||
)
|
||||
|
||||
var once sync.Once
|
||||
var version string
|
||||
// Copyright 2017 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.
|
||||
|
||||
// Version returns the semantic version (see http://semver.org).
|
||||
func Version() string {
|
||||
once.Do(func() {
|
||||
semver := fmt.Sprintf("%d.%d.%d", major, minor, patch)
|
||||
verBuilder := bytes.NewBufferString(semver)
|
||||
if tag != "" && tag != "-" {
|
||||
updated := strings.TrimPrefix(tag, "-")
|
||||
_, err := verBuilder.WriteString("-" + updated)
|
||||
if err == nil {
|
||||
verBuilder = bytes.NewBufferString(semver)
|
||||
}
|
||||
}
|
||||
version = verBuilder.String()
|
||||
})
|
||||
return version
|
||||
return version.Number
|
||||
}
|
||||
|
|
|
@ -0,0 +1,328 @@
|
|||
package logger
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// LevelType tells a logger the minimum level to log. When code reports a log entry,
|
||||
// the LogLevel indicates the level of the log entry. The logger only records entries
|
||||
// whose level is at least the level it was told to log. See the Log* constants.
|
||||
// For example, if a logger is configured with LogError, then LogError, LogPanic,
|
||||
// and LogFatal entries will be logged; lower level entries are ignored.
|
||||
type LevelType uint32
|
||||
|
||||
const (
|
||||
// LogNone tells a logger not to log any entries passed to it.
|
||||
LogNone LevelType = iota
|
||||
|
||||
// LogFatal tells a logger to log all LogFatal entries passed to it.
|
||||
LogFatal
|
||||
|
||||
// LogPanic tells a logger to log all LogPanic and LogFatal entries passed to it.
|
||||
LogPanic
|
||||
|
||||
// LogError tells a logger to log all LogError, LogPanic and LogFatal entries passed to it.
|
||||
LogError
|
||||
|
||||
// LogWarning tells a logger to log all LogWarning, LogError, LogPanic and LogFatal entries passed to it.
|
||||
LogWarning
|
||||
|
||||
// LogInfo tells a logger to log all LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it.
|
||||
LogInfo
|
||||
|
||||
// LogDebug tells a logger to log all LogDebug, LogInfo, LogWarning, LogError, LogPanic and LogFatal entries passed to it.
|
||||
LogDebug
|
||||
)
|
||||
|
||||
const (
|
||||
logNone = "NONE"
|
||||
logFatal = "FATAL"
|
||||
logPanic = "PANIC"
|
||||
logError = "ERROR"
|
||||
logWarning = "WARNING"
|
||||
logInfo = "INFO"
|
||||
logDebug = "DEBUG"
|
||||
logUnknown = "UNKNOWN"
|
||||
)
|
||||
|
||||
// ParseLevel converts the specified string into the corresponding LevelType.
|
||||
func ParseLevel(s string) (lt LevelType, err error) {
|
||||
switch strings.ToUpper(s) {
|
||||
case logFatal:
|
||||
lt = LogFatal
|
||||
case logPanic:
|
||||
lt = LogPanic
|
||||
case logError:
|
||||
lt = LogError
|
||||
case logWarning:
|
||||
lt = LogWarning
|
||||
case logInfo:
|
||||
lt = LogInfo
|
||||
case logDebug:
|
||||
lt = LogDebug
|
||||
default:
|
||||
err = fmt.Errorf("bad log level '%s'", s)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// String implements the stringer interface for LevelType.
|
||||
func (lt LevelType) String() string {
|
||||
switch lt {
|
||||
case LogNone:
|
||||
return logNone
|
||||
case LogFatal:
|
||||
return logFatal
|
||||
case LogPanic:
|
||||
return logPanic
|
||||
case LogError:
|
||||
return logError
|
||||
case LogWarning:
|
||||
return logWarning
|
||||
case LogInfo:
|
||||
return logInfo
|
||||
case LogDebug:
|
||||
return logDebug
|
||||
default:
|
||||
return logUnknown
|
||||
}
|
||||
}
|
||||
|
||||
// Filter defines functions for filtering HTTP request/response content.
|
||||
type Filter struct {
|
||||
// URL returns a potentially modified string representation of a request URL.
|
||||
URL func(u *url.URL) string
|
||||
|
||||
// Header returns a potentially modified set of values for the specified key.
|
||||
// To completely exclude the header key/values return false.
|
||||
Header func(key string, val []string) (bool, []string)
|
||||
|
||||
// Body returns a potentially modified request/response body.
|
||||
Body func(b []byte) []byte
|
||||
}
|
||||
|
||||
func (f Filter) processURL(u *url.URL) string {
|
||||
if f.URL == nil {
|
||||
return u.String()
|
||||
}
|
||||
return f.URL(u)
|
||||
}
|
||||
|
||||
func (f Filter) processHeader(k string, val []string) (bool, []string) {
|
||||
if f.Header == nil {
|
||||
return true, val
|
||||
}
|
||||
return f.Header(k, val)
|
||||
}
|
||||
|
||||
func (f Filter) processBody(b []byte) []byte {
|
||||
if f.Body == nil {
|
||||
return b
|
||||
}
|
||||
return f.Body(b)
|
||||
}
|
||||
|
||||
// Writer defines methods for writing to a logging facility.
|
||||
type Writer interface {
|
||||
// Writeln writes the specified message with the standard log entry header and new-line character.
|
||||
Writeln(level LevelType, message string)
|
||||
|
||||
// Writef writes the specified format specifier with the standard log entry header and no new-line character.
|
||||
Writef(level LevelType, format string, a ...interface{})
|
||||
|
||||
// WriteRequest writes the specified HTTP request to the logger if the log level is greater than
|
||||
// or equal to LogInfo. The request body, if set, is logged at level LogDebug or higher.
|
||||
// Custom filters can be specified to exclude URL, header, and/or body content from the log.
|
||||
// By default no request content is excluded.
|
||||
WriteRequest(req *http.Request, filter Filter)
|
||||
|
||||
// WriteResponse writes the specified HTTP response to the logger if the log level is greater than
|
||||
// or equal to LogInfo. The response body, if set, is logged at level LogDebug or higher.
|
||||
// Custom filters can be specified to exclude URL, header, and/or body content from the log.
|
||||
// By default no respone content is excluded.
|
||||
WriteResponse(resp *http.Response, filter Filter)
|
||||
}
|
||||
|
||||
// Instance is the default log writer initialized during package init.
|
||||
// This can be replaced with a custom implementation as required.
|
||||
var Instance Writer
|
||||
|
||||
// default log level
|
||||
var logLevel = LogNone
|
||||
|
||||
// Level returns the value specified in AZURE_GO_AUTOREST_LOG_LEVEL.
|
||||
// If no value was specified the default value is LogNone.
|
||||
// Custom loggers can call this to retrieve the configured log level.
|
||||
func Level() LevelType {
|
||||
return logLevel
|
||||
}
|
||||
|
||||
func init() {
|
||||
// separated for testing purposes
|
||||
initDefaultLogger()
|
||||
}
|
||||
|
||||
func initDefaultLogger() {
|
||||
// init with nilLogger so callers don't have to do a nil check on Default
|
||||
Instance = nilLogger{}
|
||||
llStr := strings.ToLower(os.Getenv("AZURE_GO_SDK_LOG_LEVEL"))
|
||||
if llStr == "" {
|
||||
return
|
||||
}
|
||||
var err error
|
||||
logLevel, err = ParseLevel(llStr)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "go-autorest: failed to parse log level: %s\n", err.Error())
|
||||
return
|
||||
}
|
||||
if logLevel == LogNone {
|
||||
return
|
||||
}
|
||||
// default to stderr
|
||||
dest := os.Stderr
|
||||
lfStr := os.Getenv("AZURE_GO_SDK_LOG_FILE")
|
||||
if strings.EqualFold(lfStr, "stdout") {
|
||||
dest = os.Stdout
|
||||
} else if lfStr != "" {
|
||||
lf, err := os.Create(lfStr)
|
||||
if err == nil {
|
||||
dest = lf
|
||||
} else {
|
||||
fmt.Fprintf(os.Stderr, "go-autorest: failed to create log file, using stderr: %s\n", err.Error())
|
||||
}
|
||||
}
|
||||
Instance = fileLogger{
|
||||
logLevel: logLevel,
|
||||
mu: &sync.Mutex{},
|
||||
logFile: dest,
|
||||
}
|
||||
}
|
||||
|
||||
// the nil logger does nothing
|
||||
type nilLogger struct{}
|
||||
|
||||
func (nilLogger) Writeln(LevelType, string) {}
|
||||
|
||||
func (nilLogger) Writef(LevelType, string, ...interface{}) {}
|
||||
|
||||
func (nilLogger) WriteRequest(*http.Request, Filter) {}
|
||||
|
||||
func (nilLogger) WriteResponse(*http.Response, Filter) {}
|
||||
|
||||
// A File is used instead of a Logger so the stream can be flushed after every write.
|
||||
type fileLogger struct {
|
||||
logLevel LevelType
|
||||
mu *sync.Mutex // for synchronizing writes to logFile
|
||||
logFile *os.File
|
||||
}
|
||||
|
||||
func (fl fileLogger) Writeln(level LevelType, message string) {
|
||||
fl.Writef(level, "%s\n", message)
|
||||
}
|
||||
|
||||
func (fl fileLogger) Writef(level LevelType, format string, a ...interface{}) {
|
||||
if fl.logLevel >= level {
|
||||
fl.mu.Lock()
|
||||
defer fl.mu.Unlock()
|
||||
fmt.Fprintf(fl.logFile, "%s %s", entryHeader(level), fmt.Sprintf(format, a...))
|
||||
fl.logFile.Sync()
|
||||
}
|
||||
}
|
||||
|
||||
func (fl fileLogger) WriteRequest(req *http.Request, filter Filter) {
|
||||
if req == nil || fl.logLevel < LogInfo {
|
||||
return
|
||||
}
|
||||
b := &bytes.Buffer{}
|
||||
fmt.Fprintf(b, "%s REQUEST: %s %s\n", entryHeader(LogInfo), req.Method, filter.processURL(req.URL))
|
||||
// dump headers
|
||||
for k, v := range req.Header {
|
||||
if ok, mv := filter.processHeader(k, v); ok {
|
||||
fmt.Fprintf(b, "%s: %s\n", k, strings.Join(mv, ","))
|
||||
}
|
||||
}
|
||||
if fl.shouldLogBody(req.Header, req.Body) {
|
||||
// dump body
|
||||
body, err := ioutil.ReadAll(req.Body)
|
||||
if err == nil {
|
||||
fmt.Fprintln(b, string(filter.processBody(body)))
|
||||
if nc, ok := req.Body.(io.Seeker); ok {
|
||||
// rewind to the beginning
|
||||
nc.Seek(0, io.SeekStart)
|
||||
} else {
|
||||
// recreate the body
|
||||
req.Body = ioutil.NopCloser(bytes.NewReader(body))
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(b, "failed to read body: %v\n", err)
|
||||
}
|
||||
}
|
||||
fl.mu.Lock()
|
||||
defer fl.mu.Unlock()
|
||||
fmt.Fprint(fl.logFile, b.String())
|
||||
fl.logFile.Sync()
|
||||
}
|
||||
|
||||
func (fl fileLogger) WriteResponse(resp *http.Response, filter Filter) {
|
||||
if resp == nil || fl.logLevel < LogInfo {
|
||||
return
|
||||
}
|
||||
b := &bytes.Buffer{}
|
||||
fmt.Fprintf(b, "%s RESPONSE: %d %s\n", entryHeader(LogInfo), resp.StatusCode, filter.processURL(resp.Request.URL))
|
||||
// dump headers
|
||||
for k, v := range resp.Header {
|
||||
if ok, mv := filter.processHeader(k, v); ok {
|
||||
fmt.Fprintf(b, "%s: %s\n", k, strings.Join(mv, ","))
|
||||
}
|
||||
}
|
||||
if fl.shouldLogBody(resp.Header, resp.Body) {
|
||||
// dump body
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err == nil {
|
||||
fmt.Fprintln(b, string(filter.processBody(body)))
|
||||
resp.Body = ioutil.NopCloser(bytes.NewReader(body))
|
||||
} else {
|
||||
fmt.Fprintf(b, "failed to read body: %v\n", err)
|
||||
}
|
||||
}
|
||||
fl.mu.Lock()
|
||||
defer fl.mu.Unlock()
|
||||
fmt.Fprint(fl.logFile, b.String())
|
||||
fl.logFile.Sync()
|
||||
}
|
||||
|
||||
// returns true if the provided body should be included in the log
|
||||
func (fl fileLogger) shouldLogBody(header http.Header, body io.ReadCloser) bool {
|
||||
ct := header.Get("Content-Type")
|
||||
return fl.logLevel >= LogDebug && body != nil && strings.Index(ct, "application/octet-stream") == -1
|
||||
}
|
||||
|
||||
// creates standard header for log entries, it contains a timestamp and the log level
|
||||
func entryHeader(level LevelType) string {
|
||||
// this format provides a fixed number of digits so the size of the timestamp is constant
|
||||
return fmt.Sprintf("(%s) %s:", time.Now().Format("2006-01-02T15:04:05.0000000Z07:00"), level.String())
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package version
|
||||
|
||||
// Copyright 2017 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.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
// Number contains the semantic version of this SDK.
|
||||
const Number = "v10.15.4"
|
||||
|
||||
var (
|
||||
userAgent = fmt.Sprintf("Go/%s (%s-%s) go-autorest/%s",
|
||||
runtime.Version(),
|
||||
runtime.GOARCH,
|
||||
runtime.GOOS,
|
||||
Number,
|
||||
)
|
||||
)
|
||||
|
||||
// UserAgent returns a string containing the Go version, system archityecture and OS, and the go-autorest version.
|
||||
func UserAgent() string {
|
||||
return userAgent
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
*.o
|
||||
*.a
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.prof
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
||||
.glide/
|
||||
|
||||
# Gogland
|
||||
.idea/
|
|
@ -0,0 +1,18 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.7
|
||||
- tip
|
||||
|
||||
# sudo=false makes the build run using a container
|
||||
sudo: false
|
||||
|
||||
before_install:
|
||||
- go get github.com/mattn/goveralls
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
- go get golang.org/x/tools/cmd/goimports
|
||||
- go get github.com/golang/lint/golint
|
||||
script:
|
||||
- gofiles=$(find ./ -name '*.go') && [ -z "$gofiles" ] || unformatted=$(goimports -l $gofiles) && [ -z "$unformatted" ] || (echo >&2 "Go files must be formatted with gofmt. Following files has problem:\n $unformatted" && false)
|
||||
- golint ./... # This won't break the build, just show warnings
|
||||
- $HOME/gopath/bin/goveralls -service=travis-ci
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue