diff --git a/builtin/providers/azurerm/config.go b/builtin/providers/azurerm/config.go index c0dcb8041..acd66ce49 100644 --- a/builtin/providers/azurerm/config.go +++ b/builtin/providers/azurerm/config.go @@ -8,6 +8,7 @@ import ( "github.com/Azure/azure-sdk-for-go/arm/cdn" "github.com/Azure/azure-sdk-for-go/arm/compute" + "github.com/Azure/azure-sdk-for-go/arm/keyvault" "github.com/Azure/azure-sdk-for-go/arm/network" "github.com/Azure/azure-sdk-for-go/arm/resources/resources" "github.com/Azure/azure-sdk-for-go/arm/scheduler" @@ -75,6 +76,8 @@ type ArmClient struct { serviceBusNamespacesClient servicebus.NamespacesClient serviceBusTopicsClient servicebus.TopicsClient serviceBusSubscriptionsClient servicebus.SubscriptionsClient + + keyVaultClient keyvault.VaultsClient } func withRequestLogging() autorest.SendDecorator { @@ -374,6 +377,12 @@ func (c *Config) getArmClient() (*ArmClient, error) { sbsc.Sender = autorest.CreateSender(withRequestLogging()) client.serviceBusSubscriptionsClient = sbsc + kvc := keyvault.NewVaultsClient(c.SubscriptionID) + setUserAgent(&kvc.Client) + kvc.Authorizer = spt + kvc.Sender = autorest.CreateSender(withRequestLogging()) + client.keyVaultClient = kvc + return &client, nil } diff --git a/builtin/providers/azurerm/import_arm_key_vault_test.go b/builtin/providers/azurerm/import_arm_key_vault_test.go new file mode 100644 index 000000000..087902e02 --- /dev/null +++ b/builtin/providers/azurerm/import_arm_key_vault_test.go @@ -0,0 +1,33 @@ +package azurerm + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccAzureRMKeyVault_importBasic(t *testing.T) { + resourceName := "azurerm_key_vault.test" + + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMKeyVault_basic, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: config, + }, + + resource.TestStep{ + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} diff --git a/builtin/providers/azurerm/provider.go b/builtin/providers/azurerm/provider.go index 9b56ac07e..ed74f849d 100644 --- a/builtin/providers/azurerm/provider.go +++ b/builtin/providers/azurerm/provider.go @@ -61,6 +61,7 @@ func Provider() terraform.ResourceProvider { "azurerm_lb_probe": resourceArmLoadBalancerProbe(), "azurerm_lb_rule": resourceArmLoadBalancerRule(), + "azurerm_key_vault": resourceArmKeyVault(), "azurerm_local_network_gateway": resourceArmLocalNetworkGateway(), "azurerm_network_interface": resourceArmNetworkInterface(), "azurerm_network_security_group": resourceArmNetworkSecurityGroup(), @@ -191,7 +192,7 @@ func registerAzureResourceProvidersWithSubscription(client *riviera.Client) erro var err error providerRegistrationOnce.Do(func() { // We register Microsoft.Compute during client initialization - providers := []string{"Microsoft.Network", "Microsoft.Cdn", "Microsoft.Storage", "Microsoft.Sql", "Microsoft.Search", "Microsoft.Resources", "Microsoft.ServiceBus"} + providers := []string{"Microsoft.Network", "Microsoft.Cdn", "Microsoft.Storage", "Microsoft.Sql", "Microsoft.Search", "Microsoft.Resources", "Microsoft.ServiceBus", "Microsoft.KeyVault"} var wg sync.WaitGroup wg.Add(len(providers)) diff --git a/builtin/providers/azurerm/resource_arm_key_vault.go b/builtin/providers/azurerm/resource_arm_key_vault.go new file mode 100644 index 000000000..3688bd116 --- /dev/null +++ b/builtin/providers/azurerm/resource_arm_key_vault.go @@ -0,0 +1,329 @@ +package azurerm + +import ( + "fmt" + "log" + "net/http" + + "github.com/Azure/azure-sdk-for-go/arm/keyvault" + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/helper/validation" + "github.com/satori/uuid" +) + +// As can be seen in the API definition, the Sku Family only supports the value +// `A` and is a required field +// https://github.com/Azure/azure-rest-api-specs/blob/master/arm-keyvault/2015-06-01/swagger/keyvault.json#L239 +var armKeyVaultSkuFamily = "A" + +func resourceArmKeyVault() *schema.Resource { + return &schema.Resource{ + Create: resourceArmKeyVaultCreate, + Read: resourceArmKeyVaultRead, + Update: resourceArmKeyVaultCreate, + Delete: resourceArmKeyVaultDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + StateFunc: azureRMNormalizeLocation, + }, + + "resource_group_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "sku": { + Type: schema.TypeSet, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{ + string(keyvault.Standard), + string(keyvault.Premium), + }, false), + }, + }, + }, + }, + + "vault_uri": { + Type: schema.TypeString, + Computed: true, + }, + + "tenant_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateUUID, + }, + + "access_policy": { + Type: schema.TypeList, + Optional: true, + MinItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "tenant_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateUUID, + }, + "object_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateUUID, + }, + "key_permissions": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + string(keyvault.All), + string(keyvault.Backup), + string(keyvault.Create), + string(keyvault.Decrypt), + string(keyvault.Delete), + string(keyvault.Encrypt), + string(keyvault.Get), + string(keyvault.Import), + string(keyvault.List), + string(keyvault.Restore), + string(keyvault.Sign), + string(keyvault.Unwrapkey), + string(keyvault.Update), + string(keyvault.Verify), + string(keyvault.Wrapkey), + }, false), + }, + }, + "secret_permissions": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + string(keyvault.SecretPermissionsAll), + string(keyvault.SecretPermissionsDelete), + string(keyvault.SecretPermissionsGet), + string(keyvault.SecretPermissionsList), + string(keyvault.SecretPermissionsSet), + }, false), + }, + }, + }, + }, + }, + + "enabled_for_deployment": { + Type: schema.TypeBool, + Optional: true, + }, + + "enabled_for_disk_encryption": { + Type: schema.TypeBool, + Optional: true, + }, + + "enabled_for_template_deployment": { + Type: schema.TypeBool, + Optional: true, + }, + + "tags": tagsSchema(), + }, + } +} + +func resourceArmKeyVaultCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).keyVaultClient + log.Printf("[INFO] preparing arguments for Azure ARM KeyVault creation.") + + name := d.Get("name").(string) + location := d.Get("location").(string) + resGroup := d.Get("resource_group_name").(string) + tenantUUID := uuid.FromStringOrNil(d.Get("tenant_id").(string)) + enabledForDeployment := d.Get("enabled_for_deployment").(bool) + enabledForDiskEncryption := d.Get("enabled_for_disk_encryption").(bool) + enabledForTemplateDeployment := d.Get("enabled_for_template_deployment").(bool) + tags := d.Get("tags").(map[string]interface{}) + + parameters := keyvault.VaultCreateOrUpdateParameters{ + Location: &location, + Properties: &keyvault.VaultProperties{ + TenantID: &tenantUUID, + Sku: expandKeyVaultSku(d), + AccessPolicies: expandKeyVaultAccessPolicies(d), + EnabledForDeployment: &enabledForDeployment, + EnabledForDiskEncryption: &enabledForDiskEncryption, + EnabledForTemplateDeployment: &enabledForTemplateDeployment, + }, + Tags: expandTags(tags), + } + + _, err := client.CreateOrUpdate(resGroup, name, parameters) + if err != nil { + return err + } + + read, err := client.Get(resGroup, name) + if err != nil { + return err + } + if read.ID == nil { + return fmt.Errorf("Cannot read KeyVault %s (resource group %s) ID", name, resGroup) + } + + d.SetId(*read.ID) + + return resourceArmKeyVaultRead(d, meta) +} + +func resourceArmKeyVaultRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).keyVaultClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["vaults"] + + resp, err := client.Get(resGroup, name) + if err != nil { + return fmt.Errorf("Error making Read request on Azure KeyVault %s: %s", name, err) + } + if resp.StatusCode == http.StatusNotFound { + d.SetId("") + return nil + } + + d.Set("name", resp.Name) + d.Set("resource_group_name", resGroup) + d.Set("location", azureRMNormalizeLocation(*resp.Location)) + d.Set("tenant_id", resp.Properties.TenantID.String()) + d.Set("enabled_for_deployment", resp.Properties.EnabledForDeployment) + d.Set("enabled_for_disk_encryption", resp.Properties.EnabledForDiskEncryption) + d.Set("enabled_for_template_deployment", resp.Properties.EnabledForTemplateDeployment) + d.Set("sku", flattenKeyVaultSku(resp.Properties.Sku)) + d.Set("access_policy", flattenKeyVaultAccessPolicies(resp.Properties.AccessPolicies)) + d.Set("vault_uri", resp.Properties.VaultURI) + + flattenAndSetTags(d, resp.Tags) + + return nil +} + +func resourceArmKeyVaultDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).keyVaultClient + + id, err := parseAzureResourceID(d.Id()) + if err != nil { + return err + } + resGroup := id.ResourceGroup + name := id.Path["vaults"] + + _, err = client.Delete(resGroup, name) + + return err +} + +func expandKeyVaultSku(d *schema.ResourceData) *keyvault.Sku { + skuSets := d.Get("sku").(*schema.Set).List() + sku := skuSets[0].(map[string]interface{}) + + return &keyvault.Sku{ + Family: &armKeyVaultSkuFamily, + Name: keyvault.SkuName(sku["name"].(string)), + } +} + +func expandKeyVaultAccessPolicies(d *schema.ResourceData) *[]keyvault.AccessPolicyEntry { + policies := d.Get("access_policy").([]interface{}) + result := make([]keyvault.AccessPolicyEntry, 0, len(policies)) + + for _, policySet := range policies { + policyRaw := policySet.(map[string]interface{}) + + keyPermissionsRaw := policyRaw["key_permissions"].([]interface{}) + keyPermissions := []keyvault.KeyPermissions{} + for _, permission := range keyPermissionsRaw { + keyPermissions = append(keyPermissions, keyvault.KeyPermissions(permission.(string))) + } + + secretPermissionsRaw := policyRaw["secret_permissions"].([]interface{}) + secretPermissions := []keyvault.SecretPermissions{} + for _, permission := range secretPermissionsRaw { + secretPermissions = append(secretPermissions, keyvault.SecretPermissions(permission.(string))) + } + + policy := keyvault.AccessPolicyEntry{ + Permissions: &keyvault.Permissions{ + Keys: &keyPermissions, + Secrets: &secretPermissions, + }, + } + + tenantUUID := uuid.FromStringOrNil(policyRaw["tenant_id"].(string)) + policy.TenantID = &tenantUUID + objectUUID := uuid.FromStringOrNil(policyRaw["object_id"].(string)) + policy.ObjectID = &objectUUID + + result = append(result, policy) + } + + return &result +} + +func flattenKeyVaultSku(sku *keyvault.Sku) []interface{} { + result := map[string]interface{}{ + "name": string(sku.Name), + } + + return []interface{}{result} +} + +func flattenKeyVaultAccessPolicies(policies *[]keyvault.AccessPolicyEntry) []interface{} { + result := make([]interface{}, 0, len(*policies)) + + for _, policy := range *policies { + policyRaw := make(map[string]interface{}) + + keyPermissionsRaw := make([]interface{}, 0, len(*policy.Permissions.Keys)) + for _, keyPermission := range *policy.Permissions.Keys { + keyPermissionsRaw = append(keyPermissionsRaw, string(keyPermission)) + } + + secretPermissionsRaw := make([]interface{}, 0, len(*policy.Permissions.Secrets)) + for _, secretPermission := range *policy.Permissions.Secrets { + secretPermissionsRaw = append(secretPermissionsRaw, string(secretPermission)) + } + + policyRaw["tenant_id"] = policy.TenantID.String() + policyRaw["object_id"] = policy.ObjectID.String() + policyRaw["key_permissions"] = keyPermissionsRaw + policyRaw["secret_permissions"] = secretPermissionsRaw + + result = append(result, policyRaw) + } + + return result +} diff --git a/builtin/providers/azurerm/resource_arm_key_vault_test.go b/builtin/providers/azurerm/resource_arm_key_vault_test.go new file mode 100644 index 000000000..9b9bb8733 --- /dev/null +++ b/builtin/providers/azurerm/resource_arm_key_vault_test.go @@ -0,0 +1,198 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureRMKeyVault_basic(t *testing.T) { + ri := acctest.RandInt() + config := fmt.Sprintf(testAccAzureRMKeyVault_basic, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKeyVaultExists("azurerm_key_vault.test"), + ), + }, + }, + }) +} + +func TestAccAzureRMKeyVault_update(t *testing.T) { + ri := acctest.RandInt() + preConfig := fmt.Sprintf(testAccAzureRMKeyVault_basic, ri, ri) + postConfig := fmt.Sprintf(testAccAzureRMKeyVault_update, ri, ri) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMKeyVaultDestroy, + Steps: []resource.TestStep{ + { + Config: preConfig, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMKeyVaultExists("azurerm_key_vault.test"), + resource.TestCheckResourceAttr("azurerm_key_vault.test", "access_policy.0.key_permissions.0", "all"), + resource.TestCheckResourceAttr("azurerm_key_vault.test", "access_policy.0.secret_permissions.0", "all"), + resource.TestCheckResourceAttr("azurerm_key_vault.test", "tags.environment", "Production"), + ), + }, + { + Config: postConfig, + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("azurerm_key_vault.test", "access_policy.0.key_permissions.0", "get"), + resource.TestCheckResourceAttr("azurerm_key_vault.test", "access_policy.0.secret_permissions.0", "get"), + resource.TestCheckResourceAttr("azurerm_key_vault.test", "enabled_for_deployment", "true"), + resource.TestCheckResourceAttr("azurerm_key_vault.test", "enabled_for_disk_encryption", "true"), + resource.TestCheckResourceAttr("azurerm_key_vault.test", "enabled_for_template_deployment", "true"), + resource.TestCheckResourceAttr("azurerm_key_vault.test", "tags.environment", "Staging"), + ), + }, + }, + }) +} + +func testCheckAzureRMKeyVaultDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*ArmClient).keyVaultClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_key_vault" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := client.Get(resourceGroup, name) + if err != nil { + if resp.StatusCode == http.StatusNotFound { + return nil + } + return err + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Key Vault still exists:\n%#v", resp.Properties) + } + } + + return nil +} + +func testCheckAzureRMKeyVaultExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + vaultName := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for vault: %s", vaultName) + } + + client := testAccProvider.Meta().(*ArmClient).keyVaultClient + + resp, err := client.Get(resourceGroup, vaultName) + if err != nil { + return fmt.Errorf("Bad: Get on keyVaultClient: %s", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Vault %q (resource group: %q) does not exist", vaultName, resourceGroup) + } + + return nil + } +} + +var testAccAzureRMKeyVault_basic = ` +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US" +} + +resource "azurerm_key_vault" "test" { + name = "vault%d" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + + sku { + name = "premium" + } + + access_policy { + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${data.azurerm_client_config.current.client_id}" + + key_permissions = [ + "all" + ] + + secret_permissions = [ + "all" + ] + } + + tags { + environment = "Production" + } +} +` + +var testAccAzureRMKeyVault_update = ` +data "azurerm_client_config" "current" {} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%d" + location = "West US" +} + +resource "azurerm_key_vault" "test" { + name = "vault%d" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + + sku { + name = "premium" + } + + access_policy { + tenant_id = "${data.azurerm_client_config.current.tenant_id}" + object_id = "${data.azurerm_client_config.current.client_id}" + + key_permissions = [ + "get" + ] + + secret_permissions = [ + "get" + ] + } + + enabled_for_deployment = true + enabled_for_disk_encryption = true + enabled_for_template_deployment = true + + tags { + environment = "Staging" + } +} +` diff --git a/builtin/providers/azurerm/validators.go b/builtin/providers/azurerm/validators.go index d6fa6a943..2b8ef82f2 100644 --- a/builtin/providers/azurerm/validators.go +++ b/builtin/providers/azurerm/validators.go @@ -1,6 +1,10 @@ package azurerm -import "fmt" +import ( + "fmt" + + "github.com/satori/uuid" +) func validateJsonString(v interface{}, k string) (ws []string, errors []error) { if _, err := normalizeJsonString(v); err != nil { @@ -8,3 +12,10 @@ func validateJsonString(v interface{}, k string) (ws []string, errors []error) { } return } + +func validateUUID(v interface{}, k string) (ws []string, errors []error) { + if _, err := uuid.FromString(v.(string)); err != nil { + errors = append(errors, fmt.Errorf("%q is an invalid UUUID: %s", k, err)) + } + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/keyvault/client.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/keyvault/client.go new file mode 100644 index 000000000..77581b446 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/keyvault/client.go @@ -0,0 +1,59 @@ +// Package keyvault implements the Azure ARM Keyvault service API version +// 2015-06-01. +// +// The Azure management API provides a RESTful set of web services that +// interact with Azure Key Vault. +package keyvault + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" +) + +const ( + // APIVersion is the version of the Keyvault + APIVersion = "2015-06-01" + + // DefaultBaseURI is the default URI used for the service Keyvault + DefaultBaseURI = "https://management.azure.com" +) + +// ManagementClient is the base client for Keyvault. +type ManagementClient struct { + autorest.Client + BaseURI string + APIVersion string + SubscriptionID string +} + +// New creates an instance of the ManagementClient client. +func New(subscriptionID string) ManagementClient { + return NewWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewWithBaseURI creates an instance of the ManagementClient client. +func NewWithBaseURI(baseURI string, subscriptionID string) ManagementClient { + return ManagementClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + APIVersion: APIVersion, + SubscriptionID: subscriptionID, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/keyvault/models.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/keyvault/models.go new file mode 100644 index 000000000..b3573d2f1 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/keyvault/models.go @@ -0,0 +1,172 @@ +package keyvault + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/to" + "github.com/satori/uuid" + "net/http" +) + +// KeyPermissions enumerates the values for key permissions. +type KeyPermissions string + +const ( + // All specifies the all state for key permissions. + All KeyPermissions = "all" + // Backup specifies the backup state for key permissions. + Backup KeyPermissions = "backup" + // Create specifies the create state for key permissions. + Create KeyPermissions = "create" + // Decrypt specifies the decrypt state for key permissions. + Decrypt KeyPermissions = "decrypt" + // Delete specifies the delete state for key permissions. + Delete KeyPermissions = "delete" + // Encrypt specifies the encrypt state for key permissions. + Encrypt KeyPermissions = "encrypt" + // Get specifies the get state for key permissions. + Get KeyPermissions = "get" + // Import specifies the import state for key permissions. + Import KeyPermissions = "import" + // List specifies the list state for key permissions. + List KeyPermissions = "list" + // Restore specifies the restore state for key permissions. + Restore KeyPermissions = "restore" + // Sign specifies the sign state for key permissions. + Sign KeyPermissions = "sign" + // Unwrapkey specifies the unwrapkey state for key permissions. + Unwrapkey KeyPermissions = "unwrapkey" + // Update specifies the update state for key permissions. + Update KeyPermissions = "update" + // Verify specifies the verify state for key permissions. + Verify KeyPermissions = "verify" + // Wrapkey specifies the wrapkey state for key permissions. + Wrapkey KeyPermissions = "wrapkey" +) + +// SecretPermissions enumerates the values for secret permissions. +type SecretPermissions string + +const ( + // SecretPermissionsAll specifies the secret permissions all state for + // secret permissions. + SecretPermissionsAll SecretPermissions = "all" + // SecretPermissionsDelete specifies the secret permissions delete state + // for secret permissions. + SecretPermissionsDelete SecretPermissions = "delete" + // SecretPermissionsGet specifies the secret permissions get state for + // secret permissions. + SecretPermissionsGet SecretPermissions = "get" + // SecretPermissionsList specifies the secret permissions list state for + // secret permissions. + SecretPermissionsList SecretPermissions = "list" + // SecretPermissionsSet specifies the secret permissions set state for + // secret permissions. + SecretPermissionsSet SecretPermissions = "set" +) + +// SkuName enumerates the values for sku name. +type SkuName string + +const ( + // Premium specifies the premium state for sku name. + Premium SkuName = "premium" + // Standard specifies the standard state for sku name. + Standard SkuName = "standard" +) + +// AccessPolicyEntry is an array of 0 to 16 identities that have access to the +// key vault. All identities in the array must use the same tenant ID as the +// key vault's tenant ID. +type AccessPolicyEntry struct { + TenantID *uuid.UUID `json:"tenantId,omitempty"` + ObjectID *uuid.UUID `json:"objectId,omitempty"` + ApplicationID *uuid.UUID `json:"applicationId,omitempty"` + Permissions *Permissions `json:"permissions,omitempty"` +} + +// Permissions is permissions the identity has for keys and secrets +type Permissions struct { + Keys *[]KeyPermissions `json:"keys,omitempty"` + Secrets *[]SecretPermissions `json:"secrets,omitempty"` +} + +// Resource is key Vault 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"` +} + +// Sku is sKU details +type Sku struct { + Family *string `json:"family,omitempty"` + Name SkuName `json:"name,omitempty"` +} + +// Vault is resource information with extended details. +type Vault struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *VaultProperties `json:"properties,omitempty"` +} + +// VaultCreateOrUpdateParameters is parameters for creating or updating a vault +type VaultCreateOrUpdateParameters struct { + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + Properties *VaultProperties `json:"properties,omitempty"` +} + +// VaultListResult is list of vaults +type VaultListResult struct { + autorest.Response `json:"-"` + Value *[]Vault `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// VaultListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client VaultListResult) VaultListResultPreparer() (*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))) +} + +// VaultProperties is properties of the vault +type VaultProperties struct { + VaultURI *string `json:"vaultUri,omitempty"` + TenantID *uuid.UUID `json:"tenantId,omitempty"` + Sku *Sku `json:"sku,omitempty"` + AccessPolicies *[]AccessPolicyEntry `json:"accessPolicies,omitempty"` + EnabledForDeployment *bool `json:"enabledForDeployment,omitempty"` + EnabledForDiskEncryption *bool `json:"enabledForDiskEncryption,omitempty"` + EnabledForTemplateDeployment *bool `json:"enabledForTemplateDeployment,omitempty"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/keyvault/vaults.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/keyvault/vaults.go new file mode 100644 index 000000000..0464d9c61 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/keyvault/vaults.go @@ -0,0 +1,427 @@ +package keyvault + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// VaultsClient is the the Azure management API provides a RESTful set of web +// services that interact with Azure Key Vault. +type VaultsClient struct { + ManagementClient +} + +// NewVaultsClient creates an instance of the VaultsClient client. +func NewVaultsClient(subscriptionID string) VaultsClient { + return NewVaultsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewVaultsClientWithBaseURI creates an instance of the VaultsClient client. +func NewVaultsClientWithBaseURI(baseURI string, subscriptionID string) VaultsClient { + return VaultsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate create or update a key vault in the specified subscription. +// +// resourceGroupName is the name of the Resource Group to which the server +// belongs. vaultName is name of the vault parameters is parameters to create +// or update the vault +func (client VaultsClient) CreateOrUpdate(resourceGroupName string, vaultName string, parameters VaultCreateOrUpdateParameters) (result Vault, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: vaultName, + Constraints: []validation.Constraint{{Target: "vaultName", Name: validation.Pattern, Rule: `^[a-zA-Z0-9-]{3,24}$`, Chain: nil}}}, + {TargetValue: parameters, + Constraints: []validation.Constraint{{Target: "parameters.Location", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "parameters.Properties", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "parameters.Properties.Sku", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "parameters.Properties.Sku.Family", Name: validation.Null, Rule: true, Chain: nil}}}, + {Target: "parameters.Properties.AccessPolicies", Name: validation.Null, Rule: true, + Chain: []validation.Constraint{{Target: "parameters.Properties.AccessPolicies", Name: validation.MaxItems, Rule: 16, Chain: nil}}}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "keyvault.VaultsClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, vaultName, parameters) + if err != nil { + return result, autorest.NewErrorWithError(err, "keyvault.VaultsClient", "CreateOrUpdate", nil, "Failure preparing request") + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "keyvault.VaultsClient", "CreateOrUpdate", resp, "Failure sending request") + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "keyvault.VaultsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client VaultsClient) CreateOrUpdatePreparer(resourceGroupName string, vaultName string, parameters VaultCreateOrUpdateParameters) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vaultName": autorest.Encode("path", vaultName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.KeyVault/vaults/{vaultName}", pathParameters), + autorest.WithJSON(parameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client VaultsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client VaultsClient) CreateOrUpdateResponder(resp *http.Response) (result Vault, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusCreated, http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete deletes the specified Azure key vault. +// +// resourceGroupName is the name of the Resource Group to which the vault +// belongs. vaultName is the name of the vault to delete +func (client VaultsClient) Delete(resourceGroupName string, vaultName string) (result autorest.Response, err error) { + req, err := client.DeletePreparer(resourceGroupName, vaultName) + if err != nil { + return result, autorest.NewErrorWithError(err, "keyvault.VaultsClient", "Delete", nil, "Failure preparing request") + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + return result, autorest.NewErrorWithError(err, "keyvault.VaultsClient", "Delete", resp, "Failure sending request") + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "keyvault.VaultsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client VaultsClient) DeletePreparer(resourceGroupName string, vaultName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vaultName": autorest.Encode("path", vaultName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.KeyVault/vaults/{vaultName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client VaultsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client VaultsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get gets the specified Azure key vault. +// +// resourceGroupName is the name of the Resource Group to which the vault +// belongs. vaultName is the name of the vault. +func (client VaultsClient) Get(resourceGroupName string, vaultName string) (result Vault, err error) { + req, err := client.GetPreparer(resourceGroupName, vaultName) + if err != nil { + return result, autorest.NewErrorWithError(err, "keyvault.VaultsClient", "Get", nil, "Failure preparing request") + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "keyvault.VaultsClient", "Get", resp, "Failure sending request") + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "keyvault.VaultsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client VaultsClient) GetPreparer(resourceGroupName string, vaultName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + "vaultName": autorest.Encode("path", vaultName), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.KeyVault/vaults/{vaultName}", 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 VaultsClient) 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 VaultsClient) GetResponder(resp *http.Response) (result Vault, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List the List operation gets information about the vaults associated with +// the subscription. +// +// filter is the filter to apply on the operation. top is maximum number of +// results to return. +func (client VaultsClient) List(filter string, top *int32) (result VaultListResult, err error) { + req, err := client.ListPreparer(filter, top) + if err != nil { + return result, autorest.NewErrorWithError(err, "keyvault.VaultsClient", "List", nil, "Failure preparing request") + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "keyvault.VaultsClient", "List", resp, "Failure sending request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "keyvault.VaultsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client VaultsClient) ListPreparer(filter string, top *int32) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "$filter": autorest.Encode("query", filter), + "api-version": client.APIVersion, + } + if top != nil { + queryParameters["$top"] = autorest.Encode("query", *top) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/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 VaultsClient) 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 VaultsClient) ListResponder(resp *http.Response) (result VaultListResult, 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 VaultsClient) ListNextResults(lastResults VaultListResult) (result VaultListResult, err error) { + req, err := lastResults.VaultListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "keyvault.VaultsClient", "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, "keyvault.VaultsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "keyvault.VaultsClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListByResourceGroup the List operation gets information about the vaults +// associated with the subscription and within the specified resource group. +// +// resourceGroupName is the name of the Resource Group to which the vault +// belongs. top is maximum number of results to return. +func (client VaultsClient) ListByResourceGroup(resourceGroupName string, top *int32) (result VaultListResult, err error) { + req, err := client.ListByResourceGroupPreparer(resourceGroupName, top) + if err != nil { + return result, autorest.NewErrorWithError(err, "keyvault.VaultsClient", "ListByResourceGroup", nil, "Failure preparing request") + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "keyvault.VaultsClient", "ListByResourceGroup", resp, "Failure sending request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "keyvault.VaultsClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client VaultsClient) ListByResourceGroupPreparer(resourceGroupName string, top *int32) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + queryParameters := map[string]interface{}{ + "api-version": client.APIVersion, + } + if top != nil { + queryParameters["$top"] = autorest.Encode("query", *top) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.KeyVault/vaults", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client VaultsClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client VaultsClient) ListByResourceGroupResponder(resp *http.Response) (result VaultListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByResourceGroupNextResults retrieves the next set of results, if any. +func (client VaultsClient) ListByResourceGroupNextResults(lastResults VaultListResult) (result VaultListResult, err error) { + req, err := lastResults.VaultListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "keyvault.VaultsClient", "ListByResourceGroup", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "keyvault.VaultsClient", "ListByResourceGroup", resp, "Failure sending next results request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "keyvault.VaultsClient", "ListByResourceGroup", resp, "Failure responding to next results request") + } + + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/keyvault/version.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/keyvault/version.go new file mode 100644 index 000000000..5acec43b0 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/keyvault/version.go @@ -0,0 +1,43 @@ +package keyvault + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 0.17.0.0 +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. + +import ( + "fmt" +) + +const ( + major = "5" + minor = "0" + patch = "0" + // Always begin a "tag" with a dash (as per http://semver.org) + tag = "-beta" + semVerFormat = "%s.%s.%s%s" + userAgentFormat = "Azure-SDK-for-Go/%s arm-%s/%s" +) + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return fmt.Sprintf(userAgentFormat, Version(), "keyvault", "2015-06-01") +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return fmt.Sprintf(semVerFormat, major, minor, patch, tag) +} diff --git a/vendor/github.com/satori/uuid/LICENSE b/vendor/github.com/satori/uuid/LICENSE new file mode 100644 index 000000000..488357b8a --- /dev/null +++ b/vendor/github.com/satori/uuid/LICENSE @@ -0,0 +1,20 @@ +Copyright (C) 2013-2016 by Maxim Bublis + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/satori/uuid/README.md b/vendor/github.com/satori/uuid/README.md new file mode 100644 index 000000000..b6aad1c81 --- /dev/null +++ b/vendor/github.com/satori/uuid/README.md @@ -0,0 +1,65 @@ +# UUID package for Go language + +[![Build Status](https://travis-ci.org/satori/go.uuid.png?branch=master)](https://travis-ci.org/satori/go.uuid) +[![Coverage Status](https://coveralls.io/repos/github/satori/go.uuid/badge.svg?branch=master)](https://coveralls.io/github/satori/go.uuid) +[![GoDoc](http://godoc.org/github.com/satori/go.uuid?status.png)](http://godoc.org/github.com/satori/go.uuid) + +This package provides pure Go implementation of Universally Unique Identifier (UUID). Supported both creation and parsing of UUIDs. + +With 100% test coverage and benchmarks out of box. + +Supported versions: +* Version 1, based on timestamp and MAC address (RFC 4122) +* Version 2, based on timestamp, MAC address and POSIX UID/GID (DCE 1.1) +* Version 3, based on MD5 hashing (RFC 4122) +* Version 4, based on random numbers (RFC 4122) +* Version 5, based on SHA-1 hashing (RFC 4122) + +## Installation + +Use the `go` command: + + $ go get github.com/satori/go.uuid + +## Requirements + +UUID package requires Go >= 1.2. + +## Example + +```go +package main + +import ( + "fmt" + "github.com/satori/go.uuid" +) + +func main() { + // Creating UUID Version 4 + u1 := uuid.NewV4() + fmt.Printf("UUIDv4: %s\n", u1) + + // Parsing UUID from string input + u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") + if err != nil { + fmt.Printf("Something gone wrong: %s", err) + } + fmt.Printf("Successfully parsed: %s", u2) +} +``` + +## Documentation + +[Documentation](http://godoc.org/github.com/satori/go.uuid) is hosted at GoDoc project. + +## Links +* [RFC 4122](http://tools.ietf.org/html/rfc4122) +* [DCE 1.1: Authentication and Security Services](http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01) + +## Copyright + +Copyright (C) 2013-2016 by Maxim Bublis . + +UUID package released under MIT License. +See [LICENSE](https://github.com/satori/go.uuid/blob/master/LICENSE) for details. diff --git a/vendor/github.com/satori/uuid/uuid.go b/vendor/github.com/satori/uuid/uuid.go new file mode 100644 index 000000000..295f3fc2c --- /dev/null +++ b/vendor/github.com/satori/uuid/uuid.go @@ -0,0 +1,481 @@ +// Copyright (C) 2013-2015 by Maxim Bublis +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// Package uuid provides implementation of Universally Unique Identifier (UUID). +// Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and +// version 2 (as specified in DCE 1.1). +package uuid + +import ( + "bytes" + "crypto/md5" + "crypto/rand" + "crypto/sha1" + "database/sql/driver" + "encoding/binary" + "encoding/hex" + "fmt" + "hash" + "net" + "os" + "sync" + "time" +) + +// UUID layout variants. +const ( + VariantNCS = iota + VariantRFC4122 + VariantMicrosoft + VariantFuture +) + +// UUID DCE domains. +const ( + DomainPerson = iota + DomainGroup + DomainOrg +) + +// Difference in 100-nanosecond intervals between +// UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970). +const epochStart = 122192928000000000 + +// Used in string method conversion +const dash byte = '-' + +// UUID v1/v2 storage. +var ( + storageMutex sync.Mutex + storageOnce sync.Once + epochFunc = unixTimeFunc + clockSequence uint16 + lastTime uint64 + hardwareAddr [6]byte + posixUID = uint32(os.Getuid()) + posixGID = uint32(os.Getgid()) +) + +// String parse helpers. +var ( + urnPrefix = []byte("urn:uuid:") + byteGroups = []int{8, 4, 4, 4, 12} +) + +func initClockSequence() { + buf := make([]byte, 2) + safeRandom(buf) + clockSequence = binary.BigEndian.Uint16(buf) +} + +func initHardwareAddr() { + interfaces, err := net.Interfaces() + if err == nil { + for _, iface := range interfaces { + if len(iface.HardwareAddr) >= 6 { + copy(hardwareAddr[:], iface.HardwareAddr) + return + } + } + } + + // Initialize hardwareAddr randomly in case + // of real network interfaces absence + safeRandom(hardwareAddr[:]) + + // Set multicast bit as recommended in RFC 4122 + hardwareAddr[0] |= 0x01 +} + +func initStorage() { + initClockSequence() + initHardwareAddr() +} + +func safeRandom(dest []byte) { + if _, err := rand.Read(dest); err != nil { + panic(err) + } +} + +// Returns difference in 100-nanosecond intervals between +// UUID epoch (October 15, 1582) and current time. +// This is default epoch calculation function. +func unixTimeFunc() uint64 { + return epochStart + uint64(time.Now().UnixNano()/100) +} + +// UUID representation compliant with specification +// described in RFC 4122. +type UUID [16]byte + +// NullUUID can be used with the standard sql package to represent a +// UUID value that can be NULL in the database +type NullUUID struct { + UUID UUID + Valid bool +} + +// The nil UUID is special form of UUID that is specified to have all +// 128 bits set to zero. +var Nil = UUID{} + +// Predefined namespace UUIDs. +var ( + NamespaceDNS, _ = FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") + NamespaceURL, _ = FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8") + NamespaceOID, _ = FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8") + NamespaceX500, _ = FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8") +) + +// And returns result of binary AND of two UUIDs. +func And(u1 UUID, u2 UUID) UUID { + u := UUID{} + for i := 0; i < 16; i++ { + u[i] = u1[i] & u2[i] + } + return u +} + +// Or returns result of binary OR of two UUIDs. +func Or(u1 UUID, u2 UUID) UUID { + u := UUID{} + for i := 0; i < 16; i++ { + u[i] = u1[i] | u2[i] + } + return u +} + +// Equal returns true if u1 and u2 equals, otherwise returns false. +func Equal(u1 UUID, u2 UUID) bool { + return bytes.Equal(u1[:], u2[:]) +} + +// Version returns algorithm version used to generate UUID. +func (u UUID) Version() uint { + return uint(u[6] >> 4) +} + +// Variant returns UUID layout variant. +func (u UUID) Variant() uint { + switch { + case (u[8] & 0x80) == 0x00: + return VariantNCS + case (u[8]&0xc0)|0x80 == 0x80: + return VariantRFC4122 + case (u[8]&0xe0)|0xc0 == 0xc0: + return VariantMicrosoft + } + return VariantFuture +} + +// Bytes returns bytes slice representation of UUID. +func (u UUID) Bytes() []byte { + return u[:] +} + +// Returns canonical string representation of UUID: +// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. +func (u UUID) String() string { + buf := make([]byte, 36) + + hex.Encode(buf[0:8], u[0:4]) + buf[8] = dash + hex.Encode(buf[9:13], u[4:6]) + buf[13] = dash + hex.Encode(buf[14:18], u[6:8]) + buf[18] = dash + hex.Encode(buf[19:23], u[8:10]) + buf[23] = dash + hex.Encode(buf[24:], u[10:]) + + return string(buf) +} + +// SetVersion sets version bits. +func (u *UUID) SetVersion(v byte) { + u[6] = (u[6] & 0x0f) | (v << 4) +} + +// SetVariant sets variant bits as described in RFC 4122. +func (u *UUID) SetVariant() { + u[8] = (u[8] & 0xbf) | 0x80 +} + +// MarshalText implements the encoding.TextMarshaler interface. +// The encoding is the same as returned by String. +func (u UUID) MarshalText() (text []byte, err error) { + text = []byte(u.String()) + return +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +// Following formats are supported: +// "6ba7b810-9dad-11d1-80b4-00c04fd430c8", +// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", +// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" +func (u *UUID) UnmarshalText(text []byte) (err error) { + if len(text) < 32 { + err = fmt.Errorf("uuid: UUID string too short: %s", text) + return + } + + t := text[:] + braced := false + + if bytes.Equal(t[:9], urnPrefix) { + t = t[9:] + } else if t[0] == '{' { + braced = true + t = t[1:] + } + + b := u[:] + + for i, byteGroup := range byteGroups { + if i > 0 { + if t[0] != '-' { + err = fmt.Errorf("uuid: invalid string format") + return + } + t = t[1:] + } + + if len(t) < byteGroup { + err = fmt.Errorf("uuid: UUID string too short: %s", text) + return + } + + if i == 4 && len(t) > byteGroup && + ((braced && t[byteGroup] != '}') || len(t[byteGroup:]) > 1 || !braced) { + err = fmt.Errorf("uuid: UUID string too long: %s", text) + return + } + + _, err = hex.Decode(b[:byteGroup/2], t[:byteGroup]) + if err != nil { + return + } + + t = t[byteGroup:] + b = b[byteGroup/2:] + } + + return +} + +// MarshalBinary implements the encoding.BinaryMarshaler interface. +func (u UUID) MarshalBinary() (data []byte, err error) { + data = u.Bytes() + return +} + +// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. +// It will return error if the slice isn't 16 bytes long. +func (u *UUID) UnmarshalBinary(data []byte) (err error) { + if len(data) != 16 { + err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data)) + return + } + copy(u[:], data) + + return +} + +// Value implements the driver.Valuer interface. +func (u UUID) Value() (driver.Value, error) { + return u.String(), nil +} + +// Scan implements the sql.Scanner interface. +// A 16-byte slice is handled by UnmarshalBinary, while +// a longer byte slice or a string is handled by UnmarshalText. +func (u *UUID) Scan(src interface{}) error { + switch src := src.(type) { + case []byte: + if len(src) == 16 { + return u.UnmarshalBinary(src) + } + return u.UnmarshalText(src) + + case string: + return u.UnmarshalText([]byte(src)) + } + + return fmt.Errorf("uuid: cannot convert %T to UUID", src) +} + +// Value implements the driver.Valuer interface. +func (u NullUUID) Value() (driver.Value, error) { + if !u.Valid { + return nil, nil + } + // Delegate to UUID Value function + return u.UUID.Value() +} + +// Scan implements the sql.Scanner interface. +func (u *NullUUID) Scan(src interface{}) error { + if src == nil { + u.UUID, u.Valid = Nil, false + return nil + } + + // Delegate to UUID Scan function + u.Valid = true + return u.UUID.Scan(src) +} + +// FromBytes returns UUID converted from raw byte slice input. +// It will return error if the slice isn't 16 bytes long. +func FromBytes(input []byte) (u UUID, err error) { + err = u.UnmarshalBinary(input) + return +} + +// FromBytesOrNil returns UUID converted from raw byte slice input. +// Same behavior as FromBytes, but returns a Nil UUID on error. +func FromBytesOrNil(input []byte) UUID { + uuid, err := FromBytes(input) + if err != nil { + return Nil + } + return uuid +} + +// FromString returns UUID parsed from string input. +// Input is expected in a form accepted by UnmarshalText. +func FromString(input string) (u UUID, err error) { + err = u.UnmarshalText([]byte(input)) + return +} + +// FromStringOrNil returns UUID parsed from string input. +// Same behavior as FromString, but returns a Nil UUID on error. +func FromStringOrNil(input string) UUID { + uuid, err := FromString(input) + if err != nil { + return Nil + } + return uuid +} + +// Returns UUID v1/v2 storage state. +// Returns epoch timestamp, clock sequence, and hardware address. +func getStorage() (uint64, uint16, []byte) { + storageOnce.Do(initStorage) + + storageMutex.Lock() + defer storageMutex.Unlock() + + timeNow := epochFunc() + // Clock changed backwards since last UUID generation. + // Should increase clock sequence. + if timeNow <= lastTime { + clockSequence++ + } + lastTime = timeNow + + return timeNow, clockSequence, hardwareAddr[:] +} + +// NewV1 returns UUID based on current timestamp and MAC address. +func NewV1() UUID { + u := UUID{} + + timeNow, clockSeq, hardwareAddr := getStorage() + + binary.BigEndian.PutUint32(u[0:], uint32(timeNow)) + binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32)) + binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) + binary.BigEndian.PutUint16(u[8:], clockSeq) + + copy(u[10:], hardwareAddr) + + u.SetVersion(1) + u.SetVariant() + + return u +} + +// NewV2 returns DCE Security UUID based on POSIX UID/GID. +func NewV2(domain byte) UUID { + u := UUID{} + + timeNow, clockSeq, hardwareAddr := getStorage() + + switch domain { + case DomainPerson: + binary.BigEndian.PutUint32(u[0:], posixUID) + case DomainGroup: + binary.BigEndian.PutUint32(u[0:], posixGID) + } + + binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32)) + binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) + binary.BigEndian.PutUint16(u[8:], clockSeq) + u[9] = domain + + copy(u[10:], hardwareAddr) + + u.SetVersion(2) + u.SetVariant() + + return u +} + +// NewV3 returns UUID based on MD5 hash of namespace UUID and name. +func NewV3(ns UUID, name string) UUID { + u := newFromHash(md5.New(), ns, name) + u.SetVersion(3) + u.SetVariant() + + return u +} + +// NewV4 returns random generated UUID. +func NewV4() UUID { + u := UUID{} + safeRandom(u[:]) + u.SetVersion(4) + u.SetVariant() + + return u +} + +// NewV5 returns UUID based on SHA-1 hash of namespace UUID and name. +func NewV5(ns UUID, name string) UUID { + u := newFromHash(sha1.New(), ns, name) + u.SetVersion(5) + u.SetVariant() + + return u +} + +// Returns UUID based on hashing of namespace UUID and name. +func newFromHash(h hash.Hash, ns UUID, name string) UUID { + u := UUID{} + h.Write(ns[:]) + h.Write([]byte(name)) + copy(u[:], h.Sum(nil)) + + return u +} diff --git a/vendor/vendor.json b/vendor/vendor.json index cc2a37549..7d0984fcf 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -20,6 +20,12 @@ "version": "v5.0.0-beta", "versionExact": "v5.0.0-beta" }, + { + "checksumSHA1": "twJBMkI9NiMeQbPFmw4ehZQAPaE=", + "path": "github.com/Azure/azure-sdk-for-go/arm/keyvault", + "revision": "91f3d4a4d024e3c0d4d9412916d05cf84504a616", + "revisionTime": "2016-10-05T01:22:46Z" + }, { "checksumSHA1": "33Eny6aOVU6MjMYlfzufuo9OdCk=", "comment": "v2.1.1-beta-8-gca4d906", @@ -1688,6 +1694,12 @@ "path": "github.com/satori/go.uuid", "revision": "d41af8bb6a7704f00bc3b7cba9355ae6a5a80048" }, + { + "checksumSHA1": "iqUXcP3VA+G1/gVLRpQpBUt/BuA=", + "path": "github.com/satori/uuid", + "revision": "b061729afc07e77a8aa4fad0a2fd840958f1942a", + "revisionTime": "2016-09-27T10:08:44Z" + }, { "checksumSHA1": "DWJoWDXcRi4HUCyxU6dLVVjR4pI=", "path": "github.com/sethvargo/go-fastly", diff --git a/website/source/docs/providers/azurerm/r/key_vault.html.markdown b/website/source/docs/providers/azurerm/r/key_vault.html.markdown new file mode 100644 index 000000000..3f06eef0a --- /dev/null +++ b/website/source/docs/providers/azurerm/r/key_vault.html.markdown @@ -0,0 +1,113 @@ +--- +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_key_vault" +sidebar_current: "docs-azurerm-resource-key-vault" +description: |- + Create a Key Vault. +--- + +# azurerm\_key\_vault + +Create a ServiceBus Subscription. + +## Example Usage + +``` +resource "azurerm_resource_group" "test" { + name = "resourceGroup1" + location = "West US" +} + +resource "azurerm_key_vault" "test" { + name = "testvault" + location = "West US" + resource_group_name = "${azurerm_resource_group.test.name}" + + sku { + name = "standard" + } + + tenant_id = "d6e396d0-5584-41dc-9fc0-268df99bc610" + + access_policy { + tenant_id = "d6e396d0-5584-41dc-9fc0-268df99bc610" + object_id = "d746815a-0433-4a21-b95d-fc437d2d475b" + key_permissions = [ + "all" + ] + secret_permissions = [ + "get" + ] + } + + enabled_for_disk_encryption = true + + tags { + environment = "Production" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name of the ServiceBus Subscription resource. + Changing this forces a new resource to be created. + +* `location` - (Required) Specifies the supported Azure location where the resource exists. + Changing this forces a new resource to be created. + +* `resource_group_name` - (Required) The name of the resource group in which to + create the namespace. Changing this forces a new resource to be created. + +* `sku` - (Required) An SKU block as described below. + +* `tenant_id` - (Required) The Azure Active Directory tenant ID that should be + used for authenticating requests to the key vault. + +* `access_policy` - (Required) An access policy block as described below. At least + one policy is required up to a maximum of 16. + +* `enabled_for_deployment` - (Optional) Boolean flag to specify whether Azure Virtual + Machines are permitted to retrieve certificates stored as secrets from the key + vault. Defaults to false. + +* `enabled_for_disk_encryption` - (Optional) Boolean flag to specify whether Azure + Disk Encryption is permitted to retrieve secrets from the vault and unwrap keys. + Defaults to false. + +* `enabled_for_template_deployment` - (Optional) Boolean flag to specify whether + Azure Resource Manager is permitted to retrieve secrets from the key vault. + Defaults to false. + +* `tags` - (Optional) A mapping of tags to assign to the resource. + +`sku` supports the following: + +* `name` - (Required) SKU name to specify whether the key vault is a `standard` + or `premium` vault. + +`access_policy` supports the following: + +* `tenant_id` - (Required) The Azure Active Directory tenant ID that should be used + for authenticating requests to the key vault. Must match the `tenant_id` used + above. + +* `object_id` - (Required) The object ID of a user, service principal or security + group in the Azure Active Directory tenant for the vault. The object ID must + be unique for the list of access policies. + +* `key_permissions` - (Required) List of key permissions, must be one or more from + the following: `all`, `backup`, `create`, `decrypt`, `delete`, `encrypt`, `get`, + `import`, `list`, `restore`, `sign`, `unwrapKey`, `update`, `verify`, `wrapKey`. + +* `secret_permissions` - (Required) List of secret permissions, must be one or more + from the following: `all`, `delete`, `get`, `list`, `set`. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The Vault ID. +* `vault_uri` - The URI of the vault for performing operations on keys and secrets. diff --git a/website/source/layouts/azurerm.erb b/website/source/layouts/azurerm.erb index b9e2cbd7f..383ee3aab 100644 --- a/website/source/layouts/azurerm.erb +++ b/website/source/layouts/azurerm.erb @@ -83,6 +83,17 @@ + > + Key Vault Resources + + + > Load Balancer Resources