Skip to content

Commit

Permalink
Add table azure_cosmosdb_restorable_database_account. Closes #595 (#596)
Browse files Browse the repository at this point in the history
  • Loading branch information
karanpopat authored Mar 30, 2023
1 parent 6485e1a commit 87bcb54
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 0 deletions.
1 change: 1 addition & 0 deletions azure/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ func Plugin(ctx context.Context) *plugin.Plugin {
"azure_cosmosdb_account": tableAzureCosmosDBAccount(ctx),
"azure_cosmosdb_mongo_collection": tableAzureCosmosDBMongoCollection(ctx),
"azure_cosmosdb_mongo_database": tableAzureCosmosDBMongoDatabase(ctx),
"azure_cosmosdb_restorable_database_account": tableAzureCosmosDBRestorableDatabaseAccount(ctx),
"azure_cosmosdb_sql_database": tableAzureCosmosDBSQLDatabase(ctx),
"azure_data_factory": tableAzureDataFactory(ctx),
"azure_data_factory_dataset": tableAzureDataFactoryDataset(ctx),
Expand Down
172 changes: 172 additions & 0 deletions azure/table_azure_cosmosdb_restorable_database_account.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package azure

import (
"context"

"github.com/Azure/azure-sdk-for-go/services/preview/cosmos-db/mgmt/2021-04-01-preview/documentdb"
"github.com/Azure/go-autorest/autorest/date"
"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform"

"github.com/turbot/steampipe-plugin-sdk/v5/plugin"
)

//// TABLE DEFINITION

func tableAzureCosmosDBRestorableDatabaseAccount(_ context.Context) *plugin.Table {
return &plugin.Table{
Name: "azure_cosmosdb_restorable_database_account",
Description: "Azure Cosmos DB Restorable Database Account",
List: &plugin.ListConfig{
Hydrate: listCosmosDBRestorableDatabaseAccounts,
},
Columns: azureColumns([]*plugin.Column{
{
Name: "name",
Description: "The friendly name that identifies the restorable database account.",
Type: proto.ColumnType_STRING,
},
{
Name: "id",
Description: "Contains ID to identify a restorable database account uniquely.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("ID"),
},
{
Name: "account_name",
Description: "The name of the global database account.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("RestorableDatabaseAccountProperties.AccountName"),
},
{
Name: "api_type",
Description: "The API type of the restorable database account.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("RestorableDatabaseAccountProperties.APIType"),
},
{
Name: "creation_time",
Description: "The creation time of the restorable database account.",
Type: proto.ColumnType_TIMESTAMP,
Transform: transform.FromField("RestorableDatabaseAccountProperties.CreationTime").Transform(convertDateToTime),
},
{
Name: "deletion_time",
Description: "The time at which the restorable database account has been deleted.",
Type: proto.ColumnType_TIMESTAMP,
Transform: transform.FromField("RestorableDatabaseAccountProperties.DeletionTime").Transform(convertDateToTime),
},
{
Name: "type",
Description: "Type of the resource.",
Type: proto.ColumnType_STRING,
},
{
Name: "restorable_locations",
Description: "List of regions where the database account can be restored from.",
Type: proto.ColumnType_JSON,
Transform: transform.From(mapRestorableLocations),
},

// Steampipe standard columns
{
Name: "title",
Description: ColumnDescriptionTitle,
Type: proto.ColumnType_STRING,
Transform: transform.FromField("Name"),
},
{
Name: "akas",
Description: ColumnDescriptionAkas,
Type: proto.ColumnType_JSON,
Transform: transform.FromField("ID").Transform(idToAkas),
},

// Azure standard columns
{
Name: "region",
Description: ColumnDescriptionRegion,
Type: proto.ColumnType_STRING,
Transform: transform.FromField("Location").Transform(toLower),
},
{
Name: "resource_group",
Description: ColumnDescriptionResourceGroup,
Type: proto.ColumnType_STRING,
Transform: transform.FromField("ID").Transform(extractResourceGroupFromID),
},
}),
}
}

//// LIST FUNCTION

func listCosmosDBRestorableDatabaseAccounts(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) {
logger := plugin.Logger(ctx)

session, err := GetNewSession(ctx, d, "MANAGEMENT")
if err != nil {
logger.Error("azure_cosmosdb_restorable_database_account.listCosmosDBRestorableDatabaseAccounts", "session_error", err)
return nil, err
}

documentDBClient := documentdb.NewRestorableDatabaseAccountsClientWithBaseURI(session.ResourceManagerEndpoint, session.SubscriptionID)
documentDBClient.Authorizer = session.Authorizer

result, err := documentDBClient.List(ctx)
if err != nil {
logger.Error("azure_cosmosdb_restorable_database_account.listCosmosDBRestorableDatabaseAccounts", "api_error", err)
return nil, err
}

for _, account := range *result.Value {
d.StreamListItem(ctx, account)
// Check if context has been cancelled or if the limit has been hit (if specified)
// if there is a limit, it will return the number of rows required to reach this limit
if d.RowsRemaining(ctx) == 0 {
return nil, nil
}
}

return nil, nil
}

type RestorableLocationResource struct {
LocationName string
RegionalDatabaseAccountInstanceID string
CreationTime date.Time
DeletionTime date.Time
}

func mapRestorableLocations(ctx context.Context, d *transform.TransformData) (interface{}, error) {
data := d.HydrateItem.(documentdb.RestorableDatabaseAccountGetResult)

restorableLocations := *data.RestorableDatabaseAccountProperties.RestorableLocations

if restorableLocations == nil || len(restorableLocations) < 1 {
return nil, nil
}

var restorableLocationsArr []RestorableLocationResource
for _, location := range restorableLocations {

var locationResource RestorableLocationResource

if location.LocationName != nil {
locationResource.LocationName = string(*location.LocationName)
}
if location.RegionalDatabaseAccountInstanceID != nil {
locationResource.RegionalDatabaseAccountInstanceID = string(*location.RegionalDatabaseAccountInstanceID)
}
if location.CreationTime != nil {
locationResource.CreationTime = date.Time(*location.CreationTime)
}
if location.DeletionTime != nil {
locationResource.DeletionTime = date.Time(*location.DeletionTime)
}

restorableLocationsArr = append(restorableLocationsArr, locationResource)
}

return restorableLocationsArr, nil
}
59 changes: 59 additions & 0 deletions docs/tables/azure_cosmosdb_restorable_database_account.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Table: azure_cosmosdb_restorable_database_account

Azure Cosmos DB restorable account helps to recover a Cosmos DB account from an accidental write, delete operation, or to restore data into any region.

## Examples

### Basic Info

```sql
select
name,
region,
account_name,
creation_time,
resource_group
from
azure_cosmosdb_restorable_database_account;
```

### Get the regions that the database accounts can be restored from

```sql
select
name,
region,
restorable_locations ->> 'LocationName' as restorable_location,
restorable_locations ->> 'CreationTime' as regional_database_account_creation_time,
restorable_locations ->> 'RegionalDatabaseAccountInstanceID' as restorable_location_database_instance_id
from
azure_cosmosdb_restorable_database_account;
```

### Get the accounts having point-in-time recovery enabled

```sql
select
ra.account_name,
ra.name as restorable_database_account_name,
creation_time,
ra.id as restorable_database_account_id
from
azure_cosmosdb_restorable_database_account ra,
azure_cosmosdb_account a
where
ra.account_name = a.name
and ra.subscription_id = a.subscription_id;
```

### Get the restorable account count per api type

```sql
select
api_type,
count(ra.*) as accounts
from
azure_cosmosdb_restorable_database_account ra
group by
api_type;
```

0 comments on commit 87bcb54

Please sign in to comment.