Skip to content

Commit

Permalink
Adding the Azure sync module functions along with new cloud client fu…
Browse files Browse the repository at this point in the history
…nctionality (#50366)

* Protobuf and configuration for Access Graph Azure Discovery

* Adding the Azure sync module functions along with new cloud client functionality

* Forgot to decouple role definitions fetching function from the fetcher

* Moving reconciliation to the upstream azure sync PR

* Moving reconciliation test to the upstream azure sync PR

* Updating go.sum

* Fixing rebase after protobuf gen

* Nolinting until upstream PRs

* Updating to use existing msgraph client

* Adding protection around nil values

* PR feedback

* Updating principal fetching to incorporate metadata from principal subtypes

* Updating opts to not leak URL parameters

* Conformant package name

* Using variadic options

* PR feedback

* Removing memberOf expansion

* Expanding memberships by calling memberOf on each user

* Also returning expanded principals for improved readability

* Removing ptrToList

* PR feedback

* Rebase go.sum stuff

* Go mod tidy

* Linting

* Linting

* Collecting errors from fetching memberships and using a WithContext error group

* Fixing go.mod

* Update lib/msgraph/paginated.go

Co-authored-by: Tiago Silva <[email protected]>

* PR feedback

* e ref update

* e ref update

* Fixing method

* Fetching group members from groups rather than memberships of each principal

* Linting

---------

Co-authored-by: Tiago Silva <[email protected]>
  • Loading branch information
mvbrock and tigrato authored Jan 13, 2025
1 parent b6e2bad commit 47f4498
Show file tree
Hide file tree
Showing 15 changed files with 517 additions and 1 deletion.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ require (
connectrpc.com/connect v1.18.0
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.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/compute/armcompute/v6 v6.2.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v6 v6.3.0
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi 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 @@ -668,6 +668,8 @@ github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLC
github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.1/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
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/compute/armcompute/v6 v6.2.0 h1:JAebRMoc3vL+Nd97GBprHYHucO4+wlW+tNbBIumqJlk=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.2.0/go.mod h1:zflC9v4VfViJrSvcvplqws/yGXVbUEMZi/iHpZdSPWA=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v5 v5.0.0 h1:5n7dPVqsWfVKw+ZiEKSd3Kzu7gwBkbEBkeXb8rgaE9Q=
Expand Down
1 change: 1 addition & 0 deletions integrations/event-handler/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.2.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v6 v6.3.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions integrations/event-handler/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,8 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0 h1:+m0M/LFxN43KvUL
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0/go.mod h1:PwOyop78lveYMRs6oCxjiVyBdyCgIYH6XHIVZO9/SFQ=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
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/compute/armcompute/v6 v6.2.0 h1:JAebRMoc3vL+Nd97GBprHYHucO4+wlW+tNbBIumqJlk=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.2.0/go.mod h1:zflC9v4VfViJrSvcvplqws/yGXVbUEMZi/iHpZdSPWA=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v5 v5.0.0 h1:5n7dPVqsWfVKw+ZiEKSd3Kzu7gwBkbEBkeXb8rgaE9Q=
Expand Down
1 change: 1 addition & 0 deletions integrations/terraform/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.2.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v6 v6.3.0 // indirect
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/msi/armmsi v1.2.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions integrations/terraform/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,8 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0 h1:+m0M/LFxN43KvUL
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0/go.mod h1:PwOyop78lveYMRs6oCxjiVyBdyCgIYH6XHIVZO9/SFQ=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
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/compute/armcompute/v6 v6.2.0 h1:JAebRMoc3vL+Nd97GBprHYHucO4+wlW+tNbBIumqJlk=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v6 v6.2.0/go.mod h1:zflC9v4VfViJrSvcvplqws/yGXVbUEMZi/iHpZdSPWA=
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerservice/armcontainerservice/v5 v5.0.0 h1:5n7dPVqsWfVKw+ZiEKSd3Kzu7gwBkbEBkeXb8rgaE9Q=
Expand Down
57 changes: 57 additions & 0 deletions lib/cloud/azure/roleassignments.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Teleport
* Copyright (C) 2024 Gravitational, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package azure

import (
"context"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2"
"github.com/gravitational/trace"
)

// RoleAssignmentsClient wraps the Azure API to provide a high level subset of functionality
type RoleAssignmentsClient struct {
cli *armauthorization.RoleAssignmentsClient
}

// NewRoleAssignmentsClient creates a new client for a given subscription and credentials
func NewRoleAssignmentsClient(subscription string, cred azcore.TokenCredential, options *arm.ClientOptions) (*RoleAssignmentsClient, error) {
clientFactory, err := armauthorization.NewClientFactory(subscription, cred, options)
if err != nil {
return nil, trace.Wrap(err)
}
roleDefCli := clientFactory.NewRoleAssignmentsClient()
return &RoleAssignmentsClient{cli: roleDefCli}, nil
}

// ListRoleAssignments returns role assignments for a given scope
func (c *RoleAssignmentsClient) ListRoleAssignments(ctx context.Context, scope string) ([]*armauthorization.RoleAssignment, error) {
pager := c.cli.NewListForScopePager(scope, nil)
var roleDefs []*armauthorization.RoleAssignment
for pager.More() {
page, err := pager.NextPage(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
roleDefs = append(roleDefs, page.Value...)
}
return roleDefs, nil
}
57 changes: 57 additions & 0 deletions lib/cloud/azure/roledefinitions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Teleport
* Copyright (C) 2024 Gravitational, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package azure

import (
"context"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2"
"github.com/gravitational/trace"
)

// RoleDefinitionsClient wraps the Azure API to provide a high level subset of functionality
type RoleDefinitionsClient struct {
cli *armauthorization.RoleDefinitionsClient
}

// NewRoleDefinitionsClient creates a new client for a given subscription and credentials
func NewRoleDefinitionsClient(subscription string, cred azcore.TokenCredential, options *arm.ClientOptions) (*RoleDefinitionsClient, error) {
clientFactory, err := armauthorization.NewClientFactory(subscription, cred, options)
if err != nil {
return nil, trace.Wrap(err)
}
roleDefCli := clientFactory.NewRoleDefinitionsClient()
return &RoleDefinitionsClient{cli: roleDefCli}, nil
}

// ListRoleDefinitions returns role definitions for a given scope
func (c *RoleDefinitionsClient) ListRoleDefinitions(ctx context.Context, scope string) ([]*armauthorization.RoleDefinition, error) {
pager := c.cli.NewListPager(scope, nil)
var roleDefs []*armauthorization.RoleDefinition
for pager.More() {
page, err := pager.NextPage(ctx)
if err != nil {
return nil, trace.Wrap(err)
}
roleDefs = append(roleDefs, page.Value...)
}
return roleDefs, nil
}
28 changes: 27 additions & 1 deletion lib/cloud/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,10 @@ type azureClients struct {
azurePostgresFlexServersClients azure.ClientMap[azure.PostgresFlexServersClient]
// azureRunCommandClients contains the cached Azure Run Command clients.
azureRunCommandClients azure.ClientMap[azure.RunCommandClient]
// azureRoleDefinitionsClients contains the cached Azure Role Definitions clients.
azureRoleDefinitionsClients azure.ClientMap[azure.RoleDefinitionsClient]
// azureRoleAssignmentsClients contains the cached Azure Role Assignments clients.
azureRoleAssignmentsClients azure.ClientMap[azure.RoleAssignmentsClient]
}

// credentialsSource defines where the credentials must come from.
Expand Down Expand Up @@ -717,6 +721,16 @@ func (c *cloudClients) GetAzureRunCommandClient(subscription string) (azure.RunC
return c.azureRunCommandClients.Get(subscription, c.GetAzureCredential)
}

// GetAzureRoleDefinitionsClient returns an Azure Role Definitions client
func (c *cloudClients) GetAzureRoleDefinitionsClient(subscription string) (azure.RoleDefinitionsClient, error) {
return c.azureRoleDefinitionsClients.Get(subscription, c.GetAzureCredential)
}

// GetAzureRoleAssignmentsClient returns an Azure Role Assignments client
func (c *cloudClients) GetAzureRoleAssignmentsClient(subscription string) (azure.RoleAssignmentsClient, error) {
return c.azureRoleAssignmentsClients.Get(subscription, c.GetAzureCredential)
}

// Close closes all initialized clients.
func (c *cloudClients) Close() (err error) {
c.mtx.Lock()
Expand Down Expand Up @@ -1021,6 +1035,8 @@ type TestCloudClients struct {
AzureMySQLFlex azure.MySQLFlexServersClient
AzurePostgresFlex azure.PostgresFlexServersClient
AzureRunCommand azure.RunCommandClient
AzureRoleDefinitions azure.RoleDefinitionsClient
AzureRoleAssignments azure.RoleAssignmentsClient
}

// GetAWSSession returns AWS session for the specified region, optionally
Expand Down Expand Up @@ -1244,11 +1260,21 @@ func (c *TestCloudClients) GetAzurePostgresFlexServersClient(subscription string
return c.AzurePostgresFlex, nil
}

// GetAzureRunCommand returns an Azure Run Command client for the given subscription.
// GetAzureRunCommandClient returns an Azure Run Command client for the given subscription.
func (c *TestCloudClients) GetAzureRunCommandClient(subscription string) (azure.RunCommandClient, error) {
return c.AzureRunCommand, nil
}

// GetAzureRoleDefinitionsClient returns an Azure Role Definitions client for the given subscription.
func (c *TestCloudClients) GetAzureRoleDefinitionsClient(subscription string) (azure.RoleDefinitionsClient, error) {
return c.AzureRoleDefinitions, nil
}

// GetAzureRoleAssignmentsClient returns an Azure Role Assignments client for the given subscription.
func (c *TestCloudClients) GetAzureRoleAssignmentsClient(subscription string) (azure.RoleAssignmentsClient, error) {
return c.AzureRoleAssignments, nil
}

// Close closes all initialized clients.
func (c *TestCloudClients) Close() error {
return nil
Expand Down
8 changes: 8 additions & 0 deletions lib/msgraph/paginated.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,14 @@ func (c *Client) IterateUsers(ctx context.Context, f func(*User) bool) error {
return iterateSimple(c, ctx, "users", f)
}

// IterateServicePrincipals lists all service principals in the Entra ID directory using pagination.
// `f` will be called for each object in the result set.
// if `f` returns `false`, the iteration is stopped (equivalent to `break` in a normal loop).
// Ref: [https://learn.microsoft.com/en-us/graph/api/serviceprincipal-list].
func (c *Client) IterateServicePrincipals(ctx context.Context, f func(principal *ServicePrincipal) bool) error {
return iterateSimple(c, ctx, "servicePrincipals", f)
}

// IterateGroupMembers lists all members for the given Entra ID group using pagination.
// `f` will be called for each object in the result set.
// if `f` returns `false`, the iteration is stopped (equivalent to `break` in a normal loop).
Expand Down
65 changes: 65 additions & 0 deletions lib/srv/discovery/fetchers/azure-sync/memberships.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Teleport
* Copyright (C) 2025 Gravitational, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package azuresync

import (
"context"

"github.com/gravitational/trace"
"golang.org/x/sync/errgroup"

accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha"
"github.com/gravitational/teleport/lib/msgraph"
)

const parallelism = 10 //nolint:unused // invoked in a dependent PR

// expandMemberships adds membership data to AzurePrincipal objects by querying the Graph API for group memberships
func expandMemberships(ctx context.Context, cli *msgraph.Client, principals []*accessgraphv1alpha.AzurePrincipal) ([]*accessgraphv1alpha.AzurePrincipal, error) { //nolint:unused // invoked in a dependent PR
// Map principals by ID
var principalsMap = make(map[string]*accessgraphv1alpha.AzurePrincipal)
for _, principal := range principals {
principalsMap[principal.Id] = principal
}
// Iterate through the Azure groups and add the group ID as a membership for its corresponding principal
eg, _ := errgroup.WithContext(ctx)
eg.SetLimit(parallelism)
errCh := make(chan error, len(principals))
for _, principal := range principals {
if principal.ObjectType != "group" {
continue
}
group := principal
eg.Go(func() error {
err := cli.IterateGroupMembers(ctx, group.Id, func(member msgraph.GroupMember) bool {
if memberPrincipal, ok := principalsMap[*member.GetID()]; ok {
memberPrincipal.MemberOf = append(memberPrincipal.MemberOf, group.Id)
}
return true
})
if err != nil {
errCh <- err
}
return nil
})
}
_ = eg.Wait()
close(errCh)
return principals, trace.NewAggregateFromChannel(errCh, ctx)
}
87 changes: 87 additions & 0 deletions lib/srv/discovery/fetchers/azure-sync/principals.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Teleport
* Copyright (C) 2024 Gravitational, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package azuresync

import (
"context"

"github.com/gravitational/trace"
"google.golang.org/protobuf/types/known/timestamppb"

accessgraphv1alpha "github.com/gravitational/teleport/gen/proto/go/accessgraph/v1alpha"
"github.com/gravitational/teleport/lib/msgraph"
)

type dirObjMetadata struct { //nolint:unused // invoked in a dependent PR
objectType string
}

type queryResult struct { //nolint:unused // invoked in a dependent PR
metadata dirObjMetadata
dirObj msgraph.DirectoryObject
}

// fetchPrincipals fetches the Azure principals (users, groups, and service principals) using the Graph API
func fetchPrincipals(ctx context.Context, subscriptionID string, cli *msgraph.Client) ([]*accessgraphv1alpha.AzurePrincipal, error) { //nolint: unused // invoked in a dependent PR
// Fetch the users, groups, and service principals as directory objects
var queryResults []queryResult
err := cli.IterateUsers(ctx, func(user *msgraph.User) bool {
res := queryResult{metadata: dirObjMetadata{objectType: "user"}, dirObj: user.DirectoryObject}
queryResults = append(queryResults, res)
return true
})
if err != nil {
return nil, trace.Wrap(err)
}
err = cli.IterateGroups(ctx, func(group *msgraph.Group) bool {
res := queryResult{metadata: dirObjMetadata{objectType: "group"}, dirObj: group.DirectoryObject}
queryResults = append(queryResults, res)
return true
})
if err != nil {
return nil, trace.Wrap(err)
}
err = cli.IterateServicePrincipals(ctx, func(servicePrincipal *msgraph.ServicePrincipal) bool {
res := queryResult{metadata: dirObjMetadata{objectType: "servicePrincipal"}, dirObj: servicePrincipal.DirectoryObject}
queryResults = append(queryResults, res)
return true
})
if err != nil {
return nil, trace.Wrap(err)
}

// Return the users, groups, and service principals as protobuf messages
var fetchErrs []error
var pbPrincipals []*accessgraphv1alpha.AzurePrincipal
for _, res := range queryResults {
if res.dirObj.ID == nil || res.dirObj.DisplayName == nil {
fetchErrs = append(fetchErrs,
trace.BadParameter("nil values on msgraph directory object: %v", res.dirObj))
continue
}
pbPrincipals = append(pbPrincipals, &accessgraphv1alpha.AzurePrincipal{
Id: *res.dirObj.ID,
SubscriptionId: subscriptionID,
LastSyncTime: timestamppb.Now(),
DisplayName: *res.dirObj.DisplayName,
ObjectType: res.metadata.objectType,
})
}
return pbPrincipals, trace.NewAggregate(fetchErrs...)
}
Loading

0 comments on commit 47f4498

Please sign in to comment.