From 90de29a75a91847e82ff733211e75722b8661b6b Mon Sep 17 00:00:00 2001 From: Ben Echols Date: Fri, 30 Jan 2026 16:37:15 -0800 Subject: [PATCH 1/2] Fix account_access mapping for developer role When importing a service account with developer role, the API may return the role in the deprecated RoleDeprecated string field instead of the Role enum field. This caused the enum to default to ROLE_UNSPECIFIED, which mapped to "none" - an invalid value for service accounts. Added FromAccountAccess() function that checks both fields, preferring the enum but falling back to the deprecated string field when needed. Fixes #296 Co-Authored-By: Claude Opus 4.5 --- internal/provider/enums/identity.go | 22 +++++++++++++++++++ internal/provider/group_access_resource.go | 2 +- internal/provider/service_account_resource.go | 2 +- .../provider/service_accounts_datasource.go | 2 +- internal/provider/user_datasource_model.go | 2 +- internal/provider/user_resource.go | 2 +- 6 files changed, 27 insertions(+), 5 deletions(-) diff --git a/internal/provider/enums/identity.go b/internal/provider/enums/identity.go index f0218bb3..fcde2b19 100644 --- a/internal/provider/enums/identity.go +++ b/internal/provider/enums/identity.go @@ -89,6 +89,28 @@ func FromAccountAccessRole(r identity.AccountAccess_Role) (string, error) { } } +// FromAccountAccess extracts the role string from an AccountAccess object. +// It first checks the Role enum field, and if that is UNSPECIFIED, falls back +// to the deprecated RoleDeprecated string field. This handles the case where +// the API returns the role in the deprecated field for some account types. +func FromAccountAccess(access *identity.AccountAccess) (string, error) { + if access == nil { + return "none", nil + } + + // First try the enum field + if access.GetRole() != identity.AccountAccess_ROLE_UNSPECIFIED { + return FromAccountAccessRole(access.GetRole()) + } + + // Fall back to the deprecated string field if the enum is unspecified + if deprecated := access.GetRoleDeprecated(); deprecated != "" { + return strings.ToLower(deprecated), nil + } + + return "none", nil +} + func ToNamespaceAccessPermission(s string) (identity.NamespaceAccess_Permission, error) { switch strings.ToLower(s) { case "admin": diff --git a/internal/provider/group_access_resource.go b/internal/provider/group_access_resource.go index f2a3e36c..8b7972fe 100644 --- a/internal/provider/group_access_resource.go +++ b/internal/provider/group_access_resource.go @@ -365,7 +365,7 @@ func updateGroupAccessModel(ctx context.Context, state *groupAccessResourceModel state.ID = types.StringValue(group.Id) - role, err := enums.FromAccountAccessRole(group.GetSpec().GetAccess().GetAccountAccess().GetRole()) + role, err := enums.FromAccountAccess(group.GetSpec().GetAccess().GetAccountAccess()) if err != nil { diags.AddError("Failed to convert account access role", err.Error()) return diags diff --git a/internal/provider/service_account_resource.go b/internal/provider/service_account_resource.go index 145e5f05..5c20d58a 100644 --- a/internal/provider/service_account_resource.go +++ b/internal/provider/service_account_resource.go @@ -538,7 +538,7 @@ func updateServiceAccountModelFromSpec(ctx context.Context, state *serviceAccoun state.NamespaceAccesses = types.SetNull(types.ObjectType{AttrTypes: serviceAccountNamespaceAccessAttrs}) } else { // Handle account-scoped service account - role, err := enums.FromAccountAccessRole(serviceAccount.GetSpec().GetAccess().GetAccountAccess().GetRole()) + role, err := enums.FromAccountAccess(serviceAccount.GetSpec().GetAccess().GetAccountAccess()) if err != nil { diags.AddError("Failed to convert account access role", err.Error()) } diff --git a/internal/provider/service_accounts_datasource.go b/internal/provider/service_accounts_datasource.go index 256a66a0..3d980837 100644 --- a/internal/provider/service_accounts_datasource.go +++ b/internal/provider/service_accounts_datasource.go @@ -252,7 +252,7 @@ func serviceAccountToServiceAccountDataModel(ctx context.Context, sa *identityv1 serviceAccountModel.NamespaceAccesses = types.SetNull(types.ObjectType{AttrTypes: serviceAccountNamespaceAccessAttrs}) } else { // Handle account-scoped service account - role, err := enums.FromAccountAccessRole(sa.GetSpec().GetAccess().GetAccountAccess().GetRole()) + role, err := enums.FromAccountAccess(sa.GetSpec().GetAccess().GetAccountAccess()) if err != nil { diags.AddError("Failed to convert account access role", err.Error()) return nil, diags diff --git a/internal/provider/user_datasource_model.go b/internal/provider/user_datasource_model.go index 4fd1594f..06d68baa 100644 --- a/internal/provider/user_datasource_model.go +++ b/internal/provider/user_datasource_model.go @@ -50,7 +50,7 @@ func userToUserDataModel(ctx context.Context, sa *identityv1.User) (*userDataMod UpdatedAt: types.StringValue(sa.GetLastModifiedTime().AsTime().GoString()), } - role, err := enums.FromAccountAccessRole(sa.GetSpec().GetAccess().GetAccountAccess().GetRole()) + role, err := enums.FromAccountAccess(sa.GetSpec().GetAccess().GetAccountAccess()) if err != nil { diags.AddError("Failed to convert account access role", err.Error()) return nil, diags diff --git a/internal/provider/user_resource.go b/internal/provider/user_resource.go index 48bd306c..38d16474 100644 --- a/internal/provider/user_resource.go +++ b/internal/provider/user_resource.go @@ -440,7 +440,7 @@ func updateUserModelFromSpec(ctx context.Context, state *userResourceModel, user } state.State = types.StringValue(stateStr) state.Email = types.StringValue(user.GetSpec().GetEmail()) - role, err := enums.FromAccountAccessRole(user.GetSpec().GetAccess().GetAccountAccess().GetRole()) + role, err := enums.FromAccountAccess(user.GetSpec().GetAccess().GetAccountAccess()) if err != nil { diags.AddError("Failed to convert account access role", err.Error()) return diags From 1f7ced6ad466fe5faa40af3acd4d93c525a8f9f5 Mon Sep 17 00:00:00 2001 From: Ben Echols Date: Fri, 30 Jan 2026 22:01:51 -0800 Subject: [PATCH 2/2] Allow fallback to deprecated account role --- internal/provider/enums/identity.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/provider/enums/identity.go b/internal/provider/enums/identity.go index fcde2b19..c43d7ad3 100644 --- a/internal/provider/enums/identity.go +++ b/internal/provider/enums/identity.go @@ -103,7 +103,8 @@ func FromAccountAccess(access *identity.AccountAccess) (string, error) { return FromAccountAccessRole(access.GetRole()) } - // Fall back to the deprecated string field if the enum is unspecified + // Fall back to the deprecated string field if the enum is unspecified. + //nolint:staticcheck // SA1019: RoleDeprecated still used by older Temporal Cloud accounts. if deprecated := access.GetRoleDeprecated(); deprecated != "" { return strings.ToLower(deprecated), nil }