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

SDK Migration 10: migrate policies to go-azure-sdk #1484

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading