Skip to content

Commit

Permalink
SDK Migration: migrate policies to go-azure-sdk
Browse files Browse the repository at this point in the history
  • Loading branch information
manicminer committed Sep 23, 2024
1 parent b36e16e commit c292482
Show file tree
Hide file tree
Showing 14 changed files with 642 additions and 486 deletions.
132 changes: 81 additions & 51 deletions internal/services/policies/authentication_strength_policy_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,22 @@ import (
"errors"
"fmt"
"log"
"net/http"
"slices"
"strings"
"time"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-sdk/sdk/odata"
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-sdk/microsoft-graph/common-types/stable"
"github.com/hashicorp/go-azure-sdk/microsoft-graph/policies/stable/authenticationstrengthpolicy"
"github.com/hashicorp/go-azure-sdk/sdk/nullable"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-provider-azuread/internal/clients"
"github.com/hashicorp/terraform-provider-azuread/internal/helpers"
"github.com/hashicorp/terraform-provider-azuread/internal/tf"
"github.com/hashicorp/terraform-provider-azuread/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azuread/internal/tf/validation"
"github.com/manicminer/hamilton/msgraph"
"github.com/hashicorp/terraform-provider-azuread/internal/helpers/consistency"
"github.com/hashicorp/terraform-provider-azuread/internal/helpers/tf"
"github.com/hashicorp/terraform-provider-azuread/internal/helpers/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azuread/internal/helpers/tf/validation"
)

func authenticationStrengthPolicyResource() *pluginsdk.Resource {
Expand Down Expand Up @@ -64,109 +67,136 @@ func authenticationStrengthPolicyResource() *pluginsdk.Resource {
Required: true,
Elem: &pluginsdk.Schema{
Type: pluginsdk.TypeString,
ValidateFunc: func(in interface{}, k string) ([]string, []error) {
val, ok := in.(string)
if !ok {
return nil, []error{fmt.Errorf("expected a string value for %q", k)}
}
split := strings.Split(val, ",")
for _, s := range split {
if !slices.Contains(stable.PossibleValuesForAuthenticationMethodModes(), strings.TrimSpace(s)) {
return nil, []error{fmt.Errorf("unrecognized authentication method %q in %q", s, k)}
}
}
return nil, nil
},
},
},
},
}
}

func authenticationStrengthPolicyCreate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*clients.Client).Policies.AuthenticationStrengthPoliciesClient
client := meta.(*clients.Client).Policies.AuthenticationStrengthPolicyClient

properties := msgraph.AuthenticationStrengthPolicy{
allowedCombinations := make([]stable.AuthenticationMethodModes, 0)
for _, v := range d.Get("allowed_combinations").(*pluginsdk.Set).List() {
allowedCombinations = append(allowedCombinations, stable.AuthenticationMethodModes(v.(string)))
}

properties := stable.AuthenticationStrengthPolicy{
DisplayName: pointer.To(d.Get("display_name").(string)),
Description: pointer.To(d.Get("description").(string)),
AllowedCombinations: tf.ExpandStringSlicePtr(d.Get("allowed_combinations").(*pluginsdk.Set).List()),
Description: nullable.NoZero(d.Get("description").(string)),
AllowedCombinations: pointer.To(allowedCombinations),
}

authenticationStrengthPolicy, _, err := client.Create(ctx, properties)
resp, err := client.CreateAuthenticationStrengthPolicy(ctx, properties, authenticationstrengthpolicy.DefaultCreateAuthenticationStrengthPolicyOperationOptions())
if err != nil {
return tf.ErrorDiagF(err, "Could not create authentication strength policy")
}

d.SetId(*authenticationStrengthPolicy.ID)
authenticationStrengthPolicy := resp.Model
if authenticationStrengthPolicy == nil {
return tf.ErrorDiagF(errors.New("model was nil"), "Could not create authentication strength policy")
}
if authenticationStrengthPolicy.Id == nil {
return tf.ErrorDiagF(errors.New("model returned with nil ID"), "Could not create authentication strength policy")
}

id := stable.NewPolicyAuthenticationStrengthPolicyID(*authenticationStrengthPolicy.Id)
d.SetId(id.AuthenticationStrengthPolicyId)

return authenticationStrengthPolicyRead(ctx, d, meta)
}

func authenticationStrengthPolicyUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*clients.Client).Policies.AuthenticationStrengthPoliciesClient
client := meta.(*clients.Client).Policies.AuthenticationStrengthPolicyClient
id := stable.NewPolicyAuthenticationStrengthPolicyID(d.Id())

