Skip to content

Commit

Permalink
New DataSource: data.azurerm_cosmosdb_sql_database and `data.azurer…
Browse files Browse the repository at this point in the history
…m_cosmosdb_sql_role_definition` (#18728)
  • Loading branch information
mbfrahry authored Oct 13, 2022
1 parent c4e4503 commit d699bd2
Show file tree
Hide file tree
Showing 7 changed files with 468 additions and 0 deletions.
115 changes: 115 additions & 0 deletions internal/services/cosmos/cosmosdb_sql_database_data_source.go
Original file line number Diff line number Diff line change
@@ -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
}
89 changes: 89 additions & 0 deletions internal/services/cosmos/cosmosdb_sql_database_data_source_test.go
Original file line number Diff line number Diff line change
@@ -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))
}
113 changes: 113 additions & 0 deletions internal/services/cosmos/cosmosdb_sql_role_definition_data_source.go
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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))
}
2 changes: 2 additions & 0 deletions internal/services/cosmos/registration.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
}
}

Expand Down
Loading

0 comments on commit d699bd2

Please sign in to comment.