From b0d3d10972c8bc4685fcd5eb93d062311354777b Mon Sep 17 00:00:00 2001 From: Eike Wichern <eike.wichern@freiheit.com> Date: Tue, 15 Oct 2019 12:28:18 +0200 Subject: [PATCH 01/11] Added throughput config for cosmos mongo databases --- .../resource_arm_cosmosdb_mongo_database.go | 88 +++++++++++++++---- 1 file changed, 71 insertions(+), 17 deletions(-) diff --git a/azurerm/resource_arm_cosmosdb_mongo_database.go b/azurerm/resource_arm_cosmosdb_mongo_database.go index 869d0756e839..edab8758bbac 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_database.go +++ b/azurerm/resource_arm_cosmosdb_mongo_database.go @@ -3,6 +3,8 @@ package azurerm import ( "fmt" "log" + "net/http" + "strconv" "time" "github.com/Azure/azure-sdk-for-go/services/cosmos-db/mgmt/2015-04-08/documentdb" @@ -18,7 +20,8 @@ import ( func resourceArmCosmosDbMongoDatabase() *schema.Resource { return &schema.Resource{ - Create: resourceArmCosmosDbMongoDatabaseCreate, + Create: resourceArmCosmosDbMongoDatabaseCreateUpdate, + Update: resourceArmCosmosDbMongoDatabaseCreateUpdate, Read: resourceArmCosmosDbMongoDatabaseRead, Delete: resourceArmCosmosDbMongoDatabaseDelete, @@ -49,11 +52,18 @@ func resourceArmCosmosDbMongoDatabase() *schema.Resource { ForceNew: true, ValidateFunc: validate.CosmosAccountName, }, + + "throughput": { + Type: schema.TypeInt, + Optional: true, + Default: nil, + ValidateFunc: validate.CosmosThroughput, + }, }, } } -func resourceArmCosmosDbMongoDatabaseCreate(d *schema.ResourceData, meta interface{}) error { +func resourceArmCosmosDbMongoDatabaseCreateUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*ArmClient).Cosmos.DatabaseClient ctx, cancel := timeouts.ForCreate(meta.(*ArmClient).StopContext, d) defer cancel() @@ -61,20 +71,28 @@ func resourceArmCosmosDbMongoDatabaseCreate(d *schema.ResourceData, meta interfa name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) account := d.Get("account_name").(string) + throughput := d.Get("throughput").(int) + dbHasThroughputConfigured := throughput > 0 - if features.ShouldResourcesBeImported() && d.IsNewResource() { - existing, err := client.GetMongoDBDatabase(ctx, resourceGroup, account, name) - if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("Error checking for presence of creating Cosmos Mongo Database %s (Account %s): %+v", name, account, err) - } - } else { - id, err := azure.CosmosGetIDFromResponse(existing.Response) + createUpdateOptions := map[string]*string{} + + if d.IsNewResource() { + if features.ShouldResourcesBeImported() { + existing, err := client.GetMongoDBDatabase(ctx, resourceGroup, account, name) if err != nil { - return fmt.Errorf("Error generating import ID for Cosmos Mongo Database '%s' (Account %s)", name, account) + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of creating Cosmos Mongo Database %s (Account %s): %+v", name, account, err) + } + } else { + id, err := azure.CosmosGetIDFromResponse(existing.Response) + if err != nil { + return fmt.Errorf("Error generating import ID for Cosmos Mongo Database '%s' (Account %s)", name, account) + } + + return tf.ImportAsExistsError("azurerm_cosmosdb_mongo_database", id) } - - return tf.ImportAsExistsError("azurerm_cosmosdb_mongo_database", id) + } else if dbHasThroughputConfigured { + createUpdateOptions["throughput"] = utils.String(strconv.Itoa(throughput)) } } @@ -83,7 +101,7 @@ func resourceArmCosmosDbMongoDatabaseCreate(d *schema.ResourceData, meta interfa Resource: &documentdb.MongoDBDatabaseResource{ ID: &name, }, - Options: map[string]*string{}, + Options: createUpdateOptions, }, } @@ -96,6 +114,30 @@ func resourceArmCosmosDbMongoDatabaseCreate(d *schema.ResourceData, meta interfa return fmt.Errorf("Error waiting on create/update future for Cosmos Mongo Database %s (Account %s): %+v", name, account, err) } + if dbHasThroughputConfigured { + throughputParameters := documentdb.ThroughputUpdateParameters{ + ThroughputUpdateProperties: &documentdb.ThroughputUpdateProperties{ + Resource: &documentdb.ThroughputResource{ + Throughput: utils.Int32(int32(throughput)), + }, + }, + } + + throughputFuture, err := client.UpdateMongoDBDatabaseThroughput(ctx, resourceGroup, account, name, throughputParameters) + if err != nil { + _ = d.Set("throughput", nil) + if throughputFuture.Response().StatusCode == http.StatusNotFound { + return fmt.Errorf("Error setting Throughput for Cosmos MongoDB Database %s (Account %s): %+v - "+ + "If the database has not been created with an initial throughput, you cannot configure it later.", name, account, err) + } + return fmt.Errorf("Error setting Throughput for Cosmos MongoDB Database %s (Account %s): %+v", name, account, err) + } + + if err = throughputFuture.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting on ThroughputUpdate future for Cosmos Mongo Collection %s (Account %s): %+v", name, account, err) + } + } + resp, err := client.GetMongoDBDatabase(ctx, resourceGroup, account, name) if err != nil { return fmt.Errorf("Error making get request for Cosmos Mongo Database %s (Account %s): %+v", name, account, err) @@ -131,10 +173,22 @@ func resourceArmCosmosDbMongoDatabaseRead(d *schema.ResourceData, meta interface return fmt.Errorf("Error reading Cosmos Mongo Database %s (Account %s): %+v", id.Database, id.Account, err) } - d.Set("resource_group_name", id.ResourceGroup) - d.Set("account_name", id.Account) + _ = d.Set("resource_group_name", id.ResourceGroup) + _ = d.Set("account_name", id.Account) if props := resp.MongoDBDatabaseProperties; props != nil { - d.Set("name", props.ID) + _ = d.Set("name", props.ID) + } + + throughputResp, err := client.GetMongoDBDatabaseThroughput(ctx, id.ResourceGroup, id.Account, id.Database) + if err != nil { + if !utils.ResponseWasNotFound(throughputResp.Response) { + _ = d.Set("throughput", nil) + return fmt.Errorf("Error reading Throughput on Cosmos Mongo Database %s (Account %s): %+v", id.Database, id.Account, err) + } + } else { + if throughput := throughputResp.Throughput; throughput != nil { + _ = d.Set("throughput", int(*throughput)) + } } return nil From a18fe62383162347b1084794f8c94ac5f8d6d016 Mon Sep 17 00:00:00 2001 From: Eike Wichern <eike.wichern@freiheit.com> Date: Tue, 15 Oct 2019 13:13:14 +0200 Subject: [PATCH 02/11] Improved throughput config handling for cosmos mongo collections --- .../resource_arm_cosmosdb_mongo_collection.go | 78 ++++++++++++------- .../resource_arm_cosmosdb_mongo_database.go | 2 +- 2 files changed, 49 insertions(+), 31 deletions(-) diff --git a/azurerm/resource_arm_cosmosdb_mongo_collection.go b/azurerm/resource_arm_cosmosdb_mongo_collection.go index 22e2a567ef17..91b3b2a828a4 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_collection.go +++ b/azurerm/resource_arm_cosmosdb_mongo_collection.go @@ -3,6 +3,8 @@ package azurerm import ( "fmt" "log" + "net/http" + "strconv" "strings" "time" @@ -78,7 +80,7 @@ func resourceArmCosmosDbMongoCollection() *schema.Resource { "throughput": { Type: schema.TypeInt, Optional: true, - Default: 400, + Default: nil, ValidateFunc: validate.CosmosThroughput, }, @@ -118,20 +120,27 @@ func resourceArmCosmosDbMongoCollectionCreateUpdate(d *schema.ResourceData, meta account := d.Get("account_name").(string) database := d.Get("database_name").(string) throughput := d.Get("throughput").(int) + dbHasThroughputConfigured := throughput > 0 - if features.ShouldResourcesBeImported() && d.IsNewResource() { - existing, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) - if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("Error checking for presence of creating Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) - } - } else { - id, err := azure.CosmosGetIDFromResponse(existing.Response) + createUpdateOptions := map[string]*string{} + + if d.IsNewResource() { + if features.ShouldResourcesBeImported() { + existing, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) if err != nil { - return fmt.Errorf("Error generating import ID for Cosmos Mongo Collection %s (Account %s, Database %s)", name, account, database) - } + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of creating Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + } + } else { + id, err := azure.CosmosGetIDFromResponse(existing.Response) + if err != nil { + return fmt.Errorf("Error generating import ID for Cosmos Mongo Collection %s (Account %s, Database %s)", name, account, database) + } - return tf.ImportAsExistsError("azurerm_cosmosdb_mongo_collection", id) + return tf.ImportAsExistsError("azurerm_cosmosdb_mongo_collection", id) + } + } else if dbHasThroughputConfigured { + createUpdateOptions["throughput"] = utils.String(strconv.Itoa(throughput)) } } @@ -146,7 +155,7 @@ func resourceArmCosmosDbMongoCollectionCreateUpdate(d *schema.ResourceData, meta ID: &name, Indexes: expandCosmosMongoCollectionIndexes(d.Get("indexes"), ttl), }, - Options: map[string]*string{}, + Options: createUpdateOptions, }, } @@ -165,21 +174,27 @@ func resourceArmCosmosDbMongoCollectionCreateUpdate(d *schema.ResourceData, meta return fmt.Errorf("Error waiting on create/update future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) } - throughputParameters := documentdb.ThroughputUpdateParameters{ - ThroughputUpdateProperties: &documentdb.ThroughputUpdateProperties{ - Resource: &documentdb.ThroughputResource{ - Throughput: utils.Int32(int32(throughput)), + if dbHasThroughputConfigured && !d.IsNewResource() { + throughputParameters := documentdb.ThroughputUpdateParameters{ + ThroughputUpdateProperties: &documentdb.ThroughputUpdateProperties{ + Resource: &documentdb.ThroughputResource{ + Throughput: utils.Int32(int32(throughput)), + }, }, - }, - } + } - throughputFuture, err := client.UpdateMongoDBCollectionThroughput(ctx, resourceGroup, account, database, name, throughputParameters) - if err != nil { - return fmt.Errorf("Error setting Throughput for Cosmos MongoDB Collection %s (Account %s, Database %s): %+v", name, account, database, err) - } + throughputFuture, err := client.UpdateMongoDBCollectionThroughput(ctx, resourceGroup, account, database, name, throughputParameters) + if err != nil { + _ = d.Set("throughput", nil) + if throughputFuture.Response().StatusCode == http.StatusNotFound { + return fmt.Errorf("Error setting Throughput for Cosmos MongoDB Collection %s (Account %s, Database %s): %+v - "+ + "If the collection has not been created with an initial throughput, you cannot configure it later.", name, account, database, err) + } + } - if err = throughputFuture.WaitForCompletionRef(ctx, client.Client); err != nil { - return fmt.Errorf("Error waiting on ThroughputUpdate future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + if err = throughputFuture.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting on ThroughputUpdate future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + } } resp, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) @@ -243,11 +258,14 @@ func resourceArmCosmosDbMongoCollectionRead(d *schema.ResourceData, meta interfa throughputResp, err := client.GetMongoDBCollectionThroughput(ctx, id.ResourceGroup, id.Account, id.Database, id.Collection) if err != nil { - return fmt.Errorf("Error reading Throughput on Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) - } - - if throughput := throughputResp.Throughput; throughput != nil { - d.Set("throughput", int(*throughput)) + if !utils.ResponseWasNotFound(throughputResp.Response) { + _ = d.Set("throughput", nil) + return fmt.Errorf("Error reading Throughput on Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) + } + } else { + if throughput := throughputResp.Throughput; throughput != nil { + _ = d.Set("throughput", int(*throughput)) + } } return nil diff --git a/azurerm/resource_arm_cosmosdb_mongo_database.go b/azurerm/resource_arm_cosmosdb_mongo_database.go index edab8758bbac..1a5d10464c58 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_database.go +++ b/azurerm/resource_arm_cosmosdb_mongo_database.go @@ -114,7 +114,7 @@ func resourceArmCosmosDbMongoDatabaseCreateUpdate(d *schema.ResourceData, meta i return fmt.Errorf("Error waiting on create/update future for Cosmos Mongo Database %s (Account %s): %+v", name, account, err) } - if dbHasThroughputConfigured { + if dbHasThroughputConfigured && !d.IsNewResource() { throughputParameters := documentdb.ThroughputUpdateParameters{ ThroughputUpdateProperties: &documentdb.ThroughputUpdateProperties{ Resource: &documentdb.ThroughputResource{ From 08b72ebff92a3caacf635839e4c235d3c978eb83 Mon Sep 17 00:00:00 2001 From: Eike Wichern <eike.wichern@freiheit.com> Date: Tue, 15 Oct 2019 13:17:17 +0200 Subject: [PATCH 03/11] Updated docs --- website/docs/r/cosmosdb_mongo_collection.html.markdown | 2 +- website/docs/r/cosmosdb_mongo_database.html.markdown | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/website/docs/r/cosmosdb_mongo_collection.html.markdown b/website/docs/r/cosmosdb_mongo_collection.html.markdown index da10f16a8946..d242a16284b1 100644 --- a/website/docs/r/cosmosdb_mongo_collection.html.markdown +++ b/website/docs/r/cosmosdb_mongo_collection.html.markdown @@ -56,7 +56,7 @@ The following arguments are supported: * `database_name` - (Required) The name of the Cosmos DB Mongo Database in which the Cosmos DB Mongo Collection is created. Changing this forces a new resource to be created. * `default_ttl_seconds` - (Required) The default Time To Live in seconds. If the value is `-1` items are not automatically expired. * `shard_key` - (Required) The name of the key to partition on for sharding. There must not be any other unique index keys. -* `throughput` - (Optional) The throughput of the MongoDB collection (RU/s). Must be set in increments of `100`. The default and minimum value is `400`. +* `throughput` - (Optional) The throughput of the MongoDB collection (RU/s). Must be set in increments of `100`. The minimum value is `400`. Setting this for the first time this forces a new resource to be created. * `indexes` - (Optional) One or more `indexes` blocks as defined below. --- diff --git a/website/docs/r/cosmosdb_mongo_database.html.markdown b/website/docs/r/cosmosdb_mongo_database.html.markdown index 1ab26e945ad5..3e5188067b10 100644 --- a/website/docs/r/cosmosdb_mongo_database.html.markdown +++ b/website/docs/r/cosmosdb_mongo_database.html.markdown @@ -23,6 +23,7 @@ resource "azurerm_cosmosdb_mongo_database" "example" { name = "tfex-cosmos-mongo-db" resource_group_name = "${data.azurerm_cosmosdb_account.example.resource_group_name}" account_name = "${data.azurerm_cosmosdb_account.example.name}" + throughput = 400 } ``` @@ -36,6 +37,8 @@ The following arguments are supported: * `account_name` - (Required) The name of the Cosmos DB Mongo Database to create the table within. Changing this forces a new resource to be created. +* `throughput` - (Optional) The throughput of the MongoDB collection (RU/s). Must be set in increments of `100`. The minimum value is `400`. Setting this for the first time this forces a new resource to be created. + ## Attributes Reference From 20c00761775feed3dc51e97c6d23f6d794127a59 Mon Sep 17 00:00:00 2001 From: Eike Wichern <eike.wichern@freiheit.com> Date: Sat, 26 Oct 2019 16:47:35 +0200 Subject: [PATCH 04/11] Changed code according to review --- .../resource_arm_cosmosdb_mongo_collection.go | 33 ++++++++++------ .../resource_arm_cosmosdb_mongo_database.go | 39 ++++++++++++------- .../r/cosmosdb_mongo_collection.html.markdown | 2 +- .../r/cosmosdb_mongo_database.html.markdown | 2 +- 4 files changed, 47 insertions(+), 29 deletions(-) diff --git a/azurerm/resource_arm_cosmosdb_mongo_collection.go b/azurerm/resource_arm_cosmosdb_mongo_collection.go index 91b3b2a828a4..30a9d5298530 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_collection.go +++ b/azurerm/resource_arm_cosmosdb_mongo_collection.go @@ -80,7 +80,6 @@ func resourceArmCosmosDbMongoCollection() *schema.Resource { "throughput": { Type: schema.TypeInt, Optional: true, - Default: nil, ValidateFunc: validate.CosmosThroughput, }, @@ -119,8 +118,18 @@ func resourceArmCosmosDbMongoCollectionCreateUpdate(d *schema.ResourceData, meta resourceGroup := d.Get("resource_group_name").(string) account := d.Get("account_name").(string) database := d.Get("database_name").(string) - throughput := d.Get("throughput").(int) - dbHasThroughputConfigured := throughput > 0 + + throughput, hasThroughput := d.GetOk("throughput") + var throughputStr = "" + var throughputInt = 0 + if hasThroughput { + throughputStr = fmt.Sprintf("%v", throughput) + var err error + throughputInt, err = strconv.Atoi(throughputStr) + if err != nil { + return fmt.Errorf("Configured throughput could not be converted to an integer for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + } + } createUpdateOptions := map[string]*string{} @@ -139,8 +148,9 @@ func resourceArmCosmosDbMongoCollectionCreateUpdate(d *schema.ResourceData, meta return tf.ImportAsExistsError("azurerm_cosmosdb_mongo_collection", id) } - } else if dbHasThroughputConfigured { - createUpdateOptions["throughput"] = utils.String(strconv.Itoa(throughput)) + } + if hasThroughput { + createUpdateOptions["throughput"] = utils.String(throughputStr) } } @@ -174,19 +184,19 @@ func resourceArmCosmosDbMongoCollectionCreateUpdate(d *schema.ResourceData, meta return fmt.Errorf("Error waiting on create/update future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) } - if dbHasThroughputConfigured && !d.IsNewResource() { + if hasThroughput && !d.IsNewResource() { throughputParameters := documentdb.ThroughputUpdateParameters{ ThroughputUpdateProperties: &documentdb.ThroughputUpdateProperties{ Resource: &documentdb.ThroughputResource{ - Throughput: utils.Int32(int32(throughput)), + Throughput: utils.Int32(int32(throughputInt)), }, }, } throughputFuture, err := client.UpdateMongoDBCollectionThroughput(ctx, resourceGroup, account, database, name, throughputParameters) if err != nil { - _ = d.Set("throughput", nil) if throughputFuture.Response().StatusCode == http.StatusNotFound { + d.Set("throughput", nil) return fmt.Errorf("Error setting Throughput for Cosmos MongoDB Collection %s (Account %s, Database %s): %+v - "+ "If the collection has not been created with an initial throughput, you cannot configure it later.", name, account, database, err) } @@ -259,13 +269,12 @@ func resourceArmCosmosDbMongoCollectionRead(d *schema.ResourceData, meta interfa throughputResp, err := client.GetMongoDBCollectionThroughput(ctx, id.ResourceGroup, id.Account, id.Database, id.Collection) if err != nil { if !utils.ResponseWasNotFound(throughputResp.Response) { - _ = d.Set("throughput", nil) return fmt.Errorf("Error reading Throughput on Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) + } else { + d.Set("throughput", nil) } } else { - if throughput := throughputResp.Throughput; throughput != nil { - _ = d.Set("throughput", int(*throughput)) - } + d.Set("throughput", throughputResp.Throughput) } return nil diff --git a/azurerm/resource_arm_cosmosdb_mongo_database.go b/azurerm/resource_arm_cosmosdb_mongo_database.go index 1a5d10464c58..b8517f283409 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_database.go +++ b/azurerm/resource_arm_cosmosdb_mongo_database.go @@ -56,7 +56,6 @@ func resourceArmCosmosDbMongoDatabase() *schema.Resource { "throughput": { Type: schema.TypeInt, Optional: true, - Default: nil, ValidateFunc: validate.CosmosThroughput, }, }, @@ -71,8 +70,18 @@ func resourceArmCosmosDbMongoDatabaseCreateUpdate(d *schema.ResourceData, meta i name := d.Get("name").(string) resourceGroup := d.Get("resource_group_name").(string) account := d.Get("account_name").(string) - throughput := d.Get("throughput").(int) - dbHasThroughputConfigured := throughput > 0 + + throughput, hasThroughput := d.GetOk("throughput") + var throughputStr = "" + var throughputInt = 0 + if hasThroughput { + throughputStr = fmt.Sprintf("%v", throughput) + var err error + throughputInt, err = strconv.Atoi(throughputStr) + if err != nil { + return fmt.Errorf("Configured throughput could not be converted to an integer for Cosmos Mongo Collection %s (Account %s): %+v", name, account, err) + } + } createUpdateOptions := map[string]*string{} @@ -91,8 +100,9 @@ func resourceArmCosmosDbMongoDatabaseCreateUpdate(d *schema.ResourceData, meta i return tf.ImportAsExistsError("azurerm_cosmosdb_mongo_database", id) } - } else if dbHasThroughputConfigured { - createUpdateOptions["throughput"] = utils.String(strconv.Itoa(throughput)) + } + if hasThroughput { + createUpdateOptions["throughput"] = utils.String(throughputStr) } } @@ -114,19 +124,19 @@ func resourceArmCosmosDbMongoDatabaseCreateUpdate(d *schema.ResourceData, meta i return fmt.Errorf("Error waiting on create/update future for Cosmos Mongo Database %s (Account %s): %+v", name, account, err) } - if dbHasThroughputConfigured && !d.IsNewResource() { + if hasThroughput && !d.IsNewResource() { throughputParameters := documentdb.ThroughputUpdateParameters{ ThroughputUpdateProperties: &documentdb.ThroughputUpdateProperties{ Resource: &documentdb.ThroughputResource{ - Throughput: utils.Int32(int32(throughput)), + Throughput: utils.Int32(int32(throughputInt)), }, }, } throughputFuture, err := client.UpdateMongoDBDatabaseThroughput(ctx, resourceGroup, account, name, throughputParameters) if err != nil { - _ = d.Set("throughput", nil) if throughputFuture.Response().StatusCode == http.StatusNotFound { + d.Set("throughput", nil) return fmt.Errorf("Error setting Throughput for Cosmos MongoDB Database %s (Account %s): %+v - "+ "If the database has not been created with an initial throughput, you cannot configure it later.", name, account, err) } @@ -173,22 +183,21 @@ func resourceArmCosmosDbMongoDatabaseRead(d *schema.ResourceData, meta interface return fmt.Errorf("Error reading Cosmos Mongo Database %s (Account %s): %+v", id.Database, id.Account, err) } - _ = d.Set("resource_group_name", id.ResourceGroup) - _ = d.Set("account_name", id.Account) + d.Set("resource_group_name", id.ResourceGroup) + d.Set("account_name", id.Account) if props := resp.MongoDBDatabaseProperties; props != nil { - _ = d.Set("name", props.ID) + d.Set("name", props.ID) } throughputResp, err := client.GetMongoDBDatabaseThroughput(ctx, id.ResourceGroup, id.Account, id.Database) if err != nil { if !utils.ResponseWasNotFound(throughputResp.Response) { - _ = d.Set("throughput", nil) return fmt.Errorf("Error reading Throughput on Cosmos Mongo Database %s (Account %s): %+v", id.Database, id.Account, err) + } else { + d.Set("throughput", nil) } } else { - if throughput := throughputResp.Throughput; throughput != nil { - _ = d.Set("throughput", int(*throughput)) - } + d.Set("throughput", throughputResp.Throughput) } return nil diff --git a/website/docs/r/cosmosdb_mongo_collection.html.markdown b/website/docs/r/cosmosdb_mongo_collection.html.markdown index d242a16284b1..1aa76ad2bcac 100644 --- a/website/docs/r/cosmosdb_mongo_collection.html.markdown +++ b/website/docs/r/cosmosdb_mongo_collection.html.markdown @@ -56,7 +56,7 @@ The following arguments are supported: * `database_name` - (Required) The name of the Cosmos DB Mongo Database in which the Cosmos DB Mongo Collection is created. Changing this forces a new resource to be created. * `default_ttl_seconds` - (Required) The default Time To Live in seconds. If the value is `-1` items are not automatically expired. * `shard_key` - (Required) The name of the key to partition on for sharding. There must not be any other unique index keys. -* `throughput` - (Optional) The throughput of the MongoDB collection (RU/s). Must be set in increments of `100`. The minimum value is `400`. Setting this for the first time this forces a new resource to be created. +* `throughput` - (Optional) The throughput of the MongoDB collection (RU/s). Must be set in increments of `100`. The minimum value is `400`. This must be set upon database creation otherwise it cannot be updated without a manual terraform destroy-apply. * `indexes` - (Optional) One or more `indexes` blocks as defined below. --- diff --git a/website/docs/r/cosmosdb_mongo_database.html.markdown b/website/docs/r/cosmosdb_mongo_database.html.markdown index 3e5188067b10..336fc0fe66f5 100644 --- a/website/docs/r/cosmosdb_mongo_database.html.markdown +++ b/website/docs/r/cosmosdb_mongo_database.html.markdown @@ -37,7 +37,7 @@ The following arguments are supported: * `account_name` - (Required) The name of the Cosmos DB Mongo Database to create the table within. Changing this forces a new resource to be created. -* `throughput` - (Optional) The throughput of the MongoDB collection (RU/s). Must be set in increments of `100`. The minimum value is `400`. Setting this for the first time this forces a new resource to be created. +* `throughput` - (Optional) The throughput of the MongoDB collection (RU/s). Must be set in increments of `100`. The minimum value is `400`. This must be set upon database creation otherwise it cannot be updated without a manual terraform destroy-apply. ## Attributes Reference From 12cd71069df2d53739eee585a3d9c7990ac1547c Mon Sep 17 00:00:00 2001 From: Eike Wichern <eike.wichern@freiheit.com> Date: Sun, 10 Nov 2019 00:40:03 +0100 Subject: [PATCH 05/11] Adapted acceptance test --- azurerm/resource_arm_cosmosdb_mongo_collection_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/azurerm/resource_arm_cosmosdb_mongo_collection_test.go b/azurerm/resource_arm_cosmosdb_mongo_collection_test.go index 0aa21f7edff2..3ffa7346b09d 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_collection_test.go +++ b/azurerm/resource_arm_cosmosdb_mongo_collection_test.go @@ -24,7 +24,9 @@ func TestAccAzureRMCosmosDbMongoCollection_basic(t *testing.T) { Config: testAccAzureRMCosmosDbMongoCollection_basic(ri, testLocation()), Check: resource.ComposeAggregateTestCheckFunc( testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), + resource.TestCheckResourceAttr(resourceName, "throughput", "400"), ), + ExpectNonEmptyPlan: true, }, { ResourceName: resourceName, From 9d05458254da8c4aae89fdd4e43b8876b041364d Mon Sep 17 00:00:00 2001 From: kt <kt@katbyte.me> Date: Fri, 6 Dec 2019 14:47:39 -0800 Subject: [PATCH 06/11] stash --- .../resource_arm_cosmosdb_mongo_collection.go | 142 +++++++++++------- .../resource_arm_cosmosdb_mongo_database.go | 1 + 2 files changed, 88 insertions(+), 55 deletions(-) diff --git a/azurerm/resource_arm_cosmosdb_mongo_collection.go b/azurerm/resource_arm_cosmosdb_mongo_collection.go index 30a9d5298530..dfc27709f9d3 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_collection.go +++ b/azurerm/resource_arm_cosmosdb_mongo_collection.go @@ -22,9 +22,9 @@ import ( func resourceArmCosmosDbMongoCollection() *schema.Resource { return &schema.Resource{ - Create: resourceArmCosmosDbMongoCollectionCreateUpdate, + Create: resourceArmCosmosDbMongoCollectionCreate, Read: resourceArmCosmosDbMongoCollectionRead, - Update: resourceArmCosmosDbMongoCollectionCreateUpdate, + Update: resourceArmCosmosDbMongoCollectionUpdate, Delete: resourceArmCosmosDbMongoCollectionDelete, Importer: &schema.ResourceImporter{ @@ -80,6 +80,7 @@ func resourceArmCosmosDbMongoCollection() *schema.Resource { "throughput": { Type: schema.TypeInt, Optional: true, + Computed: true, ValidateFunc: validate.CosmosThroughput, }, @@ -109,7 +110,7 @@ func resourceArmCosmosDbMongoCollection() *schema.Resource { } } -func resourceArmCosmosDbMongoCollectionCreateUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceArmCosmosDbMongoCollectionCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*ArmClient).Cosmos.DatabaseClient ctx, cancel := timeouts.ForCreateUpdate(meta.(*ArmClient).StopContext, d) defer cancel() @@ -119,38 +120,19 @@ func resourceArmCosmosDbMongoCollectionCreateUpdate(d *schema.ResourceData, meta account := d.Get("account_name").(string) database := d.Get("database_name").(string) - throughput, hasThroughput := d.GetOk("throughput") - var throughputStr = "" - var throughputInt = 0 - if hasThroughput { - throughputStr = fmt.Sprintf("%v", throughput) - var err error - throughputInt, err = strconv.Atoi(throughputStr) + if features.ShouldResourcesBeImported() { + existing, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) if err != nil { - return fmt.Errorf("Configured throughput could not be converted to an integer for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) - } - } - - createUpdateOptions := map[string]*string{} - - if d.IsNewResource() { - if features.ShouldResourcesBeImported() { - existing, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of creating Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + } + } else { + id, err := azure.CosmosGetIDFromResponse(existing.Response) if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("Error checking for presence of creating Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) - } - } else { - id, err := azure.CosmosGetIDFromResponse(existing.Response) - if err != nil { - return fmt.Errorf("Error generating import ID for Cosmos Mongo Collection %s (Account %s, Database %s)", name, account, database) - } - - return tf.ImportAsExistsError("azurerm_cosmosdb_mongo_collection", id) + return fmt.Errorf("Error generating import ID for Cosmos Mongo Collection %s (Account %s, Database %s)", name, account, database) } - } - if hasThroughput { - createUpdateOptions["throughput"] = utils.String(throughputStr) + + return tf.ImportAsExistsError("azurerm_cosmosdb_mongo_collection", id) } } @@ -165,10 +147,15 @@ func resourceArmCosmosDbMongoCollectionCreateUpdate(d *schema.ResourceData, meta ID: &name, Indexes: expandCosmosMongoCollectionIndexes(d.Get("indexes"), ttl), }, - Options: createUpdateOptions, }, } + if throughput, hasThroughput := d.GetOk("throughput"); hasThroughput { + db.MongoDBCollectionCreateUpdateProperties.Options = map[string]*string{ + "throughput": utils.String(strconv.Itoa(throughput.(int))), + } + } + if v, ok := d.GetOkExists("shard_key"); ok { db.MongoDBCollectionCreateUpdateProperties.Resource.ShardKey = map[string]*string{ v.(string): utils.String("Hash"), // looks like only hash is supported for now @@ -184,39 +171,84 @@ func resourceArmCosmosDbMongoCollectionCreateUpdate(d *schema.ResourceData, meta return fmt.Errorf("Error waiting on create/update future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) } - if hasThroughput && !d.IsNewResource() { - throughputParameters := documentdb.ThroughputUpdateParameters{ - ThroughputUpdateProperties: &documentdb.ThroughputUpdateProperties{ - Resource: &documentdb.ThroughputResource{ - Throughput: utils.Int32(int32(throughputInt)), - }, + resp, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) + if err != nil { + return fmt.Errorf("Error making get request for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + } + + id, err := azure.CosmosGetIDFromResponse(resp.Response) + if err != nil { + return fmt.Errorf("Error getting ID for Cosmos Mongo Collection %s (Account %s, Database %s) ID: %v", name, account, database, err) + } + d.SetId(id) + + return resourceArmCosmosDbMongoCollectionRead(d, meta) +} + +func resourceArmCosmosDbMongoCollectionUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).Cosmos.DatabaseClient + ctx, cancel := timeouts.ForCreateUpdate(meta.(*ArmClient).StopContext, d) + defer cancel() + + id, err := azure.ParseCosmosDatabaseCollectionID(d.Id()) + if err != nil { + return err + } + + var ttl *int + if v, ok := d.GetOkExists("default_ttl_seconds"); ok { + ttl = utils.Int(v.(int)) + } + + db := documentdb.MongoDBCollectionCreateUpdateParameters{ + MongoDBCollectionCreateUpdateProperties: &documentdb.MongoDBCollectionCreateUpdateProperties{ + Resource: &documentdb.MongoDBCollectionResource{ + ID: &id.Collection, + Indexes: expandCosmosMongoCollectionIndexes(d.Get("indexes"), ttl), }, - } + }, + } - throughputFuture, err := client.UpdateMongoDBCollectionThroughput(ctx, resourceGroup, account, database, name, throughputParameters) - if err != nil { - if throughputFuture.Response().StatusCode == http.StatusNotFound { - d.Set("throughput", nil) - return fmt.Errorf("Error setting Throughput for Cosmos MongoDB Collection %s (Account %s, Database %s): %+v - "+ - "If the collection has not been created with an initial throughput, you cannot configure it later.", name, account, database, err) - } + if v, ok := d.GetOkExists("shard_key"); ok { + db.MongoDBCollectionCreateUpdateProperties.Resource.ShardKey = map[string]*string{ + v.(string): utils.String("Hash"), // looks like only hash is supported for now } + } - if err = throughputFuture.WaitForCompletionRef(ctx, client.Client); err != nil { - return fmt.Errorf("Error waiting on ThroughputUpdate future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) - } + future, err := client.CreateUpdateMongoDBCollection(ctx, id.ResourceGroup, id.Account, id.Database, id.Collection, db) + if err != nil { + return fmt.Errorf("Error issuing create/update request for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) } - resp, err := client.GetMongoDBCollection(ctx, resourceGroup, account, database, name) + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting on create/update future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) + } + + throughputParameters := documentdb.ThroughputUpdateParameters{ + ThroughputUpdateProperties: &documentdb.ThroughputUpdateProperties{ + Resource: &documentdb.ThroughputResource{ + Throughput: utils.Int32(int32(throughputInt)), + }, + }, + } + + throughputFuture, err := client.UpdateMongoDBCollectionThroughput(ctx, id.ResourceGroup, id.Account, id.Database, id.Collection, throughputParameters) if err != nil { - return fmt.Errorf("Error making get request for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", name, account, database, err) + if throughputFuture.Response().StatusCode == http.StatusNotFound { + d.Set("throughput", nil) + return fmt.Errorf("Error setting Throughput for Cosmos MongoDB Collection %s (Account %s, Database %s): %+v - "+ + "If the collection has not been created with an initial throughput, you cannot configure it later.", id.Collection, id.Account, id.Database, err) + } } - id, err := azure.CosmosGetIDFromResponse(resp.Response) + if err = throughputFuture.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting on ThroughputUpdate future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) + } + + resp, err := client.GetMongoDBCollection(ctx, id.ResourceGroup, id.Account, id.Database, id.Collection) if err != nil { - return fmt.Errorf("Error getting ID for Cosmos Mongo Collection %s (Account %s, Database %s) ID: %v", name, account, database, err) + return fmt.Errorf("Error making get request for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) } - d.SetId(id) return resourceArmCosmosDbMongoCollectionRead(d, meta) } diff --git a/azurerm/resource_arm_cosmosdb_mongo_database.go b/azurerm/resource_arm_cosmosdb_mongo_database.go index b8517f283409..af542b3b8b8b 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_database.go +++ b/azurerm/resource_arm_cosmosdb_mongo_database.go @@ -56,6 +56,7 @@ func resourceArmCosmosDbMongoDatabase() *schema.Resource { "throughput": { Type: schema.TypeInt, Optional: true, + Computed: true, ValidateFunc: validate.CosmosThroughput, }, }, From 11a2d3474fcef3d26dbd070192a830f286b2b807 Mon Sep 17 00:00:00 2001 From: kt <kt@katbyte.me> Date: Mon, 9 Dec 2019 16:00:18 -0800 Subject: [PATCH 07/11] fix mongo throughput & deprecate collection indexes --- .../resource_arm_cosmosdb_mongo_collection.go | 44 +++---- ...urce_arm_cosmosdb_mongo_collection_test.go | 96 ++++++++++----- .../resource_arm_cosmosdb_mongo_database.go | 116 +++++++++++------- ...source_arm_cosmosdb_mongo_database_test.go | 37 ++++++ website/docs/r/network_watcher.html.markdown | 2 +- 5 files changed, 193 insertions(+), 102 deletions(-) diff --git a/azurerm/resource_arm_cosmosdb_mongo_collection.go b/azurerm/resource_arm_cosmosdb_mongo_collection.go index dfc27709f9d3..fd19c59dc046 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_collection.go +++ b/azurerm/resource_arm_cosmosdb_mongo_collection.go @@ -85,8 +85,9 @@ func resourceArmCosmosDbMongoCollection() *schema.Resource { }, "indexes": { - Type: schema.TypeSet, - Optional: true, + Type: schema.TypeSet, + Optional: true, + Deprecated: "Indexes are ignored unless they are the shared key so have ben deprecated. ", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "key": { @@ -147,6 +148,7 @@ func resourceArmCosmosDbMongoCollectionCreate(d *schema.ResourceData, meta inter ID: &name, Indexes: expandCosmosMongoCollectionIndexes(d.Get("indexes"), ttl), }, + Options: map[string]*string{}, }, } @@ -206,6 +208,7 @@ func resourceArmCosmosDbMongoCollectionUpdate(d *schema.ResourceData, meta inter ID: &id.Collection, Indexes: expandCosmosMongoCollectionIndexes(d.Get("indexes"), ttl), }, + Options: map[string]*string{}, }, } @@ -224,30 +227,27 @@ func resourceArmCosmosDbMongoCollectionUpdate(d *schema.ResourceData, meta inter return fmt.Errorf("Error waiting on create/update future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) } - throughputParameters := documentdb.ThroughputUpdateParameters{ - ThroughputUpdateProperties: &documentdb.ThroughputUpdateProperties{ - Resource: &documentdb.ThroughputResource{ - Throughput: utils.Int32(int32(throughputInt)), + if d.HasChange("throughput") { + throughputParameters := documentdb.ThroughputUpdateParameters{ + ThroughputUpdateProperties: &documentdb.ThroughputUpdateProperties{ + Resource: &documentdb.ThroughputResource{ + Throughput: utils.Int32(int32(d.Get("throughput").(int))), + }, }, - }, - } - - throughputFuture, err := client.UpdateMongoDBCollectionThroughput(ctx, id.ResourceGroup, id.Account, id.Database, id.Collection, throughputParameters) - if err != nil { - if throughputFuture.Response().StatusCode == http.StatusNotFound { - d.Set("throughput", nil) - return fmt.Errorf("Error setting Throughput for Cosmos MongoDB Collection %s (Account %s, Database %s): %+v - "+ - "If the collection has not been created with an initial throughput, you cannot configure it later.", id.Collection, id.Account, id.Database, err) } - } - if err = throughputFuture.WaitForCompletionRef(ctx, client.Client); err != nil { - return fmt.Errorf("Error waiting on ThroughputUpdate future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) - } + throughputFuture, err := client.UpdateMongoDBCollectionThroughput(ctx, id.ResourceGroup, id.Account, id.Database, id.Collection, throughputParameters) + if err != nil { + if throughputFuture.Response().StatusCode == http.StatusNotFound { + d.Set("throughput", nil) + return fmt.Errorf("Error setting Throughput for Cosmos MongoDB Collection %s (Account %s, Database %s): %+v - "+ + "If the collection has not been created with an initial throughput, you cannot configure it later.", id.Collection, id.Account, id.Database, err) + } + } - resp, err := client.GetMongoDBCollection(ctx, id.ResourceGroup, id.Account, id.Database, id.Collection) - if err != nil { - return fmt.Errorf("Error making get request for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) + if err = throughputFuture.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting on ThroughputUpdate future for Cosmos Mongo Collection %s (Account %s, Database %s): %+v", id.Collection, id.Account, id.Database, err) + } } return resourceArmCosmosDbMongoCollectionRead(d, meta) diff --git a/azurerm/resource_arm_cosmosdb_mongo_collection_test.go b/azurerm/resource_arm_cosmosdb_mongo_collection_test.go index 3ffa7346b09d..91c76f59a925 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_collection_test.go +++ b/azurerm/resource_arm_cosmosdb_mongo_collection_test.go @@ -50,10 +50,9 @@ func TestAccAzureRMCosmosDbMongoCollection_complete(t *testing.T) { Config: testAccAzureRMCosmosDbMongoCollection_complete(ri, testLocation()), Check: resource.ComposeAggregateTestCheckFunc( testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "shard_key", "day"), + resource.TestCheckResourceAttr(resourceName, "shard_key", "seven"), resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "707"), resource.TestCheckResourceAttr(resourceName, "indexes.#", "2"), - resource.TestCheckResourceAttr(resourceName, "throughput", "600"), ), }, { @@ -87,7 +86,6 @@ func TestAccAzureRMCosmosDbMongoCollection_update(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "shard_key", "day"), resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "707"), resource.TestCheckResourceAttr(resourceName, "indexes.#", "2"), - resource.TestCheckResourceAttr(resourceName, "throughput", "600"), ), }, { @@ -101,7 +99,52 @@ func TestAccAzureRMCosmosDbMongoCollection_update(t *testing.T) { testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "70707"), resource.TestCheckResourceAttr(resourceName, "indexes.#", "3"), - resource.TestCheckResourceAttr(resourceName, "throughput", "400"), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func TestAccAzureRMCosmosDbMongoCollection_throughput(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_mongo_collection.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbMongoCollectionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDbMongoCollection_throughput(ri, testLocation(), 700), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMCosmosDbMongoCollection_throughput(ri, testLocation(), 1400), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + { + Config: testAccAzureRMCosmosDbMongoCollection_basic(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), ), }, { @@ -194,19 +237,8 @@ resource "azurerm_cosmosdb_mongo_collection" "test" { account_name = "${azurerm_cosmosdb_mongo_database.test.account_name}" database_name = "${azurerm_cosmosdb_mongo_database.test.name}" + shard_key = "seven" default_ttl_seconds = 707 - shard_key = "day" - throughput = 600 - - indexes { - key = "seven" - unique = false - } - - indexes { - key = "day" - unique = true - } } `, testAccAzureRMCosmosDbMongoDatabase_basic(rInt, location), rInt) } @@ -221,23 +253,23 @@ resource "azurerm_cosmosdb_mongo_collection" "test" { account_name = "${azurerm_cosmosdb_mongo_database.test.account_name}" database_name = "${azurerm_cosmosdb_mongo_database.test.name}" + shard_key = "seven" default_ttl_seconds = 70707 - throughput = 400 - - indexes { - key = "seven" - unique = true - } - - indexes { - key = "day" - unique = false - } - - indexes { - key = "fool" - unique = false - } } `, testAccAzureRMCosmosDbMongoDatabase_basic(rInt, location), rInt) } + +func testAccAzureRMCosmosDbMongoCollection_throughput(rInt int, location string, throughput int) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_cosmosdb_mongo_collection" "test" { + name = "acctest-%[2]d" + resource_group_name = "${azurerm_cosmosdb_mongo_database.test.resource_group_name}" + account_name = "${azurerm_cosmosdb_mongo_database.test.account_name}" + database_name = "${azurerm_cosmosdb_mongo_database.test.name}" + + throughput = %[3]d +} +`, testAccAzureRMCosmosDbMongoDatabase_basic(rInt, location), rInt, throughput) +} diff --git a/azurerm/resource_arm_cosmosdb_mongo_database.go b/azurerm/resource_arm_cosmosdb_mongo_database.go index af542b3b8b8b..84a50e45dcbc 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_database.go +++ b/azurerm/resource_arm_cosmosdb_mongo_database.go @@ -20,8 +20,8 @@ import ( func resourceArmCosmosDbMongoDatabase() *schema.Resource { return &schema.Resource{ - Create: resourceArmCosmosDbMongoDatabaseCreateUpdate, - Update: resourceArmCosmosDbMongoDatabaseCreateUpdate, + Create: resourceArmCosmosDbMongoDatabaseCreate, + Update: resourceArmCosmosDbMongoDatabaseUpdate, Read: resourceArmCosmosDbMongoDatabaseRead, Delete: resourceArmCosmosDbMongoDatabaseDelete, @@ -63,7 +63,7 @@ func resourceArmCosmosDbMongoDatabase() *schema.Resource { } } -func resourceArmCosmosDbMongoDatabaseCreateUpdate(d *schema.ResourceData, meta interface{}) error { +func resourceArmCosmosDbMongoDatabaseCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*ArmClient).Cosmos.DatabaseClient ctx, cancel := timeouts.ForCreate(meta.(*ArmClient).StopContext, d) defer cancel() @@ -72,38 +72,19 @@ func resourceArmCosmosDbMongoDatabaseCreateUpdate(d *schema.ResourceData, meta i resourceGroup := d.Get("resource_group_name").(string) account := d.Get("account_name").(string) - throughput, hasThroughput := d.GetOk("throughput") - var throughputStr = "" - var throughputInt = 0 - if hasThroughput { - throughputStr = fmt.Sprintf("%v", throughput) - var err error - throughputInt, err = strconv.Atoi(throughputStr) + if features.ShouldResourcesBeImported() { + existing, err := client.GetMongoDBDatabase(ctx, resourceGroup, account, name) if err != nil { - return fmt.Errorf("Configured throughput could not be converted to an integer for Cosmos Mongo Collection %s (Account %s): %+v", name, account, err) - } - } - - createUpdateOptions := map[string]*string{} - - if d.IsNewResource() { - if features.ShouldResourcesBeImported() { - existing, err := client.GetMongoDBDatabase(ctx, resourceGroup, account, name) + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of creating Cosmos Mongo Database %s (Account %s): %+v", name, account, err) + } + } else { + id, err := azure.CosmosGetIDFromResponse(existing.Response) if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("Error checking for presence of creating Cosmos Mongo Database %s (Account %s): %+v", name, account, err) - } - } else { - id, err := azure.CosmosGetIDFromResponse(existing.Response) - if err != nil { - return fmt.Errorf("Error generating import ID for Cosmos Mongo Database '%s' (Account %s)", name, account) - } - - return tf.ImportAsExistsError("azurerm_cosmosdb_mongo_database", id) + return fmt.Errorf("Error generating import ID for Cosmos Mongo Database '%s' (Account %s)", name, account) } - } - if hasThroughput { - createUpdateOptions["throughput"] = utils.String(throughputStr) + + return tf.ImportAsExistsError("azurerm_cosmosdb_mongo_database", id) } } @@ -112,10 +93,16 @@ func resourceArmCosmosDbMongoDatabaseCreateUpdate(d *schema.ResourceData, meta i Resource: &documentdb.MongoDBDatabaseResource{ ID: &name, }, - Options: createUpdateOptions, + Options: map[string]*string{}, }, } + if throughput, hasThroughput := d.GetOk("throughput"); hasThroughput { + db.MongoDBDatabaseCreateUpdateProperties.Options = map[string]*string{ + "throughput": utils.String(strconv.Itoa(throughput.(int))), + } + } + future, err := client.CreateUpdateMongoDBDatabase(ctx, resourceGroup, account, name, db) if err != nil { return fmt.Errorf("Error issuing create/update request for Cosmos Mongo Database %s (Account %s): %+v", name, account, err) @@ -125,41 +112,76 @@ func resourceArmCosmosDbMongoDatabaseCreateUpdate(d *schema.ResourceData, meta i return fmt.Errorf("Error waiting on create/update future for Cosmos Mongo Database %s (Account %s): %+v", name, account, err) } - if hasThroughput && !d.IsNewResource() { + resp, err := client.GetMongoDBDatabase(ctx, resourceGroup, account, name) + if err != nil { + return fmt.Errorf("Error making get request for Cosmos Mongo Database %s (Account %s): %+v", name, account, err) + } + + id, err := azure.CosmosGetIDFromResponse(resp.Response) + if err != nil { + return fmt.Errorf("Error retrieving the ID for Cosmos Mongo Database '%s' (Account %s) ID: %v", name, account, err) + } + d.SetId(id) + + return resourceArmCosmosDbMongoDatabaseRead(d, meta) +} + +func resourceArmCosmosDbMongoDatabaseUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient).Cosmos.DatabaseClient + ctx, cancel := timeouts.ForCreate(meta.(*ArmClient).StopContext, d) + defer cancel() + + id, err := azure.ParseCosmosDatabaseID(d.Id()) + if err != nil { + return err + } + + db := documentdb.MongoDBDatabaseCreateUpdateParameters{ + MongoDBDatabaseCreateUpdateProperties: &documentdb.MongoDBDatabaseCreateUpdateProperties{ + Resource: &documentdb.MongoDBDatabaseResource{ + ID: &id.Database, + }, + Options: map[string]*string{}, + }, + } + + future, err := client.CreateUpdateMongoDBDatabase(ctx, id.ResourceGroup, id.Account, id.Database, db) + if err != nil { + return fmt.Errorf("Error issuing create/update request for Cosmos Mongo Database %s (Account %s): %+v", id.Database, id.Account, err) + } + + if err = future.WaitForCompletionRef(ctx, client.Client); err != nil { + return fmt.Errorf("Error waiting on create/update future for Cosmos Mongo Database %s (Account %s): %+v", id.Database, id.Account, err) + } + + if d.HasChange("throughput") { throughputParameters := documentdb.ThroughputUpdateParameters{ ThroughputUpdateProperties: &documentdb.ThroughputUpdateProperties{ Resource: &documentdb.ThroughputResource{ - Throughput: utils.Int32(int32(throughputInt)), + Throughput: utils.Int32(int32(d.Get("throughput").(int))), }, }, } - throughputFuture, err := client.UpdateMongoDBDatabaseThroughput(ctx, resourceGroup, account, name, throughputParameters) + throughputFuture, err := client.UpdateMongoDBDatabaseThroughput(ctx, id.ResourceGroup, id.Account, id.Database, throughputParameters) if err != nil { if throughputFuture.Response().StatusCode == http.StatusNotFound { d.Set("throughput", nil) return fmt.Errorf("Error setting Throughput for Cosmos MongoDB Database %s (Account %s): %+v - "+ - "If the database has not been created with an initial throughput, you cannot configure it later.", name, account, err) + "If the collection has not been created with an initial throughput, you cannot configure it later.", id.Database, id.Account, err) } - return fmt.Errorf("Error setting Throughput for Cosmos MongoDB Database %s (Account %s): %+v", name, account, err) } if err = throughputFuture.WaitForCompletionRef(ctx, client.Client); err != nil { - return fmt.Errorf("Error waiting on ThroughputUpdate future for Cosmos Mongo Collection %s (Account %s): %+v", name, account, err) + return fmt.Errorf("Error waiting on ThroughputUpdate future for Cosmos Mongo Database %s (Account %s, Database %s): %+v", id.Database, id.Account, id.Database, err) } } - resp, err := client.GetMongoDBDatabase(ctx, resourceGroup, account, name) + _, err = client.GetMongoDBDatabase(ctx, id.ResourceGroup, id.Account, id.Database) if err != nil { - return fmt.Errorf("Error making get request for Cosmos Mongo Database %s (Account %s): %+v", name, account, err) + return fmt.Errorf("Error making get request for Cosmos Mongo Database %s (Account %s): %+v", id.Database, id.Account, err) } - id, err := azure.CosmosGetIDFromResponse(resp.Response) - if err != nil { - return fmt.Errorf("Error retrieving the ID for Cosmos Mongo Database '%s' (Account %s) ID: %v", name, account, err) - } - d.SetId(id) - return resourceArmCosmosDbMongoDatabaseRead(d, meta) } diff --git a/azurerm/resource_arm_cosmosdb_mongo_database_test.go b/azurerm/resource_arm_cosmosdb_mongo_database_test.go index e41a66c30b91..e0495491282d 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_database_test.go +++ b/azurerm/resource_arm_cosmosdb_mongo_database_test.go @@ -35,6 +35,30 @@ func TestAccAzureRMCosmosDbMongoDatabase_basic(t *testing.T) { }) } +func TestAccAzureRMCosmosDbMongoDatabase_complete(t *testing.T) { + ri := tf.AccRandTimeInt() + resourceName := "azurerm_cosmosdb_mongo_database.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMCosmosDbMongoDatabaseDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMCosmosDbMongoDatabase_basic(ri, testLocation()), + Check: resource.ComposeAggregateTestCheckFunc( + testCheckAzureRMCosmosDbMongoDatabaseExists(resourceName), + ), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func testCheckAzureRMCosmosDbMongoDatabaseDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*ArmClient).Cosmos.DatabaseClient ctx := testAccProvider.Meta().(*ArmClient).StopContext @@ -102,3 +126,16 @@ resource "azurerm_cosmosdb_mongo_database" "test" { } `, testAccAzureRMCosmosDBAccount_mongoDB(rInt, location), rInt) } + +func testAccAzureRMCosmosDbMongoDatabase_complete(rInt int, location string) string { + return fmt.Sprintf(` +%[1]s + +resource "azurerm_cosmosdb_mongo_database" "test" { + name = "acctest-%[2]d" + resource_group_name = "${azurerm_cosmosdb_account.test.resource_group_name}" + account_name = "${azurerm_cosmosdb_account.test.name}" + throughput = 700 +} +`, testAccAzureRMCosmosDBAccount_mongoDB(rInt, location), rInt) +} diff --git a/website/docs/r/network_watcher.html.markdown b/website/docs/r/network_watcher.html.markdown index 9a4f07e87740..0f300d6971ad 100644 --- a/website/docs/r/network_watcher.html.markdown +++ b/website/docs/r/network_watcher.html.markdown @@ -35,7 +35,7 @@ The following arguments are supported: * `resource_group_name` - (Required) The name of the resource group in which to create the Network Watcher. Changing this forces a new resource to be created. -* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. +* `location` - (Required) `Specifies the supported Azure location where the resource exists`. Changing this forces a new resource to be created. * `tags` - (Optional) A mapping of tags to assign to the resource. From bc07b716739eeeb11e6d4281c96645bcb4dd95f9 Mon Sep 17 00:00:00 2001 From: kt <kt@katbyte.me> Date: Mon, 9 Dec 2019 17:02:31 -0800 Subject: [PATCH 08/11] fix test checks --- azurerm/resource_arm_cosmosdb_mongo_collection_test.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/azurerm/resource_arm_cosmosdb_mongo_collection_test.go b/azurerm/resource_arm_cosmosdb_mongo_collection_test.go index 91c76f59a925..2de12869f3b2 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_collection_test.go +++ b/azurerm/resource_arm_cosmosdb_mongo_collection_test.go @@ -52,7 +52,6 @@ func TestAccAzureRMCosmosDbMongoCollection_complete(t *testing.T) { testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), resource.TestCheckResourceAttr(resourceName, "shard_key", "seven"), resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "707"), - resource.TestCheckResourceAttr(resourceName, "indexes.#", "2"), ), }, { @@ -83,9 +82,8 @@ func TestAccAzureRMCosmosDbMongoCollection_update(t *testing.T) { Config: testAccAzureRMCosmosDbMongoCollection_complete(ri, testLocation()), Check: resource.ComposeAggregateTestCheckFunc( testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "shard_key", "day"), + resource.TestCheckResourceAttr(resourceName, "shard_key", "seven"), resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "707"), - resource.TestCheckResourceAttr(resourceName, "indexes.#", "2"), ), }, { @@ -98,7 +96,6 @@ func TestAccAzureRMCosmosDbMongoCollection_update(t *testing.T) { Check: resource.ComposeAggregateTestCheckFunc( testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), resource.TestCheckResourceAttr(resourceName, "default_ttl_seconds", "70707"), - resource.TestCheckResourceAttr(resourceName, "indexes.#", "3"), ), }, { From dfd0efc5c07361327503a80b189acb5aabfb488e Mon Sep 17 00:00:00 2001 From: kt <kt@katbyte.me> Date: Tue, 10 Dec 2019 10:10:38 -0800 Subject: [PATCH 09/11] fix test --- azurerm/resource_arm_cosmosdb_mongo_collection_test.go | 1 - azurerm/resource_arm_cosmosdb_mongo_database_test.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/azurerm/resource_arm_cosmosdb_mongo_collection_test.go b/azurerm/resource_arm_cosmosdb_mongo_collection_test.go index 2de12869f3b2..207020e8d317 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_collection_test.go +++ b/azurerm/resource_arm_cosmosdb_mongo_collection_test.go @@ -26,7 +26,6 @@ func TestAccAzureRMCosmosDbMongoCollection_basic(t *testing.T) { testCheckAzureRMCosmosDbMongoCollectionExists(resourceName), resource.TestCheckResourceAttr(resourceName, "throughput", "400"), ), - ExpectNonEmptyPlan: true, }, { ResourceName: resourceName, diff --git a/azurerm/resource_arm_cosmosdb_mongo_database_test.go b/azurerm/resource_arm_cosmosdb_mongo_database_test.go index e0495491282d..1a76b049d1c1 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_database_test.go +++ b/azurerm/resource_arm_cosmosdb_mongo_database_test.go @@ -45,7 +45,7 @@ func TestAccAzureRMCosmosDbMongoDatabase_complete(t *testing.T) { CheckDestroy: testCheckAzureRMCosmosDbMongoDatabaseDestroy, Steps: []resource.TestStep{ { - Config: testAccAzureRMCosmosDbMongoDatabase_basic(ri, testLocation()), + Config: testAccAzureRMCosmosDbMongoDatabase_complete(ri, testLocation()), Check: resource.ComposeAggregateTestCheckFunc( testCheckAzureRMCosmosDbMongoDatabaseExists(resourceName), ), From c51400bb9e526bddacd8fab6cda97e1e9fba20c5 Mon Sep 17 00:00:00 2001 From: kt <kt@katbyte.me> Date: Tue, 10 Dec 2019 16:02:49 -0800 Subject: [PATCH 10/11] Update network_watcher.html.markdown --- website/docs/r/network_watcher.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/network_watcher.html.markdown b/website/docs/r/network_watcher.html.markdown index 99b52e9d46dd..64620c344282 100644 --- a/website/docs/r/network_watcher.html.markdown +++ b/website/docs/r/network_watcher.html.markdown @@ -35,7 +35,7 @@ The following arguments are supported: * `resource_group_name` - (Required) The name of the resource group in which to create the Network Watcher. Changing this forces a new resource to be created. -* `location` - (Required) `Specifies the supported Azure location where the resource exists`. Changing this forces a new resource to be created. +* `location` - (Required) Specifies the supported Azure location where the resource exists. Changing this forces a new resource to be created. * `tags` - (Optional) A mapping of tags to assign to the resource. From 55d795fd40fa0a581dd7516fd278a413623e42c0 Mon Sep 17 00:00:00 2001 From: kt <kt@katbyte.me> Date: Tue, 10 Dec 2019 16:03:00 -0800 Subject: [PATCH 11/11] Update azurerm/resource_arm_cosmosdb_mongo_collection.go Co-Authored-By: Matthew Frahry <mbfrahry@gmail.com> --- azurerm/resource_arm_cosmosdb_mongo_collection.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azurerm/resource_arm_cosmosdb_mongo_collection.go b/azurerm/resource_arm_cosmosdb_mongo_collection.go index c0fdbfd6d96a..04e134541abe 100644 --- a/azurerm/resource_arm_cosmosdb_mongo_collection.go +++ b/azurerm/resource_arm_cosmosdb_mongo_collection.go @@ -87,7 +87,7 @@ func resourceArmCosmosDbMongoCollection() *schema.Resource { "indexes": { Type: schema.TypeSet, Optional: true, - Deprecated: "Indexes are ignored unless they are the shared key so have ben deprecated. ", + Deprecated: "Indexes are ignored unless they are the shared key so have been deprecated.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "key": {