Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed the table azure_role_assignment for populating the column value correctly Closes #759 #763

Merged
merged 2 commits into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 80 additions & 38 deletions azure/table_azure_role_assignment.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ package azure

import (
"context"
"fmt"

"github.com/Azure/azure-sdk-for-go/profiles/latest/authorization/mgmt/authorization"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2"

"github.com/turbot/steampipe-plugin-sdk/v5/grpc/proto"
"github.com/turbot/steampipe-plugin-sdk/v5/plugin/transform"
Expand All @@ -27,12 +26,23 @@ func tableAzureIamRoleAssignment(_ context.Context) *plugin.Table {
},
List: &plugin.ListConfig{
Hydrate: listIamRoleAssignments,
KeyColumns: []*plugin.KeyColumn{
{
Name: "principal_id",
Require: plugin.Optional,
},
},
// For the time being, the optional qualifiers have been commented out
// due to an issue with the Azure REST API that generates the following error:
// {
// "error": {
// "code": "UnsupportedQuery",
// "message": "The filter 'principalId' is not supported. Supported filters are either 'atScope()' or 'principalId eq '{value}' or assignedTo('{value}')'."
// }
// }
// Ref: https://github.com/Azure/azure-rest-api-specs/issues/28255
// We will uncomment it once the issue is resolved.

// KeyColumns: []*plugin.KeyColumn{
// {
// Name: "principal_id",
// Require: plugin.Optional,
// },
// },
},
Columns: azureColumns([]*plugin.Column{
{
Expand All @@ -50,7 +60,7 @@ func tableAzureIamRoleAssignment(_ context.Context) *plugin.Table {
Name: "scope",
Description: "Current state of the role assignment.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("RoleAssignmentPropertiesWithScope.Scope"),
Transform: transform.FromField("Properties.Scope"),
},
{
Name: "type",
Expand All @@ -61,19 +71,31 @@ func tableAzureIamRoleAssignment(_ context.Context) *plugin.Table {
Name: "principal_id",
Description: "Contains the principal id.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("RoleAssignmentPropertiesWithScope.PrincipalID"),
Transform: transform.FromField("Properties.PrincipalID"),
},
{
Name: "principal_type",
Description: "Principal type of the assigned principal ID.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("RoleAssignmentPropertiesWithScope.PrincipalType").Transform(transform.ToString),
Transform: transform.FromField("Properties.PrincipalType"),
},
{
Name: "created_on",
Description: "Time it was created.",
Type: proto.ColumnType_TIMESTAMP,
Transform: transform.FromField("Properties.CreatedOn"),
},
{
Name: "updated_on",
Description: "Time it was updated.",
Type: proto.ColumnType_TIMESTAMP,
Transform: transform.FromField("Properties.UpdatedOn"),
},
{
Name: "role_definition_id",
Description: "Name of the assigned role definition.",
Type: proto.ColumnType_STRING,
Transform: transform.FromField("RoleAssignmentPropertiesWithScope.RoleDefinitionID"),
Transform: transform.FromField("Properties.RoleDefinitionID"),
},
{
Name: "title",
Expand All @@ -94,39 +116,55 @@ func tableAzureIamRoleAssignment(_ context.Context) *plugin.Table {
//// LIST FUNCTION

func listIamRoleAssignments(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) {
session, err := GetNewSession(ctx, d, "MANAGEMENT")
session, err := GetNewSessionUpdated(ctx, d)
if err != nil {
plugin.Logger(ctx).Error("azure_role_assignment.listIamRoleAssignments", "session_error", err)
return nil, err
}
subscriptionID := session.SubscriptionID
// subscriptionID := session.SubscriptionID

authorizationClient := authorization.NewRoleAssignmentsClientWithBaseURI(session.ResourceManagerEndpoint, subscriptionID)
authorizationClient.Authorizer = session.Authorizer

var filter string
if d.EqualsQuals["principal_id"] != nil {
filter = fmt.Sprintf("principalId eq '%s'", d.EqualsQuals["principal_id"].GetStringValue())
}

result, err := authorizationClient.List(ctx, filter)
authorizationClient, err := armauthorization.NewRoleAssignmentsClient(session.SubscriptionID, session.Cred, session.ClientOptions)
if err != nil {
plugin.Logger(ctx).Error("azure_role_assignment.listIamRoleAssignments", "client_error", err)
return nil, err
}
for _, roleAssignment := range result.Values() {
d.StreamListItem(ctx, roleAssignment)
// 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
}

defaultFilter := "atScope()" // filter all result

option := &armauthorization.RoleAssignmentsClientListForScopeOptions{
TenantID: &session.TenantID,
Filter: &defaultFilter,
}

for result.NotDone() {
err = result.NextWithContext(ctx)
// For the time being, the optional qualifiers have been commented out
// due to an issue with the Azure REST API that generates the following error:
// {
// "error": {
// "code": "UnsupportedQuery",
// "message": "The filter 'principalId' is not supported. Supported filters are either 'atScope()' or 'principalId eq '{value}' or assignedTo('{value}')'."
// }
// }
// Ref: https://github.com/Azure/azure-rest-api-specs/issues/28255
// We will uncomment it once the issue is resolved.

// var filter string
// if d.EqualsQuals["principal_id"] != nil {
// filter = fmt.Sprintf("principalId eq '%s'", d.EqualsQuals["principal_id"].GetStringValue())
// }

// if filter != "" {
// option.Filter = &filter
// }

result := authorizationClient.NewListForScopePager("/subscriptions/"+session.SubscriptionID, option)

for result.More() {
res, err := result.NextPage(ctx)
if err != nil {
plugin.Logger(ctx).Error("azure_role_assignment.listIamRoleAssignments", "api_error", err)
return nil, err
}
for _, roleAssignment := range result.Values() {
for _, roleAssignment := range res.Value {
d.StreamListItem(ctx, roleAssignment)
// 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
Expand All @@ -142,20 +180,24 @@ func listIamRoleAssignments(ctx context.Context, d *plugin.QueryData, _ *plugin.
//// HYDRATE FUNCTIONS

func getIamRoleAssignment(ctx context.Context, d *plugin.QueryData, h *plugin.HydrateData) (interface{}, error) {
plugin.Logger(ctx).Trace("getIamRoleAssignment")

session, err := GetNewSession(ctx, d, "MANAGEMENT")
session, err := GetNewSessionUpdated(ctx, d)
if err != nil {
plugin.Logger(ctx).Error("azure_role_assignment.getIamRoleAssignment", "session_error", err)
return nil, err
}
subscriptionID := session.SubscriptionID
roleAssignmentID := d.EqualsQuals["id"].GetStringValue()

authorizationClient := authorization.NewRoleAssignmentsClientWithBaseURI(session.ResourceManagerEndpoint, subscriptionID)
authorizationClient.Authorizer = session.Authorizer
authorizationClient, err := armauthorization.NewRoleAssignmentsClient(subscriptionID, session.Cred, session.ClientOptions)
if err != nil {
plugin.Logger(ctx).Error("azure_role_assignment.getIamRoleAssignment", "client_error", err)
return nil, err
}

op, err := authorizationClient.GetByID(ctx, roleAssignmentID)
op, err := authorizationClient.GetByID(ctx, roleAssignmentID, nil)
if err != nil {
plugin.Logger(ctx).Error("azure_role_assignment.getIamRoleAssignment", "api_error", err)
return nil, err
}

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2
github.com/Azure/azure-sdk-for-go/sdk/data/aztables v1.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.8.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/recoveryservices/armrecoveryservicesbackup/v3 v3.0.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/sql/armsql v1.2.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,8 @@ github.com/Azure/azure-sdk-for-go/sdk/data/aztables v1.2.0 h1:aJG+Jxd9/rrLwf8R1K
github.com/Azure/azure-sdk-for-go/sdk/data/aztables v1.2.0/go.mod h1:41ONblJrPxDcnVr+voS+3xXWy/KnZLh+7zY5s6woAlQ=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 h1:Hp+EScFOu9HeCbeW8WU2yQPJd4gGwhMgKxWe+G6jNzw=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0/go.mod h1:/pz8dyNQe+Ey3yBp/XuYz7oqX8YDNWVpPB0hH3XWfbc=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.8.0 h1:0nGmzwBv5ougvzfGPCO2ljFRHvun57KpNrVCMrlk0ns=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v4 v4.8.0/go.mod h1:gYq8wyDgv6JLhGbAU6gg8amCPgQWRE+aCvrV2gyzdfs=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal/v2 v2.0.0 h1:PTFGRSlMKCQelWwxUyYVEUqseBJVemLyqWJjvMyt0do=
Expand Down
Loading