-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New Resource:
azurerm_cognitive_account_rai_policy
(#28013)
* Add new resource `azurerm_cognitive_account_rai_policy` * Optimize code and dependancies for RAI policy * Resolve golint issues by pre-allocation * Apply suggestions from code review Co-authored-by: stephybun <[email protected]> * Update according to review comment. * Change custom_blocklist.name to custom_blocklist.id * Rename custom_blocklist.id to custom_blocklist.rai_blocklist_id as suggested * Remove custom_blocklist from the RAI Policy resource * Resolve lint issue --------- Co-authored-by: stephybun <[email protected]>
- Loading branch information
1 parent
b094a9e
commit 9375225
Showing
21 changed files
with
1,581 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
338 changes: 338 additions & 0 deletions
338
internal/services/cognitive/cognitive_account_rai_policy_resource.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,338 @@ | ||
package cognitive | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/hashicorp/go-azure-helpers/lang/pointer" | ||
"github.com/hashicorp/go-azure-helpers/lang/response" | ||
"github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" | ||
"github.com/hashicorp/go-azure-sdk/resource-manager/cognitive/2024-10-01/raipolicies" | ||
"github.com/hashicorp/terraform-provider-azurerm/internal/locks" | ||
"github.com/hashicorp/terraform-provider-azurerm/internal/sdk" | ||
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" | ||
"github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" | ||
) | ||
|
||
var _ sdk.ResourceWithUpdate = &CognitiveAccountRaiPolicyResource{} | ||
|
||
type CognitiveAccountRaiPolicyResource struct{} | ||
|
||
type AccountRaiPolicyContentFilter struct { | ||
Name string `tfschema:"name"` | ||
FilterEnabled bool `tfschema:"filter_enabled"` | ||
BlockEnabled bool `tfschema:"block_enabled"` | ||
SeverityThreshold string `tfschema:"severity_threshold"` | ||
Source string `tfschema:"source"` | ||
} | ||
|
||
type AccountRaiPolicyCustomBlock struct { | ||
Id string `tfschema:"rai_blocklist_id"` | ||
BlockEnabled bool `tfschema:"block_enabled"` | ||
Source string `tfschema:"source"` | ||
} | ||
|
||
type AccountRaiPolicyResourceModel struct { | ||
Name string `tfschema:"name"` | ||
AccountId string `tfschema:"cognitive_account_id"` | ||
BasePolicyName string `tfschema:"base_policy_name"` | ||
ContentFilter []AccountRaiPolicyContentFilter `tfschema:"content_filter"` | ||
Mode string `tfschema:"mode"` | ||
Tags map[string]string `tfschema:"tags"` | ||
} | ||
|
||
func (r CognitiveAccountRaiPolicyResource) Arguments() map[string]*pluginsdk.Schema { | ||
return map[string]*pluginsdk.Schema{ | ||
"name": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validation.StringIsNotEmpty, | ||
}, | ||
|
||
"cognitive_account_id": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: raipolicies.ValidateAccountID, | ||
}, | ||
|
||
"base_policy_name": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
ValidateFunc: validation.StringIsNotEmpty, | ||
}, | ||
|
||
"content_filter": { | ||
Type: pluginsdk.TypeList, | ||
Required: true, | ||
Elem: &pluginsdk.Resource{ | ||
Schema: map[string]*pluginsdk.Schema{ | ||
"name": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ValidateFunc: validation.StringIsNotEmpty, | ||
}, | ||
"filter_enabled": { | ||
Type: pluginsdk.TypeBool, | ||
Required: true, | ||
}, | ||
"block_enabled": { | ||
Type: pluginsdk.TypeBool, | ||
Required: true, | ||
}, | ||
"severity_threshold": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ValidateFunc: validation.StringInSlice(raipolicies.PossibleValuesForContentLevel(), false), | ||
}, | ||
"source": { | ||
Type: pluginsdk.TypeString, | ||
Required: true, | ||
ValidateFunc: validation.StringInSlice(raipolicies.PossibleValuesForRaiPolicyContentSource(), false), | ||
}, | ||
}, | ||
}, | ||
}, | ||
|
||
"mode": { | ||
Type: pluginsdk.TypeString, | ||
Optional: true, | ||
ValidateFunc: validation.StringInSlice(raipolicies.PossibleValuesForRaiPolicyMode(), false), | ||
}, | ||
|
||
"tags": commonschema.Tags(), | ||
} | ||
} | ||
|
||
func (r CognitiveAccountRaiPolicyResource) Attributes() map[string]*pluginsdk.Schema { | ||
return map[string]*pluginsdk.Schema{} | ||
} | ||
|
||
func (r CognitiveAccountRaiPolicyResource) ModelObject() interface{} { | ||
return &AccountRaiPolicyResourceModel{} | ||
} | ||
|
||
func (r CognitiveAccountRaiPolicyResource) ResourceType() string { | ||
return "azurerm_cognitive_account_rai_policy" | ||
} | ||
|
||
func (r CognitiveAccountRaiPolicyResource) Create() sdk.ResourceFunc { | ||
return sdk.ResourceFunc{ | ||
Timeout: 30 * time.Minute, | ||
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { | ||
client := metadata.Client.Cognitive.RaiPoliciesClient | ||
subscriptionId := metadata.Client.Account.SubscriptionId | ||
|
||
var model AccountRaiPolicyResourceModel | ||
if err := metadata.Decode(&model); err != nil { | ||
return fmt.Errorf("decoding: %+v", err) | ||
} | ||
|
||
cognitiveAccountId, err := raipolicies.ParseAccountID(model.AccountId) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
id := raipolicies.NewRaiPolicyID(subscriptionId, cognitiveAccountId.ResourceGroupName, cognitiveAccountId.AccountName, model.Name) | ||
existing, err := client.Get(ctx, id) | ||
if err != nil { | ||
if !response.WasNotFound(existing.HttpResponse) { | ||
return fmt.Errorf("checking for presence of existing %s: %+v", id, err) | ||
} | ||
} | ||
if !response.WasNotFound(existing.HttpResponse) { | ||
return metadata.ResourceRequiresImport(r.ResourceType(), id) | ||
} | ||
|
||
locks.ByID(cognitiveAccountId.ID()) | ||
defer locks.UnlockByID(cognitiveAccountId.ID()) | ||
|
||
raiPolicy := raipolicies.RaiPolicy{ | ||
Name: pointer.To(model.Name), | ||
Properties: &raipolicies.RaiPolicyProperties{ | ||
BasePolicyName: pointer.To(model.BasePolicyName), | ||
ContentFilters: expandRaiPolicyContentFilters(model.ContentFilter), | ||
}, | ||
Tags: pointer.To(model.Tags), | ||
} | ||
|
||
if model.Mode != "" { | ||
raiPolicy.Properties.Mode = pointer.To(raipolicies.RaiPolicyMode(model.Mode)) | ||
} | ||
|
||
if _, err := client.CreateOrUpdate(ctx, id, raiPolicy); err != nil { | ||
return fmt.Errorf("creating %s: %+v", id, err) | ||
} | ||
|
||
metadata.SetID(id) | ||
|
||
return nil | ||
}, | ||
} | ||
} | ||
|
||
func (r CognitiveAccountRaiPolicyResource) Read() sdk.ResourceFunc { | ||
return sdk.ResourceFunc{ | ||
Timeout: 5 * time.Minute, | ||
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { | ||
client := metadata.Client.Cognitive.RaiPoliciesClient | ||
|
||
id, err := raipolicies.ParseRaiPolicyID(metadata.ResourceData.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
cognitiveAccountId := raipolicies.NewAccountID(id.SubscriptionId, id.ResourceGroupName, id.AccountName) | ||
|
||
resp, err := client.Get(ctx, *id) | ||
if err != nil { | ||
if response.WasNotFound(resp.HttpResponse) { | ||
return metadata.MarkAsGone(id) | ||
} | ||
return fmt.Errorf("retrieving %s: %+v", id, err) | ||
} | ||
|
||
state := AccountRaiPolicyResourceModel{ | ||
Name: id.RaiPolicyName, | ||
AccountId: cognitiveAccountId.ID(), | ||
} | ||
|
||
if model := resp.Model; model != nil { | ||
state.Tags = pointer.From(model.Tags) | ||
|
||
if props := model.Properties; props != nil { | ||
state.BasePolicyName = pointer.From(props.BasePolicyName) | ||
state.ContentFilter = flattenRaiPolicyContentFilters(props.ContentFilters) | ||
state.Mode = string(pointer.From(props.Mode)) | ||
} | ||
} | ||
|
||
return metadata.Encode(&state) | ||
}, | ||
} | ||
} | ||
|
||
func (r CognitiveAccountRaiPolicyResource) Update() sdk.ResourceFunc { | ||
return sdk.ResourceFunc{ | ||
Timeout: 30 * time.Minute, | ||
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { | ||
client := metadata.Client.Cognitive.RaiPoliciesClient | ||
|
||
id, err := raipolicies.ParseRaiPolicyID(metadata.ResourceData.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
var model AccountRaiPolicyResourceModel | ||
if err := metadata.Decode(&model); err != nil { | ||
return err | ||
} | ||
|
||
existing, err := client.Get(ctx, *id) | ||
if err != nil { | ||
return fmt.Errorf("retrieving %s: %+v", *id, err) | ||
} | ||
|
||
if existing.Model == nil { | ||
return fmt.Errorf("retrieving %s: `model` was nil", id) | ||
} | ||
|
||
if existing.Model.Properties == nil { | ||
return fmt.Errorf("retrieving %s: `properties` was nil", id) | ||
} | ||
|
||
cognitiveAccountId := raipolicies.NewAccountID(id.SubscriptionId, id.ResourceGroupName, id.AccountName) | ||
|
||
locks.ByID(cognitiveAccountId.ID()) | ||
defer locks.UnlockByID(cognitiveAccountId.ID()) | ||
|
||
payload := existing.Model | ||
|
||
if metadata.ResourceData.HasChange("content_filter") { | ||
payload.Properties.ContentFilters = expandRaiPolicyContentFilters(model.ContentFilter) | ||
} | ||
|
||
if metadata.ResourceData.HasChange("mode") { | ||
payload.Properties.Mode = pointer.To(raipolicies.RaiPolicyMode(model.Mode)) | ||
} | ||
|
||
if metadata.ResourceData.HasChange("tags") { | ||
payload.Tags = pointer.To(model.Tags) | ||
} | ||
|
||
if _, err := client.CreateOrUpdate(ctx, *id, *payload); err != nil { | ||
return fmt.Errorf("updating %s: %+v", id, err) | ||
} | ||
|
||
return nil | ||
}, | ||
} | ||
} | ||
|
||
func (r CognitiveAccountRaiPolicyResource) Delete() sdk.ResourceFunc { | ||
return sdk.ResourceFunc{ | ||
Timeout: 30 * time.Minute, | ||
Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { | ||
client := metadata.Client.Cognitive.RaiPoliciesClient | ||
|
||
id, err := raipolicies.ParseRaiPolicyID(metadata.ResourceData.Id()) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
cognitiveAccountId := raipolicies.NewAccountID(id.SubscriptionId, id.ResourceGroupName, id.AccountName) | ||
|
||
locks.ByID(cognitiveAccountId.ID()) | ||
defer locks.UnlockByID(cognitiveAccountId.ID()) | ||
|
||
if err := client.DeleteThenPoll(ctx, *id); err != nil { | ||
return fmt.Errorf("deleting %s: %+v", id, err) | ||
} | ||
|
||
return nil | ||
}, | ||
} | ||
} | ||
|
||
func (r CognitiveAccountRaiPolicyResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { | ||
return raipolicies.ValidateRaiPolicyID | ||
} | ||
|
||
func expandRaiPolicyContentFilters(filters []AccountRaiPolicyContentFilter) *[]raipolicies.RaiPolicyContentFilter { | ||
if filters == nil { | ||
return nil | ||
} | ||
|
||
contentFilters := make([]raipolicies.RaiPolicyContentFilter, 0, len(filters)) | ||
for _, filter := range filters { | ||
contentFilters = append(contentFilters, raipolicies.RaiPolicyContentFilter{ | ||
Name: pointer.To(filter.Name), | ||
Enabled: pointer.To(filter.FilterEnabled), | ||
Blocking: pointer.To(filter.BlockEnabled), | ||
SeverityThreshold: pointer.To(raipolicies.ContentLevel(filter.SeverityThreshold)), | ||
Source: pointer.To(raipolicies.RaiPolicyContentSource(filter.Source)), | ||
}) | ||
} | ||
return &contentFilters | ||
} | ||
|
||
func flattenRaiPolicyContentFilters(filters *[]raipolicies.RaiPolicyContentFilter) []AccountRaiPolicyContentFilter { | ||
contentFilters := make([]AccountRaiPolicyContentFilter, 0) | ||
if filters == nil { | ||
return contentFilters | ||
} | ||
|
||
for _, filter := range *filters { | ||
contentFilters = append(contentFilters, AccountRaiPolicyContentFilter{ | ||
Name: pointer.From(filter.Name), | ||
FilterEnabled: pointer.From(filter.Enabled), | ||
BlockEnabled: pointer.From(filter.Blocking), | ||
SeverityThreshold: string(pointer.From(filter.SeverityThreshold)), | ||
Source: string(pointer.From(filter.Source)), | ||
}) | ||
} | ||
return contentFilters | ||
} |
Oops, something went wrong.