From fdc2a83270e13982ed7c9f461564971b074365ae Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 25 Sep 2024 21:55:07 +0100 Subject: [PATCH 1/2] Remove deprecated properties and switch to SDK ID parsers/validators where there is a 1:1 match --- .../application_api_access_resource.go | 2 +- .../application_app_role_resource.go | 2 +- .../application_certificate_resource.go | 65 ++-------- .../application_certificate_resource_test.go | 64 ---------- .../applications/application_data_source.go | 27 +--- .../application_data_source_test.go | 23 ---- ...ication_fallback_public_client_resource.go | 2 +- ..._federated_identity_credential_resource.go | 61 +-------- ...rated_identity_credential_resource_test.go | 62 --------- .../application_identifier_uri_resource.go | 2 +- .../application_known_clients_resource.go | 2 +- .../application_optional_claims_resource.go | 2 +- .../application_owner_resource.go | 30 ++--- .../application_owner_resource_test.go | 5 +- .../application_password_resource.go | 65 ++-------- .../application_password_resource_test.go | 58 --------- .../application_permission_scope_resource.go | 2 +- .../application_pre_authorized_resource.go | 97 ++------------ ...pplication_pre_authorized_resource_test.go | 118 +----------------- .../application_redirect_uris_resource.go | 2 +- .../application_registration_resource.go | 3 +- .../applications/application_resource.go | 11 +- .../applications/application_resource_test.go | 7 -- .../migrations/application_resource.go | 31 ++--- .../applications/parse/application.go | 83 ------------ internal/services/applications/parse/owner.go | 95 -------------- .../applications/parse/service_principal.go | 83 ------------ .../directory_role_assignment_resource.go | 42 +------ .../service_principal_data_source.go | 24 +--- .../service_principal_data_source_test.go | 27 +--- .../service_principal_resource.go | 25 +--- .../service_principal_resource_test.go | 29 ----- .../service_principals_data_source.go | 37 +----- .../service_principals_data_source_test.go | 29 ----- 34 files changed, 95 insertions(+), 1122 deletions(-) delete mode 100644 internal/services/applications/parse/application.go delete mode 100644 internal/services/applications/parse/owner.go delete mode 100644 internal/services/applications/parse/service_principal.go diff --git a/internal/services/applications/application_api_access_resource.go b/internal/services/applications/application_api_access_resource.go index 2191399016..320049894a 100644 --- a/internal/services/applications/application_api_access_resource.go +++ b/internal/services/applications/application_api_access_resource.go @@ -51,7 +51,7 @@ func (r ApplicationApiAccessResource) Arguments() map[string]*pluginsdk.Schema { Type: pluginsdk.TypeString, Required: true, ForceNew: true, - ValidateFunc: parse.ValidateApplicationID, + ValidateFunc: stable.ValidateApplicationID, }, "api_client_id": { diff --git a/internal/services/applications/application_app_role_resource.go b/internal/services/applications/application_app_role_resource.go index a7e0534a2c..a06cdc0675 100644 --- a/internal/services/applications/application_app_role_resource.go +++ b/internal/services/applications/application_app_role_resource.go @@ -54,7 +54,7 @@ func (r ApplicationAppRoleResource) Arguments() map[string]*pluginsdk.Schema { Type: pluginsdk.TypeString, Required: true, ForceNew: true, - ValidateFunc: parse.ValidateApplicationID, + ValidateFunc: stable.ValidateApplicationID, }, "role_id": { diff --git a/internal/services/applications/application_certificate_resource.go b/internal/services/applications/application_certificate_resource.go index 398db57fea..450a96eed1 100644 --- a/internal/services/applications/application_certificate_resource.go +++ b/internal/services/applications/application_certificate_resource.go @@ -13,7 +13,6 @@ import ( "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/microsoft-graph/applications/stable/application" "github.com/hashicorp/go-azure-sdk/microsoft-graph/common-types/stable" - "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/helpers/consistency" "github.com/hashicorp/terraform-provider-azuread/internal/helpers/credentials" @@ -45,36 +44,9 @@ func applicationCertificateResource() *pluginsdk.Resource { "application_id": { Description: "The resource ID of the application for which this certificate should be created", Type: pluginsdk.TypeString, - Optional: true, - Computed: true, // TODO remove Computed in v3.0 - ForceNew: true, - ExactlyOneOf: []string{"application_id", "application_object_id"}, - ValidateFunc: parse.ValidateApplicationID, - }, - - "application_object_id": { - Description: "The object ID of the application for which this certificate should be created", - Type: pluginsdk.TypeString, - Optional: true, - Computed: true, + Required: true, ForceNew: true, - ExactlyOneOf: []string{"application_id", "application_object_id"}, - Deprecated: "The `application_object_id` property has been replaced with the `application_id` property and will be removed in version 3.0 of the AzureAD provider", - ValidateFunc: validation.Any(validation.IsUUID, parse.ValidateApplicationID), - DiffSuppressFunc: func(_, oldValue, newValue string, _ *pluginsdk.ResourceData) bool { - // Where oldValue is a UUID (i.e. the bare object ID), and newValue is a properly formed application - // resource ID, we'll ignore a diff where these point to the same application resource. - // This maintains compatibility with configurations mixing the ID attributes, e.g. - // application_object_id = azuread_application.example.id - if _, err := uuid.ParseUUID(oldValue); err == nil { - if applicationId, err := parse.ParseApplicationID(newValue); err == nil { - if applicationId.ApplicationId == oldValue { - return true - } - } - } - return false - }, + ValidateFunc: stable.ValidateApplicationID, }, "encoding": { @@ -152,24 +124,9 @@ func applicationCertificateResource() *pluginsdk.Resource { func applicationCertificateResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { client := meta.(*clients.Client).Applications.ApplicationClient - var applicationId *stable.ApplicationId - var err error - if v := d.Get("application_id").(string); v != "" { - if applicationId, err = stable.ParseApplicationID(v); err != nil { - return tf.ErrorDiagPathF(err, "application_id", "Parsing `application_id`: %q", v) - } - } else { - // TODO: this permits parsing the application_object_id as either a structured ID or a bare UUID, to avoid - // breaking users who might have `application_object_id = azuread_application.foo.id` in their config, and - // should be removed in version 3.0 along with the application_object_id property - v = d.Get("application_object_id").(string) - if _, err = uuid.ParseUUID(v); err == nil { - applicationId = pointer.To(stable.NewApplicationID(v)) - } else { - if applicationId, err = stable.ParseApplicationID(v); err != nil { - return tf.ErrorDiagPathF(err, "application_id", "Parsing `application_object_id`: %q", v) - } - } + applicationId, err := stable.ParseApplicationID(d.Get("application_id").(string)) + if err != nil { + return tf.ErrorDiagPathF(err, "application_id", "Parsing `application_id`") } credential, err := credentials.KeyCredentialForResource(d) @@ -191,7 +148,7 @@ func applicationCertificateResourceCreate(ctx context.Context, d *pluginsdk.Reso resp, err := client.GetApplication(ctx, *applicationId, application.DefaultGetApplicationOperationOptions()) if err != nil { - return tf.ErrorDiagPathF(err, "application_object_id", "Retrieving %s", applicationId) + return tf.ErrorDiagPathF(err, "application_id", "Retrieving %s", applicationId) } app := resp.Model @@ -272,7 +229,7 @@ func applicationCertificateResourceRead(ctx context.Context, d *pluginsdk.Resour resp, err := client.GetApplication(ctx, applicationId, application.DefaultGetApplicationOperationOptions()) if err != nil { - return tf.ErrorDiagPathF(err, "application_object_id", "Retrieving %s", applicationId) + return tf.ErrorDiagPathF(err, "application_id", "Retrieving %s", applicationId) } app := resp.Model @@ -293,12 +250,6 @@ func applicationCertificateResourceRead(ctx context.Context, d *pluginsdk.Resour tf.Set(d, "start_date", credential.StartDateTime.GetOrZero()) tf.Set(d, "end_date", credential.EndDateTime.GetOrZero()) - if v := d.Get("application_object_id").(string); v != "" { - tf.Set(d, "application_object_id", v) - } else { - tf.Set(d, "application_object_id", id.ObjectId) - } - return nil } @@ -317,7 +268,7 @@ func applicationCertificateResourceDelete(ctx context.Context, d *pluginsdk.Reso resp, err := client.GetApplication(ctx, applicationId, application.DefaultGetApplicationOperationOptions()) if err != nil { - return tf.ErrorDiagPathF(err, "application_object_id", "Retrieving %s", applicationId) + return tf.ErrorDiagPathF(err, "application_id", "Retrieving %s", applicationId) } app := resp.Model diff --git a/internal/services/applications/application_certificate_resource_test.go b/internal/services/applications/application_certificate_resource_test.go index 8d36e945ee..576bdf9ca7 100644 --- a/internal/services/applications/application_certificate_resource_test.go +++ b/internal/services/applications/application_certificate_resource_test.go @@ -172,40 +172,6 @@ func TestAccApplicationCertificate_requiresImport(t *testing.T) { }) } -func TestAccApplicationCertificate_deprecatedId(t *testing.T) { - data := acceptance.BuildTestData(t, "azuread_application_certificate", "test") - endDate := time.Now().AddDate(0, 3, 27).UTC().Format(time.RFC3339) - r := ApplicationCertificateResource{} - - data.ResourceTest(t, r, []acceptance.TestStep{ - { - Config: r.deprecatedId(data, endDate), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("key_id").Exists(), - ), - }, - data.ImportStep("encoding", "end_date_relative", "value"), - }) -} - -func TestAccApplicationCertificate_deprecatedId2(t *testing.T) { - data := acceptance.BuildTestData(t, "azuread_application_certificate", "test") - endDate := time.Now().AddDate(0, 3, 27).UTC().Format(time.RFC3339) - r := ApplicationCertificateResource{} - - data.ResourceTest(t, r, []acceptance.TestStep{ - { - Config: r.deprecatedId2(data, endDate), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("key_id").Exists(), - ), - }, - data.ImportStep("application_object_id", "encoding", "end_date_relative", "value"), - }) -} - func (ApplicationCertificateResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { client := clients.Applications.ApplicationClient @@ -341,33 +307,3 @@ resource "azuread_application_certificate" "import" { } `, r.basic(data, endDate)) } - -func (r ApplicationCertificateResource) deprecatedId(data acceptance.TestData, endDate string) string { - return fmt.Sprintf(` -%[1]s - -resource "azuread_application_certificate" "test" { - application_object_id = azuread_application.test.object_id - type = "AsymmetricX509Cert" - end_date = "%[2]s" - value = < 0 { + if _, errs := stable.ValidateApplicationID(id, "id"); len(errs) > 0 { out := "" for _, err := range errs { out += err.Error() @@ -642,13 +641,6 @@ func applicationResource() *pluginsdk.Resource { }, }, - "application_id": { - Description: "The Application ID (also called Client ID)", - Type: pluginsdk.TypeString, - Computed: true, - Deprecated: "The `application_id` attribute has been replaced by the `client_id` attribute and will be removed in version 3.0 of the AzureAD provider", - }, - "client_id": { Description: "The Client ID (also called Application ID)", Type: pluginsdk.TypeString, @@ -1635,7 +1627,6 @@ func applicationResourceRead(ctx context.Context, d *pluginsdk.ResourceData, met tf.Set(d, "api", flattenApplicationApi(app.Api, false)) tf.Set(d, "app_role", applications.FlattenAppRoles(app.AppRoles)) tf.Set(d, "app_role_ids", applications.FlattenAppRoleIDs(app.AppRoles)) - tf.Set(d, "application_id", app.AppId.GetOrZero()) tf.Set(d, "client_id", app.AppId.GetOrZero()) tf.Set(d, "description", app.Description.GetOrZero()) tf.Set(d, "device_only_auth_enabled", app.IsDeviceOnlyAuthSupported.GetOrZero()) diff --git a/internal/services/applications/application_resource_test.go b/internal/services/applications/application_resource_test.go index 08a7db7820..91d91dee50 100644 --- a/internal/services/applications/application_resource_test.go +++ b/internal/services/applications/application_resource_test.go @@ -31,7 +31,6 @@ func TestAccApplication_basic(t *testing.T) { Config: r.basic(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("application_id").Exists(), check.That(data.ResourceName).Key("client_id").Exists(), check.That(data.ResourceName).Key("object_id").Exists(), check.That(data.ResourceName).Key("password.#").HasValue("0"), @@ -51,7 +50,6 @@ func TestAccApplication_basicFromTemplate(t *testing.T) { Config: r.basicFromTemplate(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("application_id").Exists(), check.That(data.ResourceName).Key("client_id").Exists(), check.That(data.ResourceName).Key("object_id").Exists(), check.That(data.ResourceName).Key("display_name").HasValue(fmt.Sprintf("acctest-APP-%d", data.RandomInteger)), @@ -71,7 +69,6 @@ func TestAccApplication_complete(t *testing.T) { Config: r.complete(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("application_id").Exists(), check.That(data.ResourceName).Key("client_id").Exists(), check.That(data.ResourceName).Key("object_id").Exists(), ), @@ -89,7 +86,6 @@ func TestAccApplication_completeFromTemplate(t *testing.T) { Config: r.completeFromTemplate(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("application_id").Exists(), check.That(data.ResourceName).Key("client_id").Exists(), check.That(data.ResourceName).Key("object_id").Exists(), check.That(data.ResourceName).Key("template_id").HasValue(testApplicationTemplateId), @@ -110,7 +106,6 @@ func TestAccApplication_update(t *testing.T) { Config: r.basic(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("application_id").Exists(), check.That(data.ResourceName).Key("client_id").Exists(), check.That(data.ResourceName).Key("object_id").Exists(), ), @@ -120,7 +115,6 @@ func TestAccApplication_update(t *testing.T) { Config: r.complete(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("application_id").Exists(), check.That(data.ResourceName).Key("client_id").Exists(), check.That(data.ResourceName).Key("object_id").Exists(), ), @@ -130,7 +124,6 @@ func TestAccApplication_update(t *testing.T) { Config: r.basic(data), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), - check.That(data.ResourceName).Key("application_id").Exists(), check.That(data.ResourceName).Key("client_id").Exists(), check.That(data.ResourceName).Key("object_id").Exists(), ), diff --git a/internal/services/applications/migrations/application_resource.go b/internal/services/applications/migrations/application_resource.go index 8f5bc23c76..bc8df88c9c 100644 --- a/internal/services/applications/migrations/application_resource.go +++ b/internal/services/applications/migrations/application_resource.go @@ -8,9 +8,9 @@ import ( "fmt" "log" + "github.com/hashicorp/go-azure-sdk/microsoft-graph/common-types/stable" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/helpers/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" ) func ResourceApplicationInstanceResourceV0() *pluginsdk.Resource { @@ -27,7 +27,6 @@ func ResourceApplicationInstanceResourceV0() *pluginsdk.Resource { Type: pluginsdk.TypeString, Optional: true, Computed: true, - Deprecated: "This property has been renamed to `display_name` and will be removed in version 2.0 of the AzureAD provider", ExactlyOneOf: []string{"display_name", "name"}, }, @@ -128,10 +127,9 @@ func ResourceApplicationInstanceResourceV0() *pluginsdk.Resource { }, "is_enabled": { - Type: pluginsdk.TypeBool, - Optional: true, - Default: true, - Deprecated: "[NOTE] This attribute has been renamed to `enabled` and will be removed in version 2.0 of the AzureAD provider", + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, }, "value": { @@ -148,7 +146,6 @@ func ResourceApplicationInstanceResourceV0() *pluginsdk.Resource { Optional: true, Computed: true, ConflictsWith: []string{"sign_in_audience"}, - Deprecated: "[NOTE] This attribute will be replaced by a new property `sign_in_audience` in version 2.0 of the AzureAD provider", }, "fallback_public_client_enabled": { @@ -159,9 +156,8 @@ func ResourceApplicationInstanceResourceV0() *pluginsdk.Resource { }, "group_membership_claims": { - Type: pluginsdk.TypeString, - Optional: true, - Deprecated: "[NOTE] This attribute will become a list in version 2.0 of the AzureAD provider", + Type: pluginsdk.TypeString, + Optional: true, }, "homepage": { @@ -169,7 +165,6 @@ func ResourceApplicationInstanceResourceV0() *pluginsdk.Resource { Optional: true, Computed: true, ConflictsWith: []string{"web.0.homepage_url"}, - Deprecated: "[NOTE] This attribute will be replaced by a new attribute `homepage_url` in the `web` block in version 2.0 of the AzureAD provider", }, "identifier_uris": { @@ -186,7 +181,6 @@ func ResourceApplicationInstanceResourceV0() *pluginsdk.Resource { Optional: true, Computed: true, ConflictsWith: []string{"web.0.logout_url"}, - Deprecated: "[NOTE] This attribute will be moved into the `web` block in version 2.0 of the AzureAD provider", }, "oauth2_allow_implicit_flow": { @@ -194,7 +188,6 @@ func ResourceApplicationInstanceResourceV0() *pluginsdk.Resource { Optional: true, Computed: true, ConflictsWith: []string{"web.0.implicit_grant.0.access_token_issuance_enabled"}, - Deprecated: "[NOTE] This attribute will be moved to the `implicit_grant` block and renamed to `access_token_issuance_enabled` in version 2.0 of the AzureAD provider", }, "oauth2_permissions": { @@ -202,7 +195,6 @@ func ResourceApplicationInstanceResourceV0() *pluginsdk.Resource { Optional: true, Computed: true, ConfigMode: pluginsdk.SchemaConfigModeAttr, - Deprecated: "[NOTE] The `oauth2_permissions` block has been renamed to `oauth2_permission_scope` and moved to the `api` block. `oauth2_permissions` will be removed in version 2.0 of the AzureAD provider.", Elem: &pluginsdk.Resource{ Schema: map[string]*pluginsdk.Schema{ "id": { @@ -338,7 +330,6 @@ func ResourceApplicationInstanceResourceV0() *pluginsdk.Resource { Optional: true, Computed: true, ConflictsWith: []string{"fallback_public_client_enabled"}, - Deprecated: "[NOTE] This legacy attribute will be renamed to `fallback_public_client_enabled` in version 2.0 of the AzureAD provider", }, "reply_urls": { @@ -346,7 +337,6 @@ func ResourceApplicationInstanceResourceV0() *pluginsdk.Resource { Optional: true, Computed: true, ConflictsWith: []string{"web.0.redirect_uris"}, - Deprecated: "[NOTE] This attribute will be replaced by a new attribute `redirect_uris` in the `web` block in version 2.0 of the AzureAD provider", Elem: &pluginsdk.Schema{ Type: pluginsdk.TypeString, }, @@ -391,10 +381,9 @@ func ResourceApplicationInstanceResourceV0() *pluginsdk.Resource { }, "type": { - Type: pluginsdk.TypeString, - Optional: true, - Deprecated: "[NOTE] This legacy property is deprecated and will be removed in version 2.0 of the AzureAD provider", - Default: "webapp/api", + Type: pluginsdk.TypeString, + Optional: true, + Default: "webapp/api", }, "web": { @@ -1019,7 +1008,7 @@ func ResourceApplicationInstanceStateUpgradeV1(_ context.Context, rawState map[s return rawState, fmt.Errorf("parsing ID for `azuread_application`: %+v", err) } - newId := parse.NewApplicationID(oldId) + newId := stable.NewApplicationID(oldId) rawState["id"] = newId.ID() return rawState, nil } diff --git a/internal/services/applications/parse/application.go b/internal/services/applications/parse/application.go deleted file mode 100644 index 91ed95495f..0000000000 --- a/internal/services/applications/parse/application.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package parse - -import ( - "fmt" - - "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/hashicorp/terraform-provider-azuread/internal/helpers/tf/validation" -) - -type ApplicationId struct { - ApplicationId string -} - -func NewApplicationID(applicationId string) *ApplicationId { - return &ApplicationId{ - ApplicationId: applicationId, - } -} - -// ParseApplicationID parses 'input' into an ApplicationId -func ParseApplicationID(input string) (*ApplicationId, error) { - parser := resourceids.NewParserFromResourceIdType(&ApplicationId{}) - parsed, err := parser.Parse(input, false) - if err != nil { - return nil, fmt.Errorf("parsing %q: %+v", input, err) - } - - var ok bool - id := &ApplicationId{} - - if id.ApplicationId, ok = parsed.Parsed["applicationId"]; !ok { - return nil, resourceids.NewSegmentNotSpecifiedError(id, "applicationId", *parsed) - } - - return id, nil -} - -// ValidateApplicationID checks that 'input' can be parsed as an Application ID -func ValidateApplicationID(input interface{}, key string) (warnings []string, errors []error) { - v, ok := input.(string) - if !ok { - errors = append(errors, fmt.Errorf("expected %q to be a string", key)) - return - } - - id, err := ParseApplicationID(v) - if err != nil { - errors = append(errors, err) - return - } - - return validation.IsUUID(id.ApplicationId, "ID") -} - -func (id *ApplicationId) ID() string { - fmtString := "/applications/%s" - return fmt.Sprintf(fmtString, id.ApplicationId) -} - -// Segments returns a slice of Resource ID Segments which comprise this ID -func (id *ApplicationId) Segments() []resourceids.Segment { - return []resourceids.Segment{ - resourceids.StaticSegment("applications", "applications", "applications"), - resourceids.UserSpecifiedSegment("applicationId", "00000000-0000-0000-0000-000000000000"), - } -} - -func (id *ApplicationId) String() string { - return fmt.Sprintf("Application (Object ID: %q)", id.ApplicationId) -} - -func (id *ApplicationId) FromParseResult(input resourceids.ParseResult) error { - var ok bool - - if id.ApplicationId, ok = input.Parsed["applicationId"]; !ok { - return resourceids.NewSegmentNotSpecifiedError(id, "applicationId", input) - } - - return nil -} diff --git a/internal/services/applications/parse/owner.go b/internal/services/applications/parse/owner.go deleted file mode 100644 index 80cc232c14..0000000000 --- a/internal/services/applications/parse/owner.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package parse - -import ( - "fmt" - - "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/hashicorp/terraform-provider-azuread/internal/helpers/tf/validation" -) - -type OwnerId struct { - ApplicationId string - OwnerId string -} - -func NewOwnerID(applicationId, ownerId string) *OwnerId { - return &OwnerId{ - ApplicationId: applicationId, - OwnerId: ownerId, - } -} - -// ParseOwnerID parses 'input' into an OwnerId -func ParseOwnerID(input string) (*OwnerId, error) { - parser := resourceids.NewParserFromResourceIdType(&OwnerId{}) - parsed, err := parser.Parse(input, false) - if err != nil { - return nil, fmt.Errorf("parsing %q: %+v", input, err) - } - - var ok bool - id := &OwnerId{} - - if id.ApplicationId, ok = parsed.Parsed["applicationId"]; !ok { - return nil, resourceids.NewSegmentNotSpecifiedError(id, "applicationId", *parsed) - } - - if id.OwnerId, ok = parsed.Parsed["ownerId"]; !ok { - return nil, resourceids.NewSegmentNotSpecifiedError(id, "ownerId", *parsed) - } - - return id, nil -} - -// ValidateOwnerID checks that 'input' can be parsed as an Application ID -func ValidateOwnerID(input interface{}, key string) (warnings []string, errors []error) { - v, ok := input.(string) - if !ok { - errors = append(errors, fmt.Errorf("expected %q to be a string", key)) - return - } - - id, err := ParseOwnerID(v) - if err != nil { - errors = append(errors, err) - return - } - - return validation.IsUUID(id.OwnerId, "ID") -} - -func (id *OwnerId) ID() string { - fmtString := "/applications/%s/owners/%s" - return fmt.Sprintf(fmtString, id.ApplicationId, id.OwnerId) -} - -// Segments returns a slice of Resource ID Segments which comprise this ID -func (id *OwnerId) Segments() []resourceids.Segment { - return []resourceids.Segment{ - resourceids.StaticSegment("applications", "applications", "applications"), - resourceids.UserSpecifiedSegment("applicationId", "00000000-0000-0000-0000-000000000000"), - resourceids.StaticSegment("owners", "owners", "owners"), - resourceids.UserSpecifiedSegment("ownerId", "11111111-1111-1111-1111-111111111111"), - } -} - -func (id *OwnerId) String() string { - return fmt.Sprintf("Application Owner (Application ID: %q, Owner ID: %q)", id.ApplicationId, id.OwnerId) -} - -func (id *OwnerId) FromParseResult(input resourceids.ParseResult) error { - var ok bool - - if id.ApplicationId, ok = input.Parsed["applicationId"]; !ok { - return resourceids.NewSegmentNotSpecifiedError(id, "applicationId", input) - } - - if id.OwnerId, ok = input.Parsed["ownerId"]; !ok { - return resourceids.NewSegmentNotSpecifiedError(id, "ownerId", input) - } - - return nil -} diff --git a/internal/services/applications/parse/service_principal.go b/internal/services/applications/parse/service_principal.go deleted file mode 100644 index e9e667d1c1..0000000000 --- a/internal/services/applications/parse/service_principal.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package parse - -import ( - "fmt" - - "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/hashicorp/terraform-provider-azuread/internal/helpers/tf/validation" -) - -type ServicePrincipalId struct { - ServicePrincipalId string -} - -func NewServicePrincipalID(servicePrincipalId string) *ServicePrincipalId { - return &ServicePrincipalId{ - ServicePrincipalId: servicePrincipalId, - } -} - -// ParseServicePrincipalID parses 'input' into an ServicePrincipalId -func ParseServicePrincipalID(input string) (*ServicePrincipalId, error) { - parser := resourceids.NewParserFromResourceIdType(&ServicePrincipalId{}) - parsed, err := parser.Parse(input, false) - if err != nil { - return nil, fmt.Errorf("parsing %q: %+v", input, err) - } - - var ok bool - id := &ServicePrincipalId{} - - if id.ServicePrincipalId, ok = parsed.Parsed["servicePrincipalId"]; !ok { - return nil, resourceids.NewSegmentNotSpecifiedError(id, "servicePrincipalId", *parsed) - } - - return id, nil -} - -// ValidateServicePrincipalID checks that 'input' can be parsed as an ServicePrincipal ID -func ValidateServicePrincipalID(input interface{}, key string) (warnings []string, errors []error) { - v, ok := input.(string) - if !ok { - errors = append(errors, fmt.Errorf("expected %q to be a string", key)) - return - } - - id, err := ParseServicePrincipalID(v) - if err != nil { - errors = append(errors, err) - return - } - - return validation.IsUUID(id.ServicePrincipalId, "ID") -} - -func (id *ServicePrincipalId) ID() string { - fmtString := "/servicePrincipals/%s" - return fmt.Sprintf(fmtString, id.ServicePrincipalId) -} - -// Segments returns a slice of Resource ID Segments which comprise this ID -func (id *ServicePrincipalId) Segments() []resourceids.Segment { - return []resourceids.Segment{ - resourceids.StaticSegment("servicePrincipals", "servicePrincipals", "servicePrincipals"), - resourceids.UserSpecifiedSegment("servicePrincipalId", "00000000-0000-0000-0000-000000000000"), - } -} - -func (id *ServicePrincipalId) String() string { - return fmt.Sprintf("ServicePrincipal (Object ID: %q)", id.ServicePrincipalId) -} - -func (id *ServicePrincipalId) FromParseResult(input resourceids.ParseResult) error { - var ok bool - - if id.ServicePrincipalId, ok = input.Parsed["servicePrincipalId"]; !ok { - return resourceids.NewSegmentNotSpecifiedError(id, "servicePrincipalId", input) - } - - return nil -} diff --git a/internal/services/directoryroles/directory_role_assignment_resource.go b/internal/services/directoryroles/directory_role_assignment_resource.go index ad2b0e04c8..43bd9aa404 100644 --- a/internal/services/directoryroles/directory_role_assignment_resource.go +++ b/internal/services/directoryroles/directory_role_assignment_resource.go @@ -62,18 +62,7 @@ func directoryRoleAssignmentResource() *pluginsdk.Resource { Optional: true, Computed: true, ForceNew: true, - ConflictsWith: []string{"app_scope_object_id", "directory_scope_id", "directory_scope_object_id"}, - ValidateFunc: validation.StringIsNotEmpty, - }, - - "app_scope_object_id": { - Deprecated: "`app_scope_object_id` has been renamed to `app_scope_id` and will be removed in version 3.0 or the AzureAD Provider", - Description: "Identifier of the app-specific scope when the assignment scope is app-specific", - Type: pluginsdk.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ConflictsWith: []string{"app_scope_id", "directory_scope_id", "directory_scope_object_id"}, + ConflictsWith: []string{"directory_scope_id"}, ValidateFunc: validation.StringIsNotEmpty, }, @@ -83,17 +72,7 @@ func directoryRoleAssignmentResource() *pluginsdk.Resource { Optional: true, Computed: true, ForceNew: true, - ConflictsWith: []string{"app_scope_id", "app_scope_object_id", "directory_scope_object_id"}, - ValidateFunc: validation.StringIsNotEmpty, - }, - - "directory_scope_object_id": { - Description: "Identifier of the directory object representing the scope of the assignment", - Type: pluginsdk.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ConflictsWith: []string{"app_scope_id", "app_scope_object_id", "directory_scope_id"}, + ConflictsWith: []string{"app_scope_id"}, ValidateFunc: validation.StringIsNotEmpty, }, }, @@ -111,19 +90,8 @@ func directoryRoleAssignmentResourceCreate(ctx context.Context, d *pluginsdk.Res RoleDefinitionId: nullable.Value(roleId), } - var appScopeId, directoryScopeId string - - if v, ok := d.GetOk("app_scope_id"); ok { - appScopeId = v.(string) - } else if v, ok = d.GetOk("app_scope_object_id"); ok { - appScopeId = v.(string) - } - - if v, ok := d.GetOk("directory_scope_id"); ok { - directoryScopeId = v.(string) - } else if v, ok = d.GetOk("directory_scope_object_id"); ok { - directoryScopeId = v.(string) - } + appScopeId := d.Get("app_scope_id").(string) + directoryScopeId := d.Get("directory_scope_id").(string) switch { case appScopeId != "": @@ -197,9 +165,7 @@ func directoryRoleAssignmentResourceRead(ctx context.Context, d *pluginsdk.Resou } tf.Set(d, "app_scope_id", assignment.AppScopeId.GetOrZero()) - tf.Set(d, "app_scope_object_id", assignment.AppScopeId.GetOrZero()) tf.Set(d, "directory_scope_id", assignment.DirectoryScopeId.GetOrZero()) - tf.Set(d, "directory_scope_object_id", assignment.DirectoryScopeId.GetOrZero()) tf.Set(d, "principal_object_id", assignment.PrincipalId.GetOrZero()) tf.Set(d, "role_id", assignment.RoleDefinitionId.GetOrZero()) diff --git a/internal/services/serviceprincipals/service_principal_data_source.go b/internal/services/serviceprincipals/service_principal_data_source.go index b8b228a391..58d5851f92 100644 --- a/internal/services/serviceprincipals/service_principal_data_source.go +++ b/internal/services/serviceprincipals/service_principal_data_source.go @@ -38,7 +38,7 @@ func servicePrincipalData() *pluginsdk.Resource { Type: pluginsdk.TypeString, Optional: true, Computed: true, - ExactlyOneOf: []string{"client_id", "application_id", "display_name", "object_id"}, + ExactlyOneOf: []string{"client_id", "display_name", "object_id"}, ValidateFunc: validation.IsUUID, }, @@ -47,7 +47,7 @@ func servicePrincipalData() *pluginsdk.Resource { Type: pluginsdk.TypeString, Optional: true, Computed: true, - ExactlyOneOf: []string{"client_id", "application_id", "display_name", "object_id"}, + ExactlyOneOf: []string{"client_id", "display_name", "object_id"}, ValidateFunc: validation.StringIsNotEmpty, }, @@ -56,20 +56,10 @@ func servicePrincipalData() *pluginsdk.Resource { Type: pluginsdk.TypeString, Optional: true, Computed: true, - ExactlyOneOf: []string{"client_id", "application_id", "display_name", "object_id"}, + ExactlyOneOf: []string{"client_id", "display_name", "object_id"}, ValidateFunc: validation.IsUUID, }, - "application_id": { - Description: "The application ID (client ID) of the application associated with this service principal", - Type: pluginsdk.TypeString, - Optional: true, - Computed: true, - ExactlyOneOf: []string{"client_id", "application_id", "display_name", "object_id"}, - ValidateFunc: validation.IsUUID, - Deprecated: "The `application_id` property has been replaced with the `client_id` property and will be removed in version 3.0 of the AzureAD provider", - }, - "account_enabled": { Description: "Whether or not the service principal account is enabled", Type: pluginsdk.TypeBool, @@ -336,12 +326,7 @@ func servicePrincipalDataSourceRead(ctx context.Context, d *pluginsdk.ResourceDa } } } else { - var clientId string - if v := d.Get("client_id").(string); v != "" { - clientId = v - } else { - clientId = d.Get("application_id").(string) - } + clientId := d.Get("client_id").(string) options := serviceprincipal.ListServicePrincipalsOperationOptions{ Filter: pointer.To(fmt.Sprintf("appId eq '%s'", odata.EscapeSingleQuote(clientId))), @@ -402,7 +387,6 @@ func servicePrincipalDataSourceRead(ctx context.Context, d *pluginsdk.ResourceDa tf.Set(d, "app_role_assignment_required", servicePrincipal.AppRoleAssignmentRequired) tf.Set(d, "app_role_ids", applications.FlattenAppRoleIDs(servicePrincipal.AppRoles)) tf.Set(d, "app_roles", applications.FlattenAppRoles(servicePrincipal.AppRoles)) - tf.Set(d, "application_id", servicePrincipal.AppId.GetOrZero()) tf.Set(d, "application_tenant_id", servicePrincipal.AppOwnerOrganizationId.GetOrZero()) tf.Set(d, "client_id", servicePrincipal.AppId.GetOrZero()) tf.Set(d, "description", servicePrincipal.Description.GetOrZero()) diff --git a/internal/services/serviceprincipals/service_principal_data_source_test.go b/internal/services/serviceprincipals/service_principal_data_source_test.go index d1ee9e3e55..ffb70ed06e 100644 --- a/internal/services/serviceprincipals/service_principal_data_source_test.go +++ b/internal/services/serviceprincipals/service_principal_data_source_test.go @@ -27,18 +27,6 @@ func TestAccServicePrincipalDataSource_byClientId(t *testing.T) { }) } -func TestAccServicePrincipalDataSource_byDeprecatedApplicationId(t *testing.T) { - data := acceptance.BuildTestData(t, "data.azuread_service_principal", "test") - r := ServicePrincipalDataSource{} - - data.DataSourceTest(t, []acceptance.TestStep{ - { - Config: r.byDeprecatedApplicationId(data), - Check: r.testCheckFunc(data), - }, - }) -} - func TestAccServicePrincipalDataSource_byDisplayName(t *testing.T) { data := acceptance.BuildTestData(t, "data.azuread_service_principal", "test") r := ServicePrincipalDataSource{} @@ -102,7 +90,6 @@ func (ServicePrincipalDataSource) testCheckFunc(data acceptance.TestData) accept check.That(data.ResourceName).Key("app_role_assignment_required").HasValue("true"), check.That(data.ResourceName).Key("app_role_ids.%").HasValue("2"), check.That(data.ResourceName).Key("app_roles.#").HasValue("2"), - check.That(data.ResourceName).Key("application_id").IsUuid(), check.That(data.ResourceName).Key("application_tenant_id").HasValue(tenantId), check.That(data.ResourceName).Key("client_id").IsUuid(), check.That(data.ResourceName).Key("description").HasValue("An internal app for testing"), @@ -140,16 +127,6 @@ data "azuread_service_principal" "test" { `, ServicePrincipalResource{}.complete(data)) } -func (ServicePrincipalDataSource) byDeprecatedApplicationId(data acceptance.TestData) string { - return fmt.Sprintf(` -%[1]s - -data "azuread_service_principal" "test" { - application_id = azuread_service_principal.test.application_id -} -`, ServicePrincipalResource{}.complete(data)) -} - func (ServicePrincipalDataSource) byDisplayName(data acceptance.TestData) string { return fmt.Sprintf(` %[1]s @@ -167,7 +144,7 @@ resource "azuread_application" "test1" { } resource "azuread_service_principal" "test1" { - application_id = azuread_application.test1.application_id + client_id = azuread_application.test1.client_id } resource "azuread_application" "test2" { @@ -175,7 +152,7 @@ resource "azuread_application" "test2" { } resource "azuread_service_principal" "test2" { - application_id = azuread_application.test2.application_id + client_id = azuread_application.test2.client_id } data "azuread_service_principal" "test" { diff --git a/internal/services/serviceprincipals/service_principal_resource.go b/internal/services/serviceprincipals/service_principal_resource.go index 1c50996c22..594df36d5c 100644 --- a/internal/services/serviceprincipals/service_principal_resource.go +++ b/internal/services/serviceprincipals/service_principal_resource.go @@ -57,24 +57,11 @@ func servicePrincipalResource() *pluginsdk.Resource { "client_id": { Description: "The client ID of the application for which to create a service principal", Type: pluginsdk.TypeString, - Optional: true, - Computed: true, // TODO remove Computed in v3.0 + Required: true, ForceNew: true, - ExactlyOneOf: []string{"client_id", "application_id"}, ValidateFunc: validation.IsUUID, }, - "application_id": { - Description: "The application ID (client ID) of the application for which to create a service principal", - Type: pluginsdk.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ExactlyOneOf: []string{"client_id", "application_id"}, - ValidateFunc: validation.IsUUID, - Deprecated: "The `application_id` property has been replaced with the `client_id` property and will be removed in version 3.0 of the AzureAD provider", - }, - "account_enabled": { Description: "Whether or not the service principal account is enabled", Type: pluginsdk.TypeBool, @@ -366,14 +353,9 @@ func servicePrincipalDiffSuppress(k, old, new string, d *pluginsdk.ResourceData) func servicePrincipalResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { client := meta.(*clients.Client).ServicePrincipals.ServicePrincipalClient ownerClient := meta.(*clients.Client).ServicePrincipals.ServicePrincipalOwnerClient - callerId := meta.(*clients.Client).ObjectID - var clientId string - if v := d.Get("client_id").(string); v != "" { - clientId = v - } else { - clientId = d.Get("application_id").(string) - } + callerId := meta.(*clients.Client).ObjectID + clientId := d.Get("client_id").(string) listOptions := serviceprincipal.ListServicePrincipalsOperationOptions{ Filter: pointer.To(fmt.Sprintf("appId eq '%s'", odata.EscapeSingleQuote(clientId))), @@ -648,7 +630,6 @@ func servicePrincipalResourceRead(ctx context.Context, d *pluginsdk.ResourceData tf.Set(d, "app_role_assignment_required", servicePrincipal.AppRoleAssignmentRequired) tf.Set(d, "app_role_ids", applications.FlattenAppRoleIDs(servicePrincipal.AppRoles)) tf.Set(d, "app_roles", applications.FlattenAppRoles(servicePrincipal.AppRoles)) - tf.Set(d, "application_id", servicePrincipal.AppId.GetOrZero()) tf.Set(d, "application_tenant_id", servicePrincipal.AppOwnerOrganizationId.GetOrZero()) tf.Set(d, "client_id", servicePrincipal.AppId.GetOrZero()) tf.Set(d, "description", servicePrincipal.Description.GetOrZero()) diff --git a/internal/services/serviceprincipals/service_principal_resource_test.go b/internal/services/serviceprincipals/service_principal_resource_test.go index 405659d977..ebe8c2db06 100644 --- a/internal/services/serviceprincipals/service_principal_resource_test.go +++ b/internal/services/serviceprincipals/service_principal_resource_test.go @@ -314,21 +314,6 @@ func TestAccServicePrincipal_fromApplicationTemplate(t *testing.T) { }) } -func TestAccServicePrincipal_deprecatedId(t *testing.T) { - data := acceptance.BuildTestData(t, "azuread_service_principal", "test") - r := ServicePrincipalResource{} - - data.ResourceTest(t, r, []acceptance.TestStep{ - { - Config: r.deprecatedId(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - ), - }, - data.ImportStep("use_existing"), - }) -} - func (r ServicePrincipalResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { client := clients.ServicePrincipals.ServicePrincipalClient id := stable.NewServicePrincipalID(state.ID) @@ -707,17 +692,3 @@ resource "azuread_service_principal" "testC" { } `, data.RandomInteger) } - -func (ServicePrincipalResource) deprecatedId(data acceptance.TestData) string { - return fmt.Sprintf(` -provider "azuread" {} - -resource "azuread_application" "test" { - display_name = "acctestServicePrincipal-%[1]d" -} - -resource "azuread_service_principal" "test" { - application_id = azuread_application.test.application_id -} -`, data.RandomInteger) -} diff --git a/internal/services/serviceprincipals/service_principals_data_source.go b/internal/services/serviceprincipals/service_principals_data_source.go index bcfe9bf3c7..e0d0239be9 100644 --- a/internal/services/serviceprincipals/service_principals_data_source.go +++ b/internal/services/serviceprincipals/service_principals_data_source.go @@ -40,32 +40,19 @@ func servicePrincipalsDataSource() *pluginsdk.Resource { Type: pluginsdk.TypeList, Optional: true, Computed: true, - ExactlyOneOf: []string{"client_ids", "application_ids", "display_names", "object_ids", "return_all"}, + ExactlyOneOf: []string{"client_ids", "display_names", "object_ids", "return_all"}, Elem: &pluginsdk.Schema{ Type: pluginsdk.TypeString, ValidateFunc: validation.IsUUID, }, }, - "application_ids": { - Description: "The application IDs (client IDs) of the applications associated with the service principals", - Type: pluginsdk.TypeList, - Optional: true, - Computed: true, - ExactlyOneOf: []string{"client_ids", "application_ids", "display_names", "object_ids", "return_all"}, - Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - ValidateFunc: validation.IsUUID, - }, - Deprecated: "The `application_ids` property has been replaced with the `client_ids` property and will be removed in version 3.0 of the AzureAD provider", - }, - "display_names": { Description: "The display names of the applications associated with the service principals", Type: pluginsdk.TypeList, Optional: true, Computed: true, - ExactlyOneOf: []string{"client_ids", "application_ids", "display_names", "object_ids", "return_all"}, + ExactlyOneOf: []string{"client_ids", "display_names", "object_ids", "return_all"}, Elem: &pluginsdk.Schema{ Type: pluginsdk.TypeString, ValidateFunc: validation.StringIsNotEmpty, @@ -77,7 +64,7 @@ func servicePrincipalsDataSource() *pluginsdk.Resource { Type: pluginsdk.TypeList, Optional: true, Computed: true, - ExactlyOneOf: []string{"client_ids", "application_ids", "display_names", "object_ids", "return_all"}, + ExactlyOneOf: []string{"client_ids", "display_names", "object_ids", "return_all"}, Elem: &pluginsdk.Schema{ Type: pluginsdk.TypeString, ValidateFunc: validation.IsUUID, @@ -98,7 +85,7 @@ func servicePrincipalsDataSource() *pluginsdk.Resource { Optional: true, Default: false, ConflictsWith: []string{"ignore_missing"}, - ExactlyOneOf: []string{"client_ids", "application_ids", "display_names", "object_ids", "return_all"}, + ExactlyOneOf: []string{"client_ids", "display_names", "object_ids", "return_all"}, }, "service_principals": { @@ -119,13 +106,6 @@ func servicePrincipalsDataSource() *pluginsdk.Resource { Computed: true, }, - "application_id": { - Description: "The application ID (client ID) for the associated application", - Type: pluginsdk.TypeString, - Computed: true, - Deprecated: "The `application_id` attribute has been replaced by the `client_id` attribute and will be removed in version 3.0 of the AzureAD provider", - }, - "application_tenant_id": { Description: "The tenant ID where the associated application is registered", Type: pluginsdk.TypeString, @@ -221,12 +201,7 @@ func servicePrincipalsDataSourceRead(ctx context.Context, d *pluginsdk.ResourceD "tags", } - var clientIdsToSearch []string - if v, ok := d.Get("client_ids").([]interface{}); ok && len(v) > 0 { - clientIdsToSearch = tf.ExpandStringSlice(v) - } else if v, ok := d.Get("application_ids").([]interface{}); ok && len(v) > 0 { - clientIdsToSearch = tf.ExpandStringSlice(v) - } + clientIdsToSearch := tf.ExpandStringSlice(d.Get("client_ids").([]interface{})) if returnAll { resp, err := client.ListServicePrincipals(ctx, serviceprincipal.ListServicePrincipalsOperationOptions{Select: &fieldsToSelect}) if err != nil { @@ -363,7 +338,6 @@ func servicePrincipalsDataSourceRead(ctx context.Context, d *pluginsdk.ResourceD sp["account_enabled"] = s.AccountEnabled.GetOrZero() sp["display_name"] = s.DisplayName.GetOrZero() sp["app_role_assignment_required"] = pointer.From(s.AppRoleAssignmentRequired) - sp["application_id"] = s.AppId.GetOrZero() sp["application_tenant_id"] = s.AppOwnerOrganizationId.GetOrZero() sp["client_id"] = s.AppId.GetOrZero() sp["object_id"] = pointer.From(s.Id) @@ -383,7 +357,6 @@ func servicePrincipalsDataSourceRead(ctx context.Context, d *pluginsdk.ResourceD } d.SetId("serviceprincipals#" + base64.URLEncoding.EncodeToString(h.Sum(nil))) - tf.Set(d, "application_ids", clientIds) tf.Set(d, "client_ids", clientIds) tf.Set(d, "display_names", displayNames) tf.Set(d, "object_ids", objectIds) diff --git a/internal/services/serviceprincipals/service_principals_data_source_test.go b/internal/services/serviceprincipals/service_principals_data_source_test.go index e131d764df..d281a9795e 100644 --- a/internal/services/serviceprincipals/service_principals_data_source_test.go +++ b/internal/services/serviceprincipals/service_principals_data_source_test.go @@ -41,20 +41,6 @@ func TestAccServicePrincipalsDataSource_byClientIdsWithIgnoreMissing(t *testing. }}) } -func TestAccServicePrincipalsDataSource_byDeprecatedApplicationIds(t *testing.T) { - data := acceptance.BuildTestData(t, "data.azuread_service_principals", "test") - - data.DataSourceTest(t, []acceptance.TestStep{{ - Config: ServicePrincipalsDataSource{}.byDeprecatedApplicationIds(data), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).Key("application_ids.#").HasValue("2"), - check.That(data.ResourceName).Key("display_names.#").HasValue("2"), - check.That(data.ResourceName).Key("object_ids.#").HasValue("2"), - check.That(data.ResourceName).Key("service_principals.#").HasValue("2"), - ), - }}) -} - func TestAccServicePrincipalsDataSource_byDisplayNames(t *testing.T) { data := acceptance.BuildTestData(t, "data.azuread_service_principals", "test") @@ -113,7 +99,6 @@ func TestAccServicePrincipalsDataSource_noNames(t *testing.T) { data.DataSourceTest(t, []acceptance.TestStep{{ Config: ServicePrincipalsDataSource{}.noNames(), Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).Key("application_ids.#").HasValue("0"), check.That(data.ResourceName).Key("display_names.#").HasValue("0"), check.That(data.ResourceName).Key("object_ids.#").HasValue("0"), check.That(data.ResourceName).Key("service_principals.#").HasValue("0"), @@ -127,7 +112,6 @@ func TestAccServicePrincipalsDataSource_returnAll(t *testing.T) { data.DataSourceTest(t, []acceptance.TestStep{{ Config: ServicePrincipalsDataSource{}.returnAll(), Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).Key("application_ids.#").Exists(), check.That(data.ResourceName).Key("display_names.#").Exists(), check.That(data.ResourceName).Key("object_ids.#").Exists(), check.That(data.ResourceName).Key("service_principals.#").Exists(), @@ -223,19 +207,6 @@ data "azuread_service_principals" "test" { `, ServicePrincipalResource{}.threeServicePrincipalsABC(data), data.RandomInteger) } -func (ServicePrincipalsDataSource) byDeprecatedApplicationIds(data acceptance.TestData) string { - return fmt.Sprintf(` -%[1]s - -data "azuread_service_principals" "test" { - application_ids = [ - azuread_service_principal.testA.application_id, - azuread_service_principal.testB.application_id, - ] -} -`, ServicePrincipalResource{}.threeServicePrincipalsABC(data)) -} - func (ServicePrincipalsDataSource) noNames() string { return ` data "azuread_service_principals" "test" { From b98dda9b9ef40099293c49fa13b3358e9a407229 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 25 Sep 2024 22:44:31 +0100 Subject: [PATCH 2/2] Deprecate all instances of `end_date_relative` property --- .../services/applications/application_certificate_resource.go | 1 + internal/services/applications/application_password_resource.go | 1 + .../serviceprincipals/service_principal_certificate_resource.go | 1 + .../serviceprincipals/service_principal_password_resource.go | 1 + 4 files changed, 4 insertions(+) diff --git a/internal/services/applications/application_certificate_resource.go b/internal/services/applications/application_certificate_resource.go index 450a96eed1..6f8dfbe3de 100644 --- a/internal/services/applications/application_certificate_resource.go +++ b/internal/services/applications/application_certificate_resource.go @@ -97,6 +97,7 @@ func applicationCertificateResource() *pluginsdk.Resource { ForceNew: true, ConflictsWith: []string{"end_date"}, ValidateFunc: validation.StringIsNotEmpty, + Deprecated: "The `end_date_relative` property is deprecated and will be removed in a future version of the AzureAD provider. Please instead use the Terraform `timeadd()` function to calculate a value for the `end_date` property.", }, "type": { diff --git a/internal/services/applications/application_password_resource.go b/internal/services/applications/application_password_resource.go index 15b6bef062..6d7dad7007 100644 --- a/internal/services/applications/application_password_resource.go +++ b/internal/services/applications/application_password_resource.go @@ -90,6 +90,7 @@ func applicationPasswordResource() *pluginsdk.Resource { ForceNew: true, ConflictsWith: []string{"end_date"}, ValidateFunc: validation.StringIsNotEmpty, + Deprecated: "The `end_date_relative` property is deprecated and will be removed in a future version of the AzureAD provider. Please instead use the Terraform `timeadd()` function to calculate a value for the `end_date` property.", }, "rotate_when_changed": { diff --git a/internal/services/serviceprincipals/service_principal_certificate_resource.go b/internal/services/serviceprincipals/service_principal_certificate_resource.go index 1dd2d806ac..d417d9b243 100644 --- a/internal/services/serviceprincipals/service_principal_certificate_resource.go +++ b/internal/services/serviceprincipals/service_principal_certificate_resource.go @@ -97,6 +97,7 @@ func servicePrincipalCertificateResource() *pluginsdk.Resource { ForceNew: true, ConflictsWith: []string{"end_date"}, ValidateFunc: validation.StringIsNotEmpty, + Deprecated: "The `end_date_relative` property is deprecated and will be removed in a future version of the AzureAD provider. Please instead use the Terraform `timeadd()` function to calculate a value for the `end_date` property.", }, "type": { diff --git a/internal/services/serviceprincipals/service_principal_password_resource.go b/internal/services/serviceprincipals/service_principal_password_resource.go index 3e9f82d9cd..a1206a149f 100644 --- a/internal/services/serviceprincipals/service_principal_password_resource.go +++ b/internal/services/serviceprincipals/service_principal_password_resource.go @@ -88,6 +88,7 @@ func servicePrincipalPasswordResource() *pluginsdk.Resource { ForceNew: true, ConflictsWith: []string{"end_date"}, ValidateFunc: validation.StringIsNotEmpty, + Deprecated: "The `end_date_relative` property is deprecated and will be removed in a future version of the AzureAD provider. Please instead use the Terraform `timeadd()` function to calculate a value for the `end_date` property.", }, "rotate_when_changed": {