Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Resource: Key Vault Access Policy #1149

Merged
merged 28 commits into from
Jul 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
223a5d8
Initial support for Azure Key Vault Policy resource
Apr 23, 2018
f8b19a5
Merge branch 'master' into feature/key_vault_policy
May 4, 2018
aae8844
Updated to fix the test broken from updating the source code. We don…
May 4, 2018
24df15d
Addressed PR comments
May 8, 2018
000963e
Return nil on a delete for the shared delete/update function
May 9, 2018
981dff0
Merge branch 'master' into feature/key_vault_policy
May 13, 2018
6490dad
Removed reference to old code
May 14, 2018
56dadaa
Starting to address PR comments
May 23, 2018
2422a1f
Starting to address PR comments
May 23, 2018
4638772
Working my way through the PR comments
May 25, 2018
2c81721
Fixed some of the tests
May 29, 2018
2813a05
Ran make fmt
May 29, 2018
e9d1989
Fixed website links
May 29, 2018
2e83293
Updated route test to fail
Jun 5, 2018
0484bcf
Updated to support importing an access policy
Jun 7, 2018
bc13b6d
Updated to support importing of the resource and some enhanced tests
Jun 8, 2018
cea6c60
Reverted route_test to not fail for this pr
Jun 8, 2018
ee1dcac
Working through pr comments
Jun 9, 2018
e3d2c3d
Merge branch 'master' into feature/key_vault_policy
Jun 9, 2018
4c618a2
Updated for PR comments as well as added several unittests for the ke…
Jun 22, 2018
7ac2e22
Merge branch 'master' into feature/key_vault_policy
Jun 29, 2018
17f46df
Ran make fmt
Jun 29, 2018
f500bab
Merge branch 'master' into feature/key_vault_policy
tombuildsstuff Jul 6, 2018
44b64a0
Refactoring the helpers into the `helpers/schema` folder
tombuildsstuff Jul 6, 2018
50e2837
Adding import tests / clarifying the import docs
tombuildsstuff Jul 6, 2018
0ea420a
Handling the case of an AppID and no AppID being specified / refactor…
tombuildsstuff Jul 9, 2018
56ae66b
Fixing the error message
tombuildsstuff Jul 9, 2018
aa2d2b0
Documentation fixes
tombuildsstuff Jul 9, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 4 additions & 51 deletions azurerm/data_source_key_vault.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/Azure/azure-sdk-for-go/services/keyvault/mgmt/2016-10-01/keyvault"
"github.com/hashicorp/terraform/helper/schema"
kvschema "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

Expand Down Expand Up @@ -140,7 +141,9 @@ func dataSourceArmKeyVaultRead(d *schema.ResourceData, meta interface{}) error {
if err := d.Set("sku", flattenKeyVaultDataSourceSku(props.Sku)); err != nil {
return fmt.Errorf("Error flattening `sku` for KeyVault %q: %+v", resp.Name, err)
}
if err := d.Set("access_policy", flattenKeyVaultDataSourceAccessPolicies(props.AccessPolicies)); err != nil {

flattenedPolicies := kvschema.FlattenKeyVaultAccessPolicies(props.AccessPolicies)
if err := d.Set("access_policy", flattenedPolicies); err != nil {
return fmt.Errorf("Error flattening `access_policy` for KeyVault %q: %+v", resp.Name, err)
}
d.Set("vault_uri", props.VaultURI)
Expand All @@ -158,53 +161,3 @@ func flattenKeyVaultDataSourceSku(sku *keyvault.Sku) []interface{} {

return []interface{}{result}
}

func flattenKeyVaultDataSourceAccessPolicies(policies *[]keyvault.AccessPolicyEntry) []interface{} {
result := make([]interface{}, 0, len(*policies))

if policies == nil {
return result
}

for _, policy := range *policies {
policyRaw := make(map[string]interface{})

keyPermissionsRaw := make([]interface{}, 0)
secretPermissionsRaw := make([]interface{}, 0)
certificatePermissionsRaw := make([]interface{}, 0)

if permissions := policy.Permissions; permissions != nil {
if keys := permissions.Keys; keys != nil {
for _, keyPermission := range *keys {
keyPermissionsRaw = append(keyPermissionsRaw, string(keyPermission))
}
}
if secrets := permissions.Secrets; secrets != nil {
for _, secretPermission := range *secrets {
secretPermissionsRaw = append(secretPermissionsRaw, string(secretPermission))
}
}

if certificates := permissions.Certificates; certificates != nil {
for _, certificatePermission := range *certificates {
certificatePermissionsRaw = append(certificatePermissionsRaw, string(certificatePermission))
}
}
}

policyRaw["tenant_id"] = policy.TenantID.String()
if policy.ObjectID != nil {
policyRaw["object_id"] = *policy.ObjectID
}
if policy.ApplicationID != nil {
policyRaw["application_id"] = policy.ApplicationID.String()
}
policyRaw["key_permissions"] = keyPermissionsRaw
policyRaw["secret_permissions"] = secretPermissionsRaw
policyRaw["certificate_permissions"] = certificatePermissionsRaw

result = append(result, policyRaw)
}

return result
}
224 changes: 224 additions & 0 deletions azurerm/helpers/schema/key_vault_access_policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
package schema

import (
"github.com/Azure/azure-sdk-for-go/services/keyvault/mgmt/2016-10-01/keyvault"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/satori/go.uuid"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress"
)

func KeyVaultCertificatePermissionsSchema() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice([]string{
string(keyvault.Create),
string(keyvault.Delete),
string(keyvault.Deleteissuers),
string(keyvault.Get),
string(keyvault.Getissuers),
string(keyvault.Import),
string(keyvault.List),
string(keyvault.Listissuers),
string(keyvault.Managecontacts),
string(keyvault.Manageissuers),
string(keyvault.Purge),
string(keyvault.Recover),
string(keyvault.Setissuers),
string(keyvault.Update),
}, true),
DiffSuppressFunc: suppress.CaseDifference,
},
}
}

func KeyVaultKeyPermissionsSchema() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice([]string{
string(keyvault.KeyPermissionsBackup),
string(keyvault.KeyPermissionsCreate),
string(keyvault.KeyPermissionsDecrypt),
string(keyvault.KeyPermissionsDelete),
string(keyvault.KeyPermissionsEncrypt),
string(keyvault.KeyPermissionsGet),
string(keyvault.KeyPermissionsImport),
string(keyvault.KeyPermissionsList),
string(keyvault.KeyPermissionsPurge),
string(keyvault.KeyPermissionsRecover),
string(keyvault.KeyPermissionsRestore),
string(keyvault.KeyPermissionsSign),
string(keyvault.KeyPermissionsUnwrapKey),
string(keyvault.KeyPermissionsUpdate),
string(keyvault.KeyPermissionsVerify),
string(keyvault.KeyPermissionsWrapKey),
}, true),
DiffSuppressFunc: suppress.CaseDifference,
},
}
}

func KeyVaultSecretPermissionsSchema() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.StringInSlice([]string{
string(keyvault.SecretPermissionsBackup),
string(keyvault.SecretPermissionsDelete),
string(keyvault.SecretPermissionsGet),
string(keyvault.SecretPermissionsList),
string(keyvault.SecretPermissionsPurge),
string(keyvault.SecretPermissionsRecover),
string(keyvault.SecretPermissionsRestore),
string(keyvault.SecretPermissionsSet),
}, true),
DiffSuppressFunc: suppress.CaseDifference,
},
}
}

func ExpandKeyVaultAccessPolicies(input []interface{}) (*[]keyvault.AccessPolicyEntry, error) {
output := make([]keyvault.AccessPolicyEntry, 0)

for _, policySet := range input {
policyRaw := policySet.(map[string]interface{})

certificatePermissionsRaw := policyRaw["certificate_permissions"].([]interface{})
keyPermissionsRaw := policyRaw["key_permissions"].([]interface{})
secretPermissionsRaw := policyRaw["secret_permissions"].([]interface{})

policy := keyvault.AccessPolicyEntry{
Permissions: &keyvault.Permissions{
Certificates: ExpandCertificatePermissions(certificatePermissionsRaw),
Keys: ExpandKeyPermissions(keyPermissionsRaw),
Secrets: ExpandSecretPermissions(secretPermissionsRaw),
},
}

tenantUUID := uuid.FromStringOrNil(policyRaw["tenant_id"].(string))
policy.TenantID = &tenantUUID
objectUUID := policyRaw["object_id"].(string)
policy.ObjectID = &objectUUID

if v := policyRaw["application_id"]; v != "" {
applicationUUID := uuid.FromStringOrNil(v.(string))
policy.ApplicationID = &applicationUUID
}

output = append(output, policy)
}

return &output, nil
}

