Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Upgrades cloud_provider_access_setup and _authorization to the… #2235

Merged
merged 10 commits into from
May 7, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@ func DataSourceSetup() *schema.Resource {
}

func dataSourceMongoDBAtlasCloudProviderAccessSetupRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
conn := meta.(*config.MongoDBClient).Atlas
conn := meta.(*config.MongoDBClient).AtlasV2
projectID := d.Get("project_id").(string)
roleID := d.Get("role_id").(string)

role, _, err := conn.CloudProviderAccess.GetRole(ctx, projectID, roleID)
role, _, err := conn.CloudProviderAccessApi.GetCloudProviderAccessRole(ctx, projectID, roleID).Execute()
if err != nil {
return diag.FromErr(fmt.Errorf(ErrorCloudProviderGetRead, err))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/constant"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/config"
matlas "go.mongodb.org/atlas/mongodbatlas"
"go.mongodb.org/atlas-sdk/v20231115012/admin"
)

/*
Expand Down Expand Up @@ -92,7 +92,7 @@ func ResourceAuthorization() *schema.Resource {

func resourceMongoDBAtlasCloudProviderAccessAuthorizationRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
// sadly there is no just get API
conn := meta.(*config.MongoDBClient).Atlas
conn := meta.(*config.MongoDBClient).AtlasV2
ids := conversion.DecodeStateID(d.Id())

roleID := ids["id"] // atlas ID
Expand Down Expand Up @@ -121,7 +121,7 @@ func resourceMongoDBAtlasCloudProviderAccessAuthorizationRead(ctx context.Contex
}

// If not authorize , then request the authorization
if targetRole.ProviderName == constant.AWS && targetRole.AuthorizedDate == "" && !d.IsNewResource() {
if targetRole.ProviderName == constant.AWS && conversion.TimeToString(targetRole.GetAuthorizedDate()) == "" && !d.IsNewResource() {
d.SetId("")
return nil
}
Expand All @@ -130,7 +130,7 @@ func resourceMongoDBAtlasCloudProviderAccessAuthorizationRead(ctx context.Contex
}

func resourceMongoDBAtlasCloudProviderAccessAuthorizationCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
conn := meta.(*config.MongoDBClient).Atlas
conn := meta.(*config.MongoDBClient).AtlasV2

projectID := d.Get("project_id").(string)
roleID := d.Get("role_id").(string)
Expand All @@ -150,7 +150,7 @@ func resourceMongoDBAtlasCloudProviderAccessAuthorizationCreate(ctx context.Cont
}

func resourceMongoDBAtlasCloudProviderAccessAuthorizationUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
conn := meta.(*config.MongoDBClient).Atlas
conn := meta.(*config.MongoDBClient).AtlasV2
ids := conversion.DecodeStateID(d.Id())

roleID := ids["id"]
Expand Down Expand Up @@ -178,38 +178,38 @@ func resourceMongoDBAtlasCloudProviderAccessAuthorizationPlaceHolder(ctx context
return nil
}

func roleToSchemaAuthorization(role *matlas.CloudProviderAccessRole) map[string]any {
func roleToSchemaAuthorization(role *admin.CloudProviderAccessRole) map[string]any {
out := map[string]any{
"role_id": role.RoleID,
"role_id": role.GetRoleId(),
"aws": []any{map[string]any{
"iam_assumed_role_arn": role.IAMAssumedRoleARN,
"iam_assumed_role_arn": role.GetIamAssumedRoleArn(),
}},
"authorized_date": role.AuthorizedDate,
"authorized_date": role.GetAuthorizedDate(),
}

if role.ProviderName == "AZURE" {
out = map[string]any{
"role_id": role.AzureID,
"role_id": role.GetRoleId(),
"azure": []any{map[string]any{
"atlas_azure_app_id": role.AtlasAzureAppID,
"service_principal_id": role.AzureServicePrincipalID,
"tenant_id": role.AzureTenantID,
"atlas_azure_app_id": role.GetAtlasAzureAppId(),
"service_principal_id": role.GetServicePrincipalId(),
"tenant_id": role.GetTenantId(),
}},
"authorized_date": role.AuthorizedDate,
}
}

features := make([]map[string]any, 0, len(role.FeatureUsages))
for _, featureUsage := range role.FeatureUsages {
features := make([]map[string]any, 0, len(role.GetFeatureUsages()))
for _, featureUsage := range role.GetFeatureUsages() {
features = append(features, featureToSchema(featureUsage))
}

out["feature_usages"] = features
return out
}

func FindRole(ctx context.Context, conn *matlas.Client, projectID, roleID string) (*matlas.CloudProviderAccessRole, error) {
role, _, err := conn.CloudProviderAccess.GetRole(ctx, projectID, roleID)
func FindRole(ctx context.Context, conn *admin.APIClient, projectID, roleID string) (*admin.CloudProviderAccessRole, error) {
role, _, err := conn.CloudProviderAccessApi.GetCloudProviderAccessRole(ctx, projectID, roleID).Execute()
if err != nil {
return nil, fmt.Errorf(ErrorCloudProviderGetRead, err)
}
Expand Down Expand Up @@ -259,33 +259,33 @@ func resourceMongoDBAtlasCloudProviderAccessAuthorizationStateUpgradeV0(ctx cont
return rawState, nil
}

func authorizeRole(ctx context.Context, client *matlas.Client, d *schema.ResourceData, projectID string, targetRole *matlas.CloudProviderAccessRole) diag.Diagnostics {
req := &matlas.CloudProviderAccessRoleRequest{
func authorizeRole(ctx context.Context, client *admin.APIClient, d *schema.ResourceData, projectID string, targetRole *admin.CloudProviderAccessRole) diag.Diagnostics {
req := &admin.CloudProviderAccessRole{
ProviderName: targetRole.ProviderName,
}

roleID := targetRole.RoleID
roleID := targetRole.GetRoleId()
if targetRole.ProviderName == constant.AWS {
roleAWS, ok := d.GetOk("aws")
if !ok {
return diag.FromErr(fmt.Errorf("error CloudProviderAccessAuthorization missing iam_assumed_role_arn"))
}

req.IAMAssumedRoleARN = conversion.Pointer(roleAWS.([]any)[0].(map[string]any)["iam_assumed_role_arn"].(string))
req.SetIamAssumedRoleArn(roleAWS.([]any)[0].(map[string]any)["iam_assumed_role_arn"].(string))
}

if targetRole.ProviderName == constant.AZURE {
req.AtlasAzureAppID = targetRole.AtlasAzureAppID
req.AzureTenantID = targetRole.AzureTenantID
req.AzureServicePrincipalID = targetRole.AzureServicePrincipalID
roleID = *targetRole.AzureID
req.SetAtlasAzureAppId(targetRole.GetAtlasAzureAppId())
req.SetTenantId(targetRole.GetTenantId())
req.SetServicePrincipalId(targetRole.GetServicePrincipalId())
roleID = targetRole.GetRoleId()
}

var role *matlas.CloudProviderAccessRole
var role *admin.CloudProviderAccessRole
var err error

for i := 0; i < 3; i++ {
role, _, err = client.CloudProviderAccess.AuthorizeRole(ctx, projectID, roleID, req)
role, _, err = client.CloudProviderAccessApi.AuthorizeCloudProviderAccessRole(ctx, projectID, roleID, req).Execute()
if err != nil && strings.Contains(err.Error(), "CANNOT_ASSUME_ROLE") { // aws takes time to update , in case of single path
log.Printf("warning issue performing authorize: %s \n", err.Error())
log.Println("retrying")
Expand All @@ -304,10 +304,7 @@ func authorizeRole(ctx context.Context, client *matlas.Client, d *schema.Resourc

authSchema := roleToSchemaAuthorization(role)

resourceID := role.RoleID
if role.ProviderName == constant.AZURE {
resourceID = *role.AzureID
}
resourceID := role.GetRoleId()
d.SetId(conversion.EncodeStateID(map[string]string{
"id": resourceID,
"project_id": projectID,
Expand Down Expand Up @@ -337,9 +334,9 @@ func featureUsagesSchema() *schema.Resource {
}
}

func featureToSchema(feature *matlas.FeatureUsage) map[string]any {
func featureToSchema(feature admin.CloudProviderAccessFeatureUsage) map[string]any {
return map[string]any{
"feature_type": feature.FeatureType,
"feature_id": feature.FeatureID,
"feature_type": feature.GetFeatureType(),
"feature_id": feature.GetFeatureId(),
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,15 @@ func checkDestroy(s *terraform.State) error {
continue
}
ids := conversion.DecodeStateID(rs.Primary.ID)
roles, _, err := acc.Conn().CloudProviderAccess.ListRoles(context.Background(), ids["project_id"])
roles, _, err := acc.ConnV2().CloudProviderAccessApi.ListCloudProviderAccessRoles(context.Background(), ids["project_id"]).Execute()
marcosuma marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
return fmt.Errorf(cloudprovideraccess.ErrorCloudProviderGetRead, err)
}

// searching in roles
for i := range roles.AWSIAMRoles {
role := &(roles.AWSIAMRoles[i])
if role.RoleID == ids["id"] && role.ProviderName == ids["provider_name"] {
for i := range roles.GetAwsIamRoles() {
role := &(roles.GetAwsIamRoles()[i])
if role.GetRoleId() == ids["id"] && role.ProviderName == ids["provider_name"] {
return fmt.Errorf("error cloud Provider Access Role (%s) still exists", ids["id"])
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@ import (
"net/http"
"regexp"

"go.mongodb.org/atlas-sdk/v20231115012/admin"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/constant"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/config"
matlas "go.mongodb.org/atlas/mongodbatlas"
)

/*
Expand Down Expand Up @@ -103,12 +104,12 @@ func ResourceSetup() *schema.Resource {
}

func resourceMongoDBAtlasCloudProviderAccessSetupRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
marcosuma marked this conversation as resolved.
Show resolved Hide resolved
conn := meta.(*config.MongoDBClient).Atlas
conn := meta.(*config.MongoDBClient).AtlasV2
ids := conversion.DecodeStateID(d.Id())
projectID := ids["project_id"]
roleID := ids["id"]

role, resp, err := conn.CloudProviderAccess.GetRole(context.Background(), projectID, roleID)
role, resp, err := conn.CloudProviderAccessApi.GetCloudProviderAccessRole(context.Background(), projectID, roleID).Execute()
if err != nil {
if resp != nil && resp.StatusCode == http.StatusNotFound {
d.SetId("")
Expand All @@ -131,53 +132,41 @@ func resourceMongoDBAtlasCloudProviderAccessSetupRead(ctx context.Context, d *sc
func resourceMongoDBAtlasCloudProviderAccessSetupCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
projectID := d.Get("project_id").(string)

conn := meta.(*config.MongoDBClient).Atlas
conn := meta.(*config.MongoDBClient).AtlasV2

requestParameters := &matlas.CloudProviderAccessRoleRequest{
requestParameters := &admin.CloudProviderAccessRole{
ProviderName: d.Get("provider_name").(string),
}

if value, ok := d.GetOk("azure_config.0.atlas_azure_app_id"); ok {
requestParameters.AtlasAzureAppID = conversion.Pointer(value.(string))
requestParameters.SetAtlasAzureAppId(value.(string))
}

if value, ok := d.GetOk("azure_config.0.service_principal_id"); ok {
requestParameters.AzureServicePrincipalID = conversion.Pointer(value.(string))
requestParameters.SetServicePrincipalId(value.(string))
}

if value, ok := d.GetOk("azure_config.0.tenant_id"); ok {
requestParameters.AzureTenantID = conversion.Pointer(value.(string))
}

if value, ok := d.GetOk("azure_config.0.atlas_azure_app_id"); ok {
requestParameters.AtlasAzureAppID = conversion.Pointer(value.(string))
requestParameters.SetTenantId(value.(string))
lantoli marked this conversation as resolved.
Show resolved Hide resolved
}

if value, ok := d.GetOk("azure_config.0.service_principal_id"); ok {
requestParameters.AzureServicePrincipalID = conversion.Pointer(value.(string))
}

if value, ok := d.GetOk("azure_config.0.tenant_id"); ok {
requestParameters.AzureTenantID = conversion.Pointer(value.(string))
}

role, _, err := conn.CloudProviderAccess.CreateRole(ctx, projectID, requestParameters)
role, _, err := conn.CloudProviderAccessApi.CreateCloudProviderAccessRole(ctx, projectID, requestParameters).Execute()
if err != nil {
return diag.FromErr(fmt.Errorf(errorCloudProviderAccessCreate, err))
}

// once multiple providers enable here do a switch, select for provider type
roleSchema := roleToSchemaSetup(role)

resourceID := role.RoleID
resourceID := role.GetRoleId()
if role.ProviderName == constant.AZURE {
resourceID = *role.AzureID
resourceID = role.GetId()
}

d.SetId(conversion.EncodeStateID(map[string]string{
"id": resourceID,
"project_id": projectID,
"provider_name": role.ProviderName,
"provider_name": role.GetProviderName(),
}))

for key, val := range roleSchema {
Expand All @@ -190,20 +179,20 @@ func resourceMongoDBAtlasCloudProviderAccessSetupCreate(ctx context.Context, d *
}

func resourceMongoDBAtlasCloudProviderAccessSetupDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
conn := meta.(*config.MongoDBClient).Atlas
conn := meta.(*config.MongoDBClient).AtlasV2
ids := conversion.DecodeStateID(d.Id())

projectID := ids["project_id"]
roleID := ids["id"]
providerName := ids["provider_name"]

req := &matlas.CloudProviderDeauthorizationRequest{
ProviderName: providerName,
RoleID: roleID,
GroupID: projectID,
req := &admin.DeauthorizeCloudProviderAccessRoleApiParams{
CloudProvider: providerName,
RoleId: roleID,
GroupId: projectID,
}

_, err := conn.CloudProviderAccess.DeauthorizeRole(ctx, req)
_, err := conn.CloudProviderAccessApi.DeauthorizeCloudProviderAccessRoleWithParams(ctx, req).Execute()
if err != nil {
return diag.FromErr(fmt.Errorf(errorCloudProviderAccessDelete, err))
}
Expand All @@ -213,31 +202,31 @@ func resourceMongoDBAtlasCloudProviderAccessSetupDelete(ctx context.Context, d *
return nil
}

func roleToSchemaSetup(role *matlas.CloudProviderAccessRole) map[string]any {
func roleToSchemaSetup(role *admin.CloudProviderAccessRole) map[string]any {
if role.ProviderName == "AWS" {
out := map[string]any{
"provider_name": role.ProviderName,
"provider_name": role.GetProviderName(),
"aws_config": []any{map[string]any{
"atlas_aws_account_arn": role.AtlasAWSAccountARN,
"atlas_assumed_role_external_id": role.AtlasAssumedRoleExternalID,
"atlas_aws_account_arn": role.GetAtlasAWSAccountArn(),
"atlas_assumed_role_external_id": role.GetAtlasAssumedRoleExternalId(),
}},
"created_date": role.CreatedDate,
"role_id": role.RoleID,
"created_date": role.GetCreatedDate(),
"role_id": role.GetRoleId(),
}
return out
}

out := map[string]any{
"provider_name": role.ProviderName,
"azure_config": []any{map[string]any{
"atlas_azure_app_id": role.AtlasAzureAppID,
"service_principal_id": role.AzureServicePrincipalID,
"tenant_id": role.AzureTenantID,
"atlas_azure_app_id": role.GetAtlasAzureAppId(),
"service_principal_id": role.GetServicePrincipalId(),
"tenant_id": role.GetTenantId(),
}},
"aws_config": []any{map[string]any{}},
"created_date": role.CreatedDate,
"last_updated_date": role.LastUpdatedDate,
"role_id": role.AzureID,
"created_date": role.GetCreatedDate(),
"last_updated_date": role.GetLastUpdatedDate(),
"role_id": role.GetRoleId(),
}

return out
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,20 +136,13 @@ func checkExists(resourceName string) resource.TestCheckFunc {
ids := conversion.DecodeStateID(rs.Primary.ID)
providerName := ids["provider_name"]
id := ids["id"]
roles, _, err := acc.Conn().CloudProviderAccess.ListRoles(context.Background(), ids["project_id"])
roles, _, err := acc.ConnV2().CloudProviderAccessApi.ListCloudProviderAccessRoles(context.Background(), ids["project_id"]).Execute()
if err != nil {
return fmt.Errorf(cloudprovideraccess.ErrorCloudProviderGetRead, err)
}
if providerName == "AWS" {
for i := range roles.AWSIAMRoles {
if roles.AWSIAMRoles[i].RoleID == id && roles.AWSIAMRoles[i].ProviderName == providerName {
return nil
}
}
}
if providerName == "AZURE" {
marcosuma marked this conversation as resolved.
Show resolved Hide resolved
for i := range roles.AzureServicePrincipals {
if *roles.AzureServicePrincipals[i].AzureID == id && roles.AzureServicePrincipals[i].ProviderName == providerName {
for i := range roles.GetAwsIamRoles() {
if roles.GetAwsIamRoles()[i].GetRoleId() == id && roles.GetAwsIamRoles()[i].GetProviderName() == providerName {
return nil
}
}
Expand Down
Loading