Skip to content

Commit

Permalink
chore: Upgrades access_list_api_key resource to auto-generated SDK (#…
Browse files Browse the repository at this point in the history
…1877)

* data_source_accesslist_api_key

* data_source_accesslist_api_keys

* rename resource functions

* rename test functions

* migration tests

* read, delete

* create

* apply feedback to reduce identation level in flattenAccessListAPIKeys

* apply feedback to use ctx

* apply feedback: fix PageNum and ItemsPerPage

* new sdk in tests

* import
  • Loading branch information
lantoli committed Jan 29, 2024
1 parent 383b0c5 commit 3daca65
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 117 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/migration-tests.yml
Expand Up @@ -73,6 +73,8 @@ jobs:
project:
- 'internal/service/project/*.go'
- 'internal/service/projectipaccesslist/*.go'
- 'internal/service/accesslistapikey/*.go'
- 'internal/service/projectinvitation/*.go'
config:
- 'internal/service/alertconfiguration/*.go'
- 'internal/service/atlasuser/*.go'
Expand Down
Expand Up @@ -8,12 +8,13 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
"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/conversion"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/config"
)

func DataSource() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceMongoDBAtlasAccessListAPIKeyRead,
ReadContext: dataSourceRead,
Schema: map[string]*schema.Schema{
"org_id": {
Type: schema.TypeString,
Expand Down Expand Up @@ -52,14 +53,12 @@ func DataSource() *schema.Resource {
}
}

func dataSourceMongoDBAtlasAccessListAPIKeyRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
// Get client connection.
conn := meta.(*config.MongoDBClient).Atlas

func dataSourceRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
connV2 := meta.(*config.MongoDBClient).AtlasV2
orgID := d.Get("org_id").(string)
apiKeyID := d.Get("api_key_id").(string)
ipAddress := d.Get("ip_address").(string)
accessListAPIKey, _, err := conn.AccessListAPIKeys.Get(ctx, orgID, apiKeyID, ipAddress)
accessListAPIKey, _, err := connV2.ProgrammaticAPIKeysApi.GetApiKeyAccessList(ctx, orgID, ipAddress, apiKeyID).Execute()
if err != nil {
return diag.FromErr(fmt.Errorf("error getting access list api key information: %s", err))
}
Expand All @@ -72,11 +71,11 @@ func dataSourceMongoDBAtlasAccessListAPIKeyRead(ctx context.Context, d *schema.R
return diag.FromErr(fmt.Errorf("error setting `last_used_address`: %s", err))
}

if err := d.Set("last_used", accessListAPIKey.LastUsed); err != nil {
if err := d.Set("last_used", conversion.TimePtrToStringPtr(accessListAPIKey.LastUsed)); err != nil {
return diag.FromErr(fmt.Errorf("error setting `last_used`: %s", err))
}

if err := d.Set("created", accessListAPIKey.Created); err != nil {
if err := d.Set("created", conversion.TimePtrToStringPtr(accessListAPIKey.Created)); err != nil {
return diag.FromErr(fmt.Errorf("error setting `created`: %s", err))
}

Expand Down
Expand Up @@ -20,18 +20,16 @@ func TestAccConfigDSAccesslistAPIKey_basic(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acc.PreCheckBasic(t) },
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
CheckDestroy: testAccCheckMongoDBAtlasAccessListAPIKeyDestroy,
CheckDestroy: checkDestroy,
Steps: []resource.TestStep{
{
Config: testAccDSMongoDBAtlasAccesslistAPIKeyConfig(orgID, description, ipAddress),
Config: configDS(orgID, description, ipAddress),
Check: resource.ComposeTestCheckFunc(
// Test for Resource
testAccCheckMongoDBAtlasAccessListAPIKeyExists(resourceName),
checkExists(resourceName),
resource.TestCheckResourceAttrSet(resourceName, "org_id"),
resource.TestCheckResourceAttrSet(resourceName, "ip_address"),
resource.TestCheckResourceAttr(resourceName, "org_id", orgID),
resource.TestCheckResourceAttr(resourceName, "ip_address", ipAddress),
// Test for Data source
resource.TestCheckResourceAttrSet(dataSourceName, "org_id"),
resource.TestCheckResourceAttrSet(dataSourceName, "ip_address"),
resource.TestCheckResourceAttr(dataSourceName, "ip_address", ipAddress),
Expand All @@ -41,7 +39,7 @@ func TestAccConfigDSAccesslistAPIKey_basic(t *testing.T) {
})
}

func testAccDSMongoDBAtlasAccesslistAPIKeyConfig(orgID, description, ipAddress string) string {
func configDS(orgID, description, ipAddress string) string {
return fmt.Sprintf(`
data "mongodbatlas_access_list_api_key" "test" {
org_id = %[1]q
Expand Down
Expand Up @@ -7,14 +7,15 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/id"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"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/v20231115005/admin"
)

func PluralDataSource() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceMongoDBAtlasAccessListAPIKeysRead,
ReadContext: dataSourcePluralRead,
Schema: map[string]*schema.Schema{
"org_id": {
Type: schema.TypeString,
Expand Down Expand Up @@ -68,27 +69,44 @@ func PluralDataSource() *schema.Resource {
}
}

func dataSourceMongoDBAtlasAccessListAPIKeysRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
// Get client connection.
conn := meta.(*config.MongoDBClient).Atlas
options := &matlas.ListOptions{
PageNum: d.Get("page_num").(int),
ItemsPerPage: d.Get("items_per_page").(int),
}

func dataSourcePluralRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
connV2 := meta.(*config.MongoDBClient).AtlasV2
orgID := d.Get("org_id").(string)
apiKeyID := d.Get("api_key_id").(string)

accessListAPIKeys, _, err := conn.AccessListAPIKeys.List(ctx, orgID, apiKeyID, options)
params := &admin.ListApiKeyAccessListsEntriesApiParams{
PageNum: conversion.IntPtr(d.Get("page_num").(int)),
ItemsPerPage: conversion.IntPtr(d.Get("items_per_page").(int)),
OrgId: orgID,
ApiUserId: apiKeyID,
}
accessListAPIKeys, _, err := connV2.ProgrammaticAPIKeysApi.ListApiKeyAccessListsEntriesWithParams(ctx, params).Execute()
if err != nil {
return diag.FromErr(fmt.Errorf("error getting access list api keys information: %s", err))
}

if err := d.Set("results", flattenAccessListAPIKeys(ctx, conn, orgID, accessListAPIKeys.Results)); err != nil {
if err := d.Set("results", flattenAccessListAPIKeys(ctx, orgID, accessListAPIKeys.GetResults())); err != nil {
return diag.FromErr(fmt.Errorf("error setting `results`: %s", err))
}

d.SetId(id.UniqueId())

return nil
}

func flattenAccessListAPIKeys(ctx context.Context, orgID string, list []admin.UserAccessList) []map[string]any {
if len(list) == 0 {
return nil
}
results := make([]map[string]any, len(list))
for k, elm := range list {
results[k] = map[string]any{
"ip_address": elm.IpAddress,
"cidr_block": elm.CidrBlock,
"created": conversion.TimePtrToStringPtr(elm.Created),
"access_count": elm.Count,
"last_used": conversion.TimePtrToStringPtr(elm.LastUsed),
"last_used_address": elm.LastUsedAddress,
}
}
return results
}
Expand Up @@ -20,18 +20,16 @@ func TestAccConfigDSAccesslistAPIKeys_basic(t *testing.T) {
resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { acc.PreCheckBasic(t) },
ProtoV6ProviderFactories: acc.TestAccProviderV6Factories,
CheckDestroy: testAccCheckMongoDBAtlasAccessListAPIKeyDestroy,
CheckDestroy: checkDestroy,
Steps: []resource.TestStep{
{
Config: testAccDSMongoDBAtlasAccesslistAPIKeysConfig(orgID, description, ipAddress),
Config: configDSPlural(orgID, description, ipAddress),
Check: resource.ComposeTestCheckFunc(
// Test for Resource
testAccCheckMongoDBAtlasAccessListAPIKeyExists(resourceName),
checkExists(resourceName),
resource.TestCheckResourceAttrSet(resourceName, "org_id"),
resource.TestCheckResourceAttrSet(resourceName, "ip_address"),
resource.TestCheckResourceAttr(resourceName, "org_id", orgID),
resource.TestCheckResourceAttr(resourceName, "ip_address", ipAddress),
// Test for Data source
resource.TestCheckResourceAttrSet(dataSourceName, "org_id"),
resource.TestCheckResourceAttrSet(dataSourceName, "results.#"),
),
Expand All @@ -40,7 +38,7 @@ func TestAccConfigDSAccesslistAPIKeys_basic(t *testing.T) {
})
}

func testAccDSMongoDBAtlasAccesslistAPIKeysConfig(orgID, description, ipAddress string) string {
func configDSPlural(orgID, description, ipAddress string) string {
return fmt.Sprintf(`
data "mongodbatlas_access_list_api_keys" "test" {
org_id = %[1]q
Expand Down
83 changes: 32 additions & 51 deletions internal/service/accesslistapikey/resource_access_list_api_key.go
Expand Up @@ -13,17 +13,17 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"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/v20231115005/admin"
)

func Resource() *schema.Resource {
return &schema.Resource{
CreateContext: resourceMongoDBAtlasAccessListAPIKeyCreate,
ReadContext: resourceMongoDBAtlasAccessListAPIKeyRead,
UpdateContext: resourceMongoDBAtlasAccessListAPIKeyUpdate,
DeleteContext: resourceMongoDBAtlasAccessListAPIKeyDelete,
CreateContext: resourceCreate,
ReadContext: resourceRead,
UpdateContext: resourceUpdate,
DeleteContext: resourceDelete,
Importer: &schema.ResourceImporter{
StateContext: resourceMongoDBAtlasAccessListAPIKeyImportState,
StateContext: resourceImport,
},
Schema: map[string]*schema.Schema{
"org_id": {
Expand Down Expand Up @@ -72,8 +72,8 @@ func Resource() *schema.Resource {
}
}

func resourceMongoDBAtlasAccessListAPIKeyCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
conn := meta.(*config.MongoDBClient).Atlas
func resourceCreate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
connV2 := meta.(*config.MongoDBClient).AtlasV2
orgID := d.Get("org_id").(string)
apiKeyID := d.Get("api_key_id").(string)
IPAddress := d.Get("ip_address").(string)
Expand All @@ -95,20 +95,19 @@ func resourceMongoDBAtlasAccessListAPIKeyCreate(ctx context.Context, d *schema.R
entry = IPAddress
}

createReq := matlas.AccessListAPIKeysReq{}
createReq.CidrBlock = CIDRBlock
createReq.IPAddress = IPAddress

createRequest := []*matlas.AccessListAPIKeysReq{}
createRequest = append(createRequest, &createReq)
accessList := &[]admin.UserAccessList{
{
CidrBlock: conversion.StringPtr(CIDRBlock),
IpAddress: conversion.StringPtr(IPAddress),
},
}

_, resp, err := conn.AccessListAPIKeys.Create(ctx, orgID, apiKeyID, createRequest)
_, resp, err := connV2.ProgrammaticAPIKeysApi.CreateApiKeyAccessList(ctx, orgID, apiKeyID, accessList).Execute()
if err != nil {
if resp != nil && resp.StatusCode == http.StatusNotFound {
d.SetId("")
return nil
}

return diag.FromErr(fmt.Errorf("error create API key: %s", err))
}

Expand All @@ -118,17 +117,17 @@ func resourceMongoDBAtlasAccessListAPIKeyCreate(ctx context.Context, d *schema.R
"entry": entry,
}))

return resourceMongoDBAtlasAccessListAPIKeyRead(ctx, d, meta)
return resourceRead(ctx, d, meta)
}

func resourceMongoDBAtlasAccessListAPIKeyRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
// Get client connection.
conn := meta.(*config.MongoDBClient).Atlas
func resourceRead(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
connV2 := meta.(*config.MongoDBClient).AtlasV2
ids := conversion.DecodeStateID(d.Id())
orgID := ids["org_id"]
apiKeyID := ids["api_key_id"]

apiKey, resp, err := conn.AccessListAPIKeys.Get(ctx, orgID, apiKeyID, strings.ReplaceAll(ids["entry"], "/", "%2F"))
ipAddress := strings.ReplaceAll(ids["entry"], "/", "%2F")
apiKey, resp, err := connV2.ProgrammaticAPIKeysApi.GetApiKeyAccessList(ctx, orgID, ipAddress, apiKeyID).Execute()
if err != nil {
if resp != nil && resp.StatusCode == http.StatusNotFound || resp.StatusCode == http.StatusBadRequest {
d.SetId("")
Expand All @@ -141,7 +140,7 @@ func resourceMongoDBAtlasAccessListAPIKeyRead(ctx context.Context, d *schema.Res
return diag.FromErr(fmt.Errorf("error setting `api_key_id`: %s", err))
}

if err := d.Set("ip_address", apiKey.IPAddress); err != nil {
if err := d.Set("ip_address", apiKey.IpAddress); err != nil {
return diag.FromErr(fmt.Errorf("error setting `ip_address`: %s", err))
}

Expand All @@ -158,25 +157,25 @@ func resourceMongoDBAtlasAccessListAPIKeyRead(ctx context.Context, d *schema.Res
return nil
}

func resourceMongoDBAtlasAccessListAPIKeyUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
return resourceMongoDBAtlasAccessListAPIKeyRead(ctx, d, meta)
func resourceUpdate(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
return resourceRead(ctx, d, meta)
}

func resourceMongoDBAtlasAccessListAPIKeyDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
conn := meta.(*config.MongoDBClient).Atlas
func resourceDelete(ctx context.Context, d *schema.ResourceData, meta any) diag.Diagnostics {
connV2 := meta.(*config.MongoDBClient).AtlasV2
ids := conversion.DecodeStateID(d.Id())
orgID := ids["org_id"]
apiKeyID := ids["api_key_id"]

_, err := conn.AccessListAPIKeys.Delete(ctx, orgID, apiKeyID, strings.ReplaceAll(ids["entry"], "/", "%2F"))
ipAddress := strings.ReplaceAll(ids["entry"], "/", "%2F")
_, _, err := connV2.ProgrammaticAPIKeysApi.DeleteApiKeyAccessListEntry(ctx, orgID, apiKeyID, ipAddress).Execute()
if err != nil {
return diag.FromErr(fmt.Errorf("error deleting API Key: %s", err))
}
return nil
}

func resourceMongoDBAtlasAccessListAPIKeyImportState(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) {
conn := meta.(*config.MongoDBClient).Atlas
func resourceImport(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) {
connV2 := meta.(*config.MongoDBClient).AtlasV2

parts := strings.SplitN(d.Id(), "-", 3)
if len(parts) != 3 {
Expand All @@ -187,7 +186,8 @@ func resourceMongoDBAtlasAccessListAPIKeyImportState(ctx context.Context, d *sch
apiKeyID := parts[1]
entry := parts[2]

r, _, err := conn.AccessListAPIKeys.Get(ctx, orgID, apiKeyID, strings.ReplaceAll(entry, "/", "%2F"))
ipAddress := strings.ReplaceAll(entry, "/", "%2F")
r, _, err := connV2.ProgrammaticAPIKeysApi.GetApiKeyAccessList(ctx, orgID, ipAddress, apiKeyID).Execute()
if err != nil {
return nil, fmt.Errorf("couldn't import api key %s in project %s, error: %s", orgID, apiKeyID, err)
}
Expand All @@ -196,7 +196,7 @@ func resourceMongoDBAtlasAccessListAPIKeyImportState(ctx context.Context, d *sch
return nil, fmt.Errorf("error setting `org_id`: %s", err)
}

if err := d.Set("ip_address", r.IPAddress); err != nil {
if err := d.Set("ip_address", r.IpAddress); err != nil {
return nil, fmt.Errorf("error setting `ip_address`: %s", err)
}

Expand All @@ -212,22 +212,3 @@ func resourceMongoDBAtlasAccessListAPIKeyImportState(ctx context.Context, d *sch

return []*schema.ResourceData{d}, nil
}

func flattenAccessListAPIKeys(ctx context.Context, conn *matlas.Client, orgID string, accessListAPIKeys []*matlas.AccessListAPIKey) []map[string]any {
var results []map[string]any

if len(accessListAPIKeys) > 0 {
results = make([]map[string]any, len(accessListAPIKeys))
for k, accessListAPIKey := range accessListAPIKeys {
results[k] = map[string]any{
"ip_address": accessListAPIKey.IPAddress,
"cidr_block": accessListAPIKey.CidrBlock,
"created": accessListAPIKey.Created,
"access_count": accessListAPIKey.Count,
"last_used": accessListAPIKey.LastUsed,
"last_used_address": accessListAPIKey.LastUsedAddress,
}
}
}
return results
}

0 comments on commit 3daca65

Please sign in to comment.