func FlattenKeyVaultAccessPolicies(policies *[]keyvault.AccessPolicyEntry) []map[string]interface{} {
result := make([]map[string]interface{}, 0)

if policies == nil {
return result
}

for _, policy := range *policies {
policyRaw := make(map[string]interface{})

if tenantId := policy.TenantID; tenantId != nil {
policyRaw["tenant_id"] = tenantId.String()
}

if objectId := policy.ObjectID; objectId != nil {
policyRaw["object_id"] = *objectId
}

if appId := policy.ApplicationID; appId != nil {
policyRaw["application_id"] = appId.String()
}

if permissions := policy.Permissions; permissions != nil {
certs := FlattenCertificatePermissions(permissions.Certificates)
policyRaw["certificate_permissions"] = certs

keys := FlattenKeyPermissions(permissions.Keys)
policyRaw["key_permissions"] = keys

secrets := FlattenSecretPermissions(permissions.Secrets)
policyRaw["secret_permissions"] = secrets
}

result = append(result, policyRaw)
}

return result
}

func ExpandCertificatePermissions(input []interface{}) *[]keyvault.CertificatePermissions {
output := make([]keyvault.CertificatePermissions, 0)

for _, permission := range input {
output = append(output, keyvault.CertificatePermissions(permission.(string)))
}

return &output
}

func FlattenCertificatePermissions(input *[]keyvault.CertificatePermissions) []interface{} {
output := make([]interface{}, 0)

if input != nil {
for _, certificatePermission := range *input {
output = append(output, string(certificatePermission))
}
}

return output
}

func ExpandKeyPermissions(keyPermissionsRaw []interface{}) *[]keyvault.KeyPermissions {
output := make([]keyvault.KeyPermissions, 0)

for _, permission := range keyPermissionsRaw {
output = append(output, keyvault.KeyPermissions(permission.(string)))
}
return &output
}

func FlattenKeyPermissions(input *[]keyvault.KeyPermissions) []interface{} {
output := make([]interface{}, 0)

if input != nil {
for _, keyPermission := range *input {
output = append(output, string(keyPermission))
}
}

return output
}

func ExpandSecretPermissions(input []interface{}) *[]keyvault.SecretPermissions {
output := make([]keyvault.SecretPermissions, 0)

for _, permission := range input {
output = append(output, keyvault.SecretPermissions(permission.(string)))
}

return &output
}

func FlattenSecretPermissions(input *[]keyvault.SecretPermissions) []interface{} {
output := make([]interface{}, 0)

if input != nil {
for _, secretPermission := range *input {
output = append(output, string(secretPermission))
}
}

return output
}
57 changes: 57 additions & 0 deletions azurerm/import_arm_key_vault_access_policy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package azurerm

import (
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)

func TestAccAzureRMKeyVaultAccessPolicy_importBasic(t *testing.T) {
resourceName := "azurerm_key_vault_access_policy.test"

rs := acctest.RandString(5)
config := testAccAzureRMKeyVaultAccessPolicy_basic(rs, testLocation())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMKeyVaultDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAzureRMKeyVaultAccessPolicy_importMultiple(t *testing.T) {
rs := acctest.RandString(5)
config := testAccAzureRMKeyVaultAccessPolicy_multiple(rs, testLocation())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMKeyVaultDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: "azurerm_key_vault_access_policy.test_with_application_id",
ImportState: true,
ImportStateVerify: true,
},
{
ResourceName: "azurerm_key_vault_access_policy.test_no_application_id",
ImportState: true,
ImportStateVerify: true,
},
},
})
}
1 change: 1 addition & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_image": resourceArmImage(),
"azurerm_iothub": resourceArmIotHub(),
"azurerm_key_vault": resourceArmKeyVault(),
"azurerm_key_vault_access_policy": resourceArmKeyVaultAccessPolicy(),
"azurerm_key_vault_certificate": resourceArmKeyVaultCertificate(),
"azurerm_key_vault_key": resourceArmKeyVaultKey(),
"azurerm_key_vault_secret": resourceArmKeyVaultSecret(),
Expand Down
Loading