From 2518d3a9cd5a21088afb28d93f3067a9812a63fa Mon Sep 17 00:00:00 2001 From: bigdatasourav Date: Fri, 1 Apr 2022 14:02:08 +0530 Subject: [PATCH 1/9] Added New table --- azure/plugin.go | 2 +- azure/service.go | 4 +- azure/table_azure_management_group.go | 173 ++++++++++++++++++++++++++ docs/tables/azure_management_group.md | 42 +++++++ 4 files changed, 218 insertions(+), 3 deletions(-) create mode 100644 azure/table_azure_management_group.go create mode 100644 docs/tables/azure_management_group.md diff --git a/azure/plugin.go b/azure/plugin.go index 8f9f585f..746d03e8 100644 --- a/azure/plugin.go +++ b/azure/plugin.go @@ -96,6 +96,7 @@ func Plugin(ctx context.Context) *plugin.Plugin { "azure_log_profile": tableAzureLogProfile(ctx), "azure_logic_app_workflow": tableAzureLogicAppWorkflow(ctx), "azure_machine_learning_workspace": tableAzureMachineLearningWorkspace(ctx), + "azure_management_group": tableAzureManagementGroup(ctx), "azure_management_lock": tableAzureManagementLock(ctx), "azure_mariadb_server": tableAzureMariaDBServer(ctx), "azure_mssql_elasticpool": tableAzureMSSQLElasticPool(ctx), @@ -145,7 +146,6 @@ func Plugin(ctx context.Context) *plugin.Plugin { "azure_tenant": tableAzureTenant(ctx), "azure_virtual_network": tableAzureVirtualNetwork(ctx), "azure_virtual_network_gateway": tableAzureVirtualNetworkGateway(ctx), - // "azure_storage_table": tableAzureStorageTable(ctx), }, } diff --git a/azure/service.go b/azure/service.go index 5c9bb137..b96ca9b9 100644 --- a/azure/service.go +++ b/azure/service.go @@ -42,11 +42,11 @@ type Session struct { func GetNewSession(ctx context.Context, d *plugin.QueryData, tokenAudience string) (session *Session, err error) { logger := plugin.Logger(ctx) - cacheKey := "GetNewSession" + cacheKey := "GetNewSession" + tokenAudience if cachedData, ok := d.ConnectionManager.Cache.Get(cacheKey); ok { session = cachedData.(*Session) if session.Expires != nil && WillExpireIn(*session.Expires, 0) { - d.ConnectionManager.Cache.Delete("GetNewSession") + d.ConnectionManager.Cache.Delete(cacheKey) } else { return cachedData.(*Session), nil } diff --git a/azure/table_azure_management_group.go b/azure/table_azure_management_group.go new file mode 100644 index 00000000..a6bc4f99 --- /dev/null +++ b/azure/table_azure_management_group.go @@ -0,0 +1,173 @@ +package azure + +import ( + "context" + + "github.com/Azure/azure-sdk-for-go/profiles/latest/resources/mgmt/managementgroups" + "github.com/turbot/steampipe-plugin-sdk/v2/grpc/proto" + "github.com/turbot/steampipe-plugin-sdk/v2/plugin/transform" + + "github.com/turbot/steampipe-plugin-sdk/v2/plugin" +) + +//// TABLE DEFINITION + +func tableAzureManagementGroup(_ context.Context) *plugin.Table { + return &plugin.Table{ + Name: "azure_management_group", + Description: "Azure Management Group.", + Get: &plugin.GetConfig{ + KeyColumns: plugin.SingleColumn("name"), + Hydrate: getManagementGroup, + }, + List: &plugin.ListConfig{ + Hydrate: listManagementGroups, + }, + + Columns: []*plugin.Column{ + { + Name: "id", + Type: proto.ColumnType_STRING, + Description: "The fully qualified ID for the management group.", + Transform: transform.FromField("ID"), + }, + { + Name: "name", + Description: "The name of the management group.", + Type: proto.ColumnType_STRING, + }, + { + Name: "type", + Description: "The type of the management group.", + Type: proto.ColumnType_STRING, + }, + { + Name: "display_name", + Description: "The friendly name of the management group.", + Type: proto.ColumnType_STRING, + Transform: transform.FromField("InfoProperties.DisplayName","Properties.DisplayName"), + }, + { + Name: "tenant_id", + Description: "The AAD Tenant ID associated with the management group.", + Type: proto.ColumnType_STRING, + Transform: transform.FromField("InfoProperties.TenantID","Properties.TenantID"), + }, + { + Name: "updated_by", + Description: "The identity of the principal or process that updated the management group.", + Type: proto.ColumnType_STRING, + Hydrate: getManagementGroup, + Transform: transform.FromField("Properties.Details.UpdatedBy"), + }, + { + Name: "updated_time", + Description: "The date and time when this management group was last updated.", + Type: proto.ColumnType_TIMESTAMP, + Hydrate: getManagementGroup, + Transform: transform.FromField("Properties.Details.UpdatedTime.Time"), + }, + { + Name: "version", + Description: "The version number of the management group.", + Type: proto.ColumnType_DOUBLE, + Hydrate: getManagementGroup, + Transform: transform.FromField("Properties.Details.Version"), + }, + { + Name: "children", + Description: "The list of children of the management group.", + Type: proto.ColumnType_JSON, + Hydrate: getManagementGroup, + Transform: transform.FromField("Properties.Children"), + }, + { + Name: "parent", + Description: "The associated parent management group.", + Type: proto.ColumnType_JSON, + Hydrate: getManagementGroup, + Transform: transform.FromField("Properties.Details.Parent"), + }, + + // 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), + }, + }, + } +} + +//// LIST FUNCTION + +func listManagementGroups(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { + session, err := GetNewSession(ctx, d, "MANAGEMENT") + if err != nil { + return nil, err + } + + mgClient := managementgroups.NewClient() + mgClient.Authorizer = session.Authorizer + + result, err := mgClient.List(ctx, "", "") + if err != nil { + return nil, err + } + for _, mg := range result.Values() { + d.StreamListItem(ctx, mg) + } + + for result.NotDone() { + err = result.NextWithContext(ctx) + if err != nil { + return nil, err + } + for _, mg := range result.Values() { + d.StreamListItem(ctx, mg) + } + } + + return nil, err +} + +//// HYDRATE FUNCTIONS + +func getManagementGroup(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { + plugin.Logger(ctx).Trace("getManagementGroup") + + var name string + if h.Item != nil { + name = *h.Item.(managementgroups.Info).Name + } else { + name = d.KeyColumnQuals["name"].GetStringValue() + } + + // check if name is empty + if name == ""{ + return nil,nil + } + + session, err := GetNewSession(ctx, d, "MANAGEMENT") + if err != nil { + return nil, err + } + + mgClient := managementgroups.NewClient() + mgClient.Authorizer = session.Authorizer + + op, err := mgClient.Get(ctx, name,"children",nil,"","") + if err != nil { + return nil, err + } + + return op, nil +} + diff --git a/docs/tables/azure_management_group.md b/docs/tables/azure_management_group.md new file mode 100644 index 00000000..b7c5654b --- /dev/null +++ b/docs/tables/azure_management_group.md @@ -0,0 +1,42 @@ +# Table: azure_management_group + +Management groups provide a governance scope above subscriptions. You organize subscriptions into management groups in the governance conditions you apply cascade by inheritance to all associated subscriptions. Management groups give you enterprise-grade management at a scale no matter what type of subscriptions you might have. However, all subscriptions within a single management group must trust the same Azure Active Directory (Azure AD) tenant. + +Note: To query this table, you need to have read access to the specific management group. + +## Examples + +### Basic info + +```sql +select + id, + name, + type, + tenant_id, + updated_by +from + azure_management_group; +``` + +### List children for a specific management group + +```sql +select + name, + updated_by, + jsonb_pretty(children) as children +from + azure_management_group; +``` + +### Get parent detail for a specific management group + +```sql +select + name, + updated_by, + jsonb_pretty(parent) as parent +from + azure_management_group; +``` From bea2898b793cf7f692e862f5ae6bcaadc851e6ac Mon Sep 17 00:00:00 2001 From: bigdatasourav Date: Fri, 1 Apr 2022 14:11:17 +0530 Subject: [PATCH 2/9] Update logs --- azure/table_azure_management_group.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/azure/table_azure_management_group.go b/azure/table_azure_management_group.go index a6bc4f99..7954047d 100644 --- a/azure/table_azure_management_group.go +++ b/azure/table_azure_management_group.go @@ -119,6 +119,7 @@ func listManagementGroups(ctx context.Context, d *plugin.QueryData, _ *plugin.Hy result, err := mgClient.List(ctx, "", "") if err != nil { + plugin.Logger(ctx).Error("listManagementGroups", "list", err) return nil, err } for _, mg := range result.Values() { @@ -165,6 +166,7 @@ func getManagementGroup(ctx context.Context, d *plugin.QueryData, h *plugin.Hydr op, err := mgClient.Get(ctx, name,"children",nil,"","") if err != nil { + plugin.Logger(ctx).Error("getManagementGroup", "get", err) return nil, err } From 502ba75d8a07444d3a93a7b80003dd5dfcabee27 Mon Sep 17 00:00:00 2001 From: souravTurbot <78197905+bigdatasourav@users.noreply.github.com> Date: Fri, 1 Apr 2022 14:15:17 +0530 Subject: [PATCH 3/9] Update azure_management_group.md --- docs/tables/azure_management_group.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/tables/azure_management_group.md b/docs/tables/azure_management_group.md index b7c5654b..5e7b08e1 100644 --- a/docs/tables/azure_management_group.md +++ b/docs/tables/azure_management_group.md @@ -23,20 +23,20 @@ from ```sql select - name, + name, updated_by, - jsonb_pretty(children) as children + jsonb_pretty(children) as children from - azure_management_group; + azure_management_group; ``` ### Get parent detail for a specific management group ```sql select - name, + name, updated_by, - jsonb_pretty(parent) as parent + jsonb_pretty(parent) as parent from - azure_management_group; + azure_management_group; ``` From 025d24d649cef3c229411de9e0031410d32af798 Mon Sep 17 00:00:00 2001 From: souravTurbot <78197905+bigdatasourav@users.noreply.github.com> Date: Fri, 1 Apr 2022 14:18:20 +0530 Subject: [PATCH 4/9] Update table_azure_management_group.go --- azure/table_azure_management_group.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/azure/table_azure_management_group.go b/azure/table_azure_management_group.go index 7954047d..02ea8118 100644 --- a/azure/table_azure_management_group.go +++ b/azure/table_azure_management_group.go @@ -114,7 +114,7 @@ func listManagementGroups(ctx context.Context, d *plugin.QueryData, _ *plugin.Hy return nil, err } - mgClient := managementgroups.NewClient() + mgClient := managementgroups.NewClient() mgClient.Authorizer = session.Authorizer result, err := mgClient.List(ctx, "", "") @@ -144,7 +144,7 @@ func listManagementGroups(ctx context.Context, d *plugin.QueryData, _ *plugin.Hy func getManagementGroup(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("getManagementGroup") - var name string + var name string if h.Item != nil { name = *h.Item.(managementgroups.Info).Name } else { @@ -161,7 +161,7 @@ func getManagementGroup(ctx context.Context, d *plugin.QueryData, h *plugin.Hydr return nil, err } - mgClient := managementgroups.NewClient() + mgClient := managementgroups.NewClient() mgClient.Authorizer = session.Authorizer op, err := mgClient.Get(ctx, name,"children",nil,"","") From 61c1191cf833ef5c2b638a1914b1567d6351553d Mon Sep 17 00:00:00 2001 From: bigdatasourav Date: Fri, 1 Apr 2022 14:30:14 +0530 Subject: [PATCH 5/9] Update logs --- .github/workflows/golangci-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index afd3cf91..849927f8 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -18,5 +18,5 @@ jobs: uses: golangci/golangci-lint-action@v2 with: # Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version. - version: v1.29 + version: v1.45 args: --timeout=5m From f9ebba812faf60ca216ed12a8f8a8bc27e5fa851 Mon Sep 17 00:00:00 2001 From: bigdatasourav Date: Fri, 1 Apr 2022 15:00:29 +0530 Subject: [PATCH 6/9] Update GetNewSession method --- azure/service.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure/service.go b/azure/service.go index b96ca9b9..5c9bb137 100644 --- a/azure/service.go +++ b/azure/service.go @@ -42,11 +42,11 @@ type Session struct { func GetNewSession(ctx context.Context, d *plugin.QueryData, tokenAudience string) (session *Session, err error) { logger := plugin.Logger(ctx) - cacheKey := "GetNewSession" + tokenAudience + cacheKey := "GetNewSession" if cachedData, ok := d.ConnectionManager.Cache.Get(cacheKey); ok { session = cachedData.(*Session) if session.Expires != nil && WillExpireIn(*session.Expires, 0) { - d.ConnectionManager.Cache.Delete(cacheKey) + d.ConnectionManager.Cache.Delete("GetNewSession") } else { return cachedData.(*Session), nil } From b9f7773b99b5cddd8b96b459fdebfca895e9e631 Mon Sep 17 00:00:00 2001 From: souravTurbot <78197905+bigdatasourav@users.noreply.github.com> Date: Tue, 5 Apr 2022 11:18:23 +0530 Subject: [PATCH 7/9] Update table_azure_management_group.go --- azure/table_azure_management_group.go | 1 - 1 file changed, 1 deletion(-) diff --git a/azure/table_azure_management_group.go b/azure/table_azure_management_group.go index 02ea8118..2fb2edfb 100644 --- a/azure/table_azure_management_group.go +++ b/azure/table_azure_management_group.go @@ -23,7 +23,6 @@ func tableAzureManagementGroup(_ context.Context) *plugin.Table { List: &plugin.ListConfig{ Hydrate: listManagementGroups, }, - Columns: []*plugin.Column{ { Name: "id", From 7e3fe697e2d4febe2e137d3b237e75f6587df3f6 Mon Sep 17 00:00:00 2001 From: souravTurbot <78197905+bigdatasourav@users.noreply.github.com> Date: Tue, 5 Apr 2022 11:20:15 +0530 Subject: [PATCH 8/9] Update azure_management_group.md --- docs/tables/azure_management_group.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tables/azure_management_group.md b/docs/tables/azure_management_group.md index 5e7b08e1..4258c347 100644 --- a/docs/tables/azure_management_group.md +++ b/docs/tables/azure_management_group.md @@ -19,7 +19,7 @@ from azure_management_group; ``` -### List children for a specific management group +### List children for management groups ```sql select @@ -30,7 +30,7 @@ from azure_management_group; ``` -### Get parent detail for a specific management group +### List parent detail for management groups ```sql select From 63cc868b1d67171765d33151b0caa77f3770632c Mon Sep 17 00:00:00 2001 From: souravturbot Date: Tue, 5 Apr 2022 17:33:05 +0530 Subject: [PATCH 9/9] update --- azure/table_azure_management_group.go | 21 ++++++++++----------- docs/tables/azure_management_group.md | 4 ++-- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/azure/table_azure_management_group.go b/azure/table_azure_management_group.go index 2fb2edfb..4a86b6e2 100644 --- a/azure/table_azure_management_group.go +++ b/azure/table_azure_management_group.go @@ -17,8 +17,8 @@ func tableAzureManagementGroup(_ context.Context) *plugin.Table { Name: "azure_management_group", Description: "Azure Management Group.", Get: &plugin.GetConfig{ - KeyColumns: plugin.SingleColumn("name"), - Hydrate: getManagementGroup, + KeyColumns: plugin.SingleColumn("name"), + Hydrate: getManagementGroup, }, List: &plugin.ListConfig{ Hydrate: listManagementGroups, @@ -44,13 +44,13 @@ func tableAzureManagementGroup(_ context.Context) *plugin.Table { Name: "display_name", Description: "The friendly name of the management group.", Type: proto.ColumnType_STRING, - Transform: transform.FromField("InfoProperties.DisplayName","Properties.DisplayName"), + Transform: transform.FromField("InfoProperties.DisplayName", "Properties.DisplayName"), }, { Name: "tenant_id", Description: "The AAD Tenant ID associated with the management group.", Type: proto.ColumnType_STRING, - Transform: transform.FromField("InfoProperties.TenantID","Properties.TenantID"), + Transform: transform.FromField("InfoProperties.TenantID", "Properties.TenantID"), }, { Name: "updated_by", @@ -113,7 +113,7 @@ func listManagementGroups(ctx context.Context, d *plugin.QueryData, _ *plugin.Hy return nil, err } - mgClient := managementgroups.NewClient() + mgClient := managementgroups.NewClient() mgClient.Authorizer = session.Authorizer result, err := mgClient.List(ctx, "", "") @@ -143,7 +143,7 @@ func listManagementGroups(ctx context.Context, d *plugin.QueryData, _ *plugin.Hy func getManagementGroup(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("getManagementGroup") - var name string + var name string if h.Item != nil { name = *h.Item.(managementgroups.Info).Name } else { @@ -151,8 +151,8 @@ func getManagementGroup(ctx context.Context, d *plugin.QueryData, h *plugin.Hydr } // check if name is empty - if name == ""{ - return nil,nil + if name == "" { + return nil, nil } session, err := GetNewSession(ctx, d, "MANAGEMENT") @@ -160,10 +160,10 @@ func getManagementGroup(ctx context.Context, d *plugin.QueryData, h *plugin.Hydr return nil, err } - mgClient := managementgroups.NewClient() + mgClient := managementgroups.NewClient() mgClient.Authorizer = session.Authorizer - op, err := mgClient.Get(ctx, name,"children",nil,"","") + op, err := mgClient.Get(ctx, name, "children", nil, "", "") if err != nil { plugin.Logger(ctx).Error("getManagementGroup", "get", err) return nil, err @@ -171,4 +171,3 @@ func getManagementGroup(ctx context.Context, d *plugin.QueryData, h *plugin.Hydr return op, nil } - diff --git a/docs/tables/azure_management_group.md b/docs/tables/azure_management_group.md index 4258c347..fb834008 100644 --- a/docs/tables/azure_management_group.md +++ b/docs/tables/azure_management_group.md @@ -2,7 +2,7 @@ Management groups provide a governance scope above subscriptions. You organize subscriptions into management groups in the governance conditions you apply cascade by inheritance to all associated subscriptions. Management groups give you enterprise-grade management at a scale no matter what type of subscriptions you might have. However, all subscriptions within a single management group must trust the same Azure Active Directory (Azure AD) tenant. -Note: To query this table, you need to have read access to the specific management group. +Note: To query this table, you need to have at least read access to the specific management group. ## Examples @@ -30,7 +30,7 @@ from azure_management_group; ``` -### List parent detail for management groups +### List parent details for management groups ```sql select