properties := msgraph.AuthenticationStrengthPolicy{
ID: pointer.To(d.Id()),
properties := stable.AuthenticationStrengthPolicy{
DisplayName: pointer.To(d.Get("display_name").(string)),
Description: pointer.To(d.Get("description").(string)),
Description: nullable.NoZero(d.Get("description").(string)),
}

_, err := client.Update(ctx, properties)
if err != nil {
return tf.ErrorDiagF(err, "Could not update authentication strength policy")
if _, err := client.UpdateAuthenticationStrengthPolicy(ctx, id, properties, authenticationstrengthpolicy.DefaultUpdateAuthenticationStrengthPolicyOperationOptions()); err != nil {
return tf.ErrorDiagF(err, "Could not update %s", id)
}

if d.HasChange("allowed_combinations") {
properties.AllowedCombinations = tf.ExpandStringSlicePtr(d.Get("allowed_combinations").(*pluginsdk.Set).List())
_, err := client.UpdateAllowedCombinations(ctx, properties)
if err != nil {
return tf.ErrorDiagF(err, "Could not update authentication strength policy allowed combinations")
allowedCombinations := make([]stable.AuthenticationMethodModes, 0)
for _, v := range d.Get("allowed_combinations").(*pluginsdk.Set).List() {
allowedCombinations = append(allowedCombinations, stable.AuthenticationMethodModes(v.(string)))
}

request := authenticationstrengthpolicy.UpdateAuthenticationStrengthPolicyAllowedCombinationsRequest{
AllowedCombinations: pointer.To(allowedCombinations),
}

if _, err := client.UpdateAuthenticationStrengthPolicyAllowedCombinations(ctx, id, request, authenticationstrengthpolicy.DefaultUpdateAuthenticationStrengthPolicyAllowedCombinationsOperationOptions()); err != nil {
return tf.ErrorDiagF(err, "Could not update allowed combinations for %s", id)
}
}

return authenticationStrengthPolicyRead(ctx, d, meta)
}

func authenticationStrengthPolicyRead(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*clients.Client).Policies.AuthenticationStrengthPoliciesClient
client := meta.(*clients.Client).Policies.AuthenticationStrengthPolicyClient
id := stable.NewPolicyAuthenticationStrengthPolicyID(d.Id())

authenticationStrengthPolicy, status, err := client.Get(ctx, d.Id(), odata.Query{})
resp, err := client.GetAuthenticationStrengthPolicy(ctx, id, authenticationstrengthpolicy.DefaultGetAuthenticationStrengthPolicyOperationOptions())
if err != nil {
if status == http.StatusNotFound {
if response.WasNotFound(resp.HttpResponse) {
log.Printf("[DEBUG] Authentication Strength Policy with Object ID %q was not found - removing from state", d.Id())
d.SetId("")
return nil
}
}
authenticationStrengthPolicy := resp.Model
if authenticationStrengthPolicy == nil {
return tf.ErrorDiagF(errors.New("Bad API response"), "Result is nil")
}

d.SetId(*authenticationStrengthPolicy.ID)
tf.Set(d, "display_name", authenticationStrengthPolicy.DisplayName)
tf.Set(d, "description", authenticationStrengthPolicy.Description)
tf.Set(d, "allowed_combinations", tf.FlattenStringSlicePtr(authenticationStrengthPolicy.AllowedCombinations))
tf.Set(d, "display_name", pointer.From(authenticationStrengthPolicy.DisplayName))
tf.Set(d, "description", authenticationStrengthPolicy.Description.GetOrZero())

allowedCombinations := make([]string, 0)
for _, v := range pointer.From(authenticationStrengthPolicy.AllowedCombinations) {
allowedCombinations = append(allowedCombinations, string(v))
}
tf.Set(d, "allowed_combinations", tf.FlattenStringSlice(allowedCombinations))

return nil
}

func authenticationStrengthPolicyDelete(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*clients.Client).Policies.AuthenticationStrengthPoliciesClient
authenticationStrengthPolicyId := d.Id()
client := meta.(*clients.Client).Policies.AuthenticationStrengthPolicyClient
id := stable.NewPolicyAuthenticationStrengthPolicyID(d.Id())

if _, status, err := client.Get(ctx, authenticationStrengthPolicyId, odata.Query{}); err != nil {
if status == http.StatusNotFound {
log.Printf("[DEBUG] Authentication Strength Policy with ID %q already deleted", authenticationStrengthPolicyId)
return nil
}

return tf.ErrorDiagPathF(err, "id", "Retrieving Authentication Strength Policy with ID %q", authenticationStrengthPolicyId)
}

status, err := client.Delete(ctx, authenticationStrengthPolicyId)
if err != nil {
return tf.ErrorDiagPathF(err, "id", "Deleting Authentication Strength Policy with ID %q, got status %d", authenticationStrengthPolicyId, status)
if _, err := client.DeleteAuthenticationStrengthPolicy(ctx, id, authenticationstrengthpolicy.DefaultDeleteAuthenticationStrengthPolicyOperationOptions()); err != nil {
return tf.ErrorDiagPathF(err, "id", "Deleting %s", id)
}

if err := helpers.WaitForDeletion(ctx, func(ctx context.Context) (*bool, error) {
defer func() { client.BaseClient.DisableRetries = false }()
client.BaseClient.DisableRetries = true
if _, status, err := client.Get(ctx, authenticationStrengthPolicyId, odata.Query{}); err != nil {
if status == http.StatusNotFound {
if err := consistency.WaitForDeletion(ctx, func(ctx context.Context) (*bool, error) {
if resp, err := client.GetAuthenticationStrengthPolicy(ctx, id, authenticationstrengthpolicy.DefaultGetAuthenticationStrengthPolicyOperationOptions()); err != nil {
if response.WasNotFound(resp.HttpResponse) {
return pointer.To(false), nil
}
return nil, err
}
return pointer.To(true), nil
}); err != nil {
return tf.ErrorDiagF(err, "waiting for deletion of Authentication Strength Policy with ID %q", authenticationStrengthPolicyId)
return tf.ErrorDiagF(err, "waiting for deletion of %s", id)
}

return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ package policies_test
import (
"context"
"fmt"
"net/http"
"testing"

"github.com/hashicorp/go-azure-helpers/lang/pointer"
"github.com/hashicorp/go-azure-sdk/sdk/odata"
"github.com/hashicorp/go-azure-helpers/lang/response"
"github.com/hashicorp/go-azure-sdk/microsoft-graph/common-types/stable"
"github.com/hashicorp/go-azure-sdk/microsoft-graph/policies/stable/authenticationstrengthpolicy"
"github.com/hashicorp/terraform-provider-azuread/internal/acceptance"
"github.com/hashicorp/terraform-provider-azuread/internal/acceptance/check"
"github.com/hashicorp/terraform-provider-azuread/internal/clients"
"github.com/hashicorp/terraform-provider-azuread/internal/tf/pluginsdk"
"github.com/hashicorp/terraform-provider-azuread/internal/helpers/tf/pluginsdk"
)

type AuthenticationStrengthPolicyResource struct{}
Expand Down Expand Up @@ -78,19 +79,19 @@ func TestAccAuthenticationStrengthPolicy_update(t *testing.T) {
})
}

func (r AuthenticationStrengthPolicyResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
var id *string
func (r AuthenticationStrengthPolicyResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) {
client := clients.Policies.AuthenticationStrengthPolicyClient
id := stable.NewPolicyAuthenticationStrengthPolicyID(state.ID)

authstrengthpolicy, status, err := client.Policies.AuthenticationStrengthPoliciesClient.Get(ctx, state.ID, odata.Query{})
resp, err := client.GetAuthenticationStrengthPolicy(ctx, id, authenticationstrengthpolicy.DefaultGetAuthenticationStrengthPolicyOperationOptions())
if err != nil {
if status == http.StatusNotFound {
return nil, fmt.Errorf("Authentication Strength Policy with ID %q does not exist", state.ID)
if response.WasNotFound(resp.HttpResponse) {
return pointer.To(false), nil
}
return nil, fmt.Errorf("failed to retrieve Authentication Strength Policy with ID %q: %+v", state.ID, err)
return nil, fmt.Errorf("failed to retrieve %s: %v", id, err)
}
id = authstrengthpolicy.ID

return pointer.To(id != nil && *id == state.ID), nil
return pointer.To(true), nil
}

func (AuthenticationStrengthPolicyResource) basic(data acceptance.TestData) string {
Expand All @@ -113,14 +114,13 @@ resource "azuread_authentication_strength_policy" "test" {
display_name = "acctestASP-%[1]d"
description = "test"
allowed_combinations = [
"fido2",
"password",
"deviceBasedPush",
"temporaryAccessPassOneTime",
"federatedMultiFactor",
"federatedSingleFactor",
"fido2",
"hardwareOath,federatedSingleFactor",
"microsoftAuthenticatorPush,federatedSingleFactor",
"password",
"password,hardwareOath",
"password,microsoftAuthenticatorPush",
"password,sms",
Expand All @@ -130,6 +130,7 @@ resource "azuread_authentication_strength_policy" "test" {
"sms,federatedSingleFactor",
"softwareOath,federatedSingleFactor",
"temporaryAccessPassMultiUse",
"temporaryAccessPassOneTime",
"voice,federatedSingleFactor",
"windowsHelloForBusiness",
"x509CertificateMultiFactor",
Expand Down
Loading

0 comments on commit c292482

Please sign in to comment.