From 28dbbde2a5e2113cac1121ab31eab72356e14000 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Oct 2023 02:21:42 +0100 Subject: [PATCH 01/46] dependencies: updating to v0.64.0 of github.com/manicminer/hamilton --- go.mod | 2 +- go.sum | 4 +- .../hamilton/msgraph/applications.go | 44 +++++++++++++++++++ .../msgraph/authentication_strength_policy.go | 36 +++++++++++++++ .../manicminer/hamilton/msgraph/models.go | 16 ++++--- .../manicminer/hamilton/msgraph/valuetypes.go | 5 +++ vendor/modules.txt | 2 +- 7 files changed, 100 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index aea2767d2b..cb12a0f37a 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 github.com/hashicorp/terraform-plugin-testing v1.5.1 - github.com/manicminer/hamilton v0.63.0 + github.com/manicminer/hamilton v0.64.0 golang.org/x/text v0.13.0 ) diff --git a/go.sum b/go.sum index 95f4fd5c24..3f9300384e 100644 --- a/go.sum +++ b/go.sum @@ -218,8 +218,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/manicminer/hamilton v0.63.0 h1:Pxh+TvuRhGsKl29v3dnzAoNJYUwqn6SNp/TGddg3g7E= -github.com/manicminer/hamilton v0.63.0/go.mod h1:va/X2sztcgQ5+BSxc2eU3FTHYIyxLnHvB4LudlPUZdE= +github.com/manicminer/hamilton v0.64.0 h1:m62sFHwhyhjd0BpIU7AESZPjTeEWaF1WKLKjXuV/+Ag= +github.com/manicminer/hamilton v0.64.0/go.mod h1:va/X2sztcgQ5+BSxc2eU3FTHYIyxLnHvB4LudlPUZdE= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= diff --git a/vendor/github.com/manicminer/hamilton/msgraph/applications.go b/vendor/github.com/manicminer/hamilton/msgraph/applications.go index ec8dd9544f..598a6716c0 100644 --- a/vendor/github.com/manicminer/hamilton/msgraph/applications.go +++ b/vendor/github.com/manicminer/hamilton/msgraph/applications.go @@ -275,6 +275,50 @@ func (c *ApplicationsClient) RestoreDeleted(ctx context.Context, id string) (*Ap return &restoredApplication, status, nil } +// SetFallbackPublicClient amends the manifest of an existing Application. +func (c *ApplicationsClient) SetFallbackPublicClient(ctx context.Context, id string, fallbackPublicClient *bool) (int, error) { + var status int + + application := struct { + DirectoryObject + IsFallbackPublicClient *bool `json:"isFallbackPublicClient"` + }{ + DirectoryObject: DirectoryObject{ + Id: &id, + }, + IsFallbackPublicClient: fallbackPublicClient, + } + + body, err := json.Marshal(application) + if err != nil { + return status, fmt.Errorf("json.Marshal(): %v", err) + } + + checkApplicationConsistency := func(resp *http.Response, o *odata.OData) bool { + if resp == nil { + return false + } + if resp.StatusCode == http.StatusNotFound { + return true + } + return false + } + + _, status, _, err = c.BaseClient.Patch(ctx, PatchHttpRequestInput{ + Body: body, + ConsistencyFailureFunc: checkApplicationConsistency, + ValidStatusCodes: []int{http.StatusNoContent}, + Uri: Uri{ + Entity: fmt.Sprintf("/applications/%s", *application.ID()), + }, + }) + if err != nil { + return status, fmt.Errorf("ApplicationsClient.BaseClient.Patch(): %v", err) + } + + return status, nil +} + // AddPassword appends a new password credential to an Application. func (c *ApplicationsClient) AddPassword(ctx context.Context, applicationId string, passwordCredential PasswordCredential) (*PasswordCredential, int, error) { var status int diff --git a/vendor/github.com/manicminer/hamilton/msgraph/authentication_strength_policy.go b/vendor/github.com/manicminer/hamilton/msgraph/authentication_strength_policy.go index 25efbe5e89..1cf18468e7 100644 --- a/vendor/github.com/manicminer/hamilton/msgraph/authentication_strength_policy.go +++ b/vendor/github.com/manicminer/hamilton/msgraph/authentication_strength_policy.go @@ -141,6 +141,42 @@ func (c *AuthenticationStrengthPoliciesClient) Update(ctx context.Context, Authe return status, nil } +// Update amends an existing AuthenticationStrengthPolicy's allowed combinations +func (c *AuthenticationStrengthPoliciesClient) UpdateAllowedCombinations(ctx context.Context, policy AuthenticationStrengthPolicy) (int, error) { + var status int + + if policy.ID == nil { + return status, errors.New("cannot update AuthenticationStrengthPolicy with nil ID") + } + + if policy.AllowedCombinations == nil { + return status, errors.New("cannot update AuthenticationStrengthPolicy with nil AllowedCombinations") + } + + allowedCombinations := AuthenticationStrengthPolicy{ + AllowedCombinations: policy.AllowedCombinations, + } + + body, err := json.Marshal(allowedCombinations) + if err != nil { + return status, fmt.Errorf("json.Marshal(): %v", err) + } + + _, status, _, err = c.BaseClient.Post(ctx, PostHttpRequestInput{ + Body: body, + ConsistencyFailureFunc: RetryOn404ConsistencyFailureFunc, + ValidStatusCodes: []int{http.StatusOK}, + Uri: Uri{ + Entity: fmt.Sprintf("/policies/authenticationStrengthPolicies/%s/updateAllowedCombinations", *policy.ID), + }, + }) + if err != nil { + return status, fmt.Errorf("AuthenticationStrengthPoliciesClient.BaseClient.Post(): %v", err) + } + + return status, nil +} + // Delete removes a AuthenticationStrengthPolicy. func (c *AuthenticationStrengthPoliciesClient) Delete(ctx context.Context, id string) (int, error) { _, status, _, err := c.BaseClient.Delete(ctx, DeleteHttpRequestInput{ diff --git a/vendor/github.com/manicminer/hamilton/msgraph/models.go b/vendor/github.com/manicminer/hamilton/msgraph/models.go index 21253ff878..8bffe987b8 100644 --- a/vendor/github.com/manicminer/hamilton/msgraph/models.go +++ b/vendor/github.com/manicminer/hamilton/msgraph/models.go @@ -1140,11 +1140,11 @@ type ImplicitGrantSettings struct { } type InformationalUrl struct { - LogoUrl *string `json:"logoUrl,omitempty"` - MarketingUrl *string `json:"marketingUrl"` - PrivacyStatementUrl *string `json:"privacyStatementUrl"` - SupportUrl *string `json:"supportUrl"` - TermsOfServiceUrl *string `json:"termsOfServiceUrl"` + LogoUrl *StringNullWhenEmpty `json:"logoUrl,omitempty"` + MarketingUrl *StringNullWhenEmpty `json:"marketingUrl"` + PrivacyStatementUrl *StringNullWhenEmpty `json:"privacyStatementUrl"` + SupportUrl *StringNullWhenEmpty `json:"supportUrl"` + TermsOfServiceUrl *StringNullWhenEmpty `json:"termsOfServiceUrl"` } // Invitation describes a Invitation object. @@ -1439,6 +1439,7 @@ type ServicePrincipal struct { AppDisplayName *string `json:"appDisplayName,omitempty"` AppId *string `json:"appId,omitempty"` ApplicationTemplateId *string `json:"applicationTemplateId,omitempty"` + AppMetadata *ServicePrincipalAppMetadata `json:"appMetadata,omitempty"` AppOwnerOrganizationId *string `json:"appOwnerOrganizationId,omitempty"` AppRoleAssignmentRequired *bool `json:"appRoleAssignmentRequired,omitempty"` AppRoles *[]AppRole `json:"appRoles,omitempty"` @@ -1481,6 +1482,11 @@ func (s *ServicePrincipal) UnmarshalJSON(data []byte) error { return nil } +type ServicePrincipalAppMetadata struct { + Version *int `json:"version,omitempty"` + Data *[]KeyValueObject `json:"data,omitempty"` +} + type SynchronizationSchedule struct { Expiration *time.Time `json:"expiration,omitempty"` Interval *string `json:"interval,omitempty"` diff --git a/vendor/github.com/manicminer/hamilton/msgraph/valuetypes.go b/vendor/github.com/manicminer/hamilton/msgraph/valuetypes.go index cfd8ce229d..eca99667c1 100644 --- a/vendor/github.com/manicminer/hamilton/msgraph/valuetypes.go +++ b/vendor/github.com/manicminer/hamilton/msgraph/valuetypes.go @@ -22,6 +22,11 @@ func (s StringNullWhenEmpty) MarshalJSON() ([]byte, error) { return json.Marshal(string(s)) } +type KeyValueObject struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + type AccessPackageCatalogState = string const ( diff --git a/vendor/modules.txt b/vendor/modules.txt index 2d8062c180..f5216b08bb 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -209,7 +209,7 @@ github.com/hashicorp/terraform-svchost # github.com/hashicorp/yamux v0.1.1 ## explicit; go 1.15 github.com/hashicorp/yamux -# github.com/manicminer/hamilton v0.63.0 +# github.com/manicminer/hamilton v0.64.0 ## explicit; go 1.16 github.com/manicminer/hamilton/errors github.com/manicminer/hamilton/internal/utils From d2a19161b4be4045345feaaa4b32756263280efc Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Oct 2023 02:22:13 +0100 Subject: [PATCH 02/46] Deprecate some utils functions --- internal/tf/strings.go | 8 ++++++++ internal/utils/pointer.go | 4 ++++ internal/utils/slices.go | 12 ------------ 3 files changed, 12 insertions(+), 12 deletions(-) create mode 100644 internal/tf/strings.go diff --git a/internal/tf/strings.go b/internal/tf/strings.go new file mode 100644 index 0000000000..66f7ff739e --- /dev/null +++ b/internal/tf/strings.go @@ -0,0 +1,8 @@ +package tf + +import "github.com/manicminer/hamilton/msgraph" + +func NullableString(input string) *msgraph.StringNullWhenEmpty { + output := msgraph.StringNullWhenEmpty(input) + return &output +} diff --git a/internal/utils/pointer.go b/internal/utils/pointer.go index 8c630251f0..69d9062db1 100644 --- a/internal/utils/pointer.go +++ b/internal/utils/pointer.go @@ -5,18 +5,22 @@ package utils import "github.com/manicminer/hamilton/msgraph" +// Deprecated: Please use pointer.To() from hashicorp/go-azure-helpers func Bool(input bool) *bool { return &input } +// Deprecated: Please use pointer.To() from hashicorp/go-azure-helpers func Int32(input int32) *int32 { return &input } +// Deprecated: Please use pointer.To() from hashicorp/go-azure-helpers func String(input string) *string { return &input } +// Deprecated: Please use tf.NullableString() instead func NullableString(input string) *msgraph.StringNullWhenEmpty { output := msgraph.StringNullWhenEmpty(input) return &output diff --git a/internal/utils/slices.go b/internal/utils/slices.go index 4131f149fa..a25f968f7f 100644 --- a/internal/utils/slices.go +++ b/internal/utils/slices.go @@ -3,8 +3,6 @@ package utils -import "strings" - // Difference returns the elements in `a` that aren't in `b`. func Difference(a, b []string) []string { mb := make(map[string]struct{}, len(b)) @@ -19,13 +17,3 @@ func Difference(a, b []string) []string { } return diff } - -// EnsureStringInSlice ensures the given string is contained in a slice -func EnsureStringInSlice(sl []string, in string) []string { - for _, s := range sl { - if strings.EqualFold(s, in) { - return sl - } - } - return append(sl, in) -} From 5d14083cccc02919796d447609d018fc80db917a Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Oct 2023 02:23:04 +0100 Subject: [PATCH 03/46] New Resource: `azuread_application_registration` --- internal/provider/services.go | 1 + .../application_certificate_resource.go | 6 +- .../application_certificate_resource_test.go | 2 +- .../applications/application_data_source.go | 2 +- ..._federated_identity_credential_resource.go | 8 +- ...rated_identity_credential_resource_test.go | 2 +- .../application_password_resource.go | 6 +- .../application_password_resource_test.go | 2 +- .../application_pre_authorized_resource.go | 8 +- ...pplication_pre_authorized_resource_test.go | 2 +- .../application_registration_resource.go | 408 ++++++++++++++++++ .../application_registration_resource_test.go | 139 ++++++ .../applications/application_resource.go | 26 +- .../applications/application_resource_test.go | 2 +- .../services/applications/client/client.go | 7 +- .../applications/parse/application.go | 69 +++ .../services/applications/registration.go | 17 +- 17 files changed, 672 insertions(+), 35 deletions(-) create mode 100644 internal/services/applications/application_registration_resource.go create mode 100644 internal/services/applications/application_registration_resource_test.go create mode 100644 internal/services/applications/parse/application.go diff --git a/internal/provider/services.go b/internal/provider/services.go index 3f09b8b6ec..0a70df2808 100644 --- a/internal/provider/services.go +++ b/internal/provider/services.go @@ -23,6 +23,7 @@ import ( func SupportedTypedServices() []sdk.TypedServiceRegistration { return []sdk.TypedServiceRegistration{ + applications.Registration{}, directoryroles.Registration{}, domains.Registration{}, serviceprincipals.Registration{}, diff --git a/internal/services/applications/application_certificate_resource.go b/internal/services/applications/application_certificate_resource.go index fe1a4d9fe6..458558cd72 100644 --- a/internal/services/applications/application_certificate_resource.go +++ b/internal/services/applications/application_certificate_resource.go @@ -123,7 +123,7 @@ func applicationCertificateResource() *pluginsdk.Resource { } func applicationCertificateResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta objectId := d.Get("application_object_id").(string) credential, err := helpers.KeyCredentialForResource(d) @@ -211,7 +211,7 @@ func applicationCertificateResourceCreate(ctx context.Context, d *pluginsdk.Reso } func applicationCertificateResourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta id, err := parse.CertificateID(d.Id()) if err != nil { @@ -255,7 +255,7 @@ func applicationCertificateResourceRead(ctx context.Context, d *pluginsdk.Resour } func applicationCertificateResourceDelete(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta id, err := parse.CertificateID(d.Id()) if err != nil { diff --git a/internal/services/applications/application_certificate_resource_test.go b/internal/services/applications/application_certificate_resource_test.go index d6716cc555..5fec1d8e8c 100644 --- a/internal/services/applications/application_certificate_resource_test.go +++ b/internal/services/applications/application_certificate_resource_test.go @@ -171,7 +171,7 @@ func TestAccApplicationCertificate_requiresImport(t *testing.T) { } func (ApplicationCertificateResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { - client := clients.Applications.ApplicationsClient + client := clients.Applications.ApplicationsClientBeta client.BaseClient.DisableRetries = true defer func() { client.BaseClient.DisableRetries = false }() diff --git a/internal/services/applications/application_data_source.go b/internal/services/applications/application_data_source.go index 603a9d43e1..e649aec00f 100644 --- a/internal/services/applications/application_data_source.go +++ b/internal/services/applications/application_data_source.go @@ -495,7 +495,7 @@ func applicationDataSource() *pluginsdk.Resource { } func applicationDataSourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta client.BaseClient.DisableRetries = true defer func() { client.BaseClient.DisableRetries = false }() diff --git a/internal/services/applications/application_federated_identity_credential_resource.go b/internal/services/applications/application_federated_identity_credential_resource.go index 9efb1ca6f9..4e6c109c64 100644 --- a/internal/services/applications/application_federated_identity_credential_resource.go +++ b/internal/services/applications/application_federated_identity_credential_resource.go @@ -98,7 +98,7 @@ func applicationFederatedIdentityCredentialResource() *pluginsdk.Resource { } func applicationFederatedIdentityCredentialResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { //nolint - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta objectId := d.Get("application_object_id").(string) tf.LockByName(applicationResourceName, objectId) @@ -174,7 +174,7 @@ func applicationFederatedIdentityCredentialResourceCreate(ctx context.Context, d } func applicationFederatedIdentityCredentialResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { //nolint - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta id, err := parse.FederatedIdentityCredentialID(d.Id()) if err != nil { @@ -201,7 +201,7 @@ func applicationFederatedIdentityCredentialResourceUpdate(ctx context.Context, d } func applicationFederatedIdentityCredentialResourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { //nolint - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta id, err := parse.FederatedIdentityCredentialID(d.Id()) if err != nil { @@ -231,7 +231,7 @@ func applicationFederatedIdentityCredentialResourceRead(ctx context.Context, d * } func applicationFederatedIdentityCredentialResourceDelete(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { //nolint - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta id, err := parse.FederatedIdentityCredentialID(d.Id()) if err != nil { diff --git a/internal/services/applications/application_federated_identity_credential_resource_test.go b/internal/services/applications/application_federated_identity_credential_resource_test.go index 090fc3f5e9..faea199851 100644 --- a/internal/services/applications/application_federated_identity_credential_resource_test.go +++ b/internal/services/applications/application_federated_identity_credential_resource_test.go @@ -85,7 +85,7 @@ func TestAccApplicationFederatedIdentityCredential_update(t *testing.T) { } func (r ApplicationFederatedIdentityCredentialResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { - client := clients.Applications.ApplicationsClient + client := clients.Applications.ApplicationsClientBeta client.BaseClient.DisableRetries = true defer func() { client.BaseClient.DisableRetries = false }() diff --git a/internal/services/applications/application_password_resource.go b/internal/services/applications/application_password_resource.go index 260075f531..1ed7a2924b 100644 --- a/internal/services/applications/application_password_resource.go +++ b/internal/services/applications/application_password_resource.go @@ -117,7 +117,7 @@ func applicationPasswordResource() *pluginsdk.Resource { } func applicationPasswordResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { //nolint - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta objectId := d.Get("application_object_id").(string) credential, err := helpers.PasswordCredentialForResource(d) @@ -201,7 +201,7 @@ func applicationPasswordResourceCreate(ctx context.Context, d *pluginsdk.Resourc } func applicationPasswordResourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { //nolint - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta id, err := parse.PasswordID(d.Id()) if err != nil { @@ -255,7 +255,7 @@ func applicationPasswordResourceRead(ctx context.Context, d *pluginsdk.ResourceD } func applicationPasswordResourceDelete(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { //nolint - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta id, err := parse.PasswordID(d.Id()) if err != nil { diff --git a/internal/services/applications/application_password_resource_test.go b/internal/services/applications/application_password_resource_test.go index 288bd59ed6..72256ddc3a 100644 --- a/internal/services/applications/application_password_resource_test.go +++ b/internal/services/applications/application_password_resource_test.go @@ -79,7 +79,7 @@ func TestAccApplicationPassword_relativeEndDate(t *testing.T) { } func (r ApplicationPasswordResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { - client := clients.Applications.ApplicationsClient + client := clients.Applications.ApplicationsClientBeta client.BaseClient.DisableRetries = true defer func() { client.BaseClient.DisableRetries = false }() diff --git a/internal/services/applications/application_pre_authorized_resource.go b/internal/services/applications/application_pre_authorized_resource.go index 1ec5d7968c..f0d9bff91c 100644 --- a/internal/services/applications/application_pre_authorized_resource.go +++ b/internal/services/applications/application_pre_authorized_resource.go @@ -72,7 +72,7 @@ func applicationPreAuthorizedResource() *pluginsdk.Resource { } func applicationPreAuthorizedResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta id := parse.NewApplicationPreAuthorizedID(d.Get("application_object_id").(string), d.Get("authorized_app_id").(string)) tf.LockByName(applicationResourceName, id.ObjectId) @@ -123,7 +123,7 @@ func applicationPreAuthorizedResourceCreate(ctx context.Context, d *pluginsdk.Re } func applicationPreAuthorizedResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta id, err := parse.ApplicationPreAuthorizedID(d.Id()) if err != nil { return tf.ErrorDiagPathF(err, "id", "Parsing pre-authorized application ID %q", d.Id()) @@ -176,7 +176,7 @@ func applicationPreAuthorizedResourceUpdate(ctx context.Context, d *pluginsdk.Re } func applicationPreAuthorizedResourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta id, err := parse.ApplicationPreAuthorizedID(d.Id()) if err != nil { return tf.ErrorDiagPathF(err, "id", "Parsing pre-authorized application ID %q", d.Id()) @@ -219,7 +219,7 @@ func applicationPreAuthorizedResourceRead(ctx context.Context, d *pluginsdk.Reso } func applicationPreAuthorizedResourceDelete(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta id, err := parse.ApplicationPreAuthorizedID(d.Id()) if err != nil { return tf.ErrorDiagPathF(err, "id", "Parsing pre-authorized application ID %q", d.Id()) diff --git a/internal/services/applications/application_pre_authorized_resource_test.go b/internal/services/applications/application_pre_authorized_resource_test.go index 8ed54f229d..46b00848b1 100644 --- a/internal/services/applications/application_pre_authorized_resource_test.go +++ b/internal/services/applications/application_pre_authorized_resource_test.go @@ -54,7 +54,7 @@ func TestAccApplicationPreAuthorized_requiresImport(t *testing.T) { } func (ApplicationPreAuthorizedResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { - client := clients.Applications.ApplicationsClient + client := clients.Applications.ApplicationsClientBeta client.BaseClient.DisableRetries = true defer func() { client.BaseClient.DisableRetries = false }() diff --git a/internal/services/applications/application_registration_resource.go b/internal/services/applications/application_registration_resource.go new file mode 100644 index 0000000000..69397bb79f --- /dev/null +++ b/internal/services/applications/application_registration_resource.go @@ -0,0 +1,408 @@ +package applications + +import ( + "context" + "fmt" + "net/http" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/terraform-provider-azuread/internal/helpers" + "github.com/hashicorp/terraform-provider-azuread/internal/sdk" + "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" + "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/hashicorp/terraform-provider-azuread/internal/utils" + "github.com/manicminer/hamilton/msgraph" +) + +type ApplicationRegistrationModel struct { + ClientId string `tfschema:"client_id"` + Description string `tfschema:"description"` + DisabledByMicrosoft string `tfschema:"disabled_by_microsoft"` + DisplayName string `tfschema:"display_name"` + MarketingUrl string `tfschema:"marketing_url"` + Notes string `tfschema:"notes"` + PrivacyStatementUrl string `tfschema:"privacy_statement_url"` + PublisherDomain string `tfschema:"publisher_domain"` + RequestedAccessTokenVersion int `tfschema:"requested_access_token_version"` + ServiceManagementReference string `tfschema:"service_management_reference"` + SignInAudience string `tfschema:"sign_in_audience"` + SupportUrl string `tfschema:"support_url"` + TermsOfServiceUrl string `tfschema:"terms_of_service_url"` +} + +type ApplicationRegistrationResource struct{} + +func (r ApplicationRegistrationResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return parse.ValidateApplicationID +} + +var _ sdk.ResourceWithUpdate = ApplicationRegistrationResource{} + +func (r ApplicationRegistrationResource) ResourceType() string { + return "azuread_application_registration" +} + +func (r ApplicationRegistrationResource) ModelObject() interface{} { + return &ApplicationRegistrationModel{} +} + +func (r ApplicationRegistrationResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "display_name": { + Description: "The display name for the application", + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "description": { + Description: "Description of the application as shown to end users", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 1024), + }, + + "marketing_url": { + Description: "URL of the marketing page for the application", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "notes": { + Description: "User-specified notes relevant for the management of the application", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "privacy_statement_url": { + Description: "URL of the privacy statement for the application", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "requested_access_token_version": { + Description: "The access token version expected by this resource", + Type: pluginsdk.TypeInt, + Optional: true, + Default: 1, + ValidateFunc: func(i interface{}, key string) (warnings []string, errors []error) { + v, ok := i.(int) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be an integer", key)) + return + } + if v < 1 || v > 2 { + errors = append(errors, fmt.Errorf("value for %q must be one of: 1, 2", key)) + } + return + }, + }, + + "service_management_reference": { + Description: "References application or contact information from a service or asset management database", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "sign_in_audience": { + Description: "The Microsoft account types that are supported for the current application", + Type: pluginsdk.TypeString, + Optional: true, + Default: msgraph.SignInAudienceAzureADMyOrg, + ValidateFunc: validation.StringInSlice([]string{ + msgraph.SignInAudienceAzureADMyOrg, + msgraph.SignInAudienceAzureADMultipleOrgs, + msgraph.SignInAudienceAzureADandPersonalMicrosoftAccount, + msgraph.SignInAudiencePersonalMicrosoftAccount, + }, false), + }, + + "support_url": { + Description: "URL of the support page for the application", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "terms_of_service_url": { + Description: "URL of the terms of service statement for the application", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + } +} + +func (r ApplicationRegistrationResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "client_id": { + Description: "The Client ID (also called Application ID)", + Type: pluginsdk.TypeString, + Computed: true, + }, + + "disabled_by_microsoft": { + Description: "If the application has been disabled by Microsoft, this shows the status or reason", + Type: pluginsdk.TypeString, + Computed: true, + }, + + "publisher_domain": { + Description: "The verified publisher domain for the application", + Type: pluginsdk.TypeString, + Computed: true, + }, + } +} + +func (r ApplicationRegistrationResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + var model ApplicationRegistrationModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + properties := msgraph.Application{ + DisplayName: &model.DisplayName, + Description: tf.NullableString(model.Description), + Notes: tf.NullableString(model.Notes), + ServiceManagementReference: tf.NullableString(model.ServiceManagementReference), + SignInAudience: &model.SignInAudience, + + Api: &msgraph.ApplicationApi{ + RequestedAccessTokenVersion: pointer.To(int32(model.RequestedAccessTokenVersion)), + }, + + Info: &msgraph.InformationalUrl{ + MarketingUrl: tf.NullableString(model.MarketingUrl), + PrivacyStatementUrl: tf.NullableString(model.PrivacyStatementUrl), + SupportUrl: tf.NullableString(model.SupportUrl), + TermsOfServiceUrl: tf.NullableString(model.TermsOfServiceUrl), + }, + } + + result, _, err := client.Create(ctx, properties) + if err != nil { + return fmt.Errorf("creating %s: %+v", parse.ApplicationId{}, err) + } + + if pointer.From(result.ID()) == "" { + return fmt.Errorf("creating %s: object ID returned for application is nil/empty", parse.ApplicationId{}) + } + + id := parse.NewApplicationID(*result.ID()) + metadata.SetID(id) + + // Attempt to patch the newly created application and set the display name, which will tell us whether it exists yet, then set it back to the desired value. + // The SDK handles retries for us here in the event of 404, 429 or 5xx, then returns after giving up. + uuid, err := uuid.GenerateUUID() + if err != nil { + return fmt.Errorf("failed to generate a UUID: %v", err) + } + tempDisplayName := fmt.Sprintf("TERRAFORM_UPDATE_%s", uuid) + for _, displayNameToSet := range []string{tempDisplayName, model.DisplayName} { + // Consistency-related retries are handled by the SDK + status, err := client.Update(ctx, msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &id.ApplicationId, + }, + DisplayName: utils.String(displayNameToSet), + }) + if err != nil { + if status == http.StatusNotFound { + return fmt.Errorf("timed out whilst waiting for new %s to be replicated in Azure AD", id) + } + return fmt.Errorf("failed to patch %s after creating: %+v", id, err) + } + } + + return nil + }, + } +} + +func (r ApplicationRegistrationResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseApplicationID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", id) + } + + state := ApplicationRegistrationModel{ + ClientId: pointer.From(result.AppId), + Description: string(pointer.From(result.Description)), + DisplayName: pointer.From(result.DisplayName), + Notes: string(pointer.From(result.Notes)), + PublisherDomain: pointer.From(result.PublisherDomain), + ServiceManagementReference: string(pointer.From(result.ServiceManagementReference)), + SignInAudience: pointer.From(result.SignInAudience), + } + + if api := result.Api; api != nil { + state.RequestedAccessTokenVersion = int(pointer.From(api.RequestedAccessTokenVersion)) + } + + if info := result.Info; info != nil { + state.MarketingUrl = string(pointer.From(info.MarketingUrl)) + state.PrivacyStatementUrl = string(pointer.From(info.PrivacyStatementUrl)) + state.SupportUrl = string(pointer.From(info.SupportUrl)) + state.TermsOfServiceUrl = string(pointer.From(info.TermsOfServiceUrl)) + } + + if result.DisabledByMicrosoftStatus != nil { + state.DisabledByMicrosoft = fmt.Sprintf("%v", result.DisabledByMicrosoftStatus) + } + + return metadata.Encode(&state) + }, + } +} + +func (r ApplicationRegistrationResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + rd := metadata.ResourceData + + id, err := parse.ParseApplicationID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var model ApplicationRegistrationModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &id.ApplicationId, + }, + } + + if rd.HasChange("display_name") { + properties.DisplayName = &model.DisplayName + } + + if rd.HasChange("description") { + properties.Description = tf.NullableString(model.Description) + } + + if rd.HasChange("notes") { + properties.Notes = tf.NullableString(model.Notes) + } + + if rd.HasChange("requested_access_token_version") { + properties.Api = &msgraph.ApplicationApi{ + RequestedAccessTokenVersion: pointer.To(int32(model.RequestedAccessTokenVersion)), + } + } + + if rd.HasChange("service_management_reference") { + properties.ServiceManagementReference = tf.NullableString(model.ServiceManagementReference) + } + + if rd.HasChange("sign_in_audience") { + properties.SignInAudience = &model.SignInAudience + } + + if rd.HasChange("marketing_url") || rd.HasChange("privacy_statement_url") || rd.HasChange("support_url") || rd.HasChange("terms_of_service_url") { + properties.Info = &msgraph.InformationalUrl{} + + if rd.HasChange("marketing_url") { + properties.Info.MarketingUrl = tf.NullableString(model.MarketingUrl) + } + + if rd.HasChange("privacy_statement_url") { + properties.Info.PrivacyStatementUrl = tf.NullableString(model.PrivacyStatementUrl) + } + + if rd.HasChange("support_url") { + properties.Info.SupportUrl = tf.NullableString(model.SupportUrl) + } + + if rd.HasChange("terms_of_service_url") { + properties.Info.TermsOfServiceUrl = tf.NullableString(model.TermsOfServiceUrl) + } + } + + _, err = client.Update(ctx, properties) + if err != nil { + return fmt.Errorf("updating %s: %+v", id, err) + } + + return nil + }, + } +} + +func (r ApplicationRegistrationResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseApplicationID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + if _, err := client.Delete(ctx, id.ApplicationId); err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + + // Wait for application object to be deleted + 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, id.ApplicationId, odata.Query{}); err != nil { + if status == http.StatusNotFound { + return utils.Bool(false), nil + } + return nil, err + } + return utils.Bool(true), nil + }); err != nil { + return fmt.Errorf("waiting for deletion of %s: %q", id, err) + } + + return nil + }, + } +} diff --git a/internal/services/applications/application_registration_resource_test.go b/internal/services/applications/application_registration_resource_test.go new file mode 100644 index 0000000000..8861d835d1 --- /dev/null +++ b/internal/services/applications/application_registration_resource_test.go @@ -0,0 +1,139 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications_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/terraform-plugin-testing/terraform" + "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/services/applications/parse" +) + +type ApplicationRegistrationResource struct{} + +func TestAccApplicationRegistration_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_registration", "test") + r := ApplicationRegistrationResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("client_id").Exists(), + check.That(data.ResourceName).Key("display_name").HasValue(fmt.Sprintf("acctest-AppRegistration-%d", data.RandomInteger)), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationRegistration_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_registration", "test") + r := ApplicationRegistrationResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("client_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationRegistration_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_registration", "test") + r := ApplicationRegistrationResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("client_id").Exists(), + ), + }, + data.ImportStep(), + { + Config: r.complete(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("client_id").Exists(), + ), + }, + data.ImportStep(), + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("client_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func (r ApplicationRegistrationResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { + client := clients.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseApplicationID(state.ID) + if err != nil { + return nil, err + } + + app, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return pointer.To(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + + return pointer.To(app.ID() != nil && *app.ID() == id.ApplicationId), nil +} + +func (ApplicationRegistrationResource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} +`, data.RandomInteger) +} + +func (ApplicationRegistrationResource) complete(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-complete-%[1]d" + sign_in_audience = "AzureADandPersonalMicrosoftAccount" + + requested_access_token_version = 2 + + description = "Acceptance testing application" + notes = "Testing application" + service_management_reference = "app-for-testing" + + marketing_url = "https://hashitown-%[1]d.com/" + privacy_statement_url = "https://hashitown-%[1]d.com/privacy" + support_url = "https://support.hashitown-%[1]d.com/" + terms_of_service_url = "https://hashitown-%[1]d.com/terms" +} +`, data.RandomInteger) +} diff --git a/internal/services/applications/application_resource.go b/internal/services/applications/application_resource.go index 4f153e7018..bd2118352f 100644 --- a/internal/services/applications/application_resource.go +++ b/internal/services/applications/application_resource.go @@ -641,7 +641,7 @@ func applicationResource() *pluginsdk.Resource { } func applicationResourceCustomizeDiff(ctx context.Context, diff *pluginsdk.ResourceDiff, meta interface{}) error { - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta oldDisplayName, newDisplayName := diff.GetChange("display_name") if diff.Get("prevent_duplicate_names").(bool) && pluginsdk.ValueIsNotEmptyOrUnknown(newDisplayName) && @@ -896,7 +896,7 @@ func applicationDiffSuppress(k, old, new string, d *pluginsdk.ResourceData) bool } func applicationResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta appTemplatesClient := meta.(*clients.Client).Applications.ApplicationTemplatesClient directoryObjectsClient := meta.(*clients.Client).Applications.DirectoryObjectsClient callerId := meta.(*clients.Client).ObjectID @@ -980,10 +980,10 @@ func applicationResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, m GroupMembershipClaims: expandApplicationGroupMembershipClaims(d.Get("group_membership_claims").(*pluginsdk.Set).List()), IdentifierUris: tf.ExpandStringSlicePtr(d.Get("identifier_uris").(*pluginsdk.Set).List()), Info: &msgraph.InformationalUrl{ - MarketingUrl: utils.String(d.Get("marketing_url").(string)), - PrivacyStatementUrl: utils.String(d.Get("privacy_statement_url").(string)), - SupportUrl: utils.String(d.Get("support_url").(string)), - TermsOfServiceUrl: utils.String(d.Get("terms_of_service_url").(string)), + MarketingUrl: utils.NullableString(d.Get("marketing_url").(string)), + PrivacyStatementUrl: utils.NullableString(d.Get("privacy_statement_url").(string)), + SupportUrl: utils.NullableString(d.Get("support_url").(string)), + TermsOfServiceUrl: utils.NullableString(d.Get("terms_of_service_url").(string)), }, IsDeviceOnlyAuthSupported: utils.Bool(d.Get("device_only_auth_enabled").(bool)), IsFallbackPublicClient: utils.Bool(d.Get("fallback_public_client_enabled").(bool)), @@ -1123,7 +1123,7 @@ func applicationResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, m } func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta tenantId := meta.(*clients.Client).TenantID applicationId := d.Id() displayName := d.Get("display_name").(string) @@ -1175,10 +1175,10 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m GroupMembershipClaims: expandApplicationGroupMembershipClaims(d.Get("group_membership_claims").(*pluginsdk.Set).List()), IdentifierUris: tf.ExpandStringSlicePtr(d.Get("identifier_uris").(*pluginsdk.Set).List()), Info: &msgraph.InformationalUrl{ - MarketingUrl: utils.String(d.Get("marketing_url").(string)), - PrivacyStatementUrl: utils.String(d.Get("privacy_statement_url").(string)), - SupportUrl: utils.String(d.Get("support_url").(string)), - TermsOfServiceUrl: utils.String(d.Get("terms_of_service_url").(string)), + MarketingUrl: utils.NullableString(d.Get("marketing_url").(string)), + PrivacyStatementUrl: utils.NullableString(d.Get("privacy_statement_url").(string)), + SupportUrl: utils.NullableString(d.Get("support_url").(string)), + TermsOfServiceUrl: utils.NullableString(d.Get("terms_of_service_url").(string)), }, IsDeviceOnlyAuthSupported: utils.Bool(d.Get("device_only_auth_enabled").(bool)), IsFallbackPublicClient: utils.Bool(d.Get("fallback_public_client_enabled").(bool)), @@ -1252,7 +1252,7 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m } func applicationResourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta app, status, err := client.Get(ctx, d.Id(), odata.Query{}) if err != nil { @@ -1325,7 +1325,7 @@ func applicationResourceRead(ctx context.Context, d *pluginsdk.ResourceData, met } func applicationResourceDelete(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { - client := meta.(*clients.Client).Applications.ApplicationsClient + client := meta.(*clients.Client).Applications.ApplicationsClientBeta appId := d.Id() _, status, err := client.Get(ctx, appId, odata.Query{}) diff --git a/internal/services/applications/application_resource_test.go b/internal/services/applications/application_resource_test.go index 40a15a8aa3..51f24a3bee 100644 --- a/internal/services/applications/application_resource_test.go +++ b/internal/services/applications/application_resource_test.go @@ -587,7 +587,7 @@ func TestAccApplication_logo(t *testing.T) { } func (r ApplicationResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { - client := clients.Applications.ApplicationsClient + client := clients.Applications.ApplicationsClientBeta client.BaseClient.DisableRetries = true defer func() { client.BaseClient.DisableRetries = false }() app, status, err := client.Get(ctx, state.ID, odata.Query{}) diff --git a/internal/services/applications/client/client.go b/internal/services/applications/client/client.go index 925a0b2d21..b6bcdd9a77 100644 --- a/internal/services/applications/client/client.go +++ b/internal/services/applications/client/client.go @@ -10,6 +10,7 @@ import ( type Client struct { ApplicationsClient *msgraph.ApplicationsClient + ApplicationsClientBeta *msgraph.ApplicationsClient ApplicationTemplatesClient *msgraph.ApplicationTemplatesClient DirectoryObjectsClient *msgraph.DirectoryObjectsClient } @@ -18,8 +19,11 @@ func NewClient(o *common.ClientOptions) *Client { applicationsClient := msgraph.NewApplicationsClient() o.ConfigureClient(&applicationsClient.BaseClient) + applicationsClientBeta := msgraph.NewApplicationsClient() + o.ConfigureClient(&applicationsClientBeta.BaseClient) + // See https://github.com/microsoftgraph/msgraph-metadata/issues/273 - applicationsClient.BaseClient.ApiVersion = msgraph.VersionBeta + applicationsClientBeta.BaseClient.ApiVersion = msgraph.VersionBeta applicationTemplatesClient := msgraph.NewApplicationTemplatesClient() o.ConfigureClient(&applicationTemplatesClient.BaseClient) @@ -29,6 +33,7 @@ func NewClient(o *common.ClientOptions) *Client { return &Client{ ApplicationsClient: applicationsClient, + ApplicationsClientBeta: applicationsClientBeta, ApplicationTemplatesClient: applicationTemplatesClient, DirectoryObjectsClient: directoryObjectsClient, } diff --git a/internal/services/applications/parse/application.go b/internal/services/applications/parse/application.go new file mode 100644 index 0000000000..db5033b8c2 --- /dev/null +++ b/internal/services/applications/parse/application.go @@ -0,0 +1,69 @@ +package parse + +import ( + "fmt" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/hashicorp/terraform-provider-azuread/internal/tf/validation" +) + +type ApplicationId struct { + ApplicationId string +} + +func NewApplicationID(input string) ApplicationId { + return ApplicationId{ + ApplicationId: input, + } +} + +// 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 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 B 2 C Directory 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) +} diff --git a/internal/services/applications/registration.go b/internal/services/applications/registration.go index 4fde548c94..56e8e09a37 100644 --- a/internal/services/applications/registration.go +++ b/internal/services/applications/registration.go @@ -3,7 +3,10 @@ package applications -import "github.com/hashicorp/terraform-provider-azuread/internal/tf/pluginsdk" +import ( + "github.com/hashicorp/terraform-provider-azuread/internal/sdk" + "github.com/hashicorp/terraform-provider-azuread/internal/tf/pluginsdk" +) type Registration struct{} @@ -38,3 +41,15 @@ func (r Registration) SupportedResources() map[string]*pluginsdk.Resource { "azuread_application_pre_authorized": applicationPreAuthorizedResource(), } } + +// DataSources returns the typed DataSources supported by this service +func (r Registration) DataSources() []sdk.DataSource { + return []sdk.DataSource{} +} + +// Resources returns the typed Resources supported by this service +func (r Registration) Resources() []sdk.Resource { + return []sdk.Resource{ + ApplicationRegistrationResource{}, + } +} From df0fe7297fa48fb9f225fe7c0149ebb35be5817f Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Oct 2023 04:36:44 +0100 Subject: [PATCH 04/46] New Resource: `azuread_application_permission_scope` --- .../application_permission_scope_resource.go | 401 ++++++++++++++++++ ...lication_permission_scope_resource_test.go | 343 +++++++++++++++ .../applications/application_resource.go | 2 - .../services/applications/applications.go | 2 + .../applications/parse/application.go | 4 +- .../applications/parse/permission_scope.go | 77 ++++ .../services/applications/registration.go | 1 + 7 files changed, 826 insertions(+), 4 deletions(-) create mode 100644 internal/services/applications/application_permission_scope_resource.go create mode 100644 internal/services/applications/application_permission_scope_resource_test.go create mode 100644 internal/services/applications/parse/permission_scope.go diff --git a/internal/services/applications/application_permission_scope_resource.go b/internal/services/applications/application_permission_scope_resource.go new file mode 100644 index 0000000000..8856a2c6a9 --- /dev/null +++ b/internal/services/applications/application_permission_scope_resource.go @@ -0,0 +1,401 @@ +package applications + +import ( + "context" + "fmt" + "net/http" + "strings" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/terraform-provider-azuread/internal/sdk" + "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" + applicationsValidate "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/validate" + "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" +) + +type ApplicationPermissionScopeModel struct { + ApplicationId string `tfschema:"application_id"` + ScopeId string `tfschema:"scope_id"` + AdminConsentDescription string `tfschema:"admin_consent_description"` + AdminConsentDisplayName string `tfschema:"admin_consent_display_name"` + Type string `tfschema:"type"` + UserConsentDescription string `tfschema:"user_consent_description"` + UserConsentDisplayName string `tfschema:"user_consent_display_name"` + Value string `tfschema:"value"` +} + +type ApplicationPermissionScopeResource struct{} + +func (r ApplicationPermissionScopeResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return parse.ValidatePermissionScopeID +} + +var _ sdk.ResourceWithUpdate = ApplicationPermissionScopeResource{} + +func (r ApplicationPermissionScopeResource) ResourceType() string { + return "azuread_application_permission_scope" +} + +func (r ApplicationPermissionScopeResource) ModelObject() interface{} { + return &ApplicationPermissionScopeModel{} +} + +func (r ApplicationPermissionScopeResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "application_id": { + Description: "The resource ID of the application to which this permission scope should be applied", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: parse.ValidateApplicationID, + }, + + "scope_id": { + Description: "The unique identifier of the permission scope", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.IsUUID, + }, + + "admin_consent_description": { + Description: "Delegated permission description that appears in all tenant-wide admin consent experiences, intended to be read by an administrator granting the permission on behalf of all users", + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "admin_consent_display_name": { + Description: "Display name for the delegated permission, intended to be read by an administrator granting the permission on behalf of all users", + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "value": { + Description: "The value that is used for the `scp` claim in OAuth access tokens", + Type: pluginsdk.TypeString, + Required: true, + ValidateDiagFunc: applicationsValidate.RoleScopeClaimValue, + }, + + "type": { + Description: "Whether this delegated permission should be considered safe for non-admin users to consent to on behalf of themselves, or whether an administrator should be required for consent to the permissions", + Type: pluginsdk.TypeString, + Optional: true, + Default: msgraph.PermissionScopeTypeUser, + ValidateFunc: validation.StringInSlice([]string{ + msgraph.PermissionScopeTypeAdmin, + msgraph.PermissionScopeTypeUser, + }, false), + }, + + "user_consent_description": { + Description: "Delegated permission description that appears in the end user consent experience, intended to be read by a user consenting on their own behalf", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "user_consent_display_name": { + Description: "Display name for the delegated permission that appears in the end user consent experience", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + } +} + +func (r ApplicationPermissionScopeResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r ApplicationPermissionScopeResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + var model ApplicationPermissionScopeModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + applicationId, err := parse.ParseApplicationID(model.ApplicationId) + if err != nil { + return err + } + + id := parse.NewPermissionScopeID(applicationId.ApplicationId, model.ScopeId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + result, _, err := client.Get(ctx, applicationId.ApplicationId, odata.Query{}) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", applicationId, err) + } + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", applicationId) + } + + newScopes := make([]msgraph.PermissionScope, 0) + + // Don't forget any existing scopes, since all scopes must be updated together + if result.Api != nil && result.Api.OAuth2PermissionScopes != nil { + newScopes = *result.Api.OAuth2PermissionScopes + } + + // Check for existing scope ID + for _, scope := range newScopes { + if strings.EqualFold(*scope.ID, id.ScopeID) { + return metadata.ResourceRequiresImport(r.ResourceType(), id) + } + } + + newScopes = append(newScopes, msgraph.PermissionScope{ + ID: &model.ScopeId, + IsEnabled: pointer.To(true), + AdminConsentDescription: &model.AdminConsentDescription, + AdminConsentDisplayName: &model.AdminConsentDisplayName, + Type: model.Type, + UserConsentDescription: &model.UserConsentDescription, + UserConsentDisplayName: &model.UserConsentDisplayName, + Value: &model.Value, + }) + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &id.ApplicationId, + }, + Api: &msgraph.ApplicationApi{ + OAuth2PermissionScopes: &newScopes, + }, + } + + if _, err = client.Update(ctx, properties); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r ApplicationPermissionScopeResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParsePermissionScopeID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + applicationId := parse.NewApplicationID(id.ApplicationId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", id) + } + if result.Api == nil || result.Api.OAuth2PermissionScopes == nil { + return metadata.MarkAsGone(id) + } + + // Identify the scope by ID + var scope *msgraph.PermissionScope + for _, existingScope := range *result.Api.OAuth2PermissionScopes { + if strings.EqualFold(*existingScope.ID, id.ScopeID) { + scope = &existingScope + break + } + } + + if scope == nil { + return metadata.MarkAsGone(id) + } + + state := ApplicationPermissionScopeModel{ + ApplicationId: applicationId.ID(), + ScopeId: id.ScopeID, + AdminConsentDescription: pointer.From(scope.AdminConsentDescription), + AdminConsentDisplayName: pointer.From(scope.AdminConsentDisplayName), + Type: scope.Type, + UserConsentDescription: pointer.From(scope.UserConsentDescription), + UserConsentDisplayName: pointer.From(scope.UserConsentDisplayName), + Value: pointer.From(scope.Value), + } + + return metadata.Encode(&state) + }, + } +} + +func (r ApplicationPermissionScopeResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + + id, err := parse.ParsePermissionScopeID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var model ApplicationPermissionScopeModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + // Prepare a new scope to replace the existing one + scope := msgraph.PermissionScope{ + ID: &id.ScopeID, + IsEnabled: pointer.To(true), + AdminConsentDescription: &model.AdminConsentDescription, + AdminConsentDisplayName: &model.AdminConsentDisplayName, + Type: model.Type, + UserConsentDescription: &model.UserConsentDescription, + UserConsentDisplayName: &model.UserConsentDisplayName, + Value: &model.Value, + } + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + applicationId := parse.NewApplicationID(id.ApplicationId) + result, _, err := client.Get(ctx, applicationId.ApplicationId, odata.Query{}) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", applicationId, err) + } + if result == nil || result.Api == nil || result.Api.OAuth2PermissionScopes == nil { + return fmt.Errorf("retrieving %s: api.oauth2PermissionScopes was nil", applicationId) + } + + // Look for a scope to replace, matching by ID + newScopes := make([]msgraph.PermissionScope, 0) + found := false + for _, existingScope := range *result.Api.OAuth2PermissionScopes { + if strings.EqualFold(*existingScope.ID, id.ScopeID) { + newScopes = append(newScopes, scope) + found = true + } else { + newScopes = append(newScopes, existingScope) + } + } + if !found { + return fmt.Errorf("updating %s: could not identify existing permission scope", id) + } + + // Disable the existing scope prior to update + if err = applicationDisableOauth2PermissionScopes(ctx, client, result, &newScopes); err != nil { + return fmt.Errorf("disabling %s in preparation for update: %+v", id, err) + } + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &applicationId.ApplicationId, + }, + Api: &msgraph.ApplicationApi{ + OAuth2PermissionScopes: &newScopes, + }, + } + + // Patch the application with the new set of scopes + _, err = client.Update(ctx, properties) + if err != nil { + return fmt.Errorf("updating %s: %+v", id, err) + } + + return nil + }, + } +} + +func (r ApplicationPermissionScopeResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParsePermissionScopeID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var model ApplicationPermissionScopeModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + applicationId := parse.NewApplicationID(id.ApplicationId) + result, _, err := client.Get(ctx, applicationId.ApplicationId, odata.Query{}) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", applicationId, err) + } + if result == nil || result.Api == nil || result.Api.OAuth2PermissionScopes == nil { + return fmt.Errorf("retrieving %s: api.oauth2PermissionScopes was nil", applicationId) + } + + // Look for a scope to remove, matching by ID + newScopes := make([]msgraph.PermissionScope, 0) + found := false + for _, existingScope := range *result.Api.OAuth2PermissionScopes { + if strings.EqualFold(*existingScope.ID, id.ScopeID) { + found = true + } else { + newScopes = append(newScopes, existingScope) + } + } + if !found { + return fmt.Errorf("deleting %s: could not identify existing permission scope", id) + } + + // Disable the existing scope prior to update + if err = applicationDisableOauth2PermissionScopes(ctx, client, result, &newScopes); err != nil { + return fmt.Errorf("disabling %s in preparation for deletion: %+v", id, err) + } + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &applicationId.ApplicationId, + }, + Api: &msgraph.ApplicationApi{ + OAuth2PermissionScopes: &newScopes, + }, + } + + // Patch the application with the new set of scopes + _, err = client.Update(ctx, properties) + if err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + + return nil + }, + } +} diff --git a/internal/services/applications/application_permission_scope_resource_test.go b/internal/services/applications/application_permission_scope_resource_test.go new file mode 100644 index 0000000000..4d8cd6c751 --- /dev/null +++ b/internal/services/applications/application_permission_scope_resource_test.go @@ -0,0 +1,343 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications_test + +import ( + "context" + "fmt" + "net/http" + "strings" + "testing" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "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/services/applications/parse" +) + +type ApplicationPermissionScopeResource struct{} + +func TestAccApplicationPermissionScope_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_permission_scope", "test") + r := ApplicationPermissionScopeResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + 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("scope_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationPermissionScope_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_permission_scope", "test") + r := ApplicationPermissionScopeResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + 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("scope_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationPermissionScope_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_permission_scope", "test") + r := ApplicationPermissionScopeResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + 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("scope_id").Exists(), + ), + }, + data.ImportStep(), + { + 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("scope_id").Exists(), + ), + }, + data.ImportStep(), + { + 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("scope_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationPermissionScope_multiple(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_permission_scope", "test") + data2 := acceptance.BuildTestData(t, "azuread_application_permission_scope", "test2") + r := ApplicationPermissionScopeResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.multiple(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("scope_id").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).Key("scope_id").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + }) +} + +func TestAccApplicationPermissionScope_multipleUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_permission_scope", "test") + data2 := acceptance.BuildTestData(t, "azuread_application_permission_scope", "test2") + r := ApplicationPermissionScopeResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.multiple(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("scope_id").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).Key("scope_id").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + { + Config: r.multipleUpdate(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("scope_id").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).Key("scope_id").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + { + Config: r.multiple(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("scope_id").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).Key("scope_id").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + }) +} + +func TestAccApplicationPermissionScope_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_permission_scope", "test") + r := ApplicationPermissionScopeResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + 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("scope_id").Exists(), + ), + }, + data.RequiresImportErrorStep(r.requiresImport(data)), + }) +} + +func (r ApplicationPermissionScopeResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { + client := clients.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParsePermissionScopeID(state.ID) + if err != nil { + return nil, err + } + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return pointer.To(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return nil, fmt.Errorf("retrieving %s: result was nil", id) + } + + if result.Api == nil || result.Api.OAuth2PermissionScopes == nil { + return pointer.To(false), nil + } + + for _, scope := range *result.Api.OAuth2PermissionScopes { + if strings.EqualFold(*scope.ID, id.ScopeID) { + return pointer.To(true), nil + } + } + + return pointer.To(false), nil +} + +func (ApplicationPermissionScopeResource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} + +resource "azuread_application_permission_scope" "test" { + application_id = azuread_application_registration.test.id + scope_id = "%[2]s" + value = "administer" + + admin_consent_description = "Administer the application" + admin_consent_display_name = "Administer" +} +`, data.RandomInteger, data.RandomID) +} + +func (ApplicationPermissionScopeResource) complete(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} + +resource "azuread_application_permission_scope" "test" { + application_id = azuread_application_registration.test.id + scope_id = "%[2]s" + type = "Admin" + value = "administer" + + admin_consent_description = "Administer the application" + admin_consent_display_name = "Administer" + user_consent_description = "Allow the application to access acctest-APP-%[1]d on your behalf." + user_consent_display_name = "Access acctest-APP-%[1]d" +} +`, data.RandomInteger, data.RandomID) +} + +func (ApplicationPermissionScopeResource) multiple(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} + +resource "random_uuid" "test" {} +resource "random_uuid" "test2" {} + +resource "azuread_application_permission_scope" "test" { + application_id = azuread_application_registration.test.id + scope_id = random_uuid.test.id + value = "administer" + + admin_consent_description = "Administer the application" + admin_consent_display_name = "Administer" +} + +resource "azuread_application_permission_scope" "test2" { + application_id = azuread_application_registration.test.id + scope_id = random_uuid.test2.id + value = "operate" + + admin_consent_description = "Operate the application" + admin_consent_display_name = "Operate" +} +`, data.RandomInteger) +} + +func (ApplicationPermissionScopeResource) multipleUpdate(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} + +resource "random_uuid" "test" {} +resource "random_uuid" "test2" {} + +resource "azuread_application_permission_scope" "test" { + application_id = azuread_application_registration.test.id + scope_id = random_uuid.test.id + value = "administrate" + + admin_consent_description = "Administrate the application" + admin_consent_display_name = "Administrate" +} + +resource "azuread_application_permission_scope" "test2" { + application_id = azuread_application_registration.test.id + scope_id = random_uuid.test2.id + value = "view" + + admin_consent_description = "View the application" + admin_consent_display_name = "View" +} +`, data.RandomInteger) +} + +func (ApplicationPermissionScopeResource) requiresImport(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} + +resource "azuread_application_permission_scope" "test" { + application_id = azuread_application_registration.test.id + scope_id = "%[2]s" + value = "administer" + + admin_consent_description = "Administer the application" + admin_consent_display_name = "Administer" +} + +resource "azuread_application_permission_scope" "import" { + application_id = azuread_application_permission_scope.test.application_id + scope_id = azuread_application_permission_scope.test.scope_id + value = azuread_application_permission_scope.test.value + + admin_consent_description = azuread_application_permission_scope.test.admin_consent_description + admin_consent_display_name = azuread_application_permission_scope.test.admin_consent_display_name +} +`, data.RandomInteger, data.RandomID) +} diff --git a/internal/services/applications/application_resource.go b/internal/services/applications/application_resource.go index bd2118352f..1ffcf8eb51 100644 --- a/internal/services/applications/application_resource.go +++ b/internal/services/applications/application_resource.go @@ -27,8 +27,6 @@ import ( "github.com/manicminer/hamilton/msgraph" ) -const applicationResourceName = "azuread_application" - func applicationResource() *pluginsdk.Resource { return &pluginsdk.Resource{ CreateContext: applicationResourceCreate, diff --git a/internal/services/applications/applications.go b/internal/services/applications/applications.go index db2de9d989..a98fb505c1 100644 --- a/internal/services/applications/applications.go +++ b/internal/services/applications/applications.go @@ -20,6 +20,8 @@ import ( "github.com/manicminer/hamilton/msgraph" ) +const applicationResourceName = "azuread_application" + func applicationAppRoleChanged(existing msgraph.AppRole, new msgraph.AppRole) bool { if !reflect.DeepEqual(existing.AllowedMemberTypes, new.AllowedMemberTypes) { return true diff --git a/internal/services/applications/parse/application.go b/internal/services/applications/parse/application.go index db5033b8c2..529fde22f9 100644 --- a/internal/services/applications/parse/application.go +++ b/internal/services/applications/parse/application.go @@ -11,9 +11,9 @@ type ApplicationId struct { ApplicationId string } -func NewApplicationID(input string) ApplicationId { +func NewApplicationID(applicationId string) ApplicationId { return ApplicationId{ - ApplicationId: input, + ApplicationId: applicationId, } } diff --git a/internal/services/applications/parse/permission_scope.go b/internal/services/applications/parse/permission_scope.go new file mode 100644 index 0000000000..149a678302 --- /dev/null +++ b/internal/services/applications/parse/permission_scope.go @@ -0,0 +1,77 @@ +package parse + +import ( + "fmt" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/hashicorp/terraform-provider-azuread/internal/tf/validation" +) + +type PermissionScopeId struct { + ApplicationId string + ScopeID string +} + +func NewPermissionScopeID(applicationId, scopeId string) PermissionScopeId { + return PermissionScopeId{ + ApplicationId: applicationId, + ScopeID: scopeId, + } +} + +// ParsePermissionScopeID parses 'input' into an PermissionScopeId +func ParsePermissionScopeID(input string) (*PermissionScopeId, error) { + parser := resourceids.NewParserFromResourceIdType(PermissionScopeId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := PermissionScopeId{} + + if id.ApplicationId, ok = parsed.Parsed["applicationId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "applicationId", *parsed) + } + + if id.ScopeID, ok = parsed.Parsed["scopeId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "scopeId", *parsed) + } + + return &id, nil +} + +// ValidatePermissionScopeID checks that 'input' can be parsed as an Application ID +func ValidatePermissionScopeID(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 := ParsePermissionScopeID(v) + if err != nil { + errors = append(errors, err) + } + + return validation.IsUUID(id.ScopeID, "ID") +} + +func (id PermissionScopeId) ID() string { + fmtString := "/applications/%s/permissionScopes/%s" + return fmt.Sprintf(fmtString, id.ApplicationId, id.ScopeID) +} + +// Segments returns a slice of Resource ID Segments which comprise this B 2 C Directory ID +func (id PermissionScopeId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("applications", "applications", "applications"), + resourceids.UserSpecifiedSegment("applicationId", "00000000-0000-0000-0000-000000000000"), + resourceids.StaticSegment("permissionScopes", "permissionScopes", "permissionScopes"), + resourceids.UserSpecifiedSegment("scopeId", "11111111-1111-1111-1111-111111111111"), + } +} + +func (id PermissionScopeId) String() string { + return fmt.Sprintf("Permission Scope (Application ID: %q, Scope ID: %q)", id.ApplicationId, id.ScopeID) +} diff --git a/internal/services/applications/registration.go b/internal/services/applications/registration.go index 56e8e09a37..9af7f647f9 100644 --- a/internal/services/applications/registration.go +++ b/internal/services/applications/registration.go @@ -50,6 +50,7 @@ func (r Registration) DataSources() []sdk.DataSource { // Resources returns the typed Resources supported by this service func (r Registration) Resources() []sdk.Resource { return []sdk.Resource{ + ApplicationPermissionScopeResource{}, ApplicationRegistrationResource{}, } } From 58eae61270e997d57a74cd0fd5b045f1ce12f060 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Oct 2023 05:07:57 +0100 Subject: [PATCH 05/46] New Resource: `azuread_application_app_role` --- .../application_app_role_resource.go | 381 ++++++++++++++++++ .../application_app_role_resource_test.go | 276 +++++++++++++ .../application_permission_scope_resource.go | 3 + .../application_registration_resource.go | 3 + .../services/applications/parse/app_role.go | 79 +++- .../services/applications/registration.go | 1 + 6 files changed, 725 insertions(+), 18 deletions(-) create mode 100644 internal/services/applications/application_app_role_resource.go create mode 100644 internal/services/applications/application_app_role_resource_test.go diff --git a/internal/services/applications/application_app_role_resource.go b/internal/services/applications/application_app_role_resource.go new file mode 100644 index 0000000000..139293ddee --- /dev/null +++ b/internal/services/applications/application_app_role_resource.go @@ -0,0 +1,381 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications + +import ( + "context" + "fmt" + "net/http" + "strings" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/terraform-provider-azuread/internal/sdk" + "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" + applicationsValidate "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/validate" + "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" +) + +type ApplicationAppRoleModel struct { + ApplicationId string `tfschema:"application_id"` + RoleId string `tfschema:"role_id"` + AllowedMemberTypes []string `tfschema:"allowed_member_types"` + Description string `tfschema:"description"` + DisplayName string `tfschema:"display_name"` + Value string `tfschema:"value"` +} + +type ApplicationAppRoleResource struct{} + +func (r ApplicationAppRoleResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return parse.ValidateAppRoleID +} + +var _ sdk.ResourceWithUpdate = ApplicationAppRoleResource{} + +func (r ApplicationAppRoleResource) ResourceType() string { + return "azuread_application_app_role" +} + +func (r ApplicationAppRoleResource) ModelObject() interface{} { + return &ApplicationAppRoleModel{} +} + +func (r ApplicationAppRoleResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "application_id": { + Description: "The resource ID of the application to which this app role should be applied", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: parse.ValidateApplicationID, + }, + + "role_id": { + Description: "The unique identifier of the app role", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.IsUUID, + }, + + "allowed_member_types": { + Description: "Specifies whether this app role definition can be assigned to users and groups by setting to `User`, or to other applications (that are accessing this application in a standalone scenario) by setting to `Application`, or to both", + Type: pluginsdk.TypeSet, + Required: true, + MinItems: 1, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + ValidateFunc: validation.StringInSlice( + []string{ + msgraph.AppRoleAllowedMemberTypeApplication, + msgraph.AppRoleAllowedMemberTypeUser, + }, false, + ), + }, + }, + + "description": { + Description: "Description of the app role that appears when the role is being assigned and, if the role functions as an application permissions, during the consent experiences", + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "display_name": { + Description: "Display name for the app role that appears during app role assignment and in consent experiences", + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "value": { + Description: "The value that is used for the `roles` claim in ID tokens and OAuth access tokens that are authenticating an assigned service or user principal", + Type: pluginsdk.TypeString, + Optional: true, + ValidateDiagFunc: applicationsValidate.RoleScopeClaimValue, + }, + } +} + +func (r ApplicationAppRoleResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r ApplicationAppRoleResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + var model ApplicationAppRoleModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + applicationId, err := parse.ParseApplicationID(model.ApplicationId) + if err != nil { + return err + } + + id := parse.NewAppRoleID(applicationId.ApplicationId, model.RoleId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + result, _, err := client.Get(ctx, applicationId.ApplicationId, odata.Query{}) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", applicationId, err) + } + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", applicationId) + } + + newRoles := make([]msgraph.AppRole, 0) + + // Don't forget any existing roles, since all roles must be updated together + if result.AppRoles != nil { + newRoles = *result.AppRoles + } + + // Check for existing role ID + for _, role := range newRoles { + if strings.EqualFold(*role.ID, id.RoleID) { + return metadata.ResourceRequiresImport(r.ResourceType(), id) + } + } + + newRoles = append(newRoles, msgraph.AppRole{ + ID: &model.RoleId, + IsEnabled: pointer.To(true), + AllowedMemberTypes: &model.AllowedMemberTypes, + Description: &model.Description, + DisplayName: &model.DisplayName, + Value: &model.Value, + }) + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &id.ApplicationId, + }, + AppRoles: &newRoles, + } + + if _, err = client.Update(ctx, properties); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r ApplicationAppRoleResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseAppRoleID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + applicationId := parse.NewApplicationID(id.ApplicationId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", id) + } + if result.AppRoles == nil { + return metadata.MarkAsGone(id) + } + + // Identify the role by ID + var role *msgraph.AppRole + for _, existingRole := range *result.AppRoles { + if strings.EqualFold(*existingRole.ID, id.RoleID) { + role = &existingRole + break + } + } + + if role == nil { + return metadata.MarkAsGone(id) + } + + state := ApplicationAppRoleModel{ + ApplicationId: applicationId.ID(), + RoleId: id.RoleID, + AllowedMemberTypes: pointer.From(role.AllowedMemberTypes), + Description: pointer.From(role.Description), + DisplayName: pointer.From(role.DisplayName), + Value: pointer.From(role.Value), + } + + return metadata.Encode(&state) + }, + } +} + +func (r ApplicationAppRoleResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + + id, err := parse.ParseAppRoleID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var model ApplicationAppRoleModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + // Prepare a new role to replace the existing one + role := msgraph.AppRole{ + ID: &id.RoleID, + IsEnabled: pointer.To(true), + AllowedMemberTypes: &model.AllowedMemberTypes, + Description: &model.Description, + DisplayName: &model.DisplayName, + Value: &model.Value, + } + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + applicationId := parse.NewApplicationID(id.ApplicationId) + result, _, err := client.Get(ctx, applicationId.ApplicationId, odata.Query{}) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", applicationId, err) + } + if result == nil || result.AppRoles == nil { + return fmt.Errorf("retrieving %s: appRoles was nil", applicationId) + } + + // Look for a role to replace, matching by ID + newRoles := make([]msgraph.AppRole, 0) + found := false + for _, existingRole := range *result.AppRoles { + if strings.EqualFold(*existingRole.ID, id.RoleID) { + newRoles = append(newRoles, role) + found = true + } else { + newRoles = append(newRoles, existingRole) + } + } + if !found { + return fmt.Errorf("updating %s: could not identify existing app role", id) + } + + // Disable the existing role prior to update + if err = applicationDisableAppRoles(ctx, client, result, &newRoles); err != nil { + return fmt.Errorf("disabling %s in preparation for update: %+v", id, err) + } + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &applicationId.ApplicationId, + }, + AppRoles: &newRoles, + } + + // Patch the application with the new set of roles + _, err = client.Update(ctx, properties) + if err != nil { + return fmt.Errorf("updating %s: %+v", id, err) + } + + return nil + }, + } +} + +func (r ApplicationAppRoleResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseAppRoleID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var model ApplicationAppRoleModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + applicationId := parse.NewApplicationID(id.ApplicationId) + result, _, err := client.Get(ctx, applicationId.ApplicationId, odata.Query{}) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", applicationId, err) + } + if result == nil || result.AppRoles == nil { + return fmt.Errorf("retrieving %s: api.oauth2AppRoles was nil", applicationId) + } + + // Look for a role to remove, matching by ID + newRoles := make([]msgraph.AppRole, 0) + found := false + for _, existingRole := range *result.AppRoles { + if strings.EqualFold(*existingRole.ID, id.RoleID) { + found = true + } else { + newRoles = append(newRoles, existingRole) + } + } + if !found { + return fmt.Errorf("deleting %s: could not identify existing app role", id) + } + + // Disable the existing role prior to update + if err = applicationDisableAppRoles(ctx, client, result, &newRoles); err != nil { + return fmt.Errorf("disabling %s in preparation for deletion: %+v", id, err) + } + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &applicationId.ApplicationId, + }, + AppRoles: &newRoles, + } + + // Patch the application with the new set of roles + _, err = client.Update(ctx, properties) + if err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + + return nil + }, + } +} diff --git a/internal/services/applications/application_app_role_resource_test.go b/internal/services/applications/application_app_role_resource_test.go new file mode 100644 index 0000000000..627e003075 --- /dev/null +++ b/internal/services/applications/application_app_role_resource_test.go @@ -0,0 +1,276 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications_test + +import ( + "context" + "fmt" + "net/http" + "strings" + "testing" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "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/services/applications/parse" +) + +type ApplicationAppRoleResource struct{} + +func TestAccApplicationAppRole_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_app_role", "test") + r := ApplicationAppRoleResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + 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("role_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationAppRole_multiple(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_app_role", "test") + data2 := acceptance.BuildTestData(t, "azuread_application_app_role", "test2") + r := ApplicationAppRoleResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.multiple(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("role_id").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).Key("role_id").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + }) +} + +func TestAccApplicationAppRole_multipleUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_app_role", "test") + data2 := acceptance.BuildTestData(t, "azuread_application_app_role", "test2") + r := ApplicationAppRoleResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.multiple(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("role_id").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).Key("role_id").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + { + Config: r.multipleUpdate(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("role_id").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).Key("role_id").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + { + Config: r.multiple(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("role_id").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).Key("role_id").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + }) +} + +func TestAccApplicationAppRole_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_app_role", "test") + r := ApplicationAppRoleResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + 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("role_id").Exists(), + ), + }, + data.RequiresImportErrorStep(r.requiresImport(data)), + }) +} + +func (r ApplicationAppRoleResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { + client := clients.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseAppRoleID(state.ID) + if err != nil { + return nil, err + } + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return pointer.To(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return nil, fmt.Errorf("retrieving %s: result was nil", id) + } + + if result.AppRoles == nil { + return pointer.To(false), nil + } + + for _, role := range *result.AppRoles { + if strings.EqualFold(*role.ID, id.RoleID) { + return pointer.To(true), nil + } + } + + return pointer.To(false), nil +} + +func (ApplicationAppRoleResource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} + +resource "azuread_application_app_role" "test" { + application_id = azuread_application_registration.test.id + role_id = "%[2]s" + + allowed_member_types = ["User"] + description = "Admins can manage roles and perform all task actions" + display_name = "Admin" + value = "admin" +} +`, data.RandomInteger, data.RandomID) +} + +func (ApplicationAppRoleResource) multiple(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} + +resource "random_uuid" "test" {} +resource "random_uuid" "test2" {} + +resource "azuread_application_app_role" "test" { + application_id = azuread_application_registration.test.id + role_id = random_uuid.test.id + + allowed_member_types = ["User"] + description = "Admins can manage roles and perform all task actions" + display_name = "Administrator" + value = "admin" +} + +resource "azuread_application_app_role" "test2" { + application_id = azuread_application_registration.test.id + role_id = random_uuid.test2.id + + allowed_member_types = ["User"] + description = "Read-Only roles have limited query access" + display_name = "Read-Only" + value = "user" +} +`, data.RandomInteger) +} + +func (ApplicationAppRoleResource) multipleUpdate(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} + +resource "random_uuid" "test" {} +resource "random_uuid" "test2" {} + +resource "azuread_application_app_role" "test" { + application_id = azuread_application_registration.test.id + role_id = random_uuid.test.id + + allowed_member_types = ["User"] + description = "Supers can manage roles and perform all task actions" + display_name = "SuperUser" + value = "super" +} + +resource "azuread_application_app_role" "test2" { + application_id = azuread_application_registration.test.id + role_id = random_uuid.test2.id + + allowed_member_types = ["User"] + description = "Users can look but not touch" + display_name = "User" + value = "luser" +} +`, data.RandomInteger) +} + +func (ApplicationAppRoleResource) requiresImport(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} + +resource "azuread_application_app_role" "test" { + application_id = azuread_application_registration.test.id + role_id = "%[2]s" + + allowed_member_types = ["User"] + description = "Admins can manage roles and perform all task actions" + display_name = "Admin" + value = "admin" +} + +resource "azuread_application_app_role" "import" { + application_id = azuread_application_app_role.test.application_id + role_id = azuread_application_app_role.test.role_id + + allowed_member_types = azuread_application_app_role.test.allowed_member_types + description = azuread_application_app_role.test.description + display_name = azuread_application_app_role.test.display_name + value = azuread_application_app_role.test.value +} +`, data.RandomInteger, data.RandomID) +} diff --git a/internal/services/applications/application_permission_scope_resource.go b/internal/services/applications/application_permission_scope_resource.go index 8856a2c6a9..a8af66b58a 100644 --- a/internal/services/applications/application_permission_scope_resource.go +++ b/internal/services/applications/application_permission_scope_resource.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package applications import ( diff --git a/internal/services/applications/application_registration_resource.go b/internal/services/applications/application_registration_resource.go index 69397bb79f..f23a13ff6b 100644 --- a/internal/services/applications/application_registration_resource.go +++ b/internal/services/applications/application_registration_resource.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package applications import ( diff --git a/internal/services/applications/parse/app_role.go b/internal/services/applications/parse/app_role.go index f986c784c2..a6653a0134 100644 --- a/internal/services/applications/parse/app_role.go +++ b/internal/services/applications/parse/app_role.go @@ -1,34 +1,77 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - package parse -import "fmt" +import ( + "fmt" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/hashicorp/terraform-provider-azuread/internal/tf/validation" +) type AppRoleId struct { - ObjectId string - RoleId string + ApplicationId string + RoleID string } -func NewAppRoleID(objectId, roleId string) AppRoleId { +func NewAppRoleID(applicationId, roleId string) AppRoleId { return AppRoleId{ - ObjectId: objectId, - RoleId: roleId, + ApplicationId: applicationId, + RoleID: roleId, } } -func (id AppRoleId) String() string { - return id.ObjectId + "/role/" + id.RoleId +// ParseAppRoleID parses 'input' into an AppRoleId +func ParseAppRoleID(input string) (*AppRoleId, error) { + parser := resourceids.NewParserFromResourceIdType(AppRoleId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := AppRoleId{} + + if id.ApplicationId, ok = parsed.Parsed["applicationId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "applicationId", *parsed) + } + + if id.RoleID, ok = parsed.Parsed["roleId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "roleId", *parsed) + } + + return &id, nil } -func AppRoleID(idString string) (*AppRoleId, error) { - id, err := ObjectSubResourceID(idString, "role") +// ValidateAppRoleID checks that 'input' can be parsed as an Application ID +func ValidateAppRoleID(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 := ParseAppRoleID(v) if err != nil { - return nil, fmt.Errorf("unable to parse App Role ID: %v", err) + errors = append(errors, err) + } + + return validation.IsUUID(id.RoleID, "ID") +} + +func (id AppRoleId) ID() string { + fmtString := "/applications/%s/appRoles/%s" + return fmt.Sprintf(fmtString, id.ApplicationId, id.RoleID) +} + +// Segments returns a slice of Resource ID Segments which comprise this B 2 C Directory ID +func (id AppRoleId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("applications", "applications", "applications"), + resourceids.UserSpecifiedSegment("applicationId", "00000000-0000-0000-0000-000000000000"), + resourceids.StaticSegment("appRoles", "appRoles", "appRoles"), + resourceids.UserSpecifiedSegment("roleId", "11111111-1111-1111-1111-111111111111"), } +} - return &AppRoleId{ - ObjectId: id.objectId, - RoleId: id.subId, - }, nil +func (id AppRoleId) String() string { + return fmt.Sprintf("App Role (Application ID: %q, Role ID: %q)", id.ApplicationId, id.RoleID) } diff --git a/internal/services/applications/registration.go b/internal/services/applications/registration.go index 9af7f647f9..65317559dc 100644 --- a/internal/services/applications/registration.go +++ b/internal/services/applications/registration.go @@ -50,6 +50,7 @@ func (r Registration) DataSources() []sdk.DataSource { // Resources returns the typed Resources supported by this service func (r Registration) Resources() []sdk.Resource { return []sdk.Resource{ + ApplicationAppRoleResource{}, ApplicationPermissionScopeResource{}, ApplicationRegistrationResource{}, } From 00d782a5d1246d19e971f8b1e972e7e0c168a406 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Oct 2023 11:59:56 +0100 Subject: [PATCH 06/46] azuread_application_registration: support `homepage_url` and `logout_url` --- .../application_registration_resource.go | 38 +++++++++++++++++++ .../application_registration_resource_test.go | 2 + 2 files changed, 40 insertions(+) diff --git a/internal/services/applications/application_registration_resource.go b/internal/services/applications/application_registration_resource.go index f23a13ff6b..09ba450c5c 100644 --- a/internal/services/applications/application_registration_resource.go +++ b/internal/services/applications/application_registration_resource.go @@ -27,6 +27,8 @@ type ApplicationRegistrationModel struct { Description string `tfschema:"description"` DisabledByMicrosoft string `tfschema:"disabled_by_microsoft"` DisplayName string `tfschema:"display_name"` + HomepageUrl string `tfschema:"homepage_url"` + LogoutUrl string `tfschema:"logout_url"` MarketingUrl string `tfschema:"marketing_url"` Notes string `tfschema:"notes"` PrivacyStatementUrl string `tfschema:"privacy_statement_url"` @@ -70,6 +72,20 @@ func (r ApplicationRegistrationResource) Arguments() map[string]*pluginsdk.Schem ValidateFunc: validation.StringLenBetween(0, 1024), }, + "homepage_url": { + Description: "URL of the home page for the application", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "logout_url": { + Description: "URL of the logout page for the application, where the session is cleared for single sign-out", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + "marketing_url": { Description: "URL of the marketing page for the application", Type: pluginsdk.TypeString, @@ -197,6 +213,11 @@ func (r ApplicationRegistrationResource) Create() sdk.ResourceFunc { SupportUrl: tf.NullableString(model.SupportUrl), TermsOfServiceUrl: tf.NullableString(model.TermsOfServiceUrl), }, + + Web: &msgraph.ApplicationWeb{ + HomePageUrl: tf.NullableString(model.HomepageUrl), + LogoutUrl: tf.NullableString(model.LogoutUrl), + }, } result, _, err := client.Create(ctx, properties) @@ -285,6 +306,11 @@ func (r ApplicationRegistrationResource) Read() sdk.ResourceFunc { state.TermsOfServiceUrl = string(pointer.From(info.TermsOfServiceUrl)) } + if web := result.Web; web != nil { + state.HomepageUrl = string(pointer.From(web.HomePageUrl)) + state.LogoutUrl = string(pointer.From(web.LogoutUrl)) + } + if result.DisabledByMicrosoftStatus != nil { state.DisabledByMicrosoft = fmt.Sprintf("%v", result.DisabledByMicrosoftStatus) } @@ -363,6 +389,18 @@ func (r ApplicationRegistrationResource) Update() sdk.ResourceFunc { } } + if rd.HasChange("homepage_url") || rd.HasChange("logout_url") { + properties.Web = &msgraph.ApplicationWeb{} + + if rd.HasChange("homepage_url") { + properties.Web.HomePageUrl = tf.NullableString(model.HomepageUrl) + } + + if rd.HasChange("logout_url") { + properties.Web.LogoutUrl = tf.NullableString(model.LogoutUrl) + } + } + _, err = client.Update(ctx, properties) if err != nil { return fmt.Errorf("updating %s: %+v", id, err) diff --git a/internal/services/applications/application_registration_resource_test.go b/internal/services/applications/application_registration_resource_test.go index 8861d835d1..e5f99254a7 100644 --- a/internal/services/applications/application_registration_resource_test.go +++ b/internal/services/applications/application_registration_resource_test.go @@ -130,6 +130,8 @@ resource "azuread_application_registration" "test" { notes = "Testing application" service_management_reference = "app-for-testing" + homepage_url = "https://app.hashitown-%[1]d.com/" + logout_url = "https://app.hashitown-%[1]d.com/logout" marketing_url = "https://hashitown-%[1]d.com/" privacy_statement_url = "https://hashitown-%[1]d.com/privacy" support_url = "https://support.hashitown-%[1]d.com/" From e5ceab89c9254a3ea3bee635402b8330164226a8 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Oct 2023 12:24:27 +0100 Subject: [PATCH 07/46] fix up URL/URI validation --- .../application_registration_resource.go | 12 +- .../applications/application_resource.go | 150 +++++++++--------- .../invitations/invitation_resource.go | 10 +- .../service_principal_resource.go | 8 +- internal/tf/validation/uri.go | 103 ++++-------- internal/tf/validation/uri_test.go | 39 +++-- 6 files changed, 143 insertions(+), 179 deletions(-) diff --git a/internal/services/applications/application_registration_resource.go b/internal/services/applications/application_registration_resource.go index 09ba450c5c..42b34c3a17 100644 --- a/internal/services/applications/application_registration_resource.go +++ b/internal/services/applications/application_registration_resource.go @@ -76,21 +76,21 @@ func (r ApplicationRegistrationResource) Arguments() map[string]*pluginsdk.Schem Description: "URL of the home page for the application", Type: pluginsdk.TypeString, Optional: true, - ValidateFunc: validation.StringIsNotEmpty, + ValidateFunc: validation.IsHttpOrHttpsUrl, }, "logout_url": { Description: "URL of the logout page for the application, where the session is cleared for single sign-out", Type: pluginsdk.TypeString, Optional: true, - ValidateFunc: validation.StringIsNotEmpty, + ValidateFunc: validation.IsLogoutUrl, }, "marketing_url": { Description: "URL of the marketing page for the application", Type: pluginsdk.TypeString, Optional: true, - ValidateFunc: validation.StringIsNotEmpty, + ValidateFunc: validation.IsHttpOrHttpsUrl, }, "notes": { @@ -104,7 +104,7 @@ func (r ApplicationRegistrationResource) Arguments() map[string]*pluginsdk.Schem Description: "URL of the privacy statement for the application", Type: pluginsdk.TypeString, Optional: true, - ValidateFunc: validation.StringIsNotEmpty, + ValidateFunc: validation.IsHttpOrHttpsUrl, }, "requested_access_token_version": { @@ -149,14 +149,14 @@ func (r ApplicationRegistrationResource) Arguments() map[string]*pluginsdk.Schem Description: "URL of the support page for the application", Type: pluginsdk.TypeString, Optional: true, - ValidateFunc: validation.StringIsNotEmpty, + ValidateFunc: validation.IsHttpOrHttpsUrl, }, "terms_of_service_url": { Description: "URL of the terms of service statement for the application", Type: pluginsdk.TypeString, Optional: true, - ValidateFunc: validation.StringIsNotEmpty, + ValidateFunc: validation.IsHttpOrHttpsUrl, }, } } diff --git a/internal/services/applications/application_resource.go b/internal/services/applications/application_resource.go index 1ffcf8eb51..5192a183bb 100644 --- a/internal/services/applications/application_resource.go +++ b/internal/services/applications/application_resource.go @@ -61,10 +61,10 @@ func applicationResource() *pluginsdk.Resource { Schema: map[string]*pluginsdk.Schema{ "display_name": { - Description: "The display name for the application", - Type: pluginsdk.TypeString, - Required: true, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Description: "The display name for the application", + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, }, "api": { @@ -79,8 +79,8 @@ func applicationResource() *pluginsdk.Resource { Type: pluginsdk.TypeSet, Optional: true, Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + Type: pluginsdk.TypeString, + ValidateFunc: validation.IsUUID, }, }, @@ -97,24 +97,24 @@ func applicationResource() *pluginsdk.Resource { Elem: &pluginsdk.Resource{ Schema: map[string]*pluginsdk.Schema{ "id": { - Description: "The unique identifier of the delegated permission", - Type: pluginsdk.TypeString, - Required: true, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + Description: "The unique identifier of the delegated permission", + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.IsUUID, }, "admin_consent_description": { - Description: "Delegated permission description that appears in all tenant-wide admin consent experiences, intended to be read by an administrator granting the permission on behalf of all users", - Type: pluginsdk.TypeString, - Optional: true, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Description: "Delegated permission description that appears in all tenant-wide admin consent experiences, intended to be read by an administrator granting the permission on behalf of all users", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, }, "admin_consent_display_name": { - Description: "Display name for the delegated permission, intended to be read by an administrator granting the permission on behalf of all users", - Type: pluginsdk.TypeString, - Optional: true, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Description: "Display name for the delegated permission, intended to be read by an administrator granting the permission on behalf of all users", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, }, "enabled": { @@ -136,17 +136,17 @@ func applicationResource() *pluginsdk.Resource { }, "user_consent_description": { - Description: "Delegated permission description that appears in the end user consent experience, intended to be read by a user consenting on their own behalf", - Type: pluginsdk.TypeString, - Optional: true, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Description: "Delegated permission description that appears in the end user consent experience, intended to be read by a user consenting on their own behalf", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, }, "user_consent_display_name": { - Description: "Display name for the delegated permission that appears in the end user consent experience", - Type: pluginsdk.TypeString, - Optional: true, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Description: "Display name for the delegated permission that appears in the end user consent experience", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, }, "value": { @@ -194,10 +194,10 @@ func applicationResource() *pluginsdk.Resource { Elem: &pluginsdk.Resource{ Schema: map[string]*pluginsdk.Schema{ "id": { - Description: "The unique identifier of the app role", - Type: pluginsdk.TypeString, - Required: true, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + Description: "The unique identifier of the app role", + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.IsUUID, }, "allowed_member_types": { @@ -217,17 +217,17 @@ func applicationResource() *pluginsdk.Resource { }, "description": { - Description: "Description of the app role that appears when the role is being assigned and, if the role functions as an application permissions, during the consent experiences", - Type: pluginsdk.TypeString, - Required: true, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Description: "Description of the app role that appears when the role is being assigned and, if the role functions as an application permissions, during the consent experiences", + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, }, "display_name": { - Description: "Display name for the app role that appears during app role assignment and in consent experiences", - Type: pluginsdk.TypeString, - Required: true, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Description: "Display name for the app role that appears during app role assignment and in consent experiences", + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, }, "enabled": { @@ -257,10 +257,10 @@ func applicationResource() *pluginsdk.Resource { }, "description": { - Description: "Description of the application as shown to end users", - Type: pluginsdk.TypeString, - Optional: true, - ValidateDiagFunc: validation.ValidateDiag(validation.StringLenBetween(0, 1024)), + Description: "Description of the application as shown to end users", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringLenBetween(0, 1024), }, "device_only_auth_enabled": { @@ -331,8 +331,8 @@ func applicationResource() *pluginsdk.Resource { Type: pluginsdk.TypeSet, Optional: true, Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - ValidateDiagFunc: validation.IsAppUri, + Type: pluginsdk.TypeString, + ValidateFunc: validation.IsAppUri, }, }, @@ -350,10 +350,10 @@ func applicationResource() *pluginsdk.Resource { }, "notes": { - Description: "User-specified notes relevant for the management of the application", - Type: pluginsdk.TypeString, - Optional: true, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Description: "User-specified notes relevant for the management of the application", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, }, // This is a top level attribute because d.SetNewComputed() doesn't work inside a block @@ -393,8 +393,8 @@ func applicationResource() *pluginsdk.Resource { Set: pluginsdk.HashString, MaxItems: 100, Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + Type: pluginsdk.TypeString, + ValidateFunc: validation.IsUUID, }, }, @@ -417,8 +417,8 @@ func applicationResource() *pluginsdk.Resource { Optional: true, MaxItems: 256, Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - ValidateDiagFunc: validation.IsRedirectUriFunc(true, true), + Type: pluginsdk.TypeString, + ValidateFunc: validation.IsRedirectUriFunc(true, true), }, }, }, @@ -443,10 +443,10 @@ func applicationResource() *pluginsdk.Resource { Elem: &pluginsdk.Resource{ Schema: map[string]*pluginsdk.Schema{ "id": { - Description: "", - Type: pluginsdk.TypeString, - Required: true, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + Description: "", + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.IsUUID, }, "type": { @@ -500,8 +500,8 @@ func applicationResource() *pluginsdk.Resource { Optional: true, MaxItems: 256, Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - ValidateDiagFunc: validation.IsRedirectUriFunc(false, false), + Type: pluginsdk.TypeString, + ValidateFunc: validation.IsRedirectUriFunc(false, false), }, }, }, @@ -527,12 +527,12 @@ func applicationResource() *pluginsdk.Resource { }, "template_id": { - Description: "Unique ID of the application template from which this application is created", - Type: pluginsdk.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + Description: "Unique ID of the application template from which this application is created", + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validation.IsUUID, }, "terms_of_service_url": { @@ -549,17 +549,17 @@ func applicationResource() *pluginsdk.Resource { Elem: &pluginsdk.Resource{ Schema: map[string]*pluginsdk.Schema{ "homepage_url": { - Description: "Home page or landing page of the application", - Type: pluginsdk.TypeString, - Optional: true, - ValidateDiagFunc: validation.IsHttpOrHttpsUrl, + Description: "Home page or landing page of the application", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.IsHttpOrHttpsUrl, }, "logout_url": { - Description: "The URL that will be used by Microsoft's authorization service to sign out a user using front-channel, back-channel or SAML logout protocols", - Type: pluginsdk.TypeString, - Optional: true, - ValidateDiagFunc: validation.IsLogoutUrl, + Description: "The URL that will be used by Microsoft's authorization service to sign out a user using front-channel, back-channel or SAML logout protocols", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.IsLogoutUrl, }, "redirect_uris": { @@ -568,8 +568,8 @@ func applicationResource() *pluginsdk.Resource { Optional: true, MaxItems: 256, Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - ValidateDiagFunc: validation.IsRedirectUriFunc(true, false), + Type: pluginsdk.TypeString, + ValidateFunc: validation.IsRedirectUriFunc(true, false), }, }, @@ -730,7 +730,7 @@ func applicationResourceCustomizeDiff(ctx context.Context, diff *pluginsdk.Resou } // urn scheme not supported with personal account sign-ins for _, v := range identifierUris { - if diags := validation.IsUriFunc([]string{"http", "https", "api", "ms-appx"}, false, false, false)(v, cty.Path{}); diags.HasError() { + if _, errs := validation.IsUriFunc([]string{"http", "https", "api", "ms-appx"}, false, false, false)(v, "identifier_uris"); len(errs) > 0 { return fmt.Errorf("`identifier_uris` is invalid. The URN scheme is not supported when `sign_in_audience` is %q or %q", msgraph.SignInAudienceAzureADandPersonalMicrosoftAccount, msgraph.SignInAudiencePersonalMicrosoftAccount) } diff --git a/internal/services/invitations/invitation_resource.go b/internal/services/invitations/invitation_resource.go index 7d3975ad85..786a4ed545 100644 --- a/internal/services/invitations/invitation_resource.go +++ b/internal/services/invitations/invitation_resource.go @@ -36,11 +36,11 @@ func invitationResource() *pluginsdk.Resource { Schema: map[string]*pluginsdk.Schema{ "redirect_url": { - Description: "The URL that the user should be redirected to once the invitation is redeemed", - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateDiagFunc: validation.IsHttpOrHttpsUrl, + Description: "The URL that the user should be redirected to once the invitation is redeemed", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.IsHttpOrHttpsUrl, }, "user_email_address": { diff --git a/internal/services/serviceprincipals/service_principal_resource.go b/internal/services/serviceprincipals/service_principal_resource.go index 2a6d1e0e45..d2270d8877 100644 --- a/internal/services/serviceprincipals/service_principal_resource.go +++ b/internal/services/serviceprincipals/service_principal_resource.go @@ -158,10 +158,10 @@ func servicePrincipalResource() *pluginsdk.Resource { }, "login_url": { - Description: "The URL where the service provider redirects the user to Azure AD to authenticate. Azure AD uses the URL to launch the application from Microsoft 365 or the Azure AD My Apps. When blank, Azure AD performs IdP-initiated sign-on for applications configured with SAML-based single sign-on", - Type: pluginsdk.TypeString, - Optional: true, - ValidateDiagFunc: validation.IsHttpOrHttpsUrl, + Description: "The URL where the service provider redirects the user to Azure AD to authenticate. Azure AD uses the URL to launch the application from Microsoft 365 or the Azure AD My Apps. When blank, Azure AD performs IdP-initiated sign-on for applications configured with SAML-based single sign-on", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.IsHttpOrHttpsUrl, }, "notes": { diff --git a/internal/tf/validation/uri.go b/internal/tf/validation/uri.go index be59b9ad38..f45bdbb462 100644 --- a/internal/tf/validation/uri.go +++ b/internal/tf/validation/uri.go @@ -8,147 +8,100 @@ import ( "net/url" "strings" - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-azuread/internal/tf/pluginsdk" ) -func IsAppUri(i interface{}, path cty.Path) diag.Diagnostics { - return IsUriFunc([]string{"http", "https", "api", "ms-appx"}, true, false, false)(i, path) +func IsAppUri(i interface{}, k string) (warnings []string, errors []error) { + return IsUriFunc([]string{"http", "https", "api", "ms-appx"}, true, false, false)(i, k) } -func IsHttpOrHttpsUrl(i interface{}, path cty.Path) diag.Diagnostics { - return IsUriFunc([]string{"http", "https"}, false, true, false)(i, path) +func IsHttpOrHttpsUrl(i interface{}, k string) (warnings []string, errors []error) { + return IsUriFunc([]string{"http", "https"}, false, true, false)(i, k) } -func IsHttpsUrl(i interface{}, path cty.Path) diag.Diagnostics { - return IsUriFunc([]string{"https"}, false, true, false)(i, path) +func IsHttpsUrl(i interface{}, k string) (warnings []string, errors []error) { + return IsUriFunc([]string{"https"}, false, true, false)(i, k) } -func IsLogoutUrl(i interface{}, path cty.Path) (ret diag.Diagnostics) { - ret = IsUriFunc([]string{"http", "https"}, false, true, false)(i, path) - if len(ret) > 0 { +func IsLogoutUrl(i interface{}, k string) (warnings []string, errors []error) { + warnings, errors = IsUriFunc([]string{"http", "https"}, false, true, false)(i, k) + if len(errors) > 0 { return } if len(i.(string)) > 255 { - ret = append(ret, diag.Diagnostic{ - Severity: diag.Error, - Summary: "URL must be 255 characters or less", - AttributePath: path, - }) + errors = append(errors, fmt.Errorf("URL must be 255 characters or less for %q", k)) } return } -func IsRedirectUriFunc(urnAllowed bool, publicClient bool) schema.SchemaValidateDiagFunc { - return func(i interface{}, path cty.Path) (ret diag.Diagnostics) { +func IsRedirectUriFunc(urnAllowed bool, publicClient bool) pluginsdk.SchemaValidateFunc { + return func(i interface{}, k string) (warnings []string, errors []error) { // See https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows?pivots=b2c-custom-policy#register-the-proxyidentityexperienceframework-application var allowedSchemes []string if !publicClient { allowedSchemes = []string{"http", "https", "ms-appx-web"} } - ret = IsUriFunc(allowedSchemes, urnAllowed, true, true)(i, path) - if len(ret) > 0 { + warnings, errors = IsUriFunc(allowedSchemes, urnAllowed, true, true)(i, k) + if len(errors) > 0 { return } if len(i.(string)) > 256 { - ret = append(ret, diag.Diagnostic{ - Severity: diag.Error, - Summary: "URI must be 256 characters or less", - AttributePath: path, - }) + errors = append(errors, fmt.Errorf("URI must be 256 characters or less for %q", k)) } return } } -func IsUriFunc(validURLSchemes []string, urnAllowed bool, allowTrailingSlash bool, forceTrailingSlash bool) schema.SchemaValidateDiagFunc { - return func(i interface{}, path cty.Path) (ret diag.Diagnostics) { +func IsUriFunc(validURLSchemes []string, urnAllowed bool, allowTrailingSlash bool, forceTrailingSlash bool) pluginsdk.SchemaValidateFunc { + return func(i interface{}, k string) ([]string, []error) { v, ok := i.(string) if !ok { - ret = append(ret, diag.Diagnostic{ - Severity: diag.Error, - Summary: "Expected a string value", - AttributePath: path, - }) - return + return nil, []error{fmt.Errorf("expected a string value for %q", k)} } if v == "" { - ret = append(ret, diag.Diagnostic{ - Severity: diag.Error, - Summary: "URI must not be empty", - AttributePath: path, - }) - return + return nil, []error{fmt.Errorf("URI must not be empty for %q", k)} } if urnAllowed { parts := strings.Split(v, ":") if len(parts) >= 3 && parts[0] == "urn" { - return + return nil, nil } } u, err := url.Parse(v) if err != nil { - ret = append(ret, diag.Diagnostic{ - Severity: diag.Error, - Summary: "URI is in an invalid format", - Detail: err.Error(), - AttributePath: path, - }) - return + return nil, []error{fmt.Errorf("URI is in an invalid format for %q", k)} } if !allowTrailingSlash && u.Path == "/" { - ret = append(ret, diag.Diagnostic{ - Severity: diag.Error, - Summary: "URI must not have a trailing slash when there is no path segment", - AttributePath: path, - }) - return + return nil, []error{fmt.Errorf("URI must not have a trailing slash when there is no path segment for %q", k)} } if u.Host == "" { - ret = append(ret, diag.Diagnostic{ - Severity: diag.Error, - Summary: "URI has no host", - AttributePath: path, - }) - return + return nil, []error{fmt.Errorf("URI has no host for %q", k)} } if validURLSchemes == nil { - return + return nil, nil } if forceTrailingSlash && u.Path == "" { - ret = append(ret, diag.Diagnostic{ - Severity: diag.Error, - Summary: "URI must have a trailing slash when there is no path segment", - AttributePath: path, - }) - return + return nil, []error{fmt.Errorf("URI must have a trailing slash when there is no path segment for %q", k)} } for _, s := range validURLSchemes { if u.Scheme == s { - return + return nil, nil } } - ret = append(ret, diag.Diagnostic{ - Severity: diag.Error, - Summary: fmt.Sprintf("Expected URI to have a scheme of: %s", strings.Join(validURLSchemes, ", ")), - AttributePath: path, - }) - - return + return nil, []error{fmt.Errorf("unexpected URI scheme for %q, expected one of: %s", k, strings.Join(validURLSchemes, ", "))} } } diff --git a/internal/tf/validation/uri_test.go b/internal/tf/validation/uri_test.go index 8d1b1c5e9e..ed44e4d3d3 100644 --- a/internal/tf/validation/uri_test.go +++ b/internal/tf/validation/uri_test.go @@ -5,8 +5,6 @@ package validation import ( "testing" - - "github.com/hashicorp/go-cty/cty" ) func TestIsHTTPSURL(t *testing.T) { @@ -42,10 +40,13 @@ func TestIsHTTPSURL(t *testing.T) { for _, tc := range cases { t.Run(tc.Url, func(t *testing.T) { - diags := IsHttpsUrl(tc.Url, cty.Path{}) + warnings, errors := IsHttpsUrl(tc.Url, "test") - if len(diags) != tc.Errors { - t.Fatalf("Expected URLIsHTTPS to have %d not %d errors for %q", tc.Errors, len(diags), tc.Url) + if len(warnings) > 0 { + t.Fatalf("Expected URLIsHTTPS to have 0 not %d warnings for %q", len(warnings), tc.Url) + } + if len(errors) != tc.Errors { + t.Fatalf("Expected URLIsHTTPS to have %d not %d errors for %q", tc.Errors, len(errors), tc.Url) } }) } @@ -84,10 +85,13 @@ func TestIsHTTPOrHTTPSURL(t *testing.T) { for _, tc := range cases { t.Run(tc.Url, func(t *testing.T) { - diags := IsHttpOrHttpsUrl(tc.Url, cty.Path{}) + warnings, errors := IsHttpOrHttpsUrl(tc.Url, "test") - if len(diags) != tc.Errors { - t.Fatalf("Expected URLIsHTTPOrHTTPS to have %d not %d errors for %q", tc.Errors, len(diags), tc.Url) + if len(warnings) > 0 { + t.Fatalf("Expected URLIsHTTPOrHTTPS to have 0 not %d warnings for %q", len(warnings), tc.Url) + } + if len(errors) != tc.Errors { + t.Fatalf("Expected URLIsHTTPOrHTTPS to have %d not %d errors for %q", tc.Errors, len(errors), tc.Url) } }) } @@ -142,10 +146,13 @@ func TestIsAppURI(t *testing.T) { for _, tc := range cases { t.Run(tc.Url, func(t *testing.T) { - diags := IsAppUri(tc.Url, cty.Path{}) + warnings, errors := IsAppUri(tc.Url, "test") - if len(diags) != tc.Errors { - t.Fatalf("Expected URLIsAppURI to have %d not %d errors for %q", tc.Errors, len(diags), tc.Url) + if len(warnings) > 0 { + t.Fatalf("Expected URLIsAppURI to have 0 not %d warnings for %q", len(warnings), tc.Url) + } + if len(errors) != tc.Errors { + t.Fatalf("Expected URLIsAppURI to have %d not %d errors for %q", tc.Errors, len(errors), tc.Url) } }) } @@ -201,9 +208,13 @@ func TestIsUriFunc(t *testing.T) { for _, tc := range cases { t.Run(tc.TestName, func(t *testing.T) { - diags := IsUriFunc(tc.Schemes, tc.UrnAllowed, tc.AllowTrailingSlash, tc.ForceTrailingSlash) - if len(diags(tc.Url, cty.Path{})) != tc.Errors { - t.Fatalf("Expected IsUriFunc to have %d errors for %v", tc.Errors, tc.Url) + warnings, errors := IsUriFunc(tc.Schemes, tc.UrnAllowed, tc.AllowTrailingSlash, tc.ForceTrailingSlash)(tc.Url, "test") + + if len(warnings) > 0 { + t.Fatalf("Expected IsUriFunc() to have 0 not %d warnings for %q", len(warnings), tc.Url) + } + if len(errors) != tc.Errors { + t.Fatalf("Expected IsUriFunc() to have %d not %d errors for %v", tc.Errors, len(errors), tc.Url) } }) } From 1eaef8b075340d84140bd771b28d49d6835514d9 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Oct 2023 15:02:02 +0100 Subject: [PATCH 08/46] New Resource: `azuread_application_fallback_public_client` --- ...ication_fallback_public_client_resource.go | 169 ++++++++++++++++++ ...on_fallback_public_client_resource_test.go | 131 ++++++++++++++ .../parse/fallback_public_client.go | 70 ++++++++ .../services/applications/registration.go | 1 + 4 files changed, 371 insertions(+) create mode 100644 internal/services/applications/application_fallback_public_client_resource.go create mode 100644 internal/services/applications/application_fallback_public_client_resource_test.go create mode 100644 internal/services/applications/parse/fallback_public_client.go diff --git a/internal/services/applications/application_fallback_public_client_resource.go b/internal/services/applications/application_fallback_public_client_resource.go new file mode 100644 index 0000000000..b252fdaf04 --- /dev/null +++ b/internal/services/applications/application_fallback_public_client_resource.go @@ -0,0 +1,169 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications + +import ( + "context" + "fmt" + "net/http" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/terraform-provider-azuread/internal/sdk" + "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" + "github.com/hashicorp/terraform-provider-azuread/internal/tf" + "github.com/hashicorp/terraform-provider-azuread/internal/tf/pluginsdk" +) + +type ApplicationFallbackPublicClientModel struct { + ApplicationId string `tfschema:"application_id"` + Enabled bool `tfschema:"enabled"` +} + +type ApplicationFallbackPublicClientResource struct{} + +func (r ApplicationFallbackPublicClientResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return parse.ValidateFallbackPublicClientID +} + +var _ sdk.Resource = ApplicationFallbackPublicClientResource{} + +func (r ApplicationFallbackPublicClientResource) ResourceType() string { + return "azuread_application_fallback_public_client" +} + +func (r ApplicationFallbackPublicClientResource) ModelObject() interface{} { + return &ApplicationFallbackPublicClientModel{} +} + +func (r ApplicationFallbackPublicClientResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "application_id": { + Description: "The resource ID of the application to which the fallback public client setting should be applied", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: parse.ValidateApplicationID, + }, + + "enabled": { + Description: "Specifies explicitly whether the application is a public client. Appropriate for apps using token grant flows that don't use a redirect URI", + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + ForceNew: true, + }, + } +} + +func (r ApplicationFallbackPublicClientResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r ApplicationFallbackPublicClientResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + var model ApplicationFallbackPublicClientModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + applicationId, err := parse.ParseApplicationID(model.ApplicationId) + if err != nil { + return err + } + + id := parse.NewFallbackPublicClientID(applicationId.ApplicationId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + if _, err = client.SetFallbackPublicClient(ctx, id.ApplicationId, pointer.To(model.Enabled)); err != nil { + return fmt.Errorf("setting %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r ApplicationFallbackPublicClientResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseFallbackPublicClientID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + applicationId := parse.NewApplicationID(id.ApplicationId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", id) + } + if result.IsFallbackPublicClient == nil { + return metadata.MarkAsGone(id) + } + + state := ApplicationFallbackPublicClientModel{ + ApplicationId: applicationId.ID(), + Enabled: pointer.From(result.IsFallbackPublicClient), + } + + return metadata.Encode(&state) + }, + } +} + +func (r ApplicationFallbackPublicClientResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseFallbackPublicClientID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var model ApplicationFallbackPublicClientModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + _, err = client.SetFallbackPublicClient(ctx, id.ApplicationId, nil) + if err != nil { + return fmt.Errorf("unsetting %s: %+v", id, err) + } + + return nil + }, + } +} diff --git a/internal/services/applications/application_fallback_public_client_resource_test.go b/internal/services/applications/application_fallback_public_client_resource_test.go new file mode 100644 index 0000000000..c767259337 --- /dev/null +++ b/internal/services/applications/application_fallback_public_client_resource_test.go @@ -0,0 +1,131 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications_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/terraform-plugin-testing/terraform" + "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/services/applications/parse" +) + +type ApplicationFallbackPublicClientResource struct{} + +func TestAccApplicationFallbackPublicClient_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_fallback_public_client", "test") + r := ApplicationFallbackPublicClientResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.enabled(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("enabled").HasValue("true"), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationFallbackPublicClient_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_fallback_public_client", "test") + r := ApplicationFallbackPublicClientResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.disabled(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("enabled").HasValue("false"), + ), + }, + data.ImportStep(), + { + Config: r.enabled(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("enabled").HasValue("true"), + ), + }, + data.ImportStep(), + { + Config: r.disabled(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("enabled").HasValue("false"), + ), + }, + data.ImportStep(), + }) +} + +func (r ApplicationFallbackPublicClientResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { + client := clients.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseFallbackPublicClientID(state.ID) + if err != nil { + return nil, err + } + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return pointer.To(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return nil, fmt.Errorf("retrieving %s: result was nil", id) + } + + if result.IsFallbackPublicClient == nil { + return pointer.To(false), nil + } + + return pointer.To(true), nil +} + +func (ApplicationFallbackPublicClientResource) enabled(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-FallbackPublicClient-%[1]d" +} + +resource "azuread_application_fallback_public_client" "test" { + application_id = azuread_application_registration.test.id + enabled = true +} +`, data.RandomInteger, data.RandomID) +} + +func (ApplicationFallbackPublicClientResource) disabled(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-FallbackPublicClient-%[1]d" +} + +resource "azuread_application_fallback_public_client" "test" { + application_id = azuread_application_registration.test.id + enabled = false +} +`, data.RandomInteger) +} diff --git a/internal/services/applications/parse/fallback_public_client.go b/internal/services/applications/parse/fallback_public_client.go new file mode 100644 index 0000000000..6900796847 --- /dev/null +++ b/internal/services/applications/parse/fallback_public_client.go @@ -0,0 +1,70 @@ +package parse + +import ( + "fmt" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/hashicorp/terraform-provider-azuread/internal/tf/validation" +) + +type FallbackPublicClientId struct { + ApplicationId string +} + +func NewFallbackPublicClientID(applicationId string) FallbackPublicClientId { + return FallbackPublicClientId{ + ApplicationId: applicationId, + } +} + +// ParseFallbackPublicClientID parses 'input' into an FallbackPublicClientId +func ParseFallbackPublicClientID(input string) (*FallbackPublicClientId, error) { + parser := resourceids.NewParserFromResourceIdType(FallbackPublicClientId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := FallbackPublicClientId{} + + if id.ApplicationId, ok = parsed.Parsed["applicationId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "applicationId", *parsed) + } + + return &id, nil +} + +// ValidateFallbackPublicClientID checks that 'input' can be parsed as an Application ID +func ValidateFallbackPublicClientID(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 := ParseFallbackPublicClientID(v) + if err != nil { + errors = append(errors, err) + } + + return validation.IsUUID(id.ApplicationId, "ID") +} + +func (id FallbackPublicClientId) ID() string { + fmtString := "/applications/%s/fallbackPublicClient" + return fmt.Sprintf(fmtString, id.ApplicationId) +} + +// Segments returns a slice of Resource ID Segments which comprise this B 2 C Directory ID +func (id FallbackPublicClientId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("applications", "applications", "applications"), + resourceids.UserSpecifiedSegment("applicationId", "00000000-0000-0000-0000-000000000000"), + resourceids.StaticSegment("fallbackPublicClient", "fallbackPublicClient", "fallbackPublicClient"), + } +} + +func (id FallbackPublicClientId) String() string { + return fmt.Sprintf("Fallback Public Client (Application ID: %q)", id.ApplicationId) +} diff --git a/internal/services/applications/registration.go b/internal/services/applications/registration.go index 65317559dc..ced6b74a71 100644 --- a/internal/services/applications/registration.go +++ b/internal/services/applications/registration.go @@ -51,6 +51,7 @@ func (r Registration) DataSources() []sdk.DataSource { func (r Registration) Resources() []sdk.Resource { return []sdk.Resource{ ApplicationAppRoleResource{}, + ApplicationFallbackPublicClientResource{}, ApplicationPermissionScopeResource{}, ApplicationRegistrationResource{}, } From 7e3d001583de1ee723843dff9d96ded488fdf43c Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Oct 2023 15:38:16 +0100 Subject: [PATCH 09/46] New Resource: `azuread_application_owner` --- .../application_owner_resource.go | 183 +++++++++++++++++ .../application_owner_resource_test.go | 191 ++++++++++++++++++ internal/services/applications/parse/owner.go | 77 +++++++ .../services/applications/registration.go | 1 + 4 files changed, 452 insertions(+) create mode 100644 internal/services/applications/application_owner_resource.go create mode 100644 internal/services/applications/application_owner_resource_test.go create mode 100644 internal/services/applications/parse/owner.go diff --git a/internal/services/applications/application_owner_resource.go b/internal/services/applications/application_owner_resource.go new file mode 100644 index 0000000000..a31ecc1715 --- /dev/null +++ b/internal/services/applications/application_owner_resource.go @@ -0,0 +1,183 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications + +import ( + "context" + "fmt" + "net/http" + "time" + + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/terraform-provider-azuread/internal/sdk" + "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" + "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" +) + +type ApplicationOwnerModel struct { + ApplicationId string `tfschema:"application_id"` + OwnerObjectId string `tfschema:"owner_object_id"` +} + +type ApplicationOwnerResource struct{} + +func (r ApplicationOwnerResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return parse.ValidateOwnerID +} + +var _ sdk.Resource = ApplicationOwnerResource{} + +func (r ApplicationOwnerResource) ResourceType() string { + return "azuread_application_owner" +} + +func (r ApplicationOwnerResource) ModelObject() interface{} { + return &ApplicationOwnerModel{} +} + +func (r ApplicationOwnerResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "application_id": { + Description: "The resource ID of the application to which the fallback public client setting should be applied", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: parse.ValidateApplicationID, + }, + + "owner_object_id": { + Description: "Object ID of the principal that will be granted ownership of the application", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.IsUUID, + }, + } +} + +func (r ApplicationOwnerResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r ApplicationOwnerResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + var model ApplicationOwnerModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + applicationId, err := parse.ParseApplicationID(model.ApplicationId) + if err != nil { + return err + } + + id := parse.NewOwnerID(applicationId.ApplicationId, model.OwnerObjectId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + _, status, err := client.GetOwner(ctx, id.ApplicationId, id.OwnerID) + if err != nil && status != http.StatusNotFound { + return fmt.Errorf("checking for presence of existing %s: %+v", id, err) + } + if status != http.StatusNotFound { + return metadata.ResourceRequiresImport(r.ResourceType(), id) + } + + // Construct an @odata.id for the $ref endpoint + odataId := (odata.Id)(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, metadata.Client.TenantID, id.OwnerID)) + + properties := &msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &id.ApplicationId, + }, + Owners: &msgraph.Owners{{ + Id: &id.OwnerID, + ODataId: &odataId, + }}, + } + + if _, err = client.AddOwners(ctx, properties); err != nil { + return fmt.Errorf("adding %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r ApplicationOwnerResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseOwnerID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + applicationId := parse.NewApplicationID(id.ApplicationId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + result, status, err := client.GetOwner(ctx, id.ApplicationId, id.OwnerID) + if err != nil { + if status == http.StatusNotFound { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", id) + } + + state := ApplicationOwnerModel{ + ApplicationId: applicationId.ID(), + OwnerObjectId: id.OwnerID, + } + + return metadata.Encode(&state) + }, + } +} + +func (r ApplicationOwnerResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseOwnerID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + _, err = client.RemoveOwners(ctx, id.ApplicationId, &[]string{id.OwnerID}) + if err != nil { + return fmt.Errorf("removing %s: %+v", id, err) + } + + return nil + }, + } +} diff --git a/internal/services/applications/application_owner_resource_test.go b/internal/services/applications/application_owner_resource_test.go new file mode 100644 index 0000000000..141f7480e9 --- /dev/null +++ b/internal/services/applications/application_owner_resource_test.go @@ -0,0 +1,191 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications_test + +import ( + "context" + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "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/services/applications/parse" +) + +type ApplicationOwnerResource struct{} + +func TestAccApplicationOwner_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_owner", "test") + r := ApplicationOwnerResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + 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("owner_object_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationOwner_multiple(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_owner", "test") + data2 := acceptance.BuildTestData(t, "azuread_application_owner", "test2") + r := ApplicationOwnerResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.multiple(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("owner_object_id").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).Key("owner_object_id").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + }) +} + +func TestAccApplicationOwner_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_owner", "test") + r := ApplicationOwnerResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + 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("owner_object_id").Exists(), + ), + }, + data.RequiresImportErrorStep(r.requiresImport(data)), + }) +} + +func (r ApplicationOwnerResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { + client := clients.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseOwnerID(state.ID) + if err != nil { + return nil, err + } + + result, status, err := client.GetOwner(ctx, id.ApplicationId, id.OwnerID) + if err != nil { + if status == http.StatusNotFound { + return pointer.To(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return nil, fmt.Errorf("retrieving %s: result was nil", id) + } + + return pointer.To(true), nil +} + +func (ApplicationOwnerResource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +data "azuread_domains" "test" { + only_initial = true +} + +resource "azuread_application_registration" "test" { + display_name = "acctest-Owner-%[1]d" +} + +resource "azuread_user" "test" { + user_principal_name = "acctestAppOwner.%[1]d@${data.azuread_domains.test.domains.0.domain_name}" + display_name = "acctestAppOwner-%[1]d" + password = "%[2]s" +} + +resource "azuread_application_owner" "test" { + application_id = azuread_application_registration.test.id + owner_object_id = azuread_user.test.object_id +} +`, data.RandomInteger, data.RandomPassword) +} + +func (ApplicationOwnerResource) multiple(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +data "azuread_domains" "test" { + only_initial = true +} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} + +resource "azuread_user" "test" { + user_principal_name = "acctestAppOwner.%[1]d@${data.azuread_domains.test.domains.0.domain_name}" + display_name = "acctestAppOwner-%[1]d" + password = "%[2]s" +} + +resource "azuread_user" "test2" { + user_principal_name = "acctestAppOwner2.%[1]d@${data.azuread_domains.test.domains.0.domain_name}" + display_name = "acctestAppOwner2-%[1]d" + password = "%[2]s" +} + +resource "azuread_application_owner" "test" { + application_id = azuread_application_registration.test.id + owner_object_id = azuread_user.test.object_id +} + +resource "azuread_application_owner" "test2" { + application_id = azuread_application_registration.test.id + owner_object_id = azuread_user.test2.object_id +} +`, data.RandomInteger, data.RandomPassword) +} + +func (ApplicationOwnerResource) requiresImport(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +data "azuread_domains" "test" { + only_initial = true +} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} + +resource "azuread_user" "test" { + user_principal_name = "acctestAppOwner.%[1]d@${data.azuread_domains.test.domains.0.domain_name}" + display_name = "acctestAppOwner-%[1]d" + password = "%[2]s" +} + +resource "azuread_application_owner" "test" { + application_id = azuread_application_registration.test.id + owner_object_id = azuread_user.test.object_id +} + +resource "azuread_application_owner" "import" { + application_id = azuread_application_owner.test.application_id + owner_object_id = azuread_application_owner.test.owner_object_id +} +`, data.RandomInteger, data.RandomPassword) +} diff --git a/internal/services/applications/parse/owner.go b/internal/services/applications/parse/owner.go new file mode 100644 index 0000000000..3a0082a260 --- /dev/null +++ b/internal/services/applications/parse/owner.go @@ -0,0 +1,77 @@ +package parse + +import ( + "fmt" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/hashicorp/terraform-provider-azuread/internal/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 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 B 2 C Directory 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) +} diff --git a/internal/services/applications/registration.go b/internal/services/applications/registration.go index ced6b74a71..8b21c2c382 100644 --- a/internal/services/applications/registration.go +++ b/internal/services/applications/registration.go @@ -52,6 +52,7 @@ func (r Registration) Resources() []sdk.Resource { return []sdk.Resource{ ApplicationAppRoleResource{}, ApplicationFallbackPublicClientResource{}, + ApplicationOwnerResource{}, ApplicationPermissionScopeResource{}, ApplicationRegistrationResource{}, } From 7092d33895ca168855f5e4339a0e83db827c8fa3 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Oct 2023 16:15:57 +0100 Subject: [PATCH 10/46] New Resource: `azuread_application_identifier_uri` --- .../application_identifier_uri_resource.go | 252 ++++++++++++++++++ ...pplication_identifier_uri_resource_test.go | 172 ++++++++++++ .../applications/parse/identifier_uri.go | 76 ++++++ .../services/applications/registration.go | 1 + 4 files changed, 501 insertions(+) create mode 100644 internal/services/applications/application_identifier_uri_resource.go create mode 100644 internal/services/applications/application_identifier_uri_resource_test.go create mode 100644 internal/services/applications/parse/identifier_uri.go diff --git a/internal/services/applications/application_identifier_uri_resource.go b/internal/services/applications/application_identifier_uri_resource.go new file mode 100644 index 0000000000..b70a1917da --- /dev/null +++ b/internal/services/applications/application_identifier_uri_resource.go @@ -0,0 +1,252 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications + +import ( + "context" + "encoding/base64" + "fmt" + "github.com/manicminer/hamilton/msgraph" + "net/http" + "time" + + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/terraform-provider-azuread/internal/sdk" + "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" + "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" +) + +type ApplicationIdentifierUriModel struct { + ApplicationId string `tfschema:"application_id"` + IdentifierUri string `tfschema:"identifier_uri"` +} + +type ApplicationIdentifierUriResource struct{} + +func (r ApplicationIdentifierUriResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return parse.ValidateIdentifierUriID +} + +var _ sdk.Resource = ApplicationIdentifierUriResource{} + +func (r ApplicationIdentifierUriResource) ResourceType() string { + return "azuread_application_identifier_uri" +} + +func (r ApplicationIdentifierUriResource) ModelObject() interface{} { + return &ApplicationIdentifierUriModel{} +} + +func (r ApplicationIdentifierUriResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "application_id": { + Description: "The resource ID of the application to which the identifier URI should be added", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: parse.ValidateApplicationID, + }, + + "identifier_uri": { + Description: "The user-defined URI that uniquely identifies an application within its Azure AD tenant, or within a verified custom domain if the application is multi-tenant", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.IsAppUri, + }, + } +} + +func (r ApplicationIdentifierUriResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r ApplicationIdentifierUriResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + var model ApplicationIdentifierUriModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + applicationId, err := parse.ParseApplicationID(model.ApplicationId) + if err != nil { + return err + } + + identifierUriSegment := base64.StdEncoding.EncodeToString([]byte(model.IdentifierUri)) + id := parse.NewIdentifierUriID(applicationId.ApplicationId, identifierUriSegment) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + result, _, err := client.Get(ctx, applicationId.ApplicationId, odata.Query{}) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", applicationId, err) + } + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", applicationId) + } + + newIdentifierUris := make([]string, 0) + + // Don't forget any existing identifier URIs, since they must be updated together + if result.IdentifierUris != nil { + newIdentifierUris = *result.IdentifierUris + } + + // Check for existing identifier URI + for _, uri := range newIdentifierUris { + if uri == model.IdentifierUri { + return metadata.ResourceRequiresImport(r.ResourceType(), id) + } + } + + newIdentifierUris = append(newIdentifierUris, model.IdentifierUri) + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &id.ApplicationId, + }, + IdentifierUris: &newIdentifierUris, + } + + if _, err = client.Update(ctx, properties); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r ApplicationIdentifierUriResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseIdentifierUriID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + uriFromIdSegment, err := base64.StdEncoding.DecodeString(id.IdentifierUri) + if err != nil { + return fmt.Errorf("failed to decode identifierUri from resource ID: %+v", err) + } + + applicationId := parse.NewApplicationID(id.ApplicationId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", id) + } + if result.IdentifierUris == nil { + return metadata.MarkAsGone(id) + } + + // Match the identifier URI + var identifierUri *string + for _, existingUri := range *result.IdentifierUris { + if existingUri == string(uriFromIdSegment) { + identifierUri = &existingUri + break + } + } + + if identifierUri == nil { + return metadata.MarkAsGone(id) + } + + state := ApplicationIdentifierUriModel{ + ApplicationId: applicationId.ID(), + IdentifierUri: *identifierUri, + } + + return metadata.Encode(&state) + }, + } +} + +func (r ApplicationIdentifierUriResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseIdentifierUriID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var model ApplicationIdentifierUriModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + applicationId := parse.NewApplicationID(id.ApplicationId) + result, _, err := client.Get(ctx, applicationId.ApplicationId, odata.Query{}) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", applicationId, err) + } + if result == nil || result.IdentifierUris == nil { + return fmt.Errorf("retrieving %s: identifierUris was nil", applicationId) + } + + // Look for the identifier URI to remove + newIdentifierUris := make([]string, 0) + found := false + for _, existingUri := range *result.IdentifierUris { + if existingUri == model.IdentifierUri { + found = true + } else { + newIdentifierUris = append(newIdentifierUris, existingUri) + } + } + if !found { + return fmt.Errorf("deleting %s: could not identify existing identifier URI", id) + } + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &applicationId.ApplicationId, + }, + IdentifierUris: &newIdentifierUris, + } + + // Patch the application with the new set of identifier URIs + _, err = client.Update(ctx, properties) + if err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + + return nil + }, + } +} diff --git a/internal/services/applications/application_identifier_uri_resource_test.go b/internal/services/applications/application_identifier_uri_resource_test.go new file mode 100644 index 0000000000..d00a7bc277 --- /dev/null +++ b/internal/services/applications/application_identifier_uri_resource_test.go @@ -0,0 +1,172 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications_test + +import ( + "context" + "encoding/base64" + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "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/services/applications/parse" +) + +type ApplicationIdentifierUriResource struct{} + +func TestAccApplicationIdentifierUri_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_identifier_uri", "test") + r := ApplicationIdentifierUriResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + 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("identifier_uri").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationIdentifierUri_multiple(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_identifier_uri", "test") + data2 := acceptance.BuildTestData(t, "azuread_application_identifier_uri", "test2") + r := ApplicationIdentifierUriResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.multiple(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("identifier_uri").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).Key("identifier_uri").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + }) +} + +func TestAccApplicationIdentifierUri_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_identifier_uri", "test") + r := ApplicationIdentifierUriResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + 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("identifier_uri").Exists(), + ), + }, + data.RequiresImportErrorStep(r.requiresImport(data)), + }) +} + +func (r ApplicationIdentifierUriResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { + client := clients.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseIdentifierUriID(state.ID) + if err != nil { + return nil, err + } + + uriFromIdSegment, err := base64.StdEncoding.DecodeString(id.IdentifierUri) + if err != nil { + return nil, fmt.Errorf("failed to decode identifierUri from resource ID: %+v", err) + } + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return pointer.To(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return nil, fmt.Errorf("retrieving %s: result was nil", id) + } + + if result.IdentifierUris == nil { + return pointer.To(false), nil + } + + for _, existingUri := range *result.IdentifierUris { + if existingUri == string(uriFromIdSegment) { + return pointer.To(true), nil + } + } + + return pointer.To(false), nil +} + +func (ApplicationIdentifierUriResource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} + +resource "azuread_application_identifier_uri" "test" { + application_id = azuread_application_registration.test.id + identifier_uri = "api://hashicorptestapp-%[1]d" +} +`, data.RandomInteger) +} + +func (ApplicationIdentifierUriResource) multiple(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} + +resource "azuread_application_identifier_uri" "test" { + application_id = azuread_application_registration.test.id + identifier_uri = "api://hashicorptestapp-%[1]d" +} + +resource "azuread_application_identifier_uri" "test2" { + application_id = azuread_application_registration.test.id + identifier_uri = "api://${azuread_application_registration.test.client_id}" +} +`, data.RandomInteger) +} + +func (ApplicationIdentifierUriResource) requiresImport(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-AppRegistration-%[1]d" +} + +resource "azuread_application_identifier_uri" "test" { + application_id = azuread_application_registration.test.id + identifier_uri = "api://hashicorptestapp-%[1]d" +} + +resource "azuread_application_identifier_uri" "import" { + application_id = azuread_application_identifier_uri.test.application_id + identifier_uri = azuread_application_identifier_uri.test.identifier_uri +} +`, data.RandomInteger, data.RandomID) +} diff --git a/internal/services/applications/parse/identifier_uri.go b/internal/services/applications/parse/identifier_uri.go new file mode 100644 index 0000000000..93c21972eb --- /dev/null +++ b/internal/services/applications/parse/identifier_uri.go @@ -0,0 +1,76 @@ +package parse + +import ( + "fmt" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +type IdentifierUriId struct { + ApplicationId string + IdentifierUri string +} + +func NewIdentifierUriID(applicationId, identifierUri string) IdentifierUriId { + return IdentifierUriId{ + ApplicationId: applicationId, + IdentifierUri: identifierUri, + } +} + +// ParseIdentifierUriID parses 'input' into an IdentifierUriId +func ParseIdentifierUriID(input string) (*IdentifierUriId, error) { + parser := resourceids.NewParserFromResourceIdType(IdentifierUriId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := IdentifierUriId{} + + if id.ApplicationId, ok = parsed.Parsed["applicationId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "applicationId", *parsed) + } + + if id.IdentifierUri, ok = parsed.Parsed["identifierUri"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "identifierUri", *parsed) + } + + return &id, nil +} + +// ValidateIdentifierUriID checks that 'input' can be parsed as an Application ID +func ValidateIdentifierUriID(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 + } + + if _, err := ParseIdentifierUriID(v); err != nil { + errors = append(errors, err) + return + } + + return +} + +func (id IdentifierUriId) ID() string { + fmtString := "/applications/%s/identifierUris/%s" + return fmt.Sprintf(fmtString, id.ApplicationId, id.IdentifierUri) +} + +// Segments returns a slice of Resource ID Segments which comprise this B 2 C Directory ID +func (id IdentifierUriId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("applications", "applications", "applications"), + resourceids.UserSpecifiedSegment("applicationId", "00000000-0000-0000-0000-000000000000"), + resourceids.StaticSegment("identifierUris", "identifierUris", "identifierUris"), + resourceids.UserSpecifiedSegment("identifierUri", "aHR0cHM6Ly9leGFtcGxlLm5ldC8="), + } +} + +func (id IdentifierUriId) String() string { + return fmt.Sprintf("Application IdentifierUri (Application ID: %q, IdentifierUri ID: %q)", id.ApplicationId, id.IdentifierUri) +} diff --git a/internal/services/applications/registration.go b/internal/services/applications/registration.go index 8b21c2c382..d54651d080 100644 --- a/internal/services/applications/registration.go +++ b/internal/services/applications/registration.go @@ -52,6 +52,7 @@ func (r Registration) Resources() []sdk.Resource { return []sdk.Resource{ ApplicationAppRoleResource{}, ApplicationFallbackPublicClientResource{}, + ApplicationIdentifierUriResource{}, ApplicationOwnerResource{}, ApplicationPermissionScopeResource{}, ApplicationRegistrationResource{}, From a1ae108e85127bb1c2e89b30489753b914cabf12 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Tue, 17 Oct 2023 16:16:12 +0100 Subject: [PATCH 11/46] Fix bug in new ID validators --- .../applications/application_owner_resource.go | 14 +++++++------- .../application_owner_resource_test.go | 2 +- internal/services/applications/parse/app_role.go | 1 + .../services/applications/parse/application.go | 1 + .../applications/parse/fallback_public_client.go | 1 + internal/services/applications/parse/owner.go | 13 +++++++------ .../applications/parse/permission_scope.go | 1 + 7 files changed, 19 insertions(+), 14 deletions(-) diff --git a/internal/services/applications/application_owner_resource.go b/internal/services/applications/application_owner_resource.go index a31ecc1715..b6128d5834 100644 --- a/internal/services/applications/application_owner_resource.go +++ b/internal/services/applications/application_owner_resource.go @@ -42,7 +42,7 @@ func (r ApplicationOwnerResource) ModelObject() interface{} { func (r ApplicationOwnerResource) Arguments() map[string]*pluginsdk.Schema { return map[string]*pluginsdk.Schema{ "application_id": { - Description: "The resource ID of the application to which the fallback public client setting should be applied", + Description: "The resource ID of the application to which the owner should be added", Type: pluginsdk.TypeString, Required: true, ForceNew: true, @@ -86,7 +86,7 @@ func (r ApplicationOwnerResource) Create() sdk.ResourceFunc { tf.LockByName(applicationResourceName, id.ApplicationId) defer tf.UnlockByName(applicationResourceName, id.ApplicationId) - _, status, err := client.GetOwner(ctx, id.ApplicationId, id.OwnerID) + _, status, err := client.GetOwner(ctx, id.ApplicationId, id.OwnerId) if err != nil && status != http.StatusNotFound { return fmt.Errorf("checking for presence of existing %s: %+v", id, err) } @@ -95,14 +95,14 @@ func (r ApplicationOwnerResource) Create() sdk.ResourceFunc { } // Construct an @odata.id for the $ref endpoint - odataId := (odata.Id)(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, metadata.Client.TenantID, id.OwnerID)) + odataId := (odata.Id)(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, metadata.Client.TenantID, id.OwnerId)) properties := &msgraph.Application{ DirectoryObject: msgraph.DirectoryObject{ Id: &id.ApplicationId, }, Owners: &msgraph.Owners{{ - Id: &id.OwnerID, + Id: &id.OwnerId, ODataId: &odataId, }}, } @@ -135,7 +135,7 @@ func (r ApplicationOwnerResource) Read() sdk.ResourceFunc { tf.LockByName(applicationResourceName, id.ApplicationId) defer tf.UnlockByName(applicationResourceName, id.ApplicationId) - result, status, err := client.GetOwner(ctx, id.ApplicationId, id.OwnerID) + result, status, err := client.GetOwner(ctx, id.ApplicationId, id.OwnerId) if err != nil { if status == http.StatusNotFound { return metadata.MarkAsGone(id) @@ -148,7 +148,7 @@ func (r ApplicationOwnerResource) Read() sdk.ResourceFunc { state := ApplicationOwnerModel{ ApplicationId: applicationId.ID(), - OwnerObjectId: id.OwnerID, + OwnerObjectId: id.OwnerId, } return metadata.Encode(&state) @@ -172,7 +172,7 @@ func (r ApplicationOwnerResource) Delete() sdk.ResourceFunc { tf.LockByName(applicationResourceName, id.ApplicationId) defer tf.UnlockByName(applicationResourceName, id.ApplicationId) - _, err = client.RemoveOwners(ctx, id.ApplicationId, &[]string{id.OwnerID}) + _, err = client.RemoveOwners(ctx, id.ApplicationId, &[]string{id.OwnerId}) if err != nil { return fmt.Errorf("removing %s: %+v", id, err) } diff --git a/internal/services/applications/application_owner_resource_test.go b/internal/services/applications/application_owner_resource_test.go index 141f7480e9..d1828a2ee0 100644 --- a/internal/services/applications/application_owner_resource_test.go +++ b/internal/services/applications/application_owner_resource_test.go @@ -85,7 +85,7 @@ func (r ApplicationOwnerResource) Exists(ctx context.Context, clients *clients.C return nil, err } - result, status, err := client.GetOwner(ctx, id.ApplicationId, id.OwnerID) + result, status, err := client.GetOwner(ctx, id.ApplicationId, id.OwnerId) if err != nil { if status == http.StatusNotFound { return pointer.To(false), nil diff --git a/internal/services/applications/parse/app_role.go b/internal/services/applications/parse/app_role.go index a6653a0134..4d9d4cfa03 100644 --- a/internal/services/applications/parse/app_role.go +++ b/internal/services/applications/parse/app_role.go @@ -52,6 +52,7 @@ func ValidateAppRoleID(input interface{}, key string) (warnings []string, errors id, err := ParseAppRoleID(v) if err != nil { errors = append(errors, err) + return } return validation.IsUUID(id.RoleID, "ID") diff --git a/internal/services/applications/parse/application.go b/internal/services/applications/parse/application.go index 529fde22f9..dc4518a19a 100644 --- a/internal/services/applications/parse/application.go +++ b/internal/services/applications/parse/application.go @@ -46,6 +46,7 @@ func ValidateApplicationID(input interface{}, key string) (warnings []string, er id, err := ParseApplicationID(v) if err != nil { errors = append(errors, err) + return } return validation.IsUUID(id.ApplicationId, "ID") diff --git a/internal/services/applications/parse/fallback_public_client.go b/internal/services/applications/parse/fallback_public_client.go index 6900796847..e3455446e0 100644 --- a/internal/services/applications/parse/fallback_public_client.go +++ b/internal/services/applications/parse/fallback_public_client.go @@ -46,6 +46,7 @@ func ValidateFallbackPublicClientID(input interface{}, key string) (warnings []s id, err := ParseFallbackPublicClientID(v) if err != nil { errors = append(errors, err) + return } return validation.IsUUID(id.ApplicationId, "ID") diff --git a/internal/services/applications/parse/owner.go b/internal/services/applications/parse/owner.go index 3a0082a260..6c04b6b968 100644 --- a/internal/services/applications/parse/owner.go +++ b/internal/services/applications/parse/owner.go @@ -9,13 +9,13 @@ import ( type OwnerId struct { ApplicationId string - OwnerID string + OwnerId string } func NewOwnerID(applicationId, ownerId string) OwnerId { return OwnerId{ ApplicationId: applicationId, - OwnerID: ownerId, + OwnerId: ownerId, } } @@ -34,7 +34,7 @@ func ParseOwnerID(input string) (*OwnerId, error) { return nil, resourceids.NewSegmentNotSpecifiedError(id, "applicationId", *parsed) } - if id.OwnerID, ok = parsed.Parsed["ownerId"]; !ok { + if id.OwnerId, ok = parsed.Parsed["ownerId"]; !ok { return nil, resourceids.NewSegmentNotSpecifiedError(id, "ownerId", *parsed) } @@ -52,14 +52,15 @@ func ValidateOwnerID(input interface{}, key string) (warnings []string, errors [ id, err := ParseOwnerID(v) if err != nil { errors = append(errors, err) + return } - return validation.IsUUID(id.OwnerID, "ID") + return validation.IsUUID(id.OwnerId, "ID") } func (id OwnerId) ID() string { fmtString := "/applications/%s/owners/%s" - return fmt.Sprintf(fmtString, id.ApplicationId, id.OwnerID) + return fmt.Sprintf(fmtString, id.ApplicationId, id.OwnerId) } // Segments returns a slice of Resource ID Segments which comprise this B 2 C Directory ID @@ -73,5 +74,5 @@ func (id OwnerId) Segments() []resourceids.Segment { } func (id OwnerId) String() string { - return fmt.Sprintf("Application Owner (Application ID: %q, Owner ID: %q)", id.ApplicationId, id.OwnerID) + return fmt.Sprintf("Application Owner (Application ID: %q, Owner ID: %q)", id.ApplicationId, id.OwnerId) } diff --git a/internal/services/applications/parse/permission_scope.go b/internal/services/applications/parse/permission_scope.go index 149a678302..173ae1dd70 100644 --- a/internal/services/applications/parse/permission_scope.go +++ b/internal/services/applications/parse/permission_scope.go @@ -52,6 +52,7 @@ func ValidatePermissionScopeID(input interface{}, key string) (warnings []string id, err := ParsePermissionScopeID(v) if err != nil { errors = append(errors, err) + return } return validation.IsUUID(id.ScopeID, "ID") From d232e07226fb16f98059333cc5e3ef2b867f2339 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 18 Oct 2023 00:02:11 +0100 Subject: [PATCH 12/46] Fix up comments --- internal/services/applications/parse/app_role.go | 2 +- internal/services/applications/parse/application.go | 2 +- internal/services/applications/parse/fallback_public_client.go | 2 +- internal/services/applications/parse/identifier_uri.go | 2 +- internal/services/applications/parse/owner.go | 2 +- internal/services/applications/parse/permission_scope.go | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/services/applications/parse/app_role.go b/internal/services/applications/parse/app_role.go index 4d9d4cfa03..c18c71f28e 100644 --- a/internal/services/applications/parse/app_role.go +++ b/internal/services/applications/parse/app_role.go @@ -63,7 +63,7 @@ func (id AppRoleId) ID() string { return fmt.Sprintf(fmtString, id.ApplicationId, id.RoleID) } -// Segments returns a slice of Resource ID Segments which comprise this B 2 C Directory ID +// Segments returns a slice of Resource ID Segments which comprise this ID func (id AppRoleId) Segments() []resourceids.Segment { return []resourceids.Segment{ resourceids.StaticSegment("applications", "applications", "applications"), diff --git a/internal/services/applications/parse/application.go b/internal/services/applications/parse/application.go index dc4518a19a..95ba467043 100644 --- a/internal/services/applications/parse/application.go +++ b/internal/services/applications/parse/application.go @@ -57,7 +57,7 @@ func (id ApplicationId) ID() string { return fmt.Sprintf(fmtString, id.ApplicationId) } -// Segments returns a slice of Resource ID Segments which comprise this B 2 C Directory ID +// 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"), diff --git a/internal/services/applications/parse/fallback_public_client.go b/internal/services/applications/parse/fallback_public_client.go index e3455446e0..7feb1daf5d 100644 --- a/internal/services/applications/parse/fallback_public_client.go +++ b/internal/services/applications/parse/fallback_public_client.go @@ -57,7 +57,7 @@ func (id FallbackPublicClientId) ID() string { return fmt.Sprintf(fmtString, id.ApplicationId) } -// Segments returns a slice of Resource ID Segments which comprise this B 2 C Directory ID +// Segments returns a slice of Resource ID Segments which comprise this ID func (id FallbackPublicClientId) Segments() []resourceids.Segment { return []resourceids.Segment{ resourceids.StaticSegment("applications", "applications", "applications"), diff --git a/internal/services/applications/parse/identifier_uri.go b/internal/services/applications/parse/identifier_uri.go index 93c21972eb..4d1c1b7772 100644 --- a/internal/services/applications/parse/identifier_uri.go +++ b/internal/services/applications/parse/identifier_uri.go @@ -61,7 +61,7 @@ func (id IdentifierUriId) ID() string { return fmt.Sprintf(fmtString, id.ApplicationId, id.IdentifierUri) } -// Segments returns a slice of Resource ID Segments which comprise this B 2 C Directory ID +// Segments returns a slice of Resource ID Segments which comprise this ID func (id IdentifierUriId) Segments() []resourceids.Segment { return []resourceids.Segment{ resourceids.StaticSegment("applications", "applications", "applications"), diff --git a/internal/services/applications/parse/owner.go b/internal/services/applications/parse/owner.go index 6c04b6b968..7b16b58540 100644 --- a/internal/services/applications/parse/owner.go +++ b/internal/services/applications/parse/owner.go @@ -63,7 +63,7 @@ func (id OwnerId) ID() string { return fmt.Sprintf(fmtString, id.ApplicationId, id.OwnerId) } -// Segments returns a slice of Resource ID Segments which comprise this B 2 C Directory ID +// 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"), diff --git a/internal/services/applications/parse/permission_scope.go b/internal/services/applications/parse/permission_scope.go index 173ae1dd70..28767f3c1b 100644 --- a/internal/services/applications/parse/permission_scope.go +++ b/internal/services/applications/parse/permission_scope.go @@ -63,7 +63,7 @@ func (id PermissionScopeId) ID() string { return fmt.Sprintf(fmtString, id.ApplicationId, id.ScopeID) } -// Segments returns a slice of Resource ID Segments which comprise this B 2 C Directory ID +// Segments returns a slice of Resource ID Segments which comprise this ID func (id PermissionScopeId) Segments() []resourceids.Segment { return []resourceids.Segment{ resourceids.StaticSegment("applications", "applications", "applications"), From 2fca6ae1b24339429eaf3ac8f0d2e8287804cf20 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 18 Oct 2023 00:02:55 +0100 Subject: [PATCH 13/46] New Resource: `azuread_application_api_access` --- .../application_api_access_resource.go | 379 ++++++++++++++++++ .../application_api_access_resource_test.go | 311 ++++++++++++++ .../services/applications/parse/api_access.go | 78 ++++ .../services/applications/registration.go | 1 + 4 files changed, 769 insertions(+) create mode 100644 internal/services/applications/application_api_access_resource.go create mode 100644 internal/services/applications/application_api_access_resource_test.go create mode 100644 internal/services/applications/parse/api_access.go diff --git a/internal/services/applications/application_api_access_resource.go b/internal/services/applications/application_api_access_resource.go new file mode 100644 index 0000000000..cef619b4a8 --- /dev/null +++ b/internal/services/applications/application_api_access_resource.go @@ -0,0 +1,379 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications + +import ( + "context" + "fmt" + "net/http" + "strings" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/terraform-provider-azuread/internal/sdk" + "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" + "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" +) + +type ApplicationApiAccessModel struct { + ApplicationId string `tfschema:"application_id"` + ApiClientId string `tfschema:"api_client_id"` + Permission []ApplicationApiAccessPermission `tfschema:"permission"` +} + +type ApplicationApiAccessPermission struct { + Id string `tfschema:"id"` + Type string `tfschema:"type"` +} + +type ApplicationApiAccessResource struct{} + +func (r ApplicationApiAccessResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return parse.ValidateApiAccessID +} + +var _ sdk.ResourceWithUpdate = ApplicationApiAccessResource{} + +func (r ApplicationApiAccessResource) ResourceType() string { + return "azuread_application_api_access" +} + +func (r ApplicationApiAccessResource) ModelObject() interface{} { + return &ApplicationApiAccessModel{} +} + +func (r ApplicationApiAccessResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "application_id": { + Description: "The resource ID of the application to which this API access is granted", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: parse.ValidateApplicationID, + }, + + "api_client_id": { + Description: "The client ID of the API to which access is being granted", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.IsUUID, + }, + + "permission": { + Description: "A list of permission IDs and their types that are being granted to the application", + Type: pluginsdk.TypeSet, + Required: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "id": { + Description: "The ID of the app role or permission scope which is being granted", + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.IsUUID, + }, + + "type": { + Description: "The type of permission being granted", + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice( + []string{ + msgraph.ResourceAccessTypeRole, + msgraph.ResourceAccessTypeScope, + }, + false, + ), + }, + }, + }, + }, + } +} + +func (r ApplicationApiAccessResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r ApplicationApiAccessResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + var model ApplicationApiAccessModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + applicationId, err := parse.ParseApplicationID(model.ApplicationId) + if err != nil { + return err + } + + id := parse.NewApiAccessID(applicationId.ApplicationId, model.ApiClientId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + result, _, err := client.Get(ctx, applicationId.ApplicationId, odata.Query{}) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", applicationId, err) + } + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", applicationId) + } + + newApis := make([]msgraph.RequiredResourceAccess, 0) + + // Don't forget any existing APIs, since they must all be updated together + if result.RequiredResourceAccess != nil { + newApis = *result.RequiredResourceAccess + } + + // Check for existing API + for _, api := range newApis { + if strings.EqualFold(*api.ResourceAppId, id.ApiClientId) { + return metadata.ResourceRequiresImport(r.ResourceType(), id) + } + } + + permissions := make([]msgraph.ResourceAccess, 0) + for _, permission := range model.Permission { + permissions = append(permissions, msgraph.ResourceAccess{ + ID: pointer.To(permission.Id), + Type: permission.Type, + }) + } + + newApis = append(newApis, msgraph.RequiredResourceAccess{ + ResourceAppId: &model.ApiClientId, + ResourceAccess: &permissions, + }) + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &id.ApplicationId, + }, + RequiredResourceAccess: &newApis, + } + + if _, err = client.Update(ctx, properties); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r ApplicationApiAccessResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseApiAccessID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + applicationId := parse.NewApplicationID(id.ApplicationId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", id) + } + if result.RequiredResourceAccess == nil { + return metadata.MarkAsGone(id) + } + + // Identify the API + var api *msgraph.RequiredResourceAccess + for _, existingApi := range *result.RequiredResourceAccess { + if strings.EqualFold(*existingApi.ResourceAppId, id.ApiClientId) { + api = &existingApi + break + } + } + + if api == nil { + return metadata.MarkAsGone(id) + } + if api.ResourceAccess == nil { + return fmt.Errorf("retrieving %s: resourceAccess was nil", id) + } + + permissions := make([]ApplicationApiAccessPermission, 0) + for _, permission := range *api.ResourceAccess { + permissions = append(permissions, ApplicationApiAccessPermission{ + Id: pointer.From(permission.ID), + Type: permission.Type, + }) + } + + state := ApplicationApiAccessModel{ + ApplicationId: applicationId.ID(), + ApiClientId: pointer.From(api.ResourceAppId), + Permission: permissions, + } + + return metadata.Encode(&state) + }, + } +} + +func (r ApplicationApiAccessResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + + id, err := parse.ParseApiAccessID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var model ApplicationApiAccessModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + // Prepare a new API to replace the existing one + permissions := make([]msgraph.ResourceAccess, 0) + for _, permission := range model.Permission { + permissions = append(permissions, msgraph.ResourceAccess{ + ID: pointer.To(permission.Id), + Type: permission.Type, + }) + } + api := msgraph.RequiredResourceAccess{ + ResourceAppId: &model.ApiClientId, + ResourceAccess: &permissions, + } + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + applicationId := parse.NewApplicationID(id.ApplicationId) + result, _, err := client.Get(ctx, applicationId.ApplicationId, odata.Query{}) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", applicationId, err) + } + if result == nil || result.RequiredResourceAccess == nil { + return fmt.Errorf("retrieving %s: requiredResourceAccess was nil", applicationId) + } + + // Look for an API to replace + newApis := make([]msgraph.RequiredResourceAccess, 0) + found := false + for _, existingApi := range *result.RequiredResourceAccess { + if strings.EqualFold(*existingApi.ResourceAppId, id.ApiClientId) { + newApis = append(newApis, api) + found = true + } else { + newApis = append(newApis, existingApi) + } + } + if !found { + return fmt.Errorf("updating %s: could not identify existing API", id) + } + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &applicationId.ApplicationId, + }, + RequiredResourceAccess: &newApis, + } + + // Patch the application with the new set of APIs + _, err = client.Update(ctx, properties) + if err != nil { + return fmt.Errorf("updating %s: %+v", id, err) + } + + return nil + }, + } +} + +func (r ApplicationApiAccessResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseApiAccessID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var model ApplicationApiAccessModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + applicationId := parse.NewApplicationID(id.ApplicationId) + result, _, err := client.Get(ctx, applicationId.ApplicationId, odata.Query{}) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", applicationId, err) + } + if result == nil || result.RequiredResourceAccess == nil { + return fmt.Errorf("retrieving %s: requiredResourceAccess was nil", applicationId) + } + + // Look for an API to remove + newApis := make([]msgraph.RequiredResourceAccess, 0) + found := false + for _, existingApi := range *result.RequiredResourceAccess { + if strings.EqualFold(*existingApi.ResourceAppId, id.ApiClientId) { + found = true + } else { + newApis = append(newApis, existingApi) + } + } + if !found { + return fmt.Errorf("deleting %s: could not identify existing API", id) + } + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &applicationId.ApplicationId, + }, + RequiredResourceAccess: &newApis, + } + + // Patch the application with the new set of APIs + _, err = client.Update(ctx, properties) + if err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + + return nil + }, + } +} diff --git a/internal/services/applications/application_api_access_resource_test.go b/internal/services/applications/application_api_access_resource_test.go new file mode 100644 index 0000000000..a7228d7694 --- /dev/null +++ b/internal/services/applications/application_api_access_resource_test.go @@ -0,0 +1,311 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications_test + +import ( + "context" + "fmt" + "net/http" + "strings" + "testing" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/terraform-plugin-testing/terraform" + "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/services/applications/parse" +) + +type ApplicationApiAccessResource struct{} + +func TestAccApplicationApiAccess_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_api_access", "test") + r := ApplicationApiAccessResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + 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("api_client_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationApiAccess_multiple(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_api_access", "test") + data2 := acceptance.BuildTestData(t, "azuread_application_api_access", "test2") + r := ApplicationApiAccessResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.multiple(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("api_client_id").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).Key("api_client_id").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + }) +} + +func TestAccApplicationApiAccess_multipleUpdate(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_api_access", "test") + data2 := acceptance.BuildTestData(t, "azuread_application_api_access", "test2") + r := ApplicationApiAccessResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.multiple(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("api_client_id").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).Key("api_client_id").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + { + Config: r.multipleUpdate(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("api_client_id").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).Key("api_client_id").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + { + Config: r.multiple(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("api_client_id").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).Key("api_client_id").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + }) +} + +func TestAccApplicationApiAccess_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_api_access", "test") + r := ApplicationApiAccessResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + 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("api_client_id").Exists(), + ), + }, + data.RequiresImportErrorStep(r.requiresImport(data)), + }) +} + +func (r ApplicationApiAccessResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { + client := clients.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseApiAccessID(state.ID) + if err != nil { + return nil, err + } + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return pointer.To(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return nil, fmt.Errorf("retrieving %s: result was nil", id) + } + + if result.RequiredResourceAccess == nil { + return pointer.To(false), nil + } + + for _, api := range *result.RequiredResourceAccess { + if strings.EqualFold(*api.ResourceAppId, id.ApiClientId) { + return pointer.To(true), nil + } + } + + return pointer.To(false), nil +} + +func (ApplicationApiAccessResource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-ApiAccess-%[1]d" +} + +resource "azuread_application_api_access" "test" { + application_id = azuread_application_registration.test.id + api_client_id = "00000003-0000-0000-c000-000000000000" + + permission { + id = "9a5d68dd-52b0-4cc2-bd40-abcf44ac3a30" + type = "Role" + } + + permission { + id = "dbb9058a-0e50-45d7-ae91-66909b5d4664" + type = "Role" + } + + permission { + id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" + type = "Scope" + } +} +`, data.RandomInteger, data.RandomPassword) +} + +func (ApplicationApiAccessResource) multiple(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-ApiAccess-%[1]d" +} + +resource "azuread_application_api_access" "test" { + application_id = azuread_application_registration.test.id + api_client_id = "00000003-0000-0000-c000-000000000000" + + permission { + id = "9a5d68dd-52b0-4cc2-bd40-abcf44ac3a30" + type = "Role" + } + + permission { + id = "dbb9058a-0e50-45d7-ae91-66909b5d4664" + type = "Role" + } + + permission { + id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" + type = "Scope" + } +} + +resource "azuread_application_api_access" "test2" { + application_id = azuread_application_registration.test.id + api_client_id = "00000003-0000-0ff1-ce00-000000000000" + + permission { + id = "d13f72ca-a275-4b96-b789-48ebcc4da984" + type = "Role" + } + + permission { + id = "2beb830c-70d1-4f5b-a983-79cbdb0c6c6a" + type = "Scope" + } +} +`, data.RandomInteger, data.RandomPassword) +} + +func (ApplicationApiAccessResource) multipleUpdate(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-ApiAccess-%[1]d" +} + +resource "azuread_application_api_access" "test" { + application_id = azuread_application_registration.test.id + api_client_id = "00000003-0000-0000-c000-000000000000" + + permission { + id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" + type = "Scope" + } +} + +resource "azuread_application_api_access" "test2" { + application_id = azuread_application_registration.test.id + api_client_id = "00000003-0000-0ff1-ce00-000000000000" + + permission { + id = "d13f72ca-a275-4b96-b789-48ebcc4da984" + type = "Role" + } + + permission { + id = "df021288-bdef-4463-88db-98f22de89214" + type = "Role" + } + + permission { + id = "2beb830c-70d1-4f5b-a983-79cbdb0c6c6a" + type = "Scope" + } +} +`, data.RandomInteger, data.RandomPassword) +} + +func (ApplicationApiAccessResource) requiresImport(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-ApiAccess-%[1]d" +} + +resource "azuread_application_api_access" "test" { + application_id = azuread_application_registration.test.id + api_client_id = "00000003-0000-0000-c000-000000000000" + + permission { + id = "9a5d68dd-52b0-4cc2-bd40-abcf44ac3a30" + type = "Role" + } + + permission { + id = "dbb9058a-0e50-45d7-ae91-66909b5d4664" + type = "Role" + } + + permission { + id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" + type = "Scope" + } +} + +resource "azuread_application_api_access" "import" { + application_id = azuread_application_api_access.test.application_id + api_client_id = azuread_application_api_access.test.api_client_id + permission = azuread_application_api_access.test.permission +} +`, data.RandomInteger, data.RandomPassword) +} diff --git a/internal/services/applications/parse/api_access.go b/internal/services/applications/parse/api_access.go new file mode 100644 index 0000000000..4ca019576e --- /dev/null +++ b/internal/services/applications/parse/api_access.go @@ -0,0 +1,78 @@ +package parse + +import ( + "fmt" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/hashicorp/terraform-provider-azuread/internal/tf/validation" +) + +type ApiAccessId struct { + ApplicationId string + ApiClientId string +} + +func NewApiAccessID(applicationId, apiClientId string) ApiAccessId { + return ApiAccessId{ + ApplicationId: applicationId, + ApiClientId: apiClientId, + } +} + +// ParseApiAccessID parses 'input' into an ApiAccessId +func ParseApiAccessID(input string) (*ApiAccessId, error) { + parser := resourceids.NewParserFromResourceIdType(ApiAccessId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := ApiAccessId{} + + if id.ApplicationId, ok = parsed.Parsed["applicationId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "applicationId", *parsed) + } + + if id.ApiClientId, ok = parsed.Parsed["apiClientId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "apiClientId", *parsed) + } + + return &id, nil +} + +// ValidateApiAccessID checks that 'input' can be parsed as an Application ID +func ValidateApiAccessID(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 := ParseApiAccessID(v) + if err != nil { + errors = append(errors, err) + return + } + + return validation.IsUUID(id.ApiClientId, "ID") +} + +func (id ApiAccessId) ID() string { + fmtString := "/applications/%s/apiAccess/%s" + return fmt.Sprintf(fmtString, id.ApplicationId, id.ApiClientId) +} + +// Segments returns a slice of Resource ID Segments which comprise this ID +func (id ApiAccessId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("applications", "applications", "applications"), + resourceids.UserSpecifiedSegment("applicationId", "00000000-0000-0000-0000-000000000000"), + resourceids.StaticSegment("apiAccess", "apiAccess", "apiAccess"), + resourceids.UserSpecifiedSegment("apiClientId", "11111111-1111-1111-1111-111111111111"), + } +} + +func (id ApiAccessId) String() string { + return fmt.Sprintf("Application API Access (Application ID: %q, API Client ID: %q)", id.ApplicationId, id.ApiClientId) +} diff --git a/internal/services/applications/registration.go b/internal/services/applications/registration.go index d54651d080..4ac528ff4b 100644 --- a/internal/services/applications/registration.go +++ b/internal/services/applications/registration.go @@ -50,6 +50,7 @@ func (r Registration) DataSources() []sdk.DataSource { // Resources returns the typed Resources supported by this service func (r Registration) Resources() []sdk.Resource { return []sdk.Resource{ + ApplicationApiAccessResource{}, ApplicationAppRoleResource{}, ApplicationFallbackPublicClientResource{}, ApplicationIdentifierUriResource{}, From c170ef92e06782159e35cf85c712160bd18fec5c Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 18 Oct 2023 00:49:06 +0100 Subject: [PATCH 14/46] New Resource: `azuread_application_known_clients` --- .../application_known_clients_resource.go | 241 ++++++++++++++++++ ...application_known_clients_resource_test.go | 188 ++++++++++++++ .../applications/parse/known_clients.go | 71 ++++++ .../services/applications/registration.go | 1 + 4 files changed, 501 insertions(+) create mode 100644 internal/services/applications/application_known_clients_resource.go create mode 100644 internal/services/applications/application_known_clients_resource_test.go create mode 100644 internal/services/applications/parse/known_clients.go diff --git a/internal/services/applications/application_known_clients_resource.go b/internal/services/applications/application_known_clients_resource.go new file mode 100644 index 0000000000..f977bd0fe8 --- /dev/null +++ b/internal/services/applications/application_known_clients_resource.go @@ -0,0 +1,241 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications + +import ( + "context" + "fmt" + "net/http" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/terraform-provider-azuread/internal/sdk" + "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" + "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" +) + +type ApplicationKnownClientsModel struct { + ApplicationId string `tfschema:"application_id"` + KnownClientIds []string `tfschema:"known_client_ids"` +} + +type ApplicationKnownClientsResource struct{} + +func (r ApplicationKnownClientsResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return parse.ValidateKnownClientsID +} + +var _ sdk.ResourceWithUpdate = ApplicationKnownClientsResource{} + +func (r ApplicationKnownClientsResource) ResourceType() string { + return "azuread_application_known_clients" +} + +func (r ApplicationKnownClientsResource) ModelObject() interface{} { + return &ApplicationKnownClientsModel{} +} + +func (r ApplicationKnownClientsResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "application_id": { + Description: "The resource ID of the application to which this API access is granted", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: parse.ValidateApplicationID, + }, + + "known_client_ids": { + Description: "A list of known client IDs, used for bundling consent if you have a solution that includes an API and a client application", + Type: pluginsdk.TypeSet, + Required: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + ValidateFunc: validation.IsUUID, + }, + }, + } +} + +func (r ApplicationKnownClientsResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r ApplicationKnownClientsResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + var model ApplicationKnownClientsModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + applicationId, err := parse.ParseApplicationID(model.ApplicationId) + if err != nil { + return err + } + + id := parse.NewKnownClientsID(applicationId.ApplicationId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + result, _, err := client.Get(ctx, applicationId.ApplicationId, odata.Query{}) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", applicationId, err) + } + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", applicationId) + } + + // Check for existing known clients + if result.Api != nil && result.Api.KnownClientApplications != nil && len(*result.Api.KnownClientApplications) > 0 { + return metadata.ResourceRequiresImport(r.ResourceType(), id) + } + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &id.ApplicationId, + }, + Api: &msgraph.ApplicationApi{ + KnownClientApplications: pointer.To(model.KnownClientIds), + }, + } + + if _, err = client.Update(ctx, properties); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r ApplicationKnownClientsResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseKnownClientsID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + applicationId := parse.NewApplicationID(id.ApplicationId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", id) + } + if result.Api == nil || result.Api.KnownClientApplications == nil { + return metadata.MarkAsGone(id) + } + + state := ApplicationKnownClientsModel{ + ApplicationId: applicationId.ID(), + KnownClientIds: pointer.From(result.Api.KnownClientApplications), + } + + return metadata.Encode(&state) + }, + } +} + +func (r ApplicationKnownClientsResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + + id, err := parse.ParseKnownClientsID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + applicationId := parse.NewApplicationID(id.ApplicationId) + + var model ApplicationKnownClientsModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &applicationId.ApplicationId, + }, + Api: &msgraph.ApplicationApi{ + KnownClientApplications: pointer.To(model.KnownClientIds), + }, + } + + _, err = client.Update(ctx, properties) + if err != nil { + return fmt.Errorf("updating %s: %+v", id, err) + } + + return nil + }, + } +} + +func (r ApplicationKnownClientsResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseKnownClientsID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + applicationId := parse.NewApplicationID(id.ApplicationId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &applicationId.ApplicationId, + }, + Api: &msgraph.ApplicationApi{ + KnownClientApplications: &[]string{}, + }, + } + + _, err = client.Update(ctx, properties) + if err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + + return nil + }, + } +} diff --git a/internal/services/applications/application_known_clients_resource_test.go b/internal/services/applications/application_known_clients_resource_test.go new file mode 100644 index 0000000000..06fb012667 --- /dev/null +++ b/internal/services/applications/application_known_clients_resource_test.go @@ -0,0 +1,188 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications_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/terraform-plugin-testing/terraform" + "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/services/applications/parse" +) + +type ApplicationKnownClientsResource struct{} + +func TestAccApplicationKnownClients_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_known_clients", "test") + r := ApplicationKnownClientsResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationKnownClients_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_known_clients", "test") + r := ApplicationKnownClientsResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + ), + }, + data.ImportStep(), + { + Config: r.update(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + ), + }, + data.ImportStep(), + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationKnownClients_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_known_clients", "test") + r := ApplicationKnownClientsResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + ), + }, + data.RequiresImportErrorStep(r.requiresImport(data)), + }) +} + +func (r ApplicationKnownClientsResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { + client := clients.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseKnownClientsID(state.ID) + if err != nil { + return nil, err + } + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return pointer.To(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return nil, fmt.Errorf("retrieving %s: result was nil", id) + } + + if result.Api != nil && result.Api.KnownClientApplications != nil && len(*result.Api.KnownClientApplications) > 0 { + return pointer.To(true), nil + } + + return pointer.To(false), nil +} + +func (ApplicationKnownClientsResource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-KnownClients-%[1]d" +} + +resource "azuread_application_registration" "client" { + display_name = "acctest-Client-%[1]d" +} + +resource "azuread_application_registration" "client2" { + display_name = "acctest-Client2-%[1]d" +} + +resource "azuread_application_known_clients" "test" { + application_id = azuread_application_registration.test.id + known_client_ids = [ + azuread_application_registration.client.client_id, + azuread_application_registration.client2.client_id, + ] +} +`, data.RandomInteger, data.RandomPassword) +} + +func (ApplicationKnownClientsResource) update(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-KnownClients-%[1]d" +} + +resource "azuread_application_registration" "client" { + display_name = "acctest-Client-%[1]d" +} + +resource "azuread_application_registration" "client2" { + display_name = "acctest-Client2-%[1]d" +} + +resource "azuread_application_known_clients" "test" { + application_id = azuread_application_registration.test.id + known_client_ids = [ + azuread_application_registration.client2.client_id, + ] +} +`, data.RandomInteger, data.RandomPassword) +} + +func (ApplicationKnownClientsResource) requiresImport(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-KnownClients-%[1]d" +} + +resource "azuread_application_registration" "client" { + display_name = "acctest-Client-%[1]d" +} + +resource "azuread_application_known_clients" "test" { + application_id = azuread_application_registration.test.id + known_client_ids = [azuread_application_registration.client.client_id] +} + +resource "azuread_application_known_clients" "import" { + application_id = azuread_application_known_clients.test.application_id + known_client_ids = azuread_application_known_clients.test.known_client_ids +} +`, data.RandomInteger, data.RandomPassword) +} diff --git a/internal/services/applications/parse/known_clients.go b/internal/services/applications/parse/known_clients.go new file mode 100644 index 0000000000..265d9e1855 --- /dev/null +++ b/internal/services/applications/parse/known_clients.go @@ -0,0 +1,71 @@ +package parse + +import ( + "fmt" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/hashicorp/terraform-provider-azuread/internal/tf/validation" +) + +type KnownClientsId struct { + ApplicationId string +} + +func NewKnownClientsID(applicationId string) KnownClientsId { + return KnownClientsId{ + ApplicationId: applicationId, + } +} + +// ParseKnownClientsID parses 'input' into an KnownClientsId +func ParseKnownClientsID(input string) (*KnownClientsId, error) { + parser := resourceids.NewParserFromResourceIdType(KnownClientsId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := KnownClientsId{} + + if id.ApplicationId, ok = parsed.Parsed["applicationId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "applicationId", *parsed) + } + + return &id, nil +} + +// ValidateKnownClientsID checks that 'input' can be parsed as an Application ID +func ValidateKnownClientsID(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 := ParseKnownClientsID(v) + if err != nil { + errors = append(errors, err) + return + } + + return validation.IsUUID(id.ApplicationId, "ID") +} + +func (id KnownClientsId) ID() string { + fmtString := "/applications/%s/knownClients" + return fmt.Sprintf(fmtString, id.ApplicationId) +} + +// Segments returns a slice of Resource ID Segments which comprise this ID +func (id KnownClientsId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("applications", "applications", "applications"), + resourceids.UserSpecifiedSegment("applicationId", "00000000-0000-0000-0000-000000000000"), + resourceids.StaticSegment("knownClients", "knownClients", "knownClients"), + } +} + +func (id KnownClientsId) String() string { + return fmt.Sprintf("Known Clients (Application ID: %q)", id.ApplicationId) +} diff --git a/internal/services/applications/registration.go b/internal/services/applications/registration.go index 4ac528ff4b..a7bc04dd8c 100644 --- a/internal/services/applications/registration.go +++ b/internal/services/applications/registration.go @@ -54,6 +54,7 @@ func (r Registration) Resources() []sdk.Resource { ApplicationAppRoleResource{}, ApplicationFallbackPublicClientResource{}, ApplicationIdentifierUriResource{}, + ApplicationKnownClientsResource{}, ApplicationOwnerResource{}, ApplicationPermissionScopeResource{}, ApplicationRegistrationResource{}, From f9fa8bcebcf34934ce3ff49cb90c5507d9e734cc Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 18 Oct 2023 01:09:02 +0100 Subject: [PATCH 15/46] azuread_application_registration: remove post-create patch, support `implicit_access_token_issuance_enabled` and `implicit_id_token_issuance_enabled` --- .../application_registration_resource.go | 92 +++++++++++-------- .../application_registration_resource_test.go | 4 +- 2 files changed, 55 insertions(+), 41 deletions(-) diff --git a/internal/services/applications/application_registration_resource.go b/internal/services/applications/application_registration_resource.go index 42b34c3a17..bf77851b15 100644 --- a/internal/services/applications/application_registration_resource.go +++ b/internal/services/applications/application_registration_resource.go @@ -11,7 +11,6 @@ import ( "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" - "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/helpers" "github.com/hashicorp/terraform-provider-azuread/internal/sdk" "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" @@ -23,21 +22,23 @@ import ( ) type ApplicationRegistrationModel struct { - ClientId string `tfschema:"client_id"` - Description string `tfschema:"description"` - DisabledByMicrosoft string `tfschema:"disabled_by_microsoft"` - DisplayName string `tfschema:"display_name"` - HomepageUrl string `tfschema:"homepage_url"` - LogoutUrl string `tfschema:"logout_url"` - MarketingUrl string `tfschema:"marketing_url"` - Notes string `tfschema:"notes"` - PrivacyStatementUrl string `tfschema:"privacy_statement_url"` - PublisherDomain string `tfschema:"publisher_domain"` - RequestedAccessTokenVersion int `tfschema:"requested_access_token_version"` - ServiceManagementReference string `tfschema:"service_management_reference"` - SignInAudience string `tfschema:"sign_in_audience"` - SupportUrl string `tfschema:"support_url"` - TermsOfServiceUrl string `tfschema:"terms_of_service_url"` + ClientId string `tfschema:"client_id"` + Description string `tfschema:"description"` + DisabledByMicrosoft string `tfschema:"disabled_by_microsoft"` + DisplayName string `tfschema:"display_name"` + HomepageUrl string `tfschema:"homepage_url"` + ImplicitAccessTokenIssuanceEnabled bool `tfschema:"implicit_access_token_issuance_enabled"` + ImplicitIdTokenIssuanceEnabled bool `tfschema:"implicit_id_token_issuance_enabled"` + LogoutUrl string `tfschema:"logout_url"` + MarketingUrl string `tfschema:"marketing_url"` + Notes string `tfschema:"notes"` + PrivacyStatementUrl string `tfschema:"privacy_statement_url"` + PublisherDomain string `tfschema:"publisher_domain"` + RequestedAccessTokenVersion int `tfschema:"requested_access_token_version"` + ServiceManagementReference string `tfschema:"service_management_reference"` + SignInAudience string `tfschema:"sign_in_audience"` + SupportUrl string `tfschema:"support_url"` + TermsOfServiceUrl string `tfschema:"terms_of_service_url"` } type ApplicationRegistrationResource struct{} @@ -79,6 +80,18 @@ func (r ApplicationRegistrationResource) Arguments() map[string]*pluginsdk.Schem ValidateFunc: validation.IsHttpOrHttpsUrl, }, + "implicit_access_token_issuance_enabled": { + Description: "Whether this application can request an access token using OAuth implicit flow", + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "implicit_id_token_issuance_enabled": { + Description: "Whether this application can request an ID token using OAuth implicit flow", + Type: pluginsdk.TypeBool, + Optional: true, + }, + "logout_url": { Description: "URL of the logout page for the application, where the session is cleared for single sign-out", Type: pluginsdk.TypeString, @@ -217,6 +230,11 @@ func (r ApplicationRegistrationResource) Create() sdk.ResourceFunc { Web: &msgraph.ApplicationWeb{ HomePageUrl: tf.NullableString(model.HomepageUrl), LogoutUrl: tf.NullableString(model.LogoutUrl), + + ImplicitGrantSettings: &msgraph.ImplicitGrantSettings{ + EnableAccessTokenIssuance: pointer.To(model.ImplicitAccessTokenIssuanceEnabled), + EnableIdTokenIssuance: pointer.To(model.ImplicitIdTokenIssuanceEnabled), + }, }, } @@ -232,29 +250,6 @@ func (r ApplicationRegistrationResource) Create() sdk.ResourceFunc { id := parse.NewApplicationID(*result.ID()) metadata.SetID(id) - // Attempt to patch the newly created application and set the display name, which will tell us whether it exists yet, then set it back to the desired value. - // The SDK handles retries for us here in the event of 404, 429 or 5xx, then returns after giving up. - uuid, err := uuid.GenerateUUID() - if err != nil { - return fmt.Errorf("failed to generate a UUID: %v", err) - } - tempDisplayName := fmt.Sprintf("TERRAFORM_UPDATE_%s", uuid) - for _, displayNameToSet := range []string{tempDisplayName, model.DisplayName} { - // Consistency-related retries are handled by the SDK - status, err := client.Update(ctx, msgraph.Application{ - DirectoryObject: msgraph.DirectoryObject{ - Id: &id.ApplicationId, - }, - DisplayName: utils.String(displayNameToSet), - }) - if err != nil { - if status == http.StatusNotFound { - return fmt.Errorf("timed out whilst waiting for new %s to be replicated in Azure AD", id) - } - return fmt.Errorf("failed to patch %s after creating: %+v", id, err) - } - } - return nil }, } @@ -309,6 +304,11 @@ func (r ApplicationRegistrationResource) Read() sdk.ResourceFunc { if web := result.Web; web != nil { state.HomepageUrl = string(pointer.From(web.HomePageUrl)) state.LogoutUrl = string(pointer.From(web.LogoutUrl)) + + if implicitGrant := web.ImplicitGrantSettings; implicitGrant != nil { + state.ImplicitAccessTokenIssuanceEnabled = pointer.From(implicitGrant.EnableAccessTokenIssuance) + state.ImplicitIdTokenIssuanceEnabled = pointer.From(implicitGrant.EnableIdTokenIssuance) + } } if result.DisabledByMicrosoftStatus != nil { @@ -389,7 +389,7 @@ func (r ApplicationRegistrationResource) Update() sdk.ResourceFunc { } } - if rd.HasChange("homepage_url") || rd.HasChange("logout_url") { + if rd.HasChange("implicit_access_token_issuance_enabled") || rd.HasChange("homepage_url") || rd.HasChange("implicit_id_token_issuance_enabled") || rd.HasChange("logout_url") { properties.Web = &msgraph.ApplicationWeb{} if rd.HasChange("homepage_url") { @@ -399,6 +399,18 @@ func (r ApplicationRegistrationResource) Update() sdk.ResourceFunc { if rd.HasChange("logout_url") { properties.Web.LogoutUrl = tf.NullableString(model.LogoutUrl) } + + if rd.HasChange("implicit_access_token_issuance_enabled") || rd.HasChange("implicit_id_token_issuance_enabled") { + properties.Web.ImplicitGrantSettings = &msgraph.ImplicitGrantSettings{} + + if rd.HasChange("implicit_access_token_issuance_enabled") { + properties.Web.ImplicitGrantSettings.EnableAccessTokenIssuance = pointer.To(model.ImplicitAccessTokenIssuanceEnabled) + } + + if rd.HasChange("implicit_id_token_issuance_enabled") { + properties.Web.ImplicitGrantSettings.EnableIdTokenIssuance = pointer.To(model.ImplicitIdTokenIssuanceEnabled) + } + } } _, err = client.Update(ctx, properties) diff --git a/internal/services/applications/application_registration_resource_test.go b/internal/services/applications/application_registration_resource_test.go index e5f99254a7..6612055ece 100644 --- a/internal/services/applications/application_registration_resource_test.go +++ b/internal/services/applications/application_registration_resource_test.go @@ -124,7 +124,9 @@ resource "azuread_application_registration" "test" { display_name = "acctest-AppRegistration-complete-%[1]d" sign_in_audience = "AzureADandPersonalMicrosoftAccount" - requested_access_token_version = 2 + requested_access_token_version = 2 + implicit_access_token_issuance_enabled = true + implicit_id_token_issuance_enabled = true description = "Acceptance testing application" notes = "Testing application" From 2b05bc6ab3cd37bdea7001372a409467e0b1ec59 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 18 Oct 2023 02:57:45 +0100 Subject: [PATCH 16/46] azuread_application_registration: support `group_membership_claims` --- .../application_registration_resource.go | 57 +++++++++++++------ .../application_registration_resource_test.go | 1 + 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/internal/services/applications/application_registration_resource.go b/internal/services/applications/application_registration_resource.go index bf77851b15..6b112df91f 100644 --- a/internal/services/applications/application_registration_resource.go +++ b/internal/services/applications/application_registration_resource.go @@ -22,23 +22,24 @@ import ( ) type ApplicationRegistrationModel struct { - ClientId string `tfschema:"client_id"` - Description string `tfschema:"description"` - DisabledByMicrosoft string `tfschema:"disabled_by_microsoft"` - DisplayName string `tfschema:"display_name"` - HomepageUrl string `tfschema:"homepage_url"` - ImplicitAccessTokenIssuanceEnabled bool `tfschema:"implicit_access_token_issuance_enabled"` - ImplicitIdTokenIssuanceEnabled bool `tfschema:"implicit_id_token_issuance_enabled"` - LogoutUrl string `tfschema:"logout_url"` - MarketingUrl string `tfschema:"marketing_url"` - Notes string `tfschema:"notes"` - PrivacyStatementUrl string `tfschema:"privacy_statement_url"` - PublisherDomain string `tfschema:"publisher_domain"` - RequestedAccessTokenVersion int `tfschema:"requested_access_token_version"` - ServiceManagementReference string `tfschema:"service_management_reference"` - SignInAudience string `tfschema:"sign_in_audience"` - SupportUrl string `tfschema:"support_url"` - TermsOfServiceUrl string `tfschema:"terms_of_service_url"` + ClientId string `tfschema:"client_id"` + Description string `tfschema:"description"` + DisabledByMicrosoft string `tfschema:"disabled_by_microsoft"` + DisplayName string `tfschema:"display_name"` + GroupMembershipClaims []string `tfschema:"group_membership_claims"` + HomepageUrl string `tfschema:"homepage_url"` + ImplicitAccessTokenIssuanceEnabled bool `tfschema:"implicit_access_token_issuance_enabled"` + ImplicitIdTokenIssuanceEnabled bool `tfschema:"implicit_id_token_issuance_enabled"` + LogoutUrl string `tfschema:"logout_url"` + MarketingUrl string `tfschema:"marketing_url"` + Notes string `tfschema:"notes"` + PrivacyStatementUrl string `tfschema:"privacy_statement_url"` + PublisherDomain string `tfschema:"publisher_domain"` + RequestedAccessTokenVersion int `tfschema:"requested_access_token_version"` + ServiceManagementReference string `tfschema:"service_management_reference"` + SignInAudience string `tfschema:"sign_in_audience"` + SupportUrl string `tfschema:"support_url"` + TermsOfServiceUrl string `tfschema:"terms_of_service_url"` } type ApplicationRegistrationResource struct{} @@ -73,6 +74,22 @@ func (r ApplicationRegistrationResource) Arguments() map[string]*pluginsdk.Schem ValidateFunc: validation.StringLenBetween(0, 1024), }, + "group_membership_claims": { + Description: "Configures the `groups` claim that the app expects issued in a user or OAuth access token", + Type: pluginsdk.TypeSet, + Optional: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + ValidateFunc: validation.StringInSlice([]string{ + msgraph.GroupMembershipClaimAll, + msgraph.GroupMembershipClaimNone, + msgraph.GroupMembershipClaimApplicationGroup, + msgraph.GroupMembershipClaimDirectoryRole, + msgraph.GroupMembershipClaimSecurityGroup, + }, false), + }, + }, + "homepage_url": { Description: "URL of the home page for the application", Type: pluginsdk.TypeString, @@ -212,6 +229,7 @@ func (r ApplicationRegistrationResource) Create() sdk.ResourceFunc { properties := msgraph.Application{ DisplayName: &model.DisplayName, Description: tf.NullableString(model.Description), + GroupMembershipClaims: pointer.To(model.GroupMembershipClaims), Notes: tf.NullableString(model.Notes), ServiceManagementReference: tf.NullableString(model.ServiceManagementReference), SignInAudience: &model.SignInAudience, @@ -284,6 +302,7 @@ func (r ApplicationRegistrationResource) Read() sdk.ResourceFunc { ClientId: pointer.From(result.AppId), Description: string(pointer.From(result.Description)), DisplayName: pointer.From(result.DisplayName), + GroupMembershipClaims: pointer.From(result.GroupMembershipClaims), Notes: string(pointer.From(result.Notes)), PublisherDomain: pointer.From(result.PublisherDomain), ServiceManagementReference: string(pointer.From(result.ServiceManagementReference)), @@ -351,6 +370,10 @@ func (r ApplicationRegistrationResource) Update() sdk.ResourceFunc { properties.Description = tf.NullableString(model.Description) } + if rd.HasChange("group_membership_claims") { + properties.GroupMembershipClaims = pointer.To(model.GroupMembershipClaims) + } + if rd.HasChange("notes") { properties.Notes = tf.NullableString(model.Notes) } diff --git a/internal/services/applications/application_registration_resource_test.go b/internal/services/applications/application_registration_resource_test.go index 6612055ece..6631a853ee 100644 --- a/internal/services/applications/application_registration_resource_test.go +++ b/internal/services/applications/application_registration_resource_test.go @@ -124,6 +124,7 @@ resource "azuread_application_registration" "test" { display_name = "acctest-AppRegistration-complete-%[1]d" sign_in_audience = "AzureADandPersonalMicrosoftAccount" + group_membership_claims = ["All", "ApplicationGroup"] requested_access_token_version = 2 implicit_access_token_issuance_enabled = true implicit_id_token_issuance_enabled = true From 21610c7f868624333ecea3310b59141514668175 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 18 Oct 2023 02:58:06 +0100 Subject: [PATCH 17/46] New Resource: `azuread_application_redirect_uris` --- .../application_redirect_uris_resource.go | 313 ++++++++++++++++++ ...application_redirect_uris_resource_test.go | 202 +++++++++++ .../applications/parse/redirect_uri.go | 77 +++++ .../services/applications/registration.go | 1 + internal/tf/validation/uri.go | 12 +- 5 files changed, 599 insertions(+), 6 deletions(-) create mode 100644 internal/services/applications/application_redirect_uris_resource.go create mode 100644 internal/services/applications/application_redirect_uris_resource_test.go create mode 100644 internal/services/applications/parse/redirect_uri.go diff --git a/internal/services/applications/application_redirect_uris_resource.go b/internal/services/applications/application_redirect_uris_resource.go new file mode 100644 index 0000000000..215e4809d8 --- /dev/null +++ b/internal/services/applications/application_redirect_uris_resource.go @@ -0,0 +1,313 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications + +import ( + "context" + "fmt" + "net/http" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/terraform-provider-azuread/internal/sdk" + "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" + "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" +) + +const ( + RedirectUriTypePublicClient = "PublicClient" + RedirectUriTypeSPA = "SPA" + RedirectUriTypeWeb = "Web" +) + +type ApplicationRedirectUrisModel struct { + ApplicationId string `tfschema:"application_id"` + UriType string `tfschema:"type"` + RedirectUris []string `tfschema:"redirect_uris"` +} + +type ApplicationRedirectUrisResource struct{} + +func (r ApplicationRedirectUrisResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return parse.ValidateRedirectUrisID +} + +var _ sdk.ResourceWithUpdate = ApplicationRedirectUrisResource{} + +func (r ApplicationRedirectUrisResource) ResourceType() string { + return "azuread_application_redirect_uris" +} + +func (r ApplicationRedirectUrisResource) ModelObject() interface{} { + return &ApplicationRedirectUrisModel{} +} + +func (r ApplicationRedirectUrisResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "application_id": { + Description: "The resource ID of the application to which these redirect URIs belong", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: parse.ValidateApplicationID, + }, + + "type": { + Description: "The type of redirect URIs to assign to the application", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + RedirectUriTypePublicClient, + RedirectUriTypeSPA, + RedirectUriTypeWeb, + }, false), + }, + + "redirect_uris": { + Description: "A set of redirect URIs", + Type: pluginsdk.TypeSet, + Required: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + ValidateFunc: validation.IsRedirectUriFunc(true, true), + }, + }, + } +} + +func (r ApplicationRedirectUrisResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} +} + +func (r ApplicationRedirectUrisResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + var model ApplicationRedirectUrisModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + applicationId, err := parse.ParseApplicationID(model.ApplicationId) + if err != nil { + return err + } + + id := parse.NewRedirectUrisID(applicationId.ApplicationId, model.UriType) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + result, _, err := client.Get(ctx, applicationId.ApplicationId, odata.Query{}) + if err != nil { + return fmt.Errorf("retrieving %s: %+v", applicationId, err) + } + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", applicationId) + } + + // Check for existing redirect URIs + if existingUris := r.getRedirectUrisByType(*result, model.UriType); len(existingUris) > 0 { + return metadata.ResourceRequiresImport(r.ResourceType(), id) + } + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &id.ApplicationId, + }, + } + + r.setRedirectUrisByType(&properties, model) + + if _, err = client.Update(ctx, properties); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r ApplicationRedirectUrisResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseRedirectUrisID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + applicationId := parse.NewApplicationID(id.ApplicationId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", id) + } + + redirectUris := r.getRedirectUrisByType(*result, id.UriType) + + if len(redirectUris) == 0 { + return metadata.MarkAsGone(id) + } + + state := ApplicationRedirectUrisModel{ + ApplicationId: applicationId.ID(), + UriType: id.UriType, + RedirectUris: redirectUris, + } + + return metadata.Encode(&state) + }, + } +} + +func (r ApplicationRedirectUrisResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + + id, err := parse.ParseRedirectUrisID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + applicationId := parse.NewApplicationID(id.ApplicationId) + + var model ApplicationRedirectUrisModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &applicationId.ApplicationId, + }, + } + + r.setRedirectUrisByType(&properties, model) + + _, err = client.Update(ctx, properties) + if err != nil { + return fmt.Errorf("updating %s: %+v", id, err) + } + + return nil + }, + } +} + +func (r ApplicationRedirectUrisResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseRedirectUrisID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + applicationId := parse.NewApplicationID(id.ApplicationId) + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &applicationId.ApplicationId, + }, + } + + r.deleteRedirectUrisByType(&properties, id.UriType) + + _, err = client.Update(ctx, properties) + if err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + + return nil + }, + } +} + +func (r ApplicationRedirectUrisResource) getRedirectUrisByType(application msgraph.Application, uriType string) []string { + switch uriType { + case RedirectUriTypePublicClient: + if application.PublicClient != nil { + return pointer.From(application.PublicClient.RedirectUris) + } + case RedirectUriTypeSPA: + if application.Spa != nil { + return pointer.From(application.Spa.RedirectUris) + } + case RedirectUriTypeWeb: + if application.Web != nil { + return pointer.From(application.Web.RedirectUris) + } + } + + return nil +} + +func (r ApplicationRedirectUrisResource) setRedirectUrisByType(application *msgraph.Application, model ApplicationRedirectUrisModel) { + switch model.UriType { + case RedirectUriTypePublicClient: + application.PublicClient = &msgraph.PublicClient{ + RedirectUris: pointer.To(model.RedirectUris), + } + case RedirectUriTypeSPA: + application.Spa = &msgraph.ApplicationSpa{ + RedirectUris: pointer.To(model.RedirectUris), + } + case RedirectUriTypeWeb: + application.Web = &msgraph.ApplicationWeb{ + RedirectUris: pointer.To(model.RedirectUris), + } + } +} +func (r ApplicationRedirectUrisResource) deleteRedirectUrisByType(application *msgraph.Application, uriType string) { + switch uriType { + case RedirectUriTypePublicClient: + application.PublicClient = &msgraph.PublicClient{ + RedirectUris: &[]string{}, + } + case RedirectUriTypeSPA: + application.Spa = &msgraph.ApplicationSpa{ + RedirectUris: &[]string{}, + } + case RedirectUriTypeWeb: + application.Web = &msgraph.ApplicationWeb{ + RedirectUris: &[]string{}, + } + } +} diff --git a/internal/services/applications/application_redirect_uris_resource_test.go b/internal/services/applications/application_redirect_uris_resource_test.go new file mode 100644 index 0000000000..fba95dbd4b --- /dev/null +++ b/internal/services/applications/application_redirect_uris_resource_test.go @@ -0,0 +1,202 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications_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/terraform-plugin-testing/terraform" + "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/services/applications" + "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" +) + +type ApplicationRedirectUrisResource struct{} + +func TestAccApplicationRedirectUris_publicClient(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_redirect_uris", "test") + r := ApplicationRedirectUrisResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.publicClient(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationRedirectUris_spa(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_redirect_uris", "test") + r := ApplicationRedirectUrisResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.spa(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationRedirectUris_web(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_redirect_uris", "test") + r := ApplicationRedirectUrisResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.web(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationRedirectUris_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_redirect_uris", "test") + r := ApplicationRedirectUrisResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.web(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + ), + }, + data.RequiresImportErrorStep(r.requiresImport(data)), + }) +} + +func (r ApplicationRedirectUrisResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { + client := clients.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseRedirectUrisID(state.ID) + if err != nil { + return nil, err + } + + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return pointer.To(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + if result == nil { + return nil, fmt.Errorf("retrieving %s: result was nil", id) + } + + switch id.UriType { + case applications.RedirectUriTypePublicClient: + if result.PublicClient != nil && result.PublicClient.RedirectUris != nil && len(*result.PublicClient.RedirectUris) > 0 { + return pointer.To(true), nil + } + case applications.RedirectUriTypeSPA: + if result.Spa != nil && result.Spa.RedirectUris != nil && len(*result.Spa.RedirectUris) > 0 { + return pointer.To(true), nil + } + case applications.RedirectUriTypeWeb: + if result.Web != nil && result.Web.RedirectUris != nil && len(*result.Web.RedirectUris) > 0 { + return pointer.To(true), nil + } + } + + return pointer.To(false), nil +} + +func (ApplicationRedirectUrisResource) publicClient(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-RedirectUris-%[1]d" +} + +resource "azuread_application_redirect_uris" "test" { + application_id = azuread_application_registration.test.id + type = "PublicClient" + + redirect_uris = [ + "myapp://auth", + "sample.mobile.app.bundie.id://auth", + "https://login.microsoftonline.com/common/oauth2/nativeclient", + "https://login.live.com/oauth20_desktop.srf", + "ms-appx-web://Microsoft.AAD.BrokerPlugin/00000000-1111-1111-1111-222222222222", + "urn:ietf:wg:oauth:2.0:foo", + ] +} +`, data.RandomInteger) +} + +func (ApplicationRedirectUrisResource) spa(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-RedirectUris-%[1]d" +} + +resource "azuread_application_redirect_uris" "test" { + application_id = azuread_application_registration.test.id + type = "SPA" + + redirect_uris = [ + "https://mobile.hashitown-%[1]d.com/", + "https://beta.hashitown-%[1]d.com/", + ] +} +`, data.RandomInteger) +} + +func (ApplicationRedirectUrisResource) web(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-RedirectUris-%[1]d" +} + +resource "azuread_application_redirect_uris" "test" { + application_id = azuread_application_registration.test.id + type = "Web" + + redirect_uris = [ + "https://app.hashitown-%[1]d.com/", + "https://classic.hashitown-%[1]d.com/", + "urn:ietf:wg:oauth:2.0:oob", + ] +} +`, data.RandomInteger) +} + +func (r ApplicationRedirectUrisResource) requiresImport(data acceptance.TestData) string { + return fmt.Sprintf(` +%[1]s + +resource "azuread_application_redirect_uris" "import" { + application_id = azuread_application_redirect_uris.test.application_id + type = azuread_application_redirect_uris.test.type + redirect_uris = azuread_application_redirect_uris.test.redirect_uris +} +`, r.web(data)) +} diff --git a/internal/services/applications/parse/redirect_uri.go b/internal/services/applications/parse/redirect_uri.go new file mode 100644 index 0000000000..9cb5e4215d --- /dev/null +++ b/internal/services/applications/parse/redirect_uri.go @@ -0,0 +1,77 @@ +package parse + +import ( + "fmt" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +type RedirectUrisId struct { + ApplicationId string + UriType string +} + +func NewRedirectUrisID(applicationId, uriType string) RedirectUrisId { + return RedirectUrisId{ + ApplicationId: applicationId, + UriType: uriType, + } +} + +// ParseRedirectUrisID parses 'input' into an RedirectUrisId +func ParseRedirectUrisID(input string) (*RedirectUrisId, error) { + parser := resourceids.NewParserFromResourceIdType(RedirectUrisId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := RedirectUrisId{} + + if id.ApplicationId, ok = parsed.Parsed["applicationId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "applicationId", *parsed) + } + + if id.UriType, ok = parsed.Parsed["uriType"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "uriType", *parsed) + } + + return &id, nil +} + +// ValidateRedirectUrisID checks that 'input' can be parsed as an Application ID +func ValidateRedirectUrisID(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 + } + + _, err := ParseRedirectUrisID(v) + if err != nil { + errors = append(errors, err) + return + } + + return +} + +func (id RedirectUrisId) ID() string { + fmtString := "/applications/%s/redirectUris/%s" + return fmt.Sprintf(fmtString, id.ApplicationId, id.UriType) +} + +// Segments returns a slice of Resource ID Segments which comprise this ID +func (id RedirectUrisId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("applications", "applications", "applications"), + resourceids.UserSpecifiedSegment("applicationId", "00000000-0000-0000-0000-000000000000"), + resourceids.StaticSegment("redirectUris", "redirectUris", "redirectUris"), + resourceids.UserSpecifiedSegment("uriType", "web"), + } +} + +func (id RedirectUrisId) String() string { + return fmt.Sprintf("Application Redirect URIs (Application ID: %q, URI Type: %q)", id.ApplicationId, id.UriType) +} diff --git a/internal/services/applications/registration.go b/internal/services/applications/registration.go index a7bc04dd8c..685a5c868e 100644 --- a/internal/services/applications/registration.go +++ b/internal/services/applications/registration.go @@ -57,6 +57,7 @@ func (r Registration) Resources() []sdk.Resource { ApplicationKnownClientsResource{}, ApplicationOwnerResource{}, ApplicationPermissionScopeResource{}, + ApplicationRedirectUrisResource{}, ApplicationRegistrationResource{}, } } diff --git a/internal/tf/validation/uri.go b/internal/tf/validation/uri.go index f45bdbb462..f6951ece4e 100644 --- a/internal/tf/validation/uri.go +++ b/internal/tf/validation/uri.go @@ -36,11 +36,11 @@ func IsLogoutUrl(i interface{}, k string) (warnings []string, errors []error) { return } -func IsRedirectUriFunc(urnAllowed bool, publicClient bool) pluginsdk.SchemaValidateFunc { +func IsRedirectUriFunc(urnAllowed bool, allowAllSchemes bool) pluginsdk.SchemaValidateFunc { return func(i interface{}, k string) (warnings []string, errors []error) { // See https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows?pivots=b2c-custom-policy#register-the-proxyidentityexperienceframework-application var allowedSchemes []string - if !publicClient { + if !allowAllSchemes { allowedSchemes = []string{"http", "https", "ms-appx-web"} } @@ -57,7 +57,7 @@ func IsRedirectUriFunc(urnAllowed bool, publicClient bool) pluginsdk.SchemaValid } } -func IsUriFunc(validURLSchemes []string, urnAllowed bool, allowTrailingSlash bool, forceTrailingSlash bool) pluginsdk.SchemaValidateFunc { +func IsUriFunc(validUriSchemes []string, urnAllowed bool, allowTrailingSlash bool, forceTrailingSlash bool) pluginsdk.SchemaValidateFunc { return func(i interface{}, k string) ([]string, []error) { v, ok := i.(string) if !ok { @@ -88,7 +88,7 @@ func IsUriFunc(validURLSchemes []string, urnAllowed bool, allowTrailingSlash boo return nil, []error{fmt.Errorf("URI has no host for %q", k)} } - if validURLSchemes == nil { + if len(validUriSchemes) == 0 { return nil, nil } @@ -96,12 +96,12 @@ func IsUriFunc(validURLSchemes []string, urnAllowed bool, allowTrailingSlash boo return nil, []error{fmt.Errorf("URI must have a trailing slash when there is no path segment for %q", k)} } - for _, s := range validURLSchemes { + for _, s := range validUriSchemes { if u.Scheme == s { return nil, nil } } - return nil, []error{fmt.Errorf("unexpected URI scheme for %q, expected one of: %s", k, strings.Join(validURLSchemes, ", "))} + return nil, []error{fmt.Errorf("unexpected URI scheme for %q, expected one of: %s", k, strings.Join(validUriSchemes, ", "))} } } From 4e29ea8ab6db7f797a21278ad2014d8568dae5f9 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 18 Oct 2023 04:06:54 +0100 Subject: [PATCH 18/46] New Resource: `azuread_application_from_template` --- .../application_from_template_resource.go | 256 ++++++++++++++++++ ...application_from_template_resource_test.go | 133 +++++++++ .../applications/parse/from_template.go | 97 +++++++ .../applications/parse/service_principal.go | 70 +++++ .../services/applications/registration.go | 1 + 5 files changed, 557 insertions(+) create mode 100644 internal/services/applications/application_from_template_resource.go create mode 100644 internal/services/applications/application_from_template_resource_test.go create mode 100644 internal/services/applications/parse/from_template.go create mode 100644 internal/services/applications/parse/service_principal.go diff --git a/internal/services/applications/application_from_template_resource.go b/internal/services/applications/application_from_template_resource.go new file mode 100644 index 0000000000..0af4c8ac53 --- /dev/null +++ b/internal/services/applications/application_from_template_resource.go @@ -0,0 +1,256 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications + +import ( + "context" + "fmt" + "net/http" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/terraform-provider-azuread/internal/helpers" + "github.com/hashicorp/terraform-provider-azuread/internal/sdk" + "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" + "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/hashicorp/terraform-provider-azuread/internal/utils" + "github.com/manicminer/hamilton/msgraph" +) + +type ApplicationFromTemplateModel struct { + TemplateId string `tfschema:"template_id"` + DisplayName string `tfschema:"display_name"` + + ApplicationId string `tfschema:"application_id"` + ApplicationObjectId string `tfschema:"application_object_id"` + ServicePrincipalId string `tfschema:"service_principal_id"` + ServicePrincipalObjectId string `tfschema:"service_principal_object_id"` +} + +type ApplicationFromTemplateResource struct{} + +func (r ApplicationFromTemplateResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return parse.ValidateFromTemplateID +} + +var _ sdk.ResourceWithUpdate = ApplicationFromTemplateResource{} + +func (r ApplicationFromTemplateResource) ResourceType() string { + return "azuread_application_from_template" +} + +func (r ApplicationFromTemplateResource) ModelObject() interface{} { + return &ApplicationFromTemplateModel{} +} + +func (r ApplicationFromTemplateResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "display_name": { + Description: "The display name for the application", + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "template_id": { + Description: "The UUID of the template to instantiate for this application", + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.IsUUID, + }, + } +} + +func (r ApplicationFromTemplateResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ + "application_id": { + Description: "The resource ID for this application", + Type: pluginsdk.TypeString, + Computed: true, + }, + + "application_object_id": { + Description: "The object ID for this application", + Type: pluginsdk.TypeString, + Computed: true, + }, + + "service_principal_id": { + Description: "The resource ID for this service principal", + Type: pluginsdk.TypeString, + Computed: true, + }, + + "service_principal_object_id": { + Description: "The object ID for this service principal", + Type: pluginsdk.TypeString, + Computed: true, + }, + } +} + +func (r ApplicationFromTemplateResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationTemplatesClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + var model ApplicationFromTemplateModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + properties := msgraph.ApplicationTemplate{ + DisplayName: pointer.To(model.DisplayName), + ID: pointer.To(model.TemplateId), + } + + result, _, err := client.Instantiate(ctx, properties) + if err != nil { + return fmt.Errorf("creating %s: %+v", parse.FromTemplateId{}, err) + } + if result == nil { + return fmt.Errorf("creating %s: result was nil", parse.FromTemplateId{}) + } + if result.Application == nil { + return fmt.Errorf("creating %s: application was nil", parse.FromTemplateId{}) + } + if result.ServicePrincipal == nil { + return fmt.Errorf("creating %s: servicePrincipal was nil", parse.FromTemplateId{}) + } + + id := parse.NewFromTemplateID(model.TemplateId, *result.Application.ID(), *result.ServicePrincipal.ID()) + metadata.SetID(id) + + if err = helpers.WaitForUpdate(ctx, func(ctx context.Context) (*bool, error) { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + result, status, err := client.Get(ctx, *result.Application.ID(), odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return utils.Bool(false), nil + } + return nil, err + } + return pointer.To(result != nil), nil + }); err != nil { + return fmt.Errorf("creating %s: timed out waiting for replication of new application", parse.FromTemplateId{}) + } + + return nil + }, + } +} + +func (r ApplicationFromTemplateResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseFromTemplateID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + // Check the application exists + result, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + + if result == nil { + return fmt.Errorf("retrieving %s: result was nil", id) + } + + applicationId := parse.NewApplicationID(id.ApplicationId) + servicePrincipalId := parse.NewServicePrincipalID(id.ServicePrincipalId) + + state := ApplicationFromTemplateModel{ + DisplayName: pointer.From(result.DisplayName), + TemplateId: id.TemplateId, + ApplicationId: applicationId.ID(), + ApplicationObjectId: applicationId.ApplicationId, + ServicePrincipalId: servicePrincipalId.ID(), + ServicePrincipalObjectId: servicePrincipalId.ServicePrincipalId, + } + + return metadata.Encode(&state) + }, + } +} + +func (r ApplicationFromTemplateResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 10 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + rd := metadata.ResourceData + + id, err := parse.ParseFromTemplateID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var model ApplicationFromTemplateModel + if err := metadata.Decode(&model); err != nil { + return fmt.Errorf("decoding: %+v", err) + } + + if rd.HasChange("display_name") { + properties := msgraph.Application{ + DirectoryObject: msgraph.DirectoryObject{ + Id: &id.ApplicationId, + }, + DisplayName: pointer.To(model.DisplayName), + } + + if _, err = client.Update(ctx, properties); err != nil { + return fmt.Errorf("updating %s: %+v", id, err) + } + } + + return nil + }, + } +} + +func (r ApplicationFromTemplateResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseFromTemplateID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + tf.LockByName(applicationResourceName, id.ApplicationId) + defer tf.UnlockByName(applicationResourceName, id.ApplicationId) + + _, err = client.Delete(ctx, id.ApplicationId) + if err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) + } + + return nil + }, + } +} diff --git a/internal/services/applications/application_from_template_resource_test.go b/internal/services/applications/application_from_template_resource_test.go new file mode 100644 index 0000000000..e80ccd883c --- /dev/null +++ b/internal/services/applications/application_from_template_resource_test.go @@ -0,0 +1,133 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + +package applications_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/terraform-plugin-testing/terraform" + "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/services/applications/parse" +) + +type ApplicationFromTemplateResource struct{} + +func TestAccApplicationFromTemplate_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_from_template", "test") + r := ApplicationFromTemplateResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("template_id").Exists(), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("application_object_id").Exists(), + check.That(data.ResourceName).Key("service_principal_id").Exists(), + check.That(data.ResourceName).Key("service_principal_object_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func TestAccApplicationFromTemplate_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_from_template", "test") + r := ApplicationFromTemplateResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("template_id").Exists(), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("application_object_id").Exists(), + check.That(data.ResourceName).Key("service_principal_id").Exists(), + check.That(data.ResourceName).Key("service_principal_object_id").Exists(), + ), + }, + data.ImportStep(), + { + Config: r.update(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("template_id").Exists(), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data.ResourceName).Key("application_object_id").Exists(), + check.That(data.ResourceName).Key("service_principal_id").Exists(), + check.That(data.ResourceName).Key("service_principal_object_id").Exists(), + ), + }, + data.ImportStep(), + }) +} + +func (r ApplicationFromTemplateResource) Exists(ctx context.Context, clients *clients.Client, state *terraform.InstanceState) (*bool, error) { + client := clients.Applications.ApplicationsClient + client.BaseClient.DisableRetries = true + defer func() { client.BaseClient.DisableRetries = false }() + + id, err := parse.ParseFromTemplateID(state.ID) + if err != nil { + return nil, err + } + + // Check the application exists + _, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) + if err != nil { + if status == http.StatusNotFound { + return pointer.To(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", id, err) + } + + return pointer.To(true), nil +} + +func (ApplicationFromTemplateResource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_from_template" "test" { + display_name = "acctest-FromTemplate-%[1]d" + template_id = "%[2]s" +} + +data "azuread_application" "test" { + object_id = azuread_application_from_template.test.application_object_id +} + +data "azuread_service_principal" "test" { + object_id = azuread_application_from_template.test.service_principal_object_id +} +`, data.RandomInteger, testApplicationTemplateId) +} + +func (ApplicationFromTemplateResource) update(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_from_template" "test" { + display_name = "acctest-FromTemplateUpdated-%[1]d" + template_id = "%[2]s" +} + +data "azuread_application" "test" { + object_id = azuread_application_from_template.test.application_object_id +} + +data "azuread_service_principal" "test" { + object_id = azuread_application_from_template.test.service_principal_object_id +} +`, data.RandomInteger, testApplicationTemplateId) +} diff --git a/internal/services/applications/parse/from_template.go b/internal/services/applications/parse/from_template.go new file mode 100644 index 0000000000..14521290d7 --- /dev/null +++ b/internal/services/applications/parse/from_template.go @@ -0,0 +1,97 @@ +package parse + +import ( + "fmt" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/hashicorp/terraform-provider-azuread/internal/tf/validation" +) + +type FromTemplateId struct { + TemplateId string + ApplicationId string + ServicePrincipalId string +} + +func NewFromTemplateID(templateId, applicationId, servicePrincipalId string) FromTemplateId { + return FromTemplateId{ + TemplateId: templateId, + ApplicationId: applicationId, + ServicePrincipalId: servicePrincipalId, + } +} + +// ParseFromTemplateID parses 'input' into an FromTemplateId +func ParseFromTemplateID(input string) (*FromTemplateId, error) { + parser := resourceids.NewParserFromResourceIdType(FromTemplateId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + var ok bool + id := FromTemplateId{} + + if id.TemplateId, ok = parsed.Parsed["templateId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "templateId", *parsed) + } + + if id.ApplicationId, ok = parsed.Parsed["applicationId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "applicationId", *parsed) + } + + if id.ServicePrincipalId, ok = parsed.Parsed["servicePrincipalId"]; !ok { + return nil, resourceids.NewSegmentNotSpecifiedError(id, "servicePrincipalId", *parsed) + } + + return &id, nil +} + +// ValidateFromTemplateID checks that 'input' can be parsed as an Application ID +func ValidateFromTemplateID(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 := ParseFromTemplateID(v) + if err != nil { + errors = append(errors, err) + return + } + + if warnings, errors = validation.IsUUID(id.TemplateId, "ID"); len(errors) > 0 { + return + } + + if warnings, errors = validation.IsUUID(id.ApplicationId, "ID"); len(errors) > 0 { + return + } + + if warnings, errors = validation.IsUUID(id.ServicePrincipalId, "ID"); len(errors) > 0 { + return + } + + return +} + +func (id FromTemplateId) ID() string { + fmtString := "/applicationTemplates/%s/instantiate/%s/%s" + return fmt.Sprintf(fmtString, id.TemplateId, id.ApplicationId, id.ServicePrincipalId) +} + +// Segments returns a slice of Resource ID Segments which comprise this ID +func (id FromTemplateId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("applicationTemplates", "applicationTemplates", "applicationTemplates"), + resourceids.UserSpecifiedSegment("templateId", "00000000-0000-0000-0000-000000000000"), + resourceids.StaticSegment("instantiate", "instantiate", "instantiate"), + resourceids.UserSpecifiedSegment("applicationId", "11111111-1111-1111-1111-111111111111"), + resourceids.UserSpecifiedSegment("servicePrincipalId", "22222222-2222-2222-2222-222222222222"), + } +} + +func (id FromTemplateId) String() string { + return fmt.Sprintf("Application From Template (Template ID: %q, Application ID: %q, Service Principal ID: %q)", id.TemplateId, id.ApplicationId, id.ServicePrincipalId) +} diff --git a/internal/services/applications/parse/service_principal.go b/internal/services/applications/parse/service_principal.go new file mode 100644 index 0000000000..bc1c50de12 --- /dev/null +++ b/internal/services/applications/parse/service_principal.go @@ -0,0 +1,70 @@ +package parse + +import ( + "fmt" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/hashicorp/terraform-provider-azuread/internal/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) +} diff --git a/internal/services/applications/registration.go b/internal/services/applications/registration.go index 685a5c868e..82afc75ca2 100644 --- a/internal/services/applications/registration.go +++ b/internal/services/applications/registration.go @@ -53,6 +53,7 @@ func (r Registration) Resources() []sdk.Resource { ApplicationApiAccessResource{}, ApplicationAppRoleResource{}, ApplicationFallbackPublicClientResource{}, + ApplicationFromTemplateResource{}, ApplicationIdentifierUriResource{}, ApplicationKnownClientsResource{}, ApplicationOwnerResource{}, From 7e96eb497282c50dc43c76b2712910a3eb9a713c Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 18 Oct 2023 04:48:59 +0100 Subject: [PATCH 19/46] azuread_application: export the `client_id` attribute --- .../applications/application_data_source.go | 21 +++++++++++++---- .../application_data_source_test.go | 23 +++++++++++++++++++ .../applications/application_resource.go | 7 ++++++ .../applications/application_resource_test.go | 19 ++++++++++----- 4 files changed, 60 insertions(+), 10 deletions(-) diff --git a/internal/services/applications/application_data_source.go b/internal/services/applications/application_data_source.go index e649aec00f..d55ea33e19 100644 --- a/internal/services/applications/application_data_source.go +++ b/internal/services/applications/application_data_source.go @@ -33,7 +33,7 @@ func applicationDataSource() *pluginsdk.Resource { Type: pluginsdk.TypeString, Optional: true, Computed: true, - ExactlyOneOf: []string{"application_id", "display_name", "object_id"}, + ExactlyOneOf: []string{"application_id", "client_id", "display_name", "object_id"}, ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), }, @@ -42,7 +42,16 @@ func applicationDataSource() *pluginsdk.Resource { Type: pluginsdk.TypeString, Optional: true, Computed: true, - ExactlyOneOf: []string{"application_id", "display_name", "object_id"}, + ExactlyOneOf: []string{"application_id", "client_id", "display_name", "object_id"}, + ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + }, + + "client_id": { + Description: "The Client ID (also called Application ID)", + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + ExactlyOneOf: []string{"application_id", "client_id", "display_name", "object_id"}, ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), }, @@ -57,7 +66,7 @@ func applicationDataSource() *pluginsdk.Resource { Type: pluginsdk.TypeString, Optional: true, Computed: true, - ExactlyOneOf: []string{"application_id", "display_name", "object_id"}, + ExactlyOneOf: []string{"application_id", "client_id", "display_name", "object_id"}, ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), }, @@ -517,11 +526,14 @@ func applicationDataSourceRead(ctx context.Context, d *pluginsdk.ResourceData, m if applicationId, ok := d.Get("application_id").(string); ok && applicationId != "" { fieldName = "appId" fieldValue = applicationId + } else if clientId, ok := d.Get("client_id").(string); ok && clientId != "" { + fieldName = "appId" + fieldValue = clientId } else if displayName, ok := d.Get("display_name").(string); ok && displayName != "" { fieldName = "displayName" fieldValue = displayName } else { - return tf.ErrorDiagF(nil, "One of `object_id`, `application_id` or `displayName` must be specified") + return tf.ErrorDiagF(nil, "One of `object_id`, `application_id`, `client_id`, or `displayName` must be specified") } filter := fmt.Sprintf("%s eq '%s'", fieldName, fieldValue) @@ -571,6 +583,7 @@ func applicationDataSourceRead(ctx context.Context, d *pluginsdk.ResourceData, m tf.Set(d, "app_roles", flattenApplicationAppRoles(app.AppRoles)) tf.Set(d, "app_role_ids", flattenApplicationAppRoleIDs(app.AppRoles)) tf.Set(d, "application_id", app.AppId) + tf.Set(d, "client_id", app.AppId) tf.Set(d, "device_only_auth_enabled", app.IsDeviceOnlyAuthSupported) tf.Set(d, "disabled_by_microsoft", fmt.Sprintf("%v", app.DisabledByMicrosoftStatus)) tf.Set(d, "display_name", app.DisplayName) diff --git a/internal/services/applications/application_data_source_test.go b/internal/services/applications/application_data_source_test.go index dcdcd93682..3edff3e6b1 100644 --- a/internal/services/applications/application_data_source_test.go +++ b/internal/services/applications/application_data_source_test.go @@ -37,6 +37,18 @@ func TestAccApplicationDataSource_byApplicationId(t *testing.T) { }) } +func TestAccApplicationDataSource_byClientId(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azuread_application", "test") + r := ApplicationDataSource{} + + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: r.clientId(data), + Check: r.testCheck(data), + }, + }) +} + func TestAccApplicationDataSource_byDisplayName(t *testing.T) { data := acceptance.BuildTestData(t, "data.azuread_application", "test") r := ApplicationDataSource{} @@ -52,6 +64,7 @@ func TestAccApplicationDataSource_byDisplayName(t *testing.T) { func (ApplicationDataSource) testCheck(data acceptance.TestData) acceptance.TestCheckFunc { return acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).Key("application_id").IsUuid(), + check.That(data.ResourceName).Key("client_id").IsUuid(), check.That(data.ResourceName).Key("object_id").IsUuid(), check.That(data.ResourceName).Key("api.0.oauth2_permission_scopes.#").HasValue("2"), check.That(data.ResourceName).Key("app_roles.#").HasValue("2"), @@ -98,6 +111,16 @@ data "azuread_application" "test" { `, ApplicationResource{}.complete(data)) } +func (ApplicationDataSource) clientId(data acceptance.TestData) string { + return fmt.Sprintf(` +%[1]s + +data "azuread_application" "test" { + client_id = upper(azuread_application.test.client_id) +} +`, ApplicationResource{}.complete(data)) +} + func (ApplicationDataSource) displayName(data acceptance.TestData) string { return fmt.Sprintf(` %[1]s diff --git a/internal/services/applications/application_resource.go b/internal/services/applications/application_resource.go index 5192a183bb..84b11c87ac 100644 --- a/internal/services/applications/application_resource.go +++ b/internal/services/applications/application_resource.go @@ -604,6 +604,12 @@ func applicationResource() *pluginsdk.Resource { Computed: true, }, + "client_id": { + Description: "The Client ID (also called Application ID)", + Type: pluginsdk.TypeString, + Computed: true, + }, + "object_id": { Description: "The application's object ID", Type: pluginsdk.TypeString, @@ -1267,6 +1273,7 @@ func applicationResourceRead(ctx context.Context, d *pluginsdk.ResourceData, met tf.Set(d, "app_role", flattenApplicationAppRoles(app.AppRoles)) tf.Set(d, "app_role_ids", flattenApplicationAppRoleIDs(app.AppRoles)) tf.Set(d, "application_id", app.AppId) + tf.Set(d, "client_id", app.AppId) tf.Set(d, "description", app.Description) tf.Set(d, "device_only_auth_enabled", app.IsDeviceOnlyAuthSupported) tf.Set(d, "disabled_by_microsoft", fmt.Sprintf("%v", app.DisabledByMicrosoftStatus)) diff --git a/internal/services/applications/application_resource_test.go b/internal/services/applications/application_resource_test.go index 51f24a3bee..2175afb531 100644 --- a/internal/services/applications/application_resource_test.go +++ b/internal/services/applications/application_resource_test.go @@ -30,6 +30,7 @@ func TestAccApplication_basic(t *testing.T) { 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)), ), @@ -48,6 +49,7 @@ func TestAccApplication_basicFromTemplate(t *testing.T) { 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)), check.That(data.ResourceName).Key("template_id").HasValue(testApplicationTemplateId), @@ -67,6 +69,7 @@ func TestAccApplication_complete(t *testing.T) { 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(), ), }, @@ -84,6 +87,7 @@ func TestAccApplication_completeFromTemplate(t *testing.T) { 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), check.That(data.ResourceName).Key("app_role.#").HasValue("1"), @@ -104,6 +108,7 @@ func TestAccApplication_update(t *testing.T) { 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(), ), }, @@ -113,6 +118,7 @@ func TestAccApplication_update(t *testing.T) { 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(), ), }, @@ -122,6 +128,7 @@ func TestAccApplication_update(t *testing.T) { 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(), ), }, @@ -685,8 +692,8 @@ resource "azuread_application" "test" { requested_access_token_version = 2 known_client_applications = [ - azuread_application.known1.application_id, - azuread_application.known2.application_id, + azuread_application.known1.client_id, + azuread_application.known2.client_id, ] oauth2_permission_scope { @@ -870,8 +877,8 @@ resource "azuread_application" "test" { requested_access_token_version = 2 known_client_applications = [ - azuread_application.known1.application_id, - azuread_application.known2.application_id, + azuread_application.known1.client_id, + azuread_application.known2.client_id, ] oauth2_permission_scope { @@ -1178,7 +1185,7 @@ resource "azuread_application" "test" { display_name = "acctest-APP-related-%[1]d" required_resource_access { - resource_app_id = azuread_application.service.application_id + resource_app_id = azuread_application.service.client_id resource_access { id = azuread_application.service.app_role_ids["user"] @@ -1246,7 +1253,7 @@ resource "azuread_application" "test" { display_name = "acctest-APP-related-%[1]d" required_resource_access { - resource_app_id = azuread_application.service.application_id + resource_app_id = azuread_application.service.client_id resource_access { id = azuread_application.service.app_role_ids["admin"] From 3a9766dfd32a4d952fc9d2c877e7ad31e7e85f2d Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 18 Oct 2023 18:35:46 +0100 Subject: [PATCH 20/46] acceptance: fix up regex for ImportError --- internal/acceptance/testing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/acceptance/testing.go b/internal/acceptance/testing.go index 72d3b995f4..9dbae93d04 100644 --- a/internal/acceptance/testing.go +++ b/internal/acceptance/testing.go @@ -84,6 +84,6 @@ func GetAuthConfig(t *testing.T) *auth.Credentials { } func RequiresImportError(resourceName string) *regexp.Regexp { - message := "to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for %q for more information." + message := "[Tt]o be managed via Terraform,? this resource needs to be imported into the[ \n]State. Please see the resource documentation for[ \n]%q for more information." return regexp.MustCompile(fmt.Sprintf(message, resourceName)) } From e67c84d6ee2cff33cf765aaedd1dbf5d3fa823af Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 18 Oct 2023 18:38:30 +0100 Subject: [PATCH 21/46] upgrade resource ID for azuread_application and support `application_id` property for existing resources --- internal/helpers/credentials.go | 8 +- .../application_certificate_resource.go | 97 ++- .../application_certificate_resource_test.go | 128 +++- ..._federated_identity_credential_resource.go | 99 +++- ...rated_identity_credential_resource_test.go | 76 ++- .../application_password_resource.go | 91 ++- .../application_password_resource_test.go | 78 ++- .../application_pre_authorized_resource.go | 103 +++- ...pplication_pre_authorized_resource_test.go | 132 ++++- .../applications/application_resource.go | 125 ++-- .../application_password_resource.go | 45 +- .../migrations/application_resource.go | 551 ++++++++++++++++++ .../applications/parse/application.go | 1 - .../applications/parse/credentials.go | 2 + 14 files changed, 1297 insertions(+), 239 deletions(-) diff --git a/internal/helpers/credentials.go b/internal/helpers/credentials.go index c39ec257b3..d040a77e37 100644 --- a/internal/helpers/credentials.go +++ b/internal/helpers/credentials.go @@ -14,9 +14,9 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -141,10 +141,10 @@ func KeyCredentialForResource(d *pluginsdk.ResourceData) (*msgraph.KeyCredential } credential := msgraph.KeyCredential{ - KeyId: utils.String(keyId), + KeyId: pointer.To(keyId), Type: keyType, Usage: msgraph.KeyCredentialUsageVerify, - Key: utils.String(encodedValue), + Key: pointer.To(encodedValue), } if v, ok := d.GetOk("start_date"); ok { @@ -190,7 +190,7 @@ func PasswordCredentialForResource(d *pluginsdk.ResourceData) (*msgraph.Password // display_name, start_date and end_date support intentionally remains for if/when the API supports user-specified values for these if v, ok := d.GetOk("display_name"); ok { - credential.DisplayName = utils.String(v.(string)) + credential.DisplayName = pointer.To(v.(string)) } if v, ok := d.GetOk("start_date"); ok { diff --git a/internal/services/applications/application_certificate_resource.go b/internal/services/applications/application_certificate_resource.go index 458558cd72..8fe4133090 100644 --- a/internal/services/applications/application_certificate_resource.go +++ b/internal/services/applications/application_certificate_resource.go @@ -12,14 +12,15 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/helpers" "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -30,9 +31,9 @@ func applicationCertificateResource() *pluginsdk.Resource { DeleteContext: applicationCertificateResourceDelete, Timeouts: &pluginsdk.ResourceTimeout{ - Create: pluginsdk.DefaultTimeout(5 * time.Minute), + Create: pluginsdk.DefaultTimeout(10 * time.Minute), Read: pluginsdk.DefaultTimeout(5 * time.Minute), - Update: pluginsdk.DefaultTimeout(5 * time.Minute), + Update: pluginsdk.DefaultTimeout(10 * time.Minute), Delete: pluginsdk.DefaultTimeout(5 * time.Minute), }, @@ -42,12 +43,25 @@ func applicationCertificateResource() *pluginsdk.Resource { }), Schema: map[string]*pluginsdk.Schema{ + "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, - Required: true, - ForceNew: true, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + Description: "The object ID of the application for which this certificate should be created", + Type: pluginsdk.TypeString, + Optional: true, + Computed: 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), }, "encoding": { @@ -64,12 +78,12 @@ func applicationCertificateResource() *pluginsdk.Resource { }, "key_id": { - Description: "A UUID used to uniquely identify this certificate. If omitted, a random UUID will be automatically generated", - Type: pluginsdk.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + Description: "A UUID used to uniquely identify this certificate. If omitted, a random UUID will be automatically generated", + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validation.IsUUID, }, "start_date": { @@ -92,12 +106,12 @@ func applicationCertificateResource() *pluginsdk.Resource { }, "end_date_relative": { - Description: "A relative duration for which the certificate is valid until, for example `240h` (10 days) or `2400h30m`", - Type: pluginsdk.TypeString, - Optional: true, - ForceNew: true, - ConflictsWith: []string{"end_date"}, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Description: "A relative duration for which the certificate is valid until, for example `240h` (10 days) or `2400h30m`", + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + ConflictsWith: []string{"end_date"}, + ValidateFunc: validation.StringIsNotEmpty, }, "type": { @@ -112,7 +126,7 @@ func applicationCertificateResource() *pluginsdk.Resource { }, "value": { - Description: "The certificate data, which can be PEM encoded, base64 encoded DER or hexadecimal encoded DER. See also the `encoding` argumen", + Description: "The certificate data, which can be PEM encoded, base64 encoded DER or hexadecimal encoded DER. See also the `encoding` argument", Type: pluginsdk.TypeString, Required: true, ForceNew: true, @@ -124,7 +138,26 @@ func applicationCertificateResource() *pluginsdk.Resource { func applicationCertificateResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { client := meta.(*clients.Client).Applications.ApplicationsClientBeta - objectId := d.Get("application_object_id").(string) + + var applicationId *parse.ApplicationId + var err error + if v := d.Get("application_id").(string); v != "" { + if applicationId, err = parse.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(parse.NewApplicationID(v)) + } else { + if applicationId, err = parse.ParseApplicationID(v); err != nil { + return tf.ErrorDiagPathF(err, "application_id", "Parsing `application_object_id`: %q", v) + } + } + } credential, err := helpers.KeyCredentialForResource(d) if err != nil { @@ -132,13 +165,13 @@ func applicationCertificateResourceCreate(ctx context.Context, d *pluginsdk.Reso if kerr, ok := err.(helpers.CredentialError); ok { attr = kerr.Attr() } - return tf.ErrorDiagPathF(err, attr, "Generating certificate credentials for application with object ID %q", objectId) + return tf.ErrorDiagPathF(err, attr, "Generating certificate credentials for %s", applicationId) } if credential.KeyId == nil { return tf.ErrorDiagF(errors.New("keyId for certificate credential is nil"), "Creating certificate credential") } - id := parse.NewCredentialID(objectId, "certificate", *credential.KeyId) + id := parse.NewCredentialID(applicationId.ApplicationId, "certificate", *credential.KeyId) tf.LockByName(applicationResourceName, id.ObjectId) defer tf.UnlockByName(applicationResourceName, id.ObjectId) @@ -218,7 +251,9 @@ func applicationCertificateResourceRead(ctx context.Context, d *pluginsdk.Resour return tf.ErrorDiagPathF(err, "id", "Parsing certificate credential with ID %q", d.Id()) } - app, status, err := client.Get(ctx, id.ObjectId, odata.Query{}) + applicationId := parse.NewApplicationID(id.ObjectId) + + app, status, err := client.Get(ctx, applicationId.ApplicationId, odata.Query{}) if err != nil { if status == http.StatusNotFound { log.Printf("[DEBUG] Application with ID %q for %s credential %q was not found - removing from state!", id.ObjectId, id.KeyType, id.KeyId) @@ -235,7 +270,7 @@ func applicationCertificateResourceRead(ctx context.Context, d *pluginsdk.Resour return nil } - tf.Set(d, "application_object_id", id.ObjectId) + tf.Set(d, "application_id", applicationId.ID()) tf.Set(d, "key_id", id.KeyId) tf.Set(d, "type", credential.Type) @@ -251,6 +286,12 @@ func applicationCertificateResourceRead(ctx context.Context, d *pluginsdk.Resour } tf.Set(d, "end_date", endDate) + 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 } @@ -304,10 +345,10 @@ func applicationCertificateResourceDelete(ctx context.Context, d *pluginsdk.Reso credential := helpers.GetKeyCredential(app.KeyCredentials, id.KeyId) if credential == nil { - return utils.Bool(false), nil + return pointer.To(false), nil } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of certificate credential %q from application with object ID %q", id.KeyId, id.ObjectId) } diff --git a/internal/services/applications/application_certificate_resource_test.go b/internal/services/applications/application_certificate_resource_test.go index 5fec1d8e8c..1c333718a0 100644 --- a/internal/services/applications/application_certificate_resource_test.go +++ b/internal/services/applications/application_certificate_resource_test.go @@ -10,13 +10,13 @@ import ( "testing" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/services/applications/parse" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" ) // To create test certificates: @@ -170,6 +170,40 @@ 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.ApplicationsClientBeta client.BaseClient.DisableRetries = true @@ -191,7 +225,7 @@ func (ApplicationCertificateResource) Exists(ctx context.Context, clients *clien if app.KeyCredentials != nil { for _, cred := range *app.KeyCredentials { if cred.KeyId != nil && *cred.KeyId == id.KeyId { - return utils.Bool(true), nil + return pointer.To(true), nil } } } @@ -212,10 +246,10 @@ func (r ApplicationCertificateResource) basic(data acceptance.TestData, endDate %[1]s resource "azuread_application_certificate" "test" { - application_object_id = azuread_application.test.id - type = "AsymmetricX509Cert" - end_date = "%[2]s" - value = < 0 { - _, err := client.UploadLogo(ctx, d.Id(), imageContentType, imageData) + _, err := client.UploadLogo(ctx, id.ApplicationId, imageContentType, imageData) if err != nil { - return tf.ErrorDiagF(err, "Could not upload logo image for application with object ID: %q", d.Id()) + return tf.ErrorDiagF(err, "Could not upload logo image for application with object ID: %q", id.ApplicationId) } } @@ -1129,7 +1140,12 @@ func applicationResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, m func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { client := meta.(*clients.Client).Applications.ApplicationsClientBeta tenantId := meta.(*clients.Client).TenantID - applicationId := d.Id() + + id, err := parse.ParseApplicationID(d.Id()) + if err != nil { + return tf.ErrorDiagPathF(err, "id", "Parsing ID") + } + displayName := d.Get("display_name").(string) // Perform this check at apply time to catch any duplicate names created during the same apply @@ -1144,7 +1160,7 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m return tf.ErrorDiagF(errors.New("API returned application with nil object ID during duplicate name check"), "Bad API response") } - if *existingApp.ID() != applicationId { + if *existingApp.ID() != id.ApplicationId { return tf.ImportAsDuplicateDiag("azuread_application", *existingApp.ID(), displayName) } } @@ -1170,12 +1186,12 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m properties := msgraph.Application{ DirectoryObject: msgraph.DirectoryObject{ - Id: utils.String(applicationId), + Id: pointer.To(id.ApplicationId), }, Api: expandApplicationApi(d.Get("api").([]interface{})), AppRoles: expandApplicationAppRoles(d.Get("app_role").(*pluginsdk.Set).List()), Description: utils.NullableString(d.Get("description").(string)), - DisplayName: utils.String(displayName), + DisplayName: pointer.To(displayName), GroupMembershipClaims: expandApplicationGroupMembershipClaims(d.Get("group_membership_claims").(*pluginsdk.Set).List()), IdentifierUris: tf.ExpandStringSlicePtr(d.Get("identifier_uris").(*pluginsdk.Set).List()), Info: &msgraph.InformationalUrl{ @@ -1184,36 +1200,36 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m SupportUrl: utils.NullableString(d.Get("support_url").(string)), TermsOfServiceUrl: utils.NullableString(d.Get("terms_of_service_url").(string)), }, - IsDeviceOnlyAuthSupported: utils.Bool(d.Get("device_only_auth_enabled").(bool)), - IsFallbackPublicClient: utils.Bool(d.Get("fallback_public_client_enabled").(bool)), + IsDeviceOnlyAuthSupported: pointer.To(d.Get("device_only_auth_enabled").(bool)), + IsFallbackPublicClient: pointer.To(d.Get("fallback_public_client_enabled").(bool)), Notes: utils.NullableString(d.Get("notes").(string)), - Oauth2RequirePostResponse: utils.Bool(d.Get("oauth2_post_response_required").(bool)), + Oauth2RequirePostResponse: pointer.To(d.Get("oauth2_post_response_required").(bool)), OptionalClaims: expandApplicationOptionalClaims(d.Get("optional_claims").([]interface{})), PublicClient: expandApplicationPublicClient(d.Get("public_client").([]interface{})), RequiredResourceAccess: expandApplicationRequiredResourceAccess(d.Get("required_resource_access").(*pluginsdk.Set).List()), ServiceManagementReference: utils.NullableString(d.Get("service_management_reference").(string)), - SignInAudience: utils.String(d.Get("sign_in_audience").(string)), + SignInAudience: pointer.To(d.Get("sign_in_audience").(string)), Spa: expandApplicationSpa(d.Get("single_page_application").([]interface{})), Tags: &tags, Web: expandApplicationWeb(d.Get("web").([]interface{})), } if err := applicationDisableAppRoles(ctx, client, &properties, expandApplicationAppRoles(d.Get("app_role").(*pluginsdk.Set).List())); err != nil { - return tf.ErrorDiagPathF(err, "app_role", "Could not disable App Roles for application with object ID %q", d.Id()) + return tf.ErrorDiagPathF(err, "app_role", "Could not disable App Roles for application with object ID %q", id.ApplicationId) } if err := applicationDisableOauth2PermissionScopes(ctx, client, &properties, expandApplicationOAuth2PermissionScope(d.Get("api.0.oauth2_permission_scope").(*pluginsdk.Set).List())); err != nil { - return tf.ErrorDiagPathF(err, "api.0.oauth2_permission_scope", "Could not disable OAuth2 Permission Scopes for application with object ID %q", d.Id()) + return tf.ErrorDiagPathF(err, "api.0.oauth2_permission_scope", "Could not disable OAuth2 Permission Scopes for application with object ID %q", id.ApplicationId) } if _, err := client.Update(ctx, properties); err != nil { - return tf.ErrorDiagF(err, "Could not update application with object ID: %q", d.Id()) + return tf.ErrorDiagF(err, "Could not update application with object ID: %q", id.ApplicationId) } if d.HasChange("owners") { - owners, _, err := client.ListOwners(ctx, applicationId) + owners, _, err := client.ListOwners(ctx, id.ApplicationId) if err != nil { - return tf.ErrorDiagF(err, "Could not retrieve owners for application with object ID: %q", d.Id()) + return tf.ErrorDiagF(err, "Could not retrieve owners for application with object ID: %q", id.ApplicationId) } desiredOwners := *tf.ExpandStringSlicePtr(d.Get("owners").(*pluginsdk.Set).List()) @@ -1225,7 +1241,7 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m newOwners := make(msgraph.Owners, 0) for _, ownerId := range ownersToAdd { newOwners = append(newOwners, msgraph.DirectoryObject{ - ODataId: (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + ODataId: (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, ownerId))), Id: &ownerId, }) @@ -1233,22 +1249,22 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m properties.Owners = &newOwners if _, err := client.AddOwners(ctx, &properties); err != nil { - return tf.ErrorDiagF(err, "Could not add owners to application with object ID: %q", d.Id()) + return tf.ErrorDiagF(err, "Could not add owners to application with object ID: %q", id.ApplicationId) } } if len(ownersForRemoval) > 0 { - if _, err = client.RemoveOwners(ctx, d.Id(), &ownersForRemoval); err != nil { - return tf.ErrorDiagF(err, "Could not remove owners from application with object ID: %q", d.Id()) + if _, err = client.RemoveOwners(ctx, id.ApplicationId, &ownersForRemoval); err != nil { + return tf.ErrorDiagF(err, "Could not remove owners from application with object ID: %q", id.ApplicationId) } } } // Upload the application image if imageContentType != "" && len(imageData) > 0 { - _, err := client.UploadLogo(ctx, d.Id(), imageContentType, imageData) + _, err := client.UploadLogo(ctx, id.ApplicationId, imageContentType, imageData) if err != nil { - return tf.ErrorDiagF(err, "Could not upload logo image for application with object ID: %q", d.Id()) + return tf.ErrorDiagF(err, "Could not upload logo image for application with object ID: %q", id.ApplicationId) } } @@ -1258,15 +1274,20 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m func applicationResourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { client := meta.(*clients.Client).Applications.ApplicationsClientBeta - app, status, err := client.Get(ctx, d.Id(), odata.Query{}) + id, err := parse.ParseApplicationID(d.Id()) + if err != nil { + return tf.ErrorDiagPathF(err, "id", "Parsing ID") + } + + app, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) if err != nil { if status == http.StatusNotFound { - log.Printf("[DEBUG] Application with Object ID %q was not found - removing from state", d.Id()) + log.Printf("[DEBUG] Application with Object ID %q was not found - removing from state", id.ApplicationId) d.SetId("") return nil } - return tf.ErrorDiagPathF(err, "id", "Retrieving Application with object ID %q", d.Id()) + return tf.ErrorDiagPathF(err, "id", "Retrieving Application with object ID %q", id.ApplicationId) } tf.Set(d, "api", flattenApplicationApi(app.Api, false)) @@ -1331,35 +1352,39 @@ func applicationResourceRead(ctx context.Context, d *pluginsdk.ResourceData, met func applicationResourceDelete(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { client := meta.(*clients.Client).Applications.ApplicationsClientBeta - appId := d.Id() - _, status, err := client.Get(ctx, appId, odata.Query{}) + id, err := parse.ParseApplicationID(d.Id()) + if err != nil { + return tf.ErrorDiagPathF(err, "id", "Parsing ID") + } + + _, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) if err != nil { if status == http.StatusNotFound { - return tf.ErrorDiagPathF(fmt.Errorf("Application was not found"), "id", "Retrieving Application with object ID %q", appId) + return tf.ErrorDiagPathF(fmt.Errorf("Application was not found"), "id", "Retrieving Application with object ID %q", id.ApplicationId) } - return tf.ErrorDiagPathF(err, "id", "Retrieving application with object ID %q", appId) + return tf.ErrorDiagPathF(err, "id", "Retrieving application with object ID %q", id.ApplicationId) } - status, err = client.Delete(ctx, appId) + status, err = client.Delete(ctx, id.ApplicationId) if err != nil { - return tf.ErrorDiagPathF(err, "id", "Deleting application with object ID %q, got status %d", appId, status) + return tf.ErrorDiagPathF(err, "id", "Deleting application with object ID %q, got status %d", id.ApplicationId, status) } // Wait for application object to be deleted 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, appId, odata.Query{}); err != nil { + if _, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { - return tf.ErrorDiagF(err, "Waiting for deletion of application with object ID %q", appId) + return tf.ErrorDiagF(err, "Waiting for deletion of application with object ID %q", id.ApplicationId) } return nil diff --git a/internal/services/applications/migrations/application_password_resource.go b/internal/services/applications/migrations/application_password_resource.go index 1b436df436..718a031bc8 100644 --- a/internal/services/applications/migrations/application_password_resource.go +++ b/internal/services/applications/migrations/application_password_resource.go @@ -10,25 +10,22 @@ import ( "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" "github.com/hashicorp/terraform-provider-azuread/internal/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azuread/internal/tf/validation" ) func ResourceApplicationPasswordInstanceResourceV0() *pluginsdk.Resource { return &pluginsdk.Resource{ Schema: map[string]*pluginsdk.Schema{ "application_object_id": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, }, "key_id": { - Type: pluginsdk.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + ForceNew: true, }, "description": { @@ -39,19 +36,17 @@ func ResourceApplicationPasswordInstanceResourceV0() *pluginsdk.Resource { }, "value": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - Sensitive: true, - ValidateFunc: validation.StringLenBetween(1, 863), + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + Sensitive: true, }, "start_date": { - Type: pluginsdk.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - ValidateFunc: validation.IsRFC3339Time, + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + ForceNew: true, }, "end_date": { @@ -60,15 +55,13 @@ func ResourceApplicationPasswordInstanceResourceV0() *pluginsdk.Resource { Computed: true, ForceNew: true, ExactlyOneOf: []string{"end_date_relative"}, - ValidateFunc: validation.IsRFC3339Time, }, "end_date_relative": { - Type: pluginsdk.TypeString, - Optional: true, - ForceNew: true, - ExactlyOneOf: []string{"end_date"}, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + ExactlyOneOf: []string{"end_date"}, }, }, } diff --git a/internal/services/applications/migrations/application_resource.go b/internal/services/applications/migrations/application_resource.go index 9320f79cf3..1e00ed7faf 100644 --- a/internal/services/applications/migrations/application_resource.go +++ b/internal/services/applications/migrations/application_resource.go @@ -5,8 +5,11 @@ package migrations import ( "context" + "fmt" "log" + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" "github.com/hashicorp/terraform-provider-azuread/internal/tf/pluginsdk" "github.com/manicminer/hamilton/msgraph" ) @@ -473,3 +476,551 @@ func ResourceApplicationInstanceStateUpgradeV0(_ context.Context, rawState map[s return rawState, nil } + +func ResourceApplicationInstanceResourceV1() *pluginsdk.Resource { + return &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "display_name": { + Type: pluginsdk.TypeString, + Required: true, + }, + + "api": { + Type: pluginsdk.TypeList, + Optional: true, + MaxItems: 1, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "known_client_applications": { + Type: pluginsdk.TypeSet, + Optional: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "mapped_claims_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "oauth2_permission_scope": { + Type: pluginsdk.TypeSet, + Optional: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "id": { + Type: pluginsdk.TypeString, + Required: true, + }, + + "admin_consent_description": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "admin_consent_display_name": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + }, + + "type": { + Type: pluginsdk.TypeString, + Optional: true, + Default: msgraph.PermissionScopeTypeUser, + }, + + "user_consent_description": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "user_consent_display_name": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "value": { + Type: pluginsdk.TypeString, + Optional: true, + }, + }, + }, + }, + + "requested_access_token_version": { + Type: pluginsdk.TypeInt, + Optional: true, + Default: 1, + }, + }, + }, + }, + + "app_role": { + Type: pluginsdk.TypeSet, + Optional: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "id": { + Type: pluginsdk.TypeString, + Required: true, + }, + + "allowed_member_types": { + Type: pluginsdk.TypeSet, + Required: true, + MinItems: 1, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "description": { + Type: pluginsdk.TypeString, + Required: true, + }, + + "display_name": { + Type: pluginsdk.TypeString, + Required: true, + }, + + "enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: true, + }, + + "value": { + Type: pluginsdk.TypeString, + Optional: true, + }, + }, + }, + }, + + "app_role_ids": { + Type: pluginsdk.TypeMap, + Computed: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "description": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "device_only_auth_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "fallback_public_client_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "feature_tags": { + Type: pluginsdk.TypeList, + Optional: true, + Computed: true, + ConflictsWith: []string{"tags"}, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "custom_single_sign_on": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "enterprise": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "gallery": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "hide": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + }, + }, + }, + + "group_membership_claims": { + Type: pluginsdk.TypeSet, + Optional: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "identifier_uris": { + Type: pluginsdk.TypeSet, + Optional: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "logo_image": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "marketing_url": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "notes": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "oauth2_permission_scope_ids": { + Type: pluginsdk.TypeMap, + Computed: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "oauth2_post_response_required": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "optional_claims": { + Type: pluginsdk.TypeList, + Optional: true, + MaxItems: 1, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "access_token": &pluginsdk.Schema{ + Type: pluginsdk.TypeList, + Optional: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + }, + + "source": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "essential": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + + "additional_properties": { + Type: pluginsdk.TypeList, + Optional: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + }, + }, + }, + "id_token": &pluginsdk.Schema{ + Type: pluginsdk.TypeList, + Optional: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + }, + + "source": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "essential": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + + "additional_properties": { + Type: pluginsdk.TypeList, + Optional: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + }, + }, + }, + "saml2_token": &pluginsdk.Schema{ + Type: pluginsdk.TypeList, + Optional: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + }, + + "source": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "essential": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + + "additional_properties": { + Type: pluginsdk.TypeList, + Optional: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + }, + }, + }, + }, + }, + }, + + "owners": { + Type: pluginsdk.TypeSet, + Optional: true, + Set: pluginsdk.HashString, + MaxItems: 100, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "privacy_statement_url": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "public_client": { + Type: pluginsdk.TypeList, + Optional: true, + MaxItems: 1, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "redirect_uris": { + Type: pluginsdk.TypeSet, + Optional: true, + MaxItems: 256, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + }, + }, + }, + + "required_resource_access": { + Type: pluginsdk.TypeSet, + Optional: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "resource_app_id": { + Type: pluginsdk.TypeString, + Required: true, + }, + + "resource_access": { + Type: pluginsdk.TypeList, + Required: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "id": { + Type: pluginsdk.TypeString, + Required: true, + }, + + "type": { + Type: pluginsdk.TypeString, + Required: true, + }, + }, + }, + }, + }, + }, + }, + + "service_management_reference": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "sign_in_audience": { + Type: pluginsdk.TypeString, + Optional: true, + Default: msgraph.SignInAudienceAzureADMyOrg, + }, + + "single_page_application": { + Type: pluginsdk.TypeList, + Optional: true, + MaxItems: 1, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "redirect_uris": { + Type: pluginsdk.TypeSet, + Optional: true, + MaxItems: 256, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + }, + }, + }, + + "support_url": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "tags": { + Type: pluginsdk.TypeSet, + Optional: true, + Computed: true, + Set: pluginsdk.HashString, + ConflictsWith: []string{"feature_tags"}, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "template_id": { + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + }, + + "terms_of_service_url": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "web": { + Type: pluginsdk.TypeList, + Optional: true, + MaxItems: 1, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "homepage_url": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "logout_url": { + Type: pluginsdk.TypeString, + Optional: true, + }, + + "redirect_uris": { + Type: pluginsdk.TypeSet, + Optional: true, + MaxItems: 256, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "implicit_grant": { + Type: pluginsdk.TypeList, + Optional: true, + MaxItems: 1, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "access_token_issuance_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + + "id_token_issuance_enabled": { + Type: pluginsdk.TypeBool, + Optional: true, + }, + }, + }, + }, + }, + }, + }, + + "application_id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "client_id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "object_id": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "logo_url": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "prevent_duplicate_names": { + Type: pluginsdk.TypeBool, + Optional: true, + Default: false, + }, + + "publisher_domain": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "disabled_by_microsoft": { + Type: pluginsdk.TypeString, + Computed: true, + }, + }, + } +} + +func ResourceApplicationInstanceStateUpgradeV1(_ context.Context, rawState map[string]interface{}, _ interface{}) (map[string]interface{}, error) { + log.Println("[DEBUG] Migrating ID from v1 to v2 format") + oldId := rawState["id"].(string) + if _, err := uuid.ParseUUID(oldId); err != nil { + return rawState, fmt.Errorf("parsing ID for `azuread_application`: %+v", err) + } + + newId := parse.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 index 95ba467043..435ffa2cd3 100644 --- a/internal/services/applications/parse/application.go +++ b/internal/services/applications/parse/application.go @@ -2,7 +2,6 @@ package parse import ( "fmt" - "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" "github.com/hashicorp/terraform-provider-azuread/internal/tf/validation" ) diff --git a/internal/services/applications/parse/credentials.go b/internal/services/applications/parse/credentials.go index b4d602b188..670ffc5870 100644 --- a/internal/services/applications/parse/credentials.go +++ b/internal/services/applications/parse/credentials.go @@ -8,6 +8,8 @@ import ( "strings" ) +// TODO: Remove this legacy ID in v3.0 + type CredentialId struct { ObjectId string KeyType string From 51d4c6a76fb66dc7f2c54c85e30a61b3258b8388 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 18 Oct 2023 19:23:22 +0100 Subject: [PATCH 22/46] azuread_service_principal: support `client_id` and deprecate `application_id` --- .../applications/application_data_source.go | 1 + .../application_data_source_test.go | 6 +- ..._federated_identity_credential_resource.go | 1 + .../service_principal_data_source.go | 61 +++++++----- .../service_principal_data_source_test.go | 28 +++++- .../service_principal_resource.go | 96 +++++++++++-------- .../service_principal_resource_test.go | 71 ++++++++++---- .../service_principals_data_source.go | 60 ++++++++---- .../service_principals_data_source_test.go | 51 +++++++--- .../serviceprincipals/serviceprincipals.go | 4 +- 10 files changed, 262 insertions(+), 117 deletions(-) diff --git a/internal/services/applications/application_data_source.go b/internal/services/applications/application_data_source.go index d55ea33e19..85e44106b2 100644 --- a/internal/services/applications/application_data_source.go +++ b/internal/services/applications/application_data_source.go @@ -44,6 +44,7 @@ func applicationDataSource() *pluginsdk.Resource { Computed: true, ExactlyOneOf: []string{"application_id", "client_id", "display_name", "object_id"}, ValidateDiagFunc: validation.ValidateDiag(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", }, "client_id": { diff --git a/internal/services/applications/application_data_source_test.go b/internal/services/applications/application_data_source_test.go index 3edff3e6b1..f0ab09f400 100644 --- a/internal/services/applications/application_data_source_test.go +++ b/internal/services/applications/application_data_source_test.go @@ -25,13 +25,13 @@ func TestAccApplicationDataSource_byObjectId(t *testing.T) { }) } -func TestAccApplicationDataSource_byApplicationId(t *testing.T) { +func TestAccApplicationDataSource_byApplicationIdDeprecated(t *testing.T) { data := acceptance.BuildTestData(t, "data.azuread_application", "test") r := ApplicationDataSource{} data.DataSourceTest(t, []acceptance.TestStep{ { - Config: r.applicationId(data), + Config: r.applicationIdDeprecated(data), Check: r.testCheck(data), }, }) @@ -101,7 +101,7 @@ data "azuread_application" "test" { `, ApplicationResource{}.complete(data)) } -func (ApplicationDataSource) applicationId(data acceptance.TestData) string { +func (ApplicationDataSource) applicationIdDeprecated(data acceptance.TestData) string { return fmt.Sprintf(` %[1]s diff --git a/internal/services/applications/application_federated_identity_credential_resource.go b/internal/services/applications/application_federated_identity_credential_resource.go index 7fdafd9635..adf74516ae 100644 --- a/internal/services/applications/application_federated_identity_credential_resource.go +++ b/internal/services/applications/application_federated_identity_credential_resource.go @@ -61,6 +61,7 @@ func applicationFederatedIdentityCredentialResource() *pluginsdk.Resource { Computed: 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), }, diff --git a/internal/services/serviceprincipals/service_principal_data_source.go b/internal/services/serviceprincipals/service_principal_data_source.go index 86417b3b3e..db9f0479d1 100644 --- a/internal/services/serviceprincipals/service_principal_data_source.go +++ b/internal/services/serviceprincipals/service_principal_data_source.go @@ -30,30 +30,40 @@ func servicePrincipalData() *pluginsdk.Resource { Schema: map[string]*pluginsdk.Schema{ "object_id": { - Description: "The object ID of the service principal", - Type: pluginsdk.TypeString, - Optional: true, - Computed: true, - ExactlyOneOf: []string{"application_id", "display_name", "object_id"}, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + Description: "The object ID of the service principal", + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + ExactlyOneOf: []string{"client_id", "application_id", "display_name", "object_id"}, + ValidateFunc: validation.IsUUID, }, "display_name": { - Description: "The display name of the application associated with this service principal", - Type: pluginsdk.TypeString, - Optional: true, - Computed: true, - ExactlyOneOf: []string{"application_id", "display_name", "object_id"}, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Description: "The display name 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.StringIsNotEmpty, + }, + + "client_id": { + Description: "The 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, }, "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{"application_id", "display_name", "object_id"}, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + 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": { @@ -331,9 +341,15 @@ func servicePrincipalDataSourceRead(ctx context.Context, d *pluginsdk.ResourceDa return tf.ErrorDiagF(nil, "No service principal found matching display name: %q", displayName) } } else { - applicationId := d.Get("application_id").(string) + var clientId string + if v := d.Get("client_id").(string); v != "" { + clientId = v + } else { + clientId = d.Get("application_id").(string) + } + query := odata.Query{ - Filter: fmt.Sprintf("appId eq '%s'", applicationId), + Filter: fmt.Sprintf("appId eq '%s'", clientId), } result, _, err := client.List(ctx, query) @@ -349,14 +365,14 @@ func servicePrincipalDataSourceRead(ctx context.Context, d *pluginsdk.ResourceDa continue } - if *sp.AppId == applicationId { + if *sp.AppId == clientId { servicePrincipal = &sp break } } if servicePrincipal == nil { - return tf.ErrorDiagF(nil, "No service principal found for application ID: %q", applicationId) + return tf.ErrorDiagF(nil, "No service principal found for application ID: %q", clientId) } } @@ -383,6 +399,7 @@ func servicePrincipalDataSourceRead(ctx context.Context, d *pluginsdk.ResourceDa tf.Set(d, "app_roles", helpers.ApplicationFlattenAppRoles(servicePrincipal.AppRoles)) tf.Set(d, "application_id", servicePrincipal.AppId) tf.Set(d, "application_tenant_id", servicePrincipal.AppOwnerOrganizationId) + tf.Set(d, "client_id", servicePrincipal.AppId) tf.Set(d, "description", servicePrincipal.Description) tf.Set(d, "display_name", servicePrincipal.DisplayName) tf.Set(d, "feature_tags", helpers.ApplicationFlattenFeatures(servicePrincipal.Tags, false)) diff --git a/internal/services/serviceprincipals/service_principal_data_source_test.go b/internal/services/serviceprincipals/service_principal_data_source_test.go index 7fa8e93dc0..b5bc786139 100644 --- a/internal/services/serviceprincipals/service_principal_data_source_test.go +++ b/internal/services/serviceprincipals/service_principal_data_source_test.go @@ -15,13 +15,25 @@ import ( type ServicePrincipalDataSource struct{} -func TestAccServicePrincipalDataSource_byApplicationId(t *testing.T) { +func TestAccServicePrincipalDataSource_byClientId(t *testing.T) { data := acceptance.BuildTestData(t, "data.azuread_service_principal", "test") r := ServicePrincipalDataSource{} data.DataSourceTest(t, []acceptance.TestStep{ { - Config: r.byApplicationId(data), + Config: r.byClientId(data), + Check: r.testCheckFunc(data), + }, + }) +} + +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), }, }) @@ -98,7 +110,17 @@ func (ServicePrincipalDataSource) testCheckFunc(data acceptance.TestData) accept ) } -func (ServicePrincipalDataSource) byApplicationId(data acceptance.TestData) string { +func (ServicePrincipalDataSource) byClientId(data acceptance.TestData) string { + return fmt.Sprintf(` +%[1]s + +data "azuread_service_principal" "test" { + client_id = azuread_service_principal.test.client_id +} +`, ServicePrincipalResource{}.complete(data)) +} + +func (ServicePrincipalDataSource) byDeprecatedApplicationId(data acceptance.TestData) string { return fmt.Sprintf(` %[1]s diff --git a/internal/services/serviceprincipals/service_principal_resource.go b/internal/services/serviceprincipals/service_principal_resource.go index d2270d8877..17d107ac0c 100644 --- a/internal/services/serviceprincipals/service_principal_resource.go +++ b/internal/services/serviceprincipals/service_principal_resource.go @@ -12,6 +12,7 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" @@ -47,12 +48,25 @@ func servicePrincipalResource() *pluginsdk.Resource { }), Schema: map[string]*pluginsdk.Schema{ + "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 + 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, - Required: true, - ForceNew: true, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + 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": { @@ -67,8 +81,8 @@ func servicePrincipalResource() *pluginsdk.Resource { Type: pluginsdk.TypeSet, Optional: true, Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Type: pluginsdk.TypeString, + ValidateFunc: validation.StringIsNotEmpty, }, }, @@ -176,8 +190,8 @@ func servicePrincipalResource() *pluginsdk.Resource { Type: pluginsdk.TypeSet, Optional: true, Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Type: pluginsdk.TypeString, + ValidateFunc: validation.StringIsNotEmpty, }, }, @@ -187,8 +201,8 @@ func servicePrincipalResource() *pluginsdk.Resource { Optional: true, Set: pluginsdk.HashString, Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + Type: pluginsdk.TypeString, + ValidateFunc: validation.IsUUID, }, }, @@ -299,10 +313,10 @@ func servicePrincipalResource() *pluginsdk.Resource { Elem: &pluginsdk.Resource{ Schema: map[string]*pluginsdk.Schema{ "relay_state": { - Description: "The relative URI the service provider would redirect to after completion of the single sign-on flow", - Type: pluginsdk.TypeString, - Optional: true, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Description: "The relative URI the service provider would redirect to after completion of the single sign-on flow", + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, }, }, }, @@ -355,17 +369,22 @@ func servicePrincipalResourceCreate(ctx context.Context, d *pluginsdk.ResourceDa callerId := meta.(*clients.Client).ObjectID tenantId := meta.(*clients.Client).TenantID - appId := d.Get("application_id").(string) + var clientId string + if v := d.Get("client_id").(string); v != "" { + clientId = v + } else { + clientId = d.Get("application_id").(string) + } var servicePrincipal *msgraph.ServicePrincipal var err error if d.Get("use_existing").(bool) { // Assume that a service principal already exists and try to look for it, whilst retrying to defeat eventual consistency - servicePrincipal, err = findByAppIdWithTimeout(ctx, 5*time.Minute, client, appId) + servicePrincipal, err = findByClientIdWithTimeout(ctx, 5*time.Minute, client, clientId) } else { // Otherwise perform a single List operation to check for an existing service principal - servicePrincipal, err = findByAppId(ctx, client, appId) + servicePrincipal, err = findByClientId(ctx, client, clientId) } if err != nil { return tf.ErrorDiagF(err, "Could not list existing service principals") @@ -400,15 +419,15 @@ func servicePrincipalResourceCreate(ctx context.Context, d *pluginsdk.ResourceDa tempDescription := fmt.Sprintf("TERRAFORM_UPDATE_%s", uuid) properties := msgraph.ServicePrincipal{ - AccountEnabled: utils.Bool(d.Get("account_enabled").(bool)), + AccountEnabled: pointer.To(d.Get("account_enabled").(bool)), AlternativeNames: tf.ExpandStringSlicePtr(d.Get("alternative_names").(*pluginsdk.Set).List()), - AppId: utils.String(d.Get("application_id").(string)), - AppRoleAssignmentRequired: utils.Bool(d.Get("app_role_assignment_required").(bool)), - Description: utils.NullableString(tempDescription), - LoginUrl: utils.NullableString(d.Get("login_url").(string)), - Notes: utils.NullableString(d.Get("notes").(string)), + AppId: pointer.To(clientId), + AppRoleAssignmentRequired: pointer.To(d.Get("app_role_assignment_required").(bool)), + Description: tf.NullableString(tempDescription), + LoginUrl: tf.NullableString(d.Get("login_url").(string)), + Notes: tf.NullableString(d.Get("notes").(string)), NotificationEmailAddresses: tf.ExpandStringSlicePtr(d.Get("notification_email_addresses").(*pluginsdk.Set).List()), - PreferredSingleSignOnMode: utils.NullableString(d.Get("preferred_single_sign_on_mode").(string)), + PreferredSingleSignOnMode: tf.NullableString(d.Get("preferred_single_sign_on_mode").(string)), SamlSingleSignOnSettings: expandSamlSingleSignOn(d.Get("saml_single_sign_on").([]interface{})), Tags: &tags, } @@ -424,7 +443,7 @@ func servicePrincipalResourceCreate(ctx context.Context, d *pluginsdk.ResourceDa } // @odata.id returned by API cannot be relied upon, so construct our own - callerObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + callerObject.ODataId = (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, callerId))) ownersFirst20 := msgraph.Owners{*callerObject} @@ -446,7 +465,7 @@ func servicePrincipalResourceCreate(ctx context.Context, d *pluginsdk.ResourceDa } ownerObject := msgraph.DirectoryObject{ - ODataId: (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + ODataId: (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, ownerId))), Id: &ownerId, } @@ -479,7 +498,7 @@ func servicePrincipalResourceCreate(ctx context.Context, d *pluginsdk.ResourceDa DirectoryObject: msgraph.DirectoryObject{ Id: servicePrincipal.ID(), }, - Description: utils.NullableString(d.Get("description").(string)), + Description: tf.NullableString(d.Get("description").(string)), }) if err != nil { if status == http.StatusNotFound { @@ -521,16 +540,16 @@ func servicePrincipalResourceUpdate(ctx context.Context, d *pluginsdk.ResourceDa properties := msgraph.ServicePrincipal{ DirectoryObject: msgraph.DirectoryObject{ - Id: utils.String(d.Id()), + Id: pointer.To(d.Id()), }, AlternativeNames: tf.ExpandStringSlicePtr(d.Get("alternative_names").(*pluginsdk.Set).List()), - AccountEnabled: utils.Bool(d.Get("account_enabled").(bool)), - AppRoleAssignmentRequired: utils.Bool(d.Get("app_role_assignment_required").(bool)), - Description: utils.NullableString(d.Get("description").(string)), - LoginUrl: utils.NullableString(d.Get("login_url").(string)), - Notes: utils.NullableString(d.Get("notes").(string)), + AccountEnabled: pointer.To(d.Get("account_enabled").(bool)), + AppRoleAssignmentRequired: pointer.To(d.Get("app_role_assignment_required").(bool)), + Description: tf.NullableString(d.Get("description").(string)), + LoginUrl: tf.NullableString(d.Get("login_url").(string)), + Notes: tf.NullableString(d.Get("notes").(string)), NotificationEmailAddresses: tf.ExpandStringSlicePtr(d.Get("notification_email_addresses").(*pluginsdk.Set).List()), - PreferredSingleSignOnMode: utils.NullableString(d.Get("preferred_single_sign_on_mode").(string)), + PreferredSingleSignOnMode: tf.NullableString(d.Get("preferred_single_sign_on_mode").(string)), SamlSingleSignOnSettings: expandSamlSingleSignOn(d.Get("saml_single_sign_on").([]interface{})), Tags: &tags, } @@ -554,7 +573,7 @@ func servicePrincipalResourceUpdate(ctx context.Context, d *pluginsdk.ResourceDa newOwners := make(msgraph.Owners, 0) for _, ownerId := range ownersToAdd { newOwners = append(newOwners, msgraph.DirectoryObject{ - ODataId: (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + ODataId: (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, ownerId))), Id: &ownerId, }) @@ -608,6 +627,7 @@ func servicePrincipalResourceRead(ctx context.Context, d *pluginsdk.ResourceData tf.Set(d, "app_roles", helpers.ApplicationFlattenAppRoles(servicePrincipal.AppRoles)) tf.Set(d, "application_id", servicePrincipal.AppId) tf.Set(d, "application_tenant_id", servicePrincipal.AppOwnerOrganizationId) + tf.Set(d, "client_id", servicePrincipal.AppId) tf.Set(d, "description", servicePrincipal.Description) tf.Set(d, "display_name", servicePrincipal.DisplayName) tf.Set(d, "feature_tags", helpers.ApplicationFlattenFeatures(servicePrincipal.Tags, false)) @@ -664,11 +684,11 @@ func servicePrincipalResourceDelete(ctx context.Context, d *pluginsdk.ResourceDa client.BaseClient.DisableRetries = true if _, status, err := client.Get(ctx, servicePrincipalId, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of group with object ID %q", servicePrincipalId) } diff --git a/internal/services/serviceprincipals/service_principal_resource_test.go b/internal/services/serviceprincipals/service_principal_resource_test.go index d4850a7610..febc875bd3 100644 --- a/internal/services/serviceprincipals/service_principal_resource_test.go +++ b/internal/services/serviceprincipals/service_principal_resource_test.go @@ -10,12 +10,12 @@ import ( "os" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type ServicePrincipalResource struct{} @@ -313,6 +313,21 @@ 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.ServicePrincipalsClient client.BaseClient.DisableRetries = true @@ -325,7 +340,7 @@ func (r ServicePrincipalResource) Exists(ctx context.Context, clients *clients.C } return nil, fmt.Errorf("failed to retrieve Service Principal with object ID %q: %+v", state.ID, err) } - return utils.Bool(servicePrincipal.ID() != nil && *servicePrincipal.ID() == state.ID), nil + return pointer.To(servicePrincipal.ID() != nil && *servicePrincipal.ID() == state.ID), nil } func (ServicePrincipalResource) basic(data acceptance.TestData) string { @@ -337,7 +352,7 @@ resource "azuread_application" "test" { } resource "azuread_service_principal" "test" { - application_id = azuread_application.test.application_id + client_id = azuread_application.test.client_id } `, data.RandomInteger) } @@ -415,7 +430,7 @@ func (r ServicePrincipalResource) complete(data acceptance.TestData) string { %[1]s resource "azuread_service_principal" "test" { - application_id = azuread_application.test.application_id + client_id = azuread_application.test.client_id account_enabled = false alternative_names = ["foo", "bar"] @@ -449,7 +464,7 @@ func (r ServicePrincipalResource) featureTags(data acceptance.TestData) string { %[1]s resource "azuread_service_principal" "test" { - application_id = azuread_application.test.application_id + client_id = azuread_application.test.client_id account_enabled = false alternative_names = ["foo", "bar"] @@ -483,7 +498,7 @@ func (r ServicePrincipalResource) noFeatureTags(data acceptance.TestData) string %[1]s resource "azuread_service_principal" "test" { - application_id = azuread_application.test.application_id + client_id = azuread_application.test.client_id account_enabled = false alternative_names = ["foo", "bar"] @@ -546,8 +561,8 @@ resource "azuread_application" "test" { } resource "azuread_service_principal" "test" { - application_id = azuread_application.test.application_id - owners = [] + client_id = azuread_application.test.client_id + owners = [] } `, r.templateThreeUsers(data), data.RandomInteger) } @@ -561,7 +576,7 @@ resource "azuread_application" "test" { } resource "azuread_service_principal" "test" { - application_id = azuread_application.test.application_id + client_id = azuread_application.test.client_id owners = [ azuread_user.testA.object_id, ] @@ -578,7 +593,7 @@ resource "azuread_application" "test" { } resource "azuread_service_principal" "test" { - application_id = azuread_application.test.application_id + client_id = azuread_application.test.client_id owners = [ azuread_user.testA.object_id, azuread_user.testB.object_id, @@ -604,8 +619,8 @@ resource "azuread_application" "owner" { } resource "azuread_service_principal" "owner" { - count = 27 - application_id = azuread_application.owner[count.index].application_id + count = 27 + client_id = azuread_application.owner[count.index].client_id } resource "azuread_user" "owner" { @@ -620,7 +635,7 @@ resource "azuread_application" "test" { } resource "azuread_service_principal" "test" { - application_id = azuread_application.test.application_id + client_id = azuread_application.test.client_id owners = flatten([ data.azuread_client_config.test.object_id, @@ -636,8 +651,8 @@ func (ServicePrincipalResource) useExisting(_ acceptance.TestData) string { provider "azuread" {} resource "azuread_service_principal" "msgraph" { - application_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph - use_existing = true + client_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph + use_existing = true } ` } @@ -655,9 +670,9 @@ resource "azuread_application" "test" { } resource "azuread_service_principal" "test" { - application_id = azuread_application.test.application_id - owners = [data.azuread_client_config.test.object_id] - use_existing = true + client_id = azuread_application.test.client_id + owners = [data.azuread_client_config.test.object_id] + use_existing = true } `, data.RandomInteger, testApplicationTemplateId) } @@ -679,15 +694,29 @@ resource "azuread_application" "testC" { } resource "azuread_service_principal" "testA" { - application_id = azuread_application.testA.application_id + client_id = azuread_application.testA.client_id } resource "azuread_service_principal" "testB" { - application_id = azuread_application.testB.application_id + client_id = azuread_application.testB.client_id } resource "azuread_service_principal" "testC" { - application_id = azuread_application.testC.application_id + client_id = azuread_application.testC.client_id +} +`, 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 48f6495a38..03cfa41e88 100644 --- a/internal/services/serviceprincipals/service_principals_data_source.go +++ b/internal/services/serviceprincipals/service_principals_data_source.go @@ -30,16 +30,29 @@ func servicePrincipalsDataSource() *pluginsdk.Resource { }, Schema: map[string]*pluginsdk.Schema{ + "client_ids": { + Description: "The 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, + }, + }, + "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{"application_ids", "display_names", "object_ids", "return_all"}, + ExactlyOneOf: []string{"client_ids", "application_ids", "display_names", "object_ids", "return_all"}, Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + 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": { @@ -47,10 +60,10 @@ func servicePrincipalsDataSource() *pluginsdk.Resource { Type: pluginsdk.TypeList, Optional: true, Computed: true, - ExactlyOneOf: []string{"application_ids", "display_names", "object_ids", "return_all"}, + ExactlyOneOf: []string{"client_ids", "application_ids", "display_names", "object_ids", "return_all"}, Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - ValidateDiagFunc: validation.ValidateDiag(validation.StringIsNotEmpty), + Type: pluginsdk.TypeString, + ValidateFunc: validation.StringIsNotEmpty, }, }, @@ -59,10 +72,10 @@ func servicePrincipalsDataSource() *pluginsdk.Resource { Type: pluginsdk.TypeList, Optional: true, Computed: true, - ExactlyOneOf: []string{"application_ids", "display_names", "object_ids", "return_all"}, + ExactlyOneOf: []string{"client_ids", "application_ids", "display_names", "object_ids", "return_all"}, Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - ValidateDiagFunc: validation.ValidateDiag(validation.IsUUID), + Type: pluginsdk.TypeString, + ValidateFunc: validation.IsUUID, }, }, @@ -80,7 +93,7 @@ func servicePrincipalsDataSource() *pluginsdk.Resource { Optional: true, Default: false, ConflictsWith: []string{"ignore_missing"}, - ExactlyOneOf: []string{"application_ids", "display_names", "object_ids", "return_all"}, + ExactlyOneOf: []string{"client_ids", "application_ids", "display_names", "object_ids", "return_all"}, }, "service_principals": { @@ -105,6 +118,7 @@ func servicePrincipalsDataSource() *pluginsdk.Resource { 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": { @@ -113,6 +127,12 @@ func servicePrincipalsDataSource() *pluginsdk.Resource { Computed: true, }, + "client_id": { + Description: "The application ID (client ID) for the associated application", + Type: pluginsdk.TypeString, + Computed: true, + }, + "display_name": { Description: "The display name of the application associated with this service principal", Type: pluginsdk.TypeString, @@ -183,6 +203,12 @@ func servicePrincipalsDataSourceRead(ctx context.Context, d *pluginsdk.ResourceD ignoreMissing := d.Get("ignore_missing").(bool) returnAll := d.Get("return_all").(bool) + 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) + } if returnAll { result, _, err := client.List(ctx, odata.Query{}) if err != nil { @@ -196,9 +222,9 @@ func servicePrincipalsDataSourceRead(ctx context.Context, d *pluginsdk.ResourceD } servicePrincipals = append(servicePrincipals, *result...) - } else if applicationIds, ok := d.Get("application_ids").([]interface{}); ok && len(applicationIds) > 0 { - expectedCount = len(applicationIds) - for _, v := range applicationIds { + } else if len(clientIdsToSearch) > 0 { + expectedCount = len(clientIdsToSearch) + for _, v := range clientIdsToSearch { query := odata.Query{ Filter: fmt.Sprintf("appId eq '%s'", v), } @@ -273,7 +299,7 @@ func servicePrincipalsDataSourceRead(ctx context.Context, d *pluginsdk.ResourceD return tf.ErrorDiagF(fmt.Errorf("Expected: %d, Actual: %d", expectedCount, len(servicePrincipals)), "Unexpected number of service principals returned") } - applicationIds := make([]string, 0) + clientIds := make([]string, 0) displayNames := make([]string, 0) objectIds := make([]string, 0) spList := make([]map[string]interface{}, 0) @@ -285,7 +311,7 @@ func servicePrincipalsDataSourceRead(ctx context.Context, d *pluginsdk.ResourceD objectIds = append(objectIds, *s.ID()) displayNames = append(displayNames, *s.DisplayName) if s.AppId != nil { - applicationIds = append(applicationIds, *s.AppId) + clientIds = append(clientIds, *s.AppId) } servicePrincipalNames := make([]string, 0) @@ -304,6 +330,7 @@ func servicePrincipalsDataSourceRead(ctx context.Context, d *pluginsdk.ResourceD sp["app_role_assignment_required"] = s.AppRoleAssignmentRequired sp["application_id"] = s.AppId sp["application_tenant_id"] = s.AppOwnerOrganizationId + sp["client_id"] = s.AppId sp["object_id"] = s.ID() sp["preferred_single_sign_on_mode"] = s.PreferredSingleSignOnMode sp["saml_metadata_url"] = s.SamlMetadataUrl @@ -321,7 +348,8 @@ func servicePrincipalsDataSourceRead(ctx context.Context, d *pluginsdk.ResourceD } d.SetId("serviceprincipals#" + base64.URLEncoding.EncodeToString(h.Sum(nil))) - tf.Set(d, "application_ids", applicationIds) + tf.Set(d, "application_ids", clientIds) + tf.Set(d, "client_ids", clientIds) tf.Set(d, "display_names", displayNames) tf.Set(d, "object_ids", objectIds) tf.Set(d, "service_principals", spList) diff --git a/internal/services/serviceprincipals/service_principals_data_source_test.go b/internal/services/serviceprincipals/service_principals_data_source_test.go index a1b4b1db3c..e131d764df 100644 --- a/internal/services/serviceprincipals/service_principals_data_source_test.go +++ b/internal/services/serviceprincipals/service_principals_data_source_test.go @@ -13,13 +13,27 @@ import ( type ServicePrincipalsDataSource struct{} -func TestAccServicePrincipalsDataSource_byApplicationIds(t *testing.T) { +func TestAccServicePrincipalsDataSource_byClientIds(t *testing.T) { data := acceptance.BuildTestData(t, "data.azuread_service_principals", "test") data.DataSourceTest(t, []acceptance.TestStep{{ - Config: ServicePrincipalsDataSource{}.byApplicationIds(data), + Config: ServicePrincipalsDataSource{}.byClientIds(data), Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).Key("application_ids.#").HasValue("2"), + check.That(data.ResourceName).Key("client_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_byClientIdsWithIgnoreMissing(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azuread_service_principals", "test") + + data.DataSourceTest(t, []acceptance.TestStep{{ + Config: ServicePrincipalsDataSource{}.byClientIdsWithIgnoreMissing(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).Key("client_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"), @@ -27,11 +41,11 @@ func TestAccServicePrincipalsDataSource_byApplicationIds(t *testing.T) { }}) } -func TestAccServicePrincipalsDataSource_byApplicationIdsWithIgnoreMissing(t *testing.T) { +func TestAccServicePrincipalsDataSource_byDeprecatedApplicationIds(t *testing.T) { data := acceptance.BuildTestData(t, "data.azuread_service_principals", "test") data.DataSourceTest(t, []acceptance.TestStep{{ - Config: ServicePrincipalsDataSource{}.byApplicationIdsWithIgnoreMissing(data), + 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"), @@ -180,33 +194,46 @@ data "azuread_service_principals" "test" { `, ServicePrincipalResource{}.threeServicePrincipalsABC(data)) } -func (ServicePrincipalsDataSource) byApplicationIds(data acceptance.TestData) string { +func (ServicePrincipalsDataSource) byClientIds(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, + client_ids = [ + azuread_service_principal.testA.client_id, + azuread_service_principal.testB.client_id, ] } `, ServicePrincipalResource{}.threeServicePrincipalsABC(data)) } -func (ServicePrincipalsDataSource) byApplicationIdsWithIgnoreMissing(data acceptance.TestData) string { +func (ServicePrincipalsDataSource) byClientIdsWithIgnoreMissing(data acceptance.TestData) string { return fmt.Sprintf(` %[1]s data "azuread_service_principals" "test" { ignore_missing = true + client_ids = [ + azuread_service_principal.testA.client_id, + "e0000000-0000-0000-0000-000000000000", + azuread_service_principal.testB.client_id, + ] +} +`, 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, - "e0000000-0000-0000-0000-000000000000", azuread_service_principal.testB.application_id, ] } -`, ServicePrincipalResource{}.threeServicePrincipalsABC(data), data.RandomInteger) +`, ServicePrincipalResource{}.threeServicePrincipalsABC(data)) } func (ServicePrincipalsDataSource) noNames() string { diff --git a/internal/services/serviceprincipals/serviceprincipals.go b/internal/services/serviceprincipals/serviceprincipals.go index 5d2694507e..22db232205 100644 --- a/internal/services/serviceprincipals/serviceprincipals.go +++ b/internal/services/serviceprincipals/serviceprincipals.go @@ -46,7 +46,7 @@ func flattenSamlSingleSignOn(in *msgraph.SamlSingleSignOnSettings) []map[string] }} } -func findByAppId(ctx context.Context, client *msgraph.ServicePrincipalsClient, appId string) (*msgraph.ServicePrincipal, error) { +func findByClientId(ctx context.Context, client *msgraph.ServicePrincipalsClient, appId string) (*msgraph.ServicePrincipal, error) { var servicePrincipal *msgraph.ServicePrincipal result, _, err := client.List(ctx, odata.Query{Filter: fmt.Sprintf("appId eq '%s'", appId)}) @@ -65,7 +65,7 @@ func findByAppId(ctx context.Context, client *msgraph.ServicePrincipalsClient, a return servicePrincipal, nil } -func findByAppIdWithTimeout(ctx context.Context, timeout time.Duration, client *msgraph.ServicePrincipalsClient, appId string) (*msgraph.ServicePrincipal, error) { +func findByClientIdWithTimeout(ctx context.Context, timeout time.Duration, client *msgraph.ServicePrincipalsClient, appId string) (*msgraph.ServicePrincipal, error) { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, timeout) defer cancel() From f76b3f974dcf0d44f9a117995b6df62bb67304e3 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 18 Oct 2023 22:54:03 +0100 Subject: [PATCH 23/46] documentation for `azuread_application`, also export the `object_id` attribute --- docs/resources/application.md | 8 ++- docs/resources/application_registration.md | 72 +++++++++++++++++++ .../application_registration_resource.go | 8 +++ .../application_registration_resource_test.go | 2 + 4 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 docs/resources/application_registration.md diff --git a/docs/resources/application.md b/docs/resources/application.md index f61d806d8d..dc5c5b0961 100644 --- a/docs/resources/application.md +++ b/docs/resources/application.md @@ -6,13 +6,17 @@ subcategory: "Applications" Manages an application registration within Azure Active Directory. +For a more lightweight alternative, please see the [azuread_application_registration](application_registration.html) resource. Please note that this resource should not be used together with the `azuread_application_registration` resource when managing the same application. + ## API Permissions The following API permissions are required in order to use this resource. -When authenticated with a service principal, this resource requires the following application role: `Application.ReadWrite.All` +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` + +-> When using the `Application.ReadWrite.OwnedBy` application role, you should ensure that the principal being used to run Terraform is included in the `owners` property. --> It is usually possible to create applications using this resource with just the `Application.ReadWrite.OwnedBy` application role, provided the principal being used to run Terraform is included in the `owners` property. However, this is not officially supported by the API so if you receive a `403` you need to investigate what API call is failing and add additional permissions as necessary. One commonly needed additional permission is `User.Read.All`, in case you specify additional `owners`. +Additionally, you may need the `User.Read.All` application role when including user principals in the `owners` property. When authenticated with a user principal, this resource requires one of the following directory roles: `Application Administrator` or `Global Administrator` diff --git a/docs/resources/application_registration.md b/docs/resources/application_registration.md new file mode 100644 index 0000000000..34b4d183a5 --- /dev/null +++ b/docs/resources/application_registration.md @@ -0,0 +1,72 @@ +--- +subcategory: "Applications" +--- + +# Resource: azuread_application_registration + +Manages an application registration within Azure Active Directory. + +For a more comprehensive alternative, please see the [azuread_application](application.html) resource. Please note that this resource should not be used together with the `azuread_application` resource when managing the same application. + +## API Permissions + +The following API permissions are required in order to use this resource. + +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` + +When authenticated with a user principal, this resource requires one of the following directory roles: `Application Administrator` or `Global Administrator` + +## Example Usage + +```terraform +resource "azuread_application_registration" "test" { + display_name = "Example Application" + description = "My example application" + sign_in_audience = "AzureADMyOrg" + + homepage_url = "https://app.hashitown.com/" + logout_url = "https://app.hashitown.com/logout" + marketing_url = "https://hashitown.com/" + privacy_statement_url = "https://hashitown.com/privacy" + support_url = "https://support.hashitown.com/" + terms_of_service_url = "https://hashitown.com/terms" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `description` - (Optional) A description of the application, as shown to end users. +* `display_name` - (Required) The display name for the application. +* `group_membership_claims` - (Optional) Configures the `groups` claim issued in a user or OAuth 2.0 access token that the app expects. Possible values are `None`, `SecurityGroup`, `DirectoryRole`, `ApplicationGroup` or `All`. +* `homepage_url` - (Optional) Home page or landing page of the application. +* `implicit_access_token_issuance_enabled` - (Optional) Whether this web application can request an access token using OAuth implicit flow. +* `implicit_id_token_issuance_enabled` - (Optional) Whether this web application can request an ID token using OAuth implicit flow. +* `logout_url` - (Optional) The URL that will be used by Microsoft's authorization service to sign out a user using front-channel, back-channel or SAML logout protocols. +* `marketing_url` - (Optional) URL of the marketing page for the application. +* `notes` - (Optional) User-specified notes relevant for the management of the application. +* `privacy_statement_url` - (Optional) URL of the privacy statement for the application. +* `requested_access_token_version` - (Optional) The access token version expected by this resource. Must be one of `1` or `2`, and must be `2` when `sign_in_audience` is either `AzureADandPersonalMicrosoftAccount` or `PersonalMicrosoftAccount` Defaults to `1`. +* `service_management_reference` - (Optional) References application context information from a Service or Asset Management database. +* `sign_in_audience` - (Optional) The Microsoft account types that are supported for the current application. Must be one of `AzureADMyOrg`, `AzureADMultipleOrgs`, `AzureADandPersonalMicrosoftAccount` or `PersonalMicrosoftAccount`. Defaults to `AzureADMyOrg`. +* `support_url` - (Optional) URL of the support page for the application. +* `terms_of_service_url` - (Optional) URL of the terms of service statement for the application. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `client_id` - The Client ID for the application, which is globally unique. +* `disabled_by_microsoft` - Whether Microsoft has disabled the registered application. If the application is disabled, this will be a string indicating the status/reason, e.g. `DisabledDueToViolationOfServicesAgreement` +* `id` - The resource ID for the application, for use when referencing this resource in your Terraform configuration. +* `object_id` - The object ID of the application within the tenant. +* `publisher_domain` - The verified publisher domain for the application. + +## Import + +Application Registrations can be imported using the object ID of the application, in the following format. + +```shell +terraform import azuread_application_registration.test /applications/00000000-0000-0000-0000-000000000000 +``` diff --git a/internal/services/applications/application_registration_resource.go b/internal/services/applications/application_registration_resource.go index 6b112df91f..3723190c5b 100644 --- a/internal/services/applications/application_registration_resource.go +++ b/internal/services/applications/application_registration_resource.go @@ -33,6 +33,7 @@ type ApplicationRegistrationModel struct { LogoutUrl string `tfschema:"logout_url"` MarketingUrl string `tfschema:"marketing_url"` Notes string `tfschema:"notes"` + ObjectId string `tfschema:"object_id"` PrivacyStatementUrl string `tfschema:"privacy_statement_url"` PublisherDomain string `tfschema:"publisher_domain"` RequestedAccessTokenVersion int `tfschema:"requested_access_token_version"` @@ -205,6 +206,12 @@ func (r ApplicationRegistrationResource) Attributes() map[string]*pluginsdk.Sche Computed: true, }, + "object_id": { + Description: "The object ID of the application within the tenant", + Type: pluginsdk.TypeString, + Computed: true, + }, + "publisher_domain": { Description: "The verified publisher domain for the application", Type: pluginsdk.TypeString, @@ -304,6 +311,7 @@ func (r ApplicationRegistrationResource) Read() sdk.ResourceFunc { DisplayName: pointer.From(result.DisplayName), GroupMembershipClaims: pointer.From(result.GroupMembershipClaims), Notes: string(pointer.From(result.Notes)), + ObjectId: pointer.From(result.ID()), PublisherDomain: pointer.From(result.PublisherDomain), ServiceManagementReference: string(pointer.From(result.ServiceManagementReference)), SignInAudience: pointer.From(result.SignInAudience), diff --git a/internal/services/applications/application_registration_resource_test.go b/internal/services/applications/application_registration_resource_test.go index 6631a853ee..8438189b19 100644 --- a/internal/services/applications/application_registration_resource_test.go +++ b/internal/services/applications/application_registration_resource_test.go @@ -30,6 +30,7 @@ func TestAccApplicationRegistration_basic(t *testing.T) { Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), 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-AppRegistration-%d", data.RandomInteger)), ), }, @@ -47,6 +48,7 @@ func TestAccApplicationRegistration_complete(t *testing.T) { Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), check.That(data.ResourceName).Key("client_id").Exists(), + check.That(data.ResourceName).Key("object_id").Exists(), ), }, data.ImportStep(), From 1e113e6d336f6811cf89317b24fbf16f2fbc5979 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Wed, 18 Oct 2023 23:59:06 +0100 Subject: [PATCH 24/46] documentation for `azuread_application_api_access` --- .../application_published_app_ids.md | 4 +- docs/resources/application.md | 2 +- docs/resources/application_api_access.md | 85 ++++++++++++++ docs/resources/application_registration.md | 8 +- .../application_api_access_resource.go | 97 ++++++++-------- .../application_api_access_resource_test.go | 106 +++++++----------- .../application_registration_resource.go | 20 +--- 7 files changed, 188 insertions(+), 134 deletions(-) create mode 100644 docs/resources/application_api_access.md diff --git a/docs/data-sources/application_published_app_ids.md b/docs/data-sources/application_published_app_ids.md index 713e9095d9..4935c03bfc 100644 --- a/docs/data-sources/application_published_app_ids.md +++ b/docs/data-sources/application_published_app_ids.md @@ -28,7 +28,7 @@ output "published_app_ids" { data "azuread_application_published_app_ids" "well_known" {} resource "azuread_service_principal" "msgraph" { - application_id = data.azuread_application_published_app_ids.well_known.result.MicrosoftGraph + application_id = data.azuread_application_published_app_ids.well_known.result["MicrosoftGraph"] use_existing = true } @@ -36,7 +36,7 @@ resource "azuread_application" "example" { display_name = "example" required_resource_access { - resource_app_id = data.azuread_application_published_app_ids.well_known.result.MicrosoftGraph + resource_app_id = data.azuread_application_published_app_ids.well_known.result["MicrosoftGraph"] resource_access { id = azuread_service_principal.msgraph.app_role_ids["User.Read.All"] diff --git a/docs/resources/application.md b/docs/resources/application.md index dc5c5b0961..7ac9769952 100644 --- a/docs/resources/application.md +++ b/docs/resources/application.md @@ -18,7 +18,7 @@ When authenticated with a service principal, this resource requires one of the f Additionally, you may need the `User.Read.All` application role when including user principals in the `owners` property. -When authenticated with a user principal, this resource requires one of the following directory roles: `Application Administrator` or `Global Administrator` +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` ## Example Usage diff --git a/docs/resources/application_api_access.md b/docs/resources/application_api_access.md new file mode 100644 index 0000000000..06862def13 --- /dev/null +++ b/docs/resources/application_api_access.md @@ -0,0 +1,85 @@ +--- +subcategory: "Applications" +--- + +# Resource: azuread_application_api_access + +Manages the API permissions for an application registration. + +This resource is analogous to the `required_resource_access` block in the `azuread_application` resource. When using these resources together, you should use the `ignore_changes` [lifecycle meta-argument](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle), for example: + +```terraform + +resource "azuread_application" "example" { + display_name = "example" + + lifecycle { + ignore_changes = [ + required_resource_access, + ] + } +} +``` + +## API Permissions + +The following API permissions are required in order to use this resource. + +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` + +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of the application. + +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` + +## Example Usage + +```terraform +data "azuread_application_published_app_ids" "well_known" {} + +data "azuread_service_principal" "msgraph" { + client_id = data.azuread_application_published_app_ids.well_known.result["MicrosoftGraph"] +} + +resource "azuread_application_registration" "example" { + display_name = "example" +} + +resource "azuread_application_api_access" "example_msgraph" { + application_id = azuread_application_registration.example.id + api_client_id = data.azuread_application_published_app_ids.well_known.result["MicrosoftGraph"] + + role_ids = [ + azuread_service_principal.msgraph.app_role_ids["Group.Read.All"], + azuread_service_principal.msgraph.app_role_ids["User.Read.All"], + ] + + scope_ids = [ + azuread_service_principal.msgraph.oauth2_permission_scope_ids["User.ReadWrite"], + ] +} +``` + +-> Tip: For managing permissions for an additional API, create another instance of this resource + +## Argument Reference + +The following arguments are supported: + +* `application_id` - (Required) The resource ID of the application registration. +* `api_client_id` - (Required) The client ID of the API to which access is being granted. +* `role_ids` - (Optional) A set of role IDs to be granted to the application, as published by the API. +* `scope_ids` - (Optional) A set of scope IDs to be granted to the application, as published by the API. + +-> At least one of `role_ids` or `scope_ids` must be specified. + +## Attributes Reference + +No additional attributes are exported. + +## Import + +Application API Access can be imported using the object ID of the application and the client ID of the API, in the following format. + +```shell +terraform import azuread_application_api_access.example /applications/00000000-0000-0000-0000-000000000000/apiAccess/11111111-1111-1111-1111-111111111111 +``` diff --git a/docs/resources/application_registration.md b/docs/resources/application_registration.md index 34b4d183a5..fcb39d2a8e 100644 --- a/docs/resources/application_registration.md +++ b/docs/resources/application_registration.md @@ -14,12 +14,12 @@ The following API permissions are required in order to use this resource. When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` -When authenticated with a user principal, this resource requires one of the following directory roles: `Application Administrator` or `Global Administrator` +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` ## Example Usage ```terraform -resource "azuread_application_registration" "test" { +resource "azuread_application_registration" "example" { display_name = "Example Application" description = "My example application" sign_in_audience = "AzureADMyOrg" @@ -39,7 +39,7 @@ The following arguments are supported: * `description` - (Optional) A description of the application, as shown to end users. * `display_name` - (Required) The display name for the application. -* `group_membership_claims` - (Optional) Configures the `groups` claim issued in a user or OAuth 2.0 access token that the app expects. Possible values are `None`, `SecurityGroup`, `DirectoryRole`, `ApplicationGroup` or `All`. +* `group_membership_claims` - (Optional) Configures the `groups` claim issued in a user or OAuth access token that the app expects. Possible values are `None`, `SecurityGroup`, `DirectoryRole`, `ApplicationGroup` or `All`. * `homepage_url` - (Optional) Home page or landing page of the application. * `implicit_access_token_issuance_enabled` - (Optional) Whether this web application can request an access token using OAuth implicit flow. * `implicit_id_token_issuance_enabled` - (Optional) Whether this web application can request an ID token using OAuth implicit flow. @@ -47,7 +47,7 @@ The following arguments are supported: * `marketing_url` - (Optional) URL of the marketing page for the application. * `notes` - (Optional) User-specified notes relevant for the management of the application. * `privacy_statement_url` - (Optional) URL of the privacy statement for the application. -* `requested_access_token_version` - (Optional) The access token version expected by this resource. Must be one of `1` or `2`, and must be `2` when `sign_in_audience` is either `AzureADandPersonalMicrosoftAccount` or `PersonalMicrosoftAccount` Defaults to `1`. +* `requested_access_token_version` - (Optional) The access token version expected by this resource. Must be one of `1` or `2`, and must be `2` when `sign_in_audience` is either `AzureADandPersonalMicrosoftAccount` or `PersonalMicrosoftAccount` Defaults to `2`. * `service_management_reference` - (Optional) References application context information from a Service or Asset Management database. * `sign_in_audience` - (Optional) The Microsoft account types that are supported for the current application. Must be one of `AzureADMyOrg`, `AzureADMultipleOrgs`, `AzureADandPersonalMicrosoftAccount` or `PersonalMicrosoftAccount`. Defaults to `AzureADMyOrg`. * `support_url` - (Optional) URL of the support page for the application. diff --git a/internal/services/applications/application_api_access_resource.go b/internal/services/applications/application_api_access_resource.go index cef619b4a8..aa3035e536 100644 --- a/internal/services/applications/application_api_access_resource.go +++ b/internal/services/applications/application_api_access_resource.go @@ -21,14 +21,10 @@ import ( ) type ApplicationApiAccessModel struct { - ApplicationId string `tfschema:"application_id"` - ApiClientId string `tfschema:"api_client_id"` - Permission []ApplicationApiAccessPermission `tfschema:"permission"` -} - -type ApplicationApiAccessPermission struct { - Id string `tfschema:"id"` - Type string `tfschema:"type"` + ApplicationId string `tfschema:"application_id"` + ApiClientId string `tfschema:"api_client_id"` + RoleIds []string `tfschema:"role_ids"` + ScopeIds []string `tfschema:"scope_ids"` } type ApplicationApiAccessResource struct{} @@ -65,32 +61,25 @@ func (r ApplicationApiAccessResource) Arguments() map[string]*pluginsdk.Schema { ValidateFunc: validation.IsUUID, }, - "permission": { - Description: "A list of permission IDs and their types that are being granted to the application", - Type: pluginsdk.TypeSet, - Required: true, - Elem: &pluginsdk.Resource{ - Schema: map[string]*pluginsdk.Schema{ - "id": { - Description: "The ID of the app role or permission scope which is being granted", - Type: pluginsdk.TypeString, - Required: true, - ValidateFunc: validation.IsUUID, - }, - - "type": { - Description: "The type of permission being granted", - Type: pluginsdk.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice( - []string{ - msgraph.ResourceAccessTypeRole, - msgraph.ResourceAccessTypeScope, - }, - false, - ), - }, - }, + "role_ids": { + Description: "A set of role IDs to be granted to the application, as published by the API", + Type: pluginsdk.TypeSet, + Optional: true, + AtLeastOneOf: []string{"role_ids", "scope_ids"}, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + ValidateFunc: validation.IsUUID, + }, + }, + + "scope_ids": { + Description: "A set of scope IDs to be granted to the application, as published by the API", + Type: pluginsdk.TypeSet, + Optional: true, + AtLeastOneOf: []string{"role_ids", "scope_ids"}, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + ValidateFunc: validation.IsUUID, }, }, } @@ -146,10 +135,16 @@ func (r ApplicationApiAccessResource) Create() sdk.ResourceFunc { } permissions := make([]msgraph.ResourceAccess, 0) - for _, permission := range model.Permission { + for _, roleId := range model.RoleIds { + permissions = append(permissions, msgraph.ResourceAccess{ + ID: pointer.To(roleId), + Type: msgraph.ResourceAccessTypeRole, + }) + } + for _, scopeId := range model.ScopeIds { permissions = append(permissions, msgraph.ResourceAccess{ - ID: pointer.To(permission.Id), - Type: permission.Type, + ID: pointer.To(scopeId), + Type: msgraph.ResourceAccessTypeScope, }) } @@ -223,18 +218,22 @@ func (r ApplicationApiAccessResource) Read() sdk.ResourceFunc { return fmt.Errorf("retrieving %s: resourceAccess was nil", id) } - permissions := make([]ApplicationApiAccessPermission, 0) + roleIds := make([]string, 0) + scopeIds := make([]string, 0) for _, permission := range *api.ResourceAccess { - permissions = append(permissions, ApplicationApiAccessPermission{ - Id: pointer.From(permission.ID), - Type: permission.Type, - }) + switch permission.Type { + case msgraph.ResourceAccessTypeRole: + roleIds = append(roleIds, pointer.From(permission.ID)) + case msgraph.ResourceAccessTypeScope: + scopeIds = append(scopeIds, pointer.From(permission.ID)) + } } state := ApplicationApiAccessModel{ ApplicationId: applicationId.ID(), ApiClientId: pointer.From(api.ResourceAppId), - Permission: permissions, + RoleIds: roleIds, + ScopeIds: scopeIds, } return metadata.Encode(&state) @@ -260,10 +259,16 @@ func (r ApplicationApiAccessResource) Update() sdk.ResourceFunc { // Prepare a new API to replace the existing one permissions := make([]msgraph.ResourceAccess, 0) - for _, permission := range model.Permission { + for _, roleId := range model.RoleIds { + permissions = append(permissions, msgraph.ResourceAccess{ + ID: pointer.To(roleId), + Type: msgraph.ResourceAccessTypeRole, + }) + } + for _, scopeId := range model.ScopeIds { permissions = append(permissions, msgraph.ResourceAccess{ - ID: pointer.To(permission.Id), - Type: permission.Type, + ID: pointer.To(scopeId), + Type: msgraph.ResourceAccessTypeScope, }) } api := msgraph.RequiredResourceAccess{ diff --git a/internal/services/applications/application_api_access_resource_test.go b/internal/services/applications/application_api_access_resource_test.go index a7228d7694..564747acbe 100644 --- a/internal/services/applications/application_api_access_resource_test.go +++ b/internal/services/applications/application_api_access_resource_test.go @@ -171,20 +171,14 @@ resource "azuread_application_api_access" "test" { application_id = azuread_application_registration.test.id api_client_id = "00000003-0000-0000-c000-000000000000" - permission { - id = "9a5d68dd-52b0-4cc2-bd40-abcf44ac3a30" - type = "Role" - } - - permission { - id = "dbb9058a-0e50-45d7-ae91-66909b5d4664" - type = "Role" - } - - permission { - id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" - type = "Scope" - } + role_ids = [ + "9a5d68dd-52b0-4cc2-bd40-abcf44ac3a30", + "dbb9058a-0e50-45d7-ae91-66909b5d4664", + ] + + scope_ids = [ + "e1fe6dd8-ba31-4d61-89e7-88639da4683d", + ] } `, data.RandomInteger, data.RandomPassword) } @@ -201,35 +195,27 @@ resource "azuread_application_api_access" "test" { application_id = azuread_application_registration.test.id api_client_id = "00000003-0000-0000-c000-000000000000" - permission { - id = "9a5d68dd-52b0-4cc2-bd40-abcf44ac3a30" - type = "Role" - } + role_ids = [ + "9a5d68dd-52b0-4cc2-bd40-abcf44ac3a30", + "dbb9058a-0e50-45d7-ae91-66909b5d4664", + ] - permission { - id = "dbb9058a-0e50-45d7-ae91-66909b5d4664" - type = "Role" - } - - permission { - id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" - type = "Scope" - } + scope_ids = [ + "e1fe6dd8-ba31-4d61-89e7-88639da4683d", + ] } resource "azuread_application_api_access" "test2" { application_id = azuread_application_registration.test.id api_client_id = "00000003-0000-0ff1-ce00-000000000000" - permission { - id = "d13f72ca-a275-4b96-b789-48ebcc4da984" - type = "Role" - } + role_ids = [ + "d13f72ca-a275-4b96-b789-48ebcc4da984", + ] - permission { - id = "2beb830c-70d1-4f5b-a983-79cbdb0c6c6a" - type = "Scope" - } + scope_ids = [ + "2beb830c-70d1-4f5b-a983-79cbdb0c6c6a", + ] } `, data.RandomInteger, data.RandomPassword) } @@ -246,30 +232,23 @@ resource "azuread_application_api_access" "test" { application_id = azuread_application_registration.test.id api_client_id = "00000003-0000-0000-c000-000000000000" - permission { - id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" - type = "Scope" - } + scope_ids = [ + "e1fe6dd8-ba31-4d61-89e7-88639da4683d", + ] } resource "azuread_application_api_access" "test2" { application_id = azuread_application_registration.test.id api_client_id = "00000003-0000-0ff1-ce00-000000000000" - permission { - id = "d13f72ca-a275-4b96-b789-48ebcc4da984" - type = "Role" - } - - permission { - id = "df021288-bdef-4463-88db-98f22de89214" - type = "Role" - } + role_ids = [ + "d13f72ca-a275-4b96-b789-48ebcc4da984", + "df021288-bdef-4463-88db-98f22de89214", + ] - permission { - id = "2beb830c-70d1-4f5b-a983-79cbdb0c6c6a" - type = "Scope" - } + scope_ids = [ + "2beb830c-70d1-4f5b-a983-79cbdb0c6c6a", + ] } `, data.RandomInteger, data.RandomPassword) } @@ -286,26 +265,21 @@ resource "azuread_application_api_access" "test" { application_id = azuread_application_registration.test.id api_client_id = "00000003-0000-0000-c000-000000000000" - permission { - id = "9a5d68dd-52b0-4cc2-bd40-abcf44ac3a30" - type = "Role" - } - - permission { - id = "dbb9058a-0e50-45d7-ae91-66909b5d4664" - type = "Role" - } + role_ids = [ + "9a5d68dd-52b0-4cc2-bd40-abcf44ac3a30", + "dbb9058a-0e50-45d7-ae91-66909b5d4664", + ] - permission { - id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" - type = "Scope" - } + scope_ids = [ + "e1fe6dd8-ba31-4d61-89e7-88639da4683d", + ] } resource "azuread_application_api_access" "import" { application_id = azuread_application_api_access.test.application_id api_client_id = azuread_application_api_access.test.api_client_id - permission = azuread_application_api_access.test.permission + role_ids = azuread_application_api_access.test.role_ids + scope_ids = azuread_application_api_access.test.scope_ids } `, data.RandomInteger, data.RandomPassword) } diff --git a/internal/services/applications/application_registration_resource.go b/internal/services/applications/application_registration_resource.go index 3723190c5b..8ae96c02d9 100644 --- a/internal/services/applications/application_registration_resource.go +++ b/internal/services/applications/application_registration_resource.go @@ -139,21 +139,11 @@ func (r ApplicationRegistrationResource) Arguments() map[string]*pluginsdk.Schem }, "requested_access_token_version": { - Description: "The access token version expected by this resource", - Type: pluginsdk.TypeInt, - Optional: true, - Default: 1, - ValidateFunc: func(i interface{}, key string) (warnings []string, errors []error) { - v, ok := i.(int) - if !ok { - errors = append(errors, fmt.Errorf("expected %q to be an integer", key)) - return - } - if v < 1 || v > 2 { - errors = append(errors, fmt.Errorf("value for %q must be one of: 1, 2", key)) - } - return - }, + Description: "The access token version expected by this resource", + Type: pluginsdk.TypeInt, + Optional: true, + Default: 2, + ValidateFunc: validation.IntBetween(1, 2), }, "service_management_reference": { From 49265d10a5d97f096b3ed73c26efc68ce29fb53d Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 00:22:16 +0100 Subject: [PATCH 25/46] documentation for `azuread_application_app_role` --- docs/resources/application_api_access.md | 39 ++++++----- docs/resources/application_app_role.md | 89 ++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 16 deletions(-) create mode 100644 docs/resources/application_app_role.md diff --git a/docs/resources/application_api_access.md b/docs/resources/application_api_access.md index 06862def13..279f9a3ed0 100644 --- a/docs/resources/application_api_access.md +++ b/docs/resources/application_api_access.md @@ -6,20 +6,7 @@ subcategory: "Applications" Manages the API permissions for an application registration. -This resource is analogous to the `required_resource_access` block in the `azuread_application` resource. When using these resources together, you should use the `ignore_changes` [lifecycle meta-argument](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle), for example: - -```terraform - -resource "azuread_application" "example" { - display_name = "example" - - lifecycle { - ignore_changes = [ - required_resource_access, - ] - } -} -``` +This resource is analogous to the `required_resource_access` block in the `azuread_application` resource. When using these resources together, you should use the `ignore_changes` [lifecycle meta-argument](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle) (see example below). ## API Permissions @@ -59,14 +46,34 @@ resource "azuread_application_api_access" "example_msgraph" { } ``` --> Tip: For managing permissions for an additional API, create another instance of this resource +-> **Tip** For managing permissions for an additional API, create another instance of this resource + +*Usage with azuread_application resource* + +```terraform + +resource "azuread_application" "example" { + display_name = "example" + + lifecycle { + ignore_changes = [ + required_resource_access, + ] + } +} + +resource "azuread_application_api_access" "example" { + application_id = azuread_application.example.id + # ... +} +``` ## Argument Reference The following arguments are supported: -* `application_id` - (Required) The resource ID of the application registration. * `api_client_id` - (Required) The client ID of the API to which access is being granted. +* `application_id` - (Required) The resource ID of the application registration. * `role_ids` - (Optional) A set of role IDs to be granted to the application, as published by the API. * `scope_ids` - (Optional) A set of scope IDs to be granted to the application, as published by the API. diff --git a/docs/resources/application_app_role.md b/docs/resources/application_app_role.md new file mode 100644 index 0000000000..f0658500bd --- /dev/null +++ b/docs/resources/application_app_role.md @@ -0,0 +1,89 @@ +--- +subcategory: "Applications" +--- + +# Resource: azuread_application_app_role + +Manages an app role for an application registration. + +This resource is analogous to the `app_role` block in the `azuread_application` resource. When using these resources together, you should use the `ignore_changes` [lifecycle meta-argument](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle) (see example below). + +## API Permissions + +The following API permissions are required in order to use this resource. + +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` + +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of the application. + +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` + +## Example Usage + +```terraform +resource "azuread_application_registration" "example" { + display_name = "example" +} + +resource "random_uuid" "example_administrator" {} + +resource "azuread_application_app_role" "example_administer" { + application_id = azuread_application_registration.example.id + role_id = random_uuid.example_administrator.id + + allowed_member_types = ["User"] + description = "My role description" + display_name = "Administer" + value = "admin" +} +``` + +-> **Tip** For managing more app roles, create additional instances of this resource + +*Usage with azuread_application resource* + +```terraform + +resource "azuread_application" "example" { + display_name = "example" + + lifecycle { + ignore_changes = [ + app_role, + ] + } +} + +resource "azuread_application_app_role" "example_administer" { + application_id = azuread_application.example.id + # ... +} +``` + +## Argument Reference + +The following arguments are supported: + +* `allowed_member_types` - (Required) A set of values to specify whether this app role definition can be assigned to users and groups by setting to `User`, or to other applications by setting to `Application`, or to both. +* `application_id` - (Required) The resource ID of the application registration. +* `description` - (Required) Description of the app role that appears when the role is being assigned, and if the role functions as an application permissions, during the consent experiences. +* `display_name` - (Required) Display name for the app role that appears during app role assignment and in consent experiences. +* `role_id` - (Required) The unique identifier of the app role. Must be a valid UUID. + +-> **Tip** Use the `random_uuid` resource to generate UUIDs and save them to state for app roles within your Terraform configuration + +* `value` - (Optional) The value that is used for the `roles` claim in ID tokens and OAuth 2.0 access tokens that are authenticating an assigned service or user principal. + +-> **Roles and Permission Scopes** In Azure Active Directory, application roles (`app_role`) and permission scopes (`oauth2_permission_scope`) exported by an application share the same namespace and cannot contain duplicate values. + +## Attributes Reference + +No additional attributes are exported. + +## Import + +Application App Roles can be imported using the object ID of the application and the ID of the app role, in the following format. + +```shell +terraform import azuread_application_app_role.example /applications/00000000-0000-0000-0000-000000000000/appRoles/11111111-1111-1111-1111-111111111111 +``` From dd96d9f25aa58f7d186a48acbae33bda45b255a8 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 00:29:49 +0100 Subject: [PATCH 26/46] updated documentation for `azuread_application_certificate` and `azuread_application_password` --- docs/resources/application_certificate.md | 48 ++++++++++++----------- docs/resources/application_password.md | 18 +++++---- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/docs/resources/application_certificate.md b/docs/resources/application_certificate.md index de7d3d1823..5a001c7cfd 100644 --- a/docs/resources/application_certificate.md +++ b/docs/resources/application_certificate.md @@ -10,42 +10,42 @@ Manages a certificate associated with an application within Azure Active Directo The following API permissions are required in order to use this resource. -When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.All` or `Directory.ReadWrite.All` +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` --> It's possible to use this resource with the `Application.ReadWrite.OwnedBy` application role, provided the principal being used to run Terraform is included in the `owners` property. +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of the application. -When authenticated with a user principal, this resource requires one of the following directory roles: `Application Administrator` or `Global Administrator` +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` ## Example Usage *Using a PEM certificate* ```terraform -resource "azuread_application" "example" { +resource "azuread_application_registration" "example" { display_name = "example" } resource "azuread_application_certificate" "example" { - application_object_id = azuread_application.example.id - type = "AsymmetricX509Cert" - value = file("cert.pem") - end_date = "2021-05-01T01:02:03Z" + application_id = azuread_application_registration.example.id + type = "AsymmetricX509Cert" + value = file("cert.pem") + end_date = "2021-05-01T01:02:03Z" } ``` *Using a DER certificate* ```terraform -resource "azuread_application" "example" { +resource "azuread_application_registration" "example" { display_name = "example" } resource "azuread_application_certificate" "example" { - application_object_id = azuread_application.example.id - type = "AsymmetricX509Cert" - encoding = "base64" - value = base64encode(file("cert.der")) - end_date = "2021-05-01T01:02:03Z" + application_id = azuread_application_registration.example.id + type = "AsymmetricX509Cert" + encoding = "base64" + value = base64encode(file("cert.der")) + end_date = "2021-05-01T01:02:03Z" } ``` @@ -107,12 +107,12 @@ resource "azuread_application" "example" { } resource "azuread_application_certificate" "example" { - application_object_id = azuread_application.example.id - type = "AsymmetricX509Cert" - encoding = "hex" - value = azurerm_key_vault_certificate.example.certificate_data - end_date = azurerm_key_vault_certificate.example.certificate_attribute[0].expires - start_date = azurerm_key_vault_certificate.example.certificate_attribute[0].not_before + application_id = azuread_application.example.id + type = "AsymmetricX509Cert" + encoding = "hex" + value = azurerm_key_vault_certificate.example.certificate_data + end_date = azurerm_key_vault_certificate.example.certificate_attribute[0].expires + start_date = azurerm_key_vault_certificate.example.certificate_attribute[0].not_before } ``` @@ -120,7 +120,11 @@ resource "azuread_application_certificate" "example" { The following arguments are supported: -* `application_object_id` - (Required) The object ID of the application for which this certificate should be created. Changing this field forces a new resource to be created. +* `application_id` - (Optional) The resource ID of the application for which this certificate should be created. Changing this field forces a new resource to be created. +* `application_object_id` - (Optional, Deprecated) The object ID of the application for which this certificate should be created. Changing this field forces a new resource to be created. + +~> One of `application_id` or `application_object_id` must be specified. + * `encoding` - (Optional) Specifies the encoding used for the supplied certificate data. Must be one of `pem`, `base64` or `hex`. Defaults to `pem`. -> **Tip for Azure Key Vault** The `hex` encoding option is useful for consuming certificate data from the [azurerm_key_vault_certificate](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_certificate) resource. @@ -128,7 +132,7 @@ The following arguments are supported: * `end_date` - (Optional) The end date until which the certificate is valid, formatted as an RFC3339 date string (e.g. `2018-01-01T01:02:03Z`). If omitted, the API will decide a suitable expiry date, which is typically around 2 years from the start date. Changing this field forces a new resource to be created. * `end_date_relative` - (Optional) A relative duration for which the certificate is valid until, for example `240h` (10 days) or `2400h30m`. Changing this field forces a new resource to be created. -~> One of `end_date` or `end_date_relative` must be set. The maximum allowed duration is determined by Azure AD. +~> One of `end_date` or `end_date_relative` must be specified. The maximum allowed duration is determined by Azure AD and is typically around 2 years from the creation date. * `key_id` - (Optional) A UUID used to uniquely identify this certificate. If omitted, a random UUID will be automatically generated. Changing this field forces a new resource to be created. * `start_date` - (Optional) The start date from which the certificate is valid, formatted as an RFC3339 date string (e.g. `2018-01-01T01:02:03Z`). If this isn't specified, the value is determined by Azure Active Directory and is usually the start date of the certificate for asymmetric keys, or the current timestamp for symmetric keys. Changing this field forces a new resource to be created. diff --git a/docs/resources/application_password.md b/docs/resources/application_password.md index ed39f4517a..1a5fc8a5f1 100644 --- a/docs/resources/application_password.md +++ b/docs/resources/application_password.md @@ -10,9 +10,9 @@ Manages a password credential associated with an application within Azure Active The following API permissions are required in order to use this resource. -When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.All` or `Directory.ReadWrite.All` +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` --> It's possible to use this resource with the `Application.ReadWrite.OwnedBy` application role, provided the principal being used to run Terraform is included in the `owners` property. +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of the application. When authenticated with a user principal, this resource requires one of the following directory roles: `Application Administrator` or `Global Administrator` @@ -21,19 +21,19 @@ When authenticated with a user principal, this resource requires one of the foll *Basic example* ```terraform -resource "azuread_application" "example" { +resource "azuread_application_registration" "example" { display_name = "example" } resource "azuread_application_password" "example" { - application_object_id = azuread_application.example.object_id + application_id = azuread_application_registration.example.id } ``` *Time-based rotation* ```terraform -resource "azuread_application" "example" { +resource "azuread_application_registration" "example" { display_name = "example" } @@ -42,7 +42,7 @@ resource "time_rotating" "example" { } resource "azuread_application_password" "example" { - application_object_id = azuread_application.example.object_id + application_id = azuread_application_registration.example.id rotate_when_changed = { rotation = time_rotating.example.id } @@ -53,7 +53,11 @@ resource "azuread_application_password" "example" { The following arguments are supported: -* `application_object_id` - (Required) The object ID of the application for which this password should be created. Changing this field forces a new resource to be created. +* `application_id` - (Optional) The resource ID of the application for which this password should be created. Changing this field forces a new resource to be created. +* `application_object_id` - (Optional, Deprecated) The object ID of the application for which this password should be created. Changing this field forces a new resource to be created. + +~> One of `application_id` or `application_object_id` must be specified. + * `display_name` - (Optional) A display name for the password. Changing this field forces a new resource to be created. * `end_date` - (Optional) The end date until which the password is valid, formatted as an RFC3339 date string (e.g. `2018-01-01T01:02:03Z`). Changing this field forces a new resource to be created. * `end_date_relative` - (Optional) A relative duration for which the password is valid until, for example `240h` (10 days) or `2400h30m`. Changing this field forces a new resource to be created. From 1f6d2f9e4f4d759509f5f8aa981059c902eeac58 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 00:31:17 +0100 Subject: [PATCH 27/46] updated documentation for `azuread_application_federated_identity_credential` --- ...plication_federated_identity_credential.md | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/docs/resources/application_federated_identity_credential.md b/docs/resources/application_federated_identity_credential.md index f537f7255b..9a987fc327 100644 --- a/docs/resources/application_federated_identity_credential.md +++ b/docs/resources/application_federated_identity_credential.md @@ -10,26 +10,26 @@ Manages a federated identity credential associated with an application within Az The following API permissions are required in order to use this resource. -When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.All` or `Directory.ReadWrite.All` +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` --> It's possible to use this resource with the `Application.ReadWrite.OwnedBy` application role, provided the principal being used to run Terraform is included in the `owners` property. +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of the application. When authenticated with a user principal, this resource requires one of the following directory roles: `Application Administrator` or `Global Administrator` ## Example Usage ```terraform -resource "azuread_application" "example" { +resource "azuread_application_registration" "example" { display_name = "example" } resource "azuread_application_federated_identity_credential" "example" { - application_object_id = azuread_application.example.object_id - display_name = "my-repo-deploy" - description = "Deployments for my-repo" - audiences = ["api://AzureADTokenExchange"] - issuer = "https://token.actions.githubusercontent.com" - subject = "repo:my-organization/my-repo:environment:prod" + application_id = azuread_application_registration.example.id + display_name = "my-repo-deploy" + description = "Deployments for my-repo" + audiences = ["api://AzureADTokenExchange"] + issuer = "https://token.actions.githubusercontent.com" + subject = "repo:my-organization/my-repo:environment:prod" } ``` @@ -37,7 +37,11 @@ resource "azuread_application_federated_identity_credential" "example" { The following arguments are supported: -* `application_object_id` - (Required) The object ID of the application for which this federated identity credential should be created. Changing this field forces a new resource to be created. +* `application_id` - (Optional) The resource ID of the application for which this federated identity credential should be created. Changing this field forces a new resource to be created. +* `application_object_id` - (Optional, Deprecated) The object ID of the application for which this federated identity credential should be created. Changing this field forces a new resource to be created. + +~> One of `application_id` or `application_object_id` must be specified. + * `audiences` - (Required) List of audiences that can appear in the external token. This specifies what should be accepted in the `aud` claim of incoming tokens. * `description` - (Optional) A description for the federated identity credential. * `display_name` - (Required) A unique display name for the federated identity credential. Changing this forces a new resource to be created. From 111a8784a796395e3287ff659ddcdc1ad9563f33 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 00:38:13 +0100 Subject: [PATCH 28/46] updated documentation for `azuread_application_pre_authorized_application` --- docs/resources/application_pre_authorized.md | 32 +++++++++++++------ .../application_pre_authorized_resource.go | 4 +-- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/docs/resources/application_pre_authorized.md b/docs/resources/application_pre_authorized.md index e61512efa1..aeba8aca3d 100644 --- a/docs/resources/application_pre_authorized.md +++ b/docs/resources/application_pre_authorized.md @@ -10,16 +10,16 @@ Manages client applications that are pre-authorized with the specified permissio The following API permissions are required in order to use this resource. -When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.All` or `Directory.ReadWrite.All` +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` --> It's possible to use this resource with the `Application.ReadWrite.OwnedBy` application role, provided the principal being used to run Terraform is included in the `owners` property. +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of the application. When authenticated with a user principal, this resource requires one of the following directory roles: `Application Administrator` or `Global Administrator` ## Example Usage ```terraform -resource "azuread_application" "authorized" { +resource "azuread_application_registration" "authorized" { display_name = "example-authorized-app" } @@ -31,7 +31,7 @@ resource "azuread_application" "authorizer" { admin_consent_description = "Administer the application" admin_consent_display_name = "Administer" enabled = true - id = "ced9c4c3-c273-4f0f-ac71-a20377b90f9c" + id = "00000000-0000-0000-0000-000000000000" type = "Admin" value = "administer" } @@ -40,7 +40,7 @@ resource "azuread_application" "authorizer" { admin_consent_description = "Access the application" admin_consent_display_name = "Access" enabled = true - id = "2d5e07ca-664d-4d9b-ad61-ec07fd215213" + id = "11111111-1111-1111-1111-111111111111" type = "User" user_consent_description = "Access the application" user_consent_display_name = "Access" @@ -50,9 +50,13 @@ resource "azuread_application" "authorizer" { } resource "azuread_application_pre_authorized" "example" { - application_object_id = azuread_application.authorizer.object_id - authorized_app_id = azuread_application.authorized.application_id - permission_ids = ["ced9c4c3-c273-4f0f-ac71-a20377b90f9c", "2d5e07ca-664d-4d9b-ad61-ec07fd215213"] + application_id = azuread_application.authorizer.id + authorized_client_id = azuread_application_registration.authorized.client_id + + permission_ids = [ + "00000000-0000-0000-0000-000000000000", + "11111111-1111-1111-1111-111111111111", + ] } ``` @@ -60,8 +64,16 @@ resource "azuread_application_pre_authorized" "example" { The following arguments are supported: -* `application_object_id` - (Required) The object ID of the application for which permissions are being authorized. Changing this field forces a new resource to be created. -* `authorized_application_id` - (Optional) The application ID (client ID) of the application being authorized. Changing this field forces a new resource to be created. +* `application_id` - (Optional) The resource ID of the application for which permissions are being authorized. Changing this field forces a new resource to be created. +* `application_object_id` - (Optional, Deprecated) The object ID of the application for which permissions are being authorized. Changing this field forces a new resource to be created. + +~> One of `application_id` or `application_object_id` must be specified. + +* `authorized_app_id` - (Optional, Deprecated) The client ID of the application being authorized. Changing this field forces a new resource to be created. +* `authorized_client_id` - (Optional) The client ID of the application being authorized. Changing this field forces a new resource to be created. + +~> One of `authorized_client_id` or `authorized_app_id` must be specified. + * `permission_ids` - (Required) A set of permission scope IDs required by the authorized application. ## Attributes Reference diff --git a/internal/services/applications/application_pre_authorized_resource.go b/internal/services/applications/application_pre_authorized_resource.go index a6ec8a4026..7c8080b2c1 100644 --- a/internal/services/applications/application_pre_authorized_resource.go +++ b/internal/services/applications/application_pre_authorized_resource.go @@ -68,7 +68,7 @@ func applicationPreAuthorizedResource() *pluginsdk.Resource { Description: "The application ID of the pre-authorized application", Type: pluginsdk.TypeString, Optional: true, - Computed: true, // TODO remove Computed in v3.0 + Computed: true, ForceNew: true, ExactlyOneOf: []string{"authorized_app_id", "authorized_client_id"}, Deprecated: "The `authorized_app_id` property has been replaced with the `authorized_client_id` property and will be removed in version 3.0 of the AzureAD provider", @@ -79,7 +79,7 @@ func applicationPreAuthorizedResource() *pluginsdk.Resource { Description: "The client ID of the pre-authorized application", Type: pluginsdk.TypeString, Optional: true, - Computed: true, + Computed: true, // TODO remove Computed in v3.0 ForceNew: true, ExactlyOneOf: []string{"authorized_app_id", "authorized_client_id"}, ValidateFunc: validation.IsUUID, From c97714b41ce90ce5af5dd47ae46817cdf298ba70 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 00:45:26 +0100 Subject: [PATCH 29/46] updated documentation for `azuread_application` and `data.azuread_application` --- docs/data-sources/application.md | 10 ++++++---- docs/resources/application.md | 3 ++- docs/resources/application_pre_authorized.md | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/data-sources/application.md b/docs/data-sources/application.md index 3eb17ac20c..c3b0c1b905 100644 --- a/docs/data-sources/application.md +++ b/docs/data-sources/application.md @@ -22,7 +22,7 @@ data "azuread_application" "example" { } output "application_object_id" { - value = data.azuread_application.example.id + value = data.azuread_application.example.object_id } ``` @@ -30,11 +30,12 @@ output "application_object_id" { The following arguments are supported: -* `application_id` - (Optional) Specifies the Application ID (also called Client ID). +* `application_id` - (Optional, Deprecated) Specifies the Client ID of the application. +* `client_id` - (Optional) Specifies the Client ID of the application. * `display_name` - (Optional) Specifies the display name of the application. * `object_id` - (Optional) Specifies the Object ID of the application. -~> One of `object_id`, `application_id` or `display_name` must be specified. +~> One of `client_id`, `application_id`, `display_name`, or `object_id` must be specified. ## Attributes Reference @@ -43,7 +44,8 @@ The following attributes are exported: * `api` - An `api` block as documented below. * `app_role_ids` - A mapping of app role values to app role IDs, intended to be useful when referencing app roles in other resources in your configuration. * `app_roles` - A collection of `app_role` blocks as documented below. For more information see [official documentation on Application Roles](https://docs.microsoft.com/en-us/azure/architecture/multitenant-identity/app-roles). -* `application_id` - The Application ID (also called Client ID). +* `application_id` - (Deprecated) The Client ID for the application. +* `client_id` - The Client ID for the application. * `description` - A description of the application, as shown to end users. * `device_only_auth_enabled` - Specifies whether this application supports device authentication without a user. * `disabled_by_microsoft` - Whether Microsoft has disabled the registered application. If the application is disabled, this will be a string indicating the status/reason, e.g. `DisabledDueToViolationOfServicesAgreement` diff --git a/docs/resources/application.md b/docs/resources/application.md index 7ac9769952..168783a80a 100644 --- a/docs/resources/application.md +++ b/docs/resources/application.md @@ -328,7 +328,8 @@ The following arguments are supported: In addition to all arguments above, the following attributes are exported: * `app_role_ids` - A mapping of app role values to app role IDs, intended to be useful when referencing app roles in other resources in your configuration. -* `application_id` - The Application ID (also called Client ID). +* `application_id` - (Deprecated) The Client ID for the application. +* `client_id` - The Client ID for the application. * `disabled_by_microsoft` - Whether Microsoft has disabled the registered application. If the application is disabled, this will be a string indicating the status/reason, e.g. `DisabledDueToViolationOfServicesAgreement` * `logo_url` - CDN URL to the application's logo, as uploaded with the `logo_image` property. * `oauth2_permission_scope_ids` - A mapping of OAuth2.0 permission scope values to scope IDs, intended to be useful when referencing permission scopes in other resources in your configuration. diff --git a/docs/resources/application_pre_authorized.md b/docs/resources/application_pre_authorized.md index aeba8aca3d..0d75818d87 100644 --- a/docs/resources/application_pre_authorized.md +++ b/docs/resources/application_pre_authorized.md @@ -74,7 +74,7 @@ The following arguments are supported: ~> One of `authorized_client_id` or `authorized_app_id` must be specified. -* `permission_ids` - (Required) A set of permission scope IDs required by the authorized application. +* `permission_ids` - (Required) A set of permission scope IDs required by the authorized application. ## Attributes Reference From 9904ece65dae95cb8c4a3995372accf1245ebc37 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 00:48:46 +0100 Subject: [PATCH 30/46] update golangci-lint --- .github/workflows/golint.yaml | 2 +- GNUmakefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/golint.yaml b/.github/workflows/golint.yaml index d264dc7361..f981838652 100644 --- a/.github/workflows/golint.yaml +++ b/.github/workflows/golint.yaml @@ -18,7 +18,7 @@ jobs: go-version-file: .go-version - uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc # v3.7.0 with: - version: 'v1.50.1' + version: 'v1.54.2' args: -v save-artifacts-on-fail: diff --git a/GNUmakefile b/GNUmakefile index 723f6ceca9..d7f2d83e4d 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -16,7 +16,7 @@ tools: go install github.com/bflad/tfproviderdocs@latest go install github.com/katbyte/terrafmt@latest go install mvdan.cc/gofumpt@latest - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "$$(go env GOPATH || $$GOPATH)"/bin v1.49.0 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "$$(go env GOPATH || $$GOPATH)"/bin v1.54.2 build: fmtcheck go install From d346e5448589a01e14f55b58c6deb3526f507927 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 01:16:26 +0100 Subject: [PATCH 31/46] documentation for `azuread_application_fallback_public_client` --- .../application_fallback_public_client.md | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 docs/resources/application_fallback_public_client.md diff --git a/docs/resources/application_fallback_public_client.md b/docs/resources/application_fallback_public_client.md new file mode 100644 index 0000000000..807ec77ae8 --- /dev/null +++ b/docs/resources/application_fallback_public_client.md @@ -0,0 +1,53 @@ +--- +subcategory: "Applications" +--- + +# Resource: azuread_application_fallback_public_client + +Manages the Fallback Public Client setting for an application registration. + +~> This resource is incompatible with the `azuread_application` resource, instead use this with the `azuread_application_registration` resource. + +## API Permissions + +The following API permissions are required in order to use this resource. + +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` + +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of the application. + +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` + +## Example Usage + +```terraform +resource "azuread_application_registration" "example" { + display_name = "example" +} + +resource "azuread_application_fallback_public_client" "example" { + application_id = azuread_application_registration.example.id + enabled = true +} +``` + +## Argument Reference + +The following arguments are supported: + +* `application_id` - (Required) The resource ID of the application registration. +* `enabled` - (Required) Whether to enable the application as a fallback public client. + +-> Some configurations may require the Fallback Public Client setting to be `null`, for this case simply destroy this resource (or don't use it) + +## Attributes Reference + +No additional attributes are exported. + +## Import + +The Application Fallback Public Client setting can be imported using the object ID of the application, in the following format. + +```shell +terraform import azuread_application_fallback_public_client.example /applications/00000000-0000-0000-0000-000000000000/fallbackPublicClient +``` From 89341b02903043741cd6baa97d20a7053b33b049 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 01:38:26 +0100 Subject: [PATCH 32/46] documentation for `azuread_application_from_template` --- .../access_package_catalog_role_assignment.md | 2 +- docs/resources/administrative_unit_member.md | 2 +- .../administrative_unit_role_member.md | 2 +- docs/resources/application.md | 5 +- docs/resources/application_certificate.md | 2 +- ...plication_federated_identity_credential.md | 2 +- docs/resources/application_from_template.md | 62 +++++++++++++++++++ docs/resources/application_registration.md | 2 +- docs/resources/directory_role_assignment.md | 4 +- docs/resources/directory_role_member.md | 2 +- docs/resources/group_member.md | 2 +- docs/resources/service_principal.md | 2 +- .../service_principal_certificate.md | 2 +- 13 files changed, 78 insertions(+), 13 deletions(-) create mode 100644 docs/resources/application_from_template.md diff --git a/docs/resources/access_package_catalog_role_assignment.md b/docs/resources/access_package_catalog_role_assignment.md index b2e964900d..e56d0355f6 100644 --- a/docs/resources/access_package_catalog_role_assignment.md +++ b/docs/resources/access_package_catalog_role_assignment.md @@ -57,5 +57,5 @@ In addition to all arguments above, the following attributes are exported: Catalog role assignments can be imported using the ID of the assignment, e.g. ```shell -terraform import azuread_access_package_catalog_role_assignment.test 00000000-0000-0000-0000-000000000000 +terraform import azuread_access_package_catalog_role_assignment.example 00000000-0000-0000-0000-000000000000 ``` diff --git a/docs/resources/administrative_unit_member.md b/docs/resources/administrative_unit_member.md index c1993096bb..64cfedc3c0 100644 --- a/docs/resources/administrative_unit_member.md +++ b/docs/resources/administrative_unit_member.md @@ -52,7 +52,7 @@ In addition to all arguments above, the following attributes are exported: Administrative unit members can be imported using the object ID of the administrative unit and the object ID of the member, e.g. ```shell -terraform import azuread_administrative_unit_member.test 00000000-0000-0000-0000-000000000000/member/11111111-1111-1111-1111-111111111111 +terraform import azuread_administrative_unit_member.example 00000000-0000-0000-0000-000000000000/member/11111111-1111-1111-1111-111111111111 ``` -> This ID format is unique to Terraform and is composed of the Administrative Unit Object ID and the target Member Object ID in the format `{AdministrativeUnitObjectID}/member/{MemberObjectID}`. diff --git a/docs/resources/administrative_unit_role_member.md b/docs/resources/administrative_unit_role_member.md index abdf16e5fc..e076c5da94 100644 --- a/docs/resources/administrative_unit_role_member.md +++ b/docs/resources/administrative_unit_role_member.md @@ -56,7 +56,7 @@ In addition to all arguments above, the following attributes are exported: Administrative unit role members can be imported using the object ID of the administrative unit and the unique ID of the role assignment, e.g. ```shell -terraform import azuread_administrative_unit_role_member.test 00000000-0000-0000-0000-000000000000/roleMember/zX37MRLyF0uvE-xf2WH4B7x-6CPLfudNnxFGj800htpBXqkxW7bITqGb6Rj4kuTuS +terraform import azuread_administrative_unit_role_member.example 00000000-0000-0000-0000-000000000000/roleMember/zX37MRLyF0uvE-xf2WH4B7x-6CPLfudNnxFGj800htpBXqkxW7bITqGb6Rj4kuTuS ``` -> This ID format is unique to Terraform and is composed of the Administrative Unit Object ID and the role assignment ID in the format `{AdministrativeUnitObjectID}/roleMember/{RoleAssignmentID}`. diff --git a/docs/resources/application.md b/docs/resources/application.md index 168783a80a..d474b675f0 100644 --- a/docs/resources/application.md +++ b/docs/resources/application.md @@ -203,6 +203,9 @@ The following arguments are supported: -> **Tags and Features** Azure Active Directory uses special tag values to configure the behavior of applications. These can be specified using either the `tags` property or with the `feature_tags` block. If you need to set any custom tag values not supported by the `feature_tags` block, it's recommended to use the `tags` property. Tag values also propagate to any linked service principals. * `template_id` - (Optional) Unique ID for a templated application in the Azure AD App Gallery, from which to create the application. Changing this forces a new resource to be created. + +-> **Tip for Gallery Applications** This resource can be used to instantiate a gallery application, however it will also attempt to manage the properties of the resulting application. If this is not desired, consider using the [azuread_application_registration](application_registration.html) resource instead. + * `terms_of_service_url` - (Optional) URL of the application's terms of service statement. * `web` - (Optional) A `web` block as documented below, which configures web related settings for this application. @@ -341,5 +344,5 @@ In addition to all arguments above, the following attributes are exported: Applications can be imported using their object ID, e.g. ```shell -terraform import azuread_application.test 00000000-0000-0000-0000-000000000000 +terraform import azuread_application.example 00000000-0000-0000-0000-000000000000 ``` diff --git a/docs/resources/application_certificate.md b/docs/resources/application_certificate.md index 5a001c7cfd..afa1c1608f 100644 --- a/docs/resources/application_certificate.md +++ b/docs/resources/application_certificate.md @@ -148,7 +148,7 @@ No additional attributes are exported. Certificates can be imported using the object ID of the associated application and the key ID of the certificate credential, e.g. ```shell -terraform import azuread_application_certificate.test 00000000-0000-0000-0000-000000000000/certificate/11111111-1111-1111-1111-111111111111 +terraform import azuread_application_certificate.example 00000000-0000-0000-0000-000000000000/certificate/11111111-1111-1111-1111-111111111111 ``` -> This ID format is unique to Terraform and is composed of the application's object ID, the string "certificate" and the certificate's key ID in the format `{ObjectId}/certificate/{CertificateKeyId}`. diff --git a/docs/resources/application_federated_identity_credential.md b/docs/resources/application_federated_identity_credential.md index 9a987fc327..9cc0eb9854 100644 --- a/docs/resources/application_federated_identity_credential.md +++ b/docs/resources/application_federated_identity_credential.md @@ -59,7 +59,7 @@ In addition to all arguments above, the following attributes are exported: Federated Identity Credentials can be imported using the object ID of the associated application and the ID of the federated identity credential, e.g. ```shell -terraform import azuread_application_federated_identity_credential.test 00000000-0000-0000-0000-000000000000/federatedIdentityCredential/11111111-1111-1111-1111-111111111111 +terraform import azuread_application_federated_identity_credential.example 00000000-0000-0000-0000-000000000000/federatedIdentityCredential/11111111-1111-1111-1111-111111111111 ``` -> This ID format is unique to Terraform and is composed of the application's object ID, the string "federatedIdentityCredential" and the credential ID in the format `{ObjectId}/federatedIdentityCredential/{CredentialId}`. diff --git a/docs/resources/application_from_template.md b/docs/resources/application_from_template.md new file mode 100644 index 0000000000..75f96a9317 --- /dev/null +++ b/docs/resources/application_from_template.md @@ -0,0 +1,62 @@ +--- +subcategory: "Applications" +--- + +# Resource: azuread_application_from_template + +Creates an application registration and associated service principal from a gallery template. + +-> The [azuread_application](application.html) resource can also be used to instantiate a gallery application, however unlike the `azuread_application` resource, this resource does not attempt to manage any properties of the resulting application. + +## API Permissions + +The following API permissions are required in order to use this resource. + +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` + +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` + +## Example Usage + +```terraform +data "azuread_application_template" "example" { + display_name = "Marketo" +} + +resource "azuread_application_from_template" "example" { + display_name = "Example Application" + template_id = data.azuread_application_template.example.template_id +} + +data "azuread_application" "example" { + object_id = azuread_application_from_template.example.application_object_id +} + +data "azuread_service_principal" "example" { + object_id = azuread_application_from_template.example.service_principal_object_id +} +``` + +## Argument Reference + +The following arguments are supported: + +* `display_name` - (Required) The display name for the application. +* `template_id` - (Required) Unique ID for a templated application in the Azure AD App Gallery, from which to create the application. Changing this forces a new resource to be created. + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +* `application_id` - The resource ID for the application. +* `application_object_id` - The object ID for the application. +* `service_principal_id` - The resource ID for the service principal. +* `service_principal_object_id` - The object ID for the service principal. + +## Import + +Templated Applications can be imported using the template ID, the object ID of the application, and the object ID of the service principal, in the following format. + +```shell +terraform import azuread_application_from_template.example /applicationTemplates/00000000-0000-0000-0000-000000000000/instantiate/11111111-1111-1111-1111-111111111111/22222222-2222-2222-2222-222222222222 +``` diff --git a/docs/resources/application_registration.md b/docs/resources/application_registration.md index fcb39d2a8e..1040f21d4d 100644 --- a/docs/resources/application_registration.md +++ b/docs/resources/application_registration.md @@ -68,5 +68,5 @@ In addition to all arguments above, the following attributes are exported: Application Registrations can be imported using the object ID of the application, in the following format. ```shell -terraform import azuread_application_registration.test /applications/00000000-0000-0000-0000-000000000000 +terraform import azuread_application_registration.example /applications/00000000-0000-0000-0000-000000000000 ``` diff --git a/docs/resources/directory_role_assignment.md b/docs/resources/directory_role_assignment.md index 69bb0fe172..629c5a81ec 100644 --- a/docs/resources/directory_role_assignment.md +++ b/docs/resources/directory_role_assignment.md @@ -76,7 +76,7 @@ data "azuread_user" "example" { user_principal_name = "jdoe@hashicorp.com" } -resource "azuread_directory_role_assignment" "test" { +resource "azuread_directory_role_assignment" "example" { role_id = azuread_directory_role.example.template_id principal_object_id = data.azuread_user.example.object_id directory_scope_id = format("/%s", azuread_application.example.object_id) @@ -105,5 +105,5 @@ In addition to all arguments above, the following attributes are exported: Directory role assignments can be imported using the ID of the assignment, e.g. ```shell -terraform import azuread_directory_role_assignment.test ePROZI_iKE653D_d6aoLHyr-lKgHI8ZGiIdz8CLVcng-1 +terraform import azuread_directory_role_assignment.example ePROZI_iKE653D_d6aoLHyr-lKgHI8ZGiIdz8CLVcng-1 ``` diff --git a/docs/resources/directory_role_member.md b/docs/resources/directory_role_member.md index a72ea1ec0c..a5e73eee26 100644 --- a/docs/resources/directory_role_member.md +++ b/docs/resources/directory_role_member.md @@ -52,7 +52,7 @@ In addition to all arguments above, the following attributes are exported: Directory role members can be imported using the object ID of the role and the object ID of the member, e.g. ```shell -terraform import azuread_directory_role_member.test 00000000-0000-0000-0000-000000000000/member/11111111-1111-1111-1111-111111111111 +terraform import azuread_directory_role_member.example 00000000-0000-0000-0000-000000000000/member/11111111-1111-1111-1111-111111111111 ``` -> This ID format is unique to Terraform and is composed of the Directory Role Object ID and the target Member Object ID in the format `{RoleObjectID}/member/{MemberObjectID}`. diff --git a/docs/resources/group_member.md b/docs/resources/group_member.md index 73d6ea29c7..6da1c83182 100644 --- a/docs/resources/group_member.md +++ b/docs/resources/group_member.md @@ -55,7 +55,7 @@ In addition to all arguments above, the following attributes are exported: Group members can be imported using the object ID of the group and the object ID of the member, e.g. ```shell -terraform import azuread_group_member.test 00000000-0000-0000-0000-000000000000/member/11111111-1111-1111-1111-111111111111 +terraform import azuread_group_member.example 00000000-0000-0000-0000-000000000000/member/11111111-1111-1111-1111-111111111111 ``` -> This ID format is unique to Terraform and is composed of the Azure AD Group Object ID and the target Member Object ID in the format `{GroupObjectID}/member/{MemberObjectID}`. diff --git a/docs/resources/service_principal.md b/docs/resources/service_principal.md index 0914880635..5498fd1133 100644 --- a/docs/resources/service_principal.md +++ b/docs/resources/service_principal.md @@ -179,5 +179,5 @@ In addition to all arguments above, the following attributes are exported: Service principals can be imported using their object ID, e.g. ```shell -terraform import azuread_service_principal.test 00000000-0000-0000-0000-000000000000 +terraform import azuread_service_principal.example 00000000-0000-0000-0000-000000000000 ``` diff --git a/docs/resources/service_principal_certificate.md b/docs/resources/service_principal_certificate.md index cfaff3c3e0..fca5938092 100644 --- a/docs/resources/service_principal_certificate.md +++ b/docs/resources/service_principal_certificate.md @@ -83,7 +83,7 @@ No additional attributes are exported. Certificates can be imported using the object ID of the associated service principal and the key ID of the certificate credential, e.g. ```shell -terraform import azuread_service_principal_certificate.test 00000000-0000-0000-0000-000000000000/certificate/11111111-1111-1111-1111-111111111111 +terraform import azuread_service_principal_certificate.example 00000000-0000-0000-0000-000000000000/certificate/11111111-1111-1111-1111-111111111111 ``` -> This ID format is unique to Terraform and is composed of the service principal's object ID, the string "certificate" and the certificate's key ID in the format `{ServicePrincipalObjectId}/certificate/{CertificateKeyId}`. From 80b10c44608b6c6f4919cd36cd95e4e18dd3f3c7 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 01:43:37 +0100 Subject: [PATCH 33/46] documentation for `azuread_application_identifier_uri` --- docs/resources/application_identifier_uri.md | 73 ++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 docs/resources/application_identifier_uri.md diff --git a/docs/resources/application_identifier_uri.md b/docs/resources/application_identifier_uri.md new file mode 100644 index 0000000000..03cc600da7 --- /dev/null +++ b/docs/resources/application_identifier_uri.md @@ -0,0 +1,73 @@ +--- +subcategory: "Applications" +--- + +# Resource: azuread_application_identifier_uri + +Manages a single Identifier URI for an application registration. + +This resource is analogous to the `identifier_uris` property in the `azuread_application` resource. When using these resources together, you should use the `ignore_changes` [lifecycle meta-argument](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle) (see example below). + +## API Permissions + +The following API permissions are required in order to use this resource. + +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` + +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of the application. + +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` + +## Example Usage + +```terraform +resource "azuread_application_registration" "example" { + display_name = "example" +} + +resource "azuread_application_identifier_uri" "example" { + application_id = azuread_application_registration.example.id + identifier_uri = "https://app.hashitown.com" +} +``` + +-> **Tip** For managing multiple identifier URIs for the same application, create another instance of this resource + +*Usage with azuread_application resource* + +```terraform + +resource "azuread_application" "example" { + display_name = "example" + + lifecycle { + ignore_changes = [ + identifier_uris, + ] + } +} + +resource "azuread_application_identifier_uri" "example" { + application_id = azuread_application.example.id + # ... +} +``` + +## Argument Reference + +The following arguments are supported: + +* `application_id` - (Required) The resource ID of the application registration. +* `identifier_uri` - (Required) The user-defined URI that uniquely identifies an application within its Azure AD tenant, or within a verified custom domain if the application is multi-tenant. + +## Attributes Reference + +No additional attributes are exported. + +## Import + +Application Identifier URIs can be imported using the object ID of the application and the base64-encoded identifier URI, in the following format. + +```shell +terraform import azuread_application_identifier_uri.example /applications/00000000-0000-0000-0000-000000000000/identifierUris/aHR0cHM6Ly9leGFtcGxlLm5ldC8= +``` From 38101d599a3179a42477c8afbefed60e2f839044 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 01:49:20 +0100 Subject: [PATCH 34/46] documentation for `azuread_application_known_clients` --- docs/resources/application_known_clients.md | 57 +++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 docs/resources/application_known_clients.md diff --git a/docs/resources/application_known_clients.md b/docs/resources/application_known_clients.md new file mode 100644 index 0000000000..5911336989 --- /dev/null +++ b/docs/resources/application_known_clients.md @@ -0,0 +1,57 @@ +--- +subcategory: "Applications" +--- + +# Resource: azuread_application_known_clients + +Manages the known client applications for an application registration. + +~> This resource is incompatible with the `azuread_application` resource, instead use this with the `azuread_application_registration` resource. + +## API Permissions + +The following API permissions are required in order to use this resource. + +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` + +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of the application. + +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` + +## Example Usage + +```terraform +resource "azuread_application_registration" "example" { + display_name = "example" +} + +resource "azuread_application_registration" "client" { + display_name = "example client" +} + +resource "azuread_application_known_clients" "example" { + application_id = azuread_application_registration.example.id + known_client_ids = [ + azuread_application_registration.client.client_id, + ] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `application_id` - (Required) The resource ID of the application registration. +* `known_client_ids` - (Optional) A set of client IDs for the known applications. + +## Attributes Reference + +No additional attributes are exported. + +## Import + +Application Known Clients can be imported using the object ID of the application in the following format. + +```shell +terraform import azuread_application_known_clients.example /applications/00000000-0000-0000-0000-000000000000/knownClients +``` From 0b5d422c636945f9da28caaf9fd25ed83d347208 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 01:54:56 +0100 Subject: [PATCH 35/46] documentation for `azuread_application_owner` --- docs/resources/application_owner.md | 59 +++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 docs/resources/application_owner.md diff --git a/docs/resources/application_owner.md b/docs/resources/application_owner.md new file mode 100644 index 0000000000..dff08a6c15 --- /dev/null +++ b/docs/resources/application_owner.md @@ -0,0 +1,59 @@ +--- +subcategory: "Applications" +--- + +# Resource: azuread_application_owner + +Manages a single owner of an application registration. + +~> This resource is incompatible with the `azuread_application` resource, instead use this with the `azuread_application_registration` resource. + +## API Permissions + +The following API permissions are required in order to use this resource. + +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` + +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of the application. + +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` + +## Example Usage + +```terraform +resource "azuread_application_registration" "example" { + display_name = "example" +} + +resource "azuread_user" "jane" { + user_principal_name = "jane.fischer@hashitown.com" + display_name = "Jane Fischer" + password = "Ch@ngeMe" +} + +resource "azuread_application_owner" "example_jane" { + application_id = azuread_application_registration.example.id + owner_object_id = azuread_user.jane.object_id +} +``` + +-> **Tip** For managing more application owners, create additional instances of this resource + +## Argument Reference + +The following arguments are supported: + +* `application_id` - (Required) The resource ID of the application registration. +* `owner_object_id` - (Required) The object ID of the owner to assign to the application, typically a user or service principal. + +## Attributes Reference + +No additional attributes are exported. + +## Import + +Application Owners can be imported using the object ID of the application and the object ID of the owner, in the following format. + +```shell +terraform import azuread_application_owner.example /applications/00000000-0000-0000-0000-000000000000/owners/11111111-1111-1111-1111-111111111111 +``` From 9e0d322ead059328a169507935c6799e08b80d41 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 02:03:50 +0100 Subject: [PATCH 36/46] documentation for `azuread_application_permission_scope` --- docs/resources/application_app_role.md | 2 +- .../resources/application_permission_scope.md | 90 +++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 docs/resources/application_permission_scope.md diff --git a/docs/resources/application_app_role.md b/docs/resources/application_app_role.md index f0658500bd..eba0461193 100644 --- a/docs/resources/application_app_role.md +++ b/docs/resources/application_app_role.md @@ -74,7 +74,7 @@ The following arguments are supported: * `value` - (Optional) The value that is used for the `roles` claim in ID tokens and OAuth 2.0 access tokens that are authenticating an assigned service or user principal. --> **Roles and Permission Scopes** In Azure Active Directory, application roles (`app_role`) and permission scopes (`oauth2_permission_scope`) exported by an application share the same namespace and cannot contain duplicate values. +-> **Roles and Permission Scopes** In Azure Active Directory, application roles and permission scopes exported by an application share the same namespace and cannot contain duplicate values. ## Attributes Reference diff --git a/docs/resources/application_permission_scope.md b/docs/resources/application_permission_scope.md new file mode 100644 index 0000000000..a032abe85e --- /dev/null +++ b/docs/resources/application_permission_scope.md @@ -0,0 +1,90 @@ +--- +subcategory: "Applications" +--- + +# Resource: azuread_application_permission_scope + +Manages a permission scope for an application registration. + +This resource is analogous to the `oauth2_permission_scope` block in the `api` block of the `azuread_application` resource. When using these resources together, you should use the `ignore_changes` [lifecycle meta-argument](https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle) (see example below). + +## API Permissions + +The following API permissions are required in order to use this resource. + +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` + +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of the application. + +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` + +## Example Usage + +```terraform +resource "azuread_application_registration" "example" { + display_name = "example" +} + +resource "random_uuid" "example_administer" {} + +resource "azuread_application_permission_scope" "example" { + application_id = azuread_application_registration.test.id + scope_id = random_uuid.example_administer.id + value = "administer" + + admin_consent_description = "Administer the application" + admin_consent_display_name = "Administer" +} +``` + +-> **Tip** For managing more permissions scopes, create additional instances of this resource + +*Usage with azuread_application resource* + +```terraform + +resource "azuread_application" "example" { + display_name = "example" + + lifecycle { + ignore_changes = [ + api[0].oauth2_permission_scope, + ] + } +} + +resource "azuread_application_permission_scope" "example" { + application_id = azuread_application.example.id + # ... +} +``` + +## Argument Reference + +The following arguments are supported: + +* `admin_consent_description` - (Required) Delegated permission description that appears in all tenant-wide admin consent experiences, intended to be read by an administrator granting the permission on behalf of all users. +* `admin_consent_display_name` - (Required) Display name for the delegated permission, intended to be read by an administrator granting the permission on behalf of all users. +* `application_id` - (Required) The resource ID of the application registration. +* `scope_id` - (Required) The unique identifier of the permission scope. Must be a valid UUID. +* `type` - (Required) Whether this delegated permission should be considered safe for non-admin users to consent to on behalf of themselves, or whether an administrator should be required for consent to the permissions. +* `user_consent_description` - (Required) Delegated permission description that appears in the end user consent experience, intended to be read by a user consenting on their own behalf. +* `user_consent_display_name` - (Required) Display name for the delegated permission that appears in the end user consent experience. + +-> **Tip** Use the `random_uuid` resource to generate UUIDs and save them to state for permission scopes within your Terraform configuration + +* `value` - (Optional) The value that is used for the `scp` claim in OAuth access tokens. + +-> **Roles and Permission Scopes** In Azure Active Directory, application roles and permission scopes exported by an application share the same namespace and cannot contain duplicate values. + +## Attributes Reference + +No additional attributes are exported. + +## Import + +Application App Roles can be imported using the object ID of the application and the ID of the permission scope, in the following format. + +```shell +terraform import azuread_application_permission_scope.example /applications/00000000-0000-0000-0000-000000000000/permissionScopes/11111111-1111-1111-1111-111111111111 +``` From 6fd38c55b9ba3caf1d0c4cdacc6609e24a3ddfc5 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 02:16:48 +0100 Subject: [PATCH 37/46] add missing forcenew notes --- docs/resources/application_api_access.md | 4 ++-- docs/resources/application_app_role.md | 4 ++-- docs/resources/application_fallback_public_client.md | 2 +- docs/resources/application_identifier_uri.md | 4 ++-- docs/resources/application_known_clients.md | 4 ++-- docs/resources/application_owner.md | 4 ++-- docs/resources/application_permission_scope.md | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/resources/application_api_access.md b/docs/resources/application_api_access.md index 279f9a3ed0..b51a942384 100644 --- a/docs/resources/application_api_access.md +++ b/docs/resources/application_api_access.md @@ -72,8 +72,8 @@ resource "azuread_application_api_access" "example" { The following arguments are supported: -* `api_client_id` - (Required) The client ID of the API to which access is being granted. -* `application_id` - (Required) The resource ID of the application registration. +* `api_client_id` - (Required) The client ID of the API to which access is being granted. Changing this forces a new resource to be created. +* `application_id` - (Required) The resource ID of the application registration. Changing this forces a new resource to be created. * `role_ids` - (Optional) A set of role IDs to be granted to the application, as published by the API. * `scope_ids` - (Optional) A set of scope IDs to be granted to the application, as published by the API. diff --git a/docs/resources/application_app_role.md b/docs/resources/application_app_role.md index eba0461193..3e5aa5cc51 100644 --- a/docs/resources/application_app_role.md +++ b/docs/resources/application_app_role.md @@ -65,10 +65,10 @@ resource "azuread_application_app_role" "example_administer" { The following arguments are supported: * `allowed_member_types` - (Required) A set of values to specify whether this app role definition can be assigned to users and groups by setting to `User`, or to other applications by setting to `Application`, or to both. -* `application_id` - (Required) The resource ID of the application registration. +* `application_id` - (Required) The resource ID of the application registration. Changing this forces a new resource to be created. * `description` - (Required) Description of the app role that appears when the role is being assigned, and if the role functions as an application permissions, during the consent experiences. * `display_name` - (Required) Display name for the app role that appears during app role assignment and in consent experiences. -* `role_id` - (Required) The unique identifier of the app role. Must be a valid UUID. +* `role_id` - (Required) The unique identifier of the app role. Must be a valid UUID. Changing this forces a new resource to be created. -> **Tip** Use the `random_uuid` resource to generate UUIDs and save them to state for app roles within your Terraform configuration diff --git a/docs/resources/application_fallback_public_client.md b/docs/resources/application_fallback_public_client.md index 807ec77ae8..6d904080a5 100644 --- a/docs/resources/application_fallback_public_client.md +++ b/docs/resources/application_fallback_public_client.md @@ -35,7 +35,7 @@ resource "azuread_application_fallback_public_client" "example" { The following arguments are supported: -* `application_id` - (Required) The resource ID of the application registration. +* `application_id` - (Required) The resource ID of the application registration. Changing this forces a new resource to be created. * `enabled` - (Required) Whether to enable the application as a fallback public client. -> Some configurations may require the Fallback Public Client setting to be `null`, for this case simply destroy this resource (or don't use it) diff --git a/docs/resources/application_identifier_uri.md b/docs/resources/application_identifier_uri.md index 03cc600da7..f846ed0c23 100644 --- a/docs/resources/application_identifier_uri.md +++ b/docs/resources/application_identifier_uri.md @@ -57,8 +57,8 @@ resource "azuread_application_identifier_uri" "example" { The following arguments are supported: -* `application_id` - (Required) The resource ID of the application registration. -* `identifier_uri` - (Required) The user-defined URI that uniquely identifies an application within its Azure AD tenant, or within a verified custom domain if the application is multi-tenant. +* `application_id` - (Required) The resource ID of the application registration. Changing this forces a new resource to be created. +* `identifier_uri` - (Required) The user-defined URI that uniquely identifies an application within its Azure AD tenant, or within a verified custom domain if the application is multi-tenant. Changing this forces a new resource to be created. ## Attributes Reference diff --git a/docs/resources/application_known_clients.md b/docs/resources/application_known_clients.md index 5911336989..8402f44991 100644 --- a/docs/resources/application_known_clients.md +++ b/docs/resources/application_known_clients.md @@ -41,8 +41,8 @@ resource "azuread_application_known_clients" "example" { The following arguments are supported: -* `application_id` - (Required) The resource ID of the application registration. -* `known_client_ids` - (Optional) A set of client IDs for the known applications. +* `application_id` - (Required) The resource ID of the application registration. Changing this forces a new resource to be created. +* `known_client_ids` - (Required) A set of client IDs for the known applications. ## Attributes Reference diff --git a/docs/resources/application_owner.md b/docs/resources/application_owner.md index dff08a6c15..d8c5cd2158 100644 --- a/docs/resources/application_owner.md +++ b/docs/resources/application_owner.md @@ -43,8 +43,8 @@ resource "azuread_application_owner" "example_jane" { The following arguments are supported: -* `application_id` - (Required) The resource ID of the application registration. -* `owner_object_id` - (Required) The object ID of the owner to assign to the application, typically a user or service principal. +* `application_id` - (Required) The resource ID of the application registration. Changing this forces a new resource to be created. +* `owner_object_id` - (Required) The object ID of the owner to assign to the application, typically a user or service principal. Changing this forces a new resource to be created. ## Attributes Reference diff --git a/docs/resources/application_permission_scope.md b/docs/resources/application_permission_scope.md index a032abe85e..987853021c 100644 --- a/docs/resources/application_permission_scope.md +++ b/docs/resources/application_permission_scope.md @@ -65,8 +65,8 @@ The following arguments are supported: * `admin_consent_description` - (Required) Delegated permission description that appears in all tenant-wide admin consent experiences, intended to be read by an administrator granting the permission on behalf of all users. * `admin_consent_display_name` - (Required) Display name for the delegated permission, intended to be read by an administrator granting the permission on behalf of all users. -* `application_id` - (Required) The resource ID of the application registration. -* `scope_id` - (Required) The unique identifier of the permission scope. Must be a valid UUID. +* `application_id` - (Required) The resource ID of the application registration. Changing this forces a new resource to be created. +* `scope_id` - (Required) The unique identifier of the permission scope. Must be a valid UUID. Changing this forces a new resource to be created. * `type` - (Required) Whether this delegated permission should be considered safe for non-admin users to consent to on behalf of themselves, or whether an administrator should be required for consent to the permissions. * `user_consent_description` - (Required) Delegated permission description that appears in the end user consent experience, intended to be read by a user consenting on their own behalf. * `user_consent_display_name` - (Required) Display name for the delegated permission that appears in the end user consent experience. From 6e321abab9524bb1d7a8b6a9270f209386ed357e Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 02:17:20 +0100 Subject: [PATCH 38/46] documentation for `azuread_application_redirect_uris`, also add a test case --- docs/resources/application_redirect_uris.md | 82 +++++++++++++++++++ ...application_redirect_uris_resource_test.go | 69 ++++++++++++++++ .../applications/parse/redirect_uri.go | 2 +- 3 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 docs/resources/application_redirect_uris.md diff --git a/docs/resources/application_redirect_uris.md b/docs/resources/application_redirect_uris.md new file mode 100644 index 0000000000..cbb292eca5 --- /dev/null +++ b/docs/resources/application_redirect_uris.md @@ -0,0 +1,82 @@ +--- +subcategory: "Applications" +--- + +# Resource: azuread_application_redirect_uris + +Manages the redirect URIs for an application registration. + +~> This resource is incompatible with the `azuread_application` resource, instead use this with the `azuread_application_registration` resource. + +## API Permissions + +The following API permissions are required in order to use this resource. + +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` + +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of the application. + +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` + +## Example Usage + +```terraform +resource "azuread_application_registration" "example" { + display_name = "example" +} + +resource "azuread_application_redirect_uris" "example_public" { + application_id = azuread_application_registration.example.id + type = "PublicClient" + + redirect_uris = [ + "myapp://auth", + "sample.mobile.app.bundie.id://auth", + "https://login.microsoftonline.com/common/oauth2/nativeclient", + "https://login.live.com/oauth20_desktop.srf", + "ms-appx-web://Microsoft.AAD.BrokerPlugin/00000000-1111-1111-1111-222222222222", + "urn:ietf:wg:oauth:2.0:foo", + ] +} + +resource "azuread_application_redirect_uris" "example_spa" { + application_id = azuread_application_registration.example.id + type = "SPA" + + redirect_uris = [ + "https://mobile.hashitown.com/", + "https://beta.hashitown.com/", + ] +} + +resource "azuread_application_redirect_uris" "example_web" { + application_id = azuread_application_registration.example.id + type = "Web" + + redirect_uris = [ + "https://app.hashitown.com/", + "https://classic.hashitown.com/", + "urn:ietf:wg:oauth:2.0:oob", + ] +} +``` + +## Argument Reference + +The following arguments are supported: + +* `application_id` - (Required) The resource ID of the application registration. Changing this forces a new resource to be created. +* `redirect_uris` - (Required) A set of redirect URIs to assign to the application. +* `type` - (Required) The type of redirect URIs to manage. Must be one of: `PublicClient`, `SPA`, or `Web`. Changing this forces a new resource to be created. + +## Attributes Reference + +No additional attributes are exported. + +## Import + +Application API Access can be imported using the object ID of the application and the URI type, in the following format. + +```shell +terraform import azuread_application_redirect_uris.example /applications/00000000-0000-0000-0000-000000000000/uriType/Web +``` diff --git a/internal/services/applications/application_redirect_uris_resource_test.go b/internal/services/applications/application_redirect_uris_resource_test.go index fba95dbd4b..a1bb789209 100644 --- a/internal/services/applications/application_redirect_uris_resource_test.go +++ b/internal/services/applications/application_redirect_uris_resource_test.go @@ -69,6 +69,30 @@ func TestAccApplicationRedirectUris_web(t *testing.T) { }) } +func TestAccApplicationRedirectUris_all(t *testing.T) { + data := acceptance.BuildTestData(t, "azuread_application_redirect_uris", "test_public") + data2 := acceptance.BuildTestData(t, "azuread_application_redirect_uris", "test_spa") + data3 := acceptance.BuildTestData(t, "azuread_application_redirect_uris", "test_web") + r := ApplicationRedirectUrisResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.all(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + check.That(data.ResourceName).Key("application_id").Exists(), + check.That(data2.ResourceName).ExistsInAzure(r), + check.That(data2.ResourceName).Key("application_id").Exists(), + check.That(data3.ResourceName).ExistsInAzure(r), + check.That(data3.ResourceName).Key("application_id").Exists(), + ), + }, + data.ImportStep(), + data2.ImportStep(), + data3.ImportStep(), + }) +} + func TestAccApplicationRedirectUris_requiresImport(t *testing.T) { data := acceptance.BuildTestData(t, "azuread_application_redirect_uris", "test") r := ApplicationRedirectUrisResource{} @@ -189,6 +213,51 @@ resource "azuread_application_redirect_uris" "test" { `, data.RandomInteger) } +func (ApplicationRedirectUrisResource) all(data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azuread" {} + +resource "azuread_application_registration" "test" { + display_name = "acctest-RedirectUris-%[1]d" +} + +resource "azuread_application_redirect_uris" "test_public" { + application_id = azuread_application_registration.test.id + type = "PublicClient" + + redirect_uris = [ + "myapp://auth", + "sample.mobile.app.bundie.id://auth", + "https://login.microsoftonline.com/common/oauth2/nativeclient", + "https://login.live.com/oauth20_desktop.srf", + "ms-appx-web://Microsoft.AAD.BrokerPlugin/00000000-1111-1111-1111-222222222222", + "urn:ietf:wg:oauth:2.0:foo", + ] +} + +resource "azuread_application_redirect_uris" "test_spa" { + application_id = azuread_application_registration.test.id + type = "SPA" + + redirect_uris = [ + "https://mobile.hashitown-%[1]d.com/", + "https://beta.hashitown-%[1]d.com/", + ] +} + +resource "azuread_application_redirect_uris" "test_web" { + application_id = azuread_application_registration.test.id + type = "Web" + + redirect_uris = [ + "https://app.hashitown-%[1]d.com/", + "https://classic.hashitown-%[1]d.com/", + "urn:ietf:wg:oauth:2.0:oob", + ] +} +`, data.RandomInteger) +} + func (r ApplicationRedirectUrisResource) requiresImport(data acceptance.TestData) string { return fmt.Sprintf(` %[1]s diff --git a/internal/services/applications/parse/redirect_uri.go b/internal/services/applications/parse/redirect_uri.go index 9cb5e4215d..63bd1bd73f 100644 --- a/internal/services/applications/parse/redirect_uri.go +++ b/internal/services/applications/parse/redirect_uri.go @@ -68,7 +68,7 @@ func (id RedirectUrisId) Segments() []resourceids.Segment { resourceids.StaticSegment("applications", "applications", "applications"), resourceids.UserSpecifiedSegment("applicationId", "00000000-0000-0000-0000-000000000000"), resourceids.StaticSegment("redirectUris", "redirectUris", "redirectUris"), - resourceids.UserSpecifiedSegment("uriType", "web"), + resourceids.UserSpecifiedSegment("uriType", "Web"), } } From 20a10e4a783097ae022d16b7b3e5fdb2c4d37f1c Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 02:23:22 +0100 Subject: [PATCH 39/46] updated docs for `azuread_service_principal`, `data.azuread_service_principal`, `data.azure_ad_service_principals` --- docs/data-sources/service_principal.md | 14 ++++++++------ docs/data-sources/service_principals.md | 15 +++++++++------ docs/resources/service_principal.md | 6 +++++- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/docs/data-sources/service_principal.md b/docs/data-sources/service_principal.md index 3bd7a131c3..6dc2f0fe71 100644 --- a/docs/data-sources/service_principal.md +++ b/docs/data-sources/service_principal.md @@ -24,11 +24,11 @@ data "azuread_service_principal" "example" { } ``` -*Look up by application ID (client ID)* +*Look up by client ID* ```terraform data "azuread_service_principal" "example" { - application_id = "00000000-0000-0000-0000-000000000000" + client_id = "00000000-0000-0000-0000-000000000000" } ``` @@ -44,23 +44,25 @@ data "azuread_service_principal" "example" { The following arguments are supported: -* `application_id` - (Optional) The application ID (client ID) of the application associated with this service principal. +* `application_id` - (Optional, Deprecated) The client ID of the application associated with this service principal. +* `client_id` - (Optional) The client ID of the application associated with this service principal. * `display_name` - (Optional) The display name of the application associated with this service principal. * `object_id` - (Optional) The object ID of the service principal. -~> One of `application_id`, `display_name` or `object_id` must be specified. +~> One of `client_id`, `application_id`, `display_name` or `object_id` must be specified. ## Attributes Reference The following attributes are exported: -* `account_enabled` - Whether or not the service principal account is enabled. +* `account_enabled` - Whether the service principal account is enabled. * `alternative_names` - A list of alternative names, used to retrieve service principals by subscription, identify resource group and full resource ids for managed identities. -* `application_id` - The application ID (client ID) of the application associated with this service principal. +* `application_id` - (Deprecated) The client ID of the application associated with this service principal. * `app_role_assignment_required` - Whether this service principal requires an app role assignment to a user or group before Azure AD will issue a user or access token to the application. * `app_role_ids` - A mapping of app role values to app role IDs, as published by the associated application, intended to be useful when referencing app roles in other resources in your configuration. * `app_roles` - A list of app roles published by the associated application, as documented below. For more information [official documentation](https://docs.microsoft.com/en-us/azure/architecture/multitenant-identity/app-roles). * `application_tenant_id` - The tenant ID where the associated application is registered. +* `client_id` - (Deprecated) The client ID of the application associated with this service principal. * `description` - A description of the service principal provided for internal end-users. * `display_name` - The display name of the application associated with this service principal. * `features` - A `features` block as described below. diff --git a/docs/data-sources/service_principals.md b/docs/data-sources/service_principals.md index 47ae4bb176..84c925f714 100644 --- a/docs/data-sources/service_principals.md +++ b/docs/data-sources/service_principals.md @@ -31,7 +31,7 @@ data "azuread_service_principals" "example" { ```terraform data "azuread_service_principals" "example" { - application_ids = [ + client_ids = [ "11111111-0000-0000-0000-000000000000", "22222222-0000-0000-0000-000000000000", "33333333-0000-0000-0000-000000000000", @@ -55,19 +55,21 @@ data "azuread_service_principals" "example" { The following arguments are supported: -* `application_ids` - (Optional) A list of application IDs (client IDs) of the applications associated with the service principals. +* `application_ids` - (Optional, Deprecated) A list of client IDs of the applications associated with the service principals. +* `client_ids` - (Optional) A list of client IDs of the applications associated with the service principals. * `display_names` - (Optional) A list of display names of the applications associated with the service principals. * `ignore_missing` - (Optional) Ignore missing service principals and return all service principals that are found. The data source will still fail if no service principals are found. Defaults to false. * `object_ids` - (Optional) The object IDs of the service principals. * `return_all` - (Optional) When `true`, the data source will return all service principals. Cannot be used with `ignore_missing`. Defaults to false. -~> Either `return_all`, or one of `application_ids`, `display_names` or `object_ids` must be specified. These _may_ be specified as an empty list, in which case no results will be returned. +~> Either `return_all`, or one of `client_ids`, `application_ids`, `display_names` or `object_ids` must be specified. These _may_ be specified as an empty list, in which case no results will be returned. ## Attributes Reference The following attributes are exported: -* `application_ids` - A list of application IDs (client IDs) of the applications associated with the service principals. +* `application_ids` - A list of client IDs of the applications associated with the service principals. +* `client_ids` - A list of client IDs of the applications associated with the service principals. * `display_names` - A list of display names of the applications associated with the service principals. * `object_ids` - The object IDs of the service principals. * `service_principals` - A list of service principals. Each `service_principal` object provides the attributes documented below. @@ -76,10 +78,11 @@ The following attributes are exported: `service_principal` object exports the following: -* `account_enabled` - Whether or not the service principal account is enabled. +* `account_enabled` - Whether the service principal account is enabled. * `app_role_assignment_required` - Whether this service principal requires an app role assignment to a user or group before Azure AD will issue a user or access token to the application. -* `application_id` - The application ID (client ID) of the application associated with this service principal. +* `application_id` - (Deprecated) The client ID of the application associated with this service principal. * `application_tenant_id` - The tenant ID where the associated application is registered. +* `client_ids` - The client ID of the application associated with this service principal. * `display_name` - The display name of the application associated with this service principal. * `object_id` - The object ID of the service principal. * `preferred_single_sign_on_mode` - The single sign-on mode configured for this application. Azure AD uses the preferred single sign-on mode to launch the application from Microsoft 365 or the Azure AD My Apps. diff --git a/docs/resources/service_principal.md b/docs/resources/service_principal.md index 5498fd1133..3776991802 100644 --- a/docs/resources/service_principal.md +++ b/docs/resources/service_principal.md @@ -93,7 +93,11 @@ The following arguments are supported: * `account_enabled` - (Optional) Whether or not the service principal account is enabled. Defaults to `true`. * `alternative_names` - (Optional) A set of alternative names, used to retrieve service principals by subscription, identify resource group and full resource ids for managed identities. * `app_role_assignment_required` - (Optional) Whether this service principal requires an app role assignment to a user or group before Azure AD will issue a user or access token to the application. Defaults to `false`. -* `application_id` - (Required) The application ID (client ID) of the application for which to create a service principal. +* `application_id` - (Optional, Deprecated) The client ID of the application for which to create a service principal. +* `client_id` - (Optional) The client ID of the application for which to create a service principal. + +~. At least one of `client_id` or `application_id` must be specified. + * `description` - (Optional) A description of the service principal provided for internal end-users. * `feature_tags` - (Optional) A `feature_tags` block as described below. Cannot be used together with the `tags` property. From 2c0407d4aedb90084fa5188e392655b0114ec5d9 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 01:05:06 +0100 Subject: [PATCH 40/46] linting! --- internal/helpers/applications.go | 4 +- .../administrative_unit_member_resource.go | 8 +- ...dministrative_unit_member_resource_test.go | 6 +- .../administrative_unit_resource.go | 29 ++-- .../administrative_unit_resource_test.go | 4 +- ...dministrative_unit_role_member_resource.go | 8 +- ...strative_unit_role_member_resource_test.go | 6 +- ..._federated_identity_credential_resource.go | 5 +- .../application_from_template_resource.go | 3 +- .../application_identifier_uri_resource.go | 2 +- .../application_registration_resource.go | 5 +- .../applications/application_resource.go | 28 ++-- .../applications/application_resource_test.go | 4 +- .../services/applications/applications.go | 54 +++---- .../migrations/application_resource.go | 6 +- .../applications/parse/application.go | 1 + .../app_role_assignment_resource.go | 8 +- .../app_role_assignment_resource_test.go | 6 +- .../conditional_access_policy_resource.go | 16 +-- ...conditional_access_policy_resource_test.go | 4 +- .../conditionalaccess/conditionalaccess.go | 30 ++-- .../named_location_resource.go | 12 +- .../named_location_resource_test.go | 6 +- .../custom_directory_role_resource.go | 22 +-- .../custom_directory_role_resource_test.go | 4 +- .../directory_role_assignment_resource.go | 4 +- ...directory_role_assignment_resource_test.go | 6 +- ...e_eligibility_schedule_request_resource.go | 12 +- ...gibility_schedule_request_resource_test.go | 4 +- .../directory_role_member_resource.go | 8 +- .../directory_role_member_resource_test.go | 6 +- .../directory_role_resource_test.go | 4 +- internal/services/groups/group_data_source.go | 6 +- .../services/groups/group_member_resource.go | 8 +- .../groups/group_member_resource_test.go | 4 +- internal/services/groups/group_resource.go | 113 +++++++-------- .../services/groups/group_resource_test.go | 4 +- internal/services/groups/groups.go | 2 - ...cess_package_assignment_policy_resource.go | 18 +-- ...package_assignment_policy_resource_test.go | 6 +- .../access_package_catalog_resource.go | 20 +-- .../access_package_catalog_resource_test.go | 6 +- ...ackage_catalog_role_assignment_resource.go | 12 +- ...e_catalog_role_assignment_resource_test.go | 6 +- .../access_package_resource.go | 20 +-- ...e_resource_catalog_association_resource.go | 4 +- ...ource_catalog_association_resource_test.go | 6 +- ...e_resource_package_association_resource.go | 6 +- ...ource_package_association_resource_test.go | 6 +- .../access_package_resource_test.go | 6 +- .../identitygovernance/identitygovernance.go | 46 +++--- .../invitations/invitation_resource.go | 20 +-- .../invitations/invitation_resource_test.go | 4 +- .../claims_mapping_policy_resource.go | 6 +- .../service_principal_certificate_resource.go | 6 +- ...ice_principal_certificate_resource_test.go | 4 +- ...aims_mapping_policy_assignment_resource.go | 6 +- ...mapping_policy_assignment_resource_test.go | 10 +- ...pal_delegated_permission_grant_resource.go | 14 +- ...elegated_permission_grant_resource_test.go | 4 +- .../service_principal_password_resource.go | 6 +- ...ervice_principal_password_resource_test.go | 4 +- ...ipal_token_signing_certificate_resource.go | 8 +- ...token_signing_certificate_resource_test.go | 4 +- .../serviceprincipals/serviceprincipals.go | 4 +- .../serviceprincipals/synchronization.go | 12 +- .../synchronization_job_resource.go | 8 +- .../synchronization_job_resource_test.go | 4 +- .../synchronization_secret_resource.go | 6 +- .../synchronization_secret_resource_test.go | 4 +- .../userflows/user_flow_attribute_resource.go | 16 +-- .../user_flow_attribute_resource_test.go | 4 +- internal/services/users/user_resource.go | 132 +++++++++--------- internal/services/users/user_resource_test.go | 4 +- internal/services/users/users.go | 4 +- 75 files changed, 458 insertions(+), 460 deletions(-) diff --git a/internal/helpers/applications.go b/internal/helpers/applications.go index 8f46e30ef2..96a5465f1b 100644 --- a/internal/helpers/applications.go +++ b/internal/helpers/applications.go @@ -59,7 +59,7 @@ func ApplicationFlattenAppRoleIDs(in *[]msgraph.AppRole) map[string]string { func ApplicationFlattenAppRoles(in *[]msgraph.AppRole) (result []map[string]interface{}) { if in == nil { - return + return //nolint:nakedret } for _, role := range *in { @@ -177,7 +177,7 @@ func ApplicationFlattenOAuth2PermissionScopeIDs(in *[]msgraph.PermissionScope) m func ApplicationFlattenOAuth2PermissionScopes(in *[]msgraph.PermissionScope) (result []map[string]interface{}) { if in == nil { - return + return //nolint:nakedret } for _, p := range *in { diff --git a/internal/services/administrativeunits/administrative_unit_member_resource.go b/internal/services/administrativeunits/administrative_unit_member_resource.go index 5b426f6fb7..a87feec1be 100644 --- a/internal/services/administrativeunits/administrative_unit_member_resource.go +++ b/internal/services/administrativeunits/administrative_unit_member_resource.go @@ -11,6 +11,7 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/helpers" @@ -18,7 +19,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -93,7 +93,7 @@ func administrativeUnitMemberResourceCreate(ctx context.Context, d *pluginsdk.Re if memberObject == nil { return tf.ErrorDiagF(errors.New("returned memberObject was nil"), "Could not retrieve member principal object %q", id.MemberId) } - memberObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + memberObject.ODataId = (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, id.MemberId))) members := &msgraph.Members{*memberObject} @@ -178,11 +178,11 @@ func administrativeUnitMemberResourceDelete(ctx context.Context, d *pluginsdk.Re client.BaseClient.DisableRetries = true if _, status, err := client.GetMember(ctx, id.AdministrativeUnitId, id.MemberId); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for removal of member %q from administrative unit with object ID %q", id.MemberId, id.AdministrativeUnitId) } diff --git a/internal/services/administrativeunits/administrative_unit_member_resource_test.go b/internal/services/administrativeunits/administrative_unit_member_resource_test.go index 670424aea1..67a7653c5f 100644 --- a/internal/services/administrativeunits/administrative_unit_member_resource_test.go +++ b/internal/services/administrativeunits/administrative_unit_member_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/services/administrativeunits/parse" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" ) type AdministrativeUnitMemberResource struct{} @@ -120,12 +120,12 @@ func (r AdministrativeUnitMemberResource) Exists(ctx context.Context, clients *c if _, status, err := client.GetMember(ctx, id.AdministrativeUnitId, id.MemberId); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, fmt.Errorf("failed to retrieve administrative unit member %q (administrative unit ID: %q): %+v", id.MemberId, id.AdministrativeUnitId, err) } - return utils.Bool(true), nil + return pointer.To(true), nil } func (AdministrativeUnitMemberResource) templateThreeUsers(data acceptance.TestData) string { diff --git a/internal/services/administrativeunits/administrative_unit_resource.go b/internal/services/administrativeunits/administrative_unit_resource.go index e397aa1317..84de7a56ab 100644 --- a/internal/services/administrativeunits/administrative_unit_resource.go +++ b/internal/services/administrativeunits/administrative_unit_resource.go @@ -11,6 +11,7 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" @@ -151,13 +152,13 @@ func administrativeUnitResourceCreate(ctx context.Context, d *pluginsdk.Resource tempDisplayName := fmt.Sprintf("TERRAFORM_UPDATE_%s", uuid) properties := msgraph.AdministrativeUnit{ - Description: utils.NullableString(d.Get("description").(string)), - DisplayName: utils.String(tempDisplayName), - Visibility: utils.String(msgraph.AdministrativeUnitVisibilityPublic), + Description: tf.NullableString(d.Get("description").(string)), + DisplayName: pointer.To(tempDisplayName), + Visibility: pointer.To(msgraph.AdministrativeUnitVisibilityPublic), } if d.Get("hidden_membership_enabled").(bool) { - properties.Visibility = utils.String(msgraph.AdministrativeUnitVisibilityHiddenMembership) + properties.Visibility = pointer.To(msgraph.AdministrativeUnitVisibilityHiddenMembership) } administrativeUnit, _, err := client.Create(ctx, properties) @@ -175,7 +176,7 @@ func administrativeUnitResourceCreate(ctx context.Context, d *pluginsdk.Resource // The SDK handles retries for us here in the event of 404, 429 or 5xx, then returns after giving up status, err := client.Update(ctx, msgraph.AdministrativeUnit{ ID: administrativeUnit.ID, - DisplayName: utils.String(displayName), + DisplayName: pointer.To(displayName), }) if err != nil { if status == http.StatusNotFound { @@ -195,7 +196,7 @@ func administrativeUnitResourceCreate(ctx context.Context, d *pluginsdk.Resource if memberObject == nil { return tf.ErrorDiagF(errors.New("memberObject was nil"), "Could not retrieve member principal object %q", memberId) } - memberObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + memberObject.ODataId = (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, memberId))) members = append(members, *memberObject) @@ -241,14 +242,14 @@ func administrativeUnitResourceUpdate(ctx context.Context, d *pluginsdk.Resource } administrativeUnit := msgraph.AdministrativeUnit{ - ID: utils.String(administrativeUnitId), - Description: utils.NullableString(d.Get("description").(string)), - DisplayName: utils.String(displayName), - Visibility: utils.String(msgraph.AdministrativeUnitVisibilityPublic), + ID: pointer.To(administrativeUnitId), + Description: tf.NullableString(d.Get("description").(string)), + DisplayName: pointer.To(displayName), + Visibility: pointer.To(msgraph.AdministrativeUnitVisibilityPublic), } if d.Get("hidden_membership_enabled").(bool) { - administrativeUnit.Visibility = utils.String(msgraph.AdministrativeUnitVisibilityHiddenMembership) + administrativeUnit.Visibility = pointer.To(msgraph.AdministrativeUnitVisibilityHiddenMembership) } if _, err := client.Update(ctx, administrativeUnit); err != nil { @@ -282,7 +283,7 @@ func administrativeUnitResourceUpdate(ctx context.Context, d *pluginsdk.Resource if memberObject == nil { return tf.ErrorDiagF(errors.New("returned memberObject was nil"), "Could not retrieve member principal object %q", memberId) } - memberObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + memberObject.ODataId = (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, memberId))) newMembers = append(newMembers, *memberObject) @@ -354,11 +355,11 @@ func administrativeUnitResourceDelete(ctx context.Context, d *pluginsdk.Resource client.BaseClient.DisableRetries = true if _, status, err := client.Get(ctx, administrativeUnitId, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of administrative unit with object ID %q", administrativeUnitId) } diff --git a/internal/services/administrativeunits/administrative_unit_resource_test.go b/internal/services/administrativeunits/administrative_unit_resource_test.go index 7551d343f1..d1cdb0fece 100644 --- a/internal/services/administrativeunits/administrative_unit_resource_test.go +++ b/internal/services/administrativeunits/administrative_unit_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type AdministrativeUnitResource struct{} @@ -103,7 +103,7 @@ func (r AdministrativeUnitResource) Exists(ctx context.Context, clients *clients } return nil, fmt.Errorf("failed to retrieve Administratove Unit with object ID %q: %+v", state.ID, err) } - return utils.Bool(role.ID != nil && *role.ID == state.ID), nil + return pointer.To(role.ID != nil && *role.ID == state.ID), nil } func (AdministrativeUnitResource) basic(data acceptance.TestData) string { diff --git a/internal/services/administrativeunits/administrative_unit_role_member_resource.go b/internal/services/administrativeunits/administrative_unit_role_member_resource.go index eacee8b70f..534a3a2cb3 100644 --- a/internal/services/administrativeunits/administrative_unit_role_member_resource.go +++ b/internal/services/administrativeunits/administrative_unit_role_member_resource.go @@ -9,13 +9,13 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/services/administrativeunits/parse" "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -68,12 +68,12 @@ func administrativeUnitRoleMemberResource() *pluginsdk.Resource { func administrativeUnitRoleMemberResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) pluginsdk.Diagnostics { client := meta.(*clients.Client).AdministrativeUnits.AdministrativeUnitsClient - memberID := utils.String(d.Get("member_object_id").(string)) - adminUnitID := utils.String(d.Get("administrative_unit_object_id").(string)) + memberID := pointer.To(d.Get("member_object_id").(string)) + adminUnitID := pointer.To(d.Get("administrative_unit_object_id").(string)) properties := msgraph.ScopedRoleMembership{ AdministrativeUnitId: adminUnitID, - RoleId: utils.String(d.Get("role_object_id").(string)), + RoleId: pointer.To(d.Get("role_object_id").(string)), RoleMemberInfo: &msgraph.Identity{ Id: memberID, }, diff --git a/internal/services/administrativeunits/administrative_unit_role_member_resource_test.go b/internal/services/administrativeunits/administrative_unit_role_member_resource_test.go index 15c06b184b..cd7a8e7764 100644 --- a/internal/services/administrativeunits/administrative_unit_role_member_resource_test.go +++ b/internal/services/administrativeunits/administrative_unit_role_member_resource_test.go @@ -9,13 +9,13 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/services/administrativeunits/parse" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" ) type AdministrativeUnitRoleMemberResource struct{} @@ -109,12 +109,12 @@ func (r AdministrativeUnitRoleMemberResource) Exists(ctx context.Context, client if _, status, err := client.GetScopedRoleMember(ctx, id.AdministrativeUnitId, id.ScopedRoleMembershipId, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, fmt.Errorf("failed to retrieve administrative unit role membership %q (AU ID: %q): %+v", id.ScopedRoleMembershipId, id.AdministrativeUnitId, err) } - return utils.Bool(true), nil + return pointer.To(true), nil } func (AdministrativeUnitRoleMemberResource) templateThreeUsers(data acceptance.TestData) string { diff --git a/internal/services/applications/application_federated_identity_credential_resource.go b/internal/services/applications/application_federated_identity_credential_resource.go index adf74516ae..146e19723a 100644 --- a/internal/services/applications/application_federated_identity_credential_resource.go +++ b/internal/services/applications/application_federated_identity_credential_resource.go @@ -20,7 +20,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -151,7 +150,7 @@ func applicationFederatedIdentityCredentialResourceCreate(ctx context.Context, d credential := msgraph.FederatedIdentityCredential{ Audiences: tf.ExpandStringSlicePtr(d.Get("audiences").([]interface{})), - Description: utils.NullableString(d.Get("description").(string)), + Description: tf.NullableString(d.Get("description").(string)), Issuer: pointer.To(d.Get("issuer").(string)), Name: pointer.To(d.Get("display_name").(string)), Subject: pointer.To(d.Get("subject").(string)), @@ -221,7 +220,7 @@ func applicationFederatedIdentityCredentialResourceUpdate(ctx context.Context, d credential := msgraph.FederatedIdentityCredential{ ID: pointer.To(id.KeyId), Audiences: tf.ExpandStringSlicePtr(d.Get("audiences").([]interface{})), - Description: utils.NullableString(d.Get("description").(string)), + Description: tf.NullableString(d.Get("description").(string)), Issuer: pointer.To(d.Get("issuer").(string)), Subject: pointer.To(d.Get("subject").(string)), } diff --git a/internal/services/applications/application_from_template_resource.go b/internal/services/applications/application_from_template_resource.go index 0af4c8ac53..1a3d7ca951 100644 --- a/internal/services/applications/application_from_template_resource.go +++ b/internal/services/applications/application_from_template_resource.go @@ -17,7 +17,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -137,7 +136,7 @@ func (r ApplicationFromTemplateResource) Create() sdk.ResourceFunc { result, status, err := client.Get(ctx, *result.Application.ID(), odata.Query{}) if err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } diff --git a/internal/services/applications/application_identifier_uri_resource.go b/internal/services/applications/application_identifier_uri_resource.go index b70a1917da..b0994836db 100644 --- a/internal/services/applications/application_identifier_uri_resource.go +++ b/internal/services/applications/application_identifier_uri_resource.go @@ -7,7 +7,6 @@ import ( "context" "encoding/base64" "fmt" - "github.com/manicminer/hamilton/msgraph" "net/http" "time" @@ -17,6 +16,7 @@ import ( "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" ) type ApplicationIdentifierUriModel struct { diff --git a/internal/services/applications/application_registration_resource.go b/internal/services/applications/application_registration_resource.go index 8ae96c02d9..947bdc4fde 100644 --- a/internal/services/applications/application_registration_resource.go +++ b/internal/services/applications/application_registration_resource.go @@ -17,7 +17,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -467,11 +466,11 @@ func (r ApplicationRegistrationResource) Delete() sdk.ResourceFunc { client.BaseClient.DisableRetries = true if _, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return fmt.Errorf("waiting for deletion of %s: %q", id, err) } diff --git a/internal/services/applications/application_resource.go b/internal/services/applications/application_resource.go index 730bed2ebe..72f338a357 100644 --- a/internal/services/applications/application_resource.go +++ b/internal/services/applications/application_resource.go @@ -989,24 +989,24 @@ func applicationResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, m properties := msgraph.Application{ Api: api, AppRoles: expandApplicationAppRoles(d.Get("app_role").(*pluginsdk.Set).List()), - Description: utils.NullableString(d.Get("description").(string)), + Description: tf.NullableString(d.Get("description").(string)), DisplayName: pointer.To(displayName), GroupMembershipClaims: expandApplicationGroupMembershipClaims(d.Get("group_membership_claims").(*pluginsdk.Set).List()), IdentifierUris: tf.ExpandStringSlicePtr(d.Get("identifier_uris").(*pluginsdk.Set).List()), Info: &msgraph.InformationalUrl{ - MarketingUrl: utils.NullableString(d.Get("marketing_url").(string)), - PrivacyStatementUrl: utils.NullableString(d.Get("privacy_statement_url").(string)), - SupportUrl: utils.NullableString(d.Get("support_url").(string)), - TermsOfServiceUrl: utils.NullableString(d.Get("terms_of_service_url").(string)), + MarketingUrl: tf.NullableString(d.Get("marketing_url").(string)), + PrivacyStatementUrl: tf.NullableString(d.Get("privacy_statement_url").(string)), + SupportUrl: tf.NullableString(d.Get("support_url").(string)), + TermsOfServiceUrl: tf.NullableString(d.Get("terms_of_service_url").(string)), }, IsDeviceOnlyAuthSupported: pointer.To(d.Get("device_only_auth_enabled").(bool)), IsFallbackPublicClient: pointer.To(d.Get("fallback_public_client_enabled").(bool)), - Notes: utils.NullableString(d.Get("notes").(string)), + Notes: tf.NullableString(d.Get("notes").(string)), Oauth2RequirePostResponse: pointer.To(d.Get("oauth2_post_response_required").(bool)), OptionalClaims: expandApplicationOptionalClaims(d.Get("optional_claims").([]interface{})), PublicClient: expandApplicationPublicClient(d.Get("public_client").([]interface{})), RequiredResourceAccess: expandApplicationRequiredResourceAccess(d.Get("required_resource_access").(*pluginsdk.Set).List()), - ServiceManagementReference: utils.NullableString(d.Get("service_management_reference").(string)), + ServiceManagementReference: tf.NullableString(d.Get("service_management_reference").(string)), SignInAudience: pointer.To(d.Get("sign_in_audience").(string)), Spa: expandApplicationSpa(d.Get("single_page_application").([]interface{})), Tags: &tags, @@ -1190,24 +1190,24 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m }, Api: expandApplicationApi(d.Get("api").([]interface{})), AppRoles: expandApplicationAppRoles(d.Get("app_role").(*pluginsdk.Set).List()), - Description: utils.NullableString(d.Get("description").(string)), + Description: tf.NullableString(d.Get("description").(string)), DisplayName: pointer.To(displayName), GroupMembershipClaims: expandApplicationGroupMembershipClaims(d.Get("group_membership_claims").(*pluginsdk.Set).List()), IdentifierUris: tf.ExpandStringSlicePtr(d.Get("identifier_uris").(*pluginsdk.Set).List()), Info: &msgraph.InformationalUrl{ - MarketingUrl: utils.NullableString(d.Get("marketing_url").(string)), - PrivacyStatementUrl: utils.NullableString(d.Get("privacy_statement_url").(string)), - SupportUrl: utils.NullableString(d.Get("support_url").(string)), - TermsOfServiceUrl: utils.NullableString(d.Get("terms_of_service_url").(string)), + MarketingUrl: tf.NullableString(d.Get("marketing_url").(string)), + PrivacyStatementUrl: tf.NullableString(d.Get("privacy_statement_url").(string)), + SupportUrl: tf.NullableString(d.Get("support_url").(string)), + TermsOfServiceUrl: tf.NullableString(d.Get("terms_of_service_url").(string)), }, IsDeviceOnlyAuthSupported: pointer.To(d.Get("device_only_auth_enabled").(bool)), IsFallbackPublicClient: pointer.To(d.Get("fallback_public_client_enabled").(bool)), - Notes: utils.NullableString(d.Get("notes").(string)), + Notes: tf.NullableString(d.Get("notes").(string)), Oauth2RequirePostResponse: pointer.To(d.Get("oauth2_post_response_required").(bool)), OptionalClaims: expandApplicationOptionalClaims(d.Get("optional_claims").([]interface{})), PublicClient: expandApplicationPublicClient(d.Get("public_client").([]interface{})), RequiredResourceAccess: expandApplicationRequiredResourceAccess(d.Get("required_resource_access").(*pluginsdk.Set).List()), - ServiceManagementReference: utils.NullableString(d.Get("service_management_reference").(string)), + ServiceManagementReference: tf.NullableString(d.Get("service_management_reference").(string)), SignInAudience: pointer.To(d.Get("sign_in_audience").(string)), Spa: expandApplicationSpa(d.Get("single_page_application").([]interface{})), Tags: &tags, diff --git a/internal/services/applications/application_resource_test.go b/internal/services/applications/application_resource_test.go index 2175afb531..4dedc02af1 100644 --- a/internal/services/applications/application_resource_test.go +++ b/internal/services/applications/application_resource_test.go @@ -10,12 +10,12 @@ import ( "regexp" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type ApplicationResource struct{} @@ -604,7 +604,7 @@ func (r ApplicationResource) Exists(ctx context.Context, clients *clients.Client } return nil, fmt.Errorf("failed to retrieve Application with object ID %q: %+v", state.ID, err) } - return utils.Bool(app.ID() != nil && *app.ID() == state.ID), nil + return pointer.To(app.ID() != nil && *app.ID() == state.ID), nil } func (ApplicationResource) basic(data acceptance.TestData) string { diff --git a/internal/services/applications/applications.go b/internal/services/applications/applications.go index a98fb505c1..9059e080a0 100644 --- a/internal/services/applications/applications.go +++ b/internal/services/applications/applications.go @@ -12,11 +12,11 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "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/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -380,10 +380,10 @@ func applicationValidateRolesScopes(appRoles, oauth2Permissions []interface{}) e func expandApplicationApi(input []interface{}) (result *msgraph.ApplicationApi) { result = &msgraph.ApplicationApi{ - AcceptMappedClaims: utils.Bool(false), + AcceptMappedClaims: pointer.To(false), KnownClientApplications: &[]string{}, OAuth2PermissionScopes: &[]msgraph.PermissionScope{}, - RequestedAccessTokenVersion: utils.Int32(int32(1)), + RequestedAccessTokenVersion: pointer.To(int32(1)), } if len(input) == 0 || input[0] == nil { @@ -392,14 +392,14 @@ func expandApplicationApi(input []interface{}) (result *msgraph.ApplicationApi) in := input[0].(map[string]interface{}) if v, ok := in["mapped_claims_enabled"]; ok { - result.AcceptMappedClaims = utils.Bool(v.(bool)) + result.AcceptMappedClaims = pointer.To(v.(bool)) } if v, ok := in["known_client_applications"]; ok { result.KnownClientApplications = tf.ExpandStringSlicePtr(v.(*pluginsdk.Set).List()) } result.OAuth2PermissionScopes = expandApplicationOAuth2PermissionScope(in["oauth2_permission_scope"].(*pluginsdk.Set).List()) if v, ok := in["requested_access_token_version"]; ok { - result.RequestedAccessTokenVersion = utils.Int32(int32(v.(int))) + result.RequestedAccessTokenVersion = pointer.To(int32(v.(int))) } return @@ -424,15 +424,15 @@ func expandApplicationAppRoles(input []interface{}) *[]msgraph.AppRole { } newAppRole := msgraph.AppRole{ - ID: utils.String(appRole["id"].(string)), + ID: pointer.To(appRole["id"].(string)), AllowedMemberTypes: &allowedMemberTypes, - Description: utils.String(appRole["description"].(string)), - DisplayName: utils.String(appRole["display_name"].(string)), - IsEnabled: utils.Bool(appRole["enabled"].(bool)), + Description: pointer.To(appRole["description"].(string)), + DisplayName: pointer.To(appRole["display_name"].(string)), + IsEnabled: pointer.To(appRole["enabled"].(bool)), } if v, ok := appRole["value"]; ok { - newAppRole.Value = utils.String(v.(string)) + newAppRole.Value = pointer.To(v.(string)) } result = append(result, newAppRole) @@ -462,8 +462,8 @@ func expandApplicationImplicitGrantSettings(input []interface{}) *msgraph.Implic } return &msgraph.ImplicitGrantSettings{ - EnableAccessTokenIssuance: utils.Bool(enableAccessTokenIssuance), - EnableIdTokenIssuance: utils.Bool(enableIdTokenIssuance), + EnableAccessTokenIssuance: pointer.To(enableAccessTokenIssuance), + EnableIdTokenIssuance: pointer.To(enableIdTokenIssuance), } } @@ -478,14 +478,14 @@ func expandApplicationOAuth2PermissionScope(in []interface{}) *[]msgraph.Permiss result = append(result, msgraph.PermissionScope{ - AdminConsentDescription: utils.String(oauth2Permissions["admin_consent_description"].(string)), - AdminConsentDisplayName: utils.String(oauth2Permissions["admin_consent_display_name"].(string)), - ID: utils.String(oauth2Permissions["id"].(string)), - IsEnabled: utils.Bool(oauth2Permissions["enabled"].(bool)), + AdminConsentDescription: pointer.To(oauth2Permissions["admin_consent_description"].(string)), + AdminConsentDisplayName: pointer.To(oauth2Permissions["admin_consent_display_name"].(string)), + ID: pointer.To(oauth2Permissions["id"].(string)), + IsEnabled: pointer.To(oauth2Permissions["enabled"].(bool)), Type: oauth2Permissions["type"].(string), - UserConsentDescription: utils.String(oauth2Permissions["user_consent_description"].(string)), - UserConsentDisplayName: utils.String(oauth2Permissions["user_consent_display_name"].(string)), - Value: utils.String(oauth2Permissions["value"].(string)), + UserConsentDescription: pointer.To(oauth2Permissions["user_consent_description"].(string)), + UserConsentDisplayName: pointer.To(oauth2Permissions["user_consent_display_name"].(string)), + Value: pointer.To(oauth2Permissions["value"].(string)), }, ) } @@ -526,8 +526,8 @@ func expandApplicationOptionalClaim(in []interface{}) *[]msgraph.OptionalClaim { } newClaim := msgraph.OptionalClaim{ - Name: utils.String(optionalClaim["name"].(string)), - Essential: utils.Bool(optionalClaim["essential"].(bool)), + Name: pointer.To(optionalClaim["name"].(string)), + Essential: pointer.To(optionalClaim["essential"].(bool)), AdditionalProperties: &additionalProps, } @@ -566,7 +566,7 @@ func expandApplicationRequiredResourceAccess(in []interface{}) *[]msgraph.Requir requiredResourceAccess := raw.(map[string]interface{}) result = append(result, msgraph.RequiredResourceAccess{ - ResourceAppId: utils.String(requiredResourceAccess["resource_app_id"].(string)), + ResourceAppId: pointer.To(requiredResourceAccess["resource_app_id"].(string)), ResourceAccess: expandApplicationResourceAccess( requiredResourceAccess["resource_access"].([]interface{}), ), @@ -586,7 +586,7 @@ func expandApplicationResourceAccess(in []interface{}) *[]msgraph.ResourceAccess resourceAccess := resourceAccessRaw.(map[string]interface{}) result = append(result, msgraph.ResourceAccess{ - ID: utils.String(resourceAccess["id"].(string)), + ID: pointer.To(resourceAccess["id"].(string)), Type: resourceAccess["type"].(string), }) } @@ -611,9 +611,9 @@ func expandApplicationSpa(input []interface{}) (result *msgraph.ApplicationSpa) func expandApplicationWeb(input []interface{}) (result *msgraph.ApplicationWeb) { result = &msgraph.ApplicationWeb{ - HomePageUrl: utils.NullableString(""), + HomePageUrl: tf.NullableString(""), ImplicitGrantSettings: expandApplicationImplicitGrantSettings(nil), - LogoutUrl: utils.NullableString(""), + LogoutUrl: tf.NullableString(""), RedirectUris: &[]string{}, } @@ -622,8 +622,8 @@ func expandApplicationWeb(input []interface{}) (result *msgraph.ApplicationWeb) } in := input[0].(map[string]interface{}) - result.HomePageUrl = utils.NullableString(in["homepage_url"].(string)) - result.LogoutUrl = utils.NullableString(in["logout_url"].(string)) + result.HomePageUrl = tf.NullableString(in["homepage_url"].(string)) + result.LogoutUrl = tf.NullableString(in["logout_url"].(string)) result.ImplicitGrantSettings = expandApplicationImplicitGrantSettings(in["implicit_grant"].([]interface{})) result.RedirectUris = tf.ExpandStringSlicePtr(in["redirect_uris"].(*pluginsdk.Set).List()) diff --git a/internal/services/applications/migrations/application_resource.go b/internal/services/applications/migrations/application_resource.go index 1e00ed7faf..7e9bda8a68 100644 --- a/internal/services/applications/migrations/application_resource.go +++ b/internal/services/applications/migrations/application_resource.go @@ -709,7 +709,7 @@ func ResourceApplicationInstanceResourceV1() *pluginsdk.Resource { MaxItems: 1, Elem: &pluginsdk.Resource{ Schema: map[string]*pluginsdk.Schema{ - "access_token": &pluginsdk.Schema{ + "access_token": { Type: pluginsdk.TypeList, Optional: true, Elem: &pluginsdk.Resource{ @@ -740,7 +740,7 @@ func ResourceApplicationInstanceResourceV1() *pluginsdk.Resource { }, }, }, - "id_token": &pluginsdk.Schema{ + "id_token": { Type: pluginsdk.TypeList, Optional: true, Elem: &pluginsdk.Resource{ @@ -771,7 +771,7 @@ func ResourceApplicationInstanceResourceV1() *pluginsdk.Resource { }, }, }, - "saml2_token": &pluginsdk.Schema{ + "saml2_token": { Type: pluginsdk.TypeList, Optional: true, Elem: &pluginsdk.Resource{ diff --git a/internal/services/applications/parse/application.go b/internal/services/applications/parse/application.go index 435ffa2cd3..95ba467043 100644 --- a/internal/services/applications/parse/application.go +++ b/internal/services/applications/parse/application.go @@ -2,6 +2,7 @@ package parse import ( "fmt" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" "github.com/hashicorp/terraform-provider-azuread/internal/tf/validation" ) diff --git a/internal/services/approleassignments/app_role_assignment_resource.go b/internal/services/approleassignments/app_role_assignment_resource.go index b60b8f2fa2..cc8015e18b 100644 --- a/internal/services/approleassignments/app_role_assignment_resource.go +++ b/internal/services/approleassignments/app_role_assignment_resource.go @@ -11,13 +11,13 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/services/approleassignments/parse" "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -98,9 +98,9 @@ func appRoleAssignmentResourceCreate(ctx context.Context, d *pluginsdk.ResourceD return tf.ErrorDiagF(err, "Could not retrieve service principal for resource (Object ID: %q)", resourceId) } properties := msgraph.AppRoleAssignment{ - AppRoleId: utils.String(appRoleId), - PrincipalId: utils.String(principalId), - ResourceId: utils.String(resourceId), + AppRoleId: pointer.To(appRoleId), + PrincipalId: pointer.To(principalId), + ResourceId: pointer.To(resourceId), } appRoleAssignment, _, err := client.Assign(ctx, properties) diff --git a/internal/services/approleassignments/app_role_assignment_resource_test.go b/internal/services/approleassignments/app_role_assignment_resource_test.go index 50ec3d0a8c..a199a3f523 100644 --- a/internal/services/approleassignments/app_role_assignment_resource_test.go +++ b/internal/services/approleassignments/app_role_assignment_resource_test.go @@ -9,13 +9,13 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/services/approleassignments/parse" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" ) type AppRoleAssignmentResource struct{} @@ -121,11 +121,11 @@ func (r AppRoleAssignmentResource) Exists(ctx context.Context, clients *clients. for _, assignment := range *appRoleAssignments { if assignment.Id != nil && *assignment.Id == id.AssignmentId { - return utils.Bool(true), nil + return pointer.To(true), nil } } - return utils.Bool(false), nil + return pointer.To(false), nil } func (AppRoleAssignmentResource) servicePrincipalForMsGraph(data acceptance.TestData) string { diff --git a/internal/services/conditionalaccess/conditional_access_policy_resource.go b/internal/services/conditionalaccess/conditional_access_policy_resource.go index a4d3d38479..8ca44d0fb6 100644 --- a/internal/services/conditionalaccess/conditional_access_policy_resource.go +++ b/internal/services/conditionalaccess/conditional_access_policy_resource.go @@ -11,6 +11,7 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" @@ -18,7 +19,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -539,8 +539,8 @@ func conditionalAccessPolicyResourceCreate(ctx context.Context, d *pluginsdk.Res client := meta.(*clients.Client).ConditionalAccess.PoliciesClient properties := msgraph.ConditionalAccessPolicy{ - DisplayName: utils.String(d.Get("display_name").(string)), - State: utils.String(d.Get("state").(string)), + DisplayName: pointer.To(d.Get("display_name").(string)), + State: pointer.To(d.Get("state").(string)), Conditions: expandConditionalAccessConditionSet(d.Get("conditions").([]interface{})), } @@ -570,9 +570,9 @@ func conditionalAccessPolicyResourceUpdate(ctx context.Context, d *pluginsdk.Res client := meta.(*clients.Client).ConditionalAccess.PoliciesClient properties := msgraph.ConditionalAccessPolicy{ - ID: utils.String(d.Id()), - DisplayName: utils.String(d.Get("display_name").(string)), - State: utils.String(d.Get("state").(string)), + ID: pointer.To(d.Id()), + DisplayName: pointer.To(d.Get("display_name").(string)), + State: pointer.To(d.Get("state").(string)), Conditions: expandConditionalAccessConditionSet(d.Get("conditions").([]interface{})), } @@ -672,11 +672,11 @@ func conditionalAccessPolicyResourceDelete(ctx context.Context, d *pluginsdk.Res client.BaseClient.DisableRetries = true if _, status, err := client.Get(ctx, policyId, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of conditional access policy with ID %q", policyId) } diff --git a/internal/services/conditionalaccess/conditional_access_policy_resource_test.go b/internal/services/conditionalaccess/conditional_access_policy_resource_test.go index 19bda5f9dd..afaa8bb4aa 100644 --- a/internal/services/conditionalaccess/conditional_access_policy_resource_test.go +++ b/internal/services/conditionalaccess/conditional_access_policy_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type ConditionalAccessPolicyResource struct{} @@ -309,7 +309,7 @@ func (r ConditionalAccessPolicyResource) Exists(ctx context.Context, clients *cl } id = app.ID - return utils.Bool(id != nil && *id == state.ID), nil + return pointer.To(id != nil && *id == state.ID), nil } func (ConditionalAccessPolicyResource) basic(data acceptance.TestData) string { diff --git a/internal/services/conditionalaccess/conditionalaccess.go b/internal/services/conditionalaccess/conditionalaccess.go index 0c08557abe..5ae3b43bc4 100644 --- a/internal/services/conditionalaccess/conditionalaccess.go +++ b/internal/services/conditionalaccess/conditionalaccess.go @@ -4,8 +4,8 @@ package conditionalaccess import ( + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/terraform-provider-azuread/internal/tf" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -414,31 +414,31 @@ func expandConditionalAccessSessionControls(in []interface{}) *msgraph.Condition config := in[0].(map[string]interface{}) result.ApplicationEnforcedRestrictions = &msgraph.ApplicationEnforcedRestrictionsSessionControl{ - IsEnabled: utils.Bool(config["application_enforced_restrictions_enabled"].(bool)), + IsEnabled: pointer.To(config["application_enforced_restrictions_enabled"].(bool)), } if cloudAppSecurity := config["cloud_app_security_policy"].(string); cloudAppSecurity != "" { result.CloudAppSecurity = &msgraph.CloudAppSecurityControl{ - IsEnabled: utils.Bool(true), - CloudAppSecurityType: utils.String(cloudAppSecurity), + IsEnabled: pointer.To(true), + CloudAppSecurityType: pointer.To(cloudAppSecurity), } } DisableResilienceDefaults := config["disable_resilience_defaults"] - result.DisableResilienceDefaults = utils.Bool(DisableResilienceDefaults.(bool)) + result.DisableResilienceDefaults = pointer.To(DisableResilienceDefaults.(bool)) if persistentBrowserMode := config["persistent_browser_mode"].(string); persistentBrowserMode != "" { result.PersistentBrowser = &msgraph.PersistentBrowserSessionControl{ - IsEnabled: utils.Bool(true), - Mode: utils.String(persistentBrowserMode), + IsEnabled: pointer.To(true), + Mode: pointer.To(persistentBrowserMode), } } if signInFrequency := config["sign_in_frequency"].(int); signInFrequency > 0 { result.SignInFrequency = &msgraph.SignInFrequencySessionControl{ - IsEnabled: utils.Bool(true), - Type: utils.String(config["sign_in_frequency_period"].(string)), - Value: utils.Int32(int32(signInFrequency)), + IsEnabled: pointer.To(true), + Type: pointer.To(config["sign_in_frequency_period"].(string)), + Value: pointer.To(int32(signInFrequency)), } } @@ -454,8 +454,8 @@ func expandConditionalAccessFilter(in []interface{}) *msgraph.ConditionalAccessF config := in[0].(map[string]interface{}) - result.Mode = utils.String(config["mode"].(string)) - result.Rule = utils.String(config["rule"].(string)) + result.Mode = pointer.To(config["mode"].(string)) + result.Rule = pointer.To(config["rule"].(string)) return &result } @@ -472,7 +472,7 @@ func expandCountryNamedLocation(in []interface{}) *msgraph.CountryNamedLocation includeUnknown := config["include_unknown_countries_and_regions"] result.CountriesAndRegions = tf.ExpandStringSlicePtr(countriesAndRegions) - result.IncludeUnknownCountriesAndRegions = utils.Bool(includeUnknown.(bool)) + result.IncludeUnknownCountriesAndRegions = pointer.To(includeUnknown.(bool)) return &result } @@ -489,7 +489,7 @@ func expandIPNamedLocation(in []interface{}) *msgraph.IPNamedLocation { trusted := config["trusted"] result.IPRanges = expandIPNamedLocationIPRange(ipRanges) - result.IsTrusted = utils.Bool(trusted.(bool)) + result.IsTrusted = pointer.To(trusted.(bool)) return &result } @@ -502,7 +502,7 @@ func expandIPNamedLocationIPRange(in []interface{}) *[]msgraph.IPNamedLocationIP result := make([]msgraph.IPNamedLocationIPRange, 0) for _, cidr := range in { result = append(result, msgraph.IPNamedLocationIPRange{ - CIDRAddress: utils.String(cidr.(string)), + CIDRAddress: pointer.To(cidr.(string)), }) } diff --git a/internal/services/conditionalaccess/named_location_resource.go b/internal/services/conditionalaccess/named_location_resource.go index 04ad311e18..1de19bf9e0 100644 --- a/internal/services/conditionalaccess/named_location_resource.go +++ b/internal/services/conditionalaccess/named_location_resource.go @@ -12,6 +12,7 @@ import ( "reflect" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" @@ -19,7 +20,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -109,7 +109,7 @@ func namedLocationResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, displayName := d.Get("display_name").(string) base := msgraph.BaseNamedLocation{ - DisplayName: utils.String(displayName), + DisplayName: pointer.To(displayName), } if v, ok := d.GetOk("ip"); ok { @@ -149,7 +149,7 @@ func namedLocationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, client := meta.(*clients.Client).ConditionalAccess.NamedLocationsClient base := msgraph.BaseNamedLocation{ - ID: utils.String(d.Id()), + ID: pointer.To(d.Id()), } if d.HasChange("display_name") { @@ -291,7 +291,7 @@ func namedLocationResourceDelete(ctx context.Context, d *pluginsdk.ResourceData, BaseNamedLocation: &msgraph.BaseNamedLocation{ ID: &namedLocationId, }, - IsTrusted: utils.Bool(false), + IsTrusted: pointer.To(false), } if _, err := client.UpdateIP(ctx, properties); err != nil { return tf.ErrorDiagF(err, "Updating named location with ID %q", namedLocationId) @@ -320,11 +320,11 @@ func namedLocationResourceDelete(ctx context.Context, d *pluginsdk.ResourceData, client.BaseClient.DisableRetries = true if _, status, err := client.Get(ctx, namedLocationId, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "waiting for deletion of named location with ID %q", namedLocationId) } diff --git a/internal/services/conditionalaccess/named_location_resource_test.go b/internal/services/conditionalaccess/named_location_resource_test.go index 844f11ab44..e728245189 100644 --- a/internal/services/conditionalaccess/named_location_resource_test.go +++ b/internal/services/conditionalaccess/named_location_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -149,10 +149,10 @@ func (r NamedLocationResource) Exists(ctx context.Context, clients *clients.Clie ipnl, ok1 := (*namedLocation).(msgraph.IPNamedLocation) cnl, ok2 := (*namedLocation).(msgraph.CountryNamedLocation) if ok1 { - return utils.Bool(ipnl.ID != nil && *ipnl.ID == state.ID), nil + return pointer.To(ipnl.ID != nil && *ipnl.ID == state.ID), nil } if ok2 { - return utils.Bool(cnl.ID != nil && *cnl.ID == state.ID), nil + return pointer.To(cnl.ID != nil && *cnl.ID == state.ID), nil } return nil, fmt.Errorf("Unable to match object ID %q to a known type", state.ID) } diff --git a/internal/services/directoryroles/custom_directory_role_resource.go b/internal/services/directoryroles/custom_directory_role_resource.go index 225ac03c7c..f850a257dd 100644 --- a/internal/services/directoryroles/custom_directory_role_resource.go +++ b/internal/services/directoryroles/custom_directory_role_resource.go @@ -11,13 +11,13 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -115,12 +115,12 @@ func customDirectoryRoleResourceCreate(ctx context.Context, d *pluginsdk.Resourc displayName := d.Get("display_name").(string) properties := msgraph.UnifiedRoleDefinition{ - Description: utils.NullableString(d.Get("description").(string)), - DisplayName: utils.String(displayName), - IsEnabled: utils.Bool(d.Get("enabled").(bool)), + Description: tf.NullableString(d.Get("description").(string)), + DisplayName: pointer.To(displayName), + IsEnabled: pointer.To(d.Get("enabled").(bool)), RolePermissions: expandCustomRolePermissions(d.Get("permissions").(*pluginsdk.Set).List()), - TemplateId: utils.String(d.Get("template_id").(string)), - Version: utils.String(d.Get("version").(string)), + TemplateId: pointer.To(d.Get("template_id").(string)), + Version: pointer.To(d.Get("version").(string)), } role, _, err := client.Create(ctx, properties) @@ -147,12 +147,12 @@ func customDirectoryRoleResourceUpdate(ctx context.Context, d *pluginsdk.Resourc DirectoryObject: msgraph.DirectoryObject{ Id: &roleId, }, - Description: utils.NullableString(d.Get("description").(string)), - DisplayName: utils.String(displayName), - IsEnabled: utils.Bool(d.Get("enabled").(bool)), + Description: tf.NullableString(d.Get("description").(string)), + DisplayName: pointer.To(displayName), + IsEnabled: pointer.To(d.Get("enabled").(bool)), RolePermissions: expandCustomRolePermissions(d.Get("permissions").(*pluginsdk.Set).List()), - TemplateId: utils.String(d.Get("template_id").(string)), - Version: utils.String(d.Get("version").(string)), + TemplateId: pointer.To(d.Get("template_id").(string)), + Version: pointer.To(d.Get("version").(string)), } _, err := client.Update(ctx, properties) diff --git a/internal/services/directoryroles/custom_directory_role_resource_test.go b/internal/services/directoryroles/custom_directory_role_resource_test.go index 92f13df411..b2afac4eb5 100644 --- a/internal/services/directoryroles/custom_directory_role_resource_test.go +++ b/internal/services/directoryroles/custom_directory_role_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type CustomDirectoryRoleResource struct{} @@ -141,7 +141,7 @@ func (r CustomDirectoryRoleResource) Exists(ctx context.Context, clients *client return nil, fmt.Errorf("failed to retrieve Custom Directory Role with object ID %q: %+v", state.ID, err) } - return utils.Bool(role.ID() != nil && *role.ID() == state.ID), nil + return pointer.To(role.ID() != nil && *role.ID() == state.ID), nil } func (r CustomDirectoryRoleResource) basic(data acceptance.TestData) string { diff --git a/internal/services/directoryroles/directory_role_assignment_resource.go b/internal/services/directoryroles/directory_role_assignment_resource.go index e6404b180e..ff6b089dde 100644 --- a/internal/services/directoryroles/directory_role_assignment_resource.go +++ b/internal/services/directoryroles/directory_role_assignment_resource.go @@ -11,12 +11,12 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -132,7 +132,7 @@ func directoryRoleAssignmentResourceCreate(ctx context.Context, d *pluginsdk.Res case directoryScopeId != "": properties.DirectoryScopeId = &directoryScopeId default: - properties.DirectoryScopeId = utils.String("/") + properties.DirectoryScopeId = pointer.To("/") } assignment, status, err := client.Create(ctx, properties) diff --git a/internal/services/directoryroles/directory_role_assignment_resource_test.go b/internal/services/directoryroles/directory_role_assignment_resource_test.go index 8fa400deb3..c030dcc97a 100644 --- a/internal/services/directoryroles/directory_role_assignment_resource_test.go +++ b/internal/services/directoryroles/directory_role_assignment_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type DirectoryRoleAssignmentResource struct{} @@ -151,12 +151,12 @@ func (r DirectoryRoleAssignmentResource) Exists(ctx context.Context, clients *cl if _, status, err := client.Get(ctx, state.ID, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, fmt.Errorf("failed to retrieve directory role assignment %q: %+v", state.ID, err) } - return utils.Bool(true), nil + return pointer.To(true), nil } func (DirectoryRoleAssignmentResource) templateThreeUsers(data acceptance.TestData) string { diff --git a/internal/services/directoryroles/directory_role_eligibility_schedule_request_resource.go b/internal/services/directoryroles/directory_role_eligibility_schedule_request_resource.go index d955352f46..220e0c7361 100644 --- a/internal/services/directoryroles/directory_role_eligibility_schedule_request_resource.go +++ b/internal/services/directoryroles/directory_role_eligibility_schedule_request_resource.go @@ -8,6 +8,7 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" @@ -15,7 +16,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -85,7 +85,7 @@ func directoryRoleEligibilityScheduleRequestResourceCreate(ctx context.Context, now := time.Now() properties := msgraph.UnifiedRoleEligibilityScheduleRequest{ - Action: utils.String(msgraph.UnifiedRoleScheduleRequestActionAdminAssign), + Action: pointer.To(msgraph.UnifiedRoleScheduleRequestActionAdminAssign), RoleDefinitionId: &roleDefinitionId, PrincipalId: &principalId, Justification: &justification, @@ -93,7 +93,7 @@ func directoryRoleEligibilityScheduleRequestResourceCreate(ctx context.Context, ScheduleInfo: &msgraph.RequestSchedule{ StartDateTime: &now, Expiration: &msgraph.ExpirationPattern{ - Type: utils.String(msgraph.ExpirationPatternTypeNoExpiration), + Type: pointer.To(msgraph.ExpirationPatternTypeNoExpiration), }, }, } @@ -115,11 +115,11 @@ func directoryRoleEligibilityScheduleRequestResourceCreate(ctx context.Context, resr, status, err := client.Get(ctx, *roleEligibilityScheduleRequest.ID, odata.Query{}) if err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(resr != nil), nil + return pointer.To(resr != nil), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for role eligibility schedule request for %q to be created for directory role %q", principalId, roleDefinitionId) } @@ -158,7 +158,7 @@ func directoryRoleEligibilityScheduleRequestResourceDelete(ctx context.Context, return tf.ErrorDiagF(err, "Retrieving roleEligibilityScheduleRequest %q", id) } - roleEligibilityScheduleRequest.Action = utils.String(msgraph.UnifiedRoleScheduleRequestActionAdminRemove) + roleEligibilityScheduleRequest.Action = pointer.To(msgraph.UnifiedRoleScheduleRequestActionAdminRemove) if _, _, err := client.Create(ctx, *roleEligibilityScheduleRequest); err != nil { return tf.ErrorDiagF(err, "Deleting role eligibility schedule request %q: %+v", d.Id(), err) diff --git a/internal/services/directoryroles/directory_role_eligibility_schedule_request_resource_test.go b/internal/services/directoryroles/directory_role_eligibility_schedule_request_resource_test.go index 31b986fc93..99a014fae8 100644 --- a/internal/services/directoryroles/directory_role_eligibility_schedule_request_resource_test.go +++ b/internal/services/directoryroles/directory_role_eligibility_schedule_request_resource_test.go @@ -6,12 +6,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type RoleEligibilityScheduleRequestResource struct{} @@ -42,7 +42,7 @@ func (r RoleEligibilityScheduleRequestResource) Exists(ctx context.Context, clie return nil, fmt.Errorf("failed to retrieve Role Eligibility Schedule Request with object ID %q: %+v", state.ID, err) } - return utils.Bool(resr.ID != nil && *resr.ID == state.ID), nil + return pointer.To(resr.ID != nil && *resr.ID == state.ID), nil } func (r RoleEligibilityScheduleRequestResource) basic(data acceptance.TestData) string { diff --git a/internal/services/directoryroles/directory_role_member_resource.go b/internal/services/directoryroles/directory_role_member_resource.go index 82d7395767..d1d145c024 100644 --- a/internal/services/directoryroles/directory_role_member_resource.go +++ b/internal/services/directoryroles/directory_role_member_resource.go @@ -11,6 +11,7 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/helpers" @@ -18,7 +19,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -95,7 +95,7 @@ func directoryRoleMemberResourceCreate(ctx context.Context, d *pluginsdk.Resourc if memberObject == nil { return tf.ErrorDiagF(errors.New("returned memberObject was nil"), "Could not retrieve member principal object %q", id.MemberId) } - memberObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + memberObject.ODataId = (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, id.MemberId))) role.Members = &msgraph.Members{*memberObject} @@ -180,11 +180,11 @@ func directoryRoleMemberResourceDelete(ctx context.Context, d *pluginsdk.Resourc client.BaseClient.DisableRetries = true if _, status, err := client.GetMember(ctx, id.DirectoryRoleId, id.MemberId); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for removal of member %q from directory role with object ID %q", id.MemberId, id.DirectoryRoleId) } diff --git a/internal/services/directoryroles/directory_role_member_resource_test.go b/internal/services/directoryroles/directory_role_member_resource_test.go index ee7e88e699..44f5177b00 100644 --- a/internal/services/directoryroles/directory_role_member_resource_test.go +++ b/internal/services/directoryroles/directory_role_member_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/services/directoryroles/parse" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" ) type DirectoryRoleMemberResource struct{} @@ -120,12 +120,12 @@ func (r DirectoryRoleMemberResource) Exists(ctx context.Context, clients *client if _, status, err := client.GetMember(ctx, id.DirectoryRoleId, id.MemberId); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, fmt.Errorf("failed to retrieve directory role member %q (role ID: %q): %+v", id.MemberId, id.DirectoryRoleId, err) } - return utils.Bool(true), nil + return pointer.To(true), nil } func (DirectoryRoleMemberResource) templateThreeUsers(data acceptance.TestData) string { diff --git a/internal/services/directoryroles/directory_role_resource_test.go b/internal/services/directoryroles/directory_role_resource_test.go index a23bc2e9cb..301711ca96 100644 --- a/internal/services/directoryroles/directory_role_resource_test.go +++ b/internal/services/directoryroles/directory_role_resource_test.go @@ -9,11 +9,11 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type DirectoryRoleResource struct{} @@ -64,7 +64,7 @@ func (r DirectoryRoleResource) Exists(ctx context.Context, clients *clients.Clie } return nil, fmt.Errorf("failed to retrieve Directory Role with object ID %q: %+v", state.ID, err) } - return utils.Bool(role.ID() != nil && *role.ID() == state.ID), nil + return pointer.To(role.ID() != nil && *role.ID() == state.ID), nil } func (DirectoryRoleResource) byDisplayName(_ acceptance.TestData) string { diff --git a/internal/services/groups/group_data_source.go b/internal/services/groups/group_data_source.go index e885d39c73..e7eb5014f0 100644 --- a/internal/services/groups/group_data_source.go +++ b/internal/services/groups/group_data_source.go @@ -10,12 +10,12 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -261,10 +261,10 @@ func groupDataSourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta in var mailEnabled, securityEnabled *bool if v, exists := d.GetOkExists("mail_enabled"); exists { //nolint:staticcheck // needed to detect unset booleans - mailEnabled = utils.Bool(v.(bool)) + mailEnabled = pointer.To(v.(bool)) } if v, exists := d.GetOkExists("security_enabled"); exists { //nolint:staticcheck // needed to detect unset booleans - securityEnabled = utils.Bool(v.(bool)) + securityEnabled = pointer.To(v.(bool)) } var mailNickname string diff --git a/internal/services/groups/group_member_resource.go b/internal/services/groups/group_member_resource.go index 5c78d4d514..3296182401 100644 --- a/internal/services/groups/group_member_resource.go +++ b/internal/services/groups/group_member_resource.go @@ -12,6 +12,7 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/helpers" @@ -19,7 +20,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -100,7 +100,7 @@ func groupMemberResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, m if memberObject == nil { return tf.ErrorDiagF(errors.New("returned memberObject was nil"), "Could not retrieve member principal object %q", memberId) } - memberObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + memberObject.ODataId = (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, memberId))) group.Members = &msgraph.Members{*memberObject} @@ -174,11 +174,11 @@ func groupMemberResourceDelete(ctx context.Context, d *pluginsdk.ResourceData, m client.BaseClient.DisableRetries = true if _, status, err := client.GetMember(ctx, id.GroupId, id.MemberId); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for removal of member %q from group with object ID %q", id.MemberId, id.GroupId) } diff --git a/internal/services/groups/group_member_resource_test.go b/internal/services/groups/group_member_resource_test.go index 55b784c9d1..cda6849ce4 100644 --- a/internal/services/groups/group_member_resource_test.go +++ b/internal/services/groups/group_member_resource_test.go @@ -9,12 +9,12 @@ import ( "strings" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/services/groups/parse" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" ) type GroupMemberResource struct{} @@ -155,7 +155,7 @@ func (r GroupMemberResource) Exists(ctx context.Context, clients *clients.Client if members != nil { for _, objectId := range *members { if strings.EqualFold(objectId, id.MemberId) { - return utils.Bool(true), nil + return pointer.To(true), nil } } } diff --git a/internal/services/groups/group_resource.go b/internal/services/groups/group_resource.go index 23ab523d87..101e5cc0f5 100644 --- a/internal/services/groups/group_resource.go +++ b/internal/services/groups/group_resource.go @@ -13,6 +13,7 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" @@ -489,10 +490,10 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in var writebackConfiguration *msgraph.GroupWritebackConfiguration if v := d.Get("writeback_enabled").(bool); v { writebackConfiguration = &msgraph.GroupWritebackConfiguration{ - IsEnabled: utils.Bool(d.Get("writeback_enabled").(bool)), + IsEnabled: pointer.To(d.Get("writeback_enabled").(bool)), } if onPremisesGroupType := d.Get("onpremises_group_type").(string); onPremisesGroupType != "" { - writebackConfiguration.OnPremisesGroupType = utils.String(onPremisesGroupType) + writebackConfiguration.OnPremisesGroupType = pointer.To(onPremisesGroupType) } } @@ -503,35 +504,35 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in DirectoryObject: msgraph.DirectoryObject{ ODataType: &odataType, }, - Description: utils.NullableString(description), - DisplayName: utils.String(displayName), + Description: tf.NullableString(description), + DisplayName: pointer.To(displayName), GroupTypes: &groupTypes, - IsAssignableToRole: utils.Bool(d.Get("assignable_to_role").(bool)), - MailEnabled: utils.Bool(mailEnabled), - MailNickname: utils.String(mailNickname), - MembershipRule: utils.NullableString(""), + IsAssignableToRole: pointer.To(d.Get("assignable_to_role").(bool)), + MailEnabled: pointer.To(mailEnabled), + MailNickname: pointer.To(mailNickname), + MembershipRule: tf.NullableString(""), ResourceBehaviorOptions: &behaviorOptions, ResourceProvisioningOptions: &provisioningOptions, - SecurityEnabled: utils.Bool(securityEnabled), + SecurityEnabled: pointer.To(securityEnabled), WritebackConfiguration: writebackConfiguration, } if v, ok := d.GetOk("dynamic_membership"); ok && len(v.([]interface{})) > 0 { if d.Get("dynamic_membership.0.enabled").(bool) { - properties.MembershipRuleProcessingState = utils.String("On") + properties.MembershipRuleProcessingState = pointer.To("On") } else { - properties.MembershipRuleProcessingState = utils.String("Paused") + properties.MembershipRuleProcessingState = pointer.To("Paused") } - properties.MembershipRule = utils.NullableString(d.Get("dynamic_membership.0.rule").(string)) + properties.MembershipRule = tf.NullableString(d.Get("dynamic_membership.0.rule").(string)) } if theme := d.Get("theme").(string); theme != "" { - properties.Theme = utils.NullableString(theme) + properties.Theme = tf.NullableString(theme) } if visibility := d.Get("visibility").(string); visibility != "" { - properties.Visibility = utils.String(visibility) + properties.Visibility = pointer.To(visibility) } // Sort the owners into two slices, the first containing up to 20 and the rest overflowing to the second slice @@ -549,7 +550,7 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in if ownerObject.ID() == nil { return nil, errors.New("ownerObject ID was nil") } - ownerObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + ownerObject.ODataId = (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, id))) if ownerObject.ODataType == nil { @@ -714,7 +715,7 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in DirectoryObject: msgraph.DirectoryObject{ Id: group.ID(), }, - DisplayName: utils.String(displayNameToSet), + DisplayName: pointer.To(displayNameToSet), }) if err != nil { if status == http.StatusNotFound { @@ -731,11 +732,11 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in group, status, err := client.Get(ctx, *group.ID(), odata.Query{}) if err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(group.DisplayName != nil && *group.DisplayName == displayName), nil + return pointer.To(group.DisplayName != nil && *group.DisplayName == displayName), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for update of `display_name` for group with object ID %q", *group.ID()) } @@ -752,13 +753,13 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in if err != nil { return nil, err } - return utils.Bool(group.Description != nil && *group.Description != ""), nil + return pointer.To(group.Description != nil && *group.Description != ""), nil }); updated { status, err = client.Update(ctx, msgraph.Group{ DirectoryObject: msgraph.DirectoryObject{ Id: group.ID(), }, - Description: utils.NullableString(""), + Description: tf.NullableString(""), }) if err != nil { if status == http.StatusNotFound { @@ -775,7 +776,7 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in if err != nil { return nil, err } - return utils.Bool(group.Description == nil || *group.Description == ""), nil + return pointer.To(group.Description == nil || *group.Description == ""), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting to remove `description` for group with object ID %q", *group.ID()) } @@ -793,7 +794,7 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in DirectoryObject: msgraph.DirectoryObject{ Id: group.ID(), }, - AllowExternalSenders: utils.Bool(allowExternalSenders.(bool)), + AllowExternalSenders: pointer.To(allowExternalSenders.(bool)), }); err != nil { return tf.ErrorDiagF(err, "Failed to set `external_senders_allowed` for group with object ID %q", *group.ID()) } @@ -806,7 +807,7 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in if err != nil { return nil, err } - return utils.Bool(groupExtra != nil && groupExtra.AllowExternalSenders != nil && *groupExtra.AllowExternalSenders == allowExternalSenders), nil + return pointer.To(groupExtra != nil && groupExtra.AllowExternalSenders != nil && *groupExtra.AllowExternalSenders == allowExternalSenders), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for update of `external_senders_allowed` for group with object ID %q", *group.ID()) } @@ -818,7 +819,7 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in DirectoryObject: msgraph.DirectoryObject{ Id: group.ID(), }, - AutoSubscribeNewMembers: utils.Bool(autoSubscribeNewMembers.(bool)), + AutoSubscribeNewMembers: pointer.To(autoSubscribeNewMembers.(bool)), }); err != nil { return tf.ErrorDiagF(err, "Failed to set `auto_subscribe_new_members` for group with object ID %q", *group.ID()) } @@ -831,7 +832,7 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in if err != nil { return nil, err } - return utils.Bool(groupExtra != nil && groupExtra.AutoSubscribeNewMembers != nil && *groupExtra.AutoSubscribeNewMembers == autoSubscribeNewMembers), nil + return pointer.To(groupExtra != nil && groupExtra.AutoSubscribeNewMembers != nil && *groupExtra.AutoSubscribeNewMembers == autoSubscribeNewMembers), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for update of `auto_subscribe_new_members` for group with object ID %q", *group.ID()) } @@ -843,7 +844,7 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in DirectoryObject: msgraph.DirectoryObject{ Id: group.ID(), }, - HideFromAddressLists: utils.Bool(hideFromAddressList.(bool)), + HideFromAddressLists: pointer.To(hideFromAddressList.(bool)), }); err != nil { return tf.ErrorDiagF(err, "Failed to set `hide_from_address_lists` for group with object ID %q", *group.ID()) } @@ -856,7 +857,7 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in if err != nil { return nil, err } - return utils.Bool(groupExtra != nil && groupExtra.HideFromAddressLists != nil && *groupExtra.HideFromAddressLists == hideFromAddressList), nil + return pointer.To(groupExtra != nil && groupExtra.HideFromAddressLists != nil && *groupExtra.HideFromAddressLists == hideFromAddressList), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for update of `hide_from_address_lists` for group with object ID %q", *group.ID()) } @@ -868,7 +869,7 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in DirectoryObject: msgraph.DirectoryObject{ Id: group.ID(), }, - HideFromOutlookClients: utils.Bool(hideFromOutlookClients.(bool)), + HideFromOutlookClients: pointer.To(hideFromOutlookClients.(bool)), }); err != nil { return tf.ErrorDiagF(err, "Failed to set `hide_from_outlook_clients` for group with object ID %q", *group.ID()) } @@ -881,7 +882,7 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in if err != nil { return nil, err } - return utils.Bool(groupExtra != nil && groupExtra.HideFromOutlookClients != nil && *groupExtra.HideFromOutlookClients == hideFromOutlookClients), nil + return pointer.To(groupExtra != nil && groupExtra.HideFromOutlookClients != nil && *groupExtra.HideFromOutlookClients == hideFromOutlookClients), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for update of `hide_from_outlook_clients` for group with object ID %q", *group.ID()) } @@ -907,7 +908,7 @@ func groupResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta in if memberObject == nil { return tf.ErrorDiagF(errors.New("memberObject was nil"), "Could not retrieve member principal object %q", memberId) } - memberObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + memberObject.ODataId = (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, memberId))) members = append(members, *memberObject) @@ -965,40 +966,40 @@ func groupResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta in group := msgraph.Group{ DirectoryObject: msgraph.DirectoryObject{ - Id: utils.String(groupId), + Id: pointer.To(groupId), }, - Description: utils.NullableString(d.Get("description").(string)), - DisplayName: utils.String(displayName), - MailEnabled: utils.Bool(d.Get("mail_enabled").(bool)), - MembershipRule: utils.NullableString(""), - SecurityEnabled: utils.Bool(d.Get("security_enabled").(bool)), + Description: tf.NullableString(d.Get("description").(string)), + DisplayName: pointer.To(displayName), + MailEnabled: pointer.To(d.Get("mail_enabled").(bool)), + MembershipRule: tf.NullableString(""), + SecurityEnabled: pointer.To(d.Get("security_enabled").(bool)), } if d.HasChange("writeback_enabled") || d.HasChange("onpremises_group_type") { group.WritebackConfiguration = &msgraph.GroupWritebackConfiguration{ - IsEnabled: utils.Bool(d.Get("writeback_enabled").(bool)), + IsEnabled: pointer.To(d.Get("writeback_enabled").(bool)), } if onPremisesGroupType := d.Get("onpremises_group_type").(string); onPremisesGroupType != "" { - group.WritebackConfiguration.OnPremisesGroupType = utils.String(onPremisesGroupType) + group.WritebackConfiguration.OnPremisesGroupType = pointer.To(onPremisesGroupType) } } if v, ok := d.GetOk("dynamic_membership"); ok && len(v.([]interface{})) > 0 { if d.Get("dynamic_membership.0.enabled").(bool) { - group.MembershipRuleProcessingState = utils.String("On") + group.MembershipRuleProcessingState = pointer.To("On") } else { - group.MembershipRuleProcessingState = utils.String("Paused") + group.MembershipRuleProcessingState = pointer.To("Paused") } - group.MembershipRule = utils.NullableString(d.Get("dynamic_membership.0.rule").(string)) + group.MembershipRule = tf.NullableString(d.Get("dynamic_membership.0.rule").(string)) } if theme := d.Get("theme").(string); theme != "" { - group.Theme = utils.NullableString(theme) + group.Theme = tf.NullableString(theme) } if d.HasChange("visibility") { - group.Visibility = utils.String(d.Get("visibility").(string)) + group.Visibility = pointer.To(d.Get("visibility").(string)) } if _, err := client.Update(ctx, group); err != nil { @@ -1027,7 +1028,7 @@ func groupResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta in DirectoryObject: msgraph.DirectoryObject{ Id: group.ID(), }, - AllowExternalSenders: utils.Bool(v.(bool)), + AllowExternalSenders: pointer.To(v.(bool)), }); err != nil { return tf.ErrorDiagF(err, "Failed to set `external_senders_allowed` for group with object ID %q", *group.ID()) } @@ -1040,7 +1041,7 @@ func groupResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta in if err != nil { return nil, err } - return utils.Bool(groupExtra != nil && groupExtra.AllowExternalSenders != nil && *groupExtra.AllowExternalSenders == v.(bool)), nil + return pointer.To(groupExtra != nil && groupExtra.AllowExternalSenders != nil && *groupExtra.AllowExternalSenders == v.(bool)), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for update of `external_senders_allowed` for group with object ID %q", *group.ID()) } @@ -1052,7 +1053,7 @@ func groupResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta in DirectoryObject: msgraph.DirectoryObject{ Id: group.ID(), }, - AutoSubscribeNewMembers: utils.Bool(v.(bool)), + AutoSubscribeNewMembers: pointer.To(v.(bool)), }); err != nil { return tf.ErrorDiagF(err, "Failed to set `auto_subscribe_new_members` for group with object ID %q", *group.ID()) } @@ -1065,7 +1066,7 @@ func groupResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta in if err != nil { return nil, err } - return utils.Bool(groupExtra != nil && groupExtra.AutoSubscribeNewMembers != nil && *groupExtra.AutoSubscribeNewMembers == v.(bool)), nil + return pointer.To(groupExtra != nil && groupExtra.AutoSubscribeNewMembers != nil && *groupExtra.AutoSubscribeNewMembers == v.(bool)), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for update of `auto_subscribe_new_members` for group with object ID %q", *group.ID()) } @@ -1077,7 +1078,7 @@ func groupResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta in DirectoryObject: msgraph.DirectoryObject{ Id: group.ID(), }, - HideFromAddressLists: utils.Bool(v.(bool)), + HideFromAddressLists: pointer.To(v.(bool)), }); err != nil { return tf.ErrorDiagF(err, "Failed to set `hide_from_address_lists` for group with object ID %q", *group.ID()) } @@ -1090,7 +1091,7 @@ func groupResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta in if err != nil { return nil, err } - return utils.Bool(groupExtra != nil && groupExtra.HideFromAddressLists != nil && *groupExtra.HideFromAddressLists == v.(bool)), nil + return pointer.To(groupExtra != nil && groupExtra.HideFromAddressLists != nil && *groupExtra.HideFromAddressLists == v.(bool)), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for update of `hide_from_address_lists` for group with object ID %q", *group.ID()) } @@ -1102,7 +1103,7 @@ func groupResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta in DirectoryObject: msgraph.DirectoryObject{ Id: group.ID(), }, - HideFromOutlookClients: utils.Bool(v.(bool)), + HideFromOutlookClients: pointer.To(v.(bool)), }); err != nil { return tf.ErrorDiagF(err, "Failed to set `hide_from_outlook_clients` for group with object ID %q", *group.ID()) } @@ -1115,7 +1116,7 @@ func groupResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta in if err != nil { return nil, err } - return utils.Bool(groupExtra != nil && groupExtra.HideFromOutlookClients != nil && *groupExtra.HideFromOutlookClients == v.(bool)), nil + return pointer.To(groupExtra != nil && groupExtra.HideFromOutlookClients != nil && *groupExtra.HideFromOutlookClients == v.(bool)), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for update of `hide_from_outlook_clients` for group with object ID %q", *group.ID()) } @@ -1149,7 +1150,7 @@ func groupResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta in if memberObject == nil { return tf.ErrorDiagF(errors.New("returned memberObject was nil"), "Could not retrieve member principal object %q", memberId) } - memberObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + memberObject.ODataId = (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, memberId))) newMembers = append(newMembers, *memberObject) @@ -1190,7 +1191,7 @@ func groupResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta in if ownerObject == nil { return tf.ErrorDiagF(errors.New("returned ownerObject was nil"), "Could not retrieve owner principal object %q", ownerId) } - ownerObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + ownerObject.ODataId = (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, ownerId))) newOwners = append(newOwners, *ownerObject) @@ -1385,11 +1386,11 @@ func groupResourceDelete(ctx context.Context, d *pluginsdk.ResourceData, meta in client.BaseClient.DisableRetries = true if _, status, err := client.Get(ctx, groupId, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of group with object ID %q", groupId) } @@ -1401,7 +1402,7 @@ func addGroupToAdministrativeUnit(ctx context.Context, auClient *msgraph.Adminis members := msgraph.Members{ group.DirectoryObject, } - members[0].ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + members[0].ODataId = (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", auClient.BaseClient.Endpoint, tenantId, *group.DirectoryObject.ID()))) _, err := auClient.AddMembers(ctx, administrativeUnitId, &members) return err diff --git a/internal/services/groups/group_resource_test.go b/internal/services/groups/group_resource_test.go index acd1770597..c2cebcf910 100644 --- a/internal/services/groups/group_resource_test.go +++ b/internal/services/groups/group_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type GroupResource struct{} @@ -564,7 +564,7 @@ func (r GroupResource) Exists(ctx context.Context, clients *clients.Client, stat } return nil, fmt.Errorf("failed to retrieve Group with object ID %q: %+v", state.ID, err) } - return utils.Bool(group.ID() != nil && *group.ID() == state.ID), nil + return pointer.To(group.ID() != nil && *group.ID() == state.ID), nil } func (GroupResource) templateDiverseDirectoryObjects(data acceptance.TestData) string { diff --git a/internal/services/groups/groups.go b/internal/services/groups/groups.go index 533f969885..403f70a4f0 100644 --- a/internal/services/groups/groups.go +++ b/internal/services/groups/groups.go @@ -8,7 +8,6 @@ import ( "fmt" "math/rand" "net/http" - "time" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/manicminer/hamilton/msgraph" @@ -17,7 +16,6 @@ import ( func groupDefaultMailNickname() string { charSet := "0123456789abcdef" result := make([]byte, 9) - rand.Seed(time.Now().UTC().UnixNano()) for i := 0; i < 9; i++ { result[i] = charSet[rand.Intn(len(charSet))] } diff --git a/internal/services/identitygovernance/access_package_assignment_policy_resource.go b/internal/services/identitygovernance/access_package_assignment_policy_resource.go index 0d5a704c23..1aedc0fc0c 100644 --- a/internal/services/identitygovernance/access_package_assignment_policy_resource.go +++ b/internal/services/identitygovernance/access_package_assignment_policy_resource.go @@ -10,6 +10,7 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" @@ -17,7 +18,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -443,11 +443,11 @@ func accessPackageAssignmentPolicyResourceDelete(ctx context.Context, d *plugins client.BaseClient.DisableRetries = true if _, status, err := client.Get(ctx, accessPackageAssignmentPolicyId, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of access package assignment policy with object ID %q", accessPackageAssignmentPolicyId) } @@ -469,13 +469,13 @@ func buildAssignmentPolicyResourceData(ctx context.Context, d *pluginsdk.Resourc } properties := msgraph.AccessPackageAssignmentPolicy{ - ID: utils.String(d.Id()), - DisplayName: utils.String(d.Get("display_name").(string)), - Description: utils.String(d.Get("description").(string)), - CanExtend: utils.Bool(d.Get("extension_enabled").(bool)), - DurationInDays: utils.Int32(int32(d.Get("duration_in_days").(int))), + ID: pointer.To(d.Id()), + DisplayName: pointer.To(d.Get("display_name").(string)), + Description: pointer.To(d.Get("description").(string)), + CanExtend: pointer.To(d.Get("extension_enabled").(bool)), + DurationInDays: pointer.To(int32(d.Get("duration_in_days").(int))), Questions: expandAccessPackageQuestions(d.Get("question").([]interface{})), - AccessPackageId: utils.String(d.Get("access_package_id").(string)), + AccessPackageId: pointer.To(d.Get("access_package_id").(string)), } expirationDateValue := d.Get("expiration_date").(string) diff --git a/internal/services/identitygovernance/access_package_assignment_policy_resource_test.go b/internal/services/identitygovernance/access_package_assignment_policy_resource_test.go index 22078f3352..5b547fce5f 100644 --- a/internal/services/identitygovernance/access_package_assignment_policy_resource_test.go +++ b/internal/services/identitygovernance/access_package_assignment_policy_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type AccessPackageAssignmentPolicyResource struct{} @@ -101,11 +101,11 @@ func (AccessPackageAssignmentPolicyResource) Exists(ctx context.Context, clients _, status, err := client.Get(ctx, state.ID, odata.Query{}) if err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, fmt.Errorf("failed to retrieve Access package assignment policy with ID %q: %+v", state.ID, err) } - return utils.Bool(true), nil + return pointer.To(true), nil } func (AccessPackageAssignmentPolicyResource) simple(data acceptance.TestData) string { diff --git a/internal/services/identitygovernance/access_package_catalog_resource.go b/internal/services/identitygovernance/access_package_catalog_resource.go index 1dc8546cef..cf6545d040 100644 --- a/internal/services/identitygovernance/access_package_catalog_resource.go +++ b/internal/services/identitygovernance/access_package_catalog_resource.go @@ -11,6 +11,7 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" @@ -18,7 +19,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -88,10 +88,10 @@ func accessPackageCatalogResourceCreate(ctx context.Context, d *pluginsdk.Resour } properties := msgraph.AccessPackageCatalog{ - DisplayName: utils.String(displayName), - Description: utils.String(d.Get("description").(string)), + DisplayName: pointer.To(displayName), + Description: pointer.To(d.Get("description").(string)), State: state, - IsExternallyVisible: utils.Bool(d.Get("externally_visible").(bool)), + IsExternallyVisible: pointer.To(d.Get("externally_visible").(bool)), } accessPackageCatalog, _, err := client.Create(ctx, properties) @@ -117,11 +117,11 @@ func accessPackageCatalogResourceUpdate(ctx context.Context, d *pluginsdk.Resour } properties := msgraph.AccessPackageCatalog{ - ID: utils.String(d.Id()), - DisplayName: utils.String(d.Get("display_name").(string)), - Description: utils.String(d.Get("description").(string)), + ID: pointer.To(d.Id()), + DisplayName: pointer.To(d.Get("display_name").(string)), + Description: pointer.To(d.Get("description").(string)), State: state, - IsExternallyVisible: utils.Bool(d.Get("externally_visible").(bool)), + IsExternallyVisible: pointer.To(d.Get("externally_visible").(bool)), } if _, err := client.Update(ctx, properties); err != nil { @@ -183,11 +183,11 @@ func accessPackageCatalogResourceDelete(ctx context.Context, d *pluginsdk.Resour client.BaseClient.DisableRetries = true if _, status, err := client.Get(ctx, accessPackageCatalogId, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of access package catalog with object ID %q", accessPackageCatalogId) } diff --git a/internal/services/identitygovernance/access_package_catalog_resource_test.go b/internal/services/identitygovernance/access_package_catalog_resource_test.go index 37772be94b..696d163258 100644 --- a/internal/services/identitygovernance/access_package_catalog_resource_test.go +++ b/internal/services/identitygovernance/access_package_catalog_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type AccessPackageCatalogResource struct{} @@ -86,12 +86,12 @@ func (AccessPackageCatalogResource) Exists(ctx context.Context, clients *clients _, status, err := client.Get(ctx, state.ID, odata.Query{}) if err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, fmt.Errorf("failed to retrieve access package catalog with ID %q: %+v", state.ID, err) } - return utils.Bool(true), nil + return pointer.To(true), nil } func (AccessPackageCatalogResource) basic(data acceptance.TestData) string { diff --git a/internal/services/identitygovernance/access_package_catalog_role_assignment_resource.go b/internal/services/identitygovernance/access_package_catalog_role_assignment_resource.go index 5fbabcc528..58e6b45781 100644 --- a/internal/services/identitygovernance/access_package_catalog_role_assignment_resource.go +++ b/internal/services/identitygovernance/access_package_catalog_role_assignment_resource.go @@ -12,13 +12,13 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -78,10 +78,10 @@ func accessPackageCatalogRoleAssignmentResourceCreate(ctx context.Context, d *pl roleId := d.Get("role_id").(string) properties := msgraph.UnifiedRoleAssignment{ - DirectoryScopeId: utils.String("/"), - PrincipalId: utils.String(principalId), - RoleDefinitionId: utils.String(roleId), - AppScopeId: utils.String("/AccessPackageCatalog/" + catalogId), + DirectoryScopeId: pointer.To("/"), + PrincipalId: pointer.To(principalId), + RoleDefinitionId: pointer.To(roleId), + AppScopeId: pointer.To("/AccessPackageCatalog/" + catalogId), } assignment, status, err := client.Create(ctx, properties) @@ -112,7 +112,7 @@ func accessPackageCatalogRoleAssignmentResourceRead(ctx context.Context, d *plug catalogId := strings.TrimPrefix(*assignment.AppScopeId, "/AccessPackageCatalog/") - tf.Set(d, "catalog_id", utils.String(catalogId)) + tf.Set(d, "catalog_id", pointer.To(catalogId)) tf.Set(d, "principal_object_id", assignment.PrincipalId) tf.Set(d, "role_id", assignment.RoleDefinitionId) diff --git a/internal/services/identitygovernance/access_package_catalog_role_assignment_resource_test.go b/internal/services/identitygovernance/access_package_catalog_role_assignment_resource_test.go index bcbdb0bd8b..f4468c9349 100644 --- a/internal/services/identitygovernance/access_package_catalog_role_assignment_resource_test.go +++ b/internal/services/identitygovernance/access_package_catalog_role_assignment_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type AccessPackageCatalogRoleAssignmentResource struct{} @@ -80,12 +80,12 @@ func (r AccessPackageCatalogRoleAssignmentResource) Exists(ctx context.Context, if _, status, err := client.Get(ctx, state.ID, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, fmt.Errorf("failed to retrieve directory role assignment %q: %+v", state.ID, err) } - return utils.Bool(true), nil + return pointer.To(true), nil } func (AccessPackageCatalogRoleAssignmentResource) group(data acceptance.TestData) string { diff --git a/internal/services/identitygovernance/access_package_resource.go b/internal/services/identitygovernance/access_package_resource.go index 661d301af5..f80d847d05 100644 --- a/internal/services/identitygovernance/access_package_resource.go +++ b/internal/services/identitygovernance/access_package_resource.go @@ -10,6 +10,7 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" @@ -17,7 +18,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -90,9 +90,9 @@ func accessPackageResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, } properties := msgraph.AccessPackage{ - DisplayName: utils.String(displayName), - Description: utils.String(d.Get("description").(string)), - IsHidden: utils.Bool(d.Get("hidden").(bool)), + DisplayName: pointer.To(displayName), + Description: pointer.To(d.Get("description").(string)), + IsHidden: pointer.To(d.Get("hidden").(bool)), Catalog: accessPackageCatalog, CatalogId: accessPackageCatalog.ID, } @@ -123,10 +123,10 @@ func accessPackageResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, defer tf.UnlockByName(accessPackageResourceName, objectId) properties := msgraph.AccessPackage{ - ID: utils.String(objectId), - DisplayName: utils.String(d.Get("display_name").(string)), - Description: utils.String(d.Get("description").(string)), - IsHidden: utils.Bool(d.Get("hidden").(bool)), + ID: pointer.To(objectId), + DisplayName: pointer.To(d.Get("display_name").(string)), + Description: pointer.To(d.Get("description").(string)), + IsHidden: pointer.To(d.Get("hidden").(bool)), Catalog: accessPackageCatalog, CatalogId: accessPackageCatalog.ID, } @@ -186,11 +186,11 @@ func accessPackageResourceDelete(ctx context.Context, d *pluginsdk.ResourceData, client.BaseClient.DisableRetries = true if _, status, err := client.Get(ctx, accessPackageId, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of access package with object ID %q", accessPackageId) } diff --git a/internal/services/identitygovernance/access_package_resource_catalog_association_resource.go b/internal/services/identitygovernance/access_package_resource_catalog_association_resource.go index ee3fe903aa..c75e036a20 100644 --- a/internal/services/identitygovernance/access_package_resource_catalog_association_resource.go +++ b/internal/services/identitygovernance/access_package_resource_catalog_association_resource.go @@ -9,13 +9,13 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/services/identitygovernance/parse" "github.com/hashicorp/terraform-provider-azuread/internal/services/identitygovernance/validate" "github.com/hashicorp/terraform-provider-azuread/internal/tf" "github.com/hashicorp/terraform-provider-azuread/internal/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -84,7 +84,7 @@ func accessPackageResourceCatalogAssociationResourceCreate(ctx context.Context, properties := msgraph.AccessPackageResourceRequest{ CatalogId: &catalogId, - RequestType: utils.String("AdminAdd"), + RequestType: pointer.To("AdminAdd"), AccessPackageResource: &msgraph.AccessPackageResource{ OriginId: &resourceOriginId, OriginSystem: resourceOriginSystem, diff --git a/internal/services/identitygovernance/access_package_resource_catalog_association_resource_test.go b/internal/services/identitygovernance/access_package_resource_catalog_association_resource_test.go index 763b0f11d8..c37c362324 100644 --- a/internal/services/identitygovernance/access_package_resource_catalog_association_resource_test.go +++ b/internal/services/identitygovernance/access_package_resource_catalog_association_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/services/identitygovernance/parse" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" ) type AccessPackageResourceCatalogAssociationResource struct{} @@ -62,13 +62,13 @@ func (r AccessPackageResourceCatalogAssociationResource) Exists(ctx context.Cont _, status, err := client.Get(ctx, id.CatalogId, id.OriginId) if err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, fmt.Errorf("failed to retrieve access package catalog association with ID %q: %+v", id.ID(), err) } - return utils.Bool(true), nil + return pointer.To(true), nil } func (r AccessPackageResourceCatalogAssociationResource) complete(data acceptance.TestData) string { diff --git a/internal/services/identitygovernance/access_package_resource_package_association_resource.go b/internal/services/identitygovernance/access_package_resource_package_association_resource.go index e3fe563b11..fb9f9579ec 100644 --- a/internal/services/identitygovernance/access_package_resource_package_association_resource.go +++ b/internal/services/identitygovernance/access_package_resource_package_association_resource.go @@ -10,6 +10,7 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/services/identitygovernance/parse" @@ -17,7 +18,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -86,8 +86,8 @@ func accessPackageResourcePackageAssociationResourceCreate(ctx context.Context, properties := msgraph.AccessPackageResourceRoleScope{ AccessPackageId: &accessPackageId, AccessPackageResourceRole: &msgraph.AccessPackageResourceRole{ - DisplayName: utils.String(accessType), - OriginId: utils.String(fmt.Sprintf("%s_%s", accessType, catalogResourceAssociationId.OriginId)), + DisplayName: pointer.To(accessType), + OriginId: pointer.To(fmt.Sprintf("%s_%s", accessType, catalogResourceAssociationId.OriginId)), OriginSystem: resource.OriginSystem, AccessPackageResource: &msgraph.AccessPackageResource{ ID: resource.ID, diff --git a/internal/services/identitygovernance/access_package_resource_package_association_resource_test.go b/internal/services/identitygovernance/access_package_resource_package_association_resource_test.go index 89fd1b4cc2..9b42c72e14 100644 --- a/internal/services/identitygovernance/access_package_resource_package_association_resource_test.go +++ b/internal/services/identitygovernance/access_package_resource_package_association_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/services/identitygovernance/parse" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" ) type AccessPackageResourcePackageAssociationResource struct{} @@ -48,13 +48,13 @@ func (AccessPackageResourcePackageAssociationResource) Exists(ctx context.Contex _, status, err := client.Get(ctx, id.AccessPackageId, id.ResourcePackageAssociationId) if err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, fmt.Errorf("failed to retrieve access package resource association with ID %q: %+v", id.ID(), err) } - return utils.Bool(true), nil + return pointer.To(true), nil } func (AccessPackageResourcePackageAssociationResource) complete(data acceptance.TestData) string { diff --git a/internal/services/identitygovernance/access_package_resource_test.go b/internal/services/identitygovernance/access_package_resource_test.go index 339f2678dd..924ae49219 100644 --- a/internal/services/identitygovernance/access_package_resource_test.go +++ b/internal/services/identitygovernance/access_package_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type AccessPackageResource struct{} @@ -86,11 +86,11 @@ func (AccessPackageResource) Exists(ctx context.Context, clients *clients.Client _, status, err := client.Get(ctx, state.ID, odata.Query{}) if err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, fmt.Errorf("failed to retrieve access package with ID %q: %+v", state.ID, err) } - return utils.Bool(true), nil + return pointer.To(true), nil } func (AccessPackageResource) basic(data acceptance.TestData) string { diff --git a/internal/services/identitygovernance/identitygovernance.go b/internal/services/identitygovernance/identitygovernance.go index c984fd6ef6..aa8d3cdbc6 100644 --- a/internal/services/identitygovernance/identitygovernance.go +++ b/internal/services/identitygovernance/identitygovernance.go @@ -7,8 +7,8 @@ import ( "fmt" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -19,7 +19,7 @@ func expandRequestorSettings(input []interface{}) *msgraph.RequestorSettings { in := input[0].(map[string]interface{}) result := msgraph.RequestorSettings{ ScopeType: in["scope_type"].(string), - AcceptRequests: utils.Bool(in["requests_accepted"].(bool)), + AcceptRequests: pointer.To(in["requests_accepted"].(bool)), } result.AllowedRequestors = expandUserSets(in["requestor"].([]interface{})) @@ -46,9 +46,9 @@ func expandApprovalSettings(input []interface{}) *msgraph.ApprovalSettings { in := input[0].(map[string]interface{}) result := msgraph.ApprovalSettings{ - IsApprovalRequired: utils.Bool(in["approval_required"].(bool)), - IsApprovalRequiredForExtension: utils.Bool(in["approval_required_for_extension"].(bool)), - IsRequestorJustificationRequired: utils.Bool(in["requestor_justification_required"].(bool)), + IsApprovalRequired: pointer.To(in["approval_required"].(bool)), + IsApprovalRequiredForExtension: pointer.To(in["approval_required_for_extension"].(bool)), + IsRequestorJustificationRequired: pointer.To(in["requestor_justification_required"].(bool)), } approvalStages := make([]msgraph.ApprovalStage, 0) @@ -56,10 +56,10 @@ func expandApprovalSettings(input []interface{}) *msgraph.ApprovalSettings { v_map := v.(map[string]interface{}) stage := msgraph.ApprovalStage{ - ApprovalStageTimeOutInDays: utils.Int32(int32(v_map["approval_timeout_in_days"].(int))), - EscalationTimeInMinutes: utils.Int32(int32(v_map["enable_alternative_approval_in_days"].(int) * 24 * 60)), - IsApproverJustificationRequired: utils.Bool(v_map["approver_justification_required"].(bool)), - IsEscalationEnabled: utils.Bool(v_map["alternative_approval_enabled"].(bool)), + ApprovalStageTimeOutInDays: pointer.To(int32(v_map["approval_timeout_in_days"].(int))), + EscalationTimeInMinutes: pointer.To(int32(v_map["enable_alternative_approval_in_days"].(int) * 24 * 60)), + IsApproverJustificationRequired: pointer.To(v_map["approver_justification_required"].(bool)), + IsEscalationEnabled: pointer.To(v_map["alternative_approval_enabled"].(bool)), } stage.PrimaryApprovers = expandUserSets(v_map["primary_approver"].([]interface{})) @@ -111,10 +111,10 @@ func expandAssignmentReviewSettings(input []interface{}) (*msgraph.AssignmentRev result := msgraph.AssignmentReviewSettings{ AccessReviewTimeoutBehavior: in["access_review_timeout_behavior"].(string), - DurationInDays: utils.Int32(int32(in["duration_in_days"].(int))), - IsAccessRecommendationEnabled: utils.Bool(in["access_recommendation_enabled"].(bool)), - IsApprovalJustificationRequired: utils.Bool(in["approver_justification_required"].(bool)), - IsEnabled: utils.Bool(in["enabled"].(bool)), + DurationInDays: pointer.To(int32(in["duration_in_days"].(int))), + IsAccessRecommendationEnabled: pointer.To(in["access_recommendation_enabled"].(bool)), + IsApprovalJustificationRequired: pointer.To(in["approver_justification_required"].(bool)), + IsEnabled: pointer.To(in["enabled"].(bool)), RecurrenceType: in["review_frequency"].(string), ReviewerType: in["review_type"].(string), } @@ -159,10 +159,10 @@ func expandUserSets(input []interface{}) *[]msgraph.UserSet { oDataType, needId := userSetODataType(v_map["subject_type"].(string)) userSet := msgraph.UserSet{ ODataType: oDataType, - IsBackup: utils.Bool(v_map["backup"].(bool)), + IsBackup: pointer.To(v_map["backup"].(bool)), } if needId { - userSet.ID = utils.String(v_map["object_id"].(string)) + userSet.ID = pointer.To(v_map["object_id"].(string)) } userSets = append(userSets, userSet) @@ -239,22 +239,22 @@ func expandAccessPackageQuestions(questions []interface{}) *[]msgraph.AccessPack v_text := v_text_list[0].(map[string]interface{}) q := msgraph.AccessPackageQuestion{ - IsRequired: utils.Bool(v_map["required"].(bool)), - Sequence: utils.Int32(int32(v_map["sequence"].(int))), + IsRequired: pointer.To(v_map["required"].(bool)), + Sequence: pointer.To(int32(v_map["sequence"].(int))), Text: expandAccessPackageLocalizedContent(v_text), } v_map_choices := v_map["choice"].([]interface{}) - q.ODataType = utils.String(odata.TypeAccessPackageTextInputQuestion) + q.ODataType = pointer.To(odata.TypeAccessPackageTextInputQuestion) if len(v_map_choices) > 0 { - q.ODataType = utils.String(odata.TypeAccessPackageMultipleChoiceQuestion) + q.ODataType = pointer.To(odata.TypeAccessPackageMultipleChoiceQuestion) choices := make([]msgraph.AccessPackageMultipleChoiceQuestions, 0) for _, c := range v_map_choices { c_map := c.(map[string]interface{}) c_map_display_value := c_map["display_value"].([]interface{}) choices = append(choices, msgraph.AccessPackageMultipleChoiceQuestions{ - ActualValue: utils.String(c_map["actual_value"].(string)), + ActualValue: pointer.To(c_map["actual_value"].(string)), DisplayValue: expandAccessPackageLocalizedContent(c_map_display_value[0].(map[string]interface{})), }) } @@ -305,7 +305,7 @@ func flattenAccessPackageQuestions(input *[]msgraph.AccessPackageQuestion) []map func expandAccessPackageLocalizedContent(input map[string]interface{}) *msgraph.AccessPackageLocalizedContent { result := msgraph.AccessPackageLocalizedContent{ - DefaultText: utils.String(input["default_text"].(string)), + DefaultText: pointer.To(input["default_text"].(string)), } texts := make([]msgraph.AccessPackageLocalizedTexts, 0) @@ -313,8 +313,8 @@ func expandAccessPackageLocalizedContent(input map[string]interface{}) *msgraph. for _, v := range input["localized_text"].([]interface{}) { v_map := v.(map[string]interface{}) texts = append(texts, msgraph.AccessPackageLocalizedTexts{ - LanguageCode: utils.String(v_map["language_code"].(string)), - Text: utils.String(v_map["content"].(string)), + LanguageCode: pointer.To(v_map["language_code"].(string)), + Text: pointer.To(v_map["content"].(string)), }) } diff --git a/internal/services/invitations/invitation_resource.go b/internal/services/invitations/invitation_resource.go index 786a4ed545..57f1d379aa 100644 --- a/internal/services/invitations/invitation_resource.go +++ b/internal/services/invitations/invitation_resource.go @@ -11,13 +11,13 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -129,17 +129,17 @@ func invitationResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, me usersClient := meta.(*clients.Client).Invitations.UsersClient properties := msgraph.Invitation{ - InvitedUserEmailAddress: utils.String(d.Get("user_email_address").(string)), - InviteRedirectURL: utils.String(d.Get("redirect_url").(string)), - InvitedUserType: utils.String(d.Get("user_type").(string)), + InvitedUserEmailAddress: pointer.To(d.Get("user_email_address").(string)), + InviteRedirectURL: pointer.To(d.Get("redirect_url").(string)), + InvitedUserType: pointer.To(d.Get("user_type").(string)), } if v, ok := d.GetOk("user_display_name"); ok { - properties.InvitedUserDisplayName = utils.String(v.(string)) + properties.InvitedUserDisplayName = pointer.To(v.(string)) } if v, ok := d.GetOk("message"); ok { - properties.SendInvitationMessage = utils.Bool(true) + properties.SendInvitationMessage = pointer.To(true) properties.InvitedUserMessageInfo = expandInvitedUserMessageInfo(v.([]interface{})) } @@ -169,7 +169,7 @@ func invitationResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, me DirectoryObject: msgraph.DirectoryObject{ Id: invitation.InvitedUser.ID(), }, - CompanyName: utils.NullableString("TERRAFORM_UPDATE"), + CompanyName: tf.NullableString("TERRAFORM_UPDATE"), }) if err != nil { if status == http.StatusNotFound { @@ -181,7 +181,7 @@ func invitationResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, me DirectoryObject: msgraph.DirectoryObject{ Id: invitation.InvitedUser.ID(), }, - CompanyName: utils.NullableString(""), + CompanyName: tf.NullableString(""), }) if err != nil { if status == http.StatusNotFound { @@ -239,11 +239,11 @@ func invitationResourceDelete(ctx context.Context, d *pluginsdk.ResourceData, me client.BaseClient.DisableRetries = true if _, status, err := client.Get(ctx, userID, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of invited user with object ID %q", userID) } diff --git a/internal/services/invitations/invitation_resource_test.go b/internal/services/invitations/invitation_resource_test.go index 3a99c03533..3636abe061 100644 --- a/internal/services/invitations/invitation_resource_test.go +++ b/internal/services/invitations/invitation_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type InvitationResource struct{} @@ -154,7 +154,7 @@ func (r InvitationResource) Exists(ctx context.Context, clients *clients.Client, return nil, fmt.Errorf("failed to retrieve invited user with object ID %q: %+v", userID, err) } - return utils.Bool(user.ID() != nil && *user.ID() == userID), nil + return pointer.To(user.ID() != nil && *user.ID() == userID), nil } func (InvitationResource) basic(data acceptance.TestData) string { diff --git a/internal/services/policies/claims_mapping_policy_resource.go b/internal/services/policies/claims_mapping_policy_resource.go index 0d925e8abf..cc736cf375 100644 --- a/internal/services/policies/claims_mapping_policy_resource.go +++ b/internal/services/policies/claims_mapping_policy_resource.go @@ -9,12 +9,12 @@ import ( "log" "net/http" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/tf" "github.com/hashicorp/terraform-provider-azuread/internal/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -56,7 +56,7 @@ func claimsMappingPolicyResourceCreate(ctx context.Context, d *pluginsdk.Resourc claimsMappingPolicy := msgraph.ClaimsMappingPolicy{ Definition: tf.ExpandStringSlicePtr(d.Get("definition").([]interface{})), - DisplayName: utils.String(d.Get("display_name").(string)), + DisplayName: pointer.To(d.Get("display_name").(string)), } policy, _, err := client.Create(ctx, claimsMappingPolicy) if err != nil { @@ -102,7 +102,7 @@ func claimsMappingPolicyResourceUpdate(ctx context.Context, d *pluginsdk.Resourc Id: &objectId, }, Definition: tf.ExpandStringSlicePtr(d.Get("definition").([]interface{})), - DisplayName: utils.String(d.Get("display_name").(string)), + DisplayName: pointer.To(d.Get("display_name").(string)), } _, err := client.Update(ctx, claimsMappingPolicy) if err != nil { diff --git a/internal/services/serviceprincipals/service_principal_certificate_resource.go b/internal/services/serviceprincipals/service_principal_certificate_resource.go index 1cef63e58c..b77e3352d6 100644 --- a/internal/services/serviceprincipals/service_principal_certificate_resource.go +++ b/internal/services/serviceprincipals/service_principal_certificate_resource.go @@ -12,6 +12,7 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/helpers" @@ -19,7 +20,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -304,10 +304,10 @@ func servicePrincipalCertificateResourceDelete(ctx context.Context, d *pluginsdk credential := helpers.GetKeyCredential(servicePrincipal.KeyCredentials, id.KeyId) if credential == nil { - return utils.Bool(false), nil + return pointer.To(false), nil } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of certificate credential %q from service principal with object ID %q", id.KeyId, id.ObjectId) } diff --git a/internal/services/serviceprincipals/service_principal_certificate_resource_test.go b/internal/services/serviceprincipals/service_principal_certificate_resource_test.go index 08d134b803..f4460c24ef 100644 --- a/internal/services/serviceprincipals/service_principal_certificate_resource_test.go +++ b/internal/services/serviceprincipals/service_principal_certificate_resource_test.go @@ -10,13 +10,13 @@ import ( "testing" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/services/serviceprincipals/parse" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" ) // To create test certificates: @@ -191,7 +191,7 @@ func (r ServicePrincipalCertificateResource) Exists(ctx context.Context, clients if servicePrincipal.KeyCredentials != nil { for _, cred := range *servicePrincipal.KeyCredentials { if cred.KeyId != nil && *cred.KeyId == id.KeyId { - return utils.Bool(true), nil + return pointer.To(true), nil } } } diff --git a/internal/services/serviceprincipals/service_principal_claims_mapping_policy_assignment_resource.go b/internal/services/serviceprincipals/service_principal_claims_mapping_policy_assignment_resource.go index 66158f9203..2e07da854e 100644 --- a/internal/services/serviceprincipals/service_principal_claims_mapping_policy_assignment_resource.go +++ b/internal/services/serviceprincipals/service_principal_claims_mapping_policy_assignment_resource.go @@ -9,12 +9,12 @@ import ( "log" "net/http" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/services/serviceprincipals/parse" "github.com/hashicorp/terraform-provider-azuread/internal/tf" "github.com/hashicorp/terraform-provider-azuread/internal/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -55,12 +55,12 @@ func servicePrincipalClaimsMappingPolicyAssignmentResourceCreate(ctx context.Con properties := msgraph.ServicePrincipal{ DirectoryObject: msgraph.DirectoryObject{ - Id: utils.String(d.Get("service_principal_id").(string)), + Id: pointer.To(d.Get("service_principal_id").(string)), }, ClaimsMappingPolicies: &[]msgraph.ClaimsMappingPolicy{ { DirectoryObject: msgraph.DirectoryObject{ - ODataId: (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + ODataId: (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, policyId))), Id: &policyId, }, diff --git a/internal/services/serviceprincipals/service_principal_claims_mapping_policy_assignment_resource_test.go b/internal/services/serviceprincipals/service_principal_claims_mapping_policy_assignment_resource_test.go index e6c163d903..838ddab0a8 100644 --- a/internal/services/serviceprincipals/service_principal_claims_mapping_policy_assignment_resource_test.go +++ b/internal/services/serviceprincipals/service_principal_claims_mapping_policy_assignment_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/services/serviceprincipals/parse" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" ) type ServicePrincipalClaimsMappingPolicyAssignmentResource struct{} @@ -70,17 +70,17 @@ func (r ServicePrincipalClaimsMappingPolicyAssignmentResource) Exists(ctx contex policyList, status, err := client.ListClaimsMappingPolicy(ctx, id.ServicePrincipalId) if err != nil { if status == http.StatusNotFound { - return utils.Bool(false), fmt.Errorf("Service Policy with object ID %q does not exist", id.ServicePrincipalId) + return pointer.To(false), fmt.Errorf("Service Policy with object ID %q does not exist", id.ServicePrincipalId) } - return utils.Bool(false), fmt.Errorf("failed to retrieve claims mapping policy assignments with service policy ID %q: %+v", id.ServicePrincipalId, err) + return pointer.To(false), fmt.Errorf("failed to retrieve claims mapping policy assignments with service policy ID %q: %+v", id.ServicePrincipalId, err) } // Check the assignment is found in the currently assigned policies for _, policy := range *policyList { if policy.ID() != nil && *policy.ID() == id.ClaimsMappingPolicyId { - return utils.Bool(true), nil + return pointer.To(true), nil } } - return utils.Bool(false), nil + return pointer.To(false), nil } diff --git a/internal/services/serviceprincipals/service_principal_delegated_permission_grant_resource.go b/internal/services/serviceprincipals/service_principal_delegated_permission_grant_resource.go index 1a6a25d8f9..35ec9a1441 100644 --- a/internal/services/serviceprincipals/service_principal_delegated_permission_grant_resource.go +++ b/internal/services/serviceprincipals/service_principal_delegated_permission_grant_resource.go @@ -11,12 +11,12 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -102,16 +102,16 @@ func servicePrincipalDelegatedPermissionGrantResourceCreate(ctx context.Context, } properties := msgraph.DelegatedPermissionGrant{ - ClientId: utils.String(servicePrincipalId), - ResourceId: utils.String(resourceId), + ClientId: pointer.To(servicePrincipalId), + ResourceId: pointer.To(resourceId), Scopes: tf.ExpandStringSlicePtr(d.Get("claim_values").(*pluginsdk.Set).List()), } if v, ok := d.GetOk("user_object_id"); ok && v.(string) != "" { - properties.PrincipalId = utils.String(v.(string)) - properties.ConsentType = utils.String(msgraph.DelegatedPermissionGrantConsentTypePrincipal) + properties.PrincipalId = pointer.To(v.(string)) + properties.ConsentType = pointer.To(msgraph.DelegatedPermissionGrantConsentTypePrincipal) } else { - properties.ConsentType = utils.String(msgraph.DelegatedPermissionGrantConsentTypeAllPrincipals) + properties.ConsentType = pointer.To(msgraph.DelegatedPermissionGrantConsentTypeAllPrincipals) } delegatedPermissionGrant, _, err := client.Create(ctx, properties) @@ -132,7 +132,7 @@ func servicePrincipalDelegatedPermissionGrantResourceUpdate(ctx context.Context, client := meta.(*clients.Client).ServicePrincipals.DelegatedPermissionGrantsClient properties := msgraph.DelegatedPermissionGrant{ - Id: utils.String(d.Id()), + Id: pointer.To(d.Id()), Scopes: tf.ExpandStringSlicePtr(d.Get("claim_values").(*pluginsdk.Set).List()), } diff --git a/internal/services/serviceprincipals/service_principal_delegated_permission_grant_resource_test.go b/internal/services/serviceprincipals/service_principal_delegated_permission_grant_resource_test.go index b54c380024..81c5700489 100644 --- a/internal/services/serviceprincipals/service_principal_delegated_permission_grant_resource_test.go +++ b/internal/services/serviceprincipals/service_principal_delegated_permission_grant_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type ServicePrincipalDelegatedPermissionGrantResource struct{} @@ -61,7 +61,7 @@ func (r ServicePrincipalDelegatedPermissionGrantResource) Exists(ctx context.Con return nil, fmt.Errorf("failed to retrieve Delegated Permission Grant with ID %q: %+v", state.ID, err) } - return utils.Bool(true), nil + return pointer.To(true), nil } func (r ServicePrincipalDelegatedPermissionGrantResource) template(data acceptance.TestData) string { diff --git a/internal/services/serviceprincipals/service_principal_password_resource.go b/internal/services/serviceprincipals/service_principal_password_resource.go index 86b350283d..9994a91702 100644 --- a/internal/services/serviceprincipals/service_principal_password_resource.go +++ b/internal/services/serviceprincipals/service_principal_password_resource.go @@ -12,6 +12,7 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/helpers" @@ -20,7 +21,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" ) func servicePrincipalPasswordResource() *pluginsdk.Resource { @@ -280,10 +280,10 @@ func servicePrincipalPasswordResourceDelete(ctx context.Context, d *pluginsdk.Re credential := helpers.GetPasswordCredential(servicePrincipal.PasswordCredentials, id.KeyId) if credential == nil { - return utils.Bool(false), nil + return pointer.To(false), nil } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of password credential %q from service principal with object ID %q", id.KeyId, id.ObjectId) } diff --git a/internal/services/serviceprincipals/service_principal_password_resource_test.go b/internal/services/serviceprincipals/service_principal_password_resource_test.go index 1831f0f255..9a8d8b0f1c 100644 --- a/internal/services/serviceprincipals/service_principal_password_resource_test.go +++ b/internal/services/serviceprincipals/service_principal_password_resource_test.go @@ -10,13 +10,13 @@ import ( "testing" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/services/serviceprincipals/parse" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" ) type ServicePrincipalPasswordResource struct{} @@ -99,7 +99,7 @@ func (r ServicePrincipalPasswordResource) Exists(ctx context.Context, clients *c if servicePrincipal.PasswordCredentials != nil { for _, cred := range *servicePrincipal.PasswordCredentials { if cred.KeyId != nil && *cred.KeyId == id.KeyId { - return utils.Bool(true), nil + return pointer.To(true), nil } } } diff --git a/internal/services/serviceprincipals/service_principal_token_signing_certificate_resource.go b/internal/services/serviceprincipals/service_principal_token_signing_certificate_resource.go index 37b5a30579..e3abb4a993 100644 --- a/internal/services/serviceprincipals/service_principal_token_signing_certificate_resource.go +++ b/internal/services/serviceprincipals/service_principal_token_signing_certificate_resource.go @@ -13,6 +13,7 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/helpers" @@ -20,7 +21,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -103,7 +103,7 @@ func servicePrincipalTokenSigningCertificateResourceCreate(ctx context.Context, keyCreds := msgraph.KeyCredential{} if v, ok := d.GetOk("display_name"); ok { - keyCreds.DisplayName = utils.String(v.(string)) + keyCreds.DisplayName = pointer.To(v.(string)) } if v, ok := d.GetOk("end_date"); ok { @@ -299,10 +299,10 @@ func servicePrincipalTokenSigningCertificateResourceDelete(ctx context.Context, credential := helpers.GetKeyCredential(servicePrincipal.KeyCredentials, id.KeyId) if credential == nil { - return utils.Bool(false), nil + return pointer.To(false), nil } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of token signing certificate credential %q from service principal with object ID %q", id.KeyId, id.ObjectId) } diff --git a/internal/services/serviceprincipals/service_principal_token_signing_certificate_resource_test.go b/internal/services/serviceprincipals/service_principal_token_signing_certificate_resource_test.go index 68598fb273..bf50bb4351 100644 --- a/internal/services/serviceprincipals/service_principal_token_signing_certificate_resource_test.go +++ b/internal/services/serviceprincipals/service_principal_token_signing_certificate_resource_test.go @@ -10,13 +10,13 @@ import ( "testing" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/services/serviceprincipals/parse" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" ) type servicePrincipalTokenSigningCertificateResource struct{} @@ -83,7 +83,7 @@ func (r servicePrincipalTokenSigningCertificateResource) Exists(ctx context.Cont if servicePrincipal.KeyCredentials != nil { for _, cred := range *servicePrincipal.KeyCredentials { if cred.KeyId != nil && *cred.KeyId == id.KeyId { - return utils.Bool(true), nil + return pointer.To(true), nil } } } diff --git a/internal/services/serviceprincipals/serviceprincipals.go b/internal/services/serviceprincipals/serviceprincipals.go index 22db232205..14bac2a223 100644 --- a/internal/services/serviceprincipals/serviceprincipals.go +++ b/internal/services/serviceprincipals/serviceprincipals.go @@ -13,8 +13,8 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -26,7 +26,7 @@ func expandSamlSingleSignOn(in []interface{}) *msgraph.SamlSingleSignOnSettings samlSingleSignOnSettings := in[0].(map[string]interface{}) - result.RelayState = utils.String(samlSingleSignOnSettings["relay_state"].(string)) + result.RelayState = pointer.To(samlSingleSignOnSettings["relay_state"].(string)) return &result } diff --git a/internal/services/serviceprincipals/synchronization.go b/internal/services/serviceprincipals/synchronization.go index b914d014e7..84780f6712 100644 --- a/internal/services/serviceprincipals/synchronization.go +++ b/internal/services/serviceprincipals/synchronization.go @@ -6,7 +6,7 @@ package serviceprincipals import ( "time" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/manicminer/hamilton/msgraph" ) @@ -20,8 +20,8 @@ func emptySynchronizationSecretKeyStringValuePair(in []interface{}) *[]msgraph.S item := raw.(map[string]interface{}) result = append(result, msgraph.SynchronizationSecretKeyStringValuePair{ - Key: utils.String(item["key"].(string)), - Value: utils.String(""), + Key: pointer.To(item["key"].(string)), + Value: pointer.To(""), }) } @@ -38,8 +38,8 @@ func expandSynchronizationSecretKeyStringValuePair(in []interface{}) *[]msgraph. item := raw.(map[string]interface{}) result = append(result, msgraph.SynchronizationSecretKeyStringValuePair{ - Key: utils.String(item["key"].(string)), - Value: utils.String(item["value"].(string)), + Key: pointer.To(item["key"].(string)), + Value: pointer.To(item["value"].(string)), }) } @@ -78,7 +78,7 @@ func flattenSynchronizationSecretKeyStringValuePair(in *[]msgraph.Synchronizatio } currentItem := raw.(map[string]interface{}) if currentItem["key"].(string) == *item.Key { - value = utils.String(currentItem["value"].(string)) + value = pointer.To(currentItem["value"].(string)) } } } diff --git a/internal/services/serviceprincipals/synchronization_job_resource.go b/internal/services/serviceprincipals/synchronization_job_resource.go index 65d82c5f3b..abc635d9bc 100644 --- a/internal/services/serviceprincipals/synchronization_job_resource.go +++ b/internal/services/serviceprincipals/synchronization_job_resource.go @@ -11,6 +11,7 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/helpers" @@ -18,7 +19,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -111,7 +111,7 @@ func synchronizationJobResourceCreate(ctx context.Context, d *pluginsdk.Resource // Create a new synchronization job synchronizationJob := msgraph.SynchronizationJob{ - TemplateId: utils.String(d.Get("template_id").(string)), + TemplateId: pointer.To(d.Get("template_id").(string)), } newJob, _, err := client.Create(ctx, synchronizationJob, *servicePrincipal.ID()) @@ -232,10 +232,10 @@ func synchronizationJobResourceDelete(ctx context.Context, d *pluginsdk.Resource job, _, _ := client.Get(ctx, id.JobId, id.ServicePrincipalId) if job == nil { - return utils.Bool(false), nil + return pointer.To(false), nil } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of synchronization job %q from service principal with object ID %q", id.JobId, id.ServicePrincipalId) } diff --git a/internal/services/serviceprincipals/synchronization_job_resource_test.go b/internal/services/serviceprincipals/synchronization_job_resource_test.go index 1f85766c09..987191fab0 100644 --- a/internal/services/serviceprincipals/synchronization_job_resource_test.go +++ b/internal/services/serviceprincipals/synchronization_job_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/services/serviceprincipals/parse" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" ) type SynchronizationJobResource struct{} @@ -70,7 +70,7 @@ func (r SynchronizationJobResource) Exists(ctx context.Context, clients *clients } return nil, fmt.Errorf("Retrieving synchronization job with object ID %q", id.JobId) } - return utils.Bool(true), nil + return pointer.To(true), nil } func (SynchronizationJobResource) template(data acceptance.TestData) string { diff --git a/internal/services/serviceprincipals/synchronization_secret_resource.go b/internal/services/serviceprincipals/synchronization_secret_resource.go index 290fc4cb47..95de8cbee6 100644 --- a/internal/services/serviceprincipals/synchronization_secret_resource.go +++ b/internal/services/serviceprincipals/synchronization_secret_resource.go @@ -11,6 +11,7 @@ import ( "net/http" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-provider-azuread/internal/clients" "github.com/hashicorp/terraform-provider-azuread/internal/helpers" @@ -18,7 +19,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -203,10 +203,10 @@ func synchronizationSecretResourceDelete(ctx context.Context, d *pluginsdk.Resou // Test if credentials are removed if allCredentialsRemoved(*credentials, *synchronizationSecrets.Credentials) { - return utils.Bool(false), nil + return pointer.To(false), nil } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of synchronization secrets from service principal with object ID %q", id.ServicePrincipalId) } diff --git a/internal/services/serviceprincipals/synchronization_secret_resource_test.go b/internal/services/serviceprincipals/synchronization_secret_resource_test.go index be493d4d64..058b3b7a2c 100644 --- a/internal/services/serviceprincipals/synchronization_secret_resource_test.go +++ b/internal/services/serviceprincipals/synchronization_secret_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/services/serviceprincipals/parse" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" ) type SynchronizationSecretResource struct{} @@ -55,7 +55,7 @@ func (r SynchronizationSecretResource) Exists(ctx context.Context, clients *clie } return nil, fmt.Errorf("Retrieving synchronization secrets for service principal %q", id.ServicePrincipalId) } - return utils.Bool(true), nil + return pointer.To(true), nil } func (SynchronizationSecretResource) template(data acceptance.TestData) string { diff --git a/internal/services/userflows/user_flow_attribute_resource.go b/internal/services/userflows/user_flow_attribute_resource.go index 6381002d33..cdc4dbd8d9 100644 --- a/internal/services/userflows/user_flow_attribute_resource.go +++ b/internal/services/userflows/user_flow_attribute_resource.go @@ -12,13 +12,13 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -90,9 +90,9 @@ func userFlowAttributeResourceCreate(ctx context.Context, d *pluginsdk.ResourceD } attr := msgraph.UserFlowAttribute{ - DataType: utils.String(d.Get("data_type").(string)), - Description: utils.String(d.Get("description").(string)), - DisplayName: utils.String(displayName), + DataType: pointer.To(d.Get("data_type").(string)), + Description: pointer.To(d.Get("description").(string)), + DisplayName: pointer.To(displayName), } userFlowAttr, _, err := client.Create(ctx, attr) @@ -114,8 +114,8 @@ func userFlowAttributeResourceUpdate(ctx context.Context, d *pluginsdk.ResourceD id := d.Id() attr := msgraph.UserFlowAttribute{ - ID: utils.String(id), - Description: utils.String(d.Get("description").(string)), + ID: pointer.To(id), + Description: pointer.To(d.Get("description").(string)), } if _, err := client.Update(ctx, attr); err != nil { @@ -170,11 +170,11 @@ func userFlowAttributeResourceDelete(ctx context.Context, d *pluginsdk.ResourceD client.BaseClient.DisableRetries = true if _, status, err := client.Get(ctx, id, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of user flow attribute with ID %q", id) } diff --git a/internal/services/userflows/user_flow_attribute_resource_test.go b/internal/services/userflows/user_flow_attribute_resource_test.go index bc0487a3f9..73c4dee9df 100644 --- a/internal/services/userflows/user_flow_attribute_resource_test.go +++ b/internal/services/userflows/user_flow_attribute_resource_test.go @@ -9,12 +9,12 @@ import ( "net/http" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type UserflowAttributeResource struct{} @@ -82,7 +82,7 @@ func (r UserflowAttributeResource) Exists(ctx context.Context, clients *clients. return nil, fmt.Errorf("failed to retrieve User Flow attribute with ID %q: %+v", state.ID, err) } - return utils.Bool(userFlowAttr.ID != nil && *userFlowAttr.ID == state.ID), nil + return pointer.To(userFlowAttr.ID != nil && *userFlowAttr.ID == state.ID), nil } func (r UserflowAttributeResource) basic(data acceptance.TestData) string { diff --git a/internal/services/users/user_resource.go b/internal/services/users/user_resource.go index 33e9a774d5..3f544b470d 100644 --- a/internal/services/users/user_resource.go +++ b/internal/services/users/user_resource.go @@ -12,6 +12,7 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/go-uuid" "github.com/hashicorp/terraform-provider-azuread/internal/clients" @@ -19,7 +20,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -421,41 +421,41 @@ func userResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta int } properties := msgraph.User{ - AccountEnabled: utils.Bool(d.Get("account_enabled").(bool)), - AgeGroup: utils.NullableString(d.Get("age_group").(string)), - City: utils.NullableString(d.Get("city").(string)), - ConsentProvidedForMinor: utils.NullableString(d.Get("consent_provided_for_minor").(string)), - CompanyName: utils.NullableString(d.Get("company_name").(string)), - Country: utils.NullableString(d.Get("country").(string)), - Department: utils.NullableString(d.Get("department").(string)), - DisplayName: utils.String(d.Get("display_name").(string)), - EmployeeId: utils.NullableString(d.Get("employee_id").(string)), + AccountEnabled: pointer.To(d.Get("account_enabled").(bool)), + AgeGroup: tf.NullableString(d.Get("age_group").(string)), + City: tf.NullableString(d.Get("city").(string)), + ConsentProvidedForMinor: tf.NullableString(d.Get("consent_provided_for_minor").(string)), + CompanyName: tf.NullableString(d.Get("company_name").(string)), + Country: tf.NullableString(d.Get("country").(string)), + Department: tf.NullableString(d.Get("department").(string)), + DisplayName: pointer.To(d.Get("display_name").(string)), + EmployeeId: tf.NullableString(d.Get("employee_id").(string)), EmployeeOrgData: &msgraph.EmployeeOrgData{ - CostCenter: utils.String(d.Get("cost_center").(string)), - Division: utils.String(d.Get("division").(string)), + CostCenter: pointer.To(d.Get("cost_center").(string)), + Division: pointer.To(d.Get("division").(string)), }, - EmployeeType: utils.NullableString(d.Get("employee_type").(string)), - FaxNumber: utils.NullableString(d.Get("fax_number").(string)), - GivenName: utils.NullableString(d.Get("given_name").(string)), - JobTitle: utils.NullableString(d.Get("job_title").(string)), - Mail: utils.NullableString(d.Get("mail").(string)), - MailNickname: utils.String(mailNickName), - MobilePhone: utils.NullableString(d.Get("mobile_phone").(string)), - OfficeLocation: utils.NullableString(d.Get("office_location").(string)), + EmployeeType: tf.NullableString(d.Get("employee_type").(string)), + FaxNumber: tf.NullableString(d.Get("fax_number").(string)), + GivenName: tf.NullableString(d.Get("given_name").(string)), + JobTitle: tf.NullableString(d.Get("job_title").(string)), + Mail: tf.NullableString(d.Get("mail").(string)), + MailNickname: pointer.To(mailNickName), + MobilePhone: tf.NullableString(d.Get("mobile_phone").(string)), + OfficeLocation: tf.NullableString(d.Get("office_location").(string)), OtherMails: tf.ExpandStringSlicePtr(d.Get("other_mails").(*pluginsdk.Set).List()), - PasswordPolicies: utils.NullableString(passwordPolicies), - PostalCode: utils.NullableString(d.Get("postal_code").(string)), - PreferredLanguage: utils.NullableString(d.Get("preferred_language").(string)), - ShowInAddressList: utils.Bool(d.Get("show_in_address_list").(bool)), - State: utils.NullableString(d.Get("state").(string)), - StreetAddress: utils.NullableString(d.Get("street_address").(string)), - Surname: utils.NullableString(d.Get("surname").(string)), - UsageLocation: utils.NullableString(d.Get("usage_location").(string)), - UserPrincipalName: utils.String(upn), + PasswordPolicies: tf.NullableString(passwordPolicies), + PostalCode: tf.NullableString(d.Get("postal_code").(string)), + PreferredLanguage: tf.NullableString(d.Get("preferred_language").(string)), + ShowInAddressList: pointer.To(d.Get("show_in_address_list").(bool)), + State: tf.NullableString(d.Get("state").(string)), + StreetAddress: tf.NullableString(d.Get("street_address").(string)), + Surname: tf.NullableString(d.Get("surname").(string)), + UsageLocation: tf.NullableString(d.Get("usage_location").(string)), + UserPrincipalName: pointer.To(upn), PasswordProfile: &msgraph.UserPasswordProfile{ - ForceChangePasswordNextSignIn: utils.Bool(d.Get("force_password_change").(bool)), - Password: utils.String(password), + ForceChangePasswordNextSignIn: pointer.To(d.Get("force_password_change").(bool)), + Password: pointer.To(password), }, } @@ -464,7 +464,7 @@ func userResourceCreate(ctx context.Context, d *pluginsdk.ResourceData, meta int } if v, ok := d.GetOk("onpremises_immutable_id"); ok { - properties.OnPremisesImmutableId = utils.String(v.(string)) + properties.OnPremisesImmutableId = pointer.To(v.(string)) } user, _, err := client.Create(ctx, properties) @@ -517,43 +517,43 @@ func userResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta int properties := msgraph.User{ DirectoryObject: msgraph.DirectoryObject{ - Id: utils.String(d.Id()), + Id: pointer.To(d.Id()), }, - AccountEnabled: utils.Bool(d.Get("account_enabled").(bool)), - AgeGroup: utils.NullableString(d.Get("age_group").(string)), - City: utils.NullableString(d.Get("city").(string)), - CompanyName: utils.NullableString(d.Get("company_name").(string)), - ConsentProvidedForMinor: utils.NullableString(d.Get("consent_provided_for_minor").(string)), - Country: utils.NullableString(d.Get("country").(string)), - Department: utils.NullableString(d.Get("department").(string)), - DisplayName: utils.String(d.Get("display_name").(string)), - EmployeeId: utils.NullableString(d.Get("employee_id").(string)), + AccountEnabled: pointer.To(d.Get("account_enabled").(bool)), + AgeGroup: tf.NullableString(d.Get("age_group").(string)), + City: tf.NullableString(d.Get("city").(string)), + CompanyName: tf.NullableString(d.Get("company_name").(string)), + ConsentProvidedForMinor: tf.NullableString(d.Get("consent_provided_for_minor").(string)), + Country: tf.NullableString(d.Get("country").(string)), + Department: tf.NullableString(d.Get("department").(string)), + DisplayName: pointer.To(d.Get("display_name").(string)), + EmployeeId: tf.NullableString(d.Get("employee_id").(string)), EmployeeOrgData: &msgraph.EmployeeOrgData{ - CostCenter: utils.String(d.Get("cost_center").(string)), - Division: utils.String(d.Get("division").(string)), + CostCenter: pointer.To(d.Get("cost_center").(string)), + Division: pointer.To(d.Get("division").(string)), }, - EmployeeType: utils.NullableString(d.Get("employee_type").(string)), - FaxNumber: utils.NullableString(d.Get("fax_number").(string)), - GivenName: utils.NullableString(d.Get("given_name").(string)), - JobTitle: utils.NullableString(d.Get("job_title").(string)), - MailNickname: utils.String(d.Get("mail_nickname").(string)), - MobilePhone: utils.NullableString(d.Get("mobile_phone").(string)), - OfficeLocation: utils.NullableString(d.Get("office_location").(string)), + EmployeeType: tf.NullableString(d.Get("employee_type").(string)), + FaxNumber: tf.NullableString(d.Get("fax_number").(string)), + GivenName: tf.NullableString(d.Get("given_name").(string)), + JobTitle: tf.NullableString(d.Get("job_title").(string)), + MailNickname: pointer.To(d.Get("mail_nickname").(string)), + MobilePhone: tf.NullableString(d.Get("mobile_phone").(string)), + OfficeLocation: tf.NullableString(d.Get("office_location").(string)), OtherMails: tf.ExpandStringSlicePtr(d.Get("other_mails").(*pluginsdk.Set).List()), - PasswordPolicies: utils.NullableString(passwordPolicies), - PostalCode: utils.NullableString(d.Get("postal_code").(string)), - PreferredLanguage: utils.NullableString(d.Get("preferred_language").(string)), - State: utils.NullableString(d.Get("state").(string)), - StreetAddress: utils.NullableString(d.Get("street_address").(string)), - Surname: utils.NullableString(d.Get("surname").(string)), - UsageLocation: utils.NullableString(d.Get("usage_location").(string)), - UserPrincipalName: utils.String(d.Get("user_principal_name").(string)), + PasswordPolicies: tf.NullableString(passwordPolicies), + PostalCode: tf.NullableString(d.Get("postal_code").(string)), + PreferredLanguage: tf.NullableString(d.Get("preferred_language").(string)), + State: tf.NullableString(d.Get("state").(string)), + StreetAddress: tf.NullableString(d.Get("street_address").(string)), + Surname: tf.NullableString(d.Get("surname").(string)), + UsageLocation: tf.NullableString(d.Get("usage_location").(string)), + UserPrincipalName: pointer.To(d.Get("user_principal_name").(string)), } if password := d.Get("password").(string); d.HasChange("password") && password != "" { properties.PasswordProfile = &msgraph.UserPasswordProfile{ - ForceChangePasswordNextSignIn: utils.Bool(d.Get("force_password_change").(bool)), - Password: utils.String(password), + ForceChangePasswordNextSignIn: pointer.To(d.Get("force_password_change").(bool)), + Password: pointer.To(password), } } @@ -563,16 +563,16 @@ func userResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta int if d.HasChange("mail") { if mail := d.Get("mail").(string); mail != "" { - properties.Mail = utils.NullableString(mail) + properties.Mail = tf.NullableString(mail) } } if d.HasChange("onpremises_immutable_id") { - properties.OnPremisesImmutableId = utils.String(d.Get("onpremises_immutable_id").(string)) + properties.OnPremisesImmutableId = pointer.To(d.Get("onpremises_immutable_id").(string)) } if d.HasChange("show_in_address_list") { - properties.ShowInAddressList = utils.Bool(d.Get("show_in_address_list").(bool)) + properties.ShowInAddressList = pointer.To(d.Get("show_in_address_list").(bool)) } if _, err := client.Update(ctx, properties); err != nil { @@ -706,11 +706,11 @@ func userResourceDelete(ctx context.Context, d *pluginsdk.ResourceData, meta int client.BaseClient.DisableRetries = true if _, status, err := client.Get(ctx, userId, odata.Query{}); err != nil { if status == http.StatusNotFound { - return utils.Bool(false), nil + return pointer.To(false), nil } return nil, err } - return utils.Bool(true), nil + return pointer.To(true), nil }); err != nil { return tf.ErrorDiagF(err, "Waiting for deletion of user with object ID %q", userId) } diff --git a/internal/services/users/user_resource_test.go b/internal/services/users/user_resource_test.go index cf1c2e8211..c6834a5f10 100644 --- a/internal/services/users/user_resource_test.go +++ b/internal/services/users/user_resource_test.go @@ -10,12 +10,12 @@ import ( "regexp" "testing" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/hashicorp/terraform-plugin-testing/terraform" "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/utils" ) type UserResource struct{} @@ -139,7 +139,7 @@ func (r UserResource) Exists(ctx context.Context, clients *clients.Client, state } return nil, fmt.Errorf("failed to retrieve User with object ID %q: %+v", state.ID, err) } - return utils.Bool(user.ID() != nil && *user.ID() == state.ID), nil + return pointer.To(user.ID() != nil && *user.ID() == state.ID), nil } func (UserResource) basic(data acceptance.TestData) string { diff --git a/internal/services/users/users.go b/internal/services/users/users.go index 33e0799d8a..a395db11ca 100644 --- a/internal/services/users/users.go +++ b/internal/services/users/users.go @@ -8,8 +8,8 @@ import ( "errors" "fmt" + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-sdk/sdk/odata" - "github.com/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -22,7 +22,7 @@ func assignManager(ctx context.Context, client *msgraph.UsersClient, directoryOb if managerObject == nil { return errors.New("managerObject was nil") } - managerObject.ODataId = (*odata.Id)(utils.String(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", + managerObject.ODataId = (*odata.Id)(pointer.To(fmt.Sprintf("%s/v1.0/%s/directoryObjects/%s", client.BaseClient.Endpoint, tenantId, managerId))) manager := msgraph.User{ From 8737b782dabe951e72a3e086aa7f9f40c8c49951 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 02:35:11 +0100 Subject: [PATCH 41/46] dependencies: updating to v0.20231018.1171511 of github.com/hashicorp/go-azure-sdk --- go.mod | 10 +- go.sum | 24 +- .../sdk/environments/application_ids.go | 3 + .../sdk/environments/constants.go | 3 + .../hashicorp/go-azure-sdk/sdk/odata/query.go | 8 + .../x/crypto/chacha20/chacha_arm64.go | 4 +- .../x/crypto/chacha20/chacha_arm64.s | 4 +- .../x/crypto/chacha20/chacha_noasm.go | 4 +- vendor/golang.org/x/crypto/ed25519/ed25519.go | 71 ---- vendor/golang.org/x/crypto/sha3/sha3.go | 14 +- vendor/golang.org/x/crypto/sha3/sha3_s390x.go | 10 +- vendor/golang.org/x/crypto/sha3/shake.go | 29 +- vendor/golang.org/x/crypto/ssh/certs.go | 38 +- vendor/golang.org/x/crypto/ssh/client_auth.go | 96 +++-- vendor/golang.org/x/crypto/ssh/doc.go | 1 + vendor/golang.org/x/crypto/ssh/handshake.go | 44 +- vendor/golang.org/x/crypto/ssh/keys.go | 376 +++++++++++++++--- vendor/golang.org/x/crypto/ssh/messages.go | 14 + vendor/golang.org/x/crypto/ssh/mux.go | 6 + vendor/golang.org/x/crypto/ssh/server.go | 11 +- vendor/golang.org/x/net/http2/Dockerfile | 51 --- vendor/golang.org/x/net/http2/Makefile | 3 - vendor/golang.org/x/net/http2/server.go | 86 +++- vendor/golang.org/x/net/http2/transport.go | 33 +- vendor/golang.org/x/sys/cpu/cpu_riscv64.go | 2 +- vendor/golang.org/x/sys/cpu/hwcap_linux.go | 4 +- .../sys/internal/unsafeheader/unsafeheader.go | 30 -- vendor/golang.org/x/sys/unix/ptrace_darwin.go | 6 - vendor/golang.org/x/sys/unix/ptrace_ios.go | 6 - vendor/golang.org/x/sys/unix/syscall_aix.go | 2 - .../golang.org/x/sys/unix/syscall_darwin.go | 186 --------- .../x/sys/unix/syscall_darwin_amd64.go | 1 - .../x/sys/unix/syscall_darwin_arm64.go | 1 - .../x/sys/unix/syscall_dragonfly.go | 198 --------- .../golang.org/x/sys/unix/syscall_freebsd.go | 192 --------- vendor/golang.org/x/sys/unix/syscall_linux.go | 115 +----- .../golang.org/x/sys/unix/syscall_netbsd.go | 261 ------------ .../golang.org/x/sys/unix/syscall_openbsd.go | 74 ---- .../golang.org/x/sys/unix/syscall_solaris.go | 18 - .../x/sys/unix/syscall_zos_s390x.go | 1 - vendor/golang.org/x/sys/unix/zerrors_linux.go | 9 + .../x/sys/unix/zerrors_linux_386.go | 2 + .../x/sys/unix/zerrors_linux_amd64.go | 2 + .../x/sys/unix/zerrors_linux_arm.go | 2 + .../x/sys/unix/zerrors_linux_arm64.go | 2 + .../x/sys/unix/zerrors_linux_loong64.go | 4 + .../x/sys/unix/zerrors_linux_mips.go | 2 + .../x/sys/unix/zerrors_linux_mips64.go | 2 + .../x/sys/unix/zerrors_linux_mips64le.go | 2 + .../x/sys/unix/zerrors_linux_mipsle.go | 2 + .../x/sys/unix/zerrors_linux_ppc.go | 2 + .../x/sys/unix/zerrors_linux_ppc64.go | 2 + .../x/sys/unix/zerrors_linux_ppc64le.go | 2 + .../x/sys/unix/zerrors_linux_riscv64.go | 2 + .../x/sys/unix/zerrors_linux_s390x.go | 2 + .../x/sys/unix/zerrors_linux_sparc64.go | 2 + .../golang.org/x/sys/unix/zsyscall_aix_ppc.go | 22 - .../x/sys/unix/zsyscall_aix_ppc64.go | 22 - .../x/sys/unix/zsyscall_darwin_amd64.go | 40 +- .../x/sys/unix/zsyscall_darwin_amd64.s | 149 ------- .../x/sys/unix/zsyscall_darwin_arm64.go | 40 +- .../x/sys/unix/zsyscall_darwin_arm64.s | 149 ------- .../x/sys/unix/zsyscall_dragonfly_amd64.go | 22 - .../x/sys/unix/zsyscall_freebsd_386.go | 22 - .../x/sys/unix/zsyscall_freebsd_amd64.go | 22 - .../x/sys/unix/zsyscall_freebsd_arm.go | 22 - .../x/sys/unix/zsyscall_freebsd_arm64.go | 22 - .../x/sys/unix/zsyscall_freebsd_riscv64.go | 22 - .../x/sys/unix/zsyscall_illumos_amd64.go | 10 +- .../golang.org/x/sys/unix/zsyscall_linux.go | 22 - .../x/sys/unix/zsyscall_netbsd_386.go | 22 - .../x/sys/unix/zsyscall_netbsd_amd64.go | 22 - .../x/sys/unix/zsyscall_netbsd_arm.go | 22 - .../x/sys/unix/zsyscall_netbsd_arm64.go | 22 - .../x/sys/unix/zsyscall_openbsd_386.go | 32 +- .../x/sys/unix/zsyscall_openbsd_amd64.go | 22 - .../x/sys/unix/zsyscall_openbsd_arm.go | 32 +- .../x/sys/unix/zsyscall_openbsd_arm64.go | 32 +- .../x/sys/unix/zsyscall_openbsd_mips64.go | 32 +- .../x/sys/unix/zsyscall_openbsd_ppc64.go | 32 +- .../x/sys/unix/zsyscall_openbsd_riscv64.go | 32 +- .../x/sys/unix/zsyscall_solaris_amd64.go | 256 ++++++------ .../x/sys/unix/zsyscall_zos_s390x.go | 11 - .../x/sys/unix/zsysnum_linux_386.go | 1 + .../x/sys/unix/zsysnum_linux_amd64.go | 1 + .../x/sys/unix/zsysnum_linux_arm.go | 1 + .../x/sys/unix/zsysnum_linux_arm64.go | 1 + .../x/sys/unix/zsysnum_linux_loong64.go | 1 + .../x/sys/unix/zsysnum_linux_mips.go | 1 + .../x/sys/unix/zsysnum_linux_mips64.go | 1 + .../x/sys/unix/zsysnum_linux_mips64le.go | 1 + .../x/sys/unix/zsysnum_linux_mipsle.go | 1 + .../x/sys/unix/zsysnum_linux_ppc.go | 1 + .../x/sys/unix/zsysnum_linux_ppc64.go | 1 + .../x/sys/unix/zsysnum_linux_ppc64le.go | 1 + .../x/sys/unix/zsysnum_linux_riscv64.go | 1 + .../x/sys/unix/zsysnum_linux_s390x.go | 1 + .../x/sys/unix/zsysnum_linux_sparc64.go | 1 + vendor/golang.org/x/sys/unix/ztypes_linux.go | 8 +- .../x/sys/unix/ztypes_linux_riscv64.go | 4 + .../golang.org/x/sys/windows/exec_windows.go | 89 ++++- .../x/sys/windows/security_windows.go | 21 +- .../x/sys/windows/syscall_windows.go | 42 +- .../golang.org/x/sys/windows/types_windows.go | 7 + .../x/sys/windows/zsyscall_windows.go | 28 +- vendor/modules.txt | 16 +- 106 files changed, 1041 insertions(+), 2425 deletions(-) delete mode 100644 vendor/golang.org/x/crypto/ed25519/ed25519.go delete mode 100644 vendor/golang.org/x/net/http2/Dockerfile delete mode 100644 vendor/golang.org/x/net/http2/Makefile delete mode 100644 vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go diff --git a/go.mod b/go.mod index cb12a0f37a..c7a6fd76de 100644 --- a/go.mod +++ b/go.mod @@ -2,8 +2,8 @@ module github.com/hashicorp/terraform-provider-azuread require ( github.com/google/go-cmp v0.5.9 - github.com/hashicorp/go-azure-helpers v0.60.0 - github.com/hashicorp/go-azure-sdk v0.20230911.1163300 + github.com/hashicorp/go-azure-helpers v0.62.0 + github.com/hashicorp/go-azure-sdk v0.20231018.1171511 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/go-uuid v1.0.3 @@ -49,12 +49,12 @@ require ( github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/zclconf/go-cty v1.14.0 // indirect - golang.org/x/crypto v0.13.0 // indirect + golang.org/x/crypto v0.14.0 // indirect golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 // indirect golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.13.0 // indirect + golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.7.0 // indirect - golang.org/x/sys v0.12.0 // indirect + golang.org/x/sys v0.13.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect google.golang.org/grpc v1.57.0 // indirect diff --git a/go.sum b/go.sum index 3f9300384e..0b0418e282 100644 --- a/go.sum +++ b/go.sum @@ -129,11 +129,11 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-azure-helpers v0.55.0/go.mod h1:RQugkG8wEcNIjYmcBLHpuEI/u2mTJwO4r37rR/OKRpo= -github.com/hashicorp/go-azure-helpers v0.60.0 h1:itxb+7DujCy86aLe3E7JZZyJgZ0rn04yAcaUC1VhJXA= -github.com/hashicorp/go-azure-helpers v0.60.0/go.mod h1:BQUQp5udwbJ8pnzl0wByCLVEEyPMAFpJ9vOREiCzObo= +github.com/hashicorp/go-azure-helpers v0.62.0 h1:3Ob1yFAO71Pbdnm14HUI4dGZUaO/Nqmncu5cKMGsDBg= +github.com/hashicorp/go-azure-helpers v0.62.0/go.mod h1:ELmZ65vzHJNTk6ml4jsPD+xq2gZb7t78D35s+XN02Kk= github.com/hashicorp/go-azure-sdk v0.20230331.1143618/go.mod h1:L9JXVUcnL0GjMizCnngYUlMp1lLhDBNgSTvn6Of/5O4= -github.com/hashicorp/go-azure-sdk v0.20230911.1163300 h1:NbSXrPwMtzFQoN+pBfku7y2akKabHvVX/kIQu1d+4TM= -github.com/hashicorp/go-azure-sdk v0.20230911.1163300/go.mod h1:Rk63T4GsVOHb/WohiAX7F0tMEd8MIKV+g4aV0Jv4XEk= +github.com/hashicorp/go-azure-sdk v0.20231018.1171511 h1:n+i2b1vZ5FX/KiIvRgKtMbUAPB2aGxUrAsS0PilCcMo= +github.com/hashicorp/go-azure-sdk v0.20231018.1171511/go.mod h1:3IQjdvuhEckMgdWpvQs4e4VdiiRLIm4z82kO814t/Lw= github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -316,8 +316,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819 h1:EDuYyU/MkFXllv9QF9819VlI9a4tzGuCbhG0ExK9o1U= golang.org/x/exp v0.0.0-20230809150735-7b3493d9a819/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= @@ -354,8 +354,8 @@ golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.13.0 h1:Nvo8UFsZ8X3BhAC9699Z1j7XQ3rsZnUUm7jfBEk1ueY= -golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -400,16 +400,16 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= -golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/vendor/github.com/hashicorp/go-azure-sdk/sdk/environments/application_ids.go b/vendor/github.com/hashicorp/go-azure-sdk/sdk/environments/application_ids.go index e10e3d2e7e..388b85b93c 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/sdk/environments/application_ids.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/sdk/environments/application_ids.go @@ -33,6 +33,7 @@ var PublishedApis = map[string]string{ "AzureIotHubDeviceProvisioning": iotHubDeviceProvisioningAppId, "AzureKeyVault": keyVaultAppId, "AzureKubernetesServiceAadServer": kubernetesServiceAadServerAppId, + "AzureLinuxVirtualMachineSignIn": azureLinuxVmSignIn, "AzureMaps": mapsAppId, "AzureMediaServices": mediaServicesAppId, "AzurePortal": portalAppId, @@ -48,6 +49,7 @@ var PublishedApis = map[string]string{ "AzureSynapseStudio": synapseStudioAppId, "AzureTimeSeriesInsights": timeSeriesInsightsAppId, "AzureVPN": azureVPNAppId, + "AzureWindowsVirtualMachineSignIn": azureWindowsVmSignIn, "Bing": bingAppId, "BotFrameworkDevPortal": botFrameworkDevPortalAppId, "BranchConnectWebService": branchConnectWebServiceAppId, @@ -79,6 +81,7 @@ var PublishedApis = map[string]string{ "Microsoft365DataAtRestEncryption": microsoft365DataAtRestEncryptionAppId, "MicrosoftAzureCli": microsoftAzureCliAppId, "MicrosoftGraph": microsoftGraphAppId, + "MicrosoftIntuneEnrollment": microsoftIntuneEnrollment, "MicrosoftInvoicing": microsoftInvoicingAppId, "MicrosoftOffice": microsoftOfficeAppId, "MicrosoftStorageSync": microsoftStorageSyncAppId, diff --git a/vendor/github.com/hashicorp/go-azure-sdk/sdk/environments/constants.go b/vendor/github.com/hashicorp/go-azure-sdk/sdk/environments/constants.go index a15c4c0444..1459fc7e79 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/sdk/environments/constants.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/sdk/environments/constants.go @@ -13,6 +13,8 @@ const azureAdIdentityGovernanceInsightsAppId = "58c746b0-a0b0-4647-a8f6-12dde598 const azureAdIntegratedAppAppId = "af47b99c-8954-4b45-ab68-8121157418ef" const azureAdNotificationAppId = "fc03f97a-9db0-4627-a216-ec98ce54e018" const azureDevOpsAppId = "499b84ac-1321-427f-aa17-267ca6975798" +const azureLinuxVmSignIn = "ce6ff14a-7fdc-4685-bbe0-f6afdfcfa8e0" +const azureWindowsVmSignIn = "372140e0-b3b7-4226-8ef9-d57986796201" const azureServiceManagementAppId = "797f4846-ba00-4fd7-ba43-dac1f8f63013" const azureVPNAppId = "41b23e61-6c1e-4545-b367-cd054e0ed4b4" const batchAppId = "ddbf3205-c6bd-46ae-8127-60eb93363864" @@ -62,6 +64,7 @@ const microsoft365DataAtRestEncryptionAppId = "c066d759-24ae-40e7-a56f-027002b5d const microsoftAzureCliAppId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46" const microsoftGraphAppId = "00000003-0000-0000-c000-000000000000" const microsoftInvoicingAppId = "b6b84568-6c01-4981-a80f-09da9a20bbed" +const microsoftIntuneEnrollment = "d4ebce55-015a-49b5-a083-c84d1797ae8c" const microsoftOfficeAppId = "d3590ed6-52b3-4102-aeff-aad2292ab01c" const microsoftStorageSyncAppId = "9469b9f5-6722-4481-a2b2-14ed560b706f" const microsoftTeamsAppId = "1fec8e78-bce4-4aaf-ab1b-5451cc387264" diff --git a/vendor/github.com/hashicorp/go-azure-sdk/sdk/odata/query.go b/vendor/github.com/hashicorp/go-azure-sdk/sdk/odata/query.go index f8083f4cd9..6428d3520c 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/sdk/odata/query.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/sdk/odata/query.go @@ -190,3 +190,11 @@ func (o OrderBy) String() (val string) { } return } + +// EscapeSingleQuote replaces all occurrences of single quote, with 2 single quotes. +// For requests that use single quotes, if any parameter values also contain single quotes, +// those must be double escaped; otherwise, the request will fail due to invalid syntax. +// https://docs.microsoft.com/en-us/graph/query-parameters#escaping-single-quotes +func EscapeSingleQuote(qparam string) string { + return strings.ReplaceAll(qparam, `'`, `''`) +} diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go index 94c71ac1ac..5dfacbb983 100644 --- a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go +++ b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.11 && gc && !purego -// +build go1.11,gc,!purego +//go:build gc && !purego +// +build gc,!purego package chacha20 diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s index 63cae9e6f0..f1f66230d1 100644 --- a/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s +++ b/vendor/golang.org/x/crypto/chacha20/chacha_arm64.s @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build go1.11 && gc && !purego -// +build go1.11,gc,!purego +//go:build gc && !purego +// +build gc,!purego #include "textflag.h" diff --git a/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go b/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go index 025b49897e..02ff3d05e9 100644 --- a/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go +++ b/vendor/golang.org/x/crypto/chacha20/chacha_noasm.go @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:build (!arm64 && !s390x && !ppc64le) || (arm64 && !go1.11) || !gc || purego -// +build !arm64,!s390x,!ppc64le arm64,!go1.11 !gc purego +//go:build (!arm64 && !s390x && !ppc64le) || !gc || purego +// +build !arm64,!s390x,!ppc64le !gc purego package chacha20 diff --git a/vendor/golang.org/x/crypto/ed25519/ed25519.go b/vendor/golang.org/x/crypto/ed25519/ed25519.go deleted file mode 100644 index a7828345fc..0000000000 --- a/vendor/golang.org/x/crypto/ed25519/ed25519.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package ed25519 implements the Ed25519 signature algorithm. See -// https://ed25519.cr.yp.to/. -// -// These functions are also compatible with the “Ed25519” function defined in -// RFC 8032. However, unlike RFC 8032's formulation, this package's private key -// representation includes a public key suffix to make multiple signing -// operations with the same key more efficient. This package refers to the RFC -// 8032 private key as the “seed”. -// -// Beginning with Go 1.13, the functionality of this package was moved to the -// standard library as crypto/ed25519. This package only acts as a compatibility -// wrapper. -package ed25519 - -import ( - "crypto/ed25519" - "io" -) - -const ( - // PublicKeySize is the size, in bytes, of public keys as used in this package. - PublicKeySize = 32 - // PrivateKeySize is the size, in bytes, of private keys as used in this package. - PrivateKeySize = 64 - // SignatureSize is the size, in bytes, of signatures generated and verified by this package. - SignatureSize = 64 - // SeedSize is the size, in bytes, of private key seeds. These are the private key representations used by RFC 8032. - SeedSize = 32 -) - -// PublicKey is the type of Ed25519 public keys. -// -// This type is an alias for crypto/ed25519's PublicKey type. -// See the crypto/ed25519 package for the methods on this type. -type PublicKey = ed25519.PublicKey - -// PrivateKey is the type of Ed25519 private keys. It implements crypto.Signer. -// -// This type is an alias for crypto/ed25519's PrivateKey type. -// See the crypto/ed25519 package for the methods on this type. -type PrivateKey = ed25519.PrivateKey - -// GenerateKey generates a public/private key pair using entropy from rand. -// If rand is nil, crypto/rand.Reader will be used. -func GenerateKey(rand io.Reader) (PublicKey, PrivateKey, error) { - return ed25519.GenerateKey(rand) -} - -// NewKeyFromSeed calculates a private key from a seed. It will panic if -// len(seed) is not SeedSize. This function is provided for interoperability -// with RFC 8032. RFC 8032's private keys correspond to seeds in this -// package. -func NewKeyFromSeed(seed []byte) PrivateKey { - return ed25519.NewKeyFromSeed(seed) -} - -// Sign signs the message with privateKey and returns a signature. It will -// panic if len(privateKey) is not PrivateKeySize. -func Sign(privateKey PrivateKey, message []byte) []byte { - return ed25519.Sign(privateKey, message) -} - -// Verify reports whether sig is a valid signature of message by publicKey. It -// will panic if len(publicKey) is not PublicKeySize. -func Verify(publicKey PublicKey, message, sig []byte) bool { - return ed25519.Verify(publicKey, message, sig) -} diff --git a/vendor/golang.org/x/crypto/sha3/sha3.go b/vendor/golang.org/x/crypto/sha3/sha3.go index fa182beb40..4884d172a4 100644 --- a/vendor/golang.org/x/crypto/sha3/sha3.go +++ b/vendor/golang.org/x/crypto/sha3/sha3.go @@ -121,11 +121,11 @@ func (d *state) padAndPermute(dsbyte byte) { copyOut(d, d.buf) } -// Write absorbs more data into the hash's state. It produces an error -// if more data is written to the ShakeHash after writing +// Write absorbs more data into the hash's state. It panics if any +// output has already been read. func (d *state) Write(p []byte) (written int, err error) { if d.state != spongeAbsorbing { - panic("sha3: write to sponge after read") + panic("sha3: Write after Read") } if d.buf == nil { d.buf = d.storage.asBytes()[:0] @@ -182,12 +182,16 @@ func (d *state) Read(out []byte) (n int, err error) { } // Sum applies padding to the hash state and then squeezes out the desired -// number of output bytes. +// number of output bytes. It panics if any output has already been read. func (d *state) Sum(in []byte) []byte { + if d.state != spongeAbsorbing { + panic("sha3: Sum after Read") + } + // Make a copy of the original hash so that caller can keep writing // and summing. dup := d.clone() - hash := make([]byte, dup.outputLen) + hash := make([]byte, dup.outputLen, 64) // explicit cap to allow stack allocation dup.Read(hash) return append(in, hash...) } diff --git a/vendor/golang.org/x/crypto/sha3/sha3_s390x.go b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go index 63a3edb4ce..ec26f147ff 100644 --- a/vendor/golang.org/x/crypto/sha3/sha3_s390x.go +++ b/vendor/golang.org/x/crypto/sha3/sha3_s390x.go @@ -49,7 +49,7 @@ type asmState struct { buf []byte // care must be taken to ensure cap(buf) is a multiple of rate rate int // equivalent to block size storage [3072]byte // underlying storage for buf - outputLen int // output length if fixed, 0 if not + outputLen int // output length for full security function code // KIMD/KLMD function code state spongeDirection // whether the sponge is absorbing or squeezing } @@ -72,8 +72,10 @@ func newAsmState(function code) *asmState { s.outputLen = 64 case shake_128: s.rate = 168 + s.outputLen = 32 case shake_256: s.rate = 136 + s.outputLen = 64 default: panic("sha3: unrecognized function code") } @@ -108,7 +110,7 @@ func (s *asmState) resetBuf() { // It never returns an error. func (s *asmState) Write(b []byte) (int, error) { if s.state != spongeAbsorbing { - panic("sha3: write to sponge after read") + panic("sha3: Write after Read") } length := len(b) for len(b) > 0 { @@ -192,8 +194,8 @@ func (s *asmState) Read(out []byte) (n int, err error) { // Sum appends the current hash to b and returns the resulting slice. // It does not change the underlying hash state. func (s *asmState) Sum(b []byte) []byte { - if s.outputLen == 0 { - panic("sha3: cannot call Sum on SHAKE functions") + if s.state != spongeAbsorbing { + panic("sha3: Sum after Read") } // Copy the state to preserve the original. diff --git a/vendor/golang.org/x/crypto/sha3/shake.go b/vendor/golang.org/x/crypto/sha3/shake.go index d7be2954ab..bb69984027 100644 --- a/vendor/golang.org/x/crypto/sha3/shake.go +++ b/vendor/golang.org/x/crypto/sha3/shake.go @@ -17,26 +17,25 @@ package sha3 import ( "encoding/binary" + "hash" "io" ) -// ShakeHash defines the interface to hash functions that -// support arbitrary-length output. +// ShakeHash defines the interface to hash functions that support +// arbitrary-length output. When used as a plain [hash.Hash], it +// produces minimum-length outputs that provide full-strength generic +// security. type ShakeHash interface { - // Write absorbs more data into the hash's state. It panics if input is - // written to it after output has been read from it. - io.Writer + hash.Hash // Read reads more output from the hash; reading affects the hash's // state. (ShakeHash.Read is thus very different from Hash.Sum) - // It never returns an error. + // It never returns an error, but subsequent calls to Write or Sum + // will panic. io.Reader // Clone returns a copy of the ShakeHash in its current state. Clone() ShakeHash - - // Reset resets the ShakeHash to its initial state. - Reset() } // cSHAKE specific context @@ -81,8 +80,8 @@ func leftEncode(value uint64) []byte { return b[i-1:] } -func newCShake(N, S []byte, rate int, dsbyte byte) ShakeHash { - c := cshakeState{state: &state{rate: rate, dsbyte: dsbyte}} +func newCShake(N, S []byte, rate, outputLen int, dsbyte byte) ShakeHash { + c := cshakeState{state: &state{rate: rate, outputLen: outputLen, dsbyte: dsbyte}} // leftEncode returns max 9 bytes c.initBlock = make([]byte, 0, 9*2+len(N)+len(S)) @@ -119,7 +118,7 @@ func NewShake128() ShakeHash { if h := newShake128Asm(); h != nil { return h } - return &state{rate: rate128, dsbyte: dsbyteShake} + return &state{rate: rate128, outputLen: 32, dsbyte: dsbyteShake} } // NewShake256 creates a new SHAKE256 variable-output-length ShakeHash. @@ -129,7 +128,7 @@ func NewShake256() ShakeHash { if h := newShake256Asm(); h != nil { return h } - return &state{rate: rate256, dsbyte: dsbyteShake} + return &state{rate: rate256, outputLen: 64, dsbyte: dsbyteShake} } // NewCShake128 creates a new instance of cSHAKE128 variable-output-length ShakeHash, @@ -142,7 +141,7 @@ func NewCShake128(N, S []byte) ShakeHash { if len(N) == 0 && len(S) == 0 { return NewShake128() } - return newCShake(N, S, rate128, dsbyteCShake) + return newCShake(N, S, rate128, 32, dsbyteCShake) } // NewCShake256 creates a new instance of cSHAKE256 variable-output-length ShakeHash, @@ -155,7 +154,7 @@ func NewCShake256(N, S []byte) ShakeHash { if len(N) == 0 && len(S) == 0 { return NewShake256() } - return newCShake(N, S, rate256, dsbyteCShake) + return newCShake(N, S, rate256, 64, dsbyteCShake) } // ShakeSum128 writes an arbitrary-length digest of data into hash. diff --git a/vendor/golang.org/x/crypto/ssh/certs.go b/vendor/golang.org/x/crypto/ssh/certs.go index fc04d03e19..27d0e14aa9 100644 --- a/vendor/golang.org/x/crypto/ssh/certs.go +++ b/vendor/golang.org/x/crypto/ssh/certs.go @@ -16,8 +16,9 @@ import ( // Certificate algorithm names from [PROTOCOL.certkeys]. These values can appear // in Certificate.Type, PublicKey.Type, and ClientConfig.HostKeyAlgorithms. -// Unlike key algorithm names, these are not passed to AlgorithmSigner and don't -// appear in the Signature.Format field. +// Unlike key algorithm names, these are not passed to AlgorithmSigner nor +// returned by MultiAlgorithmSigner and don't appear in the Signature.Format +// field. const ( CertAlgoRSAv01 = "ssh-rsa-cert-v01@openssh.com" CertAlgoDSAv01 = "ssh-dss-cert-v01@openssh.com" @@ -255,10 +256,17 @@ func NewCertSigner(cert *Certificate, signer Signer) (Signer, error) { return nil, errors.New("ssh: signer and cert have different public key") } - if algorithmSigner, ok := signer.(AlgorithmSigner); ok { + switch s := signer.(type) { + case MultiAlgorithmSigner: + return &multiAlgorithmSigner{ + AlgorithmSigner: &algorithmOpenSSHCertSigner{ + &openSSHCertSigner{cert, signer}, s}, + supportedAlgorithms: s.Algorithms(), + }, nil + case AlgorithmSigner: return &algorithmOpenSSHCertSigner{ - &openSSHCertSigner{cert, signer}, algorithmSigner}, nil - } else { + &openSSHCertSigner{cert, signer}, s}, nil + default: return &openSSHCertSigner{cert, signer}, nil } } @@ -432,7 +440,9 @@ func (c *CertChecker) CheckCert(principal string, cert *Certificate) error { } // SignCert signs the certificate with an authority, setting the Nonce, -// SignatureKey, and Signature fields. +// SignatureKey, and Signature fields. If the authority implements the +// MultiAlgorithmSigner interface the first algorithm in the list is used. This +// is useful if you want to sign with a specific algorithm. func (c *Certificate) SignCert(rand io.Reader, authority Signer) error { c.Nonce = make([]byte, 32) if _, err := io.ReadFull(rand, c.Nonce); err != nil { @@ -440,8 +450,20 @@ func (c *Certificate) SignCert(rand io.Reader, authority Signer) error { } c.SignatureKey = authority.PublicKey() - // Default to KeyAlgoRSASHA512 for ssh-rsa signers. - if v, ok := authority.(AlgorithmSigner); ok && v.PublicKey().Type() == KeyAlgoRSA { + if v, ok := authority.(MultiAlgorithmSigner); ok { + if len(v.Algorithms()) == 0 { + return errors.New("the provided authority has no signature algorithm") + } + // Use the first algorithm in the list. + sig, err := v.SignWithAlgorithm(rand, c.bytesForSigning(), v.Algorithms()[0]) + if err != nil { + return err + } + c.Signature = sig + return nil + } else if v, ok := authority.(AlgorithmSigner); ok && v.PublicKey().Type() == KeyAlgoRSA { + // Default to KeyAlgoRSASHA512 for ssh-rsa signers. + // TODO: consider using KeyAlgoRSASHA256 as default. sig, err := v.SignWithAlgorithm(rand, c.bytesForSigning(), KeyAlgoRSASHA512) if err != nil { return err diff --git a/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go index 409b5ea1d4..5c3bc25723 100644 --- a/vendor/golang.org/x/crypto/ssh/client_auth.go +++ b/vendor/golang.org/x/crypto/ssh/client_auth.go @@ -71,7 +71,9 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { for auth := AuthMethod(new(noneAuth)); auth != nil; { ok, methods, err := auth.auth(sessionID, config.User, c.transport, config.Rand, extensions) if err != nil { - return err + // We return the error later if there is no other method left to + // try. + ok = authFailure } if ok == authSuccess { // success @@ -101,6 +103,12 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error { } } } + + if auth == nil && err != nil { + // We have an error and there are no other authentication methods to + // try, so we return it. + return err + } } return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", tried) } @@ -217,21 +225,45 @@ func (cb publicKeyCallback) method() string { return "publickey" } -func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (as AlgorithmSigner, algo string) { +func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (MultiAlgorithmSigner, string, error) { + var as MultiAlgorithmSigner keyFormat := signer.PublicKey().Type() - // Like in sendKexInit, if the public key implements AlgorithmSigner we - // assume it supports all algorithms, otherwise only the key format one. - as, ok := signer.(AlgorithmSigner) - if !ok { - return algorithmSignerWrapper{signer}, keyFormat + // If the signer implements MultiAlgorithmSigner we use the algorithms it + // support, if it implements AlgorithmSigner we assume it supports all + // algorithms, otherwise only the key format one. + switch s := signer.(type) { + case MultiAlgorithmSigner: + as = s + case AlgorithmSigner: + as = &multiAlgorithmSigner{ + AlgorithmSigner: s, + supportedAlgorithms: algorithmsForKeyFormat(underlyingAlgo(keyFormat)), + } + default: + as = &multiAlgorithmSigner{ + AlgorithmSigner: algorithmSignerWrapper{signer}, + supportedAlgorithms: []string{underlyingAlgo(keyFormat)}, + } + } + + getFallbackAlgo := func() (string, error) { + // Fallback to use if there is no "server-sig-algs" extension or a + // common algorithm cannot be found. We use the public key format if the + // MultiAlgorithmSigner supports it, otherwise we return an error. + if !contains(as.Algorithms(), underlyingAlgo(keyFormat)) { + return "", fmt.Errorf("ssh: no common public key signature algorithm, server only supports %q for key type %q, signer only supports %v", + underlyingAlgo(keyFormat), keyFormat, as.Algorithms()) + } + return keyFormat, nil } extPayload, ok := extensions["server-sig-algs"] if !ok { - // If there is no "server-sig-algs" extension, fall back to the key - // format algorithm. - return as, keyFormat + // If there is no "server-sig-algs" extension use the fallback + // algorithm. + algo, err := getFallbackAlgo() + return as, algo, err } // The server-sig-algs extension only carries underlying signature @@ -245,15 +277,22 @@ func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (as Alg } } - keyAlgos := algorithmsForKeyFormat(keyFormat) + // Filter algorithms based on those supported by MultiAlgorithmSigner. + var keyAlgos []string + for _, algo := range algorithmsForKeyFormat(keyFormat) { + if contains(as.Algorithms(), underlyingAlgo(algo)) { + keyAlgos = append(keyAlgos, algo) + } + } + algo, err := findCommon("public key signature algorithm", keyAlgos, serverAlgos) if err != nil { - // If there is no overlap, try the key anyway with the key format - // algorithm, to support servers that fail to list all supported - // algorithms. - return as, keyFormat + // If there is no overlap, return the fallback algorithm to support + // servers that fail to list all supported algorithms. + algo, err := getFallbackAlgo() + return as, algo, err } - return as, algo + return as, algo, nil } func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand io.Reader, extensions map[string][]byte) (authResult, []string, error) { @@ -267,10 +306,17 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand return authFailure, nil, err } var methods []string + var errSigAlgo error for _, signer := range signers { pub := signer.PublicKey() - as, algo := pickSignatureAlgorithm(signer, extensions) - + as, algo, err := pickSignatureAlgorithm(signer, extensions) + if err != nil && errSigAlgo == nil { + // If we cannot negotiate a signature algorithm store the first + // error so we can return it to provide a more meaningful message if + // no other signers work. + errSigAlgo = err + continue + } ok, err := validateKey(pub, algo, user, c) if err != nil { return authFailure, nil, err @@ -317,22 +363,12 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand // contain the "publickey" method, do not attempt to authenticate with any // other keys. According to RFC 4252 Section 7, the latter can occur when // additional authentication methods are required. - if success == authSuccess || !containsMethod(methods, cb.method()) { + if success == authSuccess || !contains(methods, cb.method()) { return success, methods, err } } - return authFailure, methods, nil -} - -func containsMethod(methods []string, method string) bool { - for _, m := range methods { - if m == method { - return true - } - } - - return false + return authFailure, methods, errSigAlgo } // validateKey validates the key provided is acceptable to the server. diff --git a/vendor/golang.org/x/crypto/ssh/doc.go b/vendor/golang.org/x/crypto/ssh/doc.go index f6bff60dc7..edbe63340d 100644 --- a/vendor/golang.org/x/crypto/ssh/doc.go +++ b/vendor/golang.org/x/crypto/ssh/doc.go @@ -13,6 +13,7 @@ others. References: + [PROTOCOL]: https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL?rev=HEAD [PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD [SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1 diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go index 07a1843e0a..70a7369ff9 100644 --- a/vendor/golang.org/x/crypto/ssh/handshake.go +++ b/vendor/golang.org/x/crypto/ssh/handshake.go @@ -461,19 +461,24 @@ func (t *handshakeTransport) sendKexInit() error { isServer := len(t.hostKeys) > 0 if isServer { for _, k := range t.hostKeys { - // If k is an AlgorithmSigner, presume it supports all signature algorithms - // associated with the key format. (Ideally AlgorithmSigner would have a - // method to advertise supported algorithms, but it doesn't. This means that - // adding support for a new algorithm is a breaking change, as we will - // immediately negotiate it even if existing implementations don't support - // it. If that ever happens, we'll have to figure something out.) - // If k is not an AlgorithmSigner, we can only assume it only supports the - // algorithms that matches the key format. (This means that Sign can't pick - // a different default.) + // If k is a MultiAlgorithmSigner, we restrict the signature + // algorithms. If k is a AlgorithmSigner, presume it supports all + // signature algorithms associated with the key format. If k is not + // an AlgorithmSigner, we can only assume it only supports the + // algorithms that matches the key format. (This means that Sign + // can't pick a different default). keyFormat := k.PublicKey().Type() - if _, ok := k.(AlgorithmSigner); ok { + + switch s := k.(type) { + case MultiAlgorithmSigner: + for _, algo := range algorithmsForKeyFormat(keyFormat) { + if contains(s.Algorithms(), underlyingAlgo(algo)) { + msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algo) + } + } + case AlgorithmSigner: msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algorithmsForKeyFormat(keyFormat)...) - } else { + default: msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, keyFormat) } } @@ -642,16 +647,20 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error { // On the server side, after the first SSH_MSG_NEWKEYS, send a SSH_MSG_EXT_INFO // message with the server-sig-algs extension if the client supports it. See - // RFC 8308, Sections 2.4 and 3.1. + // RFC 8308, Sections 2.4 and 3.1, and [PROTOCOL], Section 1.9. if !isClient && firstKeyExchange && contains(clientInit.KexAlgos, "ext-info-c") { extInfo := &extInfoMsg{ - NumExtensions: 1, - Payload: make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)), + NumExtensions: 2, + Payload: make([]byte, 0, 4+15+4+len(supportedPubKeyAuthAlgosList)+4+16+4+1), } extInfo.Payload = appendInt(extInfo.Payload, len("server-sig-algs")) extInfo.Payload = append(extInfo.Payload, "server-sig-algs"...) extInfo.Payload = appendInt(extInfo.Payload, len(supportedPubKeyAuthAlgosList)) extInfo.Payload = append(extInfo.Payload, supportedPubKeyAuthAlgosList...) + extInfo.Payload = appendInt(extInfo.Payload, len("ping@openssh.com")) + extInfo.Payload = append(extInfo.Payload, "ping@openssh.com"...) + extInfo.Payload = appendInt(extInfo.Payload, 1) + extInfo.Payload = append(extInfo.Payload, "0"...) if err := t.conn.writePacket(Marshal(extInfo)); err != nil { return err } @@ -685,9 +694,16 @@ func (a algorithmSignerWrapper) SignWithAlgorithm(rand io.Reader, data []byte, a func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner { for _, k := range hostKeys { + if s, ok := k.(MultiAlgorithmSigner); ok { + if !contains(s.Algorithms(), underlyingAlgo(algo)) { + continue + } + } + if algo == k.PublicKey().Type() { return algorithmSignerWrapper{k} } + k, ok := k.(AlgorithmSigner) if !ok { continue diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go index dac8ee7244..ef1bad731b 100644 --- a/vendor/golang.org/x/crypto/ssh/keys.go +++ b/vendor/golang.org/x/crypto/ssh/keys.go @@ -11,13 +11,16 @@ import ( "crypto/cipher" "crypto/dsa" "crypto/ecdsa" + "crypto/ed25519" "crypto/elliptic" "crypto/md5" + "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/asn1" "encoding/base64" + "encoding/binary" "encoding/hex" "encoding/pem" "errors" @@ -26,7 +29,6 @@ import ( "math/big" "strings" - "golang.org/x/crypto/ed25519" "golang.org/x/crypto/ssh/internal/bcrypt_pbkdf" ) @@ -295,6 +297,18 @@ func MarshalAuthorizedKey(key PublicKey) []byte { return b.Bytes() } +// MarshalPrivateKey returns a PEM block with the private key serialized in the +// OpenSSH format. +func MarshalPrivateKey(key crypto.PrivateKey, comment string) (*pem.Block, error) { + return marshalOpenSSHPrivateKey(key, comment, unencryptedOpenSSHMarshaler) +} + +// MarshalPrivateKeyWithPassphrase returns a PEM block holding the encrypted +// private key serialized in the OpenSSH format. +func MarshalPrivateKeyWithPassphrase(key crypto.PrivateKey, comment string, passphrase []byte) (*pem.Block, error) { + return marshalOpenSSHPrivateKey(key, comment, passphraseProtectedOpenSSHMarshaler(passphrase)) +} + // PublicKey represents a public key using an unspecified algorithm. // // Some PublicKeys provided by this package also implement CryptoPublicKey. @@ -321,7 +335,7 @@ type CryptoPublicKey interface { // A Signer can create signatures that verify against a public key. // -// Some Signers provided by this package also implement AlgorithmSigner. +// Some Signers provided by this package also implement MultiAlgorithmSigner. type Signer interface { // PublicKey returns the associated PublicKey. PublicKey() PublicKey @@ -336,9 +350,9 @@ type Signer interface { // An AlgorithmSigner is a Signer that also supports specifying an algorithm to // use for signing. // -// An AlgorithmSigner can't advertise the algorithms it supports, so it should -// be prepared to be invoked with every algorithm supported by the public key -// format. +// An AlgorithmSigner can't advertise the algorithms it supports, unless it also +// implements MultiAlgorithmSigner, so it should be prepared to be invoked with +// every algorithm supported by the public key format. type AlgorithmSigner interface { Signer @@ -349,6 +363,75 @@ type AlgorithmSigner interface { SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) } +// MultiAlgorithmSigner is an AlgorithmSigner that also reports the algorithms +// supported by that signer. +type MultiAlgorithmSigner interface { + AlgorithmSigner + + // Algorithms returns the available algorithms in preference order. The list + // must not be empty, and it must not include certificate types. + Algorithms() []string +} + +// NewSignerWithAlgorithms returns a signer restricted to the specified +// algorithms. The algorithms must be set in preference order. The list must not +// be empty, and it must not include certificate types. An error is returned if +// the specified algorithms are incompatible with the public key type. +func NewSignerWithAlgorithms(signer AlgorithmSigner, algorithms []string) (MultiAlgorithmSigner, error) { + if len(algorithms) == 0 { + return nil, errors.New("ssh: please specify at least one valid signing algorithm") + } + var signerAlgos []string + supportedAlgos := algorithmsForKeyFormat(underlyingAlgo(signer.PublicKey().Type())) + if s, ok := signer.(*multiAlgorithmSigner); ok { + signerAlgos = s.Algorithms() + } else { + signerAlgos = supportedAlgos + } + + for _, algo := range algorithms { + if !contains(supportedAlgos, algo) { + return nil, fmt.Errorf("ssh: algorithm %q is not supported for key type %q", + algo, signer.PublicKey().Type()) + } + if !contains(signerAlgos, algo) { + return nil, fmt.Errorf("ssh: algorithm %q is restricted for the provided signer", algo) + } + } + return &multiAlgorithmSigner{ + AlgorithmSigner: signer, + supportedAlgorithms: algorithms, + }, nil +} + +type multiAlgorithmSigner struct { + AlgorithmSigner + supportedAlgorithms []string +} + +func (s *multiAlgorithmSigner) Algorithms() []string { + return s.supportedAlgorithms +} + +func (s *multiAlgorithmSigner) isAlgorithmSupported(algorithm string) bool { + if algorithm == "" { + algorithm = underlyingAlgo(s.PublicKey().Type()) + } + for _, algo := range s.supportedAlgorithms { + if algorithm == algo { + return true + } + } + return false +} + +func (s *multiAlgorithmSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) { + if !s.isAlgorithmSupported(algorithm) { + return nil, fmt.Errorf("ssh: algorithm %q is not supported: %v", algorithm, s.supportedAlgorithms) + } + return s.AlgorithmSigner.SignWithAlgorithm(rand, data, algorithm) +} + type rsaPublicKey rsa.PublicKey func (r *rsaPublicKey) Type() string { @@ -512,6 +595,10 @@ func (k *dsaPrivateKey) Sign(rand io.Reader, data []byte) (*Signature, error) { return k.SignWithAlgorithm(rand, data, k.PublicKey().Type()) } +func (k *dsaPrivateKey) Algorithms() []string { + return []string{k.PublicKey().Type()} +} + func (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) { if algorithm != "" && algorithm != k.PublicKey().Type() { return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm) @@ -961,13 +1048,16 @@ func (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) { return s.SignWithAlgorithm(rand, data, s.pubKey.Type()) } +func (s *wrappedSigner) Algorithms() []string { + return algorithmsForKeyFormat(s.pubKey.Type()) +} + func (s *wrappedSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm string) (*Signature, error) { if algorithm == "" { algorithm = s.pubKey.Type() } - supportedAlgos := algorithmsForKeyFormat(s.pubKey.Type()) - if !contains(supportedAlgos, algorithm) { + if !contains(s.Algorithms(), algorithm) { return nil, fmt.Errorf("ssh: unsupported signature algorithm %q for key format %q", algorithm, s.pubKey.Type()) } @@ -1241,28 +1331,106 @@ func passphraseProtectedOpenSSHKey(passphrase []byte) openSSHDecryptFunc { } } +func unencryptedOpenSSHMarshaler(privKeyBlock []byte) ([]byte, string, string, string, error) { + key := generateOpenSSHPadding(privKeyBlock, 8) + return key, "none", "none", "", nil +} + +func passphraseProtectedOpenSSHMarshaler(passphrase []byte) openSSHEncryptFunc { + return func(privKeyBlock []byte) ([]byte, string, string, string, error) { + salt := make([]byte, 16) + if _, err := rand.Read(salt); err != nil { + return nil, "", "", "", err + } + + opts := struct { + Salt []byte + Rounds uint32 + }{salt, 16} + + // Derive key to encrypt the private key block. + k, err := bcrypt_pbkdf.Key(passphrase, salt, int(opts.Rounds), 32+aes.BlockSize) + if err != nil { + return nil, "", "", "", err + } + + // Add padding matching the block size of AES. + keyBlock := generateOpenSSHPadding(privKeyBlock, aes.BlockSize) + + // Encrypt the private key using the derived secret. + + dst := make([]byte, len(keyBlock)) + key, iv := k[:32], k[32:] + block, err := aes.NewCipher(key) + if err != nil { + return nil, "", "", "", err + } + + stream := cipher.NewCTR(block, iv) + stream.XORKeyStream(dst, keyBlock) + + return dst, "aes256-ctr", "bcrypt", string(Marshal(opts)), nil + } +} + +const privateKeyAuthMagic = "openssh-key-v1\x00" + type openSSHDecryptFunc func(CipherName, KdfName, KdfOpts string, PrivKeyBlock []byte) ([]byte, error) +type openSSHEncryptFunc func(PrivKeyBlock []byte) (ProtectedKeyBlock []byte, cipherName, kdfName, kdfOptions string, err error) + +type openSSHEncryptedPrivateKey struct { + CipherName string + KdfName string + KdfOpts string + NumKeys uint32 + PubKey []byte + PrivKeyBlock []byte +} + +type openSSHPrivateKey struct { + Check1 uint32 + Check2 uint32 + Keytype string + Rest []byte `ssh:"rest"` +} + +type openSSHRSAPrivateKey struct { + N *big.Int + E *big.Int + D *big.Int + Iqmp *big.Int + P *big.Int + Q *big.Int + Comment string + Pad []byte `ssh:"rest"` +} + +type openSSHEd25519PrivateKey struct { + Pub []byte + Priv []byte + Comment string + Pad []byte `ssh:"rest"` +} + +type openSSHECDSAPrivateKey struct { + Curve string + Pub []byte + D *big.Int + Comment string + Pad []byte `ssh:"rest"` +} // parseOpenSSHPrivateKey parses an OpenSSH private key, using the decrypt // function to unwrap the encrypted portion. unencryptedOpenSSHKey can be used // as the decrypt function to parse an unencrypted private key. See // https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.key. func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.PrivateKey, error) { - const magic = "openssh-key-v1\x00" - if len(key) < len(magic) || string(key[:len(magic)]) != magic { + if len(key) < len(privateKeyAuthMagic) || string(key[:len(privateKeyAuthMagic)]) != privateKeyAuthMagic { return nil, errors.New("ssh: invalid openssh private key format") } - remaining := key[len(magic):] - - var w struct { - CipherName string - KdfName string - KdfOpts string - NumKeys uint32 - PubKey []byte - PrivKeyBlock []byte - } + remaining := key[len(privateKeyAuthMagic):] + var w openSSHEncryptedPrivateKey if err := Unmarshal(remaining, &w); err != nil { return nil, err } @@ -1284,13 +1452,7 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv return nil, err } - pk1 := struct { - Check1 uint32 - Check2 uint32 - Keytype string - Rest []byte `ssh:"rest"` - }{} - + var pk1 openSSHPrivateKey if err := Unmarshal(privKeyBlock, &pk1); err != nil || pk1.Check1 != pk1.Check2 { if w.CipherName != "none" { return nil, x509.IncorrectPasswordError @@ -1300,18 +1462,7 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv switch pk1.Keytype { case KeyAlgoRSA: - // https://github.com/openssh/openssh-portable/blob/master/sshkey.c#L2760-L2773 - key := struct { - N *big.Int - E *big.Int - D *big.Int - Iqmp *big.Int - P *big.Int - Q *big.Int - Comment string - Pad []byte `ssh:"rest"` - }{} - + var key openSSHRSAPrivateKey if err := Unmarshal(pk1.Rest, &key); err != nil { return nil, err } @@ -1337,13 +1488,7 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv return pk, nil case KeyAlgoED25519: - key := struct { - Pub []byte - Priv []byte - Comment string - Pad []byte `ssh:"rest"` - }{} - + var key openSSHEd25519PrivateKey if err := Unmarshal(pk1.Rest, &key); err != nil { return nil, err } @@ -1360,14 +1505,7 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv copy(pk, key.Priv) return &pk, nil case KeyAlgoECDSA256, KeyAlgoECDSA384, KeyAlgoECDSA521: - key := struct { - Curve string - Pub []byte - D *big.Int - Comment string - Pad []byte `ssh:"rest"` - }{} - + var key openSSHECDSAPrivateKey if err := Unmarshal(pk1.Rest, &key); err != nil { return nil, err } @@ -1415,6 +1553,131 @@ func parseOpenSSHPrivateKey(key []byte, decrypt openSSHDecryptFunc) (crypto.Priv } } +func marshalOpenSSHPrivateKey(key crypto.PrivateKey, comment string, encrypt openSSHEncryptFunc) (*pem.Block, error) { + var w openSSHEncryptedPrivateKey + var pk1 openSSHPrivateKey + + // Random check bytes. + var check uint32 + if err := binary.Read(rand.Reader, binary.BigEndian, &check); err != nil { + return nil, err + } + + pk1.Check1 = check + pk1.Check2 = check + w.NumKeys = 1 + + // Use a []byte directly on ed25519 keys. + if k, ok := key.(*ed25519.PrivateKey); ok { + key = *k + } + + switch k := key.(type) { + case *rsa.PrivateKey: + E := new(big.Int).SetInt64(int64(k.PublicKey.E)) + // Marshal public key: + // E and N are in reversed order in the public and private key. + pubKey := struct { + KeyType string + E *big.Int + N *big.Int + }{ + KeyAlgoRSA, + E, k.PublicKey.N, + } + w.PubKey = Marshal(pubKey) + + // Marshal private key. + key := openSSHRSAPrivateKey{ + N: k.PublicKey.N, + E: E, + D: k.D, + Iqmp: k.Precomputed.Qinv, + P: k.Primes[0], + Q: k.Primes[1], + Comment: comment, + } + pk1.Keytype = KeyAlgoRSA + pk1.Rest = Marshal(key) + case ed25519.PrivateKey: + pub := make([]byte, ed25519.PublicKeySize) + priv := make([]byte, ed25519.PrivateKeySize) + copy(pub, k[32:]) + copy(priv, k) + + // Marshal public key. + pubKey := struct { + KeyType string + Pub []byte + }{ + KeyAlgoED25519, pub, + } + w.PubKey = Marshal(pubKey) + + // Marshal private key. + key := openSSHEd25519PrivateKey{ + Pub: pub, + Priv: priv, + Comment: comment, + } + pk1.Keytype = KeyAlgoED25519 + pk1.Rest = Marshal(key) + case *ecdsa.PrivateKey: + var curve, keyType string + switch name := k.Curve.Params().Name; name { + case "P-256": + curve = "nistp256" + keyType = KeyAlgoECDSA256 + case "P-384": + curve = "nistp384" + keyType = KeyAlgoECDSA384 + case "P-521": + curve = "nistp521" + keyType = KeyAlgoECDSA521 + default: + return nil, errors.New("ssh: unhandled elliptic curve " + name) + } + + pub := elliptic.Marshal(k.Curve, k.PublicKey.X, k.PublicKey.Y) + + // Marshal public key. + pubKey := struct { + KeyType string + Curve string + Pub []byte + }{ + keyType, curve, pub, + } + w.PubKey = Marshal(pubKey) + + // Marshal private key. + key := openSSHECDSAPrivateKey{ + Curve: curve, + Pub: pub, + D: k.D, + Comment: comment, + } + pk1.Keytype = keyType + pk1.Rest = Marshal(key) + default: + return nil, fmt.Errorf("ssh: unsupported key type %T", k) + } + + var err error + // Add padding and encrypt the key if necessary. + w.PrivKeyBlock, w.CipherName, w.KdfName, w.KdfOpts, err = encrypt(Marshal(pk1)) + if err != nil { + return nil, err + } + + b := Marshal(w) + block := &pem.Block{ + Type: "OPENSSH PRIVATE KEY", + Bytes: append([]byte(privateKeyAuthMagic), b...), + } + return block, nil +} + func checkOpenSSHKeyPadding(pad []byte) error { for i, b := range pad { if int(b) != i+1 { @@ -1424,6 +1687,13 @@ func checkOpenSSHKeyPadding(pad []byte) error { return nil } +func generateOpenSSHPadding(block []byte, blockSize int) []byte { + for i, l := 0, len(block); (l+i)%blockSize != 0; i++ { + block = append(block, byte(i+1)) + } + return block +} + // FingerprintLegacyMD5 returns the user presentation of the key's // fingerprint as described by RFC 4716 section 4. func FingerprintLegacyMD5(pubKey PublicKey) string { diff --git a/vendor/golang.org/x/crypto/ssh/messages.go b/vendor/golang.org/x/crypto/ssh/messages.go index 922032d952..b55f860564 100644 --- a/vendor/golang.org/x/crypto/ssh/messages.go +++ b/vendor/golang.org/x/crypto/ssh/messages.go @@ -349,6 +349,20 @@ type userAuthGSSAPIError struct { LanguageTag string } +// Transport layer OpenSSH extension. See [PROTOCOL], section 1.9 +const msgPing = 192 + +type pingMsg struct { + Data string `sshtype:"192"` +} + +// Transport layer OpenSSH extension. See [PROTOCOL], section 1.9 +const msgPong = 193 + +type pongMsg struct { + Data string `sshtype:"193"` +} + // typeTags returns the possible type bytes for the given reflect.Type, which // should be a struct. The possible values are separated by a '|' character. func typeTags(structType reflect.Type) (tags []byte) { diff --git a/vendor/golang.org/x/crypto/ssh/mux.go b/vendor/golang.org/x/crypto/ssh/mux.go index 9654c01869..d2d24c635d 100644 --- a/vendor/golang.org/x/crypto/ssh/mux.go +++ b/vendor/golang.org/x/crypto/ssh/mux.go @@ -231,6 +231,12 @@ func (m *mux) onePacket() error { return m.handleChannelOpen(packet) case msgGlobalRequest, msgRequestSuccess, msgRequestFailure: return m.handleGlobalPacket(packet) + case msgPing: + var msg pingMsg + if err := Unmarshal(packet, &msg); err != nil { + return fmt.Errorf("failed to unmarshal ping@openssh.com message: %w", err) + } + return m.sendMessage(pongMsg(msg)) } // assume a channel packet. diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go index b21322affa..727c71b9c7 100644 --- a/vendor/golang.org/x/crypto/ssh/server.go +++ b/vendor/golang.org/x/crypto/ssh/server.go @@ -576,7 +576,16 @@ userAuthLoop: if !ok || len(payload) > 0 { return nil, parseError(msgUserAuthRequest) } - + // Ensure the declared public key algo is compatible with the + // decoded one. This check will ensure we don't accept e.g. + // ssh-rsa-cert-v01@openssh.com algorithm with ssh-rsa public + // key type. The algorithm and public key type must be + // consistent: both must be certificate algorithms, or neither. + if !contains(algorithmsForKeyFormat(pubKey.Type()), algo) { + authErr = fmt.Errorf("ssh: public key type %q not compatible with selected algorithm %q", + pubKey.Type(), algo) + break + } // Ensure the public key algo and signature algo // are supported. Compare the private key // algorithm name that corresponds to algo with diff --git a/vendor/golang.org/x/net/http2/Dockerfile b/vendor/golang.org/x/net/http2/Dockerfile deleted file mode 100644 index 8512245952..0000000000 --- a/vendor/golang.org/x/net/http2/Dockerfile +++ /dev/null @@ -1,51 +0,0 @@ -# -# This Dockerfile builds a recent curl with HTTP/2 client support, using -# a recent nghttp2 build. -# -# See the Makefile for how to tag it. If Docker and that image is found, the -# Go tests use this curl binary for integration tests. -# - -FROM ubuntu:trusty - -RUN apt-get update && \ - apt-get upgrade -y && \ - apt-get install -y git-core build-essential wget - -RUN apt-get install -y --no-install-recommends \ - autotools-dev libtool pkg-config zlib1g-dev \ - libcunit1-dev libssl-dev libxml2-dev libevent-dev \ - automake autoconf - -# The list of packages nghttp2 recommends for h2load: -RUN apt-get install -y --no-install-recommends make binutils \ - autoconf automake autotools-dev \ - libtool pkg-config zlib1g-dev libcunit1-dev libssl-dev libxml2-dev \ - libev-dev libevent-dev libjansson-dev libjemalloc-dev \ - cython python3.4-dev python-setuptools - -# Note: setting NGHTTP2_VER before the git clone, so an old git clone isn't cached: -ENV NGHTTP2_VER 895da9a -RUN cd /root && git clone https://github.com/tatsuhiro-t/nghttp2.git - -WORKDIR /root/nghttp2 -RUN git reset --hard $NGHTTP2_VER -RUN autoreconf -i -RUN automake -RUN autoconf -RUN ./configure -RUN make -RUN make install - -WORKDIR /root -RUN wget https://curl.se/download/curl-7.45.0.tar.gz -RUN tar -zxvf curl-7.45.0.tar.gz -WORKDIR /root/curl-7.45.0 -RUN ./configure --with-ssl --with-nghttp2=/usr/local -RUN make -RUN make install -RUN ldconfig - -CMD ["-h"] -ENTRYPOINT ["/usr/local/bin/curl"] - diff --git a/vendor/golang.org/x/net/http2/Makefile b/vendor/golang.org/x/net/http2/Makefile deleted file mode 100644 index 55fd826f77..0000000000 --- a/vendor/golang.org/x/net/http2/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -curlimage: - docker build -t gohttp2/curl . - diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index 033b6e6db6..02c88b6b3e 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -581,9 +581,11 @@ type serverConn struct { advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client curClientStreams uint32 // number of open streams initiated by the client curPushedStreams uint32 // number of open streams initiated by server push + curHandlers uint32 // number of running handler goroutines maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes streams map[uint32]*stream + unstartedHandlers []unstartedHandler initialStreamSendWindowSize int32 maxFrameSize int32 peerMaxHeaderListSize uint32 // zero means unknown (default) @@ -981,6 +983,8 @@ func (sc *serverConn) serve() { return case gracefulShutdownMsg: sc.startGracefulShutdownInternal() + case handlerDoneMsg: + sc.handlerDone() default: panic("unknown timer") } @@ -1012,14 +1016,6 @@ func (sc *serverConn) serve() { } } -func (sc *serverConn) awaitGracefulShutdown(sharedCh <-chan struct{}, privateCh chan struct{}) { - select { - case <-sc.doneServing: - case <-sharedCh: - close(privateCh) - } -} - type serverMessage int // Message values sent to serveMsgCh. @@ -1028,6 +1024,7 @@ var ( idleTimerMsg = new(serverMessage) shutdownTimerMsg = new(serverMessage) gracefulShutdownMsg = new(serverMessage) + handlerDoneMsg = new(serverMessage) ) func (sc *serverConn) onSettingsTimer() { sc.sendServeMsg(settingsTimerMsg) } @@ -1900,9 +1897,11 @@ func (st *stream) copyTrailersToHandlerRequest() { // onReadTimeout is run on its own goroutine (from time.AfterFunc) // when the stream's ReadTimeout has fired. func (st *stream) onReadTimeout() { - // Wrap the ErrDeadlineExceeded to avoid callers depending on us - // returning the bare error. - st.body.CloseWithError(fmt.Errorf("%w", os.ErrDeadlineExceeded)) + if st.body != nil { + // Wrap the ErrDeadlineExceeded to avoid callers depending on us + // returning the bare error. + st.body.CloseWithError(fmt.Errorf("%w", os.ErrDeadlineExceeded)) + } } // onWriteTimeout is run on its own goroutine (from time.AfterFunc) @@ -2020,13 +2019,10 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { // (in Go 1.8), though. That's a more sane option anyway. if sc.hs.ReadTimeout != 0 { sc.conn.SetReadDeadline(time.Time{}) - if st.body != nil { - st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout) - } + st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout) } - go sc.runHandler(rw, req, handler) - return nil + return sc.scheduleHandler(id, rw, req, handler) } func (sc *serverConn) upgradeRequest(req *http.Request) { @@ -2046,6 +2042,10 @@ func (sc *serverConn) upgradeRequest(req *http.Request) { sc.conn.SetReadDeadline(time.Time{}) } + // This is the first request on the connection, + // so start the handler directly rather than going + // through scheduleHandler. + sc.curHandlers++ go sc.runHandler(rw, req, sc.handler.ServeHTTP) } @@ -2286,8 +2286,62 @@ func (sc *serverConn) newResponseWriter(st *stream, req *http.Request) *response return &responseWriter{rws: rws} } +type unstartedHandler struct { + streamID uint32 + rw *responseWriter + req *http.Request + handler func(http.ResponseWriter, *http.Request) +} + +// scheduleHandler starts a handler goroutine, +// or schedules one to start as soon as an existing handler finishes. +func (sc *serverConn) scheduleHandler(streamID uint32, rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) error { + sc.serveG.check() + maxHandlers := sc.advMaxStreams + if sc.curHandlers < maxHandlers { + sc.curHandlers++ + go sc.runHandler(rw, req, handler) + return nil + } + if len(sc.unstartedHandlers) > int(4*sc.advMaxStreams) { + return sc.countError("too_many_early_resets", ConnectionError(ErrCodeEnhanceYourCalm)) + } + sc.unstartedHandlers = append(sc.unstartedHandlers, unstartedHandler{ + streamID: streamID, + rw: rw, + req: req, + handler: handler, + }) + return nil +} + +func (sc *serverConn) handlerDone() { + sc.serveG.check() + sc.curHandlers-- + i := 0 + maxHandlers := sc.advMaxStreams + for ; i < len(sc.unstartedHandlers); i++ { + u := sc.unstartedHandlers[i] + if sc.streams[u.streamID] == nil { + // This stream was reset before its goroutine had a chance to start. + continue + } + if sc.curHandlers >= maxHandlers { + break + } + sc.curHandlers++ + go sc.runHandler(u.rw, u.req, u.handler) + sc.unstartedHandlers[i] = unstartedHandler{} // don't retain references + } + sc.unstartedHandlers = sc.unstartedHandlers[i:] + if len(sc.unstartedHandlers) == 0 { + sc.unstartedHandlers = nil + } +} + // Run on its own goroutine. func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) { + defer sc.sendServeMsg(handlerDoneMsg) didPanic := true defer func() { rw.rws.stream.cancelCtx() diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go index b20c749171..4515b22c4a 100644 --- a/vendor/golang.org/x/net/http2/transport.go +++ b/vendor/golang.org/x/net/http2/transport.go @@ -19,6 +19,7 @@ import ( "io/fs" "log" "math" + "math/bits" mathrand "math/rand" "net" "net/http" @@ -290,8 +291,7 @@ func (t *Transport) initConnPool() { // HTTP/2 server. type ClientConn struct { t *Transport - tconn net.Conn // usually *tls.Conn, except specialized impls - tconnClosed bool + tconn net.Conn // usually *tls.Conn, except specialized impls tlsState *tls.ConnectionState // nil only for specialized impls reused uint32 // whether conn is being reused; atomic singleUse bool // whether being used for a single http.Request @@ -1680,7 +1680,27 @@ func (cs *clientStream) frameScratchBufferLen(maxFrameSize int) int { return int(n) // doesn't truncate; max is 512K } -var bufPool sync.Pool // of *[]byte +// Seven bufPools manage different frame sizes. This helps to avoid scenarios where long-running +// streaming requests using small frame sizes occupy large buffers initially allocated for prior +// requests needing big buffers. The size ranges are as follows: +// {0 KB, 16 KB], {16 KB, 32 KB], {32 KB, 64 KB], {64 KB, 128 KB], {128 KB, 256 KB], +// {256 KB, 512 KB], {512 KB, infinity} +// In practice, the maximum scratch buffer size should not exceed 512 KB due to +// frameScratchBufferLen(maxFrameSize), thus the "infinity pool" should never be used. +// It exists mainly as a safety measure, for potential future increases in max buffer size. +var bufPools [7]sync.Pool // of *[]byte +func bufPoolIndex(size int) int { + if size <= 16384 { + return 0 + } + size -= 1 + bits := bits.Len(uint(size)) + index := bits - 14 + if index >= len(bufPools) { + return len(bufPools) - 1 + } + return index +} func (cs *clientStream) writeRequestBody(req *http.Request) (err error) { cc := cs.cc @@ -1698,12 +1718,13 @@ func (cs *clientStream) writeRequestBody(req *http.Request) (err error) { // Scratch buffer for reading into & writing from. scratchLen := cs.frameScratchBufferLen(maxFrameSize) var buf []byte - if bp, ok := bufPool.Get().(*[]byte); ok && len(*bp) >= scratchLen { - defer bufPool.Put(bp) + index := bufPoolIndex(scratchLen) + if bp, ok := bufPools[index].Get().(*[]byte); ok && len(*bp) >= scratchLen { + defer bufPools[index].Put(bp) buf = *bp } else { buf = make([]byte, scratchLen) - defer bufPool.Put(&buf) + defer bufPools[index].Put(&buf) } var sawEOF bool diff --git a/vendor/golang.org/x/sys/cpu/cpu_riscv64.go b/vendor/golang.org/x/sys/cpu/cpu_riscv64.go index bd6c128af9..ff7da60eb8 100644 --- a/vendor/golang.org/x/sys/cpu/cpu_riscv64.go +++ b/vendor/golang.org/x/sys/cpu/cpu_riscv64.go @@ -7,6 +7,6 @@ package cpu -const cacheLineSize = 32 +const cacheLineSize = 64 func initOptions() {} diff --git a/vendor/golang.org/x/sys/cpu/hwcap_linux.go b/vendor/golang.org/x/sys/cpu/hwcap_linux.go index 1d9d91f3ed..34e49f955a 100644 --- a/vendor/golang.org/x/sys/cpu/hwcap_linux.go +++ b/vendor/golang.org/x/sys/cpu/hwcap_linux.go @@ -5,7 +5,7 @@ package cpu import ( - "io/ioutil" + "os" ) const ( @@ -39,7 +39,7 @@ func readHWCAP() error { return nil } - buf, err := ioutil.ReadFile(procAuxv) + buf, err := os.ReadFile(procAuxv) if err != nil { // e.g. on android /proc/self/auxv is not accessible, so silently // ignore the error and leave Initialized = false. On some diff --git a/vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go b/vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go deleted file mode 100644 index e07899b909..0000000000 --- a/vendor/golang.org/x/sys/internal/unsafeheader/unsafeheader.go +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package unsafeheader contains header declarations for the Go runtime's -// slice and string implementations. -// -// This package allows x/sys to use types equivalent to -// reflect.SliceHeader and reflect.StringHeader without introducing -// a dependency on the (relatively heavy) "reflect" package. -package unsafeheader - -import ( - "unsafe" -) - -// Slice is the runtime representation of a slice. -// It cannot be used safely or portably and its representation may change in a later release. -type Slice struct { - Data unsafe.Pointer - Len int - Cap int -} - -// String is the runtime representation of a string. -// It cannot be used safely or portably and its representation may change in a later release. -type String struct { - Data unsafe.Pointer - Len int -} diff --git a/vendor/golang.org/x/sys/unix/ptrace_darwin.go b/vendor/golang.org/x/sys/unix/ptrace_darwin.go index 39dba6ca6a..463c3eff7f 100644 --- a/vendor/golang.org/x/sys/unix/ptrace_darwin.go +++ b/vendor/golang.org/x/sys/unix/ptrace_darwin.go @@ -7,12 +7,6 @@ package unix -import "unsafe" - func ptrace(request int, pid int, addr uintptr, data uintptr) error { return ptrace1(request, pid, addr, data) } - -func ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) error { - return ptrace1Ptr(request, pid, addr, data) -} diff --git a/vendor/golang.org/x/sys/unix/ptrace_ios.go b/vendor/golang.org/x/sys/unix/ptrace_ios.go index 9ea66330a9..ed0509a011 100644 --- a/vendor/golang.org/x/sys/unix/ptrace_ios.go +++ b/vendor/golang.org/x/sys/unix/ptrace_ios.go @@ -7,12 +7,6 @@ package unix -import "unsafe" - func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) { return ENOTSUP } - -func ptracePtr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) { - return ENOTSUP -} diff --git a/vendor/golang.org/x/sys/unix/syscall_aix.go b/vendor/golang.org/x/sys/unix/syscall_aix.go index 9a6e5acacb..e94e6cdac8 100644 --- a/vendor/golang.org/x/sys/unix/syscall_aix.go +++ b/vendor/golang.org/x/sys/unix/syscall_aix.go @@ -487,8 +487,6 @@ func Fsync(fd int) error { //sys Unlinkat(dirfd int, path string, flags int) (err error) //sys Ustat(dev int, ubuf *Ustat_t) (err error) //sys write(fd int, p []byte) (n int, err error) -//sys readlen(fd int, p *byte, np int) (n int, err error) = read -//sys writelen(fd int, p *byte, np int) (n int, err error) = write //sys Dup2(oldfd int, newfd int) (err error) //sys Fadvise(fd int, offset int64, length int64, advice int) (err error) = posix_fadvise64 diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin.go b/vendor/golang.org/x/sys/unix/syscall_darwin.go index 135cc3cd75..59542a897d 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin.go @@ -644,189 +644,3 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) { //sys write(fd int, p []byte) (n int, err error) //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys munmap(addr uintptr, length uintptr) (err error) -//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ -//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE - -/* - * Unimplemented - */ -// Profil -// Sigaction -// Sigprocmask -// Getlogin -// Sigpending -// Sigaltstack -// Ioctl -// Reboot -// Execve -// Vfork -// Sbrk -// Sstk -// Ovadvise -// Mincore -// Setitimer -// Swapon -// Select -// Sigsuspend -// Readv -// Writev -// Nfssvc -// Getfh -// Quotactl -// Csops -// Waitid -// Add_profil -// Kdebug_trace -// Sigreturn -// Atsocket -// Kqueue_from_portset_np -// Kqueue_portset -// Getattrlist -// Getdirentriesattr -// Searchfs -// Delete -// Copyfile -// Watchevent -// Waitevent -// Modwatch -// Fsctl -// Initgroups -// Posix_spawn -// Nfsclnt -// Fhopen -// Minherit -// Semsys -// Msgsys -// Shmsys -// Semctl -// Semget -// Semop -// Msgctl -// Msgget -// Msgsnd -// Msgrcv -// Shm_open -// Shm_unlink -// Sem_open -// Sem_close -// Sem_unlink -// Sem_wait -// Sem_trywait -// Sem_post -// Sem_getvalue -// Sem_init -// Sem_destroy -// Open_extended -// Umask_extended -// Stat_extended -// Lstat_extended -// Fstat_extended -// Chmod_extended -// Fchmod_extended -// Access_extended -// Settid -// Gettid -// Setsgroups -// Getsgroups -// Setwgroups -// Getwgroups -// Mkfifo_extended -// Mkdir_extended -// Identitysvc -// Shared_region_check_np -// Shared_region_map_np -// __pthread_mutex_destroy -// __pthread_mutex_init -// __pthread_mutex_lock -// __pthread_mutex_trylock -// __pthread_mutex_unlock -// __pthread_cond_init -// __pthread_cond_destroy -// __pthread_cond_broadcast -// __pthread_cond_signal -// Setsid_with_pid -// __pthread_cond_timedwait -// Aio_fsync -// Aio_return -// Aio_suspend -// Aio_cancel -// Aio_error -// Aio_read -// Aio_write -// Lio_listio -// __pthread_cond_wait -// Iopolicysys -// __pthread_kill -// __pthread_sigmask -// __sigwait -// __disable_threadsignal -// __pthread_markcancel -// __pthread_canceled -// __semwait_signal -// Proc_info -// sendfile -// Stat64_extended -// Lstat64_extended -// Fstat64_extended -// __pthread_chdir -// __pthread_fchdir -// Audit -// Auditon -// Getauid -// Setauid -// Getaudit -// Setaudit -// Getaudit_addr -// Setaudit_addr -// Auditctl -// Bsdthread_create -// Bsdthread_terminate -// Stack_snapshot -// Bsdthread_register -// Workq_open -// Workq_ops -// __mac_execve -// __mac_syscall -// __mac_get_file -// __mac_set_file -// __mac_get_link -// __mac_set_link -// __mac_get_proc -// __mac_set_proc -// __mac_get_fd -// __mac_set_fd -// __mac_get_pid -// __mac_get_lcid -// __mac_get_lctx -// __mac_set_lctx -// Setlcid -// Read_nocancel -// Write_nocancel -// Open_nocancel -// Close_nocancel -// Wait4_nocancel -// Recvmsg_nocancel -// Sendmsg_nocancel -// Recvfrom_nocancel -// Accept_nocancel -// Fcntl_nocancel -// Select_nocancel -// Fsync_nocancel -// Connect_nocancel -// Sigsuspend_nocancel -// Readv_nocancel -// Writev_nocancel -// Sendto_nocancel -// Pread_nocancel -// Pwrite_nocancel -// Waitid_nocancel -// Poll_nocancel -// Msgsnd_nocancel -// Msgrcv_nocancel -// Sem_wait_nocancel -// Aio_suspend_nocancel -// __sigwait_nocancel -// __semwait_signal_nocancel -// __mac_mount -// __mac_get_mount -// __mac_getfsstat diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go index 9fa879806b..b37310ce9b 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go @@ -47,6 +47,5 @@ func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, //sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64 //sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64 //sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace -//sys ptrace1Ptr(request int, pid int, addr unsafe.Pointer, data uintptr) (err error) = SYS_ptrace //sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64 //sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64 diff --git a/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go index f17b8c526a..d51ec99630 100644 --- a/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/syscall_darwin_arm64.go @@ -47,6 +47,5 @@ func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, //sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT //sys Lstat(path string, stat *Stat_t) (err error) //sys ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) = SYS_ptrace -//sys ptrace1Ptr(request int, pid int, addr unsafe.Pointer, data uintptr) (err error) = SYS_ptrace //sys Stat(path string, stat *Stat_t) (err error) //sys Statfs(path string, stat *Statfs_t) (err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go index d4ce988e72..97cb916f2c 100644 --- a/vendor/golang.org/x/sys/unix/syscall_dragonfly.go +++ b/vendor/golang.org/x/sys/unix/syscall_dragonfly.go @@ -343,203 +343,5 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys write(fd int, p []byte) (n int, err error) //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys munmap(addr uintptr, length uintptr) (err error) -//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ -//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE //sys accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) - -/* - * Unimplemented - * TODO(jsing): Update this list for DragonFly. - */ -// Profil -// Sigaction -// Sigprocmask -// Getlogin -// Sigpending -// Sigaltstack -// Reboot -// Execve -// Vfork -// Sbrk -// Sstk -// Ovadvise -// Mincore -// Setitimer -// Swapon -// Select -// Sigsuspend -// Readv -// Writev -// Nfssvc -// Getfh -// Quotactl -// Mount -// Csops -// Waitid -// Add_profil -// Kdebug_trace -// Sigreturn -// Atsocket -// Kqueue_from_portset_np -// Kqueue_portset -// Getattrlist -// Setattrlist -// Getdirentriesattr -// Searchfs -// Delete -// Copyfile -// Watchevent -// Waitevent -// Modwatch -// Getxattr -// Fgetxattr -// Setxattr -// Fsetxattr -// Removexattr -// Fremovexattr -// Listxattr -// Flistxattr -// Fsctl -// Initgroups -// Posix_spawn -// Nfsclnt -// Fhopen -// Minherit -// Semsys -// Msgsys -// Shmsys -// Semctl -// Semget -// Semop -// Msgctl -// Msgget -// Msgsnd -// Msgrcv -// Shmat -// Shmctl -// Shmdt -// Shmget -// Shm_open -// Shm_unlink -// Sem_open -// Sem_close -// Sem_unlink -// Sem_wait -// Sem_trywait -// Sem_post -// Sem_getvalue -// Sem_init -// Sem_destroy -// Open_extended -// Umask_extended -// Stat_extended -// Lstat_extended -// Fstat_extended -// Chmod_extended -// Fchmod_extended -// Access_extended -// Settid -// Gettid -// Setsgroups -// Getsgroups -// Setwgroups -// Getwgroups -// Mkfifo_extended -// Mkdir_extended -// Identitysvc -// Shared_region_check_np -// Shared_region_map_np -// __pthread_mutex_destroy -// __pthread_mutex_init -// __pthread_mutex_lock -// __pthread_mutex_trylock -// __pthread_mutex_unlock -// __pthread_cond_init -// __pthread_cond_destroy -// __pthread_cond_broadcast -// __pthread_cond_signal -// Setsid_with_pid -// __pthread_cond_timedwait -// Aio_fsync -// Aio_return -// Aio_suspend -// Aio_cancel -// Aio_error -// Aio_read -// Aio_write -// Lio_listio -// __pthread_cond_wait -// Iopolicysys -// __pthread_kill -// __pthread_sigmask -// __sigwait -// __disable_threadsignal -// __pthread_markcancel -// __pthread_canceled -// __semwait_signal -// Proc_info -// Stat64_extended -// Lstat64_extended -// Fstat64_extended -// __pthread_chdir -// __pthread_fchdir -// Audit -// Auditon -// Getauid -// Setauid -// Getaudit -// Setaudit -// Getaudit_addr -// Setaudit_addr -// Auditctl -// Bsdthread_create -// Bsdthread_terminate -// Stack_snapshot -// Bsdthread_register -// Workq_open -// Workq_ops -// __mac_execve -// __mac_syscall -// __mac_get_file -// __mac_set_file -// __mac_get_link -// __mac_set_link -// __mac_get_proc -// __mac_set_proc -// __mac_get_fd -// __mac_set_fd -// __mac_get_pid -// __mac_get_lcid -// __mac_get_lctx -// __mac_set_lctx -// Setlcid -// Read_nocancel -// Write_nocancel -// Open_nocancel -// Close_nocancel -// Wait4_nocancel -// Recvmsg_nocancel -// Sendmsg_nocancel -// Recvfrom_nocancel -// Accept_nocancel -// Fcntl_nocancel -// Select_nocancel -// Fsync_nocancel -// Connect_nocancel -// Sigsuspend_nocancel -// Readv_nocancel -// Writev_nocancel -// Sendto_nocancel -// Pread_nocancel -// Pwrite_nocancel -// Waitid_nocancel -// Msgsnd_nocancel -// Msgrcv_nocancel -// Sem_wait_nocancel -// Aio_suspend_nocancel -// __sigwait_nocancel -// __semwait_signal_nocancel -// __mac_mount -// __mac_get_mount -// __mac_getfsstat diff --git a/vendor/golang.org/x/sys/unix/syscall_freebsd.go b/vendor/golang.org/x/sys/unix/syscall_freebsd.go index afb10106f6..64d1bb4dba 100644 --- a/vendor/golang.org/x/sys/unix/syscall_freebsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_freebsd.go @@ -449,197 +449,5 @@ func Dup3(oldfd, newfd, flags int) error { //sys write(fd int, p []byte) (n int, err error) //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys munmap(addr uintptr, length uintptr) (err error) -//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ -//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE //sys accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) - -/* - * Unimplemented - */ -// Profil -// Sigaction -// Sigprocmask -// Getlogin -// Sigpending -// Sigaltstack -// Ioctl -// Reboot -// Execve -// Vfork -// Sbrk -// Sstk -// Ovadvise -// Mincore -// Setitimer -// Swapon -// Select -// Sigsuspend -// Readv -// Writev -// Nfssvc -// Getfh -// Quotactl -// Mount -// Csops -// Waitid -// Add_profil -// Kdebug_trace -// Sigreturn -// Atsocket -// Kqueue_from_portset_np -// Kqueue_portset -// Getattrlist -// Setattrlist -// Getdents -// Getdirentriesattr -// Searchfs -// Delete -// Copyfile -// Watchevent -// Waitevent -// Modwatch -// Fsctl -// Initgroups -// Posix_spawn -// Nfsclnt -// Fhopen -// Minherit -// Semsys -// Msgsys -// Shmsys -// Semctl -// Semget -// Semop -// Msgctl -// Msgget -// Msgsnd -// Msgrcv -// Shmat -// Shmctl -// Shmdt -// Shmget -// Shm_open -// Shm_unlink -// Sem_open -// Sem_close -// Sem_unlink -// Sem_wait -// Sem_trywait -// Sem_post -// Sem_getvalue -// Sem_init -// Sem_destroy -// Open_extended -// Umask_extended -// Stat_extended -// Lstat_extended -// Fstat_extended -// Chmod_extended -// Fchmod_extended -// Access_extended -// Settid -// Gettid -// Setsgroups -// Getsgroups -// Setwgroups -// Getwgroups -// Mkfifo_extended -// Mkdir_extended -// Identitysvc -// Shared_region_check_np -// Shared_region_map_np -// __pthread_mutex_destroy -// __pthread_mutex_init -// __pthread_mutex_lock -// __pthread_mutex_trylock -// __pthread_mutex_unlock -// __pthread_cond_init -// __pthread_cond_destroy -// __pthread_cond_broadcast -// __pthread_cond_signal -// Setsid_with_pid -// __pthread_cond_timedwait -// Aio_fsync -// Aio_return -// Aio_suspend -// Aio_cancel -// Aio_error -// Aio_read -// Aio_write -// Lio_listio -// __pthread_cond_wait -// Iopolicysys -// __pthread_kill -// __pthread_sigmask -// __sigwait -// __disable_threadsignal -// __pthread_markcancel -// __pthread_canceled -// __semwait_signal -// Proc_info -// Stat64_extended -// Lstat64_extended -// Fstat64_extended -// __pthread_chdir -// __pthread_fchdir -// Audit -// Auditon -// Getauid -// Setauid -// Getaudit -// Setaudit -// Getaudit_addr -// Setaudit_addr -// Auditctl -// Bsdthread_create -// Bsdthread_terminate -// Stack_snapshot -// Bsdthread_register -// Workq_open -// Workq_ops -// __mac_execve -// __mac_syscall -// __mac_get_file -// __mac_set_file -// __mac_get_link -// __mac_set_link -// __mac_get_proc -// __mac_set_proc -// __mac_get_fd -// __mac_set_fd -// __mac_get_pid -// __mac_get_lcid -// __mac_get_lctx -// __mac_set_lctx -// Setlcid -// Read_nocancel -// Write_nocancel -// Open_nocancel -// Close_nocancel -// Wait4_nocancel -// Recvmsg_nocancel -// Sendmsg_nocancel -// Recvfrom_nocancel -// Accept_nocancel -// Fcntl_nocancel -// Select_nocancel -// Fsync_nocancel -// Connect_nocancel -// Sigsuspend_nocancel -// Readv_nocancel -// Writev_nocancel -// Sendto_nocancel -// Pread_nocancel -// Pwrite_nocancel -// Waitid_nocancel -// Poll_nocancel -// Msgsnd_nocancel -// Msgrcv_nocancel -// Sem_wait_nocancel -// Aio_suspend_nocancel -// __sigwait_nocancel -// __semwait_signal_nocancel -// __mac_mount -// __mac_get_mount -// __mac_getfsstat diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 0ba030197f..fb4e50224c 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -693,10 +693,10 @@ type SockaddrALG struct { func (sa *SockaddrALG) sockaddr() (unsafe.Pointer, _Socklen, error) { // Leave room for NUL byte terminator. - if len(sa.Type) > 13 { + if len(sa.Type) > len(sa.raw.Type)-1 { return nil, 0, EINVAL } - if len(sa.Name) > 63 { + if len(sa.Name) > len(sa.raw.Name)-1 { return nil, 0, EINVAL } @@ -704,17 +704,8 @@ func (sa *SockaddrALG) sockaddr() (unsafe.Pointer, _Socklen, error) { sa.raw.Feat = sa.Feature sa.raw.Mask = sa.Mask - typ, err := ByteSliceFromString(sa.Type) - if err != nil { - return nil, 0, err - } - name, err := ByteSliceFromString(sa.Name) - if err != nil { - return nil, 0, err - } - - copy(sa.raw.Type[:], typ) - copy(sa.raw.Name[:], name) + copy(sa.raw.Type[:], sa.Type) + copy(sa.raw.Name[:], sa.Name) return unsafe.Pointer(&sa.raw), SizeofSockaddrALG, nil } @@ -1988,8 +1979,6 @@ func Signalfd(fd int, sigmask *Sigset_t, flags int) (newfd int, err error) { //sys Unshare(flags int) (err error) //sys write(fd int, p []byte) (n int, err error) //sys exitThread(code int) (err error) = SYS_EXIT -//sys readlen(fd int, p *byte, np int) (n int, err error) = SYS_READ -//sys writelen(fd int, p *byte, np int) (n int, err error) = SYS_WRITE //sys readv(fd int, iovs []Iovec) (n int, err error) = SYS_READV //sys writev(fd int, iovs []Iovec) (n int, err error) = SYS_WRITEV //sys preadv(fd int, iovs []Iovec, offs_l uintptr, offs_h uintptr) (n int, err error) = SYS_PREADV @@ -2493,99 +2482,3 @@ func SchedGetAttr(pid int, flags uint) (*SchedAttr, error) { } return attr, nil } - -/* - * Unimplemented - */ -// AfsSyscall -// ArchPrctl -// Brk -// ClockNanosleep -// ClockSettime -// Clone -// EpollCtlOld -// EpollPwait -// EpollWaitOld -// Execve -// Fork -// Futex -// GetKernelSyms -// GetMempolicy -// GetRobustList -// GetThreadArea -// Getpmsg -// IoCancel -// IoDestroy -// IoGetevents -// IoSetup -// IoSubmit -// IoprioGet -// IoprioSet -// KexecLoad -// LookupDcookie -// Mbind -// MigratePages -// Mincore -// ModifyLdt -// Mount -// MovePages -// MqGetsetattr -// MqNotify -// MqOpen -// MqTimedreceive -// MqTimedsend -// MqUnlink -// Msgctl -// Msgget -// Msgrcv -// Msgsnd -// Nfsservctl -// Personality -// Pselect6 -// Ptrace -// Putpmsg -// Quotactl -// Readahead -// Readv -// RemapFilePages -// RestartSyscall -// RtSigaction -// RtSigpending -// RtSigqueueinfo -// RtSigreturn -// RtSigsuspend -// RtSigtimedwait -// SchedGetPriorityMax -// SchedGetPriorityMin -// SchedGetparam -// SchedGetscheduler -// SchedRrGetInterval -// SchedSetparam -// SchedYield -// Security -// Semctl -// Semget -// Semop -// Semtimedop -// SetMempolicy -// SetRobustList -// SetThreadArea -// SetTidAddress -// Sigaltstack -// Swapoff -// Swapon -// Sysfs -// TimerCreate -// TimerDelete -// TimerGetoverrun -// TimerGettime -// TimerSettime -// Tkill (obsolete) -// Tuxcall -// Umount2 -// Uselib -// Utimensat -// Vfork -// Vhangup -// Vserver -// _Sysctl diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go index ddd1ac8534..88162099af 100644 --- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go @@ -356,8 +356,6 @@ func Statvfs(path string, buf *Statvfs_t) (err error) { //sys write(fd int, p []byte) (n int, err error) //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys munmap(addr uintptr, length uintptr) (err error) -//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ -//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) const ( @@ -371,262 +369,3 @@ const ( func mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (uintptr, error) { return mremapNetBSD(oldaddr, oldlength, newaddr, newlength, flags) } - -/* - * Unimplemented - */ -// ____semctl13 -// __clone -// __fhopen40 -// __fhstat40 -// __fhstatvfs140 -// __fstat30 -// __getcwd -// __getfh30 -// __getlogin -// __lstat30 -// __mount50 -// __msgctl13 -// __msync13 -// __ntp_gettime30 -// __posix_chown -// __posix_fchown -// __posix_lchown -// __posix_rename -// __setlogin -// __shmctl13 -// __sigaction_sigtramp -// __sigaltstack14 -// __sigpending14 -// __sigprocmask14 -// __sigsuspend14 -// __sigtimedwait -// __stat30 -// __syscall -// __vfork14 -// _ksem_close -// _ksem_destroy -// _ksem_getvalue -// _ksem_init -// _ksem_open -// _ksem_post -// _ksem_trywait -// _ksem_unlink -// _ksem_wait -// _lwp_continue -// _lwp_create -// _lwp_ctl -// _lwp_detach -// _lwp_exit -// _lwp_getname -// _lwp_getprivate -// _lwp_kill -// _lwp_park -// _lwp_self -// _lwp_setname -// _lwp_setprivate -// _lwp_suspend -// _lwp_unpark -// _lwp_unpark_all -// _lwp_wait -// _lwp_wakeup -// _pset_bind -// _sched_getaffinity -// _sched_getparam -// _sched_setaffinity -// _sched_setparam -// acct -// aio_cancel -// aio_error -// aio_fsync -// aio_read -// aio_return -// aio_suspend -// aio_write -// break -// clock_getres -// clock_gettime -// clock_settime -// compat_09_ogetdomainname -// compat_09_osetdomainname -// compat_09_ouname -// compat_10_omsgsys -// compat_10_osemsys -// compat_10_oshmsys -// compat_12_fstat12 -// compat_12_getdirentries -// compat_12_lstat12 -// compat_12_msync -// compat_12_oreboot -// compat_12_oswapon -// compat_12_stat12 -// compat_13_sigaction13 -// compat_13_sigaltstack13 -// compat_13_sigpending13 -// compat_13_sigprocmask13 -// compat_13_sigreturn13 -// compat_13_sigsuspend13 -// compat_14___semctl -// compat_14_msgctl -// compat_14_shmctl -// compat_16___sigaction14 -// compat_16___sigreturn14 -// compat_20_fhstatfs -// compat_20_fstatfs -// compat_20_getfsstat -// compat_20_statfs -// compat_30___fhstat30 -// compat_30___fstat13 -// compat_30___lstat13 -// compat_30___stat13 -// compat_30_fhopen -// compat_30_fhstat -// compat_30_fhstatvfs1 -// compat_30_getdents -// compat_30_getfh -// compat_30_ntp_gettime -// compat_30_socket -// compat_40_mount -// compat_43_fstat43 -// compat_43_lstat43 -// compat_43_oaccept -// compat_43_ocreat -// compat_43_oftruncate -// compat_43_ogetdirentries -// compat_43_ogetdtablesize -// compat_43_ogethostid -// compat_43_ogethostname -// compat_43_ogetkerninfo -// compat_43_ogetpagesize -// compat_43_ogetpeername -// compat_43_ogetrlimit -// compat_43_ogetsockname -// compat_43_okillpg -// compat_43_olseek -// compat_43_ommap -// compat_43_oquota -// compat_43_orecv -// compat_43_orecvfrom -// compat_43_orecvmsg -// compat_43_osend -// compat_43_osendmsg -// compat_43_osethostid -// compat_43_osethostname -// compat_43_osigblock -// compat_43_osigsetmask -// compat_43_osigstack -// compat_43_osigvec -// compat_43_otruncate -// compat_43_owait -// compat_43_stat43 -// execve -// extattr_delete_fd -// extattr_delete_file -// extattr_delete_link -// extattr_get_fd -// extattr_get_file -// extattr_get_link -// extattr_list_fd -// extattr_list_file -// extattr_list_link -// extattr_set_fd -// extattr_set_file -// extattr_set_link -// extattrctl -// fchroot -// fdatasync -// fgetxattr -// fktrace -// flistxattr -// fork -// fremovexattr -// fsetxattr -// fstatvfs1 -// fsync_range -// getcontext -// getitimer -// getvfsstat -// getxattr -// ktrace -// lchflags -// lchmod -// lfs_bmapv -// lfs_markv -// lfs_segclean -// lfs_segwait -// lgetxattr -// lio_listio -// listxattr -// llistxattr -// lremovexattr -// lseek -// lsetxattr -// lutimes -// madvise -// mincore -// minherit -// modctl -// mq_close -// mq_getattr -// mq_notify -// mq_open -// mq_receive -// mq_send -// mq_setattr -// mq_timedreceive -// mq_timedsend -// mq_unlink -// msgget -// msgrcv -// msgsnd -// nfssvc -// ntp_adjtime -// pmc_control -// pmc_get_info -// pollts -// preadv -// profil -// pselect -// pset_assign -// pset_create -// pset_destroy -// ptrace -// pwritev -// quotactl -// rasctl -// readv -// reboot -// removexattr -// sa_enable -// sa_preempt -// sa_register -// sa_setconcurrency -// sa_stacks -// sa_yield -// sbrk -// sched_yield -// semconfig -// semget -// semop -// setcontext -// setitimer -// setxattr -// shmat -// shmdt -// shmget -// sstk -// statvfs1 -// swapctl -// sysarch -// syscall -// timer_create -// timer_delete -// timer_getoverrun -// timer_gettime -// timer_settime -// undelete -// utrace -// uuidgen -// vadvise -// vfork -// writev diff --git a/vendor/golang.org/x/sys/unix/syscall_openbsd.go b/vendor/golang.org/x/sys/unix/syscall_openbsd.go index c5f166a115..6f34479b59 100644 --- a/vendor/golang.org/x/sys/unix/syscall_openbsd.go +++ b/vendor/golang.org/x/sys/unix/syscall_openbsd.go @@ -326,78 +326,4 @@ func Uname(uname *Utsname) error { //sys write(fd int, p []byte) (n int, err error) //sys mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) (ret uintptr, err error) //sys munmap(addr uintptr, length uintptr) (err error) -//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ -//sys writelen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_WRITE //sys utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) - -/* - * Unimplemented - */ -// __getcwd -// __semctl -// __syscall -// __sysctl -// adjfreq -// break -// clock_getres -// clock_gettime -// clock_settime -// closefrom -// execve -// fhopen -// fhstat -// fhstatfs -// fork -// futimens -// getfh -// getgid -// getitimer -// getlogin -// getthrid -// ktrace -// lfs_bmapv -// lfs_markv -// lfs_segclean -// lfs_segwait -// mincore -// minherit -// mount -// mquery -// msgctl -// msgget -// msgrcv -// msgsnd -// nfssvc -// nnpfspioctl -// preadv -// profil -// pwritev -// quotactl -// readv -// reboot -// renameat -// rfork -// sched_yield -// semget -// semop -// setgroups -// setitimer -// setsockopt -// shmat -// shmctl -// shmdt -// shmget -// sigaction -// sigaltstack -// sigpending -// sigprocmask -// sigreturn -// sigsuspend -// sysarch -// syscall -// threxit -// thrsigdivert -// thrsleep -// thrwakeup -// vfork -// writev diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go index 72d23575fa..b99cfa1342 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -698,24 +698,6 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) = libsocket.setsockopt //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Socklen) (n int, err error) = libsocket.recvfrom -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procread)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0) - n = int(r0) - if e1 != 0 { - err = e1 - } - return -} - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procwrite)), 3, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf), 0, 0, 0) - n = int(r0) - if e1 != 0 { - err = e1 - } - return -} - // Event Ports type fileObjCookie struct { diff --git a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go index 44e72edb42..4596d041ce 100644 --- a/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/syscall_zos_s390x.go @@ -192,7 +192,6 @@ func (cmsg *Cmsghdr) SetLen(length int) { //sys fcntl(fd int, cmd int, arg int) (val int, err error) //sys read(fd int, p []byte) (n int, err error) -//sys readlen(fd int, buf *byte, nbuf int) (n int, err error) = SYS_READ //sys write(fd int, p []byte) (n int, err error) //sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) = SYS___ACCEPT_A diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 0787a043be..f9c7f479b0 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -2421,6 +2421,15 @@ const ( PR_PAC_GET_ENABLED_KEYS = 0x3d PR_PAC_RESET_KEYS = 0x36 PR_PAC_SET_ENABLED_KEYS = 0x3c + PR_RISCV_V_GET_CONTROL = 0x46 + PR_RISCV_V_SET_CONTROL = 0x45 + PR_RISCV_V_VSTATE_CTRL_CUR_MASK = 0x3 + PR_RISCV_V_VSTATE_CTRL_DEFAULT = 0x0 + PR_RISCV_V_VSTATE_CTRL_INHERIT = 0x10 + PR_RISCV_V_VSTATE_CTRL_MASK = 0x1f + PR_RISCV_V_VSTATE_CTRL_NEXT_MASK = 0xc + PR_RISCV_V_VSTATE_CTRL_OFF = 0x1 + PR_RISCV_V_VSTATE_CTRL_ON = 0x2 PR_SCHED_CORE = 0x3e PR_SCHED_CORE_CREATE = 0x1 PR_SCHED_CORE_GET = 0x0 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go index cfb1430018..30aee00a53 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_386.go @@ -326,10 +326,12 @@ const ( SO_NOFCS = 0x2b SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 + SO_PASSPIDFD = 0x4c SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 SO_PEERGROUPS = 0x3b + SO_PEERPIDFD = 0x4d SO_PEERSEC = 0x1f SO_PREFER_BUSY_POLL = 0x45 SO_PROTOCOL = 0x26 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go index df64f2d590..8ebfa51278 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_amd64.go @@ -327,10 +327,12 @@ const ( SO_NOFCS = 0x2b SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 + SO_PASSPIDFD = 0x4c SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 SO_PEERGROUPS = 0x3b + SO_PEERPIDFD = 0x4d SO_PEERSEC = 0x1f SO_PREFER_BUSY_POLL = 0x45 SO_PROTOCOL = 0x26 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go index 3025cd5b2d..271a21cdc7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm.go @@ -333,10 +333,12 @@ const ( SO_NOFCS = 0x2b SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 + SO_PASSPIDFD = 0x4c SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 SO_PEERGROUPS = 0x3b + SO_PEERPIDFD = 0x4d SO_PEERSEC = 0x1f SO_PREFER_BUSY_POLL = 0x45 SO_PROTOCOL = 0x26 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go index 09e1ffbef9..910c330a39 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_arm64.go @@ -323,10 +323,12 @@ const ( SO_NOFCS = 0x2b SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 + SO_PASSPIDFD = 0x4c SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 SO_PEERGROUPS = 0x3b + SO_PEERPIDFD = 0x4d SO_PEERSEC = 0x1f SO_PREFER_BUSY_POLL = 0x45 SO_PROTOCOL = 0x26 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go index a457235407..a640798c93 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_loong64.go @@ -118,6 +118,8 @@ const ( IUCLC = 0x200 IXOFF = 0x1000 IXON = 0x400 + LASX_CTX_MAGIC = 0x41535801 + LSX_CTX_MAGIC = 0x53580001 MAP_ANON = 0x20 MAP_ANONYMOUS = 0x20 MAP_DENYWRITE = 0x800 @@ -317,10 +319,12 @@ const ( SO_NOFCS = 0x2b SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 + SO_PASSPIDFD = 0x4c SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 SO_PEERGROUPS = 0x3b + SO_PEERPIDFD = 0x4d SO_PEERSEC = 0x1f SO_PREFER_BUSY_POLL = 0x45 SO_PROTOCOL = 0x26 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go index fee7dfb819..0d5925d340 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips.go @@ -326,10 +326,12 @@ const ( SO_NOFCS = 0x2b SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 + SO_PASSPIDFD = 0x4c SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 SO_PEERGROUPS = 0x3b + SO_PEERPIDFD = 0x4d SO_PEERSEC = 0x1e SO_PREFER_BUSY_POLL = 0x45 SO_PROTOCOL = 0x1028 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go index a5b2373aea..d72a00e0b6 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64.go @@ -326,10 +326,12 @@ const ( SO_NOFCS = 0x2b SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 + SO_PASSPIDFD = 0x4c SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 SO_PEERGROUPS = 0x3b + SO_PEERPIDFD = 0x4d SO_PEERSEC = 0x1e SO_PREFER_BUSY_POLL = 0x45 SO_PROTOCOL = 0x1028 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go index 5dde82c98a..02ba129f85 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mips64le.go @@ -326,10 +326,12 @@ const ( SO_NOFCS = 0x2b SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 + SO_PASSPIDFD = 0x4c SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 SO_PEERGROUPS = 0x3b + SO_PEERPIDFD = 0x4d SO_PEERSEC = 0x1e SO_PREFER_BUSY_POLL = 0x45 SO_PROTOCOL = 0x1028 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go index 2e80ea6b33..8daa6dd968 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_mipsle.go @@ -326,10 +326,12 @@ const ( SO_NOFCS = 0x2b SO_OOBINLINE = 0x100 SO_PASSCRED = 0x11 + SO_PASSPIDFD = 0x4c SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x12 SO_PEERGROUPS = 0x3b + SO_PEERPIDFD = 0x4d SO_PEERSEC = 0x1e SO_PREFER_BUSY_POLL = 0x45 SO_PROTOCOL = 0x1028 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go index a65dcd7cbe..63c8fa2f7f 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc.go @@ -381,10 +381,12 @@ const ( SO_NOFCS = 0x2b SO_OOBINLINE = 0xa SO_PASSCRED = 0x14 + SO_PASSPIDFD = 0x4c SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x15 SO_PEERGROUPS = 0x3b + SO_PEERPIDFD = 0x4d SO_PEERSEC = 0x1f SO_PREFER_BUSY_POLL = 0x45 SO_PROTOCOL = 0x26 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go index cbd34e3d89..930799ec1b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64.go @@ -385,10 +385,12 @@ const ( SO_NOFCS = 0x2b SO_OOBINLINE = 0xa SO_PASSCRED = 0x14 + SO_PASSPIDFD = 0x4c SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x15 SO_PEERGROUPS = 0x3b + SO_PEERPIDFD = 0x4d SO_PEERSEC = 0x1f SO_PREFER_BUSY_POLL = 0x45 SO_PROTOCOL = 0x26 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go index e4afa7a317..8605a7dd7e 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_ppc64le.go @@ -385,10 +385,12 @@ const ( SO_NOFCS = 0x2b SO_OOBINLINE = 0xa SO_PASSCRED = 0x14 + SO_PASSPIDFD = 0x4c SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x15 SO_PEERGROUPS = 0x3b + SO_PEERPIDFD = 0x4d SO_PEERSEC = 0x1f SO_PREFER_BUSY_POLL = 0x45 SO_PROTOCOL = 0x26 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go index 44f45a039d..95a016f1c0 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_riscv64.go @@ -314,10 +314,12 @@ const ( SO_NOFCS = 0x2b SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 + SO_PASSPIDFD = 0x4c SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 SO_PEERGROUPS = 0x3b + SO_PEERPIDFD = 0x4d SO_PEERSEC = 0x1f SO_PREFER_BUSY_POLL = 0x45 SO_PROTOCOL = 0x26 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go index 74733e260f..1ae0108f57 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_s390x.go @@ -389,10 +389,12 @@ const ( SO_NOFCS = 0x2b SO_OOBINLINE = 0xa SO_PASSCRED = 0x10 + SO_PASSPIDFD = 0x4c SO_PASSSEC = 0x22 SO_PEEK_OFF = 0x2a SO_PEERCRED = 0x11 SO_PEERGROUPS = 0x3b + SO_PEERPIDFD = 0x4d SO_PEERSEC = 0x1f SO_PREFER_BUSY_POLL = 0x45 SO_PROTOCOL = 0x26 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go index f5f3934b1a..1bb7c6333b 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux_sparc64.go @@ -428,10 +428,12 @@ const ( SO_NOFCS = 0x27 SO_OOBINLINE = 0x100 SO_PASSCRED = 0x2 + SO_PASSPIDFD = 0x55 SO_PASSSEC = 0x1f SO_PEEK_OFF = 0x26 SO_PEERCRED = 0x40 SO_PEERGROUPS = 0x3d + SO_PEERPIDFD = 0x56 SO_PEERSEC = 0x1e SO_PREFER_BUSY_POLL = 0x48 SO_PROTOCOL = 0x1028 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go index 9a257219d7..d1d1d23311 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc.go @@ -817,28 +817,6 @@ func write(fd int, p []byte) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, p *byte, np int) (n int, err error) { - r0, er := C.read(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(p))), C.size_t(np)) - n = int(r0) - if r0 == -1 && er != nil { - err = er - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, p *byte, np int) (n int, err error) { - r0, er := C.write(C.int(fd), C.uintptr_t(uintptr(unsafe.Pointer(p))), C.size_t(np)) - n = int(r0) - if r0 == -1 && er != nil { - err = er - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Dup2(oldfd int, newfd int) (err error) { r0, er := C.dup2(C.int(oldfd), C.int(newfd)) if r0 == -1 && er != nil { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go index 6de80c20cf..f99a18adc3 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_aix_ppc64.go @@ -762,28 +762,6 @@ func write(fd int, p []byte) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, p *byte, np int) (n int, err error) { - r0, e1 := callread(fd, uintptr(unsafe.Pointer(p)), np) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, p *byte, np int) (n int, err error) { - r0, e1 := callwrite(fd, uintptr(unsafe.Pointer(p)), np) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Dup2(oldfd int, newfd int) (err error) { _, e1 := calldup2(oldfd, newfd) if e1 != 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go index 4037ccf7a9..1cad561e98 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go @@ -725,6 +725,12 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +var libc_ioctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -733,10 +739,6 @@ func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { return } -var libc_ioctl_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib" - // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { @@ -2410,28 +2412,6 @@ var libc_munmap_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fstat(fd int, stat *Stat_t) (err error) { _, _, e1 := syscall_syscall(libc_fstat64_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -2521,14 +2501,6 @@ func ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) { return } -func ptrace1Ptr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) { - _, _, e1 := syscall_syscall6(libc_ptrace_trampoline_addr, uintptr(request), uintptr(pid), addr, uintptr(data), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - var libc_ptrace_trampoline_addr uintptr //go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib" diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s index 4baaed0bc1..8b8bb28402 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s @@ -5,703 +5,586 @@ TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fdopendir(SB) - GLOBL ·libc_fdopendir_trampoline_addr(SB), RODATA, $8 DATA ·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB) TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgroups(SB) - GLOBL ·libc_getgroups_trampoline_addr(SB), RODATA, $8 DATA ·libc_getgroups_trampoline_addr(SB)/8, $libc_getgroups_trampoline<>(SB) TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setgroups(SB) - GLOBL ·libc_setgroups_trampoline_addr(SB), RODATA, $8 DATA ·libc_setgroups_trampoline_addr(SB)/8, $libc_setgroups_trampoline<>(SB) TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_wait4(SB) - GLOBL ·libc_wait4_trampoline_addr(SB), RODATA, $8 DATA ·libc_wait4_trampoline_addr(SB)/8, $libc_wait4_trampoline<>(SB) TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_accept(SB) - GLOBL ·libc_accept_trampoline_addr(SB), RODATA, $8 DATA ·libc_accept_trampoline_addr(SB)/8, $libc_accept_trampoline<>(SB) TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_bind(SB) - GLOBL ·libc_bind_trampoline_addr(SB), RODATA, $8 DATA ·libc_bind_trampoline_addr(SB)/8, $libc_bind_trampoline<>(SB) TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_connect(SB) - GLOBL ·libc_connect_trampoline_addr(SB), RODATA, $8 DATA ·libc_connect_trampoline_addr(SB)/8, $libc_connect_trampoline<>(SB) TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_socket(SB) - GLOBL ·libc_socket_trampoline_addr(SB), RODATA, $8 DATA ·libc_socket_trampoline_addr(SB)/8, $libc_socket_trampoline<>(SB) TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsockopt(SB) - GLOBL ·libc_getsockopt_trampoline_addr(SB), RODATA, $8 DATA ·libc_getsockopt_trampoline_addr(SB)/8, $libc_getsockopt_trampoline<>(SB) TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setsockopt(SB) - GLOBL ·libc_setsockopt_trampoline_addr(SB), RODATA, $8 DATA ·libc_setsockopt_trampoline_addr(SB)/8, $libc_setsockopt_trampoline<>(SB) TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpeername(SB) - GLOBL ·libc_getpeername_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpeername_trampoline_addr(SB)/8, $libc_getpeername_trampoline<>(SB) TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsockname(SB) - GLOBL ·libc_getsockname_trampoline_addr(SB), RODATA, $8 DATA ·libc_getsockname_trampoline_addr(SB)/8, $libc_getsockname_trampoline<>(SB) TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_shutdown(SB) - GLOBL ·libc_shutdown_trampoline_addr(SB), RODATA, $8 DATA ·libc_shutdown_trampoline_addr(SB)/8, $libc_shutdown_trampoline<>(SB) TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_socketpair(SB) - GLOBL ·libc_socketpair_trampoline_addr(SB), RODATA, $8 DATA ·libc_socketpair_trampoline_addr(SB)/8, $libc_socketpair_trampoline<>(SB) TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_recvfrom(SB) - GLOBL ·libc_recvfrom_trampoline_addr(SB), RODATA, $8 DATA ·libc_recvfrom_trampoline_addr(SB)/8, $libc_recvfrom_trampoline<>(SB) TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendto(SB) - GLOBL ·libc_sendto_trampoline_addr(SB), RODATA, $8 DATA ·libc_sendto_trampoline_addr(SB)/8, $libc_sendto_trampoline<>(SB) TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_recvmsg(SB) - GLOBL ·libc_recvmsg_trampoline_addr(SB), RODATA, $8 DATA ·libc_recvmsg_trampoline_addr(SB)/8, $libc_recvmsg_trampoline<>(SB) TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendmsg(SB) - GLOBL ·libc_sendmsg_trampoline_addr(SB), RODATA, $8 DATA ·libc_sendmsg_trampoline_addr(SB)/8, $libc_sendmsg_trampoline<>(SB) TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kevent(SB) - GLOBL ·libc_kevent_trampoline_addr(SB), RODATA, $8 DATA ·libc_kevent_trampoline_addr(SB)/8, $libc_kevent_trampoline<>(SB) TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_utimes(SB) - GLOBL ·libc_utimes_trampoline_addr(SB), RODATA, $8 DATA ·libc_utimes_trampoline_addr(SB)/8, $libc_utimes_trampoline<>(SB) TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_futimes(SB) - GLOBL ·libc_futimes_trampoline_addr(SB), RODATA, $8 DATA ·libc_futimes_trampoline_addr(SB)/8, $libc_futimes_trampoline<>(SB) TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_poll(SB) - GLOBL ·libc_poll_trampoline_addr(SB), RODATA, $8 DATA ·libc_poll_trampoline_addr(SB)/8, $libc_poll_trampoline<>(SB) TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_madvise(SB) - GLOBL ·libc_madvise_trampoline_addr(SB), RODATA, $8 DATA ·libc_madvise_trampoline_addr(SB)/8, $libc_madvise_trampoline<>(SB) TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mlock(SB) - GLOBL ·libc_mlock_trampoline_addr(SB), RODATA, $8 DATA ·libc_mlock_trampoline_addr(SB)/8, $libc_mlock_trampoline<>(SB) TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mlockall(SB) - GLOBL ·libc_mlockall_trampoline_addr(SB), RODATA, $8 DATA ·libc_mlockall_trampoline_addr(SB)/8, $libc_mlockall_trampoline<>(SB) TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mprotect(SB) - GLOBL ·libc_mprotect_trampoline_addr(SB), RODATA, $8 DATA ·libc_mprotect_trampoline_addr(SB)/8, $libc_mprotect_trampoline<>(SB) TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_msync(SB) - GLOBL ·libc_msync_trampoline_addr(SB), RODATA, $8 DATA ·libc_msync_trampoline_addr(SB)/8, $libc_msync_trampoline<>(SB) TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munlock(SB) - GLOBL ·libc_munlock_trampoline_addr(SB), RODATA, $8 DATA ·libc_munlock_trampoline_addr(SB)/8, $libc_munlock_trampoline<>(SB) TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munlockall(SB) - GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8 DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB) TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_closedir(SB) - GLOBL ·libc_closedir_trampoline_addr(SB), RODATA, $8 DATA ·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB) TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_readdir_r(SB) - GLOBL ·libc_readdir_r_trampoline_addr(SB), RODATA, $8 DATA ·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB) TEXT libc_pipe_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pipe(SB) - GLOBL ·libc_pipe_trampoline_addr(SB), RODATA, $8 DATA ·libc_pipe_trampoline_addr(SB)/8, $libc_pipe_trampoline<>(SB) TEXT libc_getxattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getxattr(SB) - GLOBL ·libc_getxattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_getxattr_trampoline_addr(SB)/8, $libc_getxattr_trampoline<>(SB) TEXT libc_fgetxattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fgetxattr(SB) - GLOBL ·libc_fgetxattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_fgetxattr_trampoline_addr(SB)/8, $libc_fgetxattr_trampoline<>(SB) TEXT libc_setxattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setxattr(SB) - GLOBL ·libc_setxattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_setxattr_trampoline_addr(SB)/8, $libc_setxattr_trampoline<>(SB) TEXT libc_fsetxattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fsetxattr(SB) - GLOBL ·libc_fsetxattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_fsetxattr_trampoline_addr(SB)/8, $libc_fsetxattr_trampoline<>(SB) TEXT libc_removexattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_removexattr(SB) - GLOBL ·libc_removexattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_removexattr_trampoline_addr(SB)/8, $libc_removexattr_trampoline<>(SB) TEXT libc_fremovexattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fremovexattr(SB) - GLOBL ·libc_fremovexattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_fremovexattr_trampoline_addr(SB)/8, $libc_fremovexattr_trampoline<>(SB) TEXT libc_listxattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_listxattr(SB) - GLOBL ·libc_listxattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_listxattr_trampoline_addr(SB)/8, $libc_listxattr_trampoline<>(SB) TEXT libc_flistxattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_flistxattr(SB) - GLOBL ·libc_flistxattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_flistxattr_trampoline_addr(SB)/8, $libc_flistxattr_trampoline<>(SB) TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_utimensat(SB) - GLOBL ·libc_utimensat_trampoline_addr(SB), RODATA, $8 DATA ·libc_utimensat_trampoline_addr(SB)/8, $libc_utimensat_trampoline<>(SB) TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fcntl(SB) - GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $8 DATA ·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB) TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kill(SB) - GLOBL ·libc_kill_trampoline_addr(SB), RODATA, $8 DATA ·libc_kill_trampoline_addr(SB)/8, $libc_kill_trampoline<>(SB) TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ioctl(SB) - GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB) TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sysctl(SB) - GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendfile(SB) - GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8 DATA ·libc_sendfile_trampoline_addr(SB)/8, $libc_sendfile_trampoline<>(SB) TEXT libc_shmat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_shmat(SB) - GLOBL ·libc_shmat_trampoline_addr(SB), RODATA, $8 DATA ·libc_shmat_trampoline_addr(SB)/8, $libc_shmat_trampoline<>(SB) TEXT libc_shmctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_shmctl(SB) - GLOBL ·libc_shmctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_shmctl_trampoline_addr(SB)/8, $libc_shmctl_trampoline<>(SB) TEXT libc_shmdt_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_shmdt(SB) - GLOBL ·libc_shmdt_trampoline_addr(SB), RODATA, $8 DATA ·libc_shmdt_trampoline_addr(SB)/8, $libc_shmdt_trampoline<>(SB) TEXT libc_shmget_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_shmget(SB) - GLOBL ·libc_shmget_trampoline_addr(SB), RODATA, $8 DATA ·libc_shmget_trampoline_addr(SB)/8, $libc_shmget_trampoline<>(SB) TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_access(SB) - GLOBL ·libc_access_trampoline_addr(SB), RODATA, $8 DATA ·libc_access_trampoline_addr(SB)/8, $libc_access_trampoline<>(SB) TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_adjtime(SB) - GLOBL ·libc_adjtime_trampoline_addr(SB), RODATA, $8 DATA ·libc_adjtime_trampoline_addr(SB)/8, $libc_adjtime_trampoline<>(SB) TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chdir(SB) - GLOBL ·libc_chdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_chdir_trampoline_addr(SB)/8, $libc_chdir_trampoline<>(SB) TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chflags(SB) - GLOBL ·libc_chflags_trampoline_addr(SB), RODATA, $8 DATA ·libc_chflags_trampoline_addr(SB)/8, $libc_chflags_trampoline<>(SB) TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chmod(SB) - GLOBL ·libc_chmod_trampoline_addr(SB), RODATA, $8 DATA ·libc_chmod_trampoline_addr(SB)/8, $libc_chmod_trampoline<>(SB) TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chown(SB) - GLOBL ·libc_chown_trampoline_addr(SB), RODATA, $8 DATA ·libc_chown_trampoline_addr(SB)/8, $libc_chown_trampoline<>(SB) TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chroot(SB) - GLOBL ·libc_chroot_trampoline_addr(SB), RODATA, $8 DATA ·libc_chroot_trampoline_addr(SB)/8, $libc_chroot_trampoline<>(SB) TEXT libc_clock_gettime_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_clock_gettime(SB) - GLOBL ·libc_clock_gettime_trampoline_addr(SB), RODATA, $8 DATA ·libc_clock_gettime_trampoline_addr(SB)/8, $libc_clock_gettime_trampoline<>(SB) TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_close(SB) - GLOBL ·libc_close_trampoline_addr(SB), RODATA, $8 DATA ·libc_close_trampoline_addr(SB)/8, $libc_close_trampoline<>(SB) TEXT libc_clonefile_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_clonefile(SB) - GLOBL ·libc_clonefile_trampoline_addr(SB), RODATA, $8 DATA ·libc_clonefile_trampoline_addr(SB)/8, $libc_clonefile_trampoline<>(SB) TEXT libc_clonefileat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_clonefileat(SB) - GLOBL ·libc_clonefileat_trampoline_addr(SB), RODATA, $8 DATA ·libc_clonefileat_trampoline_addr(SB)/8, $libc_clonefileat_trampoline<>(SB) TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup(SB) - GLOBL ·libc_dup_trampoline_addr(SB), RODATA, $8 DATA ·libc_dup_trampoline_addr(SB)/8, $libc_dup_trampoline<>(SB) TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup2(SB) - GLOBL ·libc_dup2_trampoline_addr(SB), RODATA, $8 DATA ·libc_dup2_trampoline_addr(SB)/8, $libc_dup2_trampoline<>(SB) TEXT libc_exchangedata_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_exchangedata(SB) - GLOBL ·libc_exchangedata_trampoline_addr(SB), RODATA, $8 DATA ·libc_exchangedata_trampoline_addr(SB)/8, $libc_exchangedata_trampoline<>(SB) TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_exit(SB) - GLOBL ·libc_exit_trampoline_addr(SB), RODATA, $8 DATA ·libc_exit_trampoline_addr(SB)/8, $libc_exit_trampoline<>(SB) TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_faccessat(SB) - GLOBL ·libc_faccessat_trampoline_addr(SB), RODATA, $8 DATA ·libc_faccessat_trampoline_addr(SB)/8, $libc_faccessat_trampoline<>(SB) TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchdir(SB) - GLOBL ·libc_fchdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchdir_trampoline_addr(SB)/8, $libc_fchdir_trampoline<>(SB) TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchflags(SB) - GLOBL ·libc_fchflags_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchflags_trampoline_addr(SB)/8, $libc_fchflags_trampoline<>(SB) TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchmod(SB) - GLOBL ·libc_fchmod_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchmod_trampoline_addr(SB)/8, $libc_fchmod_trampoline<>(SB) TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchmodat(SB) - GLOBL ·libc_fchmodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchmodat_trampoline_addr(SB)/8, $libc_fchmodat_trampoline<>(SB) TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchown(SB) - GLOBL ·libc_fchown_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchown_trampoline_addr(SB)/8, $libc_fchown_trampoline<>(SB) TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchownat(SB) - GLOBL ·libc_fchownat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchownat_trampoline_addr(SB)/8, $libc_fchownat_trampoline<>(SB) TEXT libc_fclonefileat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fclonefileat(SB) - GLOBL ·libc_fclonefileat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fclonefileat_trampoline_addr(SB)/8, $libc_fclonefileat_trampoline<>(SB) TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_flock(SB) - GLOBL ·libc_flock_trampoline_addr(SB), RODATA, $8 DATA ·libc_flock_trampoline_addr(SB)/8, $libc_flock_trampoline<>(SB) TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fpathconf(SB) - GLOBL ·libc_fpathconf_trampoline_addr(SB), RODATA, $8 DATA ·libc_fpathconf_trampoline_addr(SB)/8, $libc_fpathconf_trampoline<>(SB) TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fsync(SB) - GLOBL ·libc_fsync_trampoline_addr(SB), RODATA, $8 DATA ·libc_fsync_trampoline_addr(SB)/8, $libc_fsync_trampoline<>(SB) TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ftruncate(SB) - GLOBL ·libc_ftruncate_trampoline_addr(SB), RODATA, $8 DATA ·libc_ftruncate_trampoline_addr(SB)/8, $libc_ftruncate_trampoline<>(SB) TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getcwd(SB) - GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $8 DATA ·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB) TEXT libc_getdtablesize_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getdtablesize(SB) - GLOBL ·libc_getdtablesize_trampoline_addr(SB), RODATA, $8 DATA ·libc_getdtablesize_trampoline_addr(SB)/8, $libc_getdtablesize_trampoline<>(SB) TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getegid(SB) - GLOBL ·libc_getegid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getegid_trampoline_addr(SB)/8, $libc_getegid_trampoline<>(SB) TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_geteuid(SB) - GLOBL ·libc_geteuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_geteuid_trampoline_addr(SB)/8, $libc_geteuid_trampoline<>(SB) TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgid(SB) - GLOBL ·libc_getgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getgid_trampoline_addr(SB)/8, $libc_getgid_trampoline<>(SB) TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpgid(SB) - GLOBL ·libc_getpgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpgid_trampoline_addr(SB)/8, $libc_getpgid_trampoline<>(SB) TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpgrp(SB) - GLOBL ·libc_getpgrp_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpgrp_trampoline_addr(SB)/8, $libc_getpgrp_trampoline<>(SB) TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpid(SB) - GLOBL ·libc_getpid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpid_trampoline_addr(SB)/8, $libc_getpid_trampoline<>(SB) TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getppid(SB) - GLOBL ·libc_getppid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getppid_trampoline_addr(SB)/8, $libc_getppid_trampoline<>(SB) TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpriority(SB) - GLOBL ·libc_getpriority_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpriority_trampoline_addr(SB)/8, $libc_getpriority_trampoline<>(SB) TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrlimit(SB) - GLOBL ·libc_getrlimit_trampoline_addr(SB), RODATA, $8 DATA ·libc_getrlimit_trampoline_addr(SB)/8, $libc_getrlimit_trampoline<>(SB) TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrusage(SB) - GLOBL ·libc_getrusage_trampoline_addr(SB), RODATA, $8 DATA ·libc_getrusage_trampoline_addr(SB)/8, $libc_getrusage_trampoline<>(SB) TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsid(SB) - GLOBL ·libc_getsid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getsid_trampoline_addr(SB)/8, $libc_getsid_trampoline<>(SB) TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_gettimeofday(SB) - GLOBL ·libc_gettimeofday_trampoline_addr(SB), RODATA, $8 DATA ·libc_gettimeofday_trampoline_addr(SB)/8, $libc_gettimeofday_trampoline<>(SB) TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getuid(SB) - GLOBL ·libc_getuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getuid_trampoline_addr(SB)/8, $libc_getuid_trampoline<>(SB) TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_issetugid(SB) - GLOBL ·libc_issetugid_trampoline_addr(SB), RODATA, $8 DATA ·libc_issetugid_trampoline_addr(SB)/8, $libc_issetugid_trampoline<>(SB) TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kqueue(SB) - GLOBL ·libc_kqueue_trampoline_addr(SB), RODATA, $8 DATA ·libc_kqueue_trampoline_addr(SB)/8, $libc_kqueue_trampoline<>(SB) TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lchown(SB) - GLOBL ·libc_lchown_trampoline_addr(SB), RODATA, $8 DATA ·libc_lchown_trampoline_addr(SB)/8, $libc_lchown_trampoline<>(SB) TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_link(SB) - GLOBL ·libc_link_trampoline_addr(SB), RODATA, $8 DATA ·libc_link_trampoline_addr(SB)/8, $libc_link_trampoline<>(SB) TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_linkat(SB) - GLOBL ·libc_linkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_linkat_trampoline_addr(SB)/8, $libc_linkat_trampoline<>(SB) TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_listen(SB) - GLOBL ·libc_listen_trampoline_addr(SB), RODATA, $8 DATA ·libc_listen_trampoline_addr(SB)/8, $libc_listen_trampoline<>(SB) TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkdir(SB) - GLOBL ·libc_mkdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_mkdir_trampoline_addr(SB)/8, $libc_mkdir_trampoline<>(SB) TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkdirat(SB) - GLOBL ·libc_mkdirat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mkdirat_trampoline_addr(SB)/8, $libc_mkdirat_trampoline<>(SB) TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkfifo(SB) - GLOBL ·libc_mkfifo_trampoline_addr(SB), RODATA, $8 DATA ·libc_mkfifo_trampoline_addr(SB)/8, $libc_mkfifo_trampoline<>(SB) TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mknod(SB) - GLOBL ·libc_mknod_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknod_trampoline_addr(SB)/8, $libc_mknod_trampoline<>(SB) TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mount(SB) - GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $8 DATA ·libc_mount_trampoline_addr(SB)/8, $libc_mount_trampoline<>(SB) TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_open(SB) - GLOBL ·libc_open_trampoline_addr(SB), RODATA, $8 DATA ·libc_open_trampoline_addr(SB)/8, $libc_open_trampoline<>(SB) TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_openat(SB) - GLOBL ·libc_openat_trampoline_addr(SB), RODATA, $8 DATA ·libc_openat_trampoline_addr(SB)/8, $libc_openat_trampoline<>(SB) TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pathconf(SB) - GLOBL ·libc_pathconf_trampoline_addr(SB), RODATA, $8 DATA ·libc_pathconf_trampoline_addr(SB)/8, $libc_pathconf_trampoline<>(SB) TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pread(SB) - GLOBL ·libc_pread_trampoline_addr(SB), RODATA, $8 DATA ·libc_pread_trampoline_addr(SB)/8, $libc_pread_trampoline<>(SB) TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pwrite(SB) - GLOBL ·libc_pwrite_trampoline_addr(SB), RODATA, $8 DATA ·libc_pwrite_trampoline_addr(SB)/8, $libc_pwrite_trampoline<>(SB) TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_read(SB) - GLOBL ·libc_read_trampoline_addr(SB), RODATA, $8 DATA ·libc_read_trampoline_addr(SB)/8, $libc_read_trampoline<>(SB) TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_readlink(SB) - GLOBL ·libc_readlink_trampoline_addr(SB), RODATA, $8 DATA ·libc_readlink_trampoline_addr(SB)/8, $libc_readlink_trampoline<>(SB) TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_readlinkat(SB) - GLOBL ·libc_readlinkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_readlinkat_trampoline_addr(SB)/8, $libc_readlinkat_trampoline<>(SB) TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_rename(SB) - GLOBL ·libc_rename_trampoline_addr(SB), RODATA, $8 DATA ·libc_rename_trampoline_addr(SB)/8, $libc_rename_trampoline<>(SB) TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_renameat(SB) - GLOBL ·libc_renameat_trampoline_addr(SB), RODATA, $8 DATA ·libc_renameat_trampoline_addr(SB)/8, $libc_renameat_trampoline<>(SB) TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_revoke(SB) - GLOBL ·libc_revoke_trampoline_addr(SB), RODATA, $8 DATA ·libc_revoke_trampoline_addr(SB)/8, $libc_revoke_trampoline<>(SB) TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_rmdir(SB) - GLOBL ·libc_rmdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_rmdir_trampoline_addr(SB)/8, $libc_rmdir_trampoline<>(SB) TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lseek(SB) - GLOBL ·libc_lseek_trampoline_addr(SB), RODATA, $8 DATA ·libc_lseek_trampoline_addr(SB)/8, $libc_lseek_trampoline<>(SB) TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_select(SB) - GLOBL ·libc_select_trampoline_addr(SB), RODATA, $8 DATA ·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB) @@ -712,192 +595,160 @@ DATA ·libc_setattrlist_trampoline_addr(SB)/8, $libc_setattrlist_trampoline<>(SB TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setegid(SB) - GLOBL ·libc_setegid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setegid_trampoline_addr(SB)/8, $libc_setegid_trampoline<>(SB) TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_seteuid(SB) - GLOBL ·libc_seteuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_seteuid_trampoline_addr(SB)/8, $libc_seteuid_trampoline<>(SB) TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setgid(SB) - GLOBL ·libc_setgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setgid_trampoline_addr(SB)/8, $libc_setgid_trampoline<>(SB) TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setlogin(SB) - GLOBL ·libc_setlogin_trampoline_addr(SB), RODATA, $8 DATA ·libc_setlogin_trampoline_addr(SB)/8, $libc_setlogin_trampoline<>(SB) TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setpgid(SB) - GLOBL ·libc_setpgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setpgid_trampoline_addr(SB)/8, $libc_setpgid_trampoline<>(SB) TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setpriority(SB) - GLOBL ·libc_setpriority_trampoline_addr(SB), RODATA, $8 DATA ·libc_setpriority_trampoline_addr(SB)/8, $libc_setpriority_trampoline<>(SB) TEXT libc_setprivexec_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setprivexec(SB) - GLOBL ·libc_setprivexec_trampoline_addr(SB), RODATA, $8 DATA ·libc_setprivexec_trampoline_addr(SB)/8, $libc_setprivexec_trampoline<>(SB) TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setregid(SB) - GLOBL ·libc_setregid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setregid_trampoline_addr(SB)/8, $libc_setregid_trampoline<>(SB) TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setreuid(SB) - GLOBL ·libc_setreuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB) TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setsid(SB) - GLOBL ·libc_setsid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setsid_trampoline_addr(SB)/8, $libc_setsid_trampoline<>(SB) TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_settimeofday(SB) - GLOBL ·libc_settimeofday_trampoline_addr(SB), RODATA, $8 DATA ·libc_settimeofday_trampoline_addr(SB)/8, $libc_settimeofday_trampoline<>(SB) TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setuid(SB) - GLOBL ·libc_setuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setuid_trampoline_addr(SB)/8, $libc_setuid_trampoline<>(SB) TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_symlink(SB) - GLOBL ·libc_symlink_trampoline_addr(SB), RODATA, $8 DATA ·libc_symlink_trampoline_addr(SB)/8, $libc_symlink_trampoline<>(SB) TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_symlinkat(SB) - GLOBL ·libc_symlinkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_symlinkat_trampoline_addr(SB)/8, $libc_symlinkat_trampoline<>(SB) TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sync(SB) - GLOBL ·libc_sync_trampoline_addr(SB), RODATA, $8 DATA ·libc_sync_trampoline_addr(SB)/8, $libc_sync_trampoline<>(SB) TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_truncate(SB) - GLOBL ·libc_truncate_trampoline_addr(SB), RODATA, $8 DATA ·libc_truncate_trampoline_addr(SB)/8, $libc_truncate_trampoline<>(SB) TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_umask(SB) - GLOBL ·libc_umask_trampoline_addr(SB), RODATA, $8 DATA ·libc_umask_trampoline_addr(SB)/8, $libc_umask_trampoline<>(SB) TEXT libc_undelete_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_undelete(SB) - GLOBL ·libc_undelete_trampoline_addr(SB), RODATA, $8 DATA ·libc_undelete_trampoline_addr(SB)/8, $libc_undelete_trampoline<>(SB) TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unlink(SB) - GLOBL ·libc_unlink_trampoline_addr(SB), RODATA, $8 DATA ·libc_unlink_trampoline_addr(SB)/8, $libc_unlink_trampoline<>(SB) TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unlinkat(SB) - GLOBL ·libc_unlinkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_unlinkat_trampoline_addr(SB)/8, $libc_unlinkat_trampoline<>(SB) TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unmount(SB) - GLOBL ·libc_unmount_trampoline_addr(SB), RODATA, $8 DATA ·libc_unmount_trampoline_addr(SB)/8, $libc_unmount_trampoline<>(SB) TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_write(SB) - GLOBL ·libc_write_trampoline_addr(SB), RODATA, $8 DATA ·libc_write_trampoline_addr(SB)/8, $libc_write_trampoline<>(SB) TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mmap(SB) - GLOBL ·libc_mmap_trampoline_addr(SB), RODATA, $8 DATA ·libc_mmap_trampoline_addr(SB)/8, $libc_mmap_trampoline<>(SB) TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munmap(SB) - GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8 DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB) TEXT libc_fstat64_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstat64(SB) - GLOBL ·libc_fstat64_trampoline_addr(SB), RODATA, $8 DATA ·libc_fstat64_trampoline_addr(SB)/8, $libc_fstat64_trampoline<>(SB) TEXT libc_fstatat64_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstatat64(SB) - GLOBL ·libc_fstatat64_trampoline_addr(SB), RODATA, $8 DATA ·libc_fstatat64_trampoline_addr(SB)/8, $libc_fstatat64_trampoline<>(SB) TEXT libc_fstatfs64_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstatfs64(SB) - GLOBL ·libc_fstatfs64_trampoline_addr(SB), RODATA, $8 DATA ·libc_fstatfs64_trampoline_addr(SB)/8, $libc_fstatfs64_trampoline<>(SB) TEXT libc_getfsstat64_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getfsstat64(SB) - GLOBL ·libc_getfsstat64_trampoline_addr(SB), RODATA, $8 DATA ·libc_getfsstat64_trampoline_addr(SB)/8, $libc_getfsstat64_trampoline<>(SB) TEXT libc_lstat64_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lstat64(SB) - GLOBL ·libc_lstat64_trampoline_addr(SB), RODATA, $8 DATA ·libc_lstat64_trampoline_addr(SB)/8, $libc_lstat64_trampoline<>(SB) TEXT libc_ptrace_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ptrace(SB) - GLOBL ·libc_ptrace_trampoline_addr(SB), RODATA, $8 DATA ·libc_ptrace_trampoline_addr(SB)/8, $libc_ptrace_trampoline<>(SB) TEXT libc_stat64_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_stat64(SB) - GLOBL ·libc_stat64_trampoline_addr(SB), RODATA, $8 DATA ·libc_stat64_trampoline_addr(SB)/8, $libc_stat64_trampoline<>(SB) TEXT libc_statfs64_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_statfs64(SB) - GLOBL ·libc_statfs64_trampoline_addr(SB), RODATA, $8 DATA ·libc_statfs64_trampoline_addr(SB)/8, $libc_statfs64_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go index 51d6f3fb25..b18edbd0e3 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.go @@ -725,6 +725,12 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +var libc_ioctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -733,10 +739,6 @@ func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { return } -var libc_ioctl_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_ioctl ioctl "/usr/lib/libSystem.B.dylib" - // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { @@ -2410,28 +2412,6 @@ var libc_munmap_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func Fstat(fd int, stat *Stat_t) (err error) { _, _, e1 := syscall_syscall(libc_fstat_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0) if e1 != 0 { @@ -2521,14 +2501,6 @@ func ptrace1(request int, pid int, addr uintptr, data uintptr) (err error) { return } -func ptrace1Ptr(request int, pid int, addr uintptr, data unsafe.Pointer) (err error) { - _, _, e1 := syscall_syscall6(libc_ptrace_trampoline_addr, uintptr(request), uintptr(pid), addr, uintptr(data), 0, 0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - var libc_ptrace_trampoline_addr uintptr //go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib" diff --git a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s index c3b82c0379..08362c1ab7 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s +++ b/vendor/golang.org/x/sys/unix/zsyscall_darwin_arm64.s @@ -5,703 +5,586 @@ TEXT libc_fdopendir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fdopendir(SB) - GLOBL ·libc_fdopendir_trampoline_addr(SB), RODATA, $8 DATA ·libc_fdopendir_trampoline_addr(SB)/8, $libc_fdopendir_trampoline<>(SB) TEXT libc_getgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgroups(SB) - GLOBL ·libc_getgroups_trampoline_addr(SB), RODATA, $8 DATA ·libc_getgroups_trampoline_addr(SB)/8, $libc_getgroups_trampoline<>(SB) TEXT libc_setgroups_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setgroups(SB) - GLOBL ·libc_setgroups_trampoline_addr(SB), RODATA, $8 DATA ·libc_setgroups_trampoline_addr(SB)/8, $libc_setgroups_trampoline<>(SB) TEXT libc_wait4_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_wait4(SB) - GLOBL ·libc_wait4_trampoline_addr(SB), RODATA, $8 DATA ·libc_wait4_trampoline_addr(SB)/8, $libc_wait4_trampoline<>(SB) TEXT libc_accept_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_accept(SB) - GLOBL ·libc_accept_trampoline_addr(SB), RODATA, $8 DATA ·libc_accept_trampoline_addr(SB)/8, $libc_accept_trampoline<>(SB) TEXT libc_bind_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_bind(SB) - GLOBL ·libc_bind_trampoline_addr(SB), RODATA, $8 DATA ·libc_bind_trampoline_addr(SB)/8, $libc_bind_trampoline<>(SB) TEXT libc_connect_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_connect(SB) - GLOBL ·libc_connect_trampoline_addr(SB), RODATA, $8 DATA ·libc_connect_trampoline_addr(SB)/8, $libc_connect_trampoline<>(SB) TEXT libc_socket_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_socket(SB) - GLOBL ·libc_socket_trampoline_addr(SB), RODATA, $8 DATA ·libc_socket_trampoline_addr(SB)/8, $libc_socket_trampoline<>(SB) TEXT libc_getsockopt_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsockopt(SB) - GLOBL ·libc_getsockopt_trampoline_addr(SB), RODATA, $8 DATA ·libc_getsockopt_trampoline_addr(SB)/8, $libc_getsockopt_trampoline<>(SB) TEXT libc_setsockopt_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setsockopt(SB) - GLOBL ·libc_setsockopt_trampoline_addr(SB), RODATA, $8 DATA ·libc_setsockopt_trampoline_addr(SB)/8, $libc_setsockopt_trampoline<>(SB) TEXT libc_getpeername_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpeername(SB) - GLOBL ·libc_getpeername_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpeername_trampoline_addr(SB)/8, $libc_getpeername_trampoline<>(SB) TEXT libc_getsockname_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsockname(SB) - GLOBL ·libc_getsockname_trampoline_addr(SB), RODATA, $8 DATA ·libc_getsockname_trampoline_addr(SB)/8, $libc_getsockname_trampoline<>(SB) TEXT libc_shutdown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_shutdown(SB) - GLOBL ·libc_shutdown_trampoline_addr(SB), RODATA, $8 DATA ·libc_shutdown_trampoline_addr(SB)/8, $libc_shutdown_trampoline<>(SB) TEXT libc_socketpair_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_socketpair(SB) - GLOBL ·libc_socketpair_trampoline_addr(SB), RODATA, $8 DATA ·libc_socketpair_trampoline_addr(SB)/8, $libc_socketpair_trampoline<>(SB) TEXT libc_recvfrom_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_recvfrom(SB) - GLOBL ·libc_recvfrom_trampoline_addr(SB), RODATA, $8 DATA ·libc_recvfrom_trampoline_addr(SB)/8, $libc_recvfrom_trampoline<>(SB) TEXT libc_sendto_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendto(SB) - GLOBL ·libc_sendto_trampoline_addr(SB), RODATA, $8 DATA ·libc_sendto_trampoline_addr(SB)/8, $libc_sendto_trampoline<>(SB) TEXT libc_recvmsg_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_recvmsg(SB) - GLOBL ·libc_recvmsg_trampoline_addr(SB), RODATA, $8 DATA ·libc_recvmsg_trampoline_addr(SB)/8, $libc_recvmsg_trampoline<>(SB) TEXT libc_sendmsg_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendmsg(SB) - GLOBL ·libc_sendmsg_trampoline_addr(SB), RODATA, $8 DATA ·libc_sendmsg_trampoline_addr(SB)/8, $libc_sendmsg_trampoline<>(SB) TEXT libc_kevent_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kevent(SB) - GLOBL ·libc_kevent_trampoline_addr(SB), RODATA, $8 DATA ·libc_kevent_trampoline_addr(SB)/8, $libc_kevent_trampoline<>(SB) TEXT libc_utimes_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_utimes(SB) - GLOBL ·libc_utimes_trampoline_addr(SB), RODATA, $8 DATA ·libc_utimes_trampoline_addr(SB)/8, $libc_utimes_trampoline<>(SB) TEXT libc_futimes_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_futimes(SB) - GLOBL ·libc_futimes_trampoline_addr(SB), RODATA, $8 DATA ·libc_futimes_trampoline_addr(SB)/8, $libc_futimes_trampoline<>(SB) TEXT libc_poll_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_poll(SB) - GLOBL ·libc_poll_trampoline_addr(SB), RODATA, $8 DATA ·libc_poll_trampoline_addr(SB)/8, $libc_poll_trampoline<>(SB) TEXT libc_madvise_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_madvise(SB) - GLOBL ·libc_madvise_trampoline_addr(SB), RODATA, $8 DATA ·libc_madvise_trampoline_addr(SB)/8, $libc_madvise_trampoline<>(SB) TEXT libc_mlock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mlock(SB) - GLOBL ·libc_mlock_trampoline_addr(SB), RODATA, $8 DATA ·libc_mlock_trampoline_addr(SB)/8, $libc_mlock_trampoline<>(SB) TEXT libc_mlockall_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mlockall(SB) - GLOBL ·libc_mlockall_trampoline_addr(SB), RODATA, $8 DATA ·libc_mlockall_trampoline_addr(SB)/8, $libc_mlockall_trampoline<>(SB) TEXT libc_mprotect_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mprotect(SB) - GLOBL ·libc_mprotect_trampoline_addr(SB), RODATA, $8 DATA ·libc_mprotect_trampoline_addr(SB)/8, $libc_mprotect_trampoline<>(SB) TEXT libc_msync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_msync(SB) - GLOBL ·libc_msync_trampoline_addr(SB), RODATA, $8 DATA ·libc_msync_trampoline_addr(SB)/8, $libc_msync_trampoline<>(SB) TEXT libc_munlock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munlock(SB) - GLOBL ·libc_munlock_trampoline_addr(SB), RODATA, $8 DATA ·libc_munlock_trampoline_addr(SB)/8, $libc_munlock_trampoline<>(SB) TEXT libc_munlockall_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munlockall(SB) - GLOBL ·libc_munlockall_trampoline_addr(SB), RODATA, $8 DATA ·libc_munlockall_trampoline_addr(SB)/8, $libc_munlockall_trampoline<>(SB) TEXT libc_closedir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_closedir(SB) - GLOBL ·libc_closedir_trampoline_addr(SB), RODATA, $8 DATA ·libc_closedir_trampoline_addr(SB)/8, $libc_closedir_trampoline<>(SB) TEXT libc_readdir_r_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_readdir_r(SB) - GLOBL ·libc_readdir_r_trampoline_addr(SB), RODATA, $8 DATA ·libc_readdir_r_trampoline_addr(SB)/8, $libc_readdir_r_trampoline<>(SB) TEXT libc_pipe_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pipe(SB) - GLOBL ·libc_pipe_trampoline_addr(SB), RODATA, $8 DATA ·libc_pipe_trampoline_addr(SB)/8, $libc_pipe_trampoline<>(SB) TEXT libc_getxattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getxattr(SB) - GLOBL ·libc_getxattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_getxattr_trampoline_addr(SB)/8, $libc_getxattr_trampoline<>(SB) TEXT libc_fgetxattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fgetxattr(SB) - GLOBL ·libc_fgetxattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_fgetxattr_trampoline_addr(SB)/8, $libc_fgetxattr_trampoline<>(SB) TEXT libc_setxattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setxattr(SB) - GLOBL ·libc_setxattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_setxattr_trampoline_addr(SB)/8, $libc_setxattr_trampoline<>(SB) TEXT libc_fsetxattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fsetxattr(SB) - GLOBL ·libc_fsetxattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_fsetxattr_trampoline_addr(SB)/8, $libc_fsetxattr_trampoline<>(SB) TEXT libc_removexattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_removexattr(SB) - GLOBL ·libc_removexattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_removexattr_trampoline_addr(SB)/8, $libc_removexattr_trampoline<>(SB) TEXT libc_fremovexattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fremovexattr(SB) - GLOBL ·libc_fremovexattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_fremovexattr_trampoline_addr(SB)/8, $libc_fremovexattr_trampoline<>(SB) TEXT libc_listxattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_listxattr(SB) - GLOBL ·libc_listxattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_listxattr_trampoline_addr(SB)/8, $libc_listxattr_trampoline<>(SB) TEXT libc_flistxattr_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_flistxattr(SB) - GLOBL ·libc_flistxattr_trampoline_addr(SB), RODATA, $8 DATA ·libc_flistxattr_trampoline_addr(SB)/8, $libc_flistxattr_trampoline<>(SB) TEXT libc_utimensat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_utimensat(SB) - GLOBL ·libc_utimensat_trampoline_addr(SB), RODATA, $8 DATA ·libc_utimensat_trampoline_addr(SB)/8, $libc_utimensat_trampoline<>(SB) TEXT libc_fcntl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fcntl(SB) - GLOBL ·libc_fcntl_trampoline_addr(SB), RODATA, $8 DATA ·libc_fcntl_trampoline_addr(SB)/8, $libc_fcntl_trampoline<>(SB) TEXT libc_kill_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kill(SB) - GLOBL ·libc_kill_trampoline_addr(SB), RODATA, $8 DATA ·libc_kill_trampoline_addr(SB)/8, $libc_kill_trampoline<>(SB) TEXT libc_ioctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ioctl(SB) - GLOBL ·libc_ioctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_ioctl_trampoline_addr(SB)/8, $libc_ioctl_trampoline<>(SB) TEXT libc_sysctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sysctl(SB) - GLOBL ·libc_sysctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_sysctl_trampoline_addr(SB)/8, $libc_sysctl_trampoline<>(SB) TEXT libc_sendfile_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sendfile(SB) - GLOBL ·libc_sendfile_trampoline_addr(SB), RODATA, $8 DATA ·libc_sendfile_trampoline_addr(SB)/8, $libc_sendfile_trampoline<>(SB) TEXT libc_shmat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_shmat(SB) - GLOBL ·libc_shmat_trampoline_addr(SB), RODATA, $8 DATA ·libc_shmat_trampoline_addr(SB)/8, $libc_shmat_trampoline<>(SB) TEXT libc_shmctl_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_shmctl(SB) - GLOBL ·libc_shmctl_trampoline_addr(SB), RODATA, $8 DATA ·libc_shmctl_trampoline_addr(SB)/8, $libc_shmctl_trampoline<>(SB) TEXT libc_shmdt_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_shmdt(SB) - GLOBL ·libc_shmdt_trampoline_addr(SB), RODATA, $8 DATA ·libc_shmdt_trampoline_addr(SB)/8, $libc_shmdt_trampoline<>(SB) TEXT libc_shmget_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_shmget(SB) - GLOBL ·libc_shmget_trampoline_addr(SB), RODATA, $8 DATA ·libc_shmget_trampoline_addr(SB)/8, $libc_shmget_trampoline<>(SB) TEXT libc_access_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_access(SB) - GLOBL ·libc_access_trampoline_addr(SB), RODATA, $8 DATA ·libc_access_trampoline_addr(SB)/8, $libc_access_trampoline<>(SB) TEXT libc_adjtime_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_adjtime(SB) - GLOBL ·libc_adjtime_trampoline_addr(SB), RODATA, $8 DATA ·libc_adjtime_trampoline_addr(SB)/8, $libc_adjtime_trampoline<>(SB) TEXT libc_chdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chdir(SB) - GLOBL ·libc_chdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_chdir_trampoline_addr(SB)/8, $libc_chdir_trampoline<>(SB) TEXT libc_chflags_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chflags(SB) - GLOBL ·libc_chflags_trampoline_addr(SB), RODATA, $8 DATA ·libc_chflags_trampoline_addr(SB)/8, $libc_chflags_trampoline<>(SB) TEXT libc_chmod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chmod(SB) - GLOBL ·libc_chmod_trampoline_addr(SB), RODATA, $8 DATA ·libc_chmod_trampoline_addr(SB)/8, $libc_chmod_trampoline<>(SB) TEXT libc_chown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chown(SB) - GLOBL ·libc_chown_trampoline_addr(SB), RODATA, $8 DATA ·libc_chown_trampoline_addr(SB)/8, $libc_chown_trampoline<>(SB) TEXT libc_chroot_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_chroot(SB) - GLOBL ·libc_chroot_trampoline_addr(SB), RODATA, $8 DATA ·libc_chroot_trampoline_addr(SB)/8, $libc_chroot_trampoline<>(SB) TEXT libc_clock_gettime_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_clock_gettime(SB) - GLOBL ·libc_clock_gettime_trampoline_addr(SB), RODATA, $8 DATA ·libc_clock_gettime_trampoline_addr(SB)/8, $libc_clock_gettime_trampoline<>(SB) TEXT libc_close_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_close(SB) - GLOBL ·libc_close_trampoline_addr(SB), RODATA, $8 DATA ·libc_close_trampoline_addr(SB)/8, $libc_close_trampoline<>(SB) TEXT libc_clonefile_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_clonefile(SB) - GLOBL ·libc_clonefile_trampoline_addr(SB), RODATA, $8 DATA ·libc_clonefile_trampoline_addr(SB)/8, $libc_clonefile_trampoline<>(SB) TEXT libc_clonefileat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_clonefileat(SB) - GLOBL ·libc_clonefileat_trampoline_addr(SB), RODATA, $8 DATA ·libc_clonefileat_trampoline_addr(SB)/8, $libc_clonefileat_trampoline<>(SB) TEXT libc_dup_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup(SB) - GLOBL ·libc_dup_trampoline_addr(SB), RODATA, $8 DATA ·libc_dup_trampoline_addr(SB)/8, $libc_dup_trampoline<>(SB) TEXT libc_dup2_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_dup2(SB) - GLOBL ·libc_dup2_trampoline_addr(SB), RODATA, $8 DATA ·libc_dup2_trampoline_addr(SB)/8, $libc_dup2_trampoline<>(SB) TEXT libc_exchangedata_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_exchangedata(SB) - GLOBL ·libc_exchangedata_trampoline_addr(SB), RODATA, $8 DATA ·libc_exchangedata_trampoline_addr(SB)/8, $libc_exchangedata_trampoline<>(SB) TEXT libc_exit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_exit(SB) - GLOBL ·libc_exit_trampoline_addr(SB), RODATA, $8 DATA ·libc_exit_trampoline_addr(SB)/8, $libc_exit_trampoline<>(SB) TEXT libc_faccessat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_faccessat(SB) - GLOBL ·libc_faccessat_trampoline_addr(SB), RODATA, $8 DATA ·libc_faccessat_trampoline_addr(SB)/8, $libc_faccessat_trampoline<>(SB) TEXT libc_fchdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchdir(SB) - GLOBL ·libc_fchdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchdir_trampoline_addr(SB)/8, $libc_fchdir_trampoline<>(SB) TEXT libc_fchflags_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchflags(SB) - GLOBL ·libc_fchflags_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchflags_trampoline_addr(SB)/8, $libc_fchflags_trampoline<>(SB) TEXT libc_fchmod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchmod(SB) - GLOBL ·libc_fchmod_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchmod_trampoline_addr(SB)/8, $libc_fchmod_trampoline<>(SB) TEXT libc_fchmodat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchmodat(SB) - GLOBL ·libc_fchmodat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchmodat_trampoline_addr(SB)/8, $libc_fchmodat_trampoline<>(SB) TEXT libc_fchown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchown(SB) - GLOBL ·libc_fchown_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchown_trampoline_addr(SB)/8, $libc_fchown_trampoline<>(SB) TEXT libc_fchownat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fchownat(SB) - GLOBL ·libc_fchownat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fchownat_trampoline_addr(SB)/8, $libc_fchownat_trampoline<>(SB) TEXT libc_fclonefileat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fclonefileat(SB) - GLOBL ·libc_fclonefileat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fclonefileat_trampoline_addr(SB)/8, $libc_fclonefileat_trampoline<>(SB) TEXT libc_flock_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_flock(SB) - GLOBL ·libc_flock_trampoline_addr(SB), RODATA, $8 DATA ·libc_flock_trampoline_addr(SB)/8, $libc_flock_trampoline<>(SB) TEXT libc_fpathconf_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fpathconf(SB) - GLOBL ·libc_fpathconf_trampoline_addr(SB), RODATA, $8 DATA ·libc_fpathconf_trampoline_addr(SB)/8, $libc_fpathconf_trampoline<>(SB) TEXT libc_fsync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fsync(SB) - GLOBL ·libc_fsync_trampoline_addr(SB), RODATA, $8 DATA ·libc_fsync_trampoline_addr(SB)/8, $libc_fsync_trampoline<>(SB) TEXT libc_ftruncate_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ftruncate(SB) - GLOBL ·libc_ftruncate_trampoline_addr(SB), RODATA, $8 DATA ·libc_ftruncate_trampoline_addr(SB)/8, $libc_ftruncate_trampoline<>(SB) TEXT libc_getcwd_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getcwd(SB) - GLOBL ·libc_getcwd_trampoline_addr(SB), RODATA, $8 DATA ·libc_getcwd_trampoline_addr(SB)/8, $libc_getcwd_trampoline<>(SB) TEXT libc_getdtablesize_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getdtablesize(SB) - GLOBL ·libc_getdtablesize_trampoline_addr(SB), RODATA, $8 DATA ·libc_getdtablesize_trampoline_addr(SB)/8, $libc_getdtablesize_trampoline<>(SB) TEXT libc_getegid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getegid(SB) - GLOBL ·libc_getegid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getegid_trampoline_addr(SB)/8, $libc_getegid_trampoline<>(SB) TEXT libc_geteuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_geteuid(SB) - GLOBL ·libc_geteuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_geteuid_trampoline_addr(SB)/8, $libc_geteuid_trampoline<>(SB) TEXT libc_getgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getgid(SB) - GLOBL ·libc_getgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getgid_trampoline_addr(SB)/8, $libc_getgid_trampoline<>(SB) TEXT libc_getpgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpgid(SB) - GLOBL ·libc_getpgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpgid_trampoline_addr(SB)/8, $libc_getpgid_trampoline<>(SB) TEXT libc_getpgrp_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpgrp(SB) - GLOBL ·libc_getpgrp_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpgrp_trampoline_addr(SB)/8, $libc_getpgrp_trampoline<>(SB) TEXT libc_getpid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpid(SB) - GLOBL ·libc_getpid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpid_trampoline_addr(SB)/8, $libc_getpid_trampoline<>(SB) TEXT libc_getppid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getppid(SB) - GLOBL ·libc_getppid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getppid_trampoline_addr(SB)/8, $libc_getppid_trampoline<>(SB) TEXT libc_getpriority_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getpriority(SB) - GLOBL ·libc_getpriority_trampoline_addr(SB), RODATA, $8 DATA ·libc_getpriority_trampoline_addr(SB)/8, $libc_getpriority_trampoline<>(SB) TEXT libc_getrlimit_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrlimit(SB) - GLOBL ·libc_getrlimit_trampoline_addr(SB), RODATA, $8 DATA ·libc_getrlimit_trampoline_addr(SB)/8, $libc_getrlimit_trampoline<>(SB) TEXT libc_getrusage_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getrusage(SB) - GLOBL ·libc_getrusage_trampoline_addr(SB), RODATA, $8 DATA ·libc_getrusage_trampoline_addr(SB)/8, $libc_getrusage_trampoline<>(SB) TEXT libc_getsid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getsid(SB) - GLOBL ·libc_getsid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getsid_trampoline_addr(SB)/8, $libc_getsid_trampoline<>(SB) TEXT libc_gettimeofday_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_gettimeofday(SB) - GLOBL ·libc_gettimeofday_trampoline_addr(SB), RODATA, $8 DATA ·libc_gettimeofday_trampoline_addr(SB)/8, $libc_gettimeofday_trampoline<>(SB) TEXT libc_getuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getuid(SB) - GLOBL ·libc_getuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_getuid_trampoline_addr(SB)/8, $libc_getuid_trampoline<>(SB) TEXT libc_issetugid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_issetugid(SB) - GLOBL ·libc_issetugid_trampoline_addr(SB), RODATA, $8 DATA ·libc_issetugid_trampoline_addr(SB)/8, $libc_issetugid_trampoline<>(SB) TEXT libc_kqueue_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_kqueue(SB) - GLOBL ·libc_kqueue_trampoline_addr(SB), RODATA, $8 DATA ·libc_kqueue_trampoline_addr(SB)/8, $libc_kqueue_trampoline<>(SB) TEXT libc_lchown_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lchown(SB) - GLOBL ·libc_lchown_trampoline_addr(SB), RODATA, $8 DATA ·libc_lchown_trampoline_addr(SB)/8, $libc_lchown_trampoline<>(SB) TEXT libc_link_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_link(SB) - GLOBL ·libc_link_trampoline_addr(SB), RODATA, $8 DATA ·libc_link_trampoline_addr(SB)/8, $libc_link_trampoline<>(SB) TEXT libc_linkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_linkat(SB) - GLOBL ·libc_linkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_linkat_trampoline_addr(SB)/8, $libc_linkat_trampoline<>(SB) TEXT libc_listen_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_listen(SB) - GLOBL ·libc_listen_trampoline_addr(SB), RODATA, $8 DATA ·libc_listen_trampoline_addr(SB)/8, $libc_listen_trampoline<>(SB) TEXT libc_mkdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkdir(SB) - GLOBL ·libc_mkdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_mkdir_trampoline_addr(SB)/8, $libc_mkdir_trampoline<>(SB) TEXT libc_mkdirat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkdirat(SB) - GLOBL ·libc_mkdirat_trampoline_addr(SB), RODATA, $8 DATA ·libc_mkdirat_trampoline_addr(SB)/8, $libc_mkdirat_trampoline<>(SB) TEXT libc_mkfifo_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mkfifo(SB) - GLOBL ·libc_mkfifo_trampoline_addr(SB), RODATA, $8 DATA ·libc_mkfifo_trampoline_addr(SB)/8, $libc_mkfifo_trampoline<>(SB) TEXT libc_mknod_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mknod(SB) - GLOBL ·libc_mknod_trampoline_addr(SB), RODATA, $8 DATA ·libc_mknod_trampoline_addr(SB)/8, $libc_mknod_trampoline<>(SB) TEXT libc_mount_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mount(SB) - GLOBL ·libc_mount_trampoline_addr(SB), RODATA, $8 DATA ·libc_mount_trampoline_addr(SB)/8, $libc_mount_trampoline<>(SB) TEXT libc_open_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_open(SB) - GLOBL ·libc_open_trampoline_addr(SB), RODATA, $8 DATA ·libc_open_trampoline_addr(SB)/8, $libc_open_trampoline<>(SB) TEXT libc_openat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_openat(SB) - GLOBL ·libc_openat_trampoline_addr(SB), RODATA, $8 DATA ·libc_openat_trampoline_addr(SB)/8, $libc_openat_trampoline<>(SB) TEXT libc_pathconf_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pathconf(SB) - GLOBL ·libc_pathconf_trampoline_addr(SB), RODATA, $8 DATA ·libc_pathconf_trampoline_addr(SB)/8, $libc_pathconf_trampoline<>(SB) TEXT libc_pread_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pread(SB) - GLOBL ·libc_pread_trampoline_addr(SB), RODATA, $8 DATA ·libc_pread_trampoline_addr(SB)/8, $libc_pread_trampoline<>(SB) TEXT libc_pwrite_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_pwrite(SB) - GLOBL ·libc_pwrite_trampoline_addr(SB), RODATA, $8 DATA ·libc_pwrite_trampoline_addr(SB)/8, $libc_pwrite_trampoline<>(SB) TEXT libc_read_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_read(SB) - GLOBL ·libc_read_trampoline_addr(SB), RODATA, $8 DATA ·libc_read_trampoline_addr(SB)/8, $libc_read_trampoline<>(SB) TEXT libc_readlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_readlink(SB) - GLOBL ·libc_readlink_trampoline_addr(SB), RODATA, $8 DATA ·libc_readlink_trampoline_addr(SB)/8, $libc_readlink_trampoline<>(SB) TEXT libc_readlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_readlinkat(SB) - GLOBL ·libc_readlinkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_readlinkat_trampoline_addr(SB)/8, $libc_readlinkat_trampoline<>(SB) TEXT libc_rename_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_rename(SB) - GLOBL ·libc_rename_trampoline_addr(SB), RODATA, $8 DATA ·libc_rename_trampoline_addr(SB)/8, $libc_rename_trampoline<>(SB) TEXT libc_renameat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_renameat(SB) - GLOBL ·libc_renameat_trampoline_addr(SB), RODATA, $8 DATA ·libc_renameat_trampoline_addr(SB)/8, $libc_renameat_trampoline<>(SB) TEXT libc_revoke_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_revoke(SB) - GLOBL ·libc_revoke_trampoline_addr(SB), RODATA, $8 DATA ·libc_revoke_trampoline_addr(SB)/8, $libc_revoke_trampoline<>(SB) TEXT libc_rmdir_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_rmdir(SB) - GLOBL ·libc_rmdir_trampoline_addr(SB), RODATA, $8 DATA ·libc_rmdir_trampoline_addr(SB)/8, $libc_rmdir_trampoline<>(SB) TEXT libc_lseek_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lseek(SB) - GLOBL ·libc_lseek_trampoline_addr(SB), RODATA, $8 DATA ·libc_lseek_trampoline_addr(SB)/8, $libc_lseek_trampoline<>(SB) TEXT libc_select_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_select(SB) - GLOBL ·libc_select_trampoline_addr(SB), RODATA, $8 DATA ·libc_select_trampoline_addr(SB)/8, $libc_select_trampoline<>(SB) @@ -712,192 +595,160 @@ DATA ·libc_setattrlist_trampoline_addr(SB)/8, $libc_setattrlist_trampoline<>(SB TEXT libc_setegid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setegid(SB) - GLOBL ·libc_setegid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setegid_trampoline_addr(SB)/8, $libc_setegid_trampoline<>(SB) TEXT libc_seteuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_seteuid(SB) - GLOBL ·libc_seteuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_seteuid_trampoline_addr(SB)/8, $libc_seteuid_trampoline<>(SB) TEXT libc_setgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setgid(SB) - GLOBL ·libc_setgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setgid_trampoline_addr(SB)/8, $libc_setgid_trampoline<>(SB) TEXT libc_setlogin_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setlogin(SB) - GLOBL ·libc_setlogin_trampoline_addr(SB), RODATA, $8 DATA ·libc_setlogin_trampoline_addr(SB)/8, $libc_setlogin_trampoline<>(SB) TEXT libc_setpgid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setpgid(SB) - GLOBL ·libc_setpgid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setpgid_trampoline_addr(SB)/8, $libc_setpgid_trampoline<>(SB) TEXT libc_setpriority_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setpriority(SB) - GLOBL ·libc_setpriority_trampoline_addr(SB), RODATA, $8 DATA ·libc_setpriority_trampoline_addr(SB)/8, $libc_setpriority_trampoline<>(SB) TEXT libc_setprivexec_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setprivexec(SB) - GLOBL ·libc_setprivexec_trampoline_addr(SB), RODATA, $8 DATA ·libc_setprivexec_trampoline_addr(SB)/8, $libc_setprivexec_trampoline<>(SB) TEXT libc_setregid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setregid(SB) - GLOBL ·libc_setregid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setregid_trampoline_addr(SB)/8, $libc_setregid_trampoline<>(SB) TEXT libc_setreuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setreuid(SB) - GLOBL ·libc_setreuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setreuid_trampoline_addr(SB)/8, $libc_setreuid_trampoline<>(SB) TEXT libc_setsid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setsid(SB) - GLOBL ·libc_setsid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setsid_trampoline_addr(SB)/8, $libc_setsid_trampoline<>(SB) TEXT libc_settimeofday_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_settimeofday(SB) - GLOBL ·libc_settimeofday_trampoline_addr(SB), RODATA, $8 DATA ·libc_settimeofday_trampoline_addr(SB)/8, $libc_settimeofday_trampoline<>(SB) TEXT libc_setuid_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_setuid(SB) - GLOBL ·libc_setuid_trampoline_addr(SB), RODATA, $8 DATA ·libc_setuid_trampoline_addr(SB)/8, $libc_setuid_trampoline<>(SB) TEXT libc_symlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_symlink(SB) - GLOBL ·libc_symlink_trampoline_addr(SB), RODATA, $8 DATA ·libc_symlink_trampoline_addr(SB)/8, $libc_symlink_trampoline<>(SB) TEXT libc_symlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_symlinkat(SB) - GLOBL ·libc_symlinkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_symlinkat_trampoline_addr(SB)/8, $libc_symlinkat_trampoline<>(SB) TEXT libc_sync_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_sync(SB) - GLOBL ·libc_sync_trampoline_addr(SB), RODATA, $8 DATA ·libc_sync_trampoline_addr(SB)/8, $libc_sync_trampoline<>(SB) TEXT libc_truncate_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_truncate(SB) - GLOBL ·libc_truncate_trampoline_addr(SB), RODATA, $8 DATA ·libc_truncate_trampoline_addr(SB)/8, $libc_truncate_trampoline<>(SB) TEXT libc_umask_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_umask(SB) - GLOBL ·libc_umask_trampoline_addr(SB), RODATA, $8 DATA ·libc_umask_trampoline_addr(SB)/8, $libc_umask_trampoline<>(SB) TEXT libc_undelete_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_undelete(SB) - GLOBL ·libc_undelete_trampoline_addr(SB), RODATA, $8 DATA ·libc_undelete_trampoline_addr(SB)/8, $libc_undelete_trampoline<>(SB) TEXT libc_unlink_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unlink(SB) - GLOBL ·libc_unlink_trampoline_addr(SB), RODATA, $8 DATA ·libc_unlink_trampoline_addr(SB)/8, $libc_unlink_trampoline<>(SB) TEXT libc_unlinkat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unlinkat(SB) - GLOBL ·libc_unlinkat_trampoline_addr(SB), RODATA, $8 DATA ·libc_unlinkat_trampoline_addr(SB)/8, $libc_unlinkat_trampoline<>(SB) TEXT libc_unmount_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_unmount(SB) - GLOBL ·libc_unmount_trampoline_addr(SB), RODATA, $8 DATA ·libc_unmount_trampoline_addr(SB)/8, $libc_unmount_trampoline<>(SB) TEXT libc_write_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_write(SB) - GLOBL ·libc_write_trampoline_addr(SB), RODATA, $8 DATA ·libc_write_trampoline_addr(SB)/8, $libc_write_trampoline<>(SB) TEXT libc_mmap_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_mmap(SB) - GLOBL ·libc_mmap_trampoline_addr(SB), RODATA, $8 DATA ·libc_mmap_trampoline_addr(SB)/8, $libc_mmap_trampoline<>(SB) TEXT libc_munmap_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_munmap(SB) - GLOBL ·libc_munmap_trampoline_addr(SB), RODATA, $8 DATA ·libc_munmap_trampoline_addr(SB)/8, $libc_munmap_trampoline<>(SB) TEXT libc_fstat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstat(SB) - GLOBL ·libc_fstat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fstat_trampoline_addr(SB)/8, $libc_fstat_trampoline<>(SB) TEXT libc_fstatat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstatat(SB) - GLOBL ·libc_fstatat_trampoline_addr(SB), RODATA, $8 DATA ·libc_fstatat_trampoline_addr(SB)/8, $libc_fstatat_trampoline<>(SB) TEXT libc_fstatfs_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_fstatfs(SB) - GLOBL ·libc_fstatfs_trampoline_addr(SB), RODATA, $8 DATA ·libc_fstatfs_trampoline_addr(SB)/8, $libc_fstatfs_trampoline<>(SB) TEXT libc_getfsstat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_getfsstat(SB) - GLOBL ·libc_getfsstat_trampoline_addr(SB), RODATA, $8 DATA ·libc_getfsstat_trampoline_addr(SB)/8, $libc_getfsstat_trampoline<>(SB) TEXT libc_lstat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_lstat(SB) - GLOBL ·libc_lstat_trampoline_addr(SB), RODATA, $8 DATA ·libc_lstat_trampoline_addr(SB)/8, $libc_lstat_trampoline<>(SB) TEXT libc_ptrace_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_ptrace(SB) - GLOBL ·libc_ptrace_trampoline_addr(SB), RODATA, $8 DATA ·libc_ptrace_trampoline_addr(SB)/8, $libc_ptrace_trampoline<>(SB) TEXT libc_stat_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_stat(SB) - GLOBL ·libc_stat_trampoline_addr(SB), RODATA, $8 DATA ·libc_stat_trampoline_addr(SB)/8, $libc_stat_trampoline<>(SB) TEXT libc_statfs_trampoline<>(SB),NOSPLIT,$0-0 JMP libc_statfs(SB) - GLOBL ·libc_statfs_trampoline_addr(SB), RODATA, $8 DATA ·libc_statfs_trampoline_addr(SB)/8, $libc_statfs_trampoline<>(SB) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go index 0eabac7ade..0c67df64a5 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_dragonfly_amd64.go @@ -1642,28 +1642,6 @@ func munmap(addr uintptr, length uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) { r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) nfd = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go index ee313eb007..e6e05d145b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_386.go @@ -1862,28 +1862,6 @@ func munmap(addr uintptr, length uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) { r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) nfd = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go index 4c986e448e..7508accac9 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_amd64.go @@ -1862,28 +1862,6 @@ func munmap(addr uintptr, length uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) { r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) nfd = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go index 555216944a..7b56aead46 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm.go @@ -1862,28 +1862,6 @@ func munmap(addr uintptr, length uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) { r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) nfd = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go index 67a226fbf5..cc623dcaae 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_arm64.go @@ -1862,28 +1862,6 @@ func munmap(addr uintptr, length uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) { r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) nfd = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go index f0b9ddaaa2..5818491974 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_freebsd_riscv64.go @@ -1862,28 +1862,6 @@ func munmap(addr uintptr, length uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func accept4(fd int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (nfd int, err error) { r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) nfd = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go index b57c7050d7..6be25cd190 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go @@ -40,7 +40,7 @@ func readv(fd int, iovs []Iovec) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procreadv)), 3, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(iovs)), 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -55,7 +55,7 @@ func preadv(fd int, iovs []Iovec, off int64) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procpreadv)), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(iovs)), uintptr(off), 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -70,7 +70,7 @@ func writev(fd int, iovs []Iovec) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procwritev)), 3, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(iovs)), 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -85,7 +85,7 @@ func pwritev(fd int, iovs []Iovec, off int64) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procpwritev)), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(iovs)), uintptr(off), 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -96,7 +96,7 @@ func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procaccept4)), 4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0) fd = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 14ab34a565..1ff3aec74c 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -1734,28 +1734,6 @@ func exitThread(code int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, p *byte, np int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, p *byte, np int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(p)), uintptr(np)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func readv(fd int, iovs []Iovec) (n int, err error) { var _p0 unsafe.Pointer if len(iovs) > 0 { diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go index 35f499b32a..2df3c5bac6 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_386.go @@ -1824,28 +1824,6 @@ func munmap(addr uintptr, length uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go index 3cda65b0da..a60556babb 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_amd64.go @@ -1824,28 +1824,6 @@ func munmap(addr uintptr, length uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go index 1e1fea902b..9f788917a4 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm.go @@ -1824,28 +1824,6 @@ func munmap(addr uintptr, length uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go index 3b77da1107..82a4cb2dc4 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_netbsd_arm64.go @@ -1824,28 +1824,6 @@ func munmap(addr uintptr, length uintptr) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := Syscall(SYS_WRITE, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go index 9ab9abf721..66b3b64563 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_386.go @@ -549,6 +549,12 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +var libc_ioctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -557,10 +563,6 @@ func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { return } -var libc_ioctl_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" - // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { @@ -2211,28 +2213,6 @@ var libc_munmap_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go index 915761eab7..c5c4cc112e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_amd64.go @@ -2213,28 +2213,6 @@ var libc_munmap_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go index 8e87fdf153..93bfbb3287 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm.go @@ -549,6 +549,12 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +var libc_ioctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -557,10 +563,6 @@ func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { return } -var libc_ioctl_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" - // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { @@ -2211,28 +2213,6 @@ var libc_munmap_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go index 12a7a2160e..a107b8fda5 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_arm64.go @@ -549,6 +549,12 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +var libc_ioctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -557,10 +563,6 @@ func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { return } -var libc_ioctl_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" - // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { @@ -2211,28 +2213,6 @@ var libc_munmap_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go index b19e8aa031..c427de509e 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_mips64.go @@ -549,6 +549,12 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +var libc_ioctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -557,10 +563,6 @@ func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { return } -var libc_ioctl_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" - // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { @@ -2211,28 +2213,6 @@ var libc_munmap_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go index fb99594c93..60c1a99ae4 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_ppc64.go @@ -549,6 +549,12 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +var libc_ioctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -557,10 +563,6 @@ func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { return } -var libc_ioctl_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" - // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { @@ -2211,28 +2213,6 @@ var libc_munmap_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go index 32cbbbc52b..52eba360f8 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_openbsd_riscv64.go @@ -549,6 +549,12 @@ func ioctl(fd int, req uint, arg uintptr) (err error) { return } +var libc_ioctl_trampoline_addr uintptr + +//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { _, _, e1 := syscall_syscall(libc_ioctl_trampoline_addr, uintptr(fd), uintptr(req), uintptr(arg)) if e1 != 0 { @@ -557,10 +563,6 @@ func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) { return } -var libc_ioctl_trampoline_addr uintptr - -//go:cgo_import_dynamic libc_ioctl ioctl "libc.so" - // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT func sysctl(mib []_C_int, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { @@ -2211,28 +2213,6 @@ var libc_munmap_trampoline_addr uintptr // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_read_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - -func writelen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(libc_write_trampoline_addr, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func utimensat(dirfd int, path string, times *[2]Timespec, flags int) (err error) { var _p0 *byte _p0, err = BytePtrFromString(path) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index 609d1c598a..b401894644 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -436,7 +436,7 @@ func pipe(p *[2]_C_int) (n int, err error) { r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procpipe)), 1, uintptr(unsafe.Pointer(p)), 0, 0, 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -446,7 +446,7 @@ func pipe(p *[2]_C_int) (n int, err error) { func pipe2(p *[2]_C_int, flags int) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procpipe2)), 2, uintptr(unsafe.Pointer(p)), uintptr(flags), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -456,7 +456,7 @@ func pipe2(p *[2]_C_int, flags int) (err error) { func getsockname(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetsockname)), 3, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -471,7 +471,7 @@ func Getcwd(buf []byte) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procGetcwd)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0, 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -482,7 +482,7 @@ func getgroups(ngid int, gid *_Gid_t) (n int, err error) { r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procgetgroups)), 2, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0, 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -492,7 +492,7 @@ func getgroups(ngid int, gid *_Gid_t) (n int, err error) { func setgroups(ngid int, gid *_Gid_t) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procsetgroups)), 2, uintptr(ngid), uintptr(unsafe.Pointer(gid)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -503,7 +503,7 @@ func wait4(pid int32, statusp *_C_int, options int, rusage *Rusage) (wpid int32, r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procwait4)), 4, uintptr(pid), uintptr(unsafe.Pointer(statusp)), uintptr(options), uintptr(unsafe.Pointer(rusage)), 0, 0) wpid = int32(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -518,7 +518,7 @@ func gethostname(buf []byte) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgethostname)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0, 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -533,7 +533,7 @@ func utimes(path string, times *[2]Timeval) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procutimes)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -548,7 +548,7 @@ func utimensat(fd int, path string, times *[2]Timespec, flag int) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procutimensat)), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(times)), uintptr(flag), 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -559,7 +559,7 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procfcntl)), 3, uintptr(fd), uintptr(cmd), uintptr(arg), 0, 0, 0) val = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -569,7 +569,7 @@ func fcntl(fd int, cmd int, arg int) (val int, err error) { func futimesat(fildes int, path *byte, times *[2]Timeval) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procfutimesat)), 3, uintptr(fildes), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(times)), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -580,7 +580,7 @@ func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procaccept)), 3, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) fd = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -591,7 +591,7 @@ func recvmsg(s int, msg *Msghdr, flags int) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proc__xnet_recvmsg)), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -602,7 +602,7 @@ func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proc__xnet_sendmsg)), 3, uintptr(s), uintptr(unsafe.Pointer(msg)), uintptr(flags), 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -612,7 +612,7 @@ func sendmsg(s int, msg *Msghdr, flags int) (n int, err error) { func acct(path *byte) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procacct)), 1, uintptr(unsafe.Pointer(path)), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -647,7 +647,7 @@ func ioctlRet(fd int, req int, arg uintptr) (ret int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0) ret = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -658,7 +658,7 @@ func ioctlPtrRet(fd int, req int, arg unsafe.Pointer) (ret int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0) ret = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -669,7 +669,7 @@ func poll(fds *PollFd, nfds int, timeout int) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procpoll)), 3, uintptr(unsafe.Pointer(fds)), uintptr(nfds), uintptr(timeout), 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -684,7 +684,7 @@ func Access(path string, mode uint32) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procAccess)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -694,7 +694,7 @@ func Access(path string, mode uint32) (err error) { func Adjtime(delta *Timeval, olddelta *Timeval) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procAdjtime)), 2, uintptr(unsafe.Pointer(delta)), uintptr(unsafe.Pointer(olddelta)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -709,7 +709,7 @@ func Chdir(path string) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procChdir)), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -724,7 +724,7 @@ func Chmod(path string, mode uint32) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procChmod)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -739,7 +739,7 @@ func Chown(path string, uid int, gid int) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procChown)), 3, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -754,7 +754,7 @@ func Chroot(path string) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procChroot)), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -764,7 +764,7 @@ func Chroot(path string) (err error) { func ClockGettime(clockid int32, time *Timespec) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procClockGettime)), 2, uintptr(clockid), uintptr(unsafe.Pointer(time)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -774,7 +774,7 @@ func ClockGettime(clockid int32, time *Timespec) (err error) { func Close(fd int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procClose)), 1, uintptr(fd), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -790,7 +790,7 @@ func Creat(path string, mode uint32) (fd int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procCreat)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0) fd = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -801,7 +801,7 @@ func Dup(fd int) (nfd int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procDup)), 1, uintptr(fd), 0, 0, 0, 0, 0) nfd = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -811,7 +811,7 @@ func Dup(fd int) (nfd int, err error) { func Dup2(oldfd int, newfd int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procDup2)), 2, uintptr(oldfd), uintptr(newfd), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -833,7 +833,7 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFaccessat)), 4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -843,7 +843,7 @@ func Faccessat(dirfd int, path string, mode uint32, flags int) (err error) { func Fchdir(fd int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFchdir)), 1, uintptr(fd), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -853,7 +853,7 @@ func Fchdir(fd int) (err error) { func Fchmod(fd int, mode uint32) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFchmod)), 2, uintptr(fd), uintptr(mode), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -868,7 +868,7 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFchmodat)), 4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(flags), 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -878,7 +878,7 @@ func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) { func Fchown(fd int, uid int, gid int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFchown)), 3, uintptr(fd), uintptr(uid), uintptr(gid), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -893,7 +893,7 @@ func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFchownat)), 5, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), uintptr(flags), 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -903,7 +903,7 @@ func Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) { func Fdatasync(fd int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFdatasync)), 1, uintptr(fd), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -913,7 +913,7 @@ func Fdatasync(fd int) (err error) { func Flock(fd int, how int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFlock)), 2, uintptr(fd), uintptr(how), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -924,7 +924,7 @@ func Fpathconf(fd int, name int) (val int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFpathconf)), 2, uintptr(fd), uintptr(name), 0, 0, 0, 0) val = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -934,7 +934,7 @@ func Fpathconf(fd int, name int) (val int, err error) { func Fstat(fd int, stat *Stat_t) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFstat)), 2, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -949,7 +949,7 @@ func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFstatat)), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -959,7 +959,7 @@ func Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) { func Fstatvfs(fd int, vfsstat *Statvfs_t) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFstatvfs)), 2, uintptr(fd), uintptr(unsafe.Pointer(vfsstat)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -974,7 +974,7 @@ func Getdents(fd int, buf []byte, basep *uintptr) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procGetdents)), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1001,7 +1001,7 @@ func Getpgid(pid int) (pgid int, err error) { r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procGetpgid)), 1, uintptr(pid), 0, 0, 0, 0, 0) pgid = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1012,7 +1012,7 @@ func Getpgrp() (pgid int, err error) { r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procGetpgrp)), 0, 0, 0, 0, 0, 0, 0) pgid = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1047,7 +1047,7 @@ func Getpriority(which int, who int) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procGetpriority)), 2, uintptr(which), uintptr(who), 0, 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1057,7 +1057,7 @@ func Getpriority(which int, who int) (n int, err error) { func Getrlimit(which int, lim *Rlimit) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procGetrlimit)), 2, uintptr(which), uintptr(unsafe.Pointer(lim)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1067,7 +1067,7 @@ func Getrlimit(which int, lim *Rlimit) (err error) { func Getrusage(who int, rusage *Rusage) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procGetrusage)), 2, uintptr(who), uintptr(unsafe.Pointer(rusage)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1078,7 +1078,7 @@ func Getsid(pid int) (sid int, err error) { r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procGetsid)), 1, uintptr(pid), 0, 0, 0, 0, 0) sid = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1088,7 +1088,7 @@ func Getsid(pid int) (sid int, err error) { func Gettimeofday(tv *Timeval) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procGettimeofday)), 1, uintptr(unsafe.Pointer(tv)), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1106,7 +1106,7 @@ func Getuid() (uid int) { func Kill(pid int, signum syscall.Signal) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procKill)), 2, uintptr(pid), uintptr(signum), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1121,7 +1121,7 @@ func Lchown(path string, uid int, gid int) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procLchown)), 3, uintptr(unsafe.Pointer(_p0)), uintptr(uid), uintptr(gid), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1141,7 +1141,7 @@ func Link(path string, link string) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procLink)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1151,7 +1151,7 @@ func Link(path string, link string) (err error) { func Listen(s int, backlog int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proc__xnet_llisten)), 2, uintptr(s), uintptr(backlog), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1166,7 +1166,7 @@ func Lstat(path string, stat *Stat_t) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procLstat)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1180,7 +1180,7 @@ func Madvise(b []byte, advice int) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMadvise)), 3, uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(advice), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1195,7 +1195,7 @@ func Mkdir(path string, mode uint32) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMkdir)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1210,7 +1210,7 @@ func Mkdirat(dirfd int, path string, mode uint32) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMkdirat)), 3, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1225,7 +1225,7 @@ func Mkfifo(path string, mode uint32) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMkfifo)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1240,7 +1240,7 @@ func Mkfifoat(dirfd int, path string, mode uint32) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMkfifoat)), 3, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1255,7 +1255,7 @@ func Mknod(path string, mode uint32, dev int) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMknod)), 3, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1270,7 +1270,7 @@ func Mknodat(dirfd int, path string, mode uint32, dev int) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMknodat)), 4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(dev), 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1284,7 +1284,7 @@ func Mlock(b []byte) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMlock)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1294,7 +1294,7 @@ func Mlock(b []byte) (err error) { func Mlockall(flags int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMlockall)), 1, uintptr(flags), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1308,7 +1308,7 @@ func Mprotect(b []byte, prot int) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMprotect)), 3, uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(prot), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1322,7 +1322,7 @@ func Msync(b []byte, flags int) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMsync)), 3, uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(flags), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1336,7 +1336,7 @@ func Munlock(b []byte) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMunlock)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1346,7 +1346,7 @@ func Munlock(b []byte) (err error) { func Munlockall() (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procMunlockall)), 0, 0, 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1356,7 +1356,7 @@ func Munlockall() (err error) { func Nanosleep(time *Timespec, leftover *Timespec) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procNanosleep)), 2, uintptr(unsafe.Pointer(time)), uintptr(unsafe.Pointer(leftover)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1372,7 +1372,7 @@ func Open(path string, mode int, perm uint32) (fd int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procOpen)), 3, uintptr(unsafe.Pointer(_p0)), uintptr(mode), uintptr(perm), 0, 0, 0) fd = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1388,7 +1388,7 @@ func Openat(dirfd int, path string, flags int, mode uint32) (fd int, err error) r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procOpenat)), 4, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), uintptr(mode), 0, 0) fd = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1404,7 +1404,7 @@ func Pathconf(path string, name int) (val int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procPathconf)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(name), 0, 0, 0, 0) val = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1414,7 +1414,7 @@ func Pathconf(path string, name int) (val int, err error) { func Pause() (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procPause)), 0, 0, 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1429,7 +1429,7 @@ func pread(fd int, p []byte, offset int64) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procpread)), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1444,7 +1444,7 @@ func pwrite(fd int, p []byte, offset int64) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procpwrite)), 4, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(offset), 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1459,7 +1459,7 @@ func read(fd int, p []byte) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procread)), 3, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1479,7 +1479,7 @@ func Readlink(path string, buf []byte) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procReadlink)), 3, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(len(buf)), 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1499,7 +1499,7 @@ func Rename(from string, to string) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procRename)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1519,7 +1519,7 @@ func Renameat(olddirfd int, oldpath string, newdirfd int, newpath string) (err e } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procRenameat)), 4, uintptr(olddirfd), uintptr(unsafe.Pointer(_p0)), uintptr(newdirfd), uintptr(unsafe.Pointer(_p1)), 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1534,7 +1534,7 @@ func Rmdir(path string) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procRmdir)), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1545,7 +1545,7 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proclseek)), 3, uintptr(fd), uintptr(offset), uintptr(whence), 0, 0, 0) newoffset = int64(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1556,7 +1556,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procSelect)), 5, uintptr(nfd), uintptr(unsafe.Pointer(r)), uintptr(unsafe.Pointer(w)), uintptr(unsafe.Pointer(e)), uintptr(unsafe.Pointer(timeout)), 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1566,7 +1566,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err func Setegid(egid int) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procSetegid)), 1, uintptr(egid), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1576,7 +1576,7 @@ func Setegid(egid int) (err error) { func Seteuid(euid int) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procSeteuid)), 1, uintptr(euid), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1586,7 +1586,7 @@ func Seteuid(euid int) (err error) { func Setgid(gid int) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procSetgid)), 1, uintptr(gid), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1600,7 +1600,7 @@ func Sethostname(p []byte) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procSethostname)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1610,7 +1610,7 @@ func Sethostname(p []byte) (err error) { func Setpgid(pid int, pgid int) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procSetpgid)), 2, uintptr(pid), uintptr(pgid), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1620,7 +1620,7 @@ func Setpgid(pid int, pgid int) (err error) { func Setpriority(which int, who int, prio int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procSetpriority)), 3, uintptr(which), uintptr(who), uintptr(prio), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1630,7 +1630,7 @@ func Setpriority(which int, who int, prio int) (err error) { func Setregid(rgid int, egid int) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procSetregid)), 2, uintptr(rgid), uintptr(egid), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1640,7 +1640,7 @@ func Setregid(rgid int, egid int) (err error) { func Setreuid(ruid int, euid int) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procSetreuid)), 2, uintptr(ruid), uintptr(euid), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1651,7 +1651,7 @@ func Setsid() (pid int, err error) { r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procSetsid)), 0, 0, 0, 0, 0, 0, 0) pid = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1661,7 +1661,7 @@ func Setsid() (pid int, err error) { func Setuid(uid int) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procSetuid)), 1, uintptr(uid), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1671,7 +1671,7 @@ func Setuid(uid int) (err error) { func Shutdown(s int, how int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procshutdown)), 2, uintptr(s), uintptr(how), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1686,7 +1686,7 @@ func Stat(path string, stat *Stat_t) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procStat)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(stat)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1701,7 +1701,7 @@ func Statvfs(path string, vfsstat *Statvfs_t) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procStatvfs)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(vfsstat)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1721,7 +1721,7 @@ func Symlink(path string, link string) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procSymlink)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1731,7 +1731,7 @@ func Symlink(path string, link string) (err error) { func Sync() (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procSync)), 0, 0, 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1742,7 +1742,7 @@ func Sysconf(which int) (n int64, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procSysconf)), 1, uintptr(which), 0, 0, 0, 0, 0) n = int64(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1753,7 +1753,7 @@ func Times(tms *Tms) (ticks uintptr, err error) { r0, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procTimes)), 1, uintptr(unsafe.Pointer(tms)), 0, 0, 0, 0, 0) ticks = uintptr(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1768,7 +1768,7 @@ func Truncate(path string, length int64) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procTruncate)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(length), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1778,7 +1778,7 @@ func Truncate(path string, length int64) (err error) { func Fsync(fd int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFsync)), 1, uintptr(fd), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1788,7 +1788,7 @@ func Fsync(fd int) (err error) { func Ftruncate(fd int, length int64) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procFtruncate)), 2, uintptr(fd), uintptr(length), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1806,7 +1806,7 @@ func Umask(mask int) (oldmask int) { func Uname(buf *Utsname) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procUname)), 1, uintptr(unsafe.Pointer(buf)), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1821,7 +1821,7 @@ func Unmount(target string, flags int) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procumount)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1836,7 +1836,7 @@ func Unlink(path string) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procUnlink)), 1, uintptr(unsafe.Pointer(_p0)), 0, 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1851,7 +1851,7 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procUnlinkat)), 3, uintptr(dirfd), uintptr(unsafe.Pointer(_p0)), uintptr(flags), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1861,7 +1861,7 @@ func Unlinkat(dirfd int, path string, flags int) (err error) { func Ustat(dev int, ubuf *Ustat_t) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procUstat)), 2, uintptr(dev), uintptr(unsafe.Pointer(ubuf)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1876,7 +1876,7 @@ func Utime(path string, buf *Utimbuf) (err error) { } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procUtime)), 2, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(buf)), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1886,7 +1886,7 @@ func Utime(path string, buf *Utimbuf) (err error) { func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proc__xnet_bind)), 3, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1896,7 +1896,7 @@ func bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { func connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proc__xnet_connect)), 3, uintptr(s), uintptr(addr), uintptr(addrlen), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1907,7 +1907,7 @@ func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) ( r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procmmap)), 6, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flag), uintptr(fd), uintptr(pos)) ret = uintptr(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1917,7 +1917,7 @@ func mmap(addr uintptr, length uintptr, prot int, flag int, fd int, pos int64) ( func munmap(addr uintptr, length uintptr) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procmunmap)), 2, uintptr(addr), uintptr(length), 0, 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1928,7 +1928,7 @@ func sendfile(outfd int, infd int, offset *int64, count int) (written int, err e r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procsendfile)), 4, uintptr(outfd), uintptr(infd), uintptr(unsafe.Pointer(offset)), uintptr(count), 0, 0) written = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1942,7 +1942,7 @@ func sendto(s int, buf []byte, flags int, to unsafe.Pointer, addrlen _Socklen) ( } _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proc__xnet_sendto)), 6, uintptr(s), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), uintptr(flags), uintptr(to), uintptr(addrlen)) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1953,7 +1953,7 @@ func socket(domain int, typ int, proto int) (fd int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proc__xnet_socket)), 3, uintptr(domain), uintptr(typ), uintptr(proto), 0, 0, 0) fd = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1963,7 +1963,7 @@ func socket(domain int, typ int, proto int) (fd int, err error) { func socketpair(domain int, typ int, proto int, fd *[2]int32) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&proc__xnet_socketpair)), 4, uintptr(domain), uintptr(typ), uintptr(proto), uintptr(unsafe.Pointer(fd)), 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1978,7 +1978,7 @@ func write(fd int, p []byte) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procwrite)), 3, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1988,7 +1988,7 @@ func write(fd int, p []byte) (n int, err error) { func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&proc__xnet_getsockopt)), 5, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(unsafe.Pointer(vallen)), 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -1998,7 +1998,7 @@ func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { _, _, e1 := rawSysvicall6(uintptr(unsafe.Pointer(&procgetpeername)), 3, uintptr(fd), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -2008,7 +2008,7 @@ func getpeername(fd int, rsa *RawSockaddrAny, addrlen *_Socklen) (err error) { func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procsetsockopt)), 5, uintptr(s), uintptr(level), uintptr(name), uintptr(val), uintptr(vallen), 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -2023,7 +2023,7 @@ func recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *_Sockl r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procrecvfrom)), 6, uintptr(fd), uintptr(unsafe.Pointer(_p0)), uintptr(len(p)), uintptr(flags), uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(fromlen))) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -2034,7 +2034,7 @@ func port_create() (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procport_create)), 0, 0, 0, 0, 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -2045,7 +2045,7 @@ func port_associate(port int, source int, object uintptr, events int, user *byte r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procport_associate)), 5, uintptr(port), uintptr(source), uintptr(object), uintptr(events), uintptr(unsafe.Pointer(user)), 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -2056,7 +2056,7 @@ func port_dissociate(port int, source int, object uintptr) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procport_dissociate)), 3, uintptr(port), uintptr(source), uintptr(object), 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -2067,7 +2067,7 @@ func port_get(port int, pe *portEvent, timeout *Timespec) (n int, err error) { r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procport_get)), 3, uintptr(port), uintptr(unsafe.Pointer(pe)), uintptr(unsafe.Pointer(timeout)), 0, 0, 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -2078,7 +2078,7 @@ func port_getn(port int, pe *portEvent, max uint32, nget *uint32, timeout *Times r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procport_getn)), 5, uintptr(port), uintptr(unsafe.Pointer(pe)), uintptr(max), uintptr(unsafe.Pointer(nget)), uintptr(unsafe.Pointer(timeout)), 0) n = int(r0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -2088,7 +2088,7 @@ func port_getn(port int, pe *portEvent, max uint32, nget *uint32, timeout *Times func putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procputmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(flags), 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } @@ -2098,7 +2098,7 @@ func putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error) { func getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error) { _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(unsafe.Pointer(flags)), 0, 0) if e1 != 0 { - err = e1 + err = errnoErr(e1) } return } diff --git a/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go b/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go index c31681743c..1d8fe1d4b2 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_zos_s390x.go @@ -40,17 +40,6 @@ func read(fd int, p []byte) (n int, err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func readlen(fd int, buf *byte, nbuf int) (n int, err error) { - r0, _, e1 := syscall_syscall(SYS_READ, uintptr(fd), uintptr(unsafe.Pointer(buf)), uintptr(nbuf)) - n = int(r0) - if e1 != 0 { - err = errnoErr(e1) - } - return -} - -// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT - func write(fd int, p []byte) (n int, err error) { var _p0 unsafe.Pointer if len(p) > 0 { diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go index c9c4ad0314..9862853d34 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_386.go @@ -447,4 +447,5 @@ const ( SYS_PROCESS_MRELEASE = 448 SYS_FUTEX_WAITV = 449 SYS_SET_MEMPOLICY_HOME_NODE = 450 + SYS_CACHESTAT = 451 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go index 12ff3417c5..8901f0f4e5 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_amd64.go @@ -369,4 +369,5 @@ const ( SYS_PROCESS_MRELEASE = 448 SYS_FUTEX_WAITV = 449 SYS_SET_MEMPOLICY_HOME_NODE = 450 + SYS_CACHESTAT = 451 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go index c3fb5e77ab..6902c37eed 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm.go @@ -411,4 +411,5 @@ const ( SYS_PROCESS_MRELEASE = 448 SYS_FUTEX_WAITV = 449 SYS_SET_MEMPOLICY_HOME_NODE = 450 + SYS_CACHESTAT = 451 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go index 358c847a40..a6d3dff811 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_arm64.go @@ -314,4 +314,5 @@ const ( SYS_PROCESS_MRELEASE = 448 SYS_FUTEX_WAITV = 449 SYS_SET_MEMPOLICY_HOME_NODE = 450 + SYS_CACHESTAT = 451 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go index 81c4849b16..b18f3f7107 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_loong64.go @@ -308,4 +308,5 @@ const ( SYS_PROCESS_MRELEASE = 448 SYS_FUTEX_WAITV = 449 SYS_SET_MEMPOLICY_HOME_NODE = 450 + SYS_CACHESTAT = 451 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go index 202a57e900..0302e5e3de 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips.go @@ -431,4 +431,5 @@ const ( SYS_PROCESS_MRELEASE = 4448 SYS_FUTEX_WAITV = 4449 SYS_SET_MEMPOLICY_HOME_NODE = 4450 + SYS_CACHESTAT = 4451 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go index 1fbceb52d7..6693ba4a0f 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64.go @@ -361,4 +361,5 @@ const ( SYS_PROCESS_MRELEASE = 5448 SYS_FUTEX_WAITV = 5449 SYS_SET_MEMPOLICY_HOME_NODE = 5450 + SYS_CACHESTAT = 5451 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go index b4ffb7a207..fd93f4987c 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mips64le.go @@ -361,4 +361,5 @@ const ( SYS_PROCESS_MRELEASE = 5448 SYS_FUTEX_WAITV = 5449 SYS_SET_MEMPOLICY_HOME_NODE = 5450 + SYS_CACHESTAT = 5451 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go index 867985f9b4..760ddcadc2 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_mipsle.go @@ -431,4 +431,5 @@ const ( SYS_PROCESS_MRELEASE = 4448 SYS_FUTEX_WAITV = 4449 SYS_SET_MEMPOLICY_HOME_NODE = 4450 + SYS_CACHESTAT = 4451 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go index a8cce69ede..cff2b2555b 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc.go @@ -438,4 +438,5 @@ const ( SYS_PROCESS_MRELEASE = 448 SYS_FUTEX_WAITV = 449 SYS_SET_MEMPOLICY_HOME_NODE = 450 + SYS_CACHESTAT = 451 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go index d44c5b39d7..a4b2405d09 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64.go @@ -410,4 +410,5 @@ const ( SYS_PROCESS_MRELEASE = 448 SYS_FUTEX_WAITV = 449 SYS_SET_MEMPOLICY_HOME_NODE = 450 + SYS_CACHESTAT = 451 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go index 4214dd9c03..aca54b4e3a 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_ppc64le.go @@ -410,4 +410,5 @@ const ( SYS_PROCESS_MRELEASE = 448 SYS_FUTEX_WAITV = 449 SYS_SET_MEMPOLICY_HOME_NODE = 450 + SYS_CACHESTAT = 451 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go index ef285c567b..9d1738d641 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_riscv64.go @@ -315,4 +315,5 @@ const ( SYS_PROCESS_MRELEASE = 448 SYS_FUTEX_WAITV = 449 SYS_SET_MEMPOLICY_HOME_NODE = 450 + SYS_CACHESTAT = 451 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go index e6ed7d637d..022878dc8d 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_s390x.go @@ -376,4 +376,5 @@ const ( SYS_PROCESS_MRELEASE = 448 SYS_FUTEX_WAITV = 449 SYS_SET_MEMPOLICY_HOME_NODE = 450 + SYS_CACHESTAT = 451 ) diff --git a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go index 92f628ef4f..4100a761c2 100644 --- a/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go +++ b/vendor/golang.org/x/sys/unix/zsysnum_linux_sparc64.go @@ -389,4 +389,5 @@ const ( SYS_PROCESS_MRELEASE = 448 SYS_FUTEX_WAITV = 449 SYS_SET_MEMPOLICY_HOME_NODE = 450 + SYS_CACHESTAT = 451 ) diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index 494493c78c..18aa70b426 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -1977,7 +1977,7 @@ const ( NFT_MSG_GETFLOWTABLE = 0x17 NFT_MSG_DELFLOWTABLE = 0x18 NFT_MSG_GETRULE_RESET = 0x19 - NFT_MSG_MAX = 0x21 + NFT_MSG_MAX = 0x22 NFTA_LIST_UNSPEC = 0x0 NFTA_LIST_ELEM = 0x1 NFTA_HOOK_UNSPEC = 0x0 @@ -4499,7 +4499,7 @@ const ( NL80211_ATTR_MAC_HINT = 0xc8 NL80211_ATTR_MAC_MASK = 0xd7 NL80211_ATTR_MAX_AP_ASSOC_STA = 0xca - NL80211_ATTR_MAX = 0x145 + NL80211_ATTR_MAX = 0x146 NL80211_ATTR_MAX_CRIT_PROT_DURATION = 0xb4 NL80211_ATTR_MAX_CSA_COUNTERS = 0xce NL80211_ATTR_MAX_MATCH_SETS = 0x85 @@ -4869,7 +4869,7 @@ const ( NL80211_CMD_LEAVE_IBSS = 0x2c NL80211_CMD_LEAVE_MESH = 0x45 NL80211_CMD_LEAVE_OCB = 0x6d - NL80211_CMD_MAX = 0x99 + NL80211_CMD_MAX = 0x9a NL80211_CMD_MICHAEL_MIC_FAILURE = 0x29 NL80211_CMD_MODIFY_LINK_STA = 0x97 NL80211_CMD_NAN_MATCH = 0x78 @@ -5503,7 +5503,7 @@ const ( NL80211_RATE_INFO_HE_RU_ALLOC_52 = 0x1 NL80211_RATE_INFO_HE_RU_ALLOC_996 = 0x5 NL80211_RATE_INFO_HE_RU_ALLOC = 0x11 - NL80211_RATE_INFO_MAX = 0x16 + NL80211_RATE_INFO_MAX = 0x1d NL80211_RATE_INFO_MCS = 0x2 NL80211_RATE_INFO_SHORT_GI = 0x4 NL80211_RATE_INFO_VHT_MCS = 0x6 diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go index 83c69c119f..1b4c97c32a 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux_riscv64.go @@ -733,6 +733,10 @@ const ( RISCV_HWPROBE_KEY_IMA_EXT_0 = 0x4 RISCV_HWPROBE_IMA_FD = 0x1 RISCV_HWPROBE_IMA_C = 0x2 + RISCV_HWPROBE_IMA_V = 0x4 + RISCV_HWPROBE_EXT_ZBA = 0x8 + RISCV_HWPROBE_EXT_ZBB = 0x10 + RISCV_HWPROBE_EXT_ZBS = 0x20 RISCV_HWPROBE_KEY_CPUPERF_0 = 0x5 RISCV_HWPROBE_MISALIGNED_UNKNOWN = 0x0 RISCV_HWPROBE_MISALIGNED_EMULATED = 0x1 diff --git a/vendor/golang.org/x/sys/windows/exec_windows.go b/vendor/golang.org/x/sys/windows/exec_windows.go index a52e0331d8..9cabbb6941 100644 --- a/vendor/golang.org/x/sys/windows/exec_windows.go +++ b/vendor/golang.org/x/sys/windows/exec_windows.go @@ -22,7 +22,7 @@ import ( // but only if there is space or tab inside s. func EscapeArg(s string) string { if len(s) == 0 { - return "\"\"" + return `""` } n := len(s) hasSpace := false @@ -35,7 +35,7 @@ func EscapeArg(s string) string { } } if hasSpace { - n += 2 + n += 2 // Reserve space for quotes. } if n == len(s) { return s @@ -82,20 +82,68 @@ func EscapeArg(s string) string { // in CreateProcess's CommandLine argument, CreateService/ChangeServiceConfig's BinaryPathName argument, // or any program that uses CommandLineToArgv. func ComposeCommandLine(args []string) string { - var commandLine string - for i := range args { - if i > 0 { - commandLine += " " + if len(args) == 0 { + return "" + } + + // Per https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw: + // “This function accepts command lines that contain a program name; the + // program name can be enclosed in quotation marks or not.” + // + // Unfortunately, it provides no means of escaping interior quotation marks + // within that program name, and we have no way to report them here. + prog := args[0] + mustQuote := len(prog) == 0 + for i := 0; i < len(prog); i++ { + c := prog[i] + if c <= ' ' || (c == '"' && i == 0) { + // Force quotes for not only the ASCII space and tab as described in the + // MSDN article, but also ASCII control characters. + // The documentation for CommandLineToArgvW doesn't say what happens when + // the first argument is not a valid program name, but it empirically + // seems to drop unquoted control characters. + mustQuote = true + break + } + } + var commandLine []byte + if mustQuote { + commandLine = make([]byte, 0, len(prog)+2) + commandLine = append(commandLine, '"') + for i := 0; i < len(prog); i++ { + c := prog[i] + if c == '"' { + // This quote would interfere with our surrounding quotes. + // We have no way to report an error, so just strip out + // the offending character instead. + continue + } + commandLine = append(commandLine, c) } - commandLine += EscapeArg(args[i]) + commandLine = append(commandLine, '"') + } else { + if len(args) == 1 { + // args[0] is a valid command line representing itself. + // No need to allocate a new slice or string for it. + return prog + } + commandLine = []byte(prog) } - return commandLine + + for _, arg := range args[1:] { + commandLine = append(commandLine, ' ') + // TODO(bcmills): since we're already appending to a slice, it would be nice + // to avoid the intermediate allocations of EscapeArg. + // Perhaps we can factor out an appendEscapedArg function. + commandLine = append(commandLine, EscapeArg(arg)...) + } + return string(commandLine) } // DecomposeCommandLine breaks apart its argument command line into unescaped parts using CommandLineToArgv, // as gathered from GetCommandLine, QUERY_SERVICE_CONFIG's BinaryPathName argument, or elsewhere that // command lines are passed around. -// DecomposeCommandLine returns error if commandLine contains NUL. +// DecomposeCommandLine returns an error if commandLine contains NUL. func DecomposeCommandLine(commandLine string) ([]string, error) { if len(commandLine) == 0 { return []string{}, nil @@ -105,18 +153,35 @@ func DecomposeCommandLine(commandLine string) ([]string, error) { return nil, errorspkg.New("string with NUL passed to DecomposeCommandLine") } var argc int32 - argv, err := CommandLineToArgv(&utf16CommandLine[0], &argc) + argv, err := commandLineToArgv(&utf16CommandLine[0], &argc) if err != nil { return nil, err } defer LocalFree(Handle(unsafe.Pointer(argv))) + var args []string - for _, v := range (*argv)[:argc] { - args = append(args, UTF16ToString((*v)[:])) + for _, p := range unsafe.Slice(argv, argc) { + args = append(args, UTF16PtrToString(p)) } return args, nil } +// CommandLineToArgv parses a Unicode command line string and sets +// argc to the number of parsed arguments. +// +// The returned memory should be freed using a single call to LocalFree. +// +// Note that although the return type of CommandLineToArgv indicates 8192 +// entries of up to 8192 characters each, the actual count of parsed arguments +// may exceed 8192, and the documentation for CommandLineToArgvW does not mention +// any bound on the lengths of the individual argument strings. +// (See https://go.dev/issue/63236.) +func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) { + argp, err := commandLineToArgv(cmd, argc) + argv = (*[8192]*[8192]uint16)(unsafe.Pointer(argp)) + return argv, err +} + func CloseOnExec(fd Handle) { SetHandleInformation(Handle(fd), HANDLE_FLAG_INHERIT, 0) } diff --git a/vendor/golang.org/x/sys/windows/security_windows.go b/vendor/golang.org/x/sys/windows/security_windows.go index d414ef13be..26be94a8a7 100644 --- a/vendor/golang.org/x/sys/windows/security_windows.go +++ b/vendor/golang.org/x/sys/windows/security_windows.go @@ -7,8 +7,6 @@ package windows import ( "syscall" "unsafe" - - "golang.org/x/sys/internal/unsafeheader" ) const ( @@ -1341,21 +1339,14 @@ func (selfRelativeSD *SECURITY_DESCRIPTOR) copySelfRelativeSecurityDescriptor() sdLen = min } - var src []byte - h := (*unsafeheader.Slice)(unsafe.Pointer(&src)) - h.Data = unsafe.Pointer(selfRelativeSD) - h.Len = sdLen - h.Cap = sdLen - + src := unsafe.Slice((*byte)(unsafe.Pointer(selfRelativeSD)), sdLen) + // SECURITY_DESCRIPTOR has pointers in it, which means checkptr expects for it to + // be aligned properly. When we're copying a Windows-allocated struct to a + // Go-allocated one, make sure that the Go allocation is aligned to the + // pointer size. const psize = int(unsafe.Sizeof(uintptr(0))) - - var dst []byte - h = (*unsafeheader.Slice)(unsafe.Pointer(&dst)) alloc := make([]uintptr, (sdLen+psize-1)/psize) - h.Data = (*unsafeheader.Slice)(unsafe.Pointer(&alloc)).Data - h.Len = sdLen - h.Cap = sdLen - + dst := unsafe.Slice((*byte)(unsafe.Pointer(&alloc[0])), sdLen) copy(dst, src) return (*SECURITY_DESCRIPTOR)(unsafe.Pointer(&dst[0])) } diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go index 67bad0926a..35cfc57ca8 100644 --- a/vendor/golang.org/x/sys/windows/syscall_windows.go +++ b/vendor/golang.org/x/sys/windows/syscall_windows.go @@ -15,8 +15,6 @@ import ( "time" "unicode/utf16" "unsafe" - - "golang.org/x/sys/internal/unsafeheader" ) type Handle uintptr @@ -240,7 +238,7 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys SetFileAttributes(name *uint16, attrs uint32) (err error) = kernel32.SetFileAttributesW //sys GetFileAttributesEx(name *uint16, level uint32, info *byte) (err error) = kernel32.GetFileAttributesExW //sys GetCommandLine() (cmd *uint16) = kernel32.GetCommandLineW -//sys CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW +//sys commandLineToArgv(cmd *uint16, argc *int32) (argv **uint16, err error) [failretval==nil] = shell32.CommandLineToArgvW //sys LocalFree(hmem Handle) (handle Handle, err error) [failretval!=0] //sys LocalAlloc(flags uint32, length uint32) (ptr uintptr, err error) //sys SetHandleInformation(handle Handle, mask uint32, flags uint32) (err error) @@ -299,12 +297,15 @@ func NewCallbackCDecl(fn interface{}) uintptr { //sys RegNotifyChangeKeyValue(key Handle, watchSubtree bool, notifyFilter uint32, event Handle, asynchronous bool) (regerrno error) = advapi32.RegNotifyChangeKeyValue //sys GetCurrentProcessId() (pid uint32) = kernel32.GetCurrentProcessId //sys ProcessIdToSessionId(pid uint32, sessionid *uint32) (err error) = kernel32.ProcessIdToSessionId +//sys ClosePseudoConsole(console Handle) = kernel32.ClosePseudoConsole +//sys createPseudoConsole(size uint32, in Handle, out Handle, flags uint32, pconsole *Handle) (hr error) = kernel32.CreatePseudoConsole //sys GetConsoleMode(console Handle, mode *uint32) (err error) = kernel32.GetConsoleMode //sys SetConsoleMode(console Handle, mode uint32) (err error) = kernel32.SetConsoleMode //sys GetConsoleScreenBufferInfo(console Handle, info *ConsoleScreenBufferInfo) (err error) = kernel32.GetConsoleScreenBufferInfo //sys setConsoleCursorPosition(console Handle, position uint32) (err error) = kernel32.SetConsoleCursorPosition //sys WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW //sys ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW +//sys resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole //sys CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot //sys Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW //sys Module32Next(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32NextW @@ -1667,12 +1668,8 @@ func NewNTUnicodeString(s string) (*NTUnicodeString, error) { // Slice returns a uint16 slice that aliases the data in the NTUnicodeString. func (s *NTUnicodeString) Slice() []uint16 { - var slice []uint16 - hdr := (*unsafeheader.Slice)(unsafe.Pointer(&slice)) - hdr.Data = unsafe.Pointer(s.Buffer) - hdr.Len = int(s.Length) - hdr.Cap = int(s.MaximumLength) - return slice + slice := unsafe.Slice(s.Buffer, s.MaximumLength) + return slice[:s.Length] } func (s *NTUnicodeString) String() string { @@ -1695,12 +1692,8 @@ func NewNTString(s string) (*NTString, error) { // Slice returns a byte slice that aliases the data in the NTString. func (s *NTString) Slice() []byte { - var slice []byte - hdr := (*unsafeheader.Slice)(unsafe.Pointer(&slice)) - hdr.Data = unsafe.Pointer(s.Buffer) - hdr.Len = int(s.Length) - hdr.Cap = int(s.MaximumLength) - return slice + slice := unsafe.Slice(s.Buffer, s.MaximumLength) + return slice[:s.Length] } func (s *NTString) String() string { @@ -1752,10 +1745,7 @@ func LoadResourceData(module, resInfo Handle) (data []byte, err error) { if err != nil { return } - h := (*unsafeheader.Slice)(unsafe.Pointer(&data)) - h.Data = unsafe.Pointer(ptr) - h.Len = int(size) - h.Cap = int(size) + data = unsafe.Slice((*byte)(unsafe.Pointer(ptr)), size) return } @@ -1826,3 +1816,17 @@ type PSAPI_WORKING_SET_EX_INFORMATION struct { // A PSAPI_WORKING_SET_EX_BLOCK union that indicates the attributes of the page at VirtualAddress. VirtualAttributes PSAPI_WORKING_SET_EX_BLOCK } + +// CreatePseudoConsole creates a windows pseudo console. +func CreatePseudoConsole(size Coord, in Handle, out Handle, flags uint32, pconsole *Handle) error { + // We need this wrapper to manually cast Coord to uint32. The autogenerated wrappers only + // accept arguments that can be casted to uintptr, and Coord can't. + return createPseudoConsole(*((*uint32)(unsafe.Pointer(&size))), in, out, flags, pconsole) +} + +// ResizePseudoConsole resizes the internal buffers of the pseudo console to the width and height specified in `size`. +func ResizePseudoConsole(pconsole Handle, size Coord) error { + // We need this wrapper to manually cast Coord to uint32. The autogenerated wrappers only + // accept arguments that can be casted to uintptr, and Coord can't. + return resizePseudoConsole(pconsole, *((*uint32)(unsafe.Pointer(&size)))) +} diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 88e62a6385..b88dc7c85e 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -247,6 +247,7 @@ const ( PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY = 0x00020007 PROC_THREAD_ATTRIBUTE_UMS_THREAD = 0x00030006 PROC_THREAD_ATTRIBUTE_PROTECTION_LEVEL = 0x0002000b + PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE = 0x00020016 ) const ( @@ -2139,6 +2140,12 @@ const ( ENABLE_LVB_GRID_WORLDWIDE = 0x10 ) +// Pseudo console related constants used for the flags parameter to +// CreatePseudoConsole. See: https://learn.microsoft.com/en-us/windows/console/createpseudoconsole +const ( + PSEUDOCONSOLE_INHERIT_CURSOR = 0x1 +) + type Coord struct { X int16 Y int16 diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go index 5c385580f6..8b1688de4c 100644 --- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go +++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go @@ -188,6 +188,7 @@ var ( procCancelIo = modkernel32.NewProc("CancelIo") procCancelIoEx = modkernel32.NewProc("CancelIoEx") procCloseHandle = modkernel32.NewProc("CloseHandle") + procClosePseudoConsole = modkernel32.NewProc("ClosePseudoConsole") procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe") procCreateDirectoryW = modkernel32.NewProc("CreateDirectoryW") procCreateEventExW = modkernel32.NewProc("CreateEventExW") @@ -202,6 +203,7 @@ var ( procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW") procCreatePipe = modkernel32.NewProc("CreatePipe") procCreateProcessW = modkernel32.NewProc("CreateProcessW") + procCreatePseudoConsole = modkernel32.NewProc("CreatePseudoConsole") procCreateSymbolicLinkW = modkernel32.NewProc("CreateSymbolicLinkW") procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") procDefineDosDeviceW = modkernel32.NewProc("DefineDosDeviceW") @@ -328,6 +330,7 @@ var ( procReleaseMutex = modkernel32.NewProc("ReleaseMutex") procRemoveDirectoryW = modkernel32.NewProc("RemoveDirectoryW") procResetEvent = modkernel32.NewProc("ResetEvent") + procResizePseudoConsole = modkernel32.NewProc("ResizePseudoConsole") procResumeThread = modkernel32.NewProc("ResumeThread") procSetCommTimeouts = modkernel32.NewProc("SetCommTimeouts") procSetConsoleCursorPosition = modkernel32.NewProc("SetConsoleCursorPosition") @@ -1633,6 +1636,11 @@ func CloseHandle(handle Handle) (err error) { return } +func ClosePseudoConsole(console Handle) { + syscall.Syscall(procClosePseudoConsole.Addr(), 1, uintptr(console), 0, 0) + return +} + func ConnectNamedPipe(pipe Handle, overlapped *Overlapped) (err error) { r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(overlapped)), 0) if r1 == 0 { @@ -1762,6 +1770,14 @@ func CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityA return } +func createPseudoConsole(size uint32, in Handle, out Handle, flags uint32, pconsole *Handle) (hr error) { + r0, _, _ := syscall.Syscall6(procCreatePseudoConsole.Addr(), 5, uintptr(size), uintptr(in), uintptr(out), uintptr(flags), uintptr(unsafe.Pointer(pconsole)), 0) + if r0 != 0 { + hr = syscall.Errno(r0) + } + return +} + func CreateSymbolicLink(symlinkfilename *uint16, targetfilename *uint16, flags uint32) (err error) { r1, _, e1 := syscall.Syscall(procCreateSymbolicLinkW.Addr(), 3, uintptr(unsafe.Pointer(symlinkfilename)), uintptr(unsafe.Pointer(targetfilename)), uintptr(flags)) if r1&0xff == 0 { @@ -2862,6 +2878,14 @@ func ResetEvent(event Handle) (err error) { return } +func resizePseudoConsole(pconsole Handle, size uint32) (hr error) { + r0, _, _ := syscall.Syscall(procResizePseudoConsole.Addr(), 2, uintptr(pconsole), uintptr(size), 0) + if r0 != 0 { + hr = syscall.Errno(r0) + } + return +} + func ResumeThread(thread Handle) (ret uint32, err error) { r0, _, e1 := syscall.Syscall(procResumeThread.Addr(), 1, uintptr(thread), 0, 0) ret = uint32(r0) @@ -3820,9 +3844,9 @@ func setupUninstallOEMInf(infFileName *uint16, flags SUOI, reserved uintptr) (er return } -func CommandLineToArgv(cmd *uint16, argc *int32) (argv *[8192]*[8192]uint16, err error) { +func commandLineToArgv(cmd *uint16, argc *int32) (argv **uint16, err error) { r0, _, e1 := syscall.Syscall(procCommandLineToArgvW.Addr(), 2, uintptr(unsafe.Pointer(cmd)), uintptr(unsafe.Pointer(argc)), 0) - argv = (*[8192]*[8192]uint16)(unsafe.Pointer(r0)) + argv = (**uint16)(unsafe.Pointer(r0)) if argv == nil { err = errnoErr(e1) } diff --git a/vendor/modules.txt b/vendor/modules.txt index f5216b08bb..61e92a629b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -60,12 +60,12 @@ github.com/google/go-cmp/cmp/internal/value # github.com/hashicorp/errwrap v1.1.0 ## explicit github.com/hashicorp/errwrap -# github.com/hashicorp/go-azure-helpers v0.60.0 -## explicit; go 1.19 +# github.com/hashicorp/go-azure-helpers v0.62.0 +## explicit; go 1.21 github.com/hashicorp/go-azure-helpers/lang/pointer github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids -# github.com/hashicorp/go-azure-sdk v0.20230911.1163300 -## explicit; go 1.19 +# github.com/hashicorp/go-azure-sdk v0.20231018.1171511 +## explicit; go 1.21 github.com/hashicorp/go-azure-sdk/sdk/auth github.com/hashicorp/go-azure-sdk/sdk/claims github.com/hashicorp/go-azure-sdk/sdk/environments @@ -261,7 +261,7 @@ github.com/zclconf/go-cty/cty/function/stdlib github.com/zclconf/go-cty/cty/gocty github.com/zclconf/go-cty/cty/json github.com/zclconf/go-cty/cty/set -# golang.org/x/crypto v0.13.0 +# golang.org/x/crypto v0.14.0 ## explicit; go 1.17 golang.org/x/crypto/argon2 golang.org/x/crypto/blake2b @@ -270,7 +270,6 @@ golang.org/x/crypto/cast5 golang.org/x/crypto/chacha20 golang.org/x/crypto/curve25519 golang.org/x/crypto/curve25519/internal/field -golang.org/x/crypto/ed25519 golang.org/x/crypto/hkdf golang.org/x/crypto/internal/alias golang.org/x/crypto/internal/poly1305 @@ -287,7 +286,7 @@ golang.org/x/mod/internal/lazyregexp golang.org/x/mod/modfile golang.org/x/mod/module golang.org/x/mod/semver -# golang.org/x/net v0.13.0 +# golang.org/x/net v0.17.0 ## explicit; go 1.17 golang.org/x/net/context golang.org/x/net/http/httpguts @@ -300,10 +299,9 @@ golang.org/x/net/trace ## explicit; go 1.17 golang.org/x/oauth2 golang.org/x/oauth2/internal -# golang.org/x/sys v0.12.0 +# golang.org/x/sys v0.13.0 ## explicit; go 1.17 golang.org/x/sys/cpu -golang.org/x/sys/internal/unsafeheader golang.org/x/sys/unix golang.org/x/sys/windows # golang.org/x/text v0.13.0 From 24e1971a02c07278ecd98cb19e32a49f23d34538 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 02:35:28 +0100 Subject: [PATCH 42/46] remove final usages and delete the utils package --- .../administrative_unit_resource.go | 5 ++-- .../applications/application_resource.go | 5 ++-- internal/services/groups/group_resource.go | 13 +++++---- .../service_principal_resource.go | 5 ++-- internal/services/users/user_data_source.go | 9 +++---- internal/services/users/users_data_source.go | 7 +++-- internal/{utils => tf}/slices.go | 2 +- internal/utils/odata_query_string.go | 14 ---------- internal/utils/pointer.go | 27 ------------------- 9 files changed, 20 insertions(+), 67 deletions(-) rename internal/{utils => tf}/slices.go (96%) delete mode 100644 internal/utils/odata_query_string.go delete mode 100644 internal/utils/pointer.go diff --git a/internal/services/administrativeunits/administrative_unit_resource.go b/internal/services/administrativeunits/administrative_unit_resource.go index 84de7a56ab..5c6d345c39 100644 --- a/internal/services/administrativeunits/administrative_unit_resource.go +++ b/internal/services/administrativeunits/administrative_unit_resource.go @@ -19,7 +19,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -264,8 +263,8 @@ func administrativeUnitResourceUpdate(ctx context.Context, d *pluginsdk.Resource existingMembers := *members desiredMembers := *tf.ExpandStringSlicePtr(d.Get("members").(*pluginsdk.Set).List()) - membersForRemoval := utils.Difference(existingMembers, desiredMembers) - membersToAdd := utils.Difference(desiredMembers, existingMembers) + membersForRemoval := tf.Difference(existingMembers, desiredMembers) + membersToAdd := tf.Difference(desiredMembers, existingMembers) if len(membersForRemoval) > 0 { if _, err = client.RemoveMembers(ctx, d.Id(), &membersForRemoval); err != nil { diff --git a/internal/services/applications/application_resource.go b/internal/services/applications/application_resource.go index 72f338a357..a31e92ac37 100644 --- a/internal/services/applications/application_resource.go +++ b/internal/services/applications/application_resource.go @@ -25,7 +25,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -1234,8 +1233,8 @@ func applicationResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, m desiredOwners := *tf.ExpandStringSlicePtr(d.Get("owners").(*pluginsdk.Set).List()) existingOwners := *owners - ownersForRemoval := utils.Difference(existingOwners, desiredOwners) - ownersToAdd := utils.Difference(desiredOwners, existingOwners) + ownersForRemoval := tf.Difference(existingOwners, desiredOwners) + ownersToAdd := tf.Difference(desiredOwners, existingOwners) if len(ownersToAdd) > 0 { newOwners := make(msgraph.Owners, 0) diff --git a/internal/services/groups/group_resource.go b/internal/services/groups/group_resource.go index 101e5cc0f5..e500901547 100644 --- a/internal/services/groups/group_resource.go +++ b/internal/services/groups/group_resource.go @@ -21,7 +21,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -1131,8 +1130,8 @@ func groupResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta in existingMembers := *members desiredMembers := *tf.ExpandStringSlicePtr(d.Get("members").(*pluginsdk.Set).List()) - membersForRemoval := utils.Difference(existingMembers, desiredMembers) - membersToAdd := utils.Difference(desiredMembers, existingMembers) + membersForRemoval := tf.Difference(existingMembers, desiredMembers) + membersToAdd := tf.Difference(desiredMembers, existingMembers) if len(membersForRemoval) > 0 { if _, err = client.RemoveMembers(ctx, d.Id(), &membersForRemoval); err != nil { @@ -1178,8 +1177,8 @@ func groupResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta in } existingOwners := *owners - ownersForRemoval := utils.Difference(existingOwners, desiredOwners) - ownersToAdd := utils.Difference(desiredOwners, existingOwners) + ownersForRemoval := tf.Difference(existingOwners, desiredOwners) + ownersToAdd := tf.Difference(desiredOwners, existingOwners) if len(ownersToAdd) > 0 { newOwners := make(msgraph.Owners, 0) @@ -1222,8 +1221,8 @@ func groupResourceUpdate(ctx context.Context, d *pluginsdk.ResourceData, meta in } desiredAdministrativeUnits := tf.ExpandStringSlice(v.(*pluginsdk.Set).List()) - administrativeUnitsToLeave := utils.Difference(existingAdministrativeUnits, desiredAdministrativeUnits) - administrativeUnitsToJoin := utils.Difference(desiredAdministrativeUnits, existingAdministrativeUnits) + administrativeUnitsToLeave := tf.Difference(existingAdministrativeUnits, desiredAdministrativeUnits) + administrativeUnitsToJoin := tf.Difference(desiredAdministrativeUnits, existingAdministrativeUnits) if len(administrativeUnitsToJoin) > 0 { for _, newAdministrativeUnitId := range administrativeUnitsToJoin { diff --git a/internal/services/serviceprincipals/service_principal_resource.go b/internal/services/serviceprincipals/service_principal_resource.go index 17d107ac0c..8fd5b66b70 100644 --- a/internal/services/serviceprincipals/service_principal_resource.go +++ b/internal/services/serviceprincipals/service_principal_resource.go @@ -20,7 +20,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -566,8 +565,8 @@ func servicePrincipalResourceUpdate(ctx context.Context, d *pluginsdk.ResourceDa desiredOwners := *tf.ExpandStringSlicePtr(d.Get("owners").(*pluginsdk.Set).List()) existingOwners := *owners - ownersForRemoval := utils.Difference(existingOwners, desiredOwners) - ownersToAdd := utils.Difference(desiredOwners, existingOwners) + ownersForRemoval := tf.Difference(existingOwners, desiredOwners) + ownersToAdd := tf.Difference(desiredOwners, existingOwners) if len(ownersToAdd) > 0 { newOwners := make(msgraph.Owners, 0) diff --git a/internal/services/users/user_data_source.go b/internal/services/users/user_data_source.go index 0ccb619903..e3b5609575 100644 --- a/internal/services/users/user_data_source.go +++ b/internal/services/users/user_data_source.go @@ -15,7 +15,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -325,7 +324,7 @@ func userDataSourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta int if upn, ok := d.Get("user_principal_name").(string); ok && upn != "" { query := odata.Query{ - Filter: fmt.Sprintf("userPrincipalName eq '%s'", utils.EscapeSingleQuote(upn)), + Filter: fmt.Sprintf("userPrincipalName eq '%s'", odata.EscapeSingleQuote(upn)), } users, _, err := client.List(ctx, query) if err != nil { @@ -355,7 +354,7 @@ func userDataSourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta int user = *u } else if mail, ok := d.Get("mail").(string); ok && mail != "" { query := odata.Query{ - Filter: fmt.Sprintf("mail eq '%s'", utils.EscapeSingleQuote(mail)), + Filter: fmt.Sprintf("mail eq '%s'", odata.EscapeSingleQuote(mail)), } users, _, err := client.List(ctx, query) if err != nil { @@ -373,7 +372,7 @@ func userDataSourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta int user = (*users)[0] } else if mailNickname, ok := d.Get("mail_nickname").(string); ok && mailNickname != "" { query := odata.Query{ - Filter: fmt.Sprintf("mailNickname eq '%s'", utils.EscapeSingleQuote(mailNickname)), + Filter: fmt.Sprintf("mailNickname eq '%s'", odata.EscapeSingleQuote(mailNickname)), } users, _, err := client.List(ctx, query) if err != nil { @@ -391,7 +390,7 @@ func userDataSourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta int user = (*users)[0] } else if employeeId, ok := d.Get("employee_id").(string); ok && employeeId != "" { query := odata.Query{ - Filter: fmt.Sprintf("employeeId eq '%s'", utils.EscapeSingleQuote(employeeId)), + Filter: fmt.Sprintf("employeeId eq '%s'", odata.EscapeSingleQuote(employeeId)), } users, _, err := client.List(ctx, query) if err != nil { diff --git a/internal/services/users/users_data_source.go b/internal/services/users/users_data_source.go index 0ada4dd623..3fc8848390 100644 --- a/internal/services/users/users_data_source.go +++ b/internal/services/users/users_data_source.go @@ -18,7 +18,6 @@ import ( "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/hashicorp/terraform-provider-azuread/internal/utils" "github.com/manicminer/hamilton/msgraph" ) @@ -200,7 +199,7 @@ func usersDataSourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta in expectedCount = len(upns) for _, v := range upns { query := odata.Query{ - Filter: fmt.Sprintf("userPrincipalName eq '%s'", utils.EscapeSingleQuote(v.(string))), + Filter: fmt.Sprintf("userPrincipalName eq '%s'", odata.EscapeSingleQuote(v.(string))), } result, _, err := client.List(ctx, query) if err != nil { @@ -243,7 +242,7 @@ func usersDataSourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta in expectedCount = len(mailNicknames) for _, v := range mailNicknames { query := odata.Query{ - Filter: fmt.Sprintf("mailNickname eq '%s'", utils.EscapeSingleQuote(v.(string))), + Filter: fmt.Sprintf("mailNickname eq '%s'", odata.EscapeSingleQuote(v.(string))), } result, _, err := client.List(ctx, query) if err != nil { @@ -268,7 +267,7 @@ func usersDataSourceRead(ctx context.Context, d *pluginsdk.ResourceData, meta in expectedCount = len(employeeIds) for _, v := range employeeIds { query := odata.Query{ - Filter: fmt.Sprintf("employeeId eq '%s'", utils.EscapeSingleQuote(v.(string))), + Filter: fmt.Sprintf("employeeId eq '%s'", odata.EscapeSingleQuote(v.(string))), } result, _, err := client.List(ctx, query) if err != nil { diff --git a/internal/utils/slices.go b/internal/tf/slices.go similarity index 96% rename from internal/utils/slices.go rename to internal/tf/slices.go index a25f968f7f..0fd726e6f7 100644 --- a/internal/utils/slices.go +++ b/internal/tf/slices.go @@ -1,7 +1,7 @@ // Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 -package utils +package tf // Difference returns the elements in `a` that aren't in `b`. func Difference(a, b []string) []string { diff --git a/internal/utils/odata_query_string.go b/internal/utils/odata_query_string.go deleted file mode 100644 index 88fddf46a7..0000000000 --- a/internal/utils/odata_query_string.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package utils - -import "strings" - -// EscapeSingleQuote replaces all occurrences of single quote, with 2 single quotes. -// For requests that use single quotes, if any parameter values also contain single quotes, -// those must be double escaped; otherwise, the request will fail due to invalid syntax. -// https://docs.microsoft.com/en-us/graph/query-parameters#escaping-single-quotes -func EscapeSingleQuote(qparam string) string { - return strings.ReplaceAll(qparam, `'`, `''`) -} diff --git a/internal/utils/pointer.go b/internal/utils/pointer.go deleted file mode 100644 index 69d9062db1..0000000000 --- a/internal/utils/pointer.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) HashiCorp, Inc. -// SPDX-License-Identifier: MPL-2.0 - -package utils - -import "github.com/manicminer/hamilton/msgraph" - -// Deprecated: Please use pointer.To() from hashicorp/go-azure-helpers -func Bool(input bool) *bool { - return &input -} - -// Deprecated: Please use pointer.To() from hashicorp/go-azure-helpers -func Int32(input int32) *int32 { - return &input -} - -// Deprecated: Please use pointer.To() from hashicorp/go-azure-helpers -func String(input string) *string { - return &input -} - -// Deprecated: Please use tf.NullableString() instead -func NullableString(input string) *msgraph.StringNullWhenEmpty { - output := msgraph.StringNullWhenEmpty(input) - return &output -} From f487c5706b2a0fd58dce9239a33d121a03d49160 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 11:30:36 +0100 Subject: [PATCH 43/46] docs: update permissions for service principal resources --- docs/resources/service_principal.md | 6 +++--- docs/resources/service_principal_certificate.md | 6 ++++-- docs/resources/service_principal_password.md | 6 ++++-- .../service_principal_token_signing_certificate.md | 6 ++++-- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/docs/resources/service_principal.md b/docs/resources/service_principal.md index 3776991802..24ddfa2d5f 100644 --- a/docs/resources/service_principal.md +++ b/docs/resources/service_principal.md @@ -10,11 +10,11 @@ Manages a service principal associated with an application within Azure Active D The following API permissions are required in order to use this resource. -When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.All` or `Directory.ReadWrite.All` +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` -It may be possible to manage service principals whilst having only the `Application.ReadWrite.OwnedBy` role granted, however you must ensure that both the underlying application and the service principal have the Terraform principal as an owner. +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of _both_ the linked application registration, _and_ the service principal being managed. -When authenticated with a user principal, this resource requires one of the following directory roles: `Application Administrator` or `Global Administrator` +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` ## Example Usage diff --git a/docs/resources/service_principal_certificate.md b/docs/resources/service_principal_certificate.md index fca5938092..18974a35d9 100644 --- a/docs/resources/service_principal_certificate.md +++ b/docs/resources/service_principal_certificate.md @@ -10,9 +10,11 @@ Manages a certificate associated with a service principal within Azure Active Di The following API permissions are required in order to use this resource. -When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.All` or `Directory.ReadWrite.All` +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` -When authenticated with a user principal, this resource requires one of the following directory roles: `Application Administrator` or `Global Administrator` +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of _both_ the linked application registration, _and_ the service principal being managed. + +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` ## Example Usage diff --git a/docs/resources/service_principal_password.md b/docs/resources/service_principal_password.md index 3a307cd0bc..347935a939 100644 --- a/docs/resources/service_principal_password.md +++ b/docs/resources/service_principal_password.md @@ -10,9 +10,11 @@ Manages a password credential associated with a service principal within Azure A The following API permissions are required in order to use this resource. -When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.All` or `Directory.ReadWrite.All` +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` -When authenticated with a user principal, this resource requires one of the following directory roles: `Application Administrator` or `Global Administrator` +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of _both_ the linked application registration, _and_ the service principal being managed. + +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` ## Example Usage diff --git a/docs/resources/service_principal_token_signing_certificate.md b/docs/resources/service_principal_token_signing_certificate.md index 8453ef646d..943d50a54d 100644 --- a/docs/resources/service_principal_token_signing_certificate.md +++ b/docs/resources/service_principal_token_signing_certificate.md @@ -10,9 +10,11 @@ Manages a token signing certificate associated with a service principal within A The following API permissions are required in order to use this resource. -When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.All` or `Directory.ReadWrite.All` +When authenticated with a service principal, this resource requires one of the following application roles: `Application.ReadWrite.OwnedBy` or `Application.ReadWrite.All` -When authenticated with a user principal, this resource requires one of the following directory roles: `Application Administrator` or `Global Administrator` +-> When using the `Application.ReadWrite.OwnedBy` application role, the principal being used to run Terraform must be an owner of _both_ the linked application registration, _and_ the service principal being managed. + +When authenticated with a user principal, this resource may require one of the following directory roles: `Application Administrator` or `Global Administrator` ## Example Usage From 132386c3511e78781d0238e49da2d498833cd89c Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 21:36:43 +0100 Subject: [PATCH 44/46] azuread_application test fixes --- .../applications/application_resource.go | 8 ++++++-- .../applications/application_resource_test.go | 16 ++++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/internal/services/applications/application_resource.go b/internal/services/applications/application_resource.go index a31e92ac37..eed4d108a3 100644 --- a/internal/services/applications/application_resource.go +++ b/internal/services/applications/application_resource.go @@ -45,8 +45,12 @@ func applicationResource() *pluginsdk.Resource { }, Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - if _, err := uuid.ParseUUID(id); err != nil { - return fmt.Errorf("specified ID (%q) is not valid: %s", id, err) + if _, errors := parse.ValidateApplicationID(id, "id"); len(errors) > 0 { + out := "" + for _, err := range errors { + out += err.Error() + } + return fmt.Errorf(out) } return nil }), diff --git a/internal/services/applications/application_resource_test.go b/internal/services/applications/application_resource_test.go index 4dedc02af1..8c50f7ad83 100644 --- a/internal/services/applications/application_resource_test.go +++ b/internal/services/applications/application_resource_test.go @@ -6,6 +6,7 @@ package applications_test import ( "context" "fmt" + "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" "net/http" "regexp" "testing" @@ -597,14 +598,21 @@ func (r ApplicationResource) Exists(ctx context.Context, clients *clients.Client client := clients.Applications.ApplicationsClientBeta client.BaseClient.DisableRetries = true defer func() { client.BaseClient.DisableRetries = false }() - app, status, err := client.Get(ctx, state.ID, odata.Query{}) + + id, err := parse.ParseApplicationID(state.ID) + if err != nil { + return nil, err + } + + app, status, err := client.Get(ctx, id.ApplicationId, odata.Query{}) if err != nil { if status == http.StatusNotFound { - return nil, fmt.Errorf("Application with object ID %q does not exist", state.ID) + return nil, fmt.Errorf("%s does not exist", id) } - return nil, fmt.Errorf("failed to retrieve Application with object ID %q: %+v", state.ID, err) + return nil, fmt.Errorf("retrieving %s: %+v", id, err) } - return pointer.To(app.ID() != nil && *app.ID() == state.ID), nil + + return pointer.To(app.ID() != nil && *app.ID() == id.ApplicationId), nil } func (ApplicationResource) basic(data acceptance.TestData) string { From 8d1a89b0e22756f2d114baf6a5c9954f62abf201 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Thu, 19 Oct 2023 21:40:38 +0100 Subject: [PATCH 45/46] goimports --- internal/services/applications/application_resource_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/services/applications/application_resource_test.go b/internal/services/applications/application_resource_test.go index 8c50f7ad83..3e8b9b21a6 100644 --- a/internal/services/applications/application_resource_test.go +++ b/internal/services/applications/application_resource_test.go @@ -6,7 +6,6 @@ package applications_test import ( "context" "fmt" - "github.com/hashicorp/terraform-provider-azuread/internal/services/applications/parse" "net/http" "regexp" "testing" @@ -17,6 +16,7 @@ import ( "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/services/applications/parse" ) type ApplicationResource struct{} From bf00f05152a24f39418a56a0803052816490ead6 Mon Sep 17 00:00:00 2001 From: Tom Bamford Date: Fri, 20 Oct 2023 02:40:01 +0100 Subject: [PATCH 46/46] address review, undocument deprecated properties --- docs/data-sources/application.md | 4 +--- docs/data-sources/service_principal.md | 6 ++---- docs/data-sources/service_principals.md | 4 +--- docs/resources/application.md | 1 - docs/resources/application_certificate.md | 6 +----- .../application_federated_identity_credential.md | 6 +----- docs/resources/application_password.md | 6 +----- docs/resources/application_pre_authorized.md | 12 ++---------- docs/resources/service_principal.md | 6 +----- 9 files changed, 10 insertions(+), 41 deletions(-) diff --git a/docs/data-sources/application.md b/docs/data-sources/application.md index c3b0c1b905..6fbf3d2024 100644 --- a/docs/data-sources/application.md +++ b/docs/data-sources/application.md @@ -30,12 +30,11 @@ output "application_object_id" { The following arguments are supported: -* `application_id` - (Optional, Deprecated) Specifies the Client ID of the application. * `client_id` - (Optional) Specifies the Client ID of the application. * `display_name` - (Optional) Specifies the display name of the application. * `object_id` - (Optional) Specifies the Object ID of the application. -~> One of `client_id`, `application_id`, `display_name`, or `object_id` must be specified. +~> One of `client_id`, `display_name`, or `object_id` must be specified. ## Attributes Reference @@ -44,7 +43,6 @@ The following attributes are exported: * `api` - An `api` block as documented below. * `app_role_ids` - A mapping of app role values to app role IDs, intended to be useful when referencing app roles in other resources in your configuration. * `app_roles` - A collection of `app_role` blocks as documented below. For more information see [official documentation on Application Roles](https://docs.microsoft.com/en-us/azure/architecture/multitenant-identity/app-roles). -* `application_id` - (Deprecated) The Client ID for the application. * `client_id` - The Client ID for the application. * `description` - A description of the application, as shown to end users. * `device_only_auth_enabled` - Specifies whether this application supports device authentication without a user. diff --git a/docs/data-sources/service_principal.md b/docs/data-sources/service_principal.md index 6dc2f0fe71..8ad0655a53 100644 --- a/docs/data-sources/service_principal.md +++ b/docs/data-sources/service_principal.md @@ -44,12 +44,11 @@ data "azuread_service_principal" "example" { The following arguments are supported: -* `application_id` - (Optional, Deprecated) The client ID of the application associated with this service principal. * `client_id` - (Optional) The client ID of the application associated with this service principal. * `display_name` - (Optional) The display name of the application associated with this service principal. * `object_id` - (Optional) The object ID of the service principal. -~> One of `client_id`, `application_id`, `display_name` or `object_id` must be specified. +~> One of `client_id`, `display_name` or `object_id` must be specified. ## Attributes Reference @@ -57,12 +56,11 @@ The following attributes are exported: * `account_enabled` - Whether the service principal account is enabled. * `alternative_names` - A list of alternative names, used to retrieve service principals by subscription, identify resource group and full resource ids for managed identities. -* `application_id` - (Deprecated) The client ID of the application associated with this service principal. * `app_role_assignment_required` - Whether this service principal requires an app role assignment to a user or group before Azure AD will issue a user or access token to the application. * `app_role_ids` - A mapping of app role values to app role IDs, as published by the associated application, intended to be useful when referencing app roles in other resources in your configuration. * `app_roles` - A list of app roles published by the associated application, as documented below. For more information [official documentation](https://docs.microsoft.com/en-us/azure/architecture/multitenant-identity/app-roles). * `application_tenant_id` - The tenant ID where the associated application is registered. -* `client_id` - (Deprecated) The client ID of the application associated with this service principal. +* `client_id` - The client ID of the application associated with this service principal. * `description` - A description of the service principal provided for internal end-users. * `display_name` - The display name of the application associated with this service principal. * `features` - A `features` block as described below. diff --git a/docs/data-sources/service_principals.md b/docs/data-sources/service_principals.md index 84c925f714..2db60af37a 100644 --- a/docs/data-sources/service_principals.md +++ b/docs/data-sources/service_principals.md @@ -55,14 +55,13 @@ data "azuread_service_principals" "example" { The following arguments are supported: -* `application_ids` - (Optional, Deprecated) A list of client IDs of the applications associated with the service principals. * `client_ids` - (Optional) A list of client IDs of the applications associated with the service principals. * `display_names` - (Optional) A list of display names of the applications associated with the service principals. * `ignore_missing` - (Optional) Ignore missing service principals and return all service principals that are found. The data source will still fail if no service principals are found. Defaults to false. * `object_ids` - (Optional) The object IDs of the service principals. * `return_all` - (Optional) When `true`, the data source will return all service principals. Cannot be used with `ignore_missing`. Defaults to false. -~> Either `return_all`, or one of `client_ids`, `application_ids`, `display_names` or `object_ids` must be specified. These _may_ be specified as an empty list, in which case no results will be returned. +~> Either `return_all`, or one of `client_ids`, `display_names` or `object_ids` must be specified. These _may_ be specified as an empty list, in which case no results will be returned. ## Attributes Reference @@ -80,7 +79,6 @@ The following attributes are exported: * `account_enabled` - Whether the service principal account is enabled. * `app_role_assignment_required` - Whether this service principal requires an app role assignment to a user or group before Azure AD will issue a user or access token to the application. -* `application_id` - (Deprecated) The client ID of the application associated with this service principal. * `application_tenant_id` - The tenant ID where the associated application is registered. * `client_ids` - The client ID of the application associated with this service principal. * `display_name` - The display name of the application associated with this service principal. diff --git a/docs/resources/application.md b/docs/resources/application.md index d474b675f0..7b448e246b 100644 --- a/docs/resources/application.md +++ b/docs/resources/application.md @@ -331,7 +331,6 @@ The following arguments are supported: In addition to all arguments above, the following attributes are exported: * `app_role_ids` - A mapping of app role values to app role IDs, intended to be useful when referencing app roles in other resources in your configuration. -* `application_id` - (Deprecated) The Client ID for the application. * `client_id` - The Client ID for the application. * `disabled_by_microsoft` - Whether Microsoft has disabled the registered application. If the application is disabled, this will be a string indicating the status/reason, e.g. `DisabledDueToViolationOfServicesAgreement` * `logo_url` - CDN URL to the application's logo, as uploaded with the `logo_image` property. diff --git a/docs/resources/application_certificate.md b/docs/resources/application_certificate.md index afa1c1608f..6cb1288f37 100644 --- a/docs/resources/application_certificate.md +++ b/docs/resources/application_certificate.md @@ -120,11 +120,7 @@ resource "azuread_application_certificate" "example" { The following arguments are supported: -* `application_id` - (Optional) The resource ID of the application for which this certificate should be created. Changing this field forces a new resource to be created. -* `application_object_id` - (Optional, Deprecated) The object ID of the application for which this certificate should be created. Changing this field forces a new resource to be created. - -~> One of `application_id` or `application_object_id` must be specified. - +* `application_id` - (Required) The resource ID of the application for which this certificate should be created. Changing this field forces a new resource to be created. * `encoding` - (Optional) Specifies the encoding used for the supplied certificate data. Must be one of `pem`, `base64` or `hex`. Defaults to `pem`. -> **Tip for Azure Key Vault** The `hex` encoding option is useful for consuming certificate data from the [azurerm_key_vault_certificate](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/key_vault_certificate) resource. diff --git a/docs/resources/application_federated_identity_credential.md b/docs/resources/application_federated_identity_credential.md index 9cc0eb9854..c3576173b7 100644 --- a/docs/resources/application_federated_identity_credential.md +++ b/docs/resources/application_federated_identity_credential.md @@ -37,11 +37,7 @@ resource "azuread_application_federated_identity_credential" "example" { The following arguments are supported: -* `application_id` - (Optional) The resource ID of the application for which this federated identity credential should be created. Changing this field forces a new resource to be created. -* `application_object_id` - (Optional, Deprecated) The object ID of the application for which this federated identity credential should be created. Changing this field forces a new resource to be created. - -~> One of `application_id` or `application_object_id` must be specified. - +* `application_id` - (Required) The resource ID of the application for which this federated identity credential should be created. Changing this field forces a new resource to be created. * `audiences` - (Required) List of audiences that can appear in the external token. This specifies what should be accepted in the `aud` claim of incoming tokens. * `description` - (Optional) A description for the federated identity credential. * `display_name` - (Required) A unique display name for the federated identity credential. Changing this forces a new resource to be created. diff --git a/docs/resources/application_password.md b/docs/resources/application_password.md index 1a5fc8a5f1..8f518c1c76 100644 --- a/docs/resources/application_password.md +++ b/docs/resources/application_password.md @@ -53,11 +53,7 @@ resource "azuread_application_password" "example" { The following arguments are supported: -* `application_id` - (Optional) The resource ID of the application for which this password should be created. Changing this field forces a new resource to be created. -* `application_object_id` - (Optional, Deprecated) The object ID of the application for which this password should be created. Changing this field forces a new resource to be created. - -~> One of `application_id` or `application_object_id` must be specified. - +* `application_id` - (Required) The resource ID of the application for which this password should be created. Changing this field forces a new resource to be created. * `display_name` - (Optional) A display name for the password. Changing this field forces a new resource to be created. * `end_date` - (Optional) The end date until which the password is valid, formatted as an RFC3339 date string (e.g. `2018-01-01T01:02:03Z`). Changing this field forces a new resource to be created. * `end_date_relative` - (Optional) A relative duration for which the password is valid until, for example `240h` (10 days) or `2400h30m`. Changing this field forces a new resource to be created. diff --git a/docs/resources/application_pre_authorized.md b/docs/resources/application_pre_authorized.md index 0d75818d87..3aa008c12c 100644 --- a/docs/resources/application_pre_authorized.md +++ b/docs/resources/application_pre_authorized.md @@ -64,16 +64,8 @@ resource "azuread_application_pre_authorized" "example" { The following arguments are supported: -* `application_id` - (Optional) The resource ID of the application for which permissions are being authorized. Changing this field forces a new resource to be created. -* `application_object_id` - (Optional, Deprecated) The object ID of the application for which permissions are being authorized. Changing this field forces a new resource to be created. - -~> One of `application_id` or `application_object_id` must be specified. - -* `authorized_app_id` - (Optional, Deprecated) The client ID of the application being authorized. Changing this field forces a new resource to be created. -* `authorized_client_id` - (Optional) The client ID of the application being authorized. Changing this field forces a new resource to be created. - -~> One of `authorized_client_id` or `authorized_app_id` must be specified. - +* `application_id` - (Required) The resource ID of the application for which permissions are being authorized. Changing this field forces a new resource to be created. +* `authorized_client_id` - (Required) The client ID of the application being authorized. Changing this field forces a new resource to be created. * `permission_ids` - (Required) A set of permission scope IDs required by the authorized application. ## Attributes Reference diff --git a/docs/resources/service_principal.md b/docs/resources/service_principal.md index 24ddfa2d5f..6d63b8c07c 100644 --- a/docs/resources/service_principal.md +++ b/docs/resources/service_principal.md @@ -93,11 +93,7 @@ The following arguments are supported: * `account_enabled` - (Optional) Whether or not the service principal account is enabled. Defaults to `true`. * `alternative_names` - (Optional) A set of alternative names, used to retrieve service principals by subscription, identify resource group and full resource ids for managed identities. * `app_role_assignment_required` - (Optional) Whether this service principal requires an app role assignment to a user or group before Azure AD will issue a user or access token to the application. Defaults to `false`. -* `application_id` - (Optional, Deprecated) The client ID of the application for which to create a service principal. -* `client_id` - (Optional) The client ID of the application for which to create a service principal. - -~. At least one of `client_id` or `application_id` must be specified. - +* `client_id` - (Required) The client ID of the application for which to create a service principal. * `description` - (Optional) A description of the service principal provided for internal end-users. * `feature_tags` - (Optional) A `feature_tags` block as described below. Cannot be used together with the `tags` property.