diff --git a/internal/services/cosmos/cosmosdb_sql_database_data_source.go b/internal/services/cosmos/cosmosdb_sql_database_data_source.go new file mode 100644 index 000000000000..f828162e649d --- /dev/null +++ b/internal/services/cosmos/cosmosdb_sql_database_data_source.go @@ -0,0 +1,115 @@ +package cosmos + +import ( + "fmt" + "time" + + "github.com/hashicorp/terraform-provider-azurerm/helpers/azure" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/cosmos/common" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/cosmos/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/cosmos/validate" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +func dataSourceCosmosDbSQLDatabase() *pluginsdk.Resource { + return &pluginsdk.Resource{ + Read: dataSourceCosmosDbSQLDatabaseRead, + + Timeouts: &pluginsdk.ResourceTimeout{ + Read: pluginsdk.DefaultTimeout(5 * time.Minute), + }, + + Schema: map[string]*pluginsdk.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosEntityName, + }, + + "resource_group_name": azure.SchemaResourceGroupName(), + + "account_name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.CosmosAccountName, + }, + + "throughput": { + Type: pluginsdk.TypeInt, + Computed: true, + }, + + "autoscale_settings": { + Type: pluginsdk.TypeList, + Computed: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "max_throughput": { + Type: pluginsdk.TypeInt, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceCosmosDbSQLDatabaseRead(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Cosmos.SqlClient + accountClient := meta.(*clients.Client).Cosmos.DatabaseClient + subscriptionId := meta.(*clients.Client).Account.SubscriptionId + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + id := parse.NewSqlDatabaseID(subscriptionId, d.Get("resource_group_name").(string), d.Get("account_name").(string), d.Get("name").(string)) + + resp, err := client.GetSQLDatabase(ctx, id.ResourceGroup, id.DatabaseAccountName, id.Name) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("%s was not found", id) + } + + return fmt.Errorf("reading Cosmos SQL Database %q (Account: %q): %+v", id.Name, id.DatabaseAccountName, err) + } + + d.SetId(id.ID()) + d.Set("resource_group_name", id.ResourceGroup) + d.Set("account_name", id.DatabaseAccountName) + if props := resp.SQLDatabaseGetProperties; props != nil { + if res := props.Resource; res != nil { + d.Set("name", res.ID) + } + } + + accResp, err := accountClient.Get(ctx, id.ResourceGroup, id.DatabaseAccountName) + if err != nil { + return fmt.Errorf("reading CosmosDB Account %q (Resource Group %q): %+v", id.DatabaseAccountName, id.ResourceGroup, err) + } + + if accResp.ID == nil || *accResp.ID == "" { + return fmt.Errorf("cosmosDB Account %q (Resource Group %q) ID is empty or nil", id.DatabaseAccountName, id.ResourceGroup) + } + + // if the cosmos account is serverless calling the get throughput api would yield an error + if !isServerlessCapacityMode(accResp) { + throughputResp, err := client.GetSQLDatabaseThroughput(ctx, id.ResourceGroup, id.DatabaseAccountName, id.Name) + if err != nil { + if !utils.ResponseWasNotFound(throughputResp.Response) { + return fmt.Errorf("reading Throughput on Cosmos SQL Database %q (Account: %q) ID: %v", id.Name, id.DatabaseAccountName, err) + } else { + d.Set("throughput", nil) + d.Set("autoscale_settings", nil) + } + } else { + common.SetResourceDataThroughputFromResponse(throughputResp, d) + } + } + + return nil +} diff --git a/internal/services/cosmos/cosmosdb_sql_database_data_source_test.go b/internal/services/cosmos/cosmosdb_sql_database_data_source_test.go new file mode 100644 index 000000000000..eac4f79eed7e --- /dev/null +++ b/internal/services/cosmos/cosmosdb_sql_database_data_source_test.go @@ -0,0 +1,89 @@ +package cosmos_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" +) + +type CosmosDBSqlDatabaseDataSource struct{} + +func TestAccDataSourceCosmosDBSqlDatabase_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_cosmosdb_sql_database", "test") + r := CosmosDBSqlDatabaseDataSource{} + + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeAggregateTestCheckFunc( + check.That(data.ResourceName).Key("name").Exists(), + ), + }, + }) +} + +func TestAccDataSourceCosmosSqlDatabase_throughput(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_cosmosdb_sql_database", "test") + r := CosmosDBSqlDatabaseDataSource{} + + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: r.throughput(data), + Check: acceptance.ComposeAggregateTestCheckFunc( + check.That(data.ResourceName).Key("name").Exists(), + ), + }, + }) +} + +func TestAccDataSourceCosmosSqlDatabase_serverless(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_cosmosdb_sql_database", "test") + r := CosmosDBSqlDatabaseDataSource{} + + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: r.serverless(data), + Check: acceptance.ComposeAggregateTestCheckFunc( + check.That(data.ResourceName).Key("name").Exists(), + ), + }, + }) +} + +func (CosmosDBSqlDatabaseDataSource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +data "azurerm_cosmosdb_sql_database" "test" { + name = azurerm_cosmosdb_sql_database.test.name + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_cosmosdb_sql_database.test.account_name +} +`, CosmosSqlDatabaseResource{}.basic(data)) +} + +func (CosmosDBSqlDatabaseDataSource) throughput(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +data "azurerm_cosmosdb_sql_database" "test" { + name = azurerm_cosmosdb_sql_database.test.name + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_cosmosdb_sql_database.test.account_name +} +`, CosmosSqlDatabaseResource{}.throughput(data, 4000)) +} + +func (CosmosDBSqlDatabaseDataSource) serverless(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +data "azurerm_cosmosdb_sql_database" "test" { + name = azurerm_cosmosdb_sql_database.test.name + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_cosmosdb_sql_database.test.account_name +} +`, CosmosSqlDatabaseResource{}.serverless(data)) +} diff --git a/internal/services/cosmos/cosmosdb_sql_role_definition_data_source.go b/internal/services/cosmos/cosmosdb_sql_role_definition_data_source.go new file mode 100644 index 000000000000..f72cf3519042 --- /dev/null +++ b/internal/services/cosmos/cosmosdb_sql_role_definition_data_source.go @@ -0,0 +1,113 @@ +package cosmos + +import ( + "fmt" + "time" + + "github.com/hashicorp/terraform-provider-azurerm/helpers/azure" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/cosmos/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/cosmos/validate" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" + "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +func dataSourceCosmosDbSQLRoleDefinition() *pluginsdk.Resource { + return &pluginsdk.Resource{ + Read: dataSourceCosmosDbSQLRoleDefinitionRead, + + Timeouts: &pluginsdk.ResourceTimeout{ + Read: pluginsdk.DefaultTimeout(5 * time.Minute), + }, + + Schema: map[string]*pluginsdk.Schema{ + "resource_group_name": azure.SchemaResourceGroupName(), + + "account_name": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validate.CosmosAccountName, + }, + + "role_definition_id": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.IsUUID, + }, + + "name": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "type": { + Type: pluginsdk.TypeString, + Computed: true, + }, + + "assignable_scopes": { + Type: pluginsdk.TypeSet, + Computed: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "permissions": { + Type: pluginsdk.TypeSet, + Computed: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "data_actions": { + Type: pluginsdk.TypeSet, + Computed: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + }, + }, + }, + }, + } +} + +func dataSourceCosmosDbSQLRoleDefinitionRead(d *pluginsdk.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Cosmos.SqlResourceClient + subscriptionId := meta.(*clients.Client).Account.SubscriptionId + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + roleDefinitionId := d.Get("role_definition_id").(string) + resourceGroup := d.Get("resource_group_name").(string) + accountName := d.Get("account_name").(string) + + id := parse.NewSqlRoleDefinitionID(subscriptionId, resourceGroup, accountName, roleDefinitionId) + + resp, err := client.GetSQLRoleDefinition(ctx, id.Name, id.ResourceGroup, id.DatabaseAccountName) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("%s was not found", id) + } + return fmt.Errorf("retrieving %s: %+v", id, err) + } + + d.SetId(id.ID()) + d.Set("role_definition_id", id.Name) + d.Set("resource_group_name", id.ResourceGroup) + d.Set("account_name", id.DatabaseAccountName) + + if props := resp.SQLRoleDefinitionResource; props != nil { + d.Set("assignable_scopes", utils.FlattenStringSlice(props.AssignableScopes)) + d.Set("name", props.RoleName) + d.Set("type", props.Type) + + if err := d.Set("permissions", flattenSqlRoleDefinitionPermissions(props.Permissions)); err != nil { + return fmt.Errorf("setting `permissions`: %+v", err) + } + } + + return nil +} diff --git a/internal/services/cosmos/cosmosdb_sql_role_definition_data_source_test.go b/internal/services/cosmos/cosmosdb_sql_role_definition_data_source_test.go new file mode 100644 index 000000000000..df6a2aaecd9b --- /dev/null +++ b/internal/services/cosmos/cosmosdb_sql_role_definition_data_source_test.go @@ -0,0 +1,37 @@ +package cosmos_test + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" +) + +type CosmosDBSqlRoleDefinitionDataSource struct{} + +func TestAccDataSourceCosmosDBSqlRoleDefinition_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "data.azurerm_cosmosdb_sql_role_definition", "test") + r := CosmosDBSqlRoleDefinitionDataSource{} + + data.DataSourceTest(t, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeAggregateTestCheckFunc( + check.That(data.ResourceName).Key("name").Exists(), + ), + }, + }) +} + +func (CosmosDBSqlRoleDefinitionDataSource) basic(data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +data "azurerm_cosmosdb_sql_role_definition" "test" { + resource_group_name = azurerm_resource_group.test.name + account_name = azurerm_cosmosdb_account.test.name + role_definition_id = azurerm_cosmosdb_sql_role_definition.test.role_definition_id +} +`, CosmosDbSQLRoleDefinitionResource{}.basic(data)) +} diff --git a/internal/services/cosmos/registration.go b/internal/services/cosmos/registration.go index 7e19826f18f1..e425f0e7c9bf 100644 --- a/internal/services/cosmos/registration.go +++ b/internal/services/cosmos/registration.go @@ -44,6 +44,8 @@ func (r Registration) SupportedDataSources() map[string]*pluginsdk.Resource { "azurerm_cosmosdb_account": dataSourceCosmosDbAccount(), "azurerm_cosmosdb_mongo_database": dataSourceCosmosDbMongoDatabase(), "azurerm_cosmosdb_restorable_database_accounts": dataSourceCosmosDbRestorableDatabaseAccounts(), + "azurerm_cosmosdb_sql_database": dataSourceCosmosDbSQLDatabase(), + "azurerm_cosmosdb_sql_role_definition": dataSourceCosmosDbSQLRoleDefinition(), } } diff --git a/website/docs/d/cosmosdb_sql_database.html.markdown b/website/docs/d/cosmosdb_sql_database.html.markdown new file mode 100644 index 000000000000..220d6204bc53 --- /dev/null +++ b/website/docs/d/cosmosdb_sql_database.html.markdown @@ -0,0 +1,55 @@ +--- +subcategory: "CosmosDB (DocumentDB)" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_cosmosdb_sql_database" +description: |- + Gets information about an existing CosmosDB SQL Database. +--- + +# Data Source: azurerm_cosmosdb_sql_database + +Use this data source to access information about an existing CosmosDB SQL Database. + +## Example Usage + +```hcl +data "azurerm_cosmosdb_sql_database" "example" { + name = "tfex-cosmosdb-sql-database" + resource_group_name = "tfex-cosmosdb-sql-database-rg" + account_name = "tfex-cosmosdb-sql-database-account-name" +} + +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - Specifies the name of the Cosmos DB SQL Database. + +* `resource_group_name` - The name of the resource group in which the Cosmos DB SQL Database is created. + +* `account_name` - The name of the Cosmos DB SQL Database to create the table within. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The ID of the CosmosDB SQL Database. + +* `throughput` -The throughput of SQL database (RU/s). + +* `autoscale_settings` - An `autoscale_settings` block as defined below. + +--- + +An `autoscale_settings` block supports the following: + +* `max_throughput` - The maximum throughput of the SQL database (RU/s). + + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions: + +* `read` - (Defaults to 5 minutes) Used when retrieving the CosmosDB SQL Database. \ No newline at end of file diff --git a/website/docs/d/cosmosdb_sql_role_definition.html.markdown b/website/docs/d/cosmosdb_sql_role_definition.html.markdown new file mode 100644 index 000000000000..80d3241ee3d2 --- /dev/null +++ b/website/docs/d/cosmosdb_sql_role_definition.html.markdown @@ -0,0 +1,57 @@ +--- +subcategory: "CosmosDB (DocumentDB)" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_cosmosdb_sql_role_definition" +description: |- + Gets information about an existing Cosmos DB SQL Role Definition. +--- + +# azurerm_cosmosdb_sql_role_definition + +Use this data source to access information about an existing Cosmos DB SQL Role Definition. + +## Example Usage + +```hcl +data "azurerm_cosmosdb_sql_role_definition" "example" { + name = "tfex-cosmosdb-sql-role-definition" + resource_group_name = "tfex-cosmosdb-sql-role-definition-rg" + account_name = "tfex-cosmosdb-sql-role-definition-account-name" +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `name` - (Required) An user-friendly name for the Cosmos DB SQL Role Definition. + +* `resource_group_name` - (Required) The name of the Resource Group in which the Cosmos DB SQL Role Definition is created. + +* `account_name` - (Required) The name of the Cosmos DB Account. + +* `role_definition_id` - (Optional) The GUID as the name of the Cosmos DB SQL Role Definition. + +## Attributes Reference + +In addition to the Arguments listed above - the following Attributes are exported: + +* `id` - The ID of the Cosmos DB SQL Role Definition. + +* `assignable_scopes` - A list of fully qualified scopes at or below which Role Assignments may be created using this Cosmos DB SQL Role Definition. + +* `type` - The type of the Cosmos DB SQL Role Definition. + +* `permissions` - A `permissions` block as defined below. + +--- + +A `permissions` block supports the following: + +* `data_actions` - A list of data actions that are allowed for the Cosmos DB SQL Role Definition. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions: + +* `read` - (Defaults to 5 minutes) Used when retrieving the Cosmos DB SQL Role Definition.