Skip to content

Commit

Permalink
Merge pull request #6930 from terraform-providers/f/bp-assignments
Browse files Browse the repository at this point in the history
  • Loading branch information
jackofallops committed Jun 9, 2020
2 parents 09bcf4b + 3af1f28 commit 832bf4b
Show file tree
Hide file tree
Showing 37 changed files with 6,949 additions and 0 deletions.
1 change: 1 addition & 0 deletions .teamcity/components/generated/services.kt
Expand Up @@ -10,6 +10,7 @@ var services = mapOf(
"authorization" to "Authorization",
"automation" to "Automation",
"batch" to "Batch",
"blueprints" to "Blueprints",
"bot" to "Bot",
"cdn" to "CDN",
"cognitive" to "Cognitive Services",
Expand Down
3 changes: 3 additions & 0 deletions azurerm/internal/clients/client.go
Expand Up @@ -15,6 +15,7 @@ import (
authorization "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/authorization/client"
automation "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/automation/client"
batch "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/batch/client"
blueprints "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/blueprints/client"
bot "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/bot/client"
cdn "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/cdn/client"
cognitiveServices "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/cognitive/client"
Expand Down Expand Up @@ -97,6 +98,7 @@ type Client struct {
Authorization *authorization.Client
Automation *automation.Client
Batch *batch.Client
Blueprints *blueprints.Client
Bot *bot.Client
Cdn *cdn.Client
Cognitive *cognitiveServices.Client
Expand Down Expand Up @@ -180,6 +182,7 @@ func (client *Client) Build(ctx context.Context, o *common.ClientOptions) error
client.Authorization = authorization.NewClient(o)
client.Automation = automation.NewClient(o)
client.Batch = batch.NewClient(o)
client.Blueprints = blueprints.NewClient(o)
client.Bot = bot.NewClient(o)
client.Cdn = cdn.NewClient(o)
client.Cognitive = cognitiveServices.NewClient(o)
Expand Down
1 change: 1 addition & 0 deletions azurerm/internal/provider/required_resource_providers.go
Expand Up @@ -20,6 +20,7 @@ func RequiredResourceProviders() map[string]struct{} {
"Microsoft.AppPlatform": {},
"Microsoft.Authorization": {},
"Microsoft.Automation": {},
"Microsoft.Blueprints": {},
"Microsoft.BotService": {},
"Microsoft.Cache": {},
"Microsoft.Cdn": {},
Expand Down
2 changes: 2 additions & 0 deletions azurerm/internal/provider/services.go
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/authorization"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/automation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/batch"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/blueprints"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/bot"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/cdn"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/cognitive"
Expand Down Expand Up @@ -90,6 +91,7 @@ func SupportedServices() []common.ServiceRegistration {
authorization.Registration{},
automation.Registration{},
batch.Registration{},
blueprints.Registration{},
bot.Registration{},
cdn.Registration{},
cognitive.Registration{},
Expand Down
211 changes: 211 additions & 0 deletions azurerm/internal/services/blueprints/blueprint.go
@@ -0,0 +1,211 @@
package blueprints

import (
"context"
"encoding/json"
"fmt"

"github.com/Azure/azure-sdk-for-go/services/preview/blueprint/mgmt/2018-11-01-preview/blueprint"
"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/msi/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func ManagedIdentitySchema() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
// ManagedServiceIdentityTypeNone is not valid; a valid and privileged Identity is required for the service to apply the changes.
// SystemAssigned type not currently supported - The Portal performs significant activity in temporary escalation of permissions to Owner on the target scope
// Such activity in the Provider would be brittle
// string(blueprint.ManagedServiceIdentityTypeSystemAssigned),
string(blueprint.ManagedServiceIdentityTypeUserAssigned),
}, true),
// The first character of value returned by the service is always in lower case - bug?
DiffSuppressFunc: suppress.CaseDifference,
},

"identity_ids": {
// The API only seems to care about the "key" portion of this struct, which is the ResourceID of the Identity
Type: schema.TypeList,
Required: true,
MinItems: 1,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validate.UserAssignedIdentityId,
},
},

"principal_id": {
Type: schema.TypeString,
Computed: true,
},

"tenant_id": {
Type: schema.TypeString,
Computed: true,
},
},
},
}
}

func blueprintAssignmentCreateStateRefreshFunc(ctx context.Context, client *blueprint.AssignmentsClient, scope, name string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
resp, err := client.Get(ctx, scope, name)
if err != nil {
return nil, "", fmt.Errorf("unable to retrieve Blueprint Assignment %q (Scope %q): %+v", name, scope, err)
}
if resp.ProvisioningState == blueprint.Failed {
return resp, string(resp.ProvisioningState), fmt.Errorf("Blueprint Assignment provisioning entered a Failed state.")
}

return resp, string(resp.ProvisioningState), nil
}
}

func blueprintAssignmentDeleteStateRefreshFunc(ctx context.Context, client *blueprint.AssignmentsClient, scope, name string) resource.StateRefreshFunc {
return func() (interface{}, string, error) {
resp, err := client.Get(ctx, scope, name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return resp, "NotFound", nil
} else {
return nil, "", fmt.Errorf("unable to retrieve Blueprint Assignment %q (Scope %q): %+v", name, scope, err)
}
}

return resp, string(resp.ProvisioningState), nil
}
}

func normalizeAssignmentParameterValuesJSON(jsonString interface{}) string {
if jsonString == nil || jsonString == "" {
return ""
}

var values map[string]*blueprint.ParameterValue
if err := json.Unmarshal([]byte(jsonString.(string)), &values); err != nil {
return fmt.Sprintf("unable to parse JSON: %+v", err)
}

b, _ := json.Marshal(values)
return string(b)
}

func normalizeAssignmentResourceGroupValuesJSON(jsonString interface{}) string {
if jsonString == nil || jsonString == "" {
return ""
}

var values map[string]*blueprint.ResourceGroupValue
if err := json.Unmarshal([]byte(jsonString.(string)), &values); err != nil {
return fmt.Sprintf("unable to parse JSON: %+v", err)
}

b, _ := json.Marshal(values)
return string(b)
}

func expandArmBlueprintAssignmentParameters(input string) map[string]*blueprint.ParameterValue {
var result map[string]*blueprint.ParameterValue
// the string has been validated by the schema, therefore the error is ignored here, since it will never happen.
_ = json.Unmarshal([]byte(input), &result)
return result
}

func expandArmBlueprintAssignmentResourceGroups(input string) map[string]*blueprint.ResourceGroupValue {
var result map[string]*blueprint.ResourceGroupValue
// the string has been validated by the schema, therefore the error is ignored here, since it will never happen.
_ = json.Unmarshal([]byte(input), &result)
return result
}

func expandArmBlueprintAssignmentIdentity(input []interface{}) (*blueprint.ManagedServiceIdentity, error) {
if len(input) == 0 || input[0] == nil {
return nil, fmt.Errorf("Managed Service Identity was empty")
}

raw := input[0].(map[string]interface{})

identity := blueprint.ManagedServiceIdentity{
Type: blueprint.ManagedServiceIdentityType(raw["type"].(string)),
}

identityIdsRaw := raw["identity_ids"].([]interface{})
identityIds := make(map[string]*blueprint.UserAssignedIdentity)
for _, v := range identityIdsRaw {
identityIds[v.(string)] = &blueprint.UserAssignedIdentity{}
}
identity.UserAssignedIdentities = identityIds

return &identity, nil
}

func flattenArmBlueprintAssignmentIdentity(input *blueprint.ManagedServiceIdentity) []interface{} {
if input == nil {
return []interface{}{}
}

identityIds := make([]string, 0)
if input.UserAssignedIdentities != nil {
for k := range input.UserAssignedIdentities {
identityIds = append(identityIds, k)
}
}

principalId := ""
if input.PrincipalID != nil {
principalId = *input.PrincipalID
}

tenantId := ""
if input.TenantID != nil {
tenantId = *input.TenantID
}

return []interface{}{
map[string]interface{}{
"type": string(input.Type),
"identity_ids": identityIds,
"principal_id": principalId,
"tenant_id": tenantId,
},
}
}

func flattenArmBlueprintAssignmentParameters(input map[string]*blueprint.ParameterValue) (string, error) {
if len(input) == 0 {
return "", nil
}

b, err := json.Marshal(input)
if err != nil {
return "", err
}

return string(b), nil
}

func flattenArmBlueprintAssignmentResourceGroups(input map[string]*blueprint.ResourceGroupValue) (string, error) {
if len(input) == 0 {
return "", nil
}

b, err := json.Marshal(input)
if err != nil {
return "", err
}

return string(b), nil
}

0 comments on commit 832bf4b

Please sign in to comment.