From 081dae344864803c7bda7ae56d09d4d74d67b653 Mon Sep 17 00:00:00 2001 From: ParthaI <47887552+ParthaI@users.noreply.github.com> Date: Thu, 12 Aug 2021 13:54:49 +0530 Subject: [PATCH] Add Long Term Retention Policies details in table azure_sql_database. Closes #219 (#255) --- .../azure_sql_database/test-get-query.sql | 4 +- azure/table_azure_sql_database.go | 76 ++++++++++++++++++- 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/azure-test/tests/azure_sql_database/test-get-query.sql b/azure-test/tests/azure_sql_database/test-get-query.sql index 8fec39ee..5ab60bcf 100644 --- a/azure-test/tests/azure_sql_database/test-get-query.sql +++ b/azure-test/tests/azure_sql_database/test-get-query.sql @@ -1,6 +1,4 @@ select name, id, server_name, status, type, containment_state, default_secondary_location, earliest_restore_date, edition, elastic_pool_name, location,max_size_bytes, zone_redundant, requested_service_objective_name, service_level_objective,transparent_data_encryption, title, tags, akas, region, resource_group, subscription_id from azure.azure_sql_database -where - name = '{{ resourceName }}' - and resource_group = '{{ resourceName }}'; \ No newline at end of file +where name = '{{ resourceName }}' and resource_group = '{{ resourceName }}'; \ No newline at end of file diff --git a/azure/table_azure_sql_database.go b/azure/table_azure_sql_database.go index bd05e0ee..0af272c5 100644 --- a/azure/table_azure_sql_database.go +++ b/azure/table_azure_sql_database.go @@ -4,6 +4,7 @@ import ( "context" "strings" + sqlV5 "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/v5.0/sql" "github.com/Azure/azure-sdk-for-go/services/preview/sql/mgmt/2017-03-01-preview/sql" "github.com/turbot/steampipe-plugin-sdk/grpc/proto" "github.com/turbot/steampipe-plugin-sdk/plugin/transform" @@ -148,6 +149,33 @@ func tableAzureSqlDatabase(_ context.Context) *plugin.Table { Type: proto.ColumnType_TIMESTAMP, Transform: transform.FromField("DatabaseProperties.RestorePointInTime").Transform(convertDateToTime), }, + { + Name: "requested_service_objective_name", + Description: "The name of the configured service level objective of the database.", + Type: proto.ColumnType_STRING, + Transform: transform.FromField("DatabaseProperties.RequestedServiceObjectiveName"), + }, + { + Name: "retention_policy_id", + Description: "Retention policy ID.", + Type: proto.ColumnType_STRING, + Hydrate: getSqlDatabaseLongTermRetentionPolicies, + Transform: transform.FromField("ID"), + }, + { + Name: "retention_policy_name", + Description: "Retention policy Name.", + Type: proto.ColumnType_STRING, + Hydrate: getSqlDatabaseLongTermRetentionPolicies, + Transform: transform.FromField("Name"), + }, + { + Name: "retention_policy_type", + Description: "Long term Retention policy Type.", + Type: proto.ColumnType_STRING, + Hydrate: getSqlDatabaseLongTermRetentionPolicies, + Transform: transform.FromField("Type"), + }, { Name: "source_database_deletion_date", Description: "Specifies the time that the database was deleted when createMode is Restore and sourceDatabaseId is the deleted database's original resource id.", @@ -185,10 +213,11 @@ func tableAzureSqlDatabase(_ context.Context) *plugin.Table { Transform: transform.FromField("DatabaseProperties.RecommendedIndex"), }, { - Name: "requested_service_objective_name", - Description: "The name of the configured service level objective of the database.", + Name: "retention_policy_property", + Description: "Long term Retention policy Property.", Type: proto.ColumnType_JSON, - Transform: transform.FromField("DatabaseProperties.RequestedServiceObjectiveName"), + Hydrate: getSqlDatabaseLongTermRetentionPolicies, + Transform: transform.FromField("BaseLongTermRetentionPolicyProperties"), }, { Name: "sample_name", @@ -216,7 +245,7 @@ func tableAzureSqlDatabase(_ context.Context) *plugin.Table { Transform: transform.FromField("TransparentDataEncryptionProperties"), }, - // Standard columns + // Azure standard columns { Name: "title", Description: ColumnDescriptionTitle, @@ -362,6 +391,45 @@ func getSqlDatabaseTransparentDataEncryption(ctx context.Context, d *plugin.Quer return nil, nil } +func getSqlDatabaseLongTermRetentionPolicies(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { + var serverName, databaseName, resourceGroupName string + plugin.Logger(ctx).Trace("Hydrate Database Propery", h.Item) + if h.Item != nil { + database := h.Item.(sql.Database) + serverName = strings.Split(*database.ID, "/")[8] + databaseName = *database.Name + resourceGroupName = strings.Split(string(*database.ID), "/")[4] + } else { + serverName = d.KeyColumnQuals["server_name"].GetStringValue() + databaseName = d.KeyColumnQuals["name"].GetStringValue() + resourceGroupName = d.KeyColumnQuals["resource_group"].GetStringValue() + } + + session, err := GetNewSession(ctx, d, "MANAGEMENT") + if err != nil { + return nil, err + } + subscriptionID := session.SubscriptionID + + client := sqlV5.NewLongTermRetentionPoliciesClient(subscriptionID) + client.Authorizer = session.Authorizer + + op, err := client.ListByDatabase(ctx, resourceGroupName, serverName, databaseName) + if err != nil { + return nil, err + } + + // We can add only one retention policy per SQL Database. + res := op.Values() + + // For master database we are getting the response as empty array + if len(res) == 0 { + return nil, nil + } + + return res[0], nil +} + //// TRANSFORM FUNCTION func idToServerName(ctx context.Context, d *transform.TransformData) (interface{}, error) {