From 7c5d91ab80e885a9ab6dba6c1b5232b9a20d2f4d Mon Sep 17 00:00:00 2001
From: Mistah J <26472282+mistahj67@users.noreply.github.com>
Date: Thu, 22 Aug 2024 17:00:00 -0700
Subject: [PATCH 1/8] refactor: codify resource manager vs graph params
---
client/app_role_assignments.go | 18 +-
client/apps.go | 137 +----
client/automation_accounts.go | 21 +-
client/client.go | 106 ++--
client/container_registries.go | 21 +-
client/devices.go | 39 +-
client/directory_objects.go | 42 --
client/function_apps.go | 21 +-
client/groups.go | 52 +-
client/keyvaults.go | 30 +-
client/logic_apps.go | 21 +-
client/managed_clusters.go | 27 +-
client/management_groups.go | 36 +-
client/mocks/client.go | 516 ++++++++----------
client/query/params.go | 90 ++-
client/resource_groups.go | 30 +-
client/rest/client.go | 39 +-
client/rest/mocks/client.go | 11 +-
client/role_assignments.go | 132 +----
client/roles.go | 25 +-
client/service_principals.go | 45 +-
client/storage_accounts.go | 42 +-
client/subscriptions.go | 22 +-
client/tenants.go | 5 +-
client/users.go | 32 +-
client/virtual_machines.go | 30 +-
client/vm_scale_sets.go | 27 +-
client/web_apps.go | 21 +-
cmd/list-app-owners.go | 3 +-
cmd/list-app-owners_test.go | 4 +-
cmd/list-app-role-assignments.go | 3 +-
cmd/list-apps.go | 3 +-
cmd/list-apps_test.go | 2 +-
...ist-automation-account-role-assignments.go | 2 +-
...ist-container-registry-role-assignments.go | 2 +-
cmd/list-device-owners.go | 3 +-
cmd/list-devices.go | 3 +-
cmd/list-devices_test.go | 2 +-
cmd/list-function-app-role-assignments.go | 2 +-
cmd/list-group-members.go | 3 +-
cmd/list-group-members_test.go | 4 +-
cmd/list-group-owners.go | 3 +-
cmd/list-group-owners_test.go | 4 +-
cmd/list-groups.go | 3 +-
cmd/list-groups_test.go | 2 +-
cmd/list-key-vault-role-assignments.go | 2 +-
cmd/list-key-vault-role-assignments_test.go | 4 +-
cmd/list-key-vaults.go | 3 +-
cmd/list-logic-app-role-assignments.go | 2 +-
cmd/list-managed-cluster-role-assignments.go | 2 +-
cmd/list-managed-clusters.go | 2 +-
cmd/list-management-group-descendants.go | 2 +-
cmd/list-management-group-descendants_test.go | 4 +-
cmd/list-management-group-role-assignments.go | 2 +-
...-management-group-role-assignments_test.go | 4 +-
cmd/list-management-groups.go | 2 +-
cmd/list-management-groups_test.go | 2 +-
cmd/list-resource-group-role-assignments.go | 2 +-
...st-resource-group-role-assignments_test.go | 4 +-
cmd/list-resource-groups.go | 3 +-
cmd/list-role-assignments.go | 3 +-
cmd/list-roles.go | 2 +-
cmd/list-roles_test.go | 2 +-
cmd/list-service-principal-owners.go | 3 +-
cmd/list-service-principal-owners_test.go | 4 +-
cmd/list-service-principals.go | 3 +-
cmd/list-service-principals_test.go | 2 +-
cmd/list-storage-account-role-assignments.go | 2 +-
cmd/list-subscription-role-assignments.go | 2 +-
...list-subscription-role-assignments_test.go | 4 +-
cmd/list-users.go | 5 +-
cmd/list-users_test.go | 2 +-
cmd/list-virtual-machine-role-assignments.go | 2 +-
...t-virtual-machine-role-assignments_test.go | 4 +-
cmd/list-virtual-machines.go | 3 +-
cmd/list-vm-scale-set-role-assignments.go | 2 +-
cmd/list-vm-scale-sets.go | 2 +-
cmd/list-web-app-role-assignments.go | 2 +-
go.mod | 2 +
go.sum | 4 +
80 files changed, 597 insertions(+), 1184 deletions(-)
delete mode 100644 client/directory_objects.go
diff --git a/client/app_role_assignments.go b/client/app_role_assignments.go
index 09659f0..1975d4f 100644
--- a/client/app_role_assignments.go
+++ b/client/app_role_assignments.go
@@ -21,7 +21,6 @@ import (
"context"
"fmt"
"net/url"
- "strings"
"github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/client/rest"
@@ -31,20 +30,17 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureADAppRoleAssignments(ctx context.Context, servicePrincipalId string, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.AppRoleAssignmentList, error) {
+func (s *azureClient) GetAzureADAppRoleAssignments(ctx context.Context, servicePrincipalId string, params query.GraphParams) (azure.AppRoleAssignmentList, error) {
var (
path = fmt.Sprintf("/%s/servicePrincipals/%s/appRoleAssignedTo", constants.GraphApiVersion, servicePrincipalId)
- params = query.Params{Filter: filter, Search: search, OrderBy: orderBy, Select: selectCols, Top: top, Count: count, Expand: expand}
- headers map[string]string
response azure.AppRoleAssignmentList
)
- count = count || search != "" || (filter != "" && orderBy != "") || strings.Contains(filter, "endsWith")
- if count {
- headers = make(map[string]string)
- headers["ConsistencyLevel"] = "eventual"
+ if params.Top == 0 {
+ params.Top = 999
}
- if res, err := s.msgraph.Get(ctx, path, params.AsMap(), headers); err != nil {
+
+ if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -53,7 +49,7 @@ func (s *azureClient) GetAzureADAppRoleAssignments(ctx context.Context, serviceP
}
}
-func (s *azureClient) ListAzureADAppRoleAssignments(ctx context.Context, servicePrincipal, filter, search, orderBy, expand string, selectCols []string) <-chan azure.AppRoleAssignmentResult {
+func (s *azureClient) ListAzureADAppRoleAssignments(ctx context.Context, servicePrincipal string, params query.GraphParams) <-chan azure.AppRoleAssignmentResult {
out := make(chan azure.AppRoleAssignmentResult)
go func() {
@@ -65,7 +61,7 @@ func (s *azureClient) ListAzureADAppRoleAssignments(ctx context.Context, service
nextLink string
)
- if list, err := s.GetAzureADAppRoleAssignments(ctx, servicePrincipal, filter, search, orderBy, expand, selectCols, 999, false); err != nil {
+ if list, err := s.GetAzureADAppRoleAssignments(ctx, servicePrincipal, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
diff --git a/client/apps.go b/client/apps.go
index fb60ed5..cf92a6c 100644
--- a/client/apps.go
+++ b/client/apps.go
@@ -21,79 +21,45 @@ import (
"context"
"fmt"
"net/url"
- "strings"
"github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/constants"
- "github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models/azure"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureADApp(ctx context.Context, objectId string, selectCols []string) (*azure.Application, error) {
- var (
- path = fmt.Sprintf("/%s/applications/%s", constants.GraphApiVersion, objectId)
- params = query.Params{Select: selectCols}.AsMap()
- response azure.ApplicationList
- )
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response.Value[0], nil
- }
-}
-
-func (s *azureClient) GetAzureADAppOwners(ctx context.Context, objectId string, filter string, search string, orderBy string, selectCols []string, top int32, count bool) (azure.DirectoryObjectList, error) {
+func (s *azureClient) GetAzureADAppOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error) {
var (
path = fmt.Sprintf("/%s/applications/%s/owners", constants.GraphApiBetaVersion, objectId)
- params = query.Params{Filter: filter, Search: search, OrderBy: orderBy, Select: selectCols, Top: top, Count: count}.AsMap()
response azure.DirectoryObjectList
)
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
+
+ if params.Top == 0 {
+ params.Top = 99
}
-}
-func (s *azureClient) GetAzureADAppMemberObjects(ctx context.Context, objectId string, securityEnabledOnly bool) (azure.MemberObjectList, error) {
- var (
- path = fmt.Sprintf("/%s/directoryObjects/%s/getMemberObjects", constants.GraphApiVersion, objectId)
- response azure.MemberObjectList
- body = map[string]bool{
- "securityEnabledOnly": securityEnabledOnly,
- }
- )
- if res, err := s.msgraph.Post(ctx, path, body, nil, nil); err != nil {
+ if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
} else {
return response, nil
}
-
}
-func (s *azureClient) GetAzureADApps(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.ApplicationList, error) {
+func (s *azureClient) GetAzureADApps(ctx context.Context, params query.GraphParams) (azure.ApplicationList, error) {
var (
path = fmt.Sprintf("/%s/applications", constants.GraphApiVersion)
- params = query.Params{Filter: filter, Search: search, OrderBy: orderBy, Select: selectCols, Top: top, Count: count, Expand: expand}
- headers map[string]string
response azure.ApplicationList
)
- count = count || search != "" || (filter != "" && orderBy != "") || strings.Contains(filter, "endsWith")
- if count {
- headers = make(map[string]string)
- headers["ConsistencyLevel"] = "eventual"
+ if params.Top == 0 {
+ params.Top = 99
}
- if res, err := s.msgraph.Get(ctx, path, params.AsMap(), headers); err != nil {
+
+ if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -102,7 +68,7 @@ func (s *azureClient) GetAzureADApps(ctx context.Context, filter, search, orderB
}
}
-func (s *azureClient) ListAzureADApps(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.ApplicationResult {
+func (s *azureClient) ListAzureADApps(ctx context.Context, params query.GraphParams) <-chan azure.ApplicationResult {
out := make(chan azure.ApplicationResult)
go func() {
@@ -114,7 +80,7 @@ func (s *azureClient) ListAzureADApps(ctx context.Context, filter, search, order
nextLink string
)
- if list, err := s.GetAzureADApps(ctx, filter, search, orderBy, expand, selectCols, 999, false); err != nil {
+ if list, err := s.GetAzureADApps(ctx, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
@@ -167,7 +133,7 @@ func (s *azureClient) ListAzureADApps(ctx context.Context, filter, search, order
return out
}
-func (s *azureClient) ListAzureADAppOwners(ctx context.Context, objectId string, filter, search, orderBy string, selectCols []string) <-chan azure.AppOwnerResult {
+func (s *azureClient) ListAzureADAppOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.AppOwnerResult {
out := make(chan azure.AppOwnerResult)
go func() {
@@ -179,7 +145,7 @@ func (s *azureClient) ListAzureADAppOwners(ctx context.Context, objectId string,
nextLink string
)
- if list, err := s.GetAzureADAppOwners(ctx, objectId, filter, search, orderBy, selectCols, 999, false); err != nil {
+ if list, err := s.GetAzureADAppOwners(ctx, objectId, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
@@ -237,78 +203,3 @@ func (s *azureClient) ListAzureADAppOwners(ctx context.Context, objectId string,
}()
return out
}
-
-func (s *azureClient) ListAzureADAppMemberObjects(ctx context.Context, objectId string, securityEnabledOnly bool) <-chan azure.MemberObjectResult {
- out := make(chan azure.MemberObjectResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.MemberObjectResult{
- ParentId: objectId,
- ParentType: string(enums.EntityApplication),
- }
- nextLink string
- )
- if list, err := s.GetAzureADAppMemberObjects(ctx, objectId, securityEnabledOnly); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.MemberObjectResult{
- ParentId: objectId,
- ParentType: string(enums.EntityApplication),
- Ok: u,
- }); !ok {
- return
- }
- }
-
- nextLink = list.NextLink
- for nextLink != "" {
- var list azure.MemberObjectList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.msgraph.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.MemberObjectResult{
- ParentId: objectId,
- ParentType: string(enums.EntityApplication),
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
- return out
-}
diff --git a/client/automation_accounts.go b/client/automation_accounts.go
index 512271b..88a2bcf 100644
--- a/client/automation_accounts.go
+++ b/client/automation_accounts.go
@@ -29,31 +29,14 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureAutomationAccount(ctx context.Context, subscriptionId, groupName, aaName, expand string) (*azure.AutomationAccount, error) {
- var (
- path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Automation/automationAccounts/%s", subscriptionId, groupName, aaName)
- params = query.Params{ApiVersion: "2021-07-01", Expand: expand}.AsMap()
- headers map[string]string
- response azure.AutomationAccount
- )
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
func (s *azureClient) GetAzureAutomationAccounts(ctx context.Context, subscriptionId string) (azure.AutomationAccountList, error) {
var (
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Automation/automationAccounts", subscriptionId)
- params = query.Params{ApiVersion: "2021-06-22"}.AsMap()
- headers map[string]string
+ params = query.RMParams{ApiVersion: "2021-06-22"}
response azure.AutomationAccountList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
diff --git a/client/client.go b/client/client.go
index 03e5a76..fc8e526 100644
--- a/client/client.go
+++ b/client/client.go
@@ -21,10 +21,10 @@ package client
import (
"context"
- "encoding/json"
"fmt"
"github.com/bloodhoundad/azurehound/v2/client/config"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
)
@@ -102,71 +102,71 @@ func (s azureClient) CloseIdleConnections() {
}
type AzureClient interface {
- GetAzureADApp(ctx context.Context, objectId string, selectCols []string) (*azure.Application, error)
- GetAzureADApps(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.ApplicationList, error)
- GetAzureADDirectoryObject(ctx context.Context, objectId string) (json.RawMessage, error)
- GetAzureADGroup(ctx context.Context, objectId string, selectCols []string) (*azure.Group, error)
- GetAzureADGroupOwners(ctx context.Context, objectId string, filter string, search string, orderBy string, selectCols []string, top int32, count bool) (azure.DirectoryObjectList, error)
- GetAzureADGroups(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.GroupList, error)
+ // Graph
+ GetAzureADApps(ctx context.Context, params query.GraphParams) (azure.ApplicationList, error)
+ GetAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error)
+ GetAzureADGroups(ctx context.Context, params query.GraphParams) (azure.GroupList, error)
GetAzureADOrganization(ctx context.Context, selectCols []string) (*azure.Organization, error)
- GetAzureADRole(ctx context.Context, roleId string, selectCols []string) (*azure.Role, error)
- GetAzureADRoleAssignment(ctx context.Context, objectId string, selectCols []string) (*azure.UnifiedRoleAssignment, error)
- GetAzureADRoleAssignments(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.UnifiedRoleAssignmentList, error)
- GetAzureADRoles(ctx context.Context, filter, expand string) (azure.RoleList, error)
- GetAzureADServicePrincipal(ctx context.Context, objectId string, selectCols []string) (*azure.ServicePrincipal, error)
- GetAzureADServicePrincipalOwners(ctx context.Context, objectId string, filter string, search string, orderBy string, selectCols []string, top int32, count bool) (azure.DirectoryObjectList, error)
- GetAzureADServicePrincipals(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.ServicePrincipalList, error)
+ GetAzureADRoles(ctx context.Context, filter string) (azure.RoleList, error)
+ GetAzureADRoleAssignments(ctx context.Context, params query.GraphParams) (azure.UnifiedRoleAssignmentList, error)
+ GetAzureADServicePrincipalOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error)
+ GetAzureADServicePrincipals(ctx context.Context, params query.GraphParams) (azure.ServicePrincipalList, error)
+ GetAzureADUsers(ctx context.Context, params query.GraphParams) (azure.UserList, error)
+ GetAzureDevices(ctx context.Context, params query.GraphParams) (azure.DeviceList, error)
+ GetAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error)
+ GetAzureADAppRoleAssignments(ctx context.Context, servicePrincipalId string, params query.GraphParams) (azure.AppRoleAssignmentList, error)
+ GetAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) (azure.MemberObjectList, error)
+
+ ListAzureADUsers(ctx context.Context, params query.GraphParams) <-chan azure.UserResult
+ ListAzureADApps(ctx context.Context, params query.GraphParams) <-chan azure.ApplicationResult
+ ListAzureADAppOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.AppOwnerResult
+ ListAzureADGroups(ctx context.Context, params query.GraphParams) <-chan azure.GroupResult
+ ListAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.MemberObjectResult
+ ListAzureADRoleAssignments(ctx context.Context, params query.GraphParams) <-chan azure.UnifiedRoleAssignmentResult
+ ListAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.GroupOwnerResult
+ ListAzureADRoles(ctx context.Context, filter string) <-chan azure.RoleResult
+ ListAzureADServicePrincipalOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.ServicePrincipalOwnerResult
+ ListAzureADServicePrincipals(ctx context.Context, params query.GraphParams) <-chan azure.ServicePrincipalResult
+ ListAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.DeviceRegisteredOwnerResult
+ ListAzureDevices(ctx context.Context, params query.GraphParams) <-chan azure.DeviceResult
+ ListAzureADAppRoleAssignments(ctx context.Context, servicePrincipal string, params query.GraphParams) <-chan azure.AppRoleAssignmentResult
+
+ // RM
GetAzureADTenants(ctx context.Context, includeAllTenantCategories bool) (azure.TenantList, error)
- GetAzureADUser(ctx context.Context, objectId string, selectCols []string) (*azure.User, error)
- GetAzureADUsers(ctx context.Context, filter string, search string, orderBy string, selectCols []string, top int32, count bool) (azure.UserList, error)
- GetAzureDevice(ctx context.Context, objectId string, selectCols []string) (*azure.Device, error)
- GetAzureDevices(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.DeviceList, error)
- GetAzureKeyVault(ctx context.Context, subscriptionId, groupName, vaultName string) (*azure.KeyVault, error)
- GetAzureKeyVaults(ctx context.Context, subscriptionId string, top int32) (azure.KeyVaultList, error)
- GetAzureManagementGroup(ctx context.Context, groupId, filter, expand string, recurse bool) (*azure.ManagementGroup, error)
- GetAzureManagementGroups(ctx context.Context) (azure.ManagementGroupList, error)
- GetAzureResourceGroup(ctx context.Context, subscriptionId, groupName string) (*azure.ResourceGroup, error)
- GetAzureResourceGroups(ctx context.Context, subscriptionId string, filter string, top int32) (azure.ResourceGroupList, error)
- GetAzureSubscription(ctx context.Context, objectId string) (*azure.Subscription, error)
+ GetAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) (azure.KeyVaultList, error)
+ GetAzureManagementGroups(ctx context.Context, skipToken string) (azure.ManagementGroupList, error)
+ GetAzureResourceGroups(ctx context.Context, subscriptionId string, params query.RMParams) (azure.ResourceGroupList, error)
GetAzureSubscriptions(ctx context.Context) (azure.SubscriptionList, error)
- GetAzureVirtualMachine(ctx context.Context, subscriptionId, groupName, vmName, expand string) (*azure.VirtualMachine, error)
- GetAzureVirtualMachines(ctx context.Context, subscriptionId string, statusOnly bool) (azure.VirtualMachineList, error)
- GetAzureStorageAccount(ctx context.Context, subscriptionId, groupName, saName, expand string) (*azure.StorageAccount, error)
+ GetAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) (azure.VirtualMachineList, error)
GetAzureStorageAccounts(ctx context.Context, subscriptionId string) (azure.StorageAccountList, error)
- GetResourceRoleAssignments(ctx context.Context, subscriptionId string, filter string, expand string) (azure.RoleAssignmentList, error)
- GetRoleAssignmentsForResource(ctx context.Context, resourceId string, filter string) (azure.RoleAssignmentList, error)
- ListAzureADAppMemberObjects(ctx context.Context, objectId string, securityEnabledOnly bool) <-chan azure.MemberObjectResult
- ListAzureADAppOwners(ctx context.Context, objectId string, filter, search, orderBy string, selectCols []string) <-chan azure.AppOwnerResult
- ListAzureADApps(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.ApplicationResult
- ListAzureADGroupMembers(ctx context.Context, objectId string, filter, search, orderBy string, selectCols []string) <-chan azure.MemberObjectResult
- ListAzureADGroupOwners(ctx context.Context, objectId string, filter, search, orderBy string, selectCols []string) <-chan azure.GroupOwnerResult
- ListAzureADGroups(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.GroupResult
- ListAzureADRoleAssignments(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.UnifiedRoleAssignmentResult
- ListAzureADRoles(ctx context.Context, filter, expand string) <-chan azure.RoleResult
- ListAzureADServicePrincipalOwners(ctx context.Context, objectId string, filter, search, orderBy string, selectCols []string) <-chan azure.ServicePrincipalOwnerResult
- ListAzureADServicePrincipals(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.ServicePrincipalResult
+ GetRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) (azure.RoleAssignmentList, error)
+ GetAzureContainerRegistries(ctx context.Context, subscriptionId string) (azure.ContainerRegistryList, error)
+ GetAzureWebApps(ctx context.Context, subscriptionId string) (azure.WebAppList, error)
+ GetAzureVMScaleSets(ctx context.Context, subscriptionId string) (azure.VMScaleSetList, error)
+ GetAzureStorageContainers(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, filter string, includeDeleted string, maxPageSize string) (azure.StorageContainerList, error)
+ GetAzureAutomationAccounts(ctx context.Context, subscriptionId string) (azure.AutomationAccountList, error)
+ GetAzureLogicApps(ctx context.Context, subscriptionId string, filter string, top int32) (azure.LogicAppList, error)
+ GetAzureFunctionApps(ctx context.Context, subscriptionId string) (azure.FunctionAppList, error)
+ GetAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) (azure.DescendantInfoList, error)
+
ListAzureADTenants(ctx context.Context, includeAllTenantCategories bool) <-chan azure.TenantResult
- ListAzureADUsers(ctx context.Context, filter string, search string, orderBy string, selectCols []string) <-chan azure.UserResult
ListAzureContainerRegistries(ctx context.Context, subscriptionId string) <-chan azure.ContainerRegistryResult
ListAzureWebApps(ctx context.Context, subscriptionId string) <-chan azure.WebAppResult
- ListAzureManagedClusters(ctx context.Context, subscriptionId string, statusOnly bool) <-chan azure.ManagedClusterResult
- ListAzureVMScaleSets(ctx context.Context, subscriptionId string, statusOnly bool) <-chan azure.VMScaleSetResult
- ListAzureDeviceRegisteredOwners(ctx context.Context, objectId string, securityEnabledOnly bool) <-chan azure.DeviceRegisteredOwnerResult
- ListAzureDevices(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.DeviceResult
- ListAzureKeyVaults(ctx context.Context, subscriptionId string, top int32) <-chan azure.KeyVaultResult
- ListAzureManagementGroupDescendants(ctx context.Context, groupId string) <-chan azure.DescendantInfoResult
- ListAzureManagementGroups(ctx context.Context) <-chan azure.ManagementGroupResult
- ListAzureResourceGroups(ctx context.Context, subscriptionId, filter string) <-chan azure.ResourceGroupResult
+ ListAzureManagedClusters(ctx context.Context, subscriptionId string) <-chan azure.ManagedClusterResult
+ ListAzureVMScaleSets(ctx context.Context, subscriptionId string) <-chan azure.VMScaleSetResult
+ ListAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azure.KeyVaultResult
+ ListAzureManagementGroups(ctx context.Context, skipToken string) <-chan azure.ManagementGroupResult
+ ListAzureResourceGroups(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azure.ResourceGroupResult
ListAzureSubscriptions(ctx context.Context) <-chan azure.SubscriptionResult
- ListAzureVirtualMachines(ctx context.Context, subscriptionId string, statusOnly bool) <-chan azure.VirtualMachineResult
+ ListAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azure.VirtualMachineResult
ListAzureStorageAccounts(ctx context.Context, subscriptionId string) <-chan azure.StorageAccountResult
ListAzureStorageContainers(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, filter string, includeDeleted string, maxPageSize string) <-chan azure.StorageContainerResult
ListAzureAutomationAccounts(ctx context.Context, subscriptionId string) <-chan azure.AutomationAccountResult
ListAzureLogicApps(ctx context.Context, subscriptionId string, filter string, top int32) <-chan azure.LogicAppResult
ListAzureFunctionApps(ctx context.Context, subscriptionId string) <-chan azure.FunctionAppResult
- ListResourceRoleAssignments(ctx context.Context, subscriptionId string, filter string, expand string) <-chan azure.RoleAssignmentResult
- ListRoleAssignmentsForResource(ctx context.Context, resourceId string, filter string) <-chan azure.RoleAssignmentResult
- ListAzureADAppRoleAssignments(ctx context.Context, servicePrincipal, filter, search, orderBy, expand string, selectCols []string) <-chan azure.AppRoleAssignmentResult
+ ListRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) <-chan azure.RoleAssignmentResult
+ ListAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) <-chan azure.DescendantInfoResult
+
TenantInfo() azure.Tenant
CloseIdleConnections()
}
diff --git a/client/container_registries.go b/client/container_registries.go
index 9e7eebb..ca787d6 100644
--- a/client/container_registries.go
+++ b/client/container_registries.go
@@ -29,31 +29,14 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureContainerRegistry(ctx context.Context, subscriptionId, groupName, crName, expand string) (*azure.ContainerRegistry, error) {
- var (
- path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.ContainerRegistry/registries/%s", subscriptionId, groupName, crName)
- params = query.Params{ApiVersion: "2023-01-01-preview", Expand: expand}.AsMap()
- headers map[string]string
- response azure.ContainerRegistry
- )
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
func (s *azureClient) GetAzureContainerRegistries(ctx context.Context, subscriptionId string) (azure.ContainerRegistryList, error) {
var (
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.ContainerRegistry/registries", subscriptionId)
- params = query.Params{ApiVersion: "2023-01-01-preview"}.AsMap()
- headers map[string]string
+ params = query.RMParams{ApiVersion: "2023-01-01-preview"}
response azure.ContainerRegistryList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
diff --git a/client/devices.go b/client/devices.go
index 823ab71..e86d400 100644
--- a/client/devices.go
+++ b/client/devices.go
@@ -21,7 +21,6 @@ import (
"context"
"fmt"
"net/url"
- "strings"
"github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/client/rest"
@@ -31,25 +30,9 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureDevice(ctx context.Context, objectId string, selectCols []string) (*azure.Device, error) {
- var (
- path = fmt.Sprintf("/%s/devices/%s", constants.GraphApiVersion, objectId)
- params = query.Params{Select: selectCols}.AsMap()
- response azure.DeviceList
- )
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response.Value[0], nil
- }
-}
-
-func (s *azureClient) GetAzureDeviceRegisteredOwners(ctx context.Context, objectId string, filter, search string, count bool) (azure.DirectoryObjectList, error) {
+func (s *azureClient) GetAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error) {
var (
path = fmt.Sprintf("/%s/devices/%s/registeredOwners", constants.GraphApiBetaVersion, objectId)
- params = query.Params{Filter: filter, Search: search, Count: count}.AsMap()
response azure.DirectoryObjectList
)
if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
@@ -61,20 +44,16 @@ func (s *azureClient) GetAzureDeviceRegisteredOwners(ctx context.Context, object
}
}
-func (s *azureClient) GetAzureDevices(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.DeviceList, error) {
+func (s *azureClient) GetAzureDevices(ctx context.Context, params query.GraphParams) (azure.DeviceList, error) {
var (
path = fmt.Sprintf("/%s/devices", constants.GraphApiVersion)
- params = query.Params{Filter: filter, Search: search, OrderBy: orderBy, Select: selectCols, Top: top, Count: count, Expand: expand}
- headers map[string]string
response azure.DeviceList
)
- count = count || search != "" || (filter != "" && orderBy != "") || strings.Contains(filter, "endsWith")
- if count {
- headers = make(map[string]string)
- headers["ConsistencyLevel"] = "eventual"
+ if params.Top == 0 {
+ params.Top = 999
}
- if res, err := s.msgraph.Get(ctx, path, params.AsMap(), headers); err != nil {
+ if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -83,7 +62,7 @@ func (s *azureClient) GetAzureDevices(ctx context.Context, filter, search, order
}
}
-func (s *azureClient) ListAzureDevices(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.DeviceResult {
+func (s *azureClient) ListAzureDevices(ctx context.Context, params query.GraphParams) <-chan azure.DeviceResult {
out := make(chan azure.DeviceResult)
go func() {
@@ -95,7 +74,7 @@ func (s *azureClient) ListAzureDevices(ctx context.Context, filter, search, orde
nextLink string
)
- if list, err := s.GetAzureDevices(ctx, filter, search, orderBy, expand, selectCols, 999, false); err != nil {
+ if list, err := s.GetAzureDevices(ctx, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
@@ -148,7 +127,7 @@ func (s *azureClient) ListAzureDevices(ctx context.Context, filter, search, orde
return out
}
-func (s *azureClient) ListAzureDeviceRegisteredOwners(ctx context.Context, objectId string, securityEnabledOnly bool) <-chan azure.DeviceRegisteredOwnerResult {
+func (s *azureClient) ListAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.DeviceRegisteredOwnerResult {
out := make(chan azure.DeviceRegisteredOwnerResult)
go func() {
@@ -162,7 +141,7 @@ func (s *azureClient) ListAzureDeviceRegisteredOwners(ctx context.Context, objec
nextLink string
)
- if list, err := s.GetAzureDeviceRegisteredOwners(ctx, objectId, "", "", false); err != nil {
+ if list, err := s.GetAzureDeviceRegisteredOwners(ctx, objectId, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
diff --git a/client/directory_objects.go b/client/directory_objects.go
deleted file mode 100644
index 84ad165..0000000
--- a/client/directory_objects.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (C) 2022 Specter Ops, Inc.
-//
-// This file is part of AzureHound.
-//
-// AzureHound is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// AzureHound 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 General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-package client
-
-import (
- "context"
- "encoding/json"
- "fmt"
- "io"
-
- "github.com/bloodhoundad/azurehound/v2/constants"
-)
-
-func (s *azureClient) GetAzureADDirectoryObject(ctx context.Context, objectId string) (json.RawMessage, error) {
- var (
- path = fmt.Sprintf("/%s/directoryObjects/%s", constants.GraphApiVersion, objectId)
- )
- if res, err := s.msgraph.Get(ctx, path, nil, nil); err != nil {
- return nil, err
- } else if body, err := io.ReadAll(res.Body); err != nil {
- res.Body.Close()
- return nil, err
- } else {
- res.Body.Close()
- return json.RawMessage(body), nil
- }
-}
diff --git a/client/function_apps.go b/client/function_apps.go
index 3e2e113..296f789 100644
--- a/client/function_apps.go
+++ b/client/function_apps.go
@@ -29,31 +29,14 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureFunctionApp(ctx context.Context, subscriptionId, groupName, functionAppName, expand string) (*azure.FunctionApp, error) {
- var (
- path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Web/sites/%s", subscriptionId, groupName, functionAppName)
- params = query.Params{ApiVersion: "2022-03-01", Expand: expand}.AsMap()
- headers map[string]string
- response azure.FunctionApp
- )
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
func (s *azureClient) GetAzureFunctionApps(ctx context.Context, subscriptionId string) (azure.FunctionAppList, error) {
var (
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Web/sites", subscriptionId)
- params = query.Params{ApiVersion: "2022-03-01"}.AsMap()
- headers map[string]string
+ params = query.RMParams{ApiVersion: "2022-03-01"}
response azure.FunctionAppList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
diff --git a/client/groups.go b/client/groups.go
index 5db0474..f329e77 100644
--- a/client/groups.go
+++ b/client/groups.go
@@ -21,7 +21,6 @@ import (
"context"
"fmt"
"net/url"
- "strings"
"github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/client/rest"
@@ -32,27 +31,17 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureADGroup(ctx context.Context, objectId string, selectCols []string) (*azure.Group, error) {
- var (
- path = fmt.Sprintf("/%s/groups/%s", constants.GraphApiVersion, objectId)
- params = query.Params{Select: selectCols}.AsMap()
- response azure.GroupList
- )
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response.Value[0], nil
- }
-}
-func (s *azureClient) GetAzureADGroupOwners(ctx context.Context, objectId string, filter string, search string, orderBy string, selectCols []string, top int32, count bool) (azure.DirectoryObjectList, error) {
+func (s *azureClient) GetAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error) {
var (
path = fmt.Sprintf("/%s/groups/%s/owners", constants.GraphApiBetaVersion, objectId)
- params = query.Params{Filter: filter, Search: search, OrderBy: orderBy, Select: selectCols, Top: top, Count: count}.AsMap()
response azure.DirectoryObjectList
)
+
+ if params.Top == 0 {
+ params.Top = 99
+ }
+
if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
@@ -62,10 +51,9 @@ func (s *azureClient) GetAzureADGroupOwners(ctx context.Context, objectId string
}
}
-func (s *azureClient) GetAzureADGroupMembers(ctx context.Context, objectId string, filter string, search string, count bool) (azure.MemberObjectList, error) {
+func (s *azureClient) GetAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) (azure.MemberObjectList, error) {
var (
path = fmt.Sprintf("/%s/groups/%s/members", constants.GraphApiBetaVersion, objectId)
- params = query.Params{Filter: filter, Search: search, Count: count}.AsMap()
response azure.MemberObjectList
)
if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
@@ -77,20 +65,18 @@ func (s *azureClient) GetAzureADGroupMembers(ctx context.Context, objectId strin
}
}
-func (s *azureClient) GetAzureADGroups(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.GroupList, error) {
+func (s *azureClient) GetAzureADGroups(ctx context.Context, params query.GraphParams) (azure.GroupList, error) {
var (
path = fmt.Sprintf("/%s/groups", constants.GraphApiVersion)
- params = query.Params{Filter: filter, Search: search, OrderBy: orderBy, Select: selectCols, Top: top, Count: count, Expand: expand}
headers map[string]string
response azure.GroupList
)
- count = count || search != "" || (filter != "" && orderBy != "") || strings.Contains(filter, "endsWith")
- if count {
- headers = make(map[string]string)
- headers["ConsistencyLevel"] = "eventual"
+ if params.Top == 0 {
+ params.Top = 99
}
- if res, err := s.msgraph.Get(ctx, path, params.AsMap(), headers); err != nil {
+
+ if res, err := s.msgraph.Get(ctx, path, params, headers); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -99,7 +85,7 @@ func (s *azureClient) GetAzureADGroups(ctx context.Context, filter, search, orde
}
}
-func (s *azureClient) ListAzureADGroups(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.GroupResult {
+func (s *azureClient) ListAzureADGroups(ctx context.Context, params query.GraphParams) <-chan azure.GroupResult {
out := make(chan azure.GroupResult)
go func() {
@@ -111,7 +97,7 @@ func (s *azureClient) ListAzureADGroups(ctx context.Context, filter, search, ord
nextLink string
)
- if list, err := s.GetAzureADGroups(ctx, filter, search, orderBy, expand, selectCols, 999, false); err != nil {
+ if list, err := s.GetAzureADGroups(ctx, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
@@ -164,7 +150,7 @@ func (s *azureClient) ListAzureADGroups(ctx context.Context, filter, search, ord
return out
}
-func (s *azureClient) ListAzureADGroupOwners(ctx context.Context, objectId string, filter, search, orderBy string, selectCols []string) <-chan azure.GroupOwnerResult {
+func (s *azureClient) ListAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.GroupOwnerResult {
out := make(chan azure.GroupOwnerResult)
go func() {
@@ -176,7 +162,7 @@ func (s *azureClient) ListAzureADGroupOwners(ctx context.Context, objectId strin
nextLink string
)
- if list, err := s.GetAzureADGroupOwners(ctx, objectId, filter, search, orderBy, selectCols, 999, false); err != nil {
+ if list, err := s.GetAzureADGroupOwners(ctx, objectId, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
@@ -235,7 +221,7 @@ func (s *azureClient) ListAzureADGroupOwners(ctx context.Context, objectId strin
return out
}
-func (s *azureClient) ListAzureADGroupMembers(ctx context.Context, objectId string, filter, search, orderBy string, selectCols []string) <-chan azure.MemberObjectResult {
+func (s *azureClient) ListAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.MemberObjectResult {
out := make(chan azure.MemberObjectResult)
go func() {
@@ -245,12 +231,12 @@ func (s *azureClient) ListAzureADGroupMembers(ctx context.Context, objectId stri
var (
errResult = azure.MemberObjectResult{
ParentId: objectId,
- ParentType: string(enums.EntityGroup),
+ ParentType: enums.EntityGroup,
}
nextLink string
)
- if list, err := s.GetAzureADGroupMembers(ctx, objectId, filter, search, false); err != nil {
+ if list, err := s.GetAzureADGroupMembers(ctx, objectId, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
diff --git a/client/keyvaults.go b/client/keyvaults.go
index 56e33f7..c2442df 100644
--- a/client/keyvaults.go
+++ b/client/keyvaults.go
@@ -29,31 +29,17 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureKeyVault(ctx context.Context, subscriptionId, groupName, vaultName string) (*azure.KeyVault, error) {
- var (
- path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.KeyVault/vaults/%s", subscriptionId, groupName, vaultName)
- params = query.Params{ApiVersion: "2019-09-01"}.AsMap()
- headers map[string]string
- response azure.KeyVault
- )
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
-func (s *azureClient) GetAzureKeyVaults(ctx context.Context, subscriptionId string, top int32) (azure.KeyVaultList, error) {
+func (s *azureClient) GetAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) (azure.KeyVaultList, error) {
var (
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.KeyVault/vaults", subscriptionId)
- params = query.Params{ApiVersion: "2019-09-01", Top: top}.AsMap()
- headers map[string]string
response azure.KeyVaultList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if params.ApiVersion == "" {
+ params.ApiVersion = "2019-09-01"
+ }
+
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -62,7 +48,7 @@ func (s *azureClient) GetAzureKeyVaults(ctx context.Context, subscriptionId stri
}
}
-func (s *azureClient) ListAzureKeyVaults(ctx context.Context, subscriptionId string, top int32) <-chan azure.KeyVaultResult {
+func (s *azureClient) ListAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azure.KeyVaultResult {
out := make(chan azure.KeyVaultResult)
go func() {
@@ -76,7 +62,7 @@ func (s *azureClient) ListAzureKeyVaults(ctx context.Context, subscriptionId str
nextLink string
)
- if result, err := s.GetAzureKeyVaults(ctx, subscriptionId, top); err != nil {
+ if result, err := s.GetAzureKeyVaults(ctx, subscriptionId, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
diff --git a/client/logic_apps.go b/client/logic_apps.go
index 54006a5..d460574 100644
--- a/client/logic_apps.go
+++ b/client/logic_apps.go
@@ -29,31 +29,14 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureLogicApp(ctx context.Context, subscriptionId, groupName, logicappName, expand string) (*azure.LogicApp, error) {
- var (
- path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Logic/workflows/%s", subscriptionId, groupName, logicappName)
- params = query.Params{ApiVersion: "2016-06-01", Expand: expand}.AsMap()
- headers map[string]string
- response azure.LogicApp
- )
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
func (s *azureClient) GetAzureLogicApps(ctx context.Context, subscriptionId string, filter string, top int32) (azure.LogicAppList, error) {
var (
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Logic/workflows", subscriptionId)
- params = query.Params{ApiVersion: "2016-06-01", Filter: filter, Top: top}.AsMap()
- headers map[string]string
+ params = query.RMParams{ApiVersion: "2016-06-01", Filter: filter, Top: top}
response azure.LogicAppList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
diff --git a/client/managed_clusters.go b/client/managed_clusters.go
index b1db393..ea7ad7c 100644
--- a/client/managed_clusters.go
+++ b/client/managed_clusters.go
@@ -29,31 +29,14 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureManagedCluster(ctx context.Context, subscriptionId, groupName, mcName, expand string) (*azure.ManagedCluster, error) {
- var (
- path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.ContainerService/managedClusters/%s", subscriptionId, groupName, mcName)
- params = query.Params{ApiVersion: "2021-07-01", Expand: expand}.AsMap()
- headers map[string]string
- response azure.ManagedCluster
- )
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
-func (s *azureClient) GetAzureManagedClusters(ctx context.Context, subscriptionId string, statusOnly bool) (azure.ManagedClusterList, error) {
+func (s *azureClient) GetAzureManagedClusters(ctx context.Context, subscriptionId string) (azure.ManagedClusterList, error) {
var (
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.ContainerService/managedClusters", subscriptionId)
- params = query.Params{ApiVersion: "2021-07-01", StatusOnly: statusOnly}.AsMap()
- headers map[string]string
+ params = query.RMParams{ApiVersion: "2021-07-01"}
response azure.ManagedClusterList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -62,7 +45,7 @@ func (s *azureClient) GetAzureManagedClusters(ctx context.Context, subscriptionI
}
}
-func (s *azureClient) ListAzureManagedClusters(ctx context.Context, subscriptionId string, statusOnly bool) <-chan azure.ManagedClusterResult {
+func (s *azureClient) ListAzureManagedClusters(ctx context.Context, subscriptionId string) <-chan azure.ManagedClusterResult {
out := make(chan azure.ManagedClusterResult)
go func() {
@@ -76,7 +59,7 @@ func (s *azureClient) ListAzureManagedClusters(ctx context.Context, subscription
nextLink string
)
- if result, err := s.GetAzureManagedClusters(ctx, subscriptionId, statusOnly); err != nil {
+ if result, err := s.GetAzureManagedClusters(ctx, subscriptionId); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
diff --git a/client/management_groups.go b/client/management_groups.go
index f68d866..ece4fe5 100644
--- a/client/management_groups.go
+++ b/client/management_groups.go
@@ -29,31 +29,14 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureManagementGroup(ctx context.Context, groupId, filter, expand string, recurse bool) (*azure.ManagementGroup, error) {
- var (
- path = fmt.Sprintf("/providers/Microsoft.Management/managementGroups/%s", groupId)
- params = query.Params{ApiVersion: "2020-05-01", Filter: filter, Expand: expand, Recurse: recurse}.AsMap()
- headers map[string]string
- response azure.ManagementGroup
- )
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
-func (s *azureClient) GetAzureManagementGroups(ctx context.Context) (azure.ManagementGroupList, error) {
+func (s *azureClient) GetAzureManagementGroups(ctx context.Context, skipToken string) (azure.ManagementGroupList, error) {
var (
path = "/providers/Microsoft.Management/managementGroups"
- params = query.Params{ApiVersion: "2020-05-01"}.AsMap()
- headers map[string]string
+ params = query.RMParams{ApiVersion: "2020-05-01", SkipToken: skipToken}
response azure.ManagementGroupList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -65,12 +48,11 @@ func (s *azureClient) GetAzureManagementGroups(ctx context.Context) (azure.Manag
func (s *azureClient) GetAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) (azure.DescendantInfoList, error) {
var (
path = fmt.Sprintf("/providers/Microsoft.Management/managementGroups/%s/descendants", groupId)
- params = query.Params{ApiVersion: "2020-05-01", Top: top}.AsMap()
- headers map[string]string
+ params = query.RMParams{ApiVersion: "2020-05-01", Top: top}
response azure.DescendantInfoList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -79,7 +61,7 @@ func (s *azureClient) GetAzureManagementGroupDescendants(ctx context.Context, gr
}
}
-func (s *azureClient) ListAzureManagementGroups(ctx context.Context) <-chan azure.ManagementGroupResult {
+func (s *azureClient) ListAzureManagementGroups(ctx context.Context, skipToken string) <-chan azure.ManagementGroupResult {
out := make(chan azure.ManagementGroupResult)
go func() {
@@ -91,7 +73,7 @@ func (s *azureClient) ListAzureManagementGroups(ctx context.Context) <-chan azur
nextLink string
)
- if result, err := s.GetAzureManagementGroups(ctx); err != nil {
+ if result, err := s.GetAzureManagementGroups(ctx, skipToken); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
@@ -144,7 +126,7 @@ func (s *azureClient) ListAzureManagementGroups(ctx context.Context) <-chan azur
return out
}
-func (s *azureClient) ListAzureManagementGroupDescendants(ctx context.Context, groupId string) <-chan azure.DescendantInfoResult {
+func (s *azureClient) ListAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) <-chan azure.DescendantInfoResult {
out := make(chan azure.DescendantInfoResult)
go func() {
@@ -156,7 +138,7 @@ func (s *azureClient) ListAzureManagementGroupDescendants(ctx context.Context, g
nextLink string
)
- if result, err := s.GetAzureManagementGroupDescendants(ctx, groupId, 3000); err != nil {
+ if result, err := s.GetAzureManagementGroupDescendants(ctx, groupId, top); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
diff --git a/client/mocks/client.go b/client/mocks/client.go
index fa2ca60..6ead097 100644
--- a/client/mocks/client.go
+++ b/client/mocks/client.go
@@ -6,9 +6,9 @@ package mocks
import (
context "context"
- json "encoding/json"
reflect "reflect"
+ query "github.com/bloodhoundad/azurehound/v2/client/query"
azure "github.com/bloodhoundad/azurehound/v2/models/azure"
gomock "go.uber.org/mock/gomock"
)
@@ -48,94 +48,79 @@ func (mr *MockAzureClientMockRecorder) CloseIdleConnections() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseIdleConnections", reflect.TypeOf((*MockAzureClient)(nil).CloseIdleConnections))
}
-// GetAzureADApp mocks base method.
-func (m *MockAzureClient) GetAzureADApp(arg0 context.Context, arg1 string, arg2 []string) (*azure.Application, error) {
+// GetAzureADAppRoleAssignments mocks base method.
+func (m *MockAzureClient) GetAzureADAppRoleAssignments(arg0 context.Context, arg1 string, arg2 query.GraphParams) (azure.AppRoleAssignmentList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADApp", arg0, arg1, arg2)
- ret0, _ := ret[0].(*azure.Application)
+ ret := m.ctrl.Call(m, "GetAzureADAppRoleAssignments", arg0, arg1, arg2)
+ ret0, _ := ret[0].(azure.AppRoleAssignmentList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-// GetAzureADApp indicates an expected call of GetAzureADApp.
-func (mr *MockAzureClientMockRecorder) GetAzureADApp(arg0, arg1, arg2 interface{}) *gomock.Call {
+// GetAzureADAppRoleAssignments indicates an expected call of GetAzureADAppRoleAssignments.
+func (mr *MockAzureClientMockRecorder) GetAzureADAppRoleAssignments(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADApp", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADApp), arg0, arg1, arg2)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADAppRoleAssignments", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADAppRoleAssignments), arg0, arg1, arg2)
}
// GetAzureADApps mocks base method.
-func (m *MockAzureClient) GetAzureADApps(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string, arg6 int32, arg7 bool) (azure.ApplicationList, error) {
+func (m *MockAzureClient) GetAzureADApps(arg0 context.Context, arg1 query.GraphParams) (azure.ApplicationList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADApps", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ ret := m.ctrl.Call(m, "GetAzureADApps", arg0, arg1)
ret0, _ := ret[0].(azure.ApplicationList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAzureADApps indicates an expected call of GetAzureADApps.
-func (mr *MockAzureClientMockRecorder) GetAzureADApps(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) GetAzureADApps(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADApps", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADApps), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADApps", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADApps), arg0, arg1)
}
-// GetAzureADDirectoryObject mocks base method.
-func (m *MockAzureClient) GetAzureADDirectoryObject(arg0 context.Context, arg1 string) (json.RawMessage, error) {
+// GetAzureADGroupMembers mocks base method.
+func (m *MockAzureClient) GetAzureADGroupMembers(arg0 context.Context, arg1 string, arg2 query.GraphParams) (azure.MemberObjectList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADDirectoryObject", arg0, arg1)
- ret0, _ := ret[0].(json.RawMessage)
+ ret := m.ctrl.Call(m, "GetAzureADGroupMembers", arg0, arg1, arg2)
+ ret0, _ := ret[0].(azure.MemberObjectList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-// GetAzureADDirectoryObject indicates an expected call of GetAzureADDirectoryObject.
-func (mr *MockAzureClientMockRecorder) GetAzureADDirectoryObject(arg0, arg1 interface{}) *gomock.Call {
+// GetAzureADGroupMembers indicates an expected call of GetAzureADGroupMembers.
+func (mr *MockAzureClientMockRecorder) GetAzureADGroupMembers(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADDirectoryObject", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADDirectoryObject), arg0, arg1)
-}
-
-// GetAzureADGroup mocks base method.
-func (m *MockAzureClient) GetAzureADGroup(arg0 context.Context, arg1 string, arg2 []string) (*azure.Group, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADGroup", arg0, arg1, arg2)
- ret0, _ := ret[0].(*azure.Group)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureADGroup indicates an expected call of GetAzureADGroup.
-func (mr *MockAzureClientMockRecorder) GetAzureADGroup(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADGroup", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADGroup), arg0, arg1, arg2)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADGroupMembers", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADGroupMembers), arg0, arg1, arg2)
}
// GetAzureADGroupOwners mocks base method.
-func (m *MockAzureClient) GetAzureADGroupOwners(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string, arg6 int32, arg7 bool) (azure.DirectoryObjectList, error) {
+func (m *MockAzureClient) GetAzureADGroupOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) (azure.DirectoryObjectList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADGroupOwners", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ ret := m.ctrl.Call(m, "GetAzureADGroupOwners", arg0, arg1, arg2)
ret0, _ := ret[0].(azure.DirectoryObjectList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAzureADGroupOwners indicates an expected call of GetAzureADGroupOwners.
-func (mr *MockAzureClientMockRecorder) GetAzureADGroupOwners(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) GetAzureADGroupOwners(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADGroupOwners", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADGroupOwners), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADGroupOwners", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADGroupOwners), arg0, arg1, arg2)
}
// GetAzureADGroups mocks base method.
-func (m *MockAzureClient) GetAzureADGroups(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string, arg6 int32, arg7 bool) (azure.GroupList, error) {
+func (m *MockAzureClient) GetAzureADGroups(arg0 context.Context, arg1 query.GraphParams) (azure.GroupList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADGroups", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ ret := m.ctrl.Call(m, "GetAzureADGroups", arg0, arg1)
ret0, _ := ret[0].(azure.GroupList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAzureADGroups indicates an expected call of GetAzureADGroups.
-func (mr *MockAzureClientMockRecorder) GetAzureADGroups(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) GetAzureADGroups(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADGroups", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADGroups), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADGroups", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADGroups), arg0, arg1)
}
// GetAzureADOrganization mocks base method.
@@ -153,109 +138,64 @@ func (mr *MockAzureClientMockRecorder) GetAzureADOrganization(arg0, arg1 interfa
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADOrganization", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADOrganization), arg0, arg1)
}
-// GetAzureADRole mocks base method.
-func (m *MockAzureClient) GetAzureADRole(arg0 context.Context, arg1 string, arg2 []string) (*azure.Role, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADRole", arg0, arg1, arg2)
- ret0, _ := ret[0].(*azure.Role)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureADRole indicates an expected call of GetAzureADRole.
-func (mr *MockAzureClientMockRecorder) GetAzureADRole(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADRole", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADRole), arg0, arg1, arg2)
-}
-
-// GetAzureADRoleAssignment mocks base method.
-func (m *MockAzureClient) GetAzureADRoleAssignment(arg0 context.Context, arg1 string, arg2 []string) (*azure.UnifiedRoleAssignment, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADRoleAssignment", arg0, arg1, arg2)
- ret0, _ := ret[0].(*azure.UnifiedRoleAssignment)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureADRoleAssignment indicates an expected call of GetAzureADRoleAssignment.
-func (mr *MockAzureClientMockRecorder) GetAzureADRoleAssignment(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADRoleAssignment", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADRoleAssignment), arg0, arg1, arg2)
-}
-
// GetAzureADRoleAssignments mocks base method.
-func (m *MockAzureClient) GetAzureADRoleAssignments(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string, arg6 int32, arg7 bool) (azure.UnifiedRoleAssignmentList, error) {
+func (m *MockAzureClient) GetAzureADRoleAssignments(arg0 context.Context, arg1 query.GraphParams) (azure.UnifiedRoleAssignmentList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADRoleAssignments", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ ret := m.ctrl.Call(m, "GetAzureADRoleAssignments", arg0, arg1)
ret0, _ := ret[0].(azure.UnifiedRoleAssignmentList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAzureADRoleAssignments indicates an expected call of GetAzureADRoleAssignments.
-func (mr *MockAzureClientMockRecorder) GetAzureADRoleAssignments(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) GetAzureADRoleAssignments(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADRoleAssignments", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADRoleAssignments), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADRoleAssignments", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADRoleAssignments), arg0, arg1)
}
// GetAzureADRoles mocks base method.
-func (m *MockAzureClient) GetAzureADRoles(arg0 context.Context, arg1, arg2 string) (azure.RoleList, error) {
+func (m *MockAzureClient) GetAzureADRoles(arg0 context.Context, arg1 string) (azure.RoleList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADRoles", arg0, arg1, arg2)
+ ret := m.ctrl.Call(m, "GetAzureADRoles", arg0, arg1)
ret0, _ := ret[0].(azure.RoleList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAzureADRoles indicates an expected call of GetAzureADRoles.
-func (mr *MockAzureClientMockRecorder) GetAzureADRoles(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) GetAzureADRoles(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADRoles", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADRoles), arg0, arg1, arg2)
-}
-
-// GetAzureADServicePrincipal mocks base method.
-func (m *MockAzureClient) GetAzureADServicePrincipal(arg0 context.Context, arg1 string, arg2 []string) (*azure.ServicePrincipal, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADServicePrincipal", arg0, arg1, arg2)
- ret0, _ := ret[0].(*azure.ServicePrincipal)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureADServicePrincipal indicates an expected call of GetAzureADServicePrincipal.
-func (mr *MockAzureClientMockRecorder) GetAzureADServicePrincipal(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADServicePrincipal", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADServicePrincipal), arg0, arg1, arg2)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADRoles", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADRoles), arg0, arg1)
}
// GetAzureADServicePrincipalOwners mocks base method.
-func (m *MockAzureClient) GetAzureADServicePrincipalOwners(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string, arg6 int32, arg7 bool) (azure.DirectoryObjectList, error) {
+func (m *MockAzureClient) GetAzureADServicePrincipalOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) (azure.DirectoryObjectList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADServicePrincipalOwners", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ ret := m.ctrl.Call(m, "GetAzureADServicePrincipalOwners", arg0, arg1, arg2)
ret0, _ := ret[0].(azure.DirectoryObjectList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAzureADServicePrincipalOwners indicates an expected call of GetAzureADServicePrincipalOwners.
-func (mr *MockAzureClientMockRecorder) GetAzureADServicePrincipalOwners(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) GetAzureADServicePrincipalOwners(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADServicePrincipalOwners", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADServicePrincipalOwners), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADServicePrincipalOwners", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADServicePrincipalOwners), arg0, arg1, arg2)
}
// GetAzureADServicePrincipals mocks base method.
-func (m *MockAzureClient) GetAzureADServicePrincipals(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string, arg6 int32, arg7 bool) (azure.ServicePrincipalList, error) {
+func (m *MockAzureClient) GetAzureADServicePrincipals(arg0 context.Context, arg1 query.GraphParams) (azure.ServicePrincipalList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADServicePrincipals", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ ret := m.ctrl.Call(m, "GetAzureADServicePrincipals", arg0, arg1)
ret0, _ := ret[0].(azure.ServicePrincipalList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAzureADServicePrincipals indicates an expected call of GetAzureADServicePrincipals.
-func (mr *MockAzureClientMockRecorder) GetAzureADServicePrincipals(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) GetAzureADServicePrincipals(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADServicePrincipals", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADServicePrincipals), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADServicePrincipals", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADServicePrincipals), arg0, arg1)
}
// GetAzureADTenants mocks base method.
@@ -273,83 +213,98 @@ func (mr *MockAzureClientMockRecorder) GetAzureADTenants(arg0, arg1 interface{})
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADTenants", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADTenants), arg0, arg1)
}
-// GetAzureADUser mocks base method.
-func (m *MockAzureClient) GetAzureADUser(arg0 context.Context, arg1 string, arg2 []string) (*azure.User, error) {
+// GetAzureADUsers mocks base method.
+func (m *MockAzureClient) GetAzureADUsers(arg0 context.Context, arg1 query.GraphParams) (azure.UserList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADUser", arg0, arg1, arg2)
- ret0, _ := ret[0].(*azure.User)
+ ret := m.ctrl.Call(m, "GetAzureADUsers", arg0, arg1)
+ ret0, _ := ret[0].(azure.UserList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-// GetAzureADUser indicates an expected call of GetAzureADUser.
-func (mr *MockAzureClientMockRecorder) GetAzureADUser(arg0, arg1, arg2 interface{}) *gomock.Call {
+// GetAzureADUsers indicates an expected call of GetAzureADUsers.
+func (mr *MockAzureClientMockRecorder) GetAzureADUsers(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADUser", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADUser), arg0, arg1, arg2)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADUsers", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADUsers), arg0, arg1)
}
-// GetAzureADUsers mocks base method.
-func (m *MockAzureClient) GetAzureADUsers(arg0 context.Context, arg1, arg2, arg3 string, arg4 []string, arg5 int32, arg6 bool) (azure.UserList, error) {
+// GetAzureAutomationAccounts mocks base method.
+func (m *MockAzureClient) GetAzureAutomationAccounts(arg0 context.Context, arg1 string) (azure.AutomationAccountList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADUsers", arg0, arg1, arg2, arg3, arg4, arg5, arg6)
- ret0, _ := ret[0].(azure.UserList)
+ ret := m.ctrl.Call(m, "GetAzureAutomationAccounts", arg0, arg1)
+ ret0, _ := ret[0].(azure.AutomationAccountList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-// GetAzureADUsers indicates an expected call of GetAzureADUsers.
-func (mr *MockAzureClientMockRecorder) GetAzureADUsers(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call {
+// GetAzureAutomationAccounts indicates an expected call of GetAzureAutomationAccounts.
+func (mr *MockAzureClientMockRecorder) GetAzureAutomationAccounts(arg0, arg1 interface{}) *gomock.Call {
+ mr.mock.ctrl.T.Helper()
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureAutomationAccounts", reflect.TypeOf((*MockAzureClient)(nil).GetAzureAutomationAccounts), arg0, arg1)
+}
+
+// GetAzureContainerRegistries mocks base method.
+func (m *MockAzureClient) GetAzureContainerRegistries(arg0 context.Context, arg1 string) (azure.ContainerRegistryList, error) {
+ m.ctrl.T.Helper()
+ ret := m.ctrl.Call(m, "GetAzureContainerRegistries", arg0, arg1)
+ ret0, _ := ret[0].(azure.ContainerRegistryList)
+ ret1, _ := ret[1].(error)
+ return ret0, ret1
+}
+
+// GetAzureContainerRegistries indicates an expected call of GetAzureContainerRegistries.
+func (mr *MockAzureClientMockRecorder) GetAzureContainerRegistries(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADUsers", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADUsers), arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureContainerRegistries", reflect.TypeOf((*MockAzureClient)(nil).GetAzureContainerRegistries), arg0, arg1)
}
-// GetAzureDevice mocks base method.
-func (m *MockAzureClient) GetAzureDevice(arg0 context.Context, arg1 string, arg2 []string) (*azure.Device, error) {
+// GetAzureDeviceRegisteredOwners mocks base method.
+func (m *MockAzureClient) GetAzureDeviceRegisteredOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) (azure.DirectoryObjectList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureDevice", arg0, arg1, arg2)
- ret0, _ := ret[0].(*azure.Device)
+ ret := m.ctrl.Call(m, "GetAzureDeviceRegisteredOwners", arg0, arg1, arg2)
+ ret0, _ := ret[0].(azure.DirectoryObjectList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-// GetAzureDevice indicates an expected call of GetAzureDevice.
-func (mr *MockAzureClientMockRecorder) GetAzureDevice(arg0, arg1, arg2 interface{}) *gomock.Call {
+// GetAzureDeviceRegisteredOwners indicates an expected call of GetAzureDeviceRegisteredOwners.
+func (mr *MockAzureClientMockRecorder) GetAzureDeviceRegisteredOwners(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureDevice", reflect.TypeOf((*MockAzureClient)(nil).GetAzureDevice), arg0, arg1, arg2)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureDeviceRegisteredOwners", reflect.TypeOf((*MockAzureClient)(nil).GetAzureDeviceRegisteredOwners), arg0, arg1, arg2)
}
// GetAzureDevices mocks base method.
-func (m *MockAzureClient) GetAzureDevices(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string, arg6 int32, arg7 bool) (azure.DeviceList, error) {
+func (m *MockAzureClient) GetAzureDevices(arg0 context.Context, arg1 query.GraphParams) (azure.DeviceList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureDevices", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ ret := m.ctrl.Call(m, "GetAzureDevices", arg0, arg1)
ret0, _ := ret[0].(azure.DeviceList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAzureDevices indicates an expected call of GetAzureDevices.
-func (mr *MockAzureClientMockRecorder) GetAzureDevices(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) GetAzureDevices(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureDevices", reflect.TypeOf((*MockAzureClient)(nil).GetAzureDevices), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureDevices", reflect.TypeOf((*MockAzureClient)(nil).GetAzureDevices), arg0, arg1)
}
-// GetAzureKeyVault mocks base method.
-func (m *MockAzureClient) GetAzureKeyVault(arg0 context.Context, arg1, arg2, arg3 string) (*azure.KeyVault, error) {
+// GetAzureFunctionApps mocks base method.
+func (m *MockAzureClient) GetAzureFunctionApps(arg0 context.Context, arg1 string) (azure.FunctionAppList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureKeyVault", arg0, arg1, arg2, arg3)
- ret0, _ := ret[0].(*azure.KeyVault)
+ ret := m.ctrl.Call(m, "GetAzureFunctionApps", arg0, arg1)
+ ret0, _ := ret[0].(azure.FunctionAppList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-// GetAzureKeyVault indicates an expected call of GetAzureKeyVault.
-func (mr *MockAzureClientMockRecorder) GetAzureKeyVault(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
+// GetAzureFunctionApps indicates an expected call of GetAzureFunctionApps.
+func (mr *MockAzureClientMockRecorder) GetAzureFunctionApps(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureKeyVault", reflect.TypeOf((*MockAzureClient)(nil).GetAzureKeyVault), arg0, arg1, arg2, arg3)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureFunctionApps", reflect.TypeOf((*MockAzureClient)(nil).GetAzureFunctionApps), arg0, arg1)
}
// GetAzureKeyVaults mocks base method.
-func (m *MockAzureClient) GetAzureKeyVaults(arg0 context.Context, arg1 string, arg2 int32) (azure.KeyVaultList, error) {
+func (m *MockAzureClient) GetAzureKeyVaults(arg0 context.Context, arg1 string, arg2 query.RMParams) (azure.KeyVaultList, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAzureKeyVaults", arg0, arg1, arg2)
ret0, _ := ret[0].(azure.KeyVaultList)
@@ -363,79 +318,64 @@ func (mr *MockAzureClientMockRecorder) GetAzureKeyVaults(arg0, arg1, arg2 interf
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureKeyVaults", reflect.TypeOf((*MockAzureClient)(nil).GetAzureKeyVaults), arg0, arg1, arg2)
}
-// GetAzureManagementGroup mocks base method.
-func (m *MockAzureClient) GetAzureManagementGroup(arg0 context.Context, arg1, arg2, arg3 string, arg4 bool) (*azure.ManagementGroup, error) {
+// GetAzureLogicApps mocks base method.
+func (m *MockAzureClient) GetAzureLogicApps(arg0 context.Context, arg1, arg2 string, arg3 int32) (azure.LogicAppList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureManagementGroup", arg0, arg1, arg2, arg3, arg4)
- ret0, _ := ret[0].(*azure.ManagementGroup)
+ ret := m.ctrl.Call(m, "GetAzureLogicApps", arg0, arg1, arg2, arg3)
+ ret0, _ := ret[0].(azure.LogicAppList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-// GetAzureManagementGroup indicates an expected call of GetAzureManagementGroup.
-func (mr *MockAzureClientMockRecorder) GetAzureManagementGroup(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
+// GetAzureLogicApps indicates an expected call of GetAzureLogicApps.
+func (mr *MockAzureClientMockRecorder) GetAzureLogicApps(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureManagementGroup", reflect.TypeOf((*MockAzureClient)(nil).GetAzureManagementGroup), arg0, arg1, arg2, arg3, arg4)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureLogicApps", reflect.TypeOf((*MockAzureClient)(nil).GetAzureLogicApps), arg0, arg1, arg2, arg3)
}
-// GetAzureManagementGroups mocks base method.
-func (m *MockAzureClient) GetAzureManagementGroups(arg0 context.Context) (azure.ManagementGroupList, error) {
+// GetAzureManagementGroupDescendants mocks base method.
+func (m *MockAzureClient) GetAzureManagementGroupDescendants(arg0 context.Context, arg1 string, arg2 int32) (azure.DescendantInfoList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureManagementGroups", arg0)
- ret0, _ := ret[0].(azure.ManagementGroupList)
+ ret := m.ctrl.Call(m, "GetAzureManagementGroupDescendants", arg0, arg1, arg2)
+ ret0, _ := ret[0].(azure.DescendantInfoList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-// GetAzureManagementGroups indicates an expected call of GetAzureManagementGroups.
-func (mr *MockAzureClientMockRecorder) GetAzureManagementGroups(arg0 interface{}) *gomock.Call {
+// GetAzureManagementGroupDescendants indicates an expected call of GetAzureManagementGroupDescendants.
+func (mr *MockAzureClientMockRecorder) GetAzureManagementGroupDescendants(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureManagementGroups", reflect.TypeOf((*MockAzureClient)(nil).GetAzureManagementGroups), arg0)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureManagementGroupDescendants", reflect.TypeOf((*MockAzureClient)(nil).GetAzureManagementGroupDescendants), arg0, arg1, arg2)
}
-// GetAzureResourceGroup mocks base method.
-func (m *MockAzureClient) GetAzureResourceGroup(arg0 context.Context, arg1, arg2 string) (*azure.ResourceGroup, error) {
+// GetAzureManagementGroups mocks base method.
+func (m *MockAzureClient) GetAzureManagementGroups(arg0 context.Context, arg1 string) (azure.ManagementGroupList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureResourceGroup", arg0, arg1, arg2)
- ret0, _ := ret[0].(*azure.ResourceGroup)
+ ret := m.ctrl.Call(m, "GetAzureManagementGroups", arg0, arg1)
+ ret0, _ := ret[0].(azure.ManagementGroupList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-// GetAzureResourceGroup indicates an expected call of GetAzureResourceGroup.
-func (mr *MockAzureClientMockRecorder) GetAzureResourceGroup(arg0, arg1, arg2 interface{}) *gomock.Call {
+// GetAzureManagementGroups indicates an expected call of GetAzureManagementGroups.
+func (mr *MockAzureClientMockRecorder) GetAzureManagementGroups(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureResourceGroup", reflect.TypeOf((*MockAzureClient)(nil).GetAzureResourceGroup), arg0, arg1, arg2)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureManagementGroups", reflect.TypeOf((*MockAzureClient)(nil).GetAzureManagementGroups), arg0, arg1)
}
// GetAzureResourceGroups mocks base method.
-func (m *MockAzureClient) GetAzureResourceGroups(arg0 context.Context, arg1, arg2 string, arg3 int32) (azure.ResourceGroupList, error) {
+func (m *MockAzureClient) GetAzureResourceGroups(arg0 context.Context, arg1 string, arg2 query.RMParams) (azure.ResourceGroupList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureResourceGroups", arg0, arg1, arg2, arg3)
+ ret := m.ctrl.Call(m, "GetAzureResourceGroups", arg0, arg1, arg2)
ret0, _ := ret[0].(azure.ResourceGroupList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetAzureResourceGroups indicates an expected call of GetAzureResourceGroups.
-func (mr *MockAzureClientMockRecorder) GetAzureResourceGroups(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) GetAzureResourceGroups(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureResourceGroups", reflect.TypeOf((*MockAzureClient)(nil).GetAzureResourceGroups), arg0, arg1, arg2, arg3)
-}
-
-// GetAzureStorageAccount mocks base method.
-func (m *MockAzureClient) GetAzureStorageAccount(arg0 context.Context, arg1, arg2, arg3, arg4 string) (*azure.StorageAccount, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureStorageAccount", arg0, arg1, arg2, arg3, arg4)
- ret0, _ := ret[0].(*azure.StorageAccount)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureStorageAccount indicates an expected call of GetAzureStorageAccount.
-func (mr *MockAzureClientMockRecorder) GetAzureStorageAccount(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureStorageAccount", reflect.TypeOf((*MockAzureClient)(nil).GetAzureStorageAccount), arg0, arg1, arg2, arg3, arg4)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureResourceGroups", reflect.TypeOf((*MockAzureClient)(nil).GetAzureResourceGroups), arg0, arg1, arg2)
}
// GetAzureStorageAccounts mocks base method.
@@ -453,19 +393,19 @@ func (mr *MockAzureClientMockRecorder) GetAzureStorageAccounts(arg0, arg1 interf
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureStorageAccounts", reflect.TypeOf((*MockAzureClient)(nil).GetAzureStorageAccounts), arg0, arg1)
}
-// GetAzureSubscription mocks base method.
-func (m *MockAzureClient) GetAzureSubscription(arg0 context.Context, arg1 string) (*azure.Subscription, error) {
+// GetAzureStorageContainers mocks base method.
+func (m *MockAzureClient) GetAzureStorageContainers(arg0 context.Context, arg1, arg2, arg3, arg4, arg5, arg6 string) (azure.StorageContainerList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureSubscription", arg0, arg1)
- ret0, _ := ret[0].(*azure.Subscription)
+ ret := m.ctrl.Call(m, "GetAzureStorageContainers", arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+ ret0, _ := ret[0].(azure.StorageContainerList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-// GetAzureSubscription indicates an expected call of GetAzureSubscription.
-func (mr *MockAzureClientMockRecorder) GetAzureSubscription(arg0, arg1 interface{}) *gomock.Call {
+// GetAzureStorageContainers indicates an expected call of GetAzureStorageContainers.
+func (mr *MockAzureClientMockRecorder) GetAzureStorageContainers(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureSubscription", reflect.TypeOf((*MockAzureClient)(nil).GetAzureSubscription), arg0, arg1)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureStorageContainers", reflect.TypeOf((*MockAzureClient)(nil).GetAzureStorageContainers), arg0, arg1, arg2, arg3, arg4, arg5, arg6)
}
// GetAzureSubscriptions mocks base method.
@@ -483,23 +423,23 @@ func (mr *MockAzureClientMockRecorder) GetAzureSubscriptions(arg0 interface{}) *
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureSubscriptions", reflect.TypeOf((*MockAzureClient)(nil).GetAzureSubscriptions), arg0)
}
-// GetAzureVirtualMachine mocks base method.
-func (m *MockAzureClient) GetAzureVirtualMachine(arg0 context.Context, arg1, arg2, arg3, arg4 string) (*azure.VirtualMachine, error) {
+// GetAzureVMScaleSets mocks base method.
+func (m *MockAzureClient) GetAzureVMScaleSets(arg0 context.Context, arg1 string) (azure.VMScaleSetList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureVirtualMachine", arg0, arg1, arg2, arg3, arg4)
- ret0, _ := ret[0].(*azure.VirtualMachine)
+ ret := m.ctrl.Call(m, "GetAzureVMScaleSets", arg0, arg1)
+ ret0, _ := ret[0].(azure.VMScaleSetList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-// GetAzureVirtualMachine indicates an expected call of GetAzureVirtualMachine.
-func (mr *MockAzureClientMockRecorder) GetAzureVirtualMachine(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
+// GetAzureVMScaleSets indicates an expected call of GetAzureVMScaleSets.
+func (mr *MockAzureClientMockRecorder) GetAzureVMScaleSets(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureVirtualMachine", reflect.TypeOf((*MockAzureClient)(nil).GetAzureVirtualMachine), arg0, arg1, arg2, arg3, arg4)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureVMScaleSets", reflect.TypeOf((*MockAzureClient)(nil).GetAzureVMScaleSets), arg0, arg1)
}
// GetAzureVirtualMachines mocks base method.
-func (m *MockAzureClient) GetAzureVirtualMachines(arg0 context.Context, arg1 string, arg2 bool) (azure.VirtualMachineList, error) {
+func (m *MockAzureClient) GetAzureVirtualMachines(arg0 context.Context, arg1 string, arg2 query.RMParams) (azure.VirtualMachineList, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAzureVirtualMachines", arg0, arg1, arg2)
ret0, _ := ret[0].(azure.VirtualMachineList)
@@ -513,188 +453,174 @@ func (mr *MockAzureClientMockRecorder) GetAzureVirtualMachines(arg0, arg1, arg2
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureVirtualMachines", reflect.TypeOf((*MockAzureClient)(nil).GetAzureVirtualMachines), arg0, arg1, arg2)
}
-// GetResourceRoleAssignments mocks base method.
-func (m *MockAzureClient) GetResourceRoleAssignments(arg0 context.Context, arg1, arg2, arg3 string) (azure.RoleAssignmentList, error) {
+// GetAzureWebApps mocks base method.
+func (m *MockAzureClient) GetAzureWebApps(arg0 context.Context, arg1 string) (azure.WebAppList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetResourceRoleAssignments", arg0, arg1, arg2, arg3)
- ret0, _ := ret[0].(azure.RoleAssignmentList)
+ ret := m.ctrl.Call(m, "GetAzureWebApps", arg0, arg1)
+ ret0, _ := ret[0].(azure.WebAppList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
-// GetResourceRoleAssignments indicates an expected call of GetResourceRoleAssignments.
-func (mr *MockAzureClientMockRecorder) GetResourceRoleAssignments(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
+// GetAzureWebApps indicates an expected call of GetAzureWebApps.
+func (mr *MockAzureClientMockRecorder) GetAzureWebApps(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetResourceRoleAssignments", reflect.TypeOf((*MockAzureClient)(nil).GetResourceRoleAssignments), arg0, arg1, arg2, arg3)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureWebApps", reflect.TypeOf((*MockAzureClient)(nil).GetAzureWebApps), arg0, arg1)
}
// GetRoleAssignmentsForResource mocks base method.
-func (m *MockAzureClient) GetRoleAssignmentsForResource(arg0 context.Context, arg1, arg2 string) (azure.RoleAssignmentList, error) {
+func (m *MockAzureClient) GetRoleAssignmentsForResource(arg0 context.Context, arg1, arg2, arg3 string) (azure.RoleAssignmentList, error) {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetRoleAssignmentsForResource", arg0, arg1, arg2)
+ ret := m.ctrl.Call(m, "GetRoleAssignmentsForResource", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(azure.RoleAssignmentList)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetRoleAssignmentsForResource indicates an expected call of GetRoleAssignmentsForResource.
-func (mr *MockAzureClientMockRecorder) GetRoleAssignmentsForResource(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) GetRoleAssignmentsForResource(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRoleAssignmentsForResource", reflect.TypeOf((*MockAzureClient)(nil).GetRoleAssignmentsForResource), arg0, arg1, arg2)
-}
-
-// ListAzureADAppMemberObjects mocks base method.
-func (m *MockAzureClient) ListAzureADAppMemberObjects(arg0 context.Context, arg1 string, arg2 bool) <-chan azure.MemberObjectResult {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureADAppMemberObjects", arg0, arg1, arg2)
- ret0, _ := ret[0].(<-chan azure.MemberObjectResult)
- return ret0
-}
-
-// ListAzureADAppMemberObjects indicates an expected call of ListAzureADAppMemberObjects.
-func (mr *MockAzureClientMockRecorder) ListAzureADAppMemberObjects(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADAppMemberObjects", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADAppMemberObjects), arg0, arg1, arg2)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRoleAssignmentsForResource", reflect.TypeOf((*MockAzureClient)(nil).GetRoleAssignmentsForResource), arg0, arg1, arg2, arg3)
}
// ListAzureADAppOwners mocks base method.
-func (m *MockAzureClient) ListAzureADAppOwners(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string) <-chan azure.AppOwnerResult {
+func (m *MockAzureClient) ListAzureADAppOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan azure.AppOwnerResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureADAppOwners", arg0, arg1, arg2, arg3, arg4, arg5)
+ ret := m.ctrl.Call(m, "ListAzureADAppOwners", arg0, arg1, arg2)
ret0, _ := ret[0].(<-chan azure.AppOwnerResult)
return ret0
}
// ListAzureADAppOwners indicates an expected call of ListAzureADAppOwners.
-func (mr *MockAzureClientMockRecorder) ListAzureADAppOwners(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureADAppOwners(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADAppOwners", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADAppOwners), arg0, arg1, arg2, arg3, arg4, arg5)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADAppOwners", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADAppOwners), arg0, arg1, arg2)
}
// ListAzureADAppRoleAssignments mocks base method.
-func (m *MockAzureClient) ListAzureADAppRoleAssignments(arg0 context.Context, arg1, arg2, arg3, arg4, arg5 string, arg6 []string) <-chan azure.AppRoleAssignmentResult {
+func (m *MockAzureClient) ListAzureADAppRoleAssignments(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan azure.AppRoleAssignmentResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureADAppRoleAssignments", arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+ ret := m.ctrl.Call(m, "ListAzureADAppRoleAssignments", arg0, arg1, arg2)
ret0, _ := ret[0].(<-chan azure.AppRoleAssignmentResult)
return ret0
}
// ListAzureADAppRoleAssignments indicates an expected call of ListAzureADAppRoleAssignments.
-func (mr *MockAzureClientMockRecorder) ListAzureADAppRoleAssignments(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureADAppRoleAssignments(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADAppRoleAssignments", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADAppRoleAssignments), arg0, arg1, arg2, arg3, arg4, arg5, arg6)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADAppRoleAssignments", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADAppRoleAssignments), arg0, arg1, arg2)
}
// ListAzureADApps mocks base method.
-func (m *MockAzureClient) ListAzureADApps(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string) <-chan azure.ApplicationResult {
+func (m *MockAzureClient) ListAzureADApps(arg0 context.Context, arg1 query.GraphParams) <-chan azure.ApplicationResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureADApps", arg0, arg1, arg2, arg3, arg4, arg5)
+ ret := m.ctrl.Call(m, "ListAzureADApps", arg0, arg1)
ret0, _ := ret[0].(<-chan azure.ApplicationResult)
return ret0
}
// ListAzureADApps indicates an expected call of ListAzureADApps.
-func (mr *MockAzureClientMockRecorder) ListAzureADApps(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureADApps(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADApps", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADApps), arg0, arg1, arg2, arg3, arg4, arg5)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADApps", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADApps), arg0, arg1)
}
// ListAzureADGroupMembers mocks base method.
-func (m *MockAzureClient) ListAzureADGroupMembers(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string) <-chan azure.MemberObjectResult {
+func (m *MockAzureClient) ListAzureADGroupMembers(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan azure.MemberObjectResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureADGroupMembers", arg0, arg1, arg2, arg3, arg4, arg5)
+ ret := m.ctrl.Call(m, "ListAzureADGroupMembers", arg0, arg1, arg2)
ret0, _ := ret[0].(<-chan azure.MemberObjectResult)
return ret0
}
// ListAzureADGroupMembers indicates an expected call of ListAzureADGroupMembers.
-func (mr *MockAzureClientMockRecorder) ListAzureADGroupMembers(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureADGroupMembers(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADGroupMembers", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADGroupMembers), arg0, arg1, arg2, arg3, arg4, arg5)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADGroupMembers", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADGroupMembers), arg0, arg1, arg2)
}
// ListAzureADGroupOwners mocks base method.
-func (m *MockAzureClient) ListAzureADGroupOwners(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string) <-chan azure.GroupOwnerResult {
+func (m *MockAzureClient) ListAzureADGroupOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan azure.GroupOwnerResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureADGroupOwners", arg0, arg1, arg2, arg3, arg4, arg5)
+ ret := m.ctrl.Call(m, "ListAzureADGroupOwners", arg0, arg1, arg2)
ret0, _ := ret[0].(<-chan azure.GroupOwnerResult)
return ret0
}
// ListAzureADGroupOwners indicates an expected call of ListAzureADGroupOwners.
-func (mr *MockAzureClientMockRecorder) ListAzureADGroupOwners(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureADGroupOwners(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADGroupOwners", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADGroupOwners), arg0, arg1, arg2, arg3, arg4, arg5)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADGroupOwners", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADGroupOwners), arg0, arg1, arg2)
}
// ListAzureADGroups mocks base method.
-func (m *MockAzureClient) ListAzureADGroups(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string) <-chan azure.GroupResult {
+func (m *MockAzureClient) ListAzureADGroups(arg0 context.Context, arg1 query.GraphParams) <-chan azure.GroupResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureADGroups", arg0, arg1, arg2, arg3, arg4, arg5)
+ ret := m.ctrl.Call(m, "ListAzureADGroups", arg0, arg1)
ret0, _ := ret[0].(<-chan azure.GroupResult)
return ret0
}
// ListAzureADGroups indicates an expected call of ListAzureADGroups.
-func (mr *MockAzureClientMockRecorder) ListAzureADGroups(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureADGroups(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADGroups", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADGroups), arg0, arg1, arg2, arg3, arg4, arg5)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADGroups", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADGroups), arg0, arg1)
}
// ListAzureADRoleAssignments mocks base method.
-func (m *MockAzureClient) ListAzureADRoleAssignments(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string) <-chan azure.UnifiedRoleAssignmentResult {
+func (m *MockAzureClient) ListAzureADRoleAssignments(arg0 context.Context, arg1 query.GraphParams) <-chan azure.UnifiedRoleAssignmentResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureADRoleAssignments", arg0, arg1, arg2, arg3, arg4, arg5)
+ ret := m.ctrl.Call(m, "ListAzureADRoleAssignments", arg0, arg1)
ret0, _ := ret[0].(<-chan azure.UnifiedRoleAssignmentResult)
return ret0
}
// ListAzureADRoleAssignments indicates an expected call of ListAzureADRoleAssignments.
-func (mr *MockAzureClientMockRecorder) ListAzureADRoleAssignments(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureADRoleAssignments(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADRoleAssignments", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADRoleAssignments), arg0, arg1, arg2, arg3, arg4, arg5)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADRoleAssignments", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADRoleAssignments), arg0, arg1)
}
// ListAzureADRoles mocks base method.
-func (m *MockAzureClient) ListAzureADRoles(arg0 context.Context, arg1, arg2 string) <-chan azure.RoleResult {
+func (m *MockAzureClient) ListAzureADRoles(arg0 context.Context, arg1 string) <-chan azure.RoleResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureADRoles", arg0, arg1, arg2)
+ ret := m.ctrl.Call(m, "ListAzureADRoles", arg0, arg1)
ret0, _ := ret[0].(<-chan azure.RoleResult)
return ret0
}
// ListAzureADRoles indicates an expected call of ListAzureADRoles.
-func (mr *MockAzureClientMockRecorder) ListAzureADRoles(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureADRoles(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADRoles", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADRoles), arg0, arg1, arg2)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADRoles", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADRoles), arg0, arg1)
}
// ListAzureADServicePrincipalOwners mocks base method.
-func (m *MockAzureClient) ListAzureADServicePrincipalOwners(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string) <-chan azure.ServicePrincipalOwnerResult {
+func (m *MockAzureClient) ListAzureADServicePrincipalOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan azure.ServicePrincipalOwnerResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureADServicePrincipalOwners", arg0, arg1, arg2, arg3, arg4, arg5)
+ ret := m.ctrl.Call(m, "ListAzureADServicePrincipalOwners", arg0, arg1, arg2)
ret0, _ := ret[0].(<-chan azure.ServicePrincipalOwnerResult)
return ret0
}
// ListAzureADServicePrincipalOwners indicates an expected call of ListAzureADServicePrincipalOwners.
-func (mr *MockAzureClientMockRecorder) ListAzureADServicePrincipalOwners(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureADServicePrincipalOwners(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADServicePrincipalOwners", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADServicePrincipalOwners), arg0, arg1, arg2, arg3, arg4, arg5)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADServicePrincipalOwners", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADServicePrincipalOwners), arg0, arg1, arg2)
}
// ListAzureADServicePrincipals mocks base method.
-func (m *MockAzureClient) ListAzureADServicePrincipals(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string) <-chan azure.ServicePrincipalResult {
+func (m *MockAzureClient) ListAzureADServicePrincipals(arg0 context.Context, arg1 query.GraphParams) <-chan azure.ServicePrincipalResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureADServicePrincipals", arg0, arg1, arg2, arg3, arg4, arg5)
+ ret := m.ctrl.Call(m, "ListAzureADServicePrincipals", arg0, arg1)
ret0, _ := ret[0].(<-chan azure.ServicePrincipalResult)
return ret0
}
// ListAzureADServicePrincipals indicates an expected call of ListAzureADServicePrincipals.
-func (mr *MockAzureClientMockRecorder) ListAzureADServicePrincipals(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureADServicePrincipals(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADServicePrincipals", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADServicePrincipals), arg0, arg1, arg2, arg3, arg4, arg5)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADServicePrincipals", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADServicePrincipals), arg0, arg1)
}
// ListAzureADTenants mocks base method.
@@ -712,17 +638,17 @@ func (mr *MockAzureClientMockRecorder) ListAzureADTenants(arg0, arg1 interface{}
}
// ListAzureADUsers mocks base method.
-func (m *MockAzureClient) ListAzureADUsers(arg0 context.Context, arg1, arg2, arg3 string, arg4 []string) <-chan azure.UserResult {
+func (m *MockAzureClient) ListAzureADUsers(arg0 context.Context, arg1 query.GraphParams) <-chan azure.UserResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureADUsers", arg0, arg1, arg2, arg3, arg4)
+ ret := m.ctrl.Call(m, "ListAzureADUsers", arg0, arg1)
ret0, _ := ret[0].(<-chan azure.UserResult)
return ret0
}
// ListAzureADUsers indicates an expected call of ListAzureADUsers.
-func (mr *MockAzureClientMockRecorder) ListAzureADUsers(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureADUsers(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADUsers", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADUsers), arg0, arg1, arg2, arg3, arg4)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureADUsers", reflect.TypeOf((*MockAzureClient)(nil).ListAzureADUsers), arg0, arg1)
}
// ListAzureAutomationAccounts mocks base method.
@@ -754,7 +680,7 @@ func (mr *MockAzureClientMockRecorder) ListAzureContainerRegistries(arg0, arg1 i
}
// ListAzureDeviceRegisteredOwners mocks base method.
-func (m *MockAzureClient) ListAzureDeviceRegisteredOwners(arg0 context.Context, arg1 string, arg2 bool) <-chan azure.DeviceRegisteredOwnerResult {
+func (m *MockAzureClient) ListAzureDeviceRegisteredOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan azure.DeviceRegisteredOwnerResult {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureDeviceRegisteredOwners", arg0, arg1, arg2)
ret0, _ := ret[0].(<-chan azure.DeviceRegisteredOwnerResult)
@@ -768,17 +694,17 @@ func (mr *MockAzureClientMockRecorder) ListAzureDeviceRegisteredOwners(arg0, arg
}
// ListAzureDevices mocks base method.
-func (m *MockAzureClient) ListAzureDevices(arg0 context.Context, arg1, arg2, arg3, arg4 string, arg5 []string) <-chan azure.DeviceResult {
+func (m *MockAzureClient) ListAzureDevices(arg0 context.Context, arg1 query.GraphParams) <-chan azure.DeviceResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureDevices", arg0, arg1, arg2, arg3, arg4, arg5)
+ ret := m.ctrl.Call(m, "ListAzureDevices", arg0, arg1)
ret0, _ := ret[0].(<-chan azure.DeviceResult)
return ret0
}
// ListAzureDevices indicates an expected call of ListAzureDevices.
-func (mr *MockAzureClientMockRecorder) ListAzureDevices(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureDevices(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureDevices", reflect.TypeOf((*MockAzureClient)(nil).ListAzureDevices), arg0, arg1, arg2, arg3, arg4, arg5)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureDevices", reflect.TypeOf((*MockAzureClient)(nil).ListAzureDevices), arg0, arg1)
}
// ListAzureFunctionApps mocks base method.
@@ -796,7 +722,7 @@ func (mr *MockAzureClientMockRecorder) ListAzureFunctionApps(arg0, arg1 interfac
}
// ListAzureKeyVaults mocks base method.
-func (m *MockAzureClient) ListAzureKeyVaults(arg0 context.Context, arg1 string, arg2 int32) <-chan azure.KeyVaultResult {
+func (m *MockAzureClient) ListAzureKeyVaults(arg0 context.Context, arg1 string, arg2 query.RMParams) <-chan azure.KeyVaultResult {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureKeyVaults", arg0, arg1, arg2)
ret0, _ := ret[0].(<-chan azure.KeyVaultResult)
@@ -824,49 +750,49 @@ func (mr *MockAzureClientMockRecorder) ListAzureLogicApps(arg0, arg1, arg2, arg3
}
// ListAzureManagedClusters mocks base method.
-func (m *MockAzureClient) ListAzureManagedClusters(arg0 context.Context, arg1 string, arg2 bool) <-chan azure.ManagedClusterResult {
+func (m *MockAzureClient) ListAzureManagedClusters(arg0 context.Context, arg1 string) <-chan azure.ManagedClusterResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureManagedClusters", arg0, arg1, arg2)
+ ret := m.ctrl.Call(m, "ListAzureManagedClusters", arg0, arg1)
ret0, _ := ret[0].(<-chan azure.ManagedClusterResult)
return ret0
}
// ListAzureManagedClusters indicates an expected call of ListAzureManagedClusters.
-func (mr *MockAzureClientMockRecorder) ListAzureManagedClusters(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureManagedClusters(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureManagedClusters", reflect.TypeOf((*MockAzureClient)(nil).ListAzureManagedClusters), arg0, arg1, arg2)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureManagedClusters", reflect.TypeOf((*MockAzureClient)(nil).ListAzureManagedClusters), arg0, arg1)
}
// ListAzureManagementGroupDescendants mocks base method.
-func (m *MockAzureClient) ListAzureManagementGroupDescendants(arg0 context.Context, arg1 string) <-chan azure.DescendantInfoResult {
+func (m *MockAzureClient) ListAzureManagementGroupDescendants(arg0 context.Context, arg1 string, arg2 int32) <-chan azure.DescendantInfoResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureManagementGroupDescendants", arg0, arg1)
+ ret := m.ctrl.Call(m, "ListAzureManagementGroupDescendants", arg0, arg1, arg2)
ret0, _ := ret[0].(<-chan azure.DescendantInfoResult)
return ret0
}
// ListAzureManagementGroupDescendants indicates an expected call of ListAzureManagementGroupDescendants.
-func (mr *MockAzureClientMockRecorder) ListAzureManagementGroupDescendants(arg0, arg1 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureManagementGroupDescendants(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureManagementGroupDescendants", reflect.TypeOf((*MockAzureClient)(nil).ListAzureManagementGroupDescendants), arg0, arg1)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureManagementGroupDescendants", reflect.TypeOf((*MockAzureClient)(nil).ListAzureManagementGroupDescendants), arg0, arg1, arg2)
}
// ListAzureManagementGroups mocks base method.
-func (m *MockAzureClient) ListAzureManagementGroups(arg0 context.Context) <-chan azure.ManagementGroupResult {
+func (m *MockAzureClient) ListAzureManagementGroups(arg0 context.Context, arg1 string) <-chan azure.ManagementGroupResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureManagementGroups", arg0)
+ ret := m.ctrl.Call(m, "ListAzureManagementGroups", arg0, arg1)
ret0, _ := ret[0].(<-chan azure.ManagementGroupResult)
return ret0
}
// ListAzureManagementGroups indicates an expected call of ListAzureManagementGroups.
-func (mr *MockAzureClientMockRecorder) ListAzureManagementGroups(arg0 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureManagementGroups(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureManagementGroups", reflect.TypeOf((*MockAzureClient)(nil).ListAzureManagementGroups), arg0)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureManagementGroups", reflect.TypeOf((*MockAzureClient)(nil).ListAzureManagementGroups), arg0, arg1)
}
// ListAzureResourceGroups mocks base method.
-func (m *MockAzureClient) ListAzureResourceGroups(arg0 context.Context, arg1, arg2 string) <-chan azure.ResourceGroupResult {
+func (m *MockAzureClient) ListAzureResourceGroups(arg0 context.Context, arg1 string, arg2 query.RMParams) <-chan azure.ResourceGroupResult {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureResourceGroups", arg0, arg1, arg2)
ret0, _ := ret[0].(<-chan azure.ResourceGroupResult)
@@ -922,21 +848,21 @@ func (mr *MockAzureClientMockRecorder) ListAzureSubscriptions(arg0 interface{})
}
// ListAzureVMScaleSets mocks base method.
-func (m *MockAzureClient) ListAzureVMScaleSets(arg0 context.Context, arg1 string, arg2 bool) <-chan azure.VMScaleSetResult {
+func (m *MockAzureClient) ListAzureVMScaleSets(arg0 context.Context, arg1 string) <-chan azure.VMScaleSetResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListAzureVMScaleSets", arg0, arg1, arg2)
+ ret := m.ctrl.Call(m, "ListAzureVMScaleSets", arg0, arg1)
ret0, _ := ret[0].(<-chan azure.VMScaleSetResult)
return ret0
}
// ListAzureVMScaleSets indicates an expected call of ListAzureVMScaleSets.
-func (mr *MockAzureClientMockRecorder) ListAzureVMScaleSets(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListAzureVMScaleSets(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureVMScaleSets", reflect.TypeOf((*MockAzureClient)(nil).ListAzureVMScaleSets), arg0, arg1, arg2)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureVMScaleSets", reflect.TypeOf((*MockAzureClient)(nil).ListAzureVMScaleSets), arg0, arg1)
}
// ListAzureVirtualMachines mocks base method.
-func (m *MockAzureClient) ListAzureVirtualMachines(arg0 context.Context, arg1 string, arg2 bool) <-chan azure.VirtualMachineResult {
+func (m *MockAzureClient) ListAzureVirtualMachines(arg0 context.Context, arg1 string, arg2 query.RMParams) <-chan azure.VirtualMachineResult {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureVirtualMachines", arg0, arg1, arg2)
ret0, _ := ret[0].(<-chan azure.VirtualMachineResult)
@@ -963,32 +889,18 @@ func (mr *MockAzureClientMockRecorder) ListAzureWebApps(arg0, arg1 interface{})
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAzureWebApps", reflect.TypeOf((*MockAzureClient)(nil).ListAzureWebApps), arg0, arg1)
}
-// ListResourceRoleAssignments mocks base method.
-func (m *MockAzureClient) ListResourceRoleAssignments(arg0 context.Context, arg1, arg2, arg3 string) <-chan azure.RoleAssignmentResult {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListResourceRoleAssignments", arg0, arg1, arg2, arg3)
- ret0, _ := ret[0].(<-chan azure.RoleAssignmentResult)
- return ret0
-}
-
-// ListResourceRoleAssignments indicates an expected call of ListResourceRoleAssignments.
-func (mr *MockAzureClientMockRecorder) ListResourceRoleAssignments(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListResourceRoleAssignments", reflect.TypeOf((*MockAzureClient)(nil).ListResourceRoleAssignments), arg0, arg1, arg2, arg3)
-}
-
// ListRoleAssignmentsForResource mocks base method.
-func (m *MockAzureClient) ListRoleAssignmentsForResource(arg0 context.Context, arg1, arg2 string) <-chan azure.RoleAssignmentResult {
+func (m *MockAzureClient) ListRoleAssignmentsForResource(arg0 context.Context, arg1, arg2, arg3 string) <-chan azure.RoleAssignmentResult {
m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "ListRoleAssignmentsForResource", arg0, arg1, arg2)
+ ret := m.ctrl.Call(m, "ListRoleAssignmentsForResource", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(<-chan azure.RoleAssignmentResult)
return ret0
}
// ListRoleAssignmentsForResource indicates an expected call of ListRoleAssignmentsForResource.
-func (mr *MockAzureClientMockRecorder) ListRoleAssignmentsForResource(arg0, arg1, arg2 interface{}) *gomock.Call {
+func (mr *MockAzureClientMockRecorder) ListRoleAssignmentsForResource(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListRoleAssignmentsForResource", reflect.TypeOf((*MockAzureClient)(nil).ListRoleAssignmentsForResource), arg0, arg1, arg2)
+ return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListRoleAssignmentsForResource", reflect.TypeOf((*MockAzureClient)(nil).ListRoleAssignmentsForResource), arg0, arg1, arg2, arg3)
}
// TenantInfo mocks base method.
diff --git a/client/query/params.go b/client/query/params.go
index f203ecb..3378ab5 100644
--- a/client/query/params.go
+++ b/client/query/params.go
@@ -38,38 +38,40 @@ const (
Skip string = "$skip"
SkipToken string = "$skipToken"
StatusOnly string = "StatusOnly"
+ TenantId string = "tenantId"
Top string = "$top"
)
-type Params struct {
+type Params interface {
+ AsMap() map[string]string
+ NeedsEventualConsistencyHeaderFlag() bool
+}
+
+type RMParams struct {
ApiVersion string
- Count bool
Expand string
Filter string
IncludeDeleted string
IncludeAllTenantCategories bool
MaxPageSize string
- OrderBy string
Recurse bool
- Search string
- Select []string
- Skip int
SkipToken string
StatusOnly bool
+ TenantId string // For cross-tenant request
Top int32
}
-func (s Params) AsMap() map[string]string {
+func (s RMParams) NeedsEventualConsistencyHeaderFlag() bool {
+ return false
+}
+
+func (s RMParams) AsMap() map[string]string {
params := make(map[string]string)
if s.ApiVersion != "" {
params[ApiVersion] = s.ApiVersion
}
- if s.Count {
- params[Count] = "true"
- }
-
if s.Expand != "" {
params[Expand] = s.Expand
}
@@ -82,14 +84,68 @@ func (s Params) AsMap() map[string]string {
params[IncludeAllTenantCategories] = "true"
}
- if s.OrderBy != "" {
- params[OrderBy] = s.OrderBy
- }
-
if s.Recurse {
params[Recurse] = "true"
}
+ if s.SkipToken != "" {
+ params[SkipToken] = s.SkipToken
+ }
+
+ if s.StatusOnly {
+ params[StatusOnly] = "true"
+ }
+
+ if s.TenantId != "" {
+ params[TenantId] = s.TenantId
+ }
+ if s.Top > 0 {
+ params[Top] = strconv.FormatInt(int64(s.Top), 10)
+ }
+
+ return params
+}
+
+type GraphParams struct {
+ Count bool
+ Expand string
+ Format string
+ Filter string
+ OrderBy string
+ Search string
+ Select []string
+ Skip int
+ Top int32
+ SkipToken string
+}
+
+func (s GraphParams) NeedsEventualConsistencyHeaderFlag() bool {
+ return s.Count || s.Search != "" || s.OrderBy != "" || (s.Filter != "" && s.OrderBy != "") || strings.Contains(s.Filter, "endsWith")
+}
+
+func (s GraphParams) AsMap() map[string]string {
+ params := make(map[string]string)
+
+ if s.Count {
+ params[Count] = "true"
+ }
+
+ if s.Expand != "" {
+ params[Expand] = s.Expand
+ }
+
+ if s.Format != "" {
+ params[Format] = s.Format
+ }
+
+ if s.Filter != "" {
+ params[Filter] = s.Filter
+ }
+
+ if s.OrderBy != "" {
+ params[OrderBy] = s.OrderBy
+ }
+
if s.Search != "" {
params[Search] = s.Search
}
@@ -106,10 +162,6 @@ func (s Params) AsMap() map[string]string {
params[SkipToken] = s.SkipToken
}
- if s.StatusOnly {
- params[StatusOnly] = "true"
- }
-
if s.Top > 0 {
params[Top] = strconv.FormatInt(int64(s.Top), 10)
}
diff --git a/client/resource_groups.go b/client/resource_groups.go
index c693fc4..543dfa8 100644
--- a/client/resource_groups.go
+++ b/client/resource_groups.go
@@ -29,31 +29,17 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureResourceGroup(ctx context.Context, subscriptionId, groupName string) (*azure.ResourceGroup, error) {
- var (
- path = fmt.Sprintf("/subscriptions/%s/resourcegroups/%s", subscriptionId, groupName)
- params = query.Params{ApiVersion: "2021-04-01"}.AsMap()
- headers map[string]string
- response azure.ResourceGroup
- )
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
-func (s *azureClient) GetAzureResourceGroups(ctx context.Context, subscriptionId string, filter string, top int32) (azure.ResourceGroupList, error) {
+func (s *azureClient) GetAzureResourceGroups(ctx context.Context, subscriptionId string, params query.RMParams) (azure.ResourceGroupList, error) {
var (
path = fmt.Sprintf("/subscriptions/%s/resourcegroups", subscriptionId)
- params = query.Params{ApiVersion: "2021-04-01", Filter: filter, Top: top}.AsMap()
- headers map[string]string
response azure.ResourceGroupList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if params.ApiVersion == "" {
+ params.ApiVersion = "2021-04-01"
+ }
+
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -62,7 +48,7 @@ func (s *azureClient) GetAzureResourceGroups(ctx context.Context, subscriptionId
}
}
-func (s *azureClient) ListAzureResourceGroups(ctx context.Context, subscriptionId, filter string) <-chan azure.ResourceGroupResult {
+func (s *azureClient) ListAzureResourceGroups(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azure.ResourceGroupResult {
out := make(chan azure.ResourceGroupResult)
go func() {
@@ -75,7 +61,7 @@ func (s *azureClient) ListAzureResourceGroups(ctx context.Context, subscriptionI
nextLink string
)
- if result, err := s.GetAzureResourceGroups(ctx, subscriptionId, filter, 1000); err != nil {
+ if result, err := s.GetAzureResourceGroups(ctx, subscriptionId, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
diff --git a/client/rest/client.go b/client/rest/client.go
index 919edc4..33b96ff 100644
--- a/client/rest/client.go
+++ b/client/rest/client.go
@@ -32,16 +32,17 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client/config"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/constants"
)
type RestClient interface {
Authenticate() error
- Delete(ctx context.Context, path string, body interface{}, params, headers map[string]string) (*http.Response, error)
- Get(ctx context.Context, path string, params, headers map[string]string) (*http.Response, error)
- Patch(ctx context.Context, path string, body interface{}, params, headers map[string]string) (*http.Response, error)
- Post(ctx context.Context, path string, body interface{}, params, headers map[string]string) (*http.Response, error)
- Put(ctx context.Context, path string, body interface{}, params, headers map[string]string) (*http.Response, error)
+ Delete(ctx context.Context, path string, body interface{}, params query.Params, headers map[string]string) (*http.Response, error)
+ Get(ctx context.Context, path string, params query.Params, headers map[string]string) (*http.Response, error)
+ Patch(ctx context.Context, path string, body interface{}, params query.Params, headers map[string]string) (*http.Response, error)
+ Post(ctx context.Context, path string, body interface{}, params query.Params, headers map[string]string) (*http.Response, error)
+ Put(ctx context.Context, path string, body interface{}, params query.Params, headers map[string]string) (*http.Response, error)
Send(req *http.Request) (*http.Response, error)
CloseIdleConnections()
}
@@ -154,45 +155,53 @@ func (s *restClient) Authenticate() error {
}
}
-func (s *restClient) Delete(ctx context.Context, path string, body interface{}, params, headers map[string]string) (*http.Response, error) {
+func (s *restClient) Delete(ctx context.Context, path string, body interface{}, params query.Params, headers map[string]string) (*http.Response, error) {
endpoint := s.api.ResolveReference(&url.URL{Path: path})
- if req, err := NewRequest(ctx, http.MethodDelete, endpoint, body, params, headers); err != nil {
+ if req, err := NewRequest(ctx, http.MethodDelete, endpoint, body, params.AsMap(), headers); err != nil {
return nil, err
} else {
return s.Send(req)
}
}
-func (s *restClient) Get(ctx context.Context, path string, params, headers map[string]string) (*http.Response, error) {
+func (s *restClient) Get(ctx context.Context, path string, params query.Params, headers map[string]string) (*http.Response, error) {
endpoint := s.api.ResolveReference(&url.URL{Path: path})
- if req, err := NewRequest(ctx, http.MethodGet, endpoint, nil, params, headers); err != nil {
+
+ if params.NeedsEventualConsistencyHeaderFlag() {
+ if headers == nil {
+ headers = make(map[string]string)
+ }
+ headers["ConsistencyLevel"] = "eventual"
+ }
+
+ if req, err := NewRequest(ctx, http.MethodGet, endpoint, nil, params.AsMap(), headers); err != nil {
return nil, err
} else {
return s.Send(req)
}
}
-func (s *restClient) Patch(ctx context.Context, path string, body interface{}, params, headers map[string]string) (*http.Response, error) {
+func (s *restClient) Patch(ctx context.Context, path string, body interface{}, params query.Params, headers map[string]string) (*http.Response, error) {
endpoint := s.api.ResolveReference(&url.URL{Path: path})
- if req, err := NewRequest(ctx, http.MethodPatch, endpoint, body, params, headers); err != nil {
+ if req, err := NewRequest(ctx, http.MethodPatch, endpoint, body, params.AsMap(), headers); err != nil {
return nil, err
} else {
return s.Send(req)
}
}
-func (s *restClient) Post(ctx context.Context, path string, body interface{}, params, headers map[string]string) (*http.Response, error) {
+func (s *restClient) Post(ctx context.Context, path string, body interface{}, params query.Params, headers map[string]string) (*http.Response, error) {
endpoint := s.api.ResolveReference(&url.URL{Path: path})
- if req, err := NewRequest(ctx, http.MethodPost, endpoint, body, params, headers); err != nil {
+ if req, err := NewRequest(ctx, http.MethodPost, endpoint, body, params.AsMap(), headers); err != nil {
return nil, err
} else {
return s.Send(req)
}
}
-func (s *restClient) Put(ctx context.Context, path string, body interface{}, params, headers map[string]string) (*http.Response, error) {
+func (s *restClient) Put(ctx context.Context, path string, body interface{}, params query.Params, headers map[string]string) (*http.Response, error) {
endpoint := s.api.ResolveReference(&url.URL{Path: path})
- if req, err := NewRequest(ctx, http.MethodPost, endpoint, body, params, headers); err != nil {
+ if req, err := NewRequest(ctx, http.MethodPost, endpoint, body, params.AsMap(), headers); err != nil {
return nil, err
} else {
return s.Send(req)
diff --git a/client/rest/mocks/client.go b/client/rest/mocks/client.go
index b9df20b..6c2f7ae 100644
--- a/client/rest/mocks/client.go
+++ b/client/rest/mocks/client.go
@@ -9,6 +9,7 @@ import (
http "net/http"
reflect "reflect"
+ query "github.com/bloodhoundad/azurehound/v2/client/query"
gomock "go.uber.org/mock/gomock"
)
@@ -62,7 +63,7 @@ func (mr *MockRestClientMockRecorder) CloseIdleConnections() *gomock.Call {
}
// Delete mocks base method.
-func (m *MockRestClient) Delete(arg0 context.Context, arg1 string, arg2 interface{}, arg3, arg4 map[string]string) (*http.Response, error) {
+func (m *MockRestClient) Delete(arg0 context.Context, arg1 string, arg2 interface{}, arg3 query.Params, arg4 map[string]string) (*http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Delete", arg0, arg1, arg2, arg3, arg4)
ret0, _ := ret[0].(*http.Response)
@@ -77,7 +78,7 @@ func (mr *MockRestClientMockRecorder) Delete(arg0, arg1, arg2, arg3, arg4 interf
}
// Get mocks base method.
-func (m *MockRestClient) Get(arg0 context.Context, arg1 string, arg2, arg3 map[string]string) (*http.Response, error) {
+func (m *MockRestClient) Get(arg0 context.Context, arg1 string, arg2 query.Params, arg3 map[string]string) (*http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Get", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(*http.Response)
@@ -92,7 +93,7 @@ func (mr *MockRestClientMockRecorder) Get(arg0, arg1, arg2, arg3 interface{}) *g
}
// Patch mocks base method.
-func (m *MockRestClient) Patch(arg0 context.Context, arg1 string, arg2 interface{}, arg3, arg4 map[string]string) (*http.Response, error) {
+func (m *MockRestClient) Patch(arg0 context.Context, arg1 string, arg2 interface{}, arg3 query.Params, arg4 map[string]string) (*http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Patch", arg0, arg1, arg2, arg3, arg4)
ret0, _ := ret[0].(*http.Response)
@@ -107,7 +108,7 @@ func (mr *MockRestClientMockRecorder) Patch(arg0, arg1, arg2, arg3, arg4 interfa
}
// Post mocks base method.
-func (m *MockRestClient) Post(arg0 context.Context, arg1 string, arg2 interface{}, arg3, arg4 map[string]string) (*http.Response, error) {
+func (m *MockRestClient) Post(arg0 context.Context, arg1 string, arg2 interface{}, arg3 query.Params, arg4 map[string]string) (*http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Post", arg0, arg1, arg2, arg3, arg4)
ret0, _ := ret[0].(*http.Response)
@@ -122,7 +123,7 @@ func (mr *MockRestClientMockRecorder) Post(arg0, arg1, arg2, arg3, arg4 interfac
}
// Put mocks base method.
-func (m *MockRestClient) Put(arg0 context.Context, arg1 string, arg2 interface{}, arg3, arg4 map[string]string) (*http.Response, error) {
+func (m *MockRestClient) Put(arg0 context.Context, arg1 string, arg2 interface{}, arg3 query.Params, arg4 map[string]string) (*http.Response, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Put", arg0, arg1, arg2, arg3, arg4)
ret0, _ := ret[0].(*http.Response)
diff --git a/client/role_assignments.go b/client/role_assignments.go
index 34f7da1..ab6f873 100644
--- a/client/role_assignments.go
+++ b/client/role_assignments.go
@@ -21,7 +21,6 @@ import (
"context"
"fmt"
"net/url"
- "strings"
"github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/client/rest"
@@ -31,35 +30,17 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureADRoleAssignment(ctx context.Context, objectId string, selectCols []string) (*azure.UnifiedRoleAssignment, error) {
- var (
- path = fmt.Sprintf("/%s/roleManagement/directory/roleAssignments/%s", constants.GraphApiVersion, objectId)
- params = query.Params{Select: selectCols}.AsMap()
- response azure.UnifiedRoleAssignment
- )
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
-func (s *azureClient) GetAzureADRoleAssignments(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.UnifiedRoleAssignmentList, error) {
+func (s *azureClient) GetAzureADRoleAssignments(ctx context.Context, params query.GraphParams) (azure.UnifiedRoleAssignmentList, error) {
var (
path = fmt.Sprintf("/%s/roleManagement/directory/roleAssignments", constants.GraphApiVersion)
- params = query.Params{Filter: filter, Search: search, OrderBy: orderBy, Select: selectCols, Top: top, Count: count, Expand: expand}
- headers map[string]string
response azure.UnifiedRoleAssignmentList
)
- count = count || search != "" || (filter != "" && orderBy != "") || strings.Contains(filter, "endsWith")
- if count {
- headers = make(map[string]string)
- headers["ConsistencyLevel"] = "eventual"
+ if params.Top == 0 {
+ params.Top = 999
}
- if res, err := s.msgraph.Get(ctx, path, params.AsMap(), headers); err != nil {
+
+ if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -68,7 +49,7 @@ func (s *azureClient) GetAzureADRoleAssignments(ctx context.Context, filter, sea
}
}
-func (s *azureClient) ListAzureADRoleAssignments(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.UnifiedRoleAssignmentResult {
+func (s *azureClient) ListAzureADRoleAssignments(ctx context.Context, params query.GraphParams) <-chan azure.UnifiedRoleAssignmentResult {
out := make(chan azure.UnifiedRoleAssignmentResult)
go func() {
@@ -80,7 +61,7 @@ func (s *azureClient) ListAzureADRoleAssignments(ctx context.Context, filter, se
nextLink string
)
- if list, err := s.GetAzureADRoleAssignments(ctx, filter, search, orderBy, expand, selectCols, 999, false); err != nil {
+ if list, err := s.GetAzureADRoleAssignments(ctx, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
@@ -133,15 +114,14 @@ func (s *azureClient) ListAzureADRoleAssignments(ctx context.Context, filter, se
return out
}
-func (s *azureClient) GetRoleAssignmentsForResource(ctx context.Context, resourceId string, filter string) (azure.RoleAssignmentList, error) {
+func (s *azureClient) GetRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) (azure.RoleAssignmentList, error) {
var (
path = fmt.Sprintf("%s/providers/Microsoft.Authorization/roleAssignments", resourceId)
- params = query.Params{ApiVersion: "2015-07-01", Filter: filter}.AsMap()
- headers map[string]string
+ params = query.RMParams{ApiVersion: "2015-07-01", Filter: filter, TenantId: tenantId}
response azure.RoleAssignmentList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -151,7 +131,7 @@ func (s *azureClient) GetRoleAssignmentsForResource(ctx context.Context, resourc
}
-func (s *azureClient) ListRoleAssignmentsForResource(ctx context.Context, resourceId string, filter string) <-chan azure.RoleAssignmentResult {
+func (s *azureClient) ListRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) <-chan azure.RoleAssignmentResult {
out := make(chan azure.RoleAssignmentResult)
go func() {
@@ -163,7 +143,7 @@ func (s *azureClient) ListRoleAssignmentsForResource(ctx context.Context, resour
nextLink string
)
- if result, err := s.GetRoleAssignmentsForResource(ctx, resourceId, filter); err != nil {
+ if result, err := s.GetRoleAssignmentsForResource(ctx, resourceId, filter, tenantId); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
@@ -221,91 +201,3 @@ func (s *azureClient) ListRoleAssignmentsForResource(ctx context.Context, resour
}()
return out
}
-
-func (s *azureClient) GetResourceRoleAssignments(ctx context.Context, subscriptionId string, filter string, expand string) (azure.RoleAssignmentList, error) {
- var (
- path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Authorization/roleAssignments", subscriptionId)
- params = query.Params{ApiVersion: "2015-07-01", Filter: filter, Expand: expand}.AsMap()
- headers map[string]string
- response azure.RoleAssignmentList
- )
-
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListResourceRoleAssignments(ctx context.Context, subscriptionId string, filter string, expand string) <-chan azure.RoleAssignmentResult {
- out := make(chan azure.RoleAssignmentResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.RoleAssignmentResult{ParentId: subscriptionId}
- nextLink string
- )
-
- if result, err := s.GetResourceRoleAssignments(ctx, subscriptionId, filter, expand); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.RoleAssignmentResult{
- ParentId: subscriptionId,
- Ok: u,
- }); !ok {
- return
- }
- }
-
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.RoleAssignmentList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.RoleAssignmentResult{
- ParentId: subscriptionId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
- return out
-}
diff --git a/client/roles.go b/client/roles.go
index 1f6fd5a..87fccd6 100644
--- a/client/roles.go
+++ b/client/roles.go
@@ -30,30 +30,13 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureADRole(ctx context.Context, roleId string, selectCols []string) (*azure.Role, error) {
- var (
- path = fmt.Sprintf("/%s/roleManagement/directory/roleDefinitions/%s", constants.GraphApiVersion, roleId)
- params = query.Params{Select: selectCols}.AsMap()
- response azure.RoleList
- )
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response.Value[0], nil
- }
-}
-
-func (s *azureClient) GetAzureADRoles(ctx context.Context, filter, expand string) (azure.RoleList, error) {
+func (s *azureClient) GetAzureADRoles(ctx context.Context, filter string) (azure.RoleList, error) {
var (
path = fmt.Sprintf("/%s/roleManagement/directory/roleDefinitions", constants.GraphApiVersion)
- params = query.Params{Filter: filter, Expand: expand}
- headers map[string]string
response azure.RoleList
)
- if res, err := s.msgraph.Get(ctx, path, params.AsMap(), headers); err != nil {
+ if res, err := s.msgraph.Get(ctx, path, query.GraphParams{Filter: filter}, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -62,7 +45,7 @@ func (s *azureClient) GetAzureADRoles(ctx context.Context, filter, expand string
}
}
-func (s *azureClient) ListAzureADRoles(ctx context.Context, filter, expand string) <-chan azure.RoleResult {
+func (s *azureClient) ListAzureADRoles(ctx context.Context, filter string) <-chan azure.RoleResult {
out := make(chan azure.RoleResult)
go func() {
@@ -74,7 +57,7 @@ func (s *azureClient) ListAzureADRoles(ctx context.Context, filter, expand strin
nextLink string
)
- if users, err := s.GetAzureADRoles(ctx, filter, expand); err != nil {
+ if users, err := s.GetAzureADRoles(ctx, filter); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
diff --git a/client/service_principals.go b/client/service_principals.go
index 9f8642e..1067d39 100644
--- a/client/service_principals.go
+++ b/client/service_principals.go
@@ -21,7 +21,6 @@ import (
"context"
"fmt"
"net/url"
- "strings"
"github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/client/rest"
@@ -31,27 +30,16 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureADServicePrincipal(ctx context.Context, objectId string, selectCols []string) (*azure.ServicePrincipal, error) {
- var (
- path = fmt.Sprintf("/%s/servicePrincipals/%s", constants.GraphApiVersion, objectId)
- params = query.Params{Select: selectCols}.AsMap()
- response azure.ServicePrincipalList
- )
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response.Value[0], nil
- }
-}
-
-func (s *azureClient) GetAzureADServicePrincipalOwners(ctx context.Context, objectId string, filter string, search string, orderBy string, selectCols []string, top int32, count bool) (azure.DirectoryObjectList, error) {
+func (s *azureClient) GetAzureADServicePrincipalOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error) {
var (
path = fmt.Sprintf("/%s/servicePrincipals/%s/owners", constants.GraphApiBetaVersion, objectId)
- params = query.Params{Filter: filter, Search: search, OrderBy: orderBy, Select: selectCols, Top: top, Count: count}.AsMap()
response azure.DirectoryObjectList
)
+
+ if params.Top == 0 {
+ params.Top = 999
+ }
+
if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
@@ -61,20 +49,17 @@ func (s *azureClient) GetAzureADServicePrincipalOwners(ctx context.Context, obje
}
}
-func (s *azureClient) GetAzureADServicePrincipals(ctx context.Context, filter, search, orderBy, expand string, selectCols []string, top int32, count bool) (azure.ServicePrincipalList, error) {
+func (s *azureClient) GetAzureADServicePrincipals(ctx context.Context, params query.GraphParams) (azure.ServicePrincipalList, error) {
var (
path = fmt.Sprintf("/%s/servicePrincipals", constants.GraphApiVersion)
- params = query.Params{Filter: filter, Search: search, OrderBy: orderBy, Select: selectCols, Top: top, Count: count, Expand: expand}
- headers map[string]string
response azure.ServicePrincipalList
)
- count = count || search != "" || (filter != "" && orderBy != "") || strings.Contains(filter, "endsWith")
- if count {
- headers = make(map[string]string)
- headers["ConsistencyLevel"] = "eventual"
+ if params.Top == 0 {
+ params.Top = 999
}
- if res, err := s.msgraph.Get(ctx, path, params.AsMap(), headers); err != nil {
+
+ if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -83,7 +68,7 @@ func (s *azureClient) GetAzureADServicePrincipals(ctx context.Context, filter, s
}
}
-func (s *azureClient) ListAzureADServicePrincipals(ctx context.Context, filter, search, orderBy, expand string, selectCols []string) <-chan azure.ServicePrincipalResult {
+func (s *azureClient) ListAzureADServicePrincipals(ctx context.Context, params query.GraphParams) <-chan azure.ServicePrincipalResult {
out := make(chan azure.ServicePrincipalResult)
go func() {
@@ -95,7 +80,7 @@ func (s *azureClient) ListAzureADServicePrincipals(ctx context.Context, filter,
nextLink string
)
- if list, err := s.GetAzureADServicePrincipals(ctx, filter, search, orderBy, expand, selectCols, 999, false); err != nil {
+ if list, err := s.GetAzureADServicePrincipals(ctx, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
@@ -148,7 +133,7 @@ func (s *azureClient) ListAzureADServicePrincipals(ctx context.Context, filter,
return out
}
-func (s *azureClient) ListAzureADServicePrincipalOwners(ctx context.Context, objectId string, filter, search, orderBy string, selectCols []string) <-chan azure.ServicePrincipalOwnerResult {
+func (s *azureClient) ListAzureADServicePrincipalOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.ServicePrincipalOwnerResult {
out := make(chan azure.ServicePrincipalOwnerResult)
go func() {
@@ -162,7 +147,7 @@ func (s *azureClient) ListAzureADServicePrincipalOwners(ctx context.Context, obj
nextLink string
)
- if list, err := s.GetAzureADServicePrincipalOwners(ctx, objectId, filter, search, orderBy, selectCols, 999, false); err != nil {
+ if list, err := s.GetAzureADServicePrincipalOwners(ctx, objectId, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
diff --git a/client/storage_accounts.go b/client/storage_accounts.go
index 920deb1..e08eda5 100644
--- a/client/storage_accounts.go
+++ b/client/storage_accounts.go
@@ -29,30 +29,13 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureStorageAccount(ctx context.Context, subscriptionId, groupName, saName, expand string) (*azure.StorageAccount, error) {
- var (
- path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s", subscriptionId, groupName, saName)
- params = query.Params{ApiVersion: "2021-07-01", Expand: expand}.AsMap()
- headers map[string]string
- response azure.StorageAccount
- )
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
func (s *azureClient) GetAzureStorageAccounts(ctx context.Context, subscriptionId string) (azure.StorageAccountList, error) {
var (
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Storage/storageAccounts", subscriptionId)
- params = query.Params{ApiVersion: "2022-05-01"}.AsMap()
- headers map[string]string
+ params = query.RMParams{ApiVersion: "2022-05-01"}
response azure.StorageAccountList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -135,30 +118,13 @@ func (s *azureClient) ListAzureStorageAccounts(ctx context.Context, subscription
// Storage containers
// ==
-func (s *azureClient) GetAzureStorageContainer(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, scName string, filter string, includeDeleted string, maxPageSize string) (*azure.StorageContainer, error) {
- var (
- path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s/blobServices/default/containers/%s", subscriptionId, resourceGroupName, saName, scName)
- params = query.Params{ApiVersion: "2022-05-01", Filter: filter, IncludeDeleted: includeDeleted, MaxPageSize: maxPageSize}.AsMap()
- headers map[string]string
- response azure.StorageContainer
- )
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
func (s *azureClient) GetAzureStorageContainers(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, filter string, includeDeleted string, maxPageSize string) (azure.StorageContainerList, error) {
var (
path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s/blobServices/default/containers", subscriptionId, resourceGroupName, saName)
- params = query.Params{ApiVersion: "2022-05-01", Filter: filter, IncludeDeleted: includeDeleted, MaxPageSize: maxPageSize}.AsMap()
- headers map[string]string
+ params = query.RMParams{ApiVersion: "2022-05-01", Filter: filter, IncludeDeleted: includeDeleted, MaxPageSize: maxPageSize}
response azure.StorageContainerList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
diff --git a/client/subscriptions.go b/client/subscriptions.go
index 877d18b..ed6b1fc 100644
--- a/client/subscriptions.go
+++ b/client/subscriptions.go
@@ -19,7 +19,6 @@ package client
import (
"context"
- "fmt"
"net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
@@ -29,31 +28,14 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureSubscription(ctx context.Context, objectId string) (*azure.Subscription, error) {
- var (
- path = fmt.Sprintf("/subscriptions/%s", objectId)
- params = query.Params{ApiVersion: "2020-01-01"}.AsMap()
- headers map[string]string
- response azure.Subscription
- )
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
func (s *azureClient) GetAzureSubscriptions(ctx context.Context) (azure.SubscriptionList, error) {
var (
path = "/subscriptions"
- params = query.Params{ApiVersion: "2020-01-01"}.AsMap()
- headers map[string]string
+ params = query.RMParams{ApiVersion: "2020-01-01"}
response azure.SubscriptionList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
diff --git a/client/tenants.go b/client/tenants.go
index 1584190..3963a29 100644
--- a/client/tenants.go
+++ b/client/tenants.go
@@ -33,10 +33,9 @@ import (
func (s *azureClient) GetAzureADOrganization(ctx context.Context, selectCols []string) (*azure.Organization, error) {
var (
path = fmt.Sprintf("/%s/organization", constants.GraphApiVersion)
- params = query.Params{Select: selectCols}.AsMap()
response azure.OrganizationList
)
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
+ if res, err := s.msgraph.Get(ctx, path, query.GraphParams{Select: selectCols}, nil); err != nil {
return nil, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return nil, err
@@ -48,7 +47,7 @@ func (s *azureClient) GetAzureADOrganization(ctx context.Context, selectCols []s
func (s *azureClient) GetAzureADTenants(ctx context.Context, includeAllTenantCategories bool) (azure.TenantList, error) {
var (
path = "/tenants"
- params = query.Params{ApiVersion: "2020-01-01", IncludeAllTenantCategories: includeAllTenantCategories}.AsMap()
+ params = query.RMParams{ApiVersion: "2020-01-01", IncludeAllTenantCategories: includeAllTenantCategories}
headers map[string]string
response azure.TenantList
)
diff --git a/client/users.go b/client/users.go
index cea543d..10a3913 100644
--- a/client/users.go
+++ b/client/users.go
@@ -21,7 +21,6 @@ import (
"context"
"fmt"
"net/url"
- "strings"
"github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/client/rest"
@@ -31,35 +30,16 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureADUser(ctx context.Context, objectId string, selectCols []string) (*azure.User, error) {
- var (
- path = fmt.Sprintf("/%s/users/%s", constants.GraphApiVersion, objectId)
- params = query.Params{Select: selectCols}.AsMap()
- response azure.UserList
- )
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response.Value[0], nil
- }
-}
-
-func (s *azureClient) GetAzureADUsers(ctx context.Context, filter string, search string, orderBy string, selectCols []string, top int32, count bool) (azure.UserList, error) {
+func (s *azureClient) GetAzureADUsers(ctx context.Context, params query.GraphParams) (azure.UserList, error) {
var (
path = fmt.Sprintf("/%s/users", constants.GraphApiVersion)
- params = query.Params{Filter: filter, Search: search, OrderBy: orderBy, Select: selectCols, Top: top, Count: count}
- headers map[string]string
response azure.UserList
)
- count = count || search != "" || (filter != "" && orderBy != "") || strings.Contains(filter, "endsWith")
- if count {
- headers = make(map[string]string)
- headers["ConsistencyLevel"] = "eventual"
+ if params.Top == 0 {
+ params.Top = 999
}
- if res, err := s.msgraph.Get(ctx, path, params.AsMap(), headers); err != nil {
+ if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -68,7 +48,7 @@ func (s *azureClient) GetAzureADUsers(ctx context.Context, filter string, search
}
}
-func (s *azureClient) ListAzureADUsers(ctx context.Context, filter string, search string, orderBy string, selectCols []string) <-chan azure.UserResult {
+func (s *azureClient) ListAzureADUsers(ctx context.Context, params query.GraphParams) <-chan azure.UserResult {
out := make(chan azure.UserResult)
go func() {
@@ -79,7 +59,7 @@ func (s *azureClient) ListAzureADUsers(ctx context.Context, filter string, searc
errResult = azure.UserResult{}
nextLink string
)
- if users, err := s.GetAzureADUsers(ctx, filter, search, orderBy, selectCols, 999, false); err != nil {
+ if users, err := s.GetAzureADUsers(ctx, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
diff --git a/client/virtual_machines.go b/client/virtual_machines.go
index 1934974..a346cd8 100644
--- a/client/virtual_machines.go
+++ b/client/virtual_machines.go
@@ -29,31 +29,17 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureVirtualMachine(ctx context.Context, subscriptionId, groupName, vmName, expand string) (*azure.VirtualMachine, error) {
- var (
- path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/virtualMachines/%s", subscriptionId, groupName, vmName)
- params = query.Params{ApiVersion: "2021-07-01", Expand: expand}.AsMap()
- headers map[string]string
- response azure.VirtualMachine
- )
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
-func (s *azureClient) GetAzureVirtualMachines(ctx context.Context, subscriptionId string, statusOnly bool) (azure.VirtualMachineList, error) {
+func (s *azureClient) GetAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) (azure.VirtualMachineList, error) {
var (
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Compute/virtualMachines", subscriptionId)
- params = query.Params{ApiVersion: "2021-07-01", StatusOnly: statusOnly}.AsMap()
- headers map[string]string
response azure.VirtualMachineList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if params.ApiVersion == "" {
+ params.ApiVersion = "2021-07-01"
+ }
+
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -62,7 +48,7 @@ func (s *azureClient) GetAzureVirtualMachines(ctx context.Context, subscriptionI
}
}
-func (s *azureClient) ListAzureVirtualMachines(ctx context.Context, subscriptionId string, statusOnly bool) <-chan azure.VirtualMachineResult {
+func (s *azureClient) ListAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azure.VirtualMachineResult {
out := make(chan azure.VirtualMachineResult)
go func() {
@@ -76,7 +62,7 @@ func (s *azureClient) ListAzureVirtualMachines(ctx context.Context, subscription
nextLink string
)
- if result, err := s.GetAzureVirtualMachines(ctx, subscriptionId, statusOnly); err != nil {
+ if result, err := s.GetAzureVirtualMachines(ctx, subscriptionId, params); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
diff --git a/client/vm_scale_sets.go b/client/vm_scale_sets.go
index 94879ad..32b9b65 100644
--- a/client/vm_scale_sets.go
+++ b/client/vm_scale_sets.go
@@ -29,31 +29,14 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureVMScaleSet(ctx context.Context, subscriptionId, groupName, vmssName, expand string) (*azure.VMScaleSet, error) {
- var (
- path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/virtualMachineScaleSets/%s", subscriptionId, groupName, vmssName)
- params = query.Params{ApiVersion: "2022-11-01", Expand: expand}.AsMap()
- headers map[string]string
- response azure.VMScaleSet
- )
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
-func (s *azureClient) GetAzureVMScaleSets(ctx context.Context, subscriptionId string, statusOnly bool) (azure.VMScaleSetList, error) {
+func (s *azureClient) GetAzureVMScaleSets(ctx context.Context, subscriptionId string) (azure.VMScaleSetList, error) {
var (
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Compute/virtualMachineScaleSets", subscriptionId)
- params = query.Params{ApiVersion: "2022-11-01", StatusOnly: statusOnly}.AsMap()
- headers map[string]string
+ params = query.RMParams{ApiVersion: "2022-11-01"}
response azure.VMScaleSetList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
@@ -62,7 +45,7 @@ func (s *azureClient) GetAzureVMScaleSets(ctx context.Context, subscriptionId st
}
}
-func (s *azureClient) ListAzureVMScaleSets(ctx context.Context, subscriptionId string, statusOnly bool) <-chan azure.VMScaleSetResult {
+func (s *azureClient) ListAzureVMScaleSets(ctx context.Context, subscriptionId string) <-chan azure.VMScaleSetResult {
out := make(chan azure.VMScaleSetResult)
go func() {
@@ -76,7 +59,7 @@ func (s *azureClient) ListAzureVMScaleSets(ctx context.Context, subscriptionId s
nextLink string
)
- if result, err := s.GetAzureVMScaleSets(ctx, subscriptionId, statusOnly); err != nil {
+ if result, err := s.GetAzureVMScaleSets(ctx, subscriptionId); err != nil {
errResult.Error = err
if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
return
diff --git a/client/web_apps.go b/client/web_apps.go
index d25fdfc..696c881 100644
--- a/client/web_apps.go
+++ b/client/web_apps.go
@@ -29,31 +29,14 @@ import (
"github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureWebApp(ctx context.Context, subscriptionId, groupName, waName, expand string) (*azure.WebApp, error) {
- var (
- path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Web/sites/%s", subscriptionId, groupName, waName)
- params = query.Params{ApiVersion: "2022-03-01", Expand: expand}.AsMap()
- headers map[string]string
- response azure.WebApp
- )
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
- return nil, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return nil, err
- } else {
- return &response, nil
- }
-}
-
func (s *azureClient) GetAzureWebApps(ctx context.Context, subscriptionId string) (azure.WebAppList, error) {
var (
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Web/sites", subscriptionId)
- params = query.Params{ApiVersion: "2022-03-01"}.AsMap()
- headers map[string]string
+ params = query.RMParams{ApiVersion: "2022-03-01"}
response azure.WebAppList
)
- if res, err := s.resourceManager.Get(ctx, path, params, headers); err != nil {
+ if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
diff --git a/cmd/list-app-owners.go b/cmd/list-app-owners.go
index 5fe7336..1faf8de 100644
--- a/cmd/list-app-owners.go
+++ b/cmd/list-app-owners.go
@@ -25,6 +25,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -78,7 +79,7 @@ func listAppOwners(ctx context.Context, client client.AzureClient, apps <-chan a
}
count = 0
)
- for item := range client.ListAzureADAppOwners(ctx, app.Data.Id, "", "", "", nil) {
+ for item := range client.ListAzureADAppOwners(ctx, app.Data.Id, query.GraphParams{}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing owners for this app", "appId", app.Data.AppId)
} else {
diff --git a/cmd/list-app-owners_test.go b/cmd/list-app-owners_test.go
index 666d8f1..a5bb2e3 100644
--- a/cmd/list-app-owners_test.go
+++ b/cmd/list-app-owners_test.go
@@ -48,8 +48,8 @@ func TestListAppOwners(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListAzureADAppOwners(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockAppOwnerChannel).Times(1)
- mockClient.EXPECT().ListAzureADAppOwners(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockAppOwnerChannel2).Times(1)
+ mockClient.EXPECT().ListAzureADAppOwners(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockAppOwnerChannel).Times(1)
+ mockClient.EXPECT().ListAzureADAppOwners(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockAppOwnerChannel2).Times(1)
channel := listAppOwners(ctx, mockClient, mockAppsChannel)
go func() {
diff --git a/cmd/list-app-role-assignments.go b/cmd/list-app-role-assignments.go
index 9e3aa4b..cbff4a7 100644
--- a/cmd/list-app-role-assignments.go
+++ b/cmd/list-app-role-assignments.go
@@ -26,6 +26,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -96,7 +97,7 @@ func listAppRoleAssignments(ctx context.Context, client client.AzureClient, serv
var (
count = 0
)
- for item := range client.ListAzureADAppRoleAssignments(ctx, servicePrincipal.Id, "", "", "", "", nil) {
+ for item := range client.ListAzureADAppRoleAssignments(ctx, servicePrincipal.Id, query.GraphParams{}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing app role assignments for this service principal", "servicePrincipalId", servicePrincipal)
} else {
diff --git a/cmd/list-apps.go b/cmd/list-apps.go
index 8160eb6..aabec3e 100644
--- a/cmd/list-apps.go
+++ b/cmd/list-apps.go
@@ -24,6 +24,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -64,7 +65,7 @@ func listApps(ctx context.Context, client client.AzureClient) <-chan azureWrappe
defer panicrecovery.PanicRecovery()
defer close(out)
count := 0
- for item := range client.ListAzureADApps(ctx, "", "", "", "", nil) {
+ for item := range client.ListAzureADApps(ctx, query.GraphParams{}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing applications")
return
diff --git a/cmd/list-apps_test.go b/cmd/list-apps_test.go
index 136656a..1a9b55a 100644
--- a/cmd/list-apps_test.go
+++ b/cmd/list-apps_test.go
@@ -41,7 +41,7 @@ func TestListApps(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListAzureADApps(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockChannel)
+ mockClient.EXPECT().ListAzureADApps(gomock.Any(), gomock.Any()).Return(mockChannel)
go func() {
defer close(mockChannel)
diff --git a/cmd/list-automation-account-role-assignments.go b/cmd/list-automation-account-role-assignments.go
index 7b25179..f5c6665 100644
--- a/cmd/list-automation-account-role-assignments.go
+++ b/cmd/list-automation-account-role-assignments.go
@@ -98,7 +98,7 @@ func listAutomationAccountRoleAssignments(ctx context.Context, client client.Azu
}
count = 0
)
- for item := range client.ListRoleAssignmentsForResource(ctx, id, "") {
+ for item := range client.ListRoleAssignmentsForResource(ctx, id, "", "") {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing role assignments for this automation account", "automationAccountId", id)
} else {
diff --git a/cmd/list-container-registry-role-assignments.go b/cmd/list-container-registry-role-assignments.go
index 31c3806..170b098 100644
--- a/cmd/list-container-registry-role-assignments.go
+++ b/cmd/list-container-registry-role-assignments.go
@@ -103,7 +103,7 @@ func listContainerRegistryRoleAssignments(ctx context.Context, client client.Azu
}
count = 0
)
- for item := range client.ListRoleAssignmentsForResource(ctx, id, "") {
+ for item := range client.ListRoleAssignmentsForResource(ctx, id, "", "") {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing role assignments for this container registry", "containerRegistryId", id)
} else {
diff --git a/cmd/list-device-owners.go b/cmd/list-device-owners.go
index 1d0c2e6..dee4c37 100644
--- a/cmd/list-device-owners.go
+++ b/cmd/list-device-owners.go
@@ -26,6 +26,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -95,7 +96,7 @@ func listDeviceOwners(ctx context.Context, client client.AzureClient, devices <-
}
count = 0
)
- for item := range client.ListAzureDeviceRegisteredOwners(ctx, id, false) {
+ for item := range client.ListAzureDeviceRegisteredOwners(ctx, id, query.GraphParams{}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing owners for this device", "deviceId", id)
} else {
diff --git a/cmd/list-devices.go b/cmd/list-devices.go
index 5e68b8b..184b5bb 100644
--- a/cmd/list-devices.go
+++ b/cmd/list-devices.go
@@ -24,6 +24,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -64,7 +65,7 @@ func listDevices(ctx context.Context, client client.AzureClient) <-chan interfac
defer panicrecovery.PanicRecovery()
defer close(out)
count := 0
- for item := range client.ListAzureDevices(ctx, "", "", "", "", nil) {
+ for item := range client.ListAzureDevices(ctx, query.GraphParams{}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing devices")
return
diff --git a/cmd/list-devices_test.go b/cmd/list-devices_test.go
index 1bbf4bf..83fbf83 100644
--- a/cmd/list-devices_test.go
+++ b/cmd/list-devices_test.go
@@ -41,7 +41,7 @@ func TestListDevices(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListAzureDevices(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockChannel)
+ mockClient.EXPECT().ListAzureDevices(gomock.Any(), gomock.Any()).Return(mockChannel)
go func() {
defer close(mockChannel)
diff --git a/cmd/list-function-app-role-assignments.go b/cmd/list-function-app-role-assignments.go
index d881936..a92494c 100644
--- a/cmd/list-function-app-role-assignments.go
+++ b/cmd/list-function-app-role-assignments.go
@@ -98,7 +98,7 @@ func listFunctionAppRoleAssignments(ctx context.Context, client client.AzureClie
}
count = 0
)
- for item := range client.ListRoleAssignmentsForResource(ctx, id, "") {
+ for item := range client.ListRoleAssignmentsForResource(ctx, id, "", "") {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing role assignments for this function app", "functionAppId", id)
} else {
diff --git a/cmd/list-group-members.go b/cmd/list-group-members.go
index 2f534a0..8d3bf13 100644
--- a/cmd/list-group-members.go
+++ b/cmd/list-group-members.go
@@ -26,6 +26,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -95,7 +96,7 @@ func listGroupMembers(ctx context.Context, client client.AzureClient, groups <-c
}
count = 0
)
- for item := range client.ListAzureADGroupMembers(ctx, id, "", "", "", nil) {
+ for item := range client.ListAzureADGroupMembers(ctx, id, query.GraphParams{}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing members for this group", "groupId", id)
} else {
diff --git a/cmd/list-group-members_test.go b/cmd/list-group-members_test.go
index f3cf088..0f3bff3 100644
--- a/cmd/list-group-members_test.go
+++ b/cmd/list-group-members_test.go
@@ -47,8 +47,8 @@ func TestListGroupMembers(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListAzureADGroupMembers(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockGroupMemberChannel).Times(1)
- mockClient.EXPECT().ListAzureADGroupMembers(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockGroupMemberChannel2).Times(1)
+ mockClient.EXPECT().ListAzureADGroupMembers(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockGroupMemberChannel).Times(1)
+ mockClient.EXPECT().ListAzureADGroupMembers(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockGroupMemberChannel2).Times(1)
channel := listGroupMembers(ctx, mockClient, mockGroupsChannel)
go func() {
diff --git a/cmd/list-group-owners.go b/cmd/list-group-owners.go
index e24d13b..7746812 100644
--- a/cmd/list-group-owners.go
+++ b/cmd/list-group-owners.go
@@ -26,6 +26,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -95,7 +96,7 @@ func listGroupOwners(ctx context.Context, client client.AzureClient, groups <-ch
}
count = 0
)
- for item := range client.ListAzureADGroupOwners(ctx, id, "", "", "", nil) {
+ for item := range client.ListAzureADGroupOwners(ctx, id, query.GraphParams{}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing owners for this group", "groupId", id)
} else {
diff --git a/cmd/list-group-owners_test.go b/cmd/list-group-owners_test.go
index b1e7eea..ae85f4e 100644
--- a/cmd/list-group-owners_test.go
+++ b/cmd/list-group-owners_test.go
@@ -47,8 +47,8 @@ func TestListGroupOwners(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListAzureADGroupOwners(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockGroupOwnerChannel).Times(1)
- mockClient.EXPECT().ListAzureADGroupOwners(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockGroupOwnerChannel2).Times(1)
+ mockClient.EXPECT().ListAzureADGroupOwners(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockGroupOwnerChannel).Times(1)
+ mockClient.EXPECT().ListAzureADGroupOwners(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockGroupOwnerChannel2).Times(1)
channel := listGroupOwners(ctx, mockClient, mockGroupsChannel)
go func() {
diff --git a/cmd/list-groups.go b/cmd/list-groups.go
index 47b8dde..82ca789 100644
--- a/cmd/list-groups.go
+++ b/cmd/list-groups.go
@@ -24,6 +24,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -64,7 +65,7 @@ func listGroups(ctx context.Context, client client.AzureClient) <-chan interface
defer panicrecovery.PanicRecovery()
defer close(out)
count := 0
- for item := range client.ListAzureADGroups(ctx, "securityEnabled eq true", "", "", "", nil) {
+ for item := range client.ListAzureADGroups(ctx, query.GraphParams{Filter: "securityEnabled eq true"}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing groups")
return
diff --git a/cmd/list-groups_test.go b/cmd/list-groups_test.go
index d931ff2..fa1303f 100644
--- a/cmd/list-groups_test.go
+++ b/cmd/list-groups_test.go
@@ -42,7 +42,7 @@ func TestListGroups(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListAzureADGroups(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockChannel)
+ mockClient.EXPECT().ListAzureADGroups(gomock.Any(), gomock.Any()).Return(mockChannel)
go func() {
defer close(mockChannel)
diff --git a/cmd/list-key-vault-role-assignments.go b/cmd/list-key-vault-role-assignments.go
index 05b67d2..0c6b322 100644
--- a/cmd/list-key-vault-role-assignments.go
+++ b/cmd/list-key-vault-role-assignments.go
@@ -97,7 +97,7 @@ func listKeyVaultRoleAssignments(ctx context.Context, client client.AzureClient,
}
count = 0
)
- for item := range client.ListRoleAssignmentsForResource(ctx, id, "") {
+ for item := range client.ListRoleAssignmentsForResource(ctx, id, "", "") {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing role assignments for this key vault", "keyVaultId", id)
} else {
diff --git a/cmd/list-key-vault-role-assignments_test.go b/cmd/list-key-vault-role-assignments_test.go
index db7e4c3..672d032 100644
--- a/cmd/list-key-vault-role-assignments_test.go
+++ b/cmd/list-key-vault-role-assignments_test.go
@@ -47,8 +47,8 @@ func TestListKeyVaultRoleAssignments(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockKeyVaultRoleAssignmentChannel).Times(1)
- mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockKeyVaultRoleAssignmentChannel2).Times(1)
+ mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockKeyVaultRoleAssignmentChannel).Times(1)
+ mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockKeyVaultRoleAssignmentChannel2).Times(1)
channel := listKeyVaultRoleAssignments(ctx, mockClient, mockKeyVaultsChannel)
go func() {
diff --git a/cmd/list-key-vaults.go b/cmd/list-key-vaults.go
index 66626d4..6e82e9f 100644
--- a/cmd/list-key-vaults.go
+++ b/cmd/list-key-vaults.go
@@ -26,6 +26,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -91,7 +92,7 @@ func listKeyVaults(ctx context.Context, client client.AzureClient, subscriptions
defer wg.Done()
for id := range stream {
count := 0
- for item := range client.ListAzureKeyVaults(ctx, id, 999) {
+ for item := range client.ListAzureKeyVaults(ctx, id, query.RMParams{Top: 999}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing key vaults for this subscription", "subscriptionId", id)
} else {
diff --git a/cmd/list-logic-app-role-assignments.go b/cmd/list-logic-app-role-assignments.go
index 0dd33aa..973e735 100644
--- a/cmd/list-logic-app-role-assignments.go
+++ b/cmd/list-logic-app-role-assignments.go
@@ -103,7 +103,7 @@ func listLogicAppRoleAssignments(ctx context.Context, client client.AzureClient,
}
count = 0
)
- for item := range client.ListRoleAssignmentsForResource(ctx, id, "") {
+ for item := range client.ListRoleAssignmentsForResource(ctx, id, "", "") {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing role assignments for this logic app", "logicappId", id)
} else {
diff --git a/cmd/list-managed-cluster-role-assignments.go b/cmd/list-managed-cluster-role-assignments.go
index 102db09..59c78c0 100644
--- a/cmd/list-managed-cluster-role-assignments.go
+++ b/cmd/list-managed-cluster-role-assignments.go
@@ -103,7 +103,7 @@ func listManagedClusterRoleAssignments(ctx context.Context, client client.AzureC
}
count = 0
)
- for item := range client.ListRoleAssignmentsForResource(ctx, id, "") {
+ for item := range client.ListRoleAssignmentsForResource(ctx, id, "", "") {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing role assignments for this managed cluster", "managedClusterId", id)
} else {
diff --git a/cmd/list-managed-clusters.go b/cmd/list-managed-clusters.go
index d186666..becb7be 100644
--- a/cmd/list-managed-clusters.go
+++ b/cmd/list-managed-clusters.go
@@ -95,7 +95,7 @@ func listManagedClusters(ctx context.Context, client client.AzureClient, subscri
defer wg.Done()
for id := range stream {
count := 0
- for item := range client.ListAzureManagedClusters(ctx, id, false) {
+ for item := range client.ListAzureManagedClusters(ctx, id) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing managed clusters for this subscription", "subscriptionId", id)
} else {
diff --git a/cmd/list-management-group-descendants.go b/cmd/list-management-group-descendants.go
index 404c56e..803b20f 100644
--- a/cmd/list-management-group-descendants.go
+++ b/cmd/list-management-group-descendants.go
@@ -91,7 +91,7 @@ func listManagementGroupDescendants(ctx context.Context, client client.AzureClie
defer wg.Done()
for id := range stream {
count := 0
- for item := range client.ListAzureManagementGroupDescendants(ctx, id) {
+ for item := range client.ListAzureManagementGroupDescendants(ctx, id, 3000) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing descendants for this management group", "managementGroupId", id)
} else {
diff --git a/cmd/list-management-group-descendants_test.go b/cmd/list-management-group-descendants_test.go
index 01806b1..ad5bf4c 100644
--- a/cmd/list-management-group-descendants_test.go
+++ b/cmd/list-management-group-descendants_test.go
@@ -46,8 +46,8 @@ func TestListManagementGroupDescendants(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListAzureManagementGroupDescendants(gomock.Any(), gomock.Any()).Return(mockManagementGroupDescendantChannel).Times(1)
- mockClient.EXPECT().ListAzureManagementGroupDescendants(gomock.Any(), gomock.Any()).Return(mockManagementGroupDescendantChannel2).Times(1)
+ mockClient.EXPECT().ListAzureManagementGroupDescendants(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockManagementGroupDescendantChannel).Times(1)
+ mockClient.EXPECT().ListAzureManagementGroupDescendants(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockManagementGroupDescendantChannel2).Times(1)
channel := listManagementGroupDescendants(ctx, mockClient, mockManagementGroupsChannel)
go func() {
diff --git a/cmd/list-management-group-role-assignments.go b/cmd/list-management-group-role-assignments.go
index 6ef9a51..d48fecf 100644
--- a/cmd/list-management-group-role-assignments.go
+++ b/cmd/list-management-group-role-assignments.go
@@ -97,7 +97,7 @@ func listManagementGroupRoleAssignments(ctx context.Context, client client.Azure
}
count = 0
)
- for item := range client.ListRoleAssignmentsForResource(ctx, id, "atScope()") {
+ for item := range client.ListRoleAssignmentsForResource(ctx, id, "atScope()", "") {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing role assignments for this managementGroup", "managementGroupId", id)
} else {
diff --git a/cmd/list-management-group-role-assignments_test.go b/cmd/list-management-group-role-assignments_test.go
index eed6954..321a1d4 100644
--- a/cmd/list-management-group-role-assignments_test.go
+++ b/cmd/list-management-group-role-assignments_test.go
@@ -47,8 +47,8 @@ func TestListResourceGroupRoleAssignments(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockResourceGroupRoleAssignmentChannel).Times(1)
- mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockResourceGroupRoleAssignmentChannel2).Times(1)
+ mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockResourceGroupRoleAssignmentChannel).Times(1)
+ mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockResourceGroupRoleAssignmentChannel2).Times(1)
channel := listResourceGroupRoleAssignments(ctx, mockClient, mockResourceGroupsChannel)
go func() {
diff --git a/cmd/list-management-groups.go b/cmd/list-management-groups.go
index 87ddbe0..3af3019 100644
--- a/cmd/list-management-groups.go
+++ b/cmd/list-management-groups.go
@@ -66,7 +66,7 @@ func listManagementGroups(ctx context.Context, client client.AzureClient) <-chan
defer panicrecovery.PanicRecovery()
defer close(out)
count := 0
- for item := range client.ListAzureManagementGroups(ctx) {
+ for item := range client.ListAzureManagementGroups(ctx, "") {
if item.Error != nil {
log.Info("warning: unable to process azure management groups; either the organization has no management groups or azurehound does not have the reader role on the root management group.")
return
diff --git a/cmd/list-management-groups_test.go b/cmd/list-management-groups_test.go
index 47efe17..2a676db 100644
--- a/cmd/list-management-groups_test.go
+++ b/cmd/list-management-groups_test.go
@@ -41,7 +41,7 @@ func TestListManagementGroups(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListAzureManagementGroups(gomock.Any()).Return(mockChannel)
+ mockClient.EXPECT().ListAzureManagementGroups(gomock.Any(), gomock.Any()).Return(mockChannel)
go func() {
defer close(mockChannel)
diff --git a/cmd/list-resource-group-role-assignments.go b/cmd/list-resource-group-role-assignments.go
index a6d2fb7..964c7bd 100644
--- a/cmd/list-resource-group-role-assignments.go
+++ b/cmd/list-resource-group-role-assignments.go
@@ -98,7 +98,7 @@ func listResourceGroupRoleAssignments(ctx context.Context, client client.AzureCl
}
count = 0
)
- for item := range client.ListRoleAssignmentsForResource(ctx, id, "") {
+ for item := range client.ListRoleAssignmentsForResource(ctx, id, "", "") {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing role assignments for this resourceGroup", "resourceGroupId", id)
} else {
diff --git a/cmd/list-resource-group-role-assignments_test.go b/cmd/list-resource-group-role-assignments_test.go
index 5c8c8bb..63b8c8e 100644
--- a/cmd/list-resource-group-role-assignments_test.go
+++ b/cmd/list-resource-group-role-assignments_test.go
@@ -47,8 +47,8 @@ func TestListManagementGroupRoleAssignments(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockManagementGroupRoleAssignmentChannel).Times(1)
- mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockManagementGroupRoleAssignmentChannel2).Times(1)
+ mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockManagementGroupRoleAssignmentChannel).Times(1)
+ mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockManagementGroupRoleAssignmentChannel2).Times(1)
channel := listManagementGroupRoleAssignments(ctx, mockClient, mockManagementGroupsChannel)
go func() {
diff --git a/cmd/list-resource-groups.go b/cmd/list-resource-groups.go
index c3ae948..d21de6e 100644
--- a/cmd/list-resource-groups.go
+++ b/cmd/list-resource-groups.go
@@ -26,6 +26,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -91,7 +92,7 @@ func listResourceGroups(ctx context.Context, client client.AzureClient, subscrip
defer wg.Done()
for id := range stream {
count := 0
- for item := range client.ListAzureResourceGroups(ctx, id, "") {
+ for item := range client.ListAzureResourceGroups(ctx, id, query.RMParams{Top: 1000}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing resource groups for this subscription", "subscriptionId", id)
} else {
diff --git a/cmd/list-role-assignments.go b/cmd/list-role-assignments.go
index 6e7ca32..b3248a4 100644
--- a/cmd/list-role-assignments.go
+++ b/cmd/list-role-assignments.go
@@ -26,6 +26,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -100,7 +101,7 @@ func listRoleAssignments(ctx context.Context, client client.AzureClient, roles <
filter = fmt.Sprintf("roleDefinitionId eq '%s'", id)
)
// We expand directoryScope in order to obtain the appId from app specific scoped role assignments
- for item := range client.ListAzureADRoleAssignments(ctx, filter, "", "", "directoryScope", nil) {
+ for item := range client.ListAzureADRoleAssignments(ctx, query.GraphParams{Filter: filter, Expand: "directoryScope"}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing role assignments for this role", "roleDefinitionId", id)
} else {
diff --git a/cmd/list-roles.go b/cmd/list-roles.go
index 836c9b5..427de4f 100644
--- a/cmd/list-roles.go
+++ b/cmd/list-roles.go
@@ -64,7 +64,7 @@ func listRoles(ctx context.Context, client client.AzureClient) <-chan interface{
defer panicrecovery.PanicRecovery()
defer close(out)
count := 0
- for item := range client.ListAzureADRoles(ctx, "", "") {
+ for item := range client.ListAzureADRoles(ctx, "") {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing roles")
return
diff --git a/cmd/list-roles_test.go b/cmd/list-roles_test.go
index 0805f0a..e049128 100644
--- a/cmd/list-roles_test.go
+++ b/cmd/list-roles_test.go
@@ -41,7 +41,7 @@ func TestListRoles(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListAzureADRoles(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockChannel)
+ mockClient.EXPECT().ListAzureADRoles(gomock.Any(), gomock.Any()).Return(mockChannel)
go func() {
defer close(mockChannel)
diff --git a/cmd/list-service-principal-owners.go b/cmd/list-service-principal-owners.go
index 7fd4c56..b52d8b6 100644
--- a/cmd/list-service-principal-owners.go
+++ b/cmd/list-service-principal-owners.go
@@ -26,6 +26,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -96,7 +97,7 @@ func listServicePrincipalOwners(ctx context.Context, client client.AzureClient,
}
count = 0
)
- for item := range client.ListAzureADServicePrincipalOwners(ctx, id, "", "", "", nil) {
+ for item := range client.ListAzureADServicePrincipalOwners(ctx, id, query.GraphParams{}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing owners for this service principal", "servicePrincipalId", id)
} else {
diff --git a/cmd/list-service-principal-owners_test.go b/cmd/list-service-principal-owners_test.go
index 1dff1d1..7bf1811 100644
--- a/cmd/list-service-principal-owners_test.go
+++ b/cmd/list-service-principal-owners_test.go
@@ -47,8 +47,8 @@ func TestListServicePrincipalOwners(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListAzureADServicePrincipalOwners(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockServicePrincipalOwnerChannel).Times(1)
- mockClient.EXPECT().ListAzureADServicePrincipalOwners(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockServicePrincipalOwnerChannel2).Times(1)
+ mockClient.EXPECT().ListAzureADServicePrincipalOwners(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockServicePrincipalOwnerChannel).Times(1)
+ mockClient.EXPECT().ListAzureADServicePrincipalOwners(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockServicePrincipalOwnerChannel2).Times(1)
channel := listServicePrincipalOwners(ctx, mockClient, mockServicePrincipalsChannel)
go func() {
diff --git a/cmd/list-service-principals.go b/cmd/list-service-principals.go
index 57399bd..5d427af 100644
--- a/cmd/list-service-principals.go
+++ b/cmd/list-service-principals.go
@@ -24,6 +24,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -64,7 +65,7 @@ func listServicePrincipals(ctx context.Context, client client.AzureClient) <-cha
defer panicrecovery.PanicRecovery()
defer close(out)
count := 0
- for item := range client.ListAzureADServicePrincipals(ctx, "", "", "", "", nil) {
+ for item := range client.ListAzureADServicePrincipals(ctx, query.GraphParams{}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing service principals")
return
diff --git a/cmd/list-service-principals_test.go b/cmd/list-service-principals_test.go
index c62f028..cb64655 100644
--- a/cmd/list-service-principals_test.go
+++ b/cmd/list-service-principals_test.go
@@ -41,7 +41,7 @@ func TestListServicePrincipals(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListAzureADServicePrincipals(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockChannel)
+ mockClient.EXPECT().ListAzureADServicePrincipals(gomock.Any(), gomock.Any()).Return(mockChannel)
go func() {
defer close(mockChannel)
diff --git a/cmd/list-storage-account-role-assignments.go b/cmd/list-storage-account-role-assignments.go
index 71df35a..5b70911 100644
--- a/cmd/list-storage-account-role-assignments.go
+++ b/cmd/list-storage-account-role-assignments.go
@@ -98,7 +98,7 @@ func listStorageAccountRoleAssignments(ctx context.Context, client client.AzureC
}
count = 0
)
- for item := range client.ListRoleAssignmentsForResource(ctx, id, "") {
+ for item := range client.ListRoleAssignmentsForResource(ctx, id, "", "") {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing role assignments for this storage account", "storageAccountId", id)
} else {
diff --git a/cmd/list-subscription-role-assignments.go b/cmd/list-subscription-role-assignments.go
index 94279e3..88ef907 100644
--- a/cmd/list-subscription-role-assignments.go
+++ b/cmd/list-subscription-role-assignments.go
@@ -97,7 +97,7 @@ func listSubscriptionRoleAssignments(ctx context.Context, client client.AzureCli
}
count = 0
)
- for item := range client.ListRoleAssignmentsForResource(ctx, id, "atScope()") {
+ for item := range client.ListRoleAssignmentsForResource(ctx, id, "atScope()", "") {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing role assignments for this subscription", "subscriptionId", id)
} else {
diff --git a/cmd/list-subscription-role-assignments_test.go b/cmd/list-subscription-role-assignments_test.go
index 1902684..308044e 100644
--- a/cmd/list-subscription-role-assignments_test.go
+++ b/cmd/list-subscription-role-assignments_test.go
@@ -47,8 +47,8 @@ func TestListSubscriptionRoleAssignments(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockSubscriptionRoleAssignmentChannel).Times(1)
- mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockSubscriptionRoleAssignmentChannel2).Times(1)
+ mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockSubscriptionRoleAssignmentChannel).Times(1)
+ mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockSubscriptionRoleAssignmentChannel2).Times(1)
channel := listSubscriptionRoleAssignments(ctx, mockClient, mockSubscriptionsChannel)
go func() {
diff --git a/cmd/list-users.go b/cmd/list-users.go
index 531b7a3..1ac8f87 100644
--- a/cmd/list-users.go
+++ b/cmd/list-users.go
@@ -24,6 +24,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -64,7 +65,7 @@ func listUsers(ctx context.Context, client client.AzureClient) <-chan interface{
defer panicrecovery.PanicRecovery()
defer close(out)
count := 0
- for item := range client.ListAzureADUsers(ctx, "", "", "", []string{
+ for item := range client.ListAzureADUsers(ctx, query.GraphParams{Select: []string{
"accountEnabled",
"createdDateTime",
"displayName",
@@ -76,7 +77,7 @@ func listUsers(ctx context.Context, client client.AzureClient) <-chan interface{
"userPrincipalName",
"userType",
"id",
- }) {
+ }}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing users")
return
diff --git a/cmd/list-users_test.go b/cmd/list-users_test.go
index d7e6211..3a1deb6 100644
--- a/cmd/list-users_test.go
+++ b/cmd/list-users_test.go
@@ -42,7 +42,7 @@ func TestListUsers(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListAzureADUsers(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockChannel)
+ mockClient.EXPECT().ListAzureADUsers(gomock.Any(), gomock.Any()).Return(mockChannel)
go func() {
defer close(mockChannel)
diff --git a/cmd/list-virtual-machine-role-assignments.go b/cmd/list-virtual-machine-role-assignments.go
index 097055e..a077b03 100644
--- a/cmd/list-virtual-machine-role-assignments.go
+++ b/cmd/list-virtual-machine-role-assignments.go
@@ -97,7 +97,7 @@ func listVirtualMachineRoleAssignments(ctx context.Context, client client.AzureC
}
count = 0
)
- for item := range client.ListRoleAssignmentsForResource(ctx, id, "") {
+ for item := range client.ListRoleAssignmentsForResource(ctx, id, "", "") {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing role assignments for this virtual machine", "virtualMachineId", id)
} else {
diff --git a/cmd/list-virtual-machine-role-assignments_test.go b/cmd/list-virtual-machine-role-assignments_test.go
index dffaf79..110eea4 100644
--- a/cmd/list-virtual-machine-role-assignments_test.go
+++ b/cmd/list-virtual-machine-role-assignments_test.go
@@ -47,8 +47,8 @@ func TestListVirtualMachineRoleAssignments(t *testing.T) {
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
- mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockVirtualMachineRoleAssignmentChannel).Times(1)
- mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockVirtualMachineRoleAssignmentChannel2).Times(1)
+ mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockVirtualMachineRoleAssignmentChannel).Times(1)
+ mockClient.EXPECT().ListRoleAssignmentsForResource(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(mockVirtualMachineRoleAssignmentChannel2).Times(1)
channel := listVirtualMachineRoleAssignments(ctx, mockClient, mockVirtualMachinesChannel)
go func() {
diff --git a/cmd/list-virtual-machines.go b/cmd/list-virtual-machines.go
index d28d6e5..ee7c1a8 100644
--- a/cmd/list-virtual-machines.go
+++ b/cmd/list-virtual-machines.go
@@ -26,6 +26,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -90,7 +91,7 @@ func listVirtualMachines(ctx context.Context, client client.AzureClient, subscri
defer wg.Done()
for id := range stream {
count := 0
- for item := range client.ListAzureVirtualMachines(ctx, id, false) {
+ for item := range client.ListAzureVirtualMachines(ctx, id, query.RMParams{}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing virtual machines for this subscription", "subscriptionId", id)
} else {
diff --git a/cmd/list-vm-scale-set-role-assignments.go b/cmd/list-vm-scale-set-role-assignments.go
index 4a82b2e..491ef7e 100644
--- a/cmd/list-vm-scale-set-role-assignments.go
+++ b/cmd/list-vm-scale-set-role-assignments.go
@@ -103,7 +103,7 @@ func listVMScaleSetRoleAssignments(ctx context.Context, client client.AzureClien
}
count = 0
)
- for item := range client.ListRoleAssignmentsForResource(ctx, id, "") {
+ for item := range client.ListRoleAssignmentsForResource(ctx, id, "", "") {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing role assignments for this vm scale set", "vmScaleSetId", id)
} else {
diff --git a/cmd/list-vm-scale-sets.go b/cmd/list-vm-scale-sets.go
index c55f4b2..49e9eb1 100644
--- a/cmd/list-vm-scale-sets.go
+++ b/cmd/list-vm-scale-sets.go
@@ -96,7 +96,7 @@ func listVMScaleSets(ctx context.Context, client client.AzureClient, subscriptio
defer wg.Done()
for id := range stream {
count := 0
- for item := range client.ListAzureVMScaleSets(ctx, id, false) {
+ for item := range client.ListAzureVMScaleSets(ctx, id) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing virtual machine scale sets for this subscription", "subscriptionId", id)
} else {
diff --git a/cmd/list-web-app-role-assignments.go b/cmd/list-web-app-role-assignments.go
index 90ce0ef..00f949b 100644
--- a/cmd/list-web-app-role-assignments.go
+++ b/cmd/list-web-app-role-assignments.go
@@ -103,7 +103,7 @@ func listWebAppRoleAssignments(ctx context.Context, client client.AzureClient, w
}
count = 0
)
- for item := range client.ListRoleAssignmentsForResource(ctx, id, "") {
+ for item := range client.ListRoleAssignmentsForResource(ctx, id, "", "") {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing role assignments for this web app", "webAppId", id)
} else {
diff --git a/go.mod b/go.mod
index f364545..08b4202 100644
--- a/go.mod
+++ b/go.mod
@@ -34,7 +34,9 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
golang.org/x/crypto v0.21.0 // indirect
+ golang.org/x/mod v0.8.0 // indirect
golang.org/x/text v0.14.0 // indirect
+ golang.org/x/tools v0.6.0 // indirect
gopkg.in/ini.v1 v1.66.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.0 // indirect
diff --git a/go.sum b/go.sum
index bbbb2cb..182edc3 100644
--- a/go.sum
+++ b/go.sum
@@ -424,6 +424,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
+golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -636,6 +638,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
+golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
From b05cf965aa02a4ea1922aa084be10469ba3a70e3 Mon Sep 17 00:00:00 2001
From: Mistah J <26472282+mistahj67@users.noreply.github.com>
Date: Fri, 23 Aug 2024 14:15:24 -0700
Subject: [PATCH 2/8] chore: bump cobra version
---
go.mod | 6 +++---
go.sum | 7 +++++++
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/go.mod b/go.mod
index 08b4202..7ac6e40 100644
--- a/go.mod
+++ b/go.mod
@@ -9,7 +9,7 @@ require (
github.com/judwhite/go-svc v1.2.1
github.com/manifoldco/promptui v0.9.0
github.com/rs/zerolog v1.26.0
- github.com/spf13/cobra v1.3.0
+ github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.10.1
github.com/stretchr/testify v1.7.0
@@ -24,7 +24,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
- github.com/inconshreveable/mousetrap v1.0.0 // indirect
+ github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
@@ -39,5 +39,5 @@ require (
golang.org/x/tools v0.6.0 // indirect
gopkg.in/ini.v1 v1.66.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
- gopkg.in/yaml.v3 v3.0.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
index 182edc3..04b5d27 100644
--- a/go.sum
+++ b/go.sum
@@ -91,6 +91,7 @@ github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWH
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -236,6 +237,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -332,6 +335,8 @@ github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA=
github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.3.0 h1:R7cSvGu+Vv+qX0gW5R/85dx2kmmJT5z5NM8ifdYjdn0=
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
+github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
+github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
@@ -788,6 +793,7 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
@@ -807,6 +813,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
From 1f8e1c9a85f9cbfc92a364bc34867d3659c48489 Mon Sep 17 00:00:00 2001
From: Mistah J <26472282+mistahj67@users.noreply.github.com>
Date: Mon, 26 Aug 2024 08:55:35 -0700
Subject: [PATCH 3/8] feat: add $select support to list-group-members
---
client/client.go | 33 ++++++++++++++++++++-------------
client/groups.go | 3 +--
cmd/list-group-members.go | 15 +++++++++++++--
3 files changed, 34 insertions(+), 17 deletions(-)
diff --git a/client/client.go b/client/client.go
index fc8e526..e5e988e 100644
--- a/client/client.go
+++ b/client/client.go
@@ -92,17 +92,7 @@ type azureClient struct {
tenant azure.Tenant
}
-func (s azureClient) TenantInfo() azure.Tenant {
- return s.tenant
-}
-
-func (s azureClient) CloseIdleConnections() {
- s.msgraph.CloseIdleConnections()
- s.resourceManager.CloseIdleConnections()
-}
-
-type AzureClient interface {
- // Graph
+type AzureGraphClient interface {
GetAzureADApps(ctx context.Context, params query.GraphParams) (azure.ApplicationList, error)
GetAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error)
GetAzureADGroups(ctx context.Context, params query.GraphParams) (azure.GroupList, error)
@@ -115,13 +105,15 @@ type AzureClient interface {
GetAzureDevices(ctx context.Context, params query.GraphParams) (azure.DeviceList, error)
GetAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error)
GetAzureADAppRoleAssignments(ctx context.Context, servicePrincipalId string, params query.GraphParams) (azure.AppRoleAssignmentList, error)
+
+ // https://learn.microsoft.com/en-us/graph/api/group-list-members?view=graph-rest-beta
GetAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) (azure.MemberObjectList, error)
+ ListAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.MemberObjectResult
ListAzureADUsers(ctx context.Context, params query.GraphParams) <-chan azure.UserResult
ListAzureADApps(ctx context.Context, params query.GraphParams) <-chan azure.ApplicationResult
ListAzureADAppOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.AppOwnerResult
ListAzureADGroups(ctx context.Context, params query.GraphParams) <-chan azure.GroupResult
- ListAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.MemberObjectResult
ListAzureADRoleAssignments(ctx context.Context, params query.GraphParams) <-chan azure.UnifiedRoleAssignmentResult
ListAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.GroupOwnerResult
ListAzureADRoles(ctx context.Context, filter string) <-chan azure.RoleResult
@@ -130,8 +122,9 @@ type AzureClient interface {
ListAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.DeviceRegisteredOwnerResult
ListAzureDevices(ctx context.Context, params query.GraphParams) <-chan azure.DeviceResult
ListAzureADAppRoleAssignments(ctx context.Context, servicePrincipal string, params query.GraphParams) <-chan azure.AppRoleAssignmentResult
+}
- // RM
+type AzureResourceManagerClient interface {
GetAzureADTenants(ctx context.Context, includeAllTenantCategories bool) (azure.TenantList, error)
GetAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) (azure.KeyVaultList, error)
GetAzureManagementGroups(ctx context.Context, skipToken string) (azure.ManagementGroupList, error)
@@ -166,7 +159,21 @@ type AzureClient interface {
ListAzureFunctionApps(ctx context.Context, subscriptionId string) <-chan azure.FunctionAppResult
ListRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) <-chan azure.RoleAssignmentResult
ListAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) <-chan azure.DescendantInfoResult
+}
+
+type AzureClient interface {
+ AzureGraphClient
+ AzureResourceManagerClient
TenantInfo() azure.Tenant
CloseIdleConnections()
}
+
+func (s azureClient) TenantInfo() azure.Tenant {
+ return s.tenant
+}
+
+func (s azureClient) CloseIdleConnections() {
+ s.msgraph.CloseIdleConnections()
+ s.resourceManager.CloseIdleConnections()
+}
diff --git a/client/groups.go b/client/groups.go
index f329e77..ff86db0 100644
--- a/client/groups.go
+++ b/client/groups.go
@@ -68,7 +68,6 @@ func (s *azureClient) GetAzureADGroupMembers(ctx context.Context, objectId strin
func (s *azureClient) GetAzureADGroups(ctx context.Context, params query.GraphParams) (azure.GroupList, error) {
var (
path = fmt.Sprintf("/%s/groups", constants.GraphApiVersion)
- headers map[string]string
response azure.GroupList
)
@@ -76,7 +75,7 @@ func (s *azureClient) GetAzureADGroups(ctx context.Context, params query.GraphPa
params.Top = 99
}
- if res, err := s.msgraph.Get(ctx, path, params, headers); err != nil {
+ if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
return response, err
} else if err := rest.Decode(res.Body, &response); err != nil {
return response, err
diff --git a/cmd/list-group-members.go b/cmd/list-group-members.go
index 8d3bf13..84295b0 100644
--- a/cmd/list-group-members.go
+++ b/cmd/list-group-members.go
@@ -36,6 +36,7 @@ import (
func init() {
listRootCmd.AddCommand(listGroupMembersCmd)
+ listGroupMembersCmd.Flags().StringSliceVar(&listGroupMembersSelect, "select", []string{"id,displayName,createdDateTime"}, `Select properties to include. Use "" for Azure default properties. Azurehound default is "id,displayName,createdDateTime" if flag is not supplied.`)
}
var listGroupMembersCmd = &cobra.Command{
@@ -45,7 +46,9 @@ var listGroupMembersCmd = &cobra.Command{
SilenceUsage: true,
}
-func listGroupMembersCmdImpl(cmd *cobra.Command, args []string) {
+var listGroupMembersSelect []string
+
+func listGroupMembersCmdImpl(cmd *cobra.Command, _ []string) {
ctx, stop := signal.NotifyContext(cmd.Context(), os.Interrupt, os.Kill)
defer gracefulShutdown(stop)
@@ -65,6 +68,14 @@ func listGroupMembers(ctx context.Context, client client.AzureClient, groups <-c
ids = make(chan string)
streams = pipeline.Demux(ctx.Done(), ids, 25)
wg sync.WaitGroup
+ params = query.GraphParams{
+ Select: unique(listGroupMembersSelect),
+ Filter: "",
+ Count: false,
+ Search: "",
+ Top: 0,
+ Expand: "",
+ }
)
go func() {
@@ -96,7 +107,7 @@ func listGroupMembers(ctx context.Context, client client.AzureClient, groups <-c
}
count = 0
)
- for item := range client.ListAzureADGroupMembers(ctx, id, query.GraphParams{}) {
+ for item := range client.ListAzureADGroupMembers(ctx, id, params) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing members for this group", "groupId", id)
} else {
From b64eb3d9352b1479312a991e494c9f95da1b3e85 Mon Sep 17 00:00:00 2001
From: Mistah J <26472282+mistahj67@users.noreply.github.com>
Date: Mon, 26 Aug 2024 11:49:56 -0700
Subject: [PATCH 4/8] chore: use generics to clean up
---
client/app_role_assignments.go | 82 +---
client/apps.go | 173 +-------
client/automation_accounts.go | 89 +---
client/client.go | 182 +++++---
client/container_registries.go | 89 +---
client/devices.go | 171 +-------
client/function_apps.go | 89 +---
client/groups.go | 263 +----------
client/keyvaults.go | 90 +---
client/logic_apps.go | 85 +---
client/managed_clusters.go | 89 +---
client/management_groups.go | 168 +-------
client/mocks/client.go | 407 +-----------------
client/resource_groups.go | 89 +---
client/role_assignments.go | 171 +-------
client/roles.go | 82 +---
client/service_principals.go | 174 +-------
client/storage_accounts.go | 172 +-------
client/subscriptions.go | 84 +---
client/tenants.go | 71 +--
client/users.go | 80 +---
client/virtual_machines.go | 87 +---
client/vm_scale_sets.go | 89 +---
client/web_apps.go | 89 +---
cmd/list-app-owners.go | 5 +-
...ist-automation-account-role-assignments.go | 2 +-
cmd/list-automation-accounts.go | 2 +-
cmd/list-container-registries.go | 2 +-
...ist-container-registry-role-assignments.go | 2 +-
cmd/list-device-owners.go | 2 +-
cmd/list-function-app-role-assignments.go | 2 +-
cmd/list-function-apps.go | 10 +-
cmd/list-group-members.go | 2 +-
cmd/list-group-owners.go | 5 +-
cmd/list-groups.go | 2 +-
cmd/list-key-vault-role-assignments.go | 2 +-
cmd/list-key-vaults.go | 5 +-
cmd/list-logic-app-role-assignments.go | 2 +-
cmd/list-logic-apps.go | 5 +-
cmd/list-managed-cluster-role-assignments.go | 2 +-
cmd/list-managed-clusters.go | 5 +-
cmd/list-management-group-role-assignments.go | 2 +-
cmd/list-resource-group-role-assignments.go | 2 +-
cmd/list-resource-groups.go | 2 +-
cmd/list-roles.go | 3 +-
cmd/list-service-principal-owners.go | 2 +-
cmd/list-storage-account-role-assignments.go | 2 +-
cmd/list-storage-accounts.go | 8 +-
cmd/list-storage-containers.go | 8 +-
cmd/list-subscription-role-assignments.go | 2 +-
cmd/list-users.go | 30 +-
cmd/list-virtual-machine-role-assignments.go | 2 +-
cmd/list-virtual-machines.go | 5 +-
cmd/list-vm-scale-set-role-assignments.go | 2 +-
cmd/list-vm-scale-sets.go | 5 +-
cmd/list-web-app-role-assignments.go | 2 +-
cmd/list-web-apps.go | 10 +-
models/azure/app_role_assignment.go | 12 -
models/azure/application.go | 19 -
models/azure/automation_account.go | 11 -
models/azure/container_registry.go | 11 -
models/azure/descendant-info.go | 10 -
models/azure/device.go | 19 -
models/azure/directory_object.go | 10 -
models/azure/function_app.go | 11 -
models/azure/group.go | 19 -
models/azure/key_vault.go | 11 -
models/azure/logic_app.go | 11 -
models/azure/managed_cluster.go | 11 -
models/azure/management_group.go | 10 -
models/azure/member_object.go | 34 --
models/azure/resource_group.go | 11 -
models/azure/role.go | 11 -
models/azure/role_assignment.go | 14 -
models/azure/service_principal.go | 19 -
models/azure/storage_account.go | 11 -
models/azure/storage_container.go | 11 -
models/azure/subscription.go | 10 -
models/azure/tenant.go | 5 -
models/azure/unified_role_assignment.go | 11 -
models/azure/user.go | 11 -
models/azure/virtual_machine.go | 11 -
models/azure/vm_scale_set.go | 11 -
models/azure/web_app.go | 11 -
84 files changed, 376 insertions(+), 3279 deletions(-)
delete mode 100644 models/azure/member_object.go
diff --git a/client/app_role_assignments.go b/client/app_role_assignments.go
index 1975d4f..8b1033b 100644
--- a/client/app_role_assignments.go
+++ b/client/app_role_assignments.go
@@ -20,96 +20,24 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/constants"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureADAppRoleAssignments(ctx context.Context, servicePrincipalId string, params query.GraphParams) (azure.AppRoleAssignmentList, error) {
+// GetAzureADAppRoleAssignments https://learn.microsoft.com/en-us/graph/api/serviceprincipal-list-approleassignedto?view=graph-rest-1.0
+func (s *azureClient) ListAzureADAppRoleAssignments(ctx context.Context, servicePrincipalId string, params query.GraphParams) <-chan azureResult[azure.AppRoleAssignment] {
var (
- path = fmt.Sprintf("/%s/servicePrincipals/%s/appRoleAssignedTo", constants.GraphApiVersion, servicePrincipalId)
- response azure.AppRoleAssignmentList
+ out = make(chan azureResult[azure.AppRoleAssignment])
+ path = fmt.Sprintf("/%s/servicePrincipals/%s/appRoleAssignedTo", constants.GraphApiVersion, servicePrincipalId)
)
if params.Top == 0 {
params.Top = 999
}
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureADAppRoleAssignments(ctx context.Context, servicePrincipal string, params query.GraphParams) <-chan azure.AppRoleAssignmentResult {
- out := make(chan azure.AppRoleAssignmentResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.AppRoleAssignmentResult{}
- nextLink string
- )
-
- if list, err := s.GetAzureADAppRoleAssignments(ctx, servicePrincipal, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.AppRoleAssignmentResult{Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.AppRoleAssignment](s.msgraph, ctx, path, params, out)
- nextLink = list.NextLink
- for nextLink != "" {
- var list azure.AppRoleAssignmentList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.msgraph.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.AppRoleAssignmentResult{Ok: u}); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/apps.go b/client/apps.go
index cf92a6c..4d191bc 100644
--- a/client/apps.go
+++ b/client/apps.go
@@ -19,187 +19,44 @@ package client
import (
"context"
+ "encoding/json"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/constants"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureADAppOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error) {
+// ListAzureADApps https://learn.microsoft.com/en-us/graph/api/application-list?view=graph-rest-beta
+func (s *azureClient) ListAzureADApps(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Application] {
var (
- path = fmt.Sprintf("/%s/applications/%s/owners", constants.GraphApiBetaVersion, objectId)
- response azure.DirectoryObjectList
+ out = make(chan azureResult[azure.Application])
+ path = fmt.Sprintf("/%s/applications", constants.GraphApiVersion)
+
)
if params.Top == 0 {
params.Top = 99
}
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
+ go getAzureObjectList[azure.Application](s.msgraph, ctx, path, params, out)
+
+ return out
}
-func (s *azureClient) GetAzureADApps(ctx context.Context, params query.GraphParams) (azure.ApplicationList, error) {
+// ListAzureADAppOwners https://learn.microsoft.com/en-us/graph/api/application-list-owners?view=graph-rest-beta
+func (s *azureClient) ListAzureADAppOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage] {
+
var (
- path = fmt.Sprintf("/%s/applications", constants.GraphApiVersion)
- response azure.ApplicationList
+ out = make(chan azureResult[json.RawMessage])
+ path = fmt.Sprintf("/%s/applications/%s/owners", constants.GraphApiBetaVersion, objectId)
)
if params.Top == 0 {
params.Top = 99
}
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureADApps(ctx context.Context, params query.GraphParams) <-chan azure.ApplicationResult {
- out := make(chan azure.ApplicationResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.ApplicationResult{}
- nextLink string
- )
-
- if list, err := s.GetAzureADApps(ctx, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.ApplicationResult{Ok: u}); !ok {
- return
- }
- }
-
- nextLink = list.NextLink
- for nextLink != "" {
- var list azure.ApplicationList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- return
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- return
- } else if res, err := s.msgraph.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- return
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- return
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.ApplicationResult{Ok: u}); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
- return out
-}
-
-func (s *azureClient) ListAzureADAppOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.AppOwnerResult {
- out := make(chan azure.AppOwnerResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.AppOwnerResult{}
- nextLink string
- )
-
- if list, err := s.GetAzureADAppOwners(ctx, objectId, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.AppOwnerResult{
- AppId: objectId,
- Ok: u,
- }); !ok {
- return
- }
- }
+ go getAzureObjectList[json.RawMessage](s.msgraph, ctx, path, params, out)
- nextLink = list.NextLink
- for nextLink != "" {
- var list azure.DirectoryObjectList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- return
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- return
- } else if res, err := s.msgraph.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- return
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- return
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.AppOwnerResult{
- AppId: objectId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/automation_accounts.go b/client/automation_accounts.go
index 88a2bcf..ec47f5e 100644
--- a/client/automation_accounts.go
+++ b/client/automation_accounts.go
@@ -20,97 +20,20 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureAutomationAccounts(ctx context.Context, subscriptionId string) (azure.AutomationAccountList, error) {
+// ListAzureAutomationAccounts https://learn.microsoft.com/en-us/rest/api/automation/automation-account/list?view=rest-automation-2021-06-22
+func (s *azureClient) ListAzureAutomationAccounts(ctx context.Context, subscriptionId string) <-chan azureResult[azure.AutomationAccount] {
var (
- path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Automation/automationAccounts", subscriptionId)
- params = query.RMParams{ApiVersion: "2021-06-22"}
- response azure.AutomationAccountList
+ out = make(chan azureResult[azure.AutomationAccount])
+ path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Automation/automationAccounts", subscriptionId)
+ params = query.RMParams{ApiVersion: "2021-06-22"}
)
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureAutomationAccounts(ctx context.Context, subscriptionId string) <-chan azure.AutomationAccountResult {
- out := make(chan azure.AutomationAccountResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.AutomationAccountResult{
- SubscriptionId: subscriptionId,
- }
- nextLink string
- )
-
- if result, err := s.GetAzureAutomationAccounts(ctx, subscriptionId); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.AutomationAccountResult{SubscriptionId: subscriptionId, Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.AutomationAccount](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.AutomationAccountList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.AutomationAccountResult{
- SubscriptionId: "/subscriptions/" + subscriptionId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/client.go b/client/client.go
index e5e988e..d612508 100644
--- a/client/client.go
+++ b/client/client.go
@@ -21,12 +21,17 @@ package client
import (
"context"
+ "encoding/json"
"fmt"
+ "net/http"
+ "net/url"
"github.com/bloodhoundad/azurehound/v2/client/config"
"github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
+ "github.com/bloodhoundad/azurehound/v2/panicrecovery"
+ "github.com/bloodhoundad/azurehound/v2/pipeline"
)
func NewClient(config config.Config) (AzureClient, error) {
@@ -86,6 +91,90 @@ func initClientViaGraph(msgraph, resourceManager rest.RestClient) (AzureClient,
}
}
+type azureResult[T any] struct {
+ Error error
+ Ok T
+}
+
+func getAzureObjectList[T any](client rest.RestClient, ctx context.Context, path string, params query.Params, out chan azureResult[T]) {
+ defer panicrecovery.PanicRecovery()
+ defer close(out)
+
+ var (
+ errResult azureResult[T]
+ nextLink string
+ )
+
+ for {
+ var (
+ list struct {
+ CountGraph int `json:"@odata.count,omitempty"` // The total count of all graph results
+ NextLinkGraph string `json:"@odata.nextLink,omitempty"` // The URL to use for getting the next set of graph values.
+ ContextGraph string `json:"@odata.context,omitempty"`
+ NextLinkRM string `json:"nextLink,omitempty"` // The URL to use for getting the next set of rm values.
+ Value []T `json:"value"` // A list of azure values
+ }
+ res *http.Response
+ err error
+ )
+
+ if nextLink != "" {
+ if nextUrl, err := url.Parse(nextLink); err != nil {
+ errResult.Error = err
+ _ = pipeline.Send(ctx.Done(), out, errResult)
+ return
+ } else {
+ if req, err := rest.NewRequest(ctx, "GET", nextUrl, nil, params.AsMap(), nil); err != nil {
+ errResult.Error = err
+ _ = pipeline.Send(ctx.Done(), out, errResult)
+ return
+ } else if res, err = client.Send(req); err != nil {
+ errResult.Error = err
+ _ = pipeline.Send(ctx.Done(), out, errResult)
+ return
+ }
+ }
+ } else {
+ if res, err = client.Get(ctx, path, params, nil); err != nil {
+ errResult.Error = err
+ _ = pipeline.Send(ctx.Done(), out, errResult)
+ return
+ }
+ }
+
+ if err := rest.Decode(res.Body, &list); err != nil {
+ errResult.Error = err
+ _ = pipeline.Send(ctx.Done(), out, errResult)
+ return
+ } else {
+ for _, u := range list.Value {
+ if ok := pipeline.Send(ctx.Done(), out, azureResult[T]{Ok: u}); !ok {
+ return
+ }
+ }
+ }
+
+ if list.NextLinkRM == "" && list.NextLinkGraph == "" {
+ break
+ } else if list.NextLinkGraph != "" {
+ nextLink = list.NextLinkGraph
+ } else if list.NextLinkRM != "" {
+ nextLink = list.NextLinkRM
+ }
+ }
+}
+
+func getAzureObject[T any](client rest.RestClient, ctx context.Context, path string, params query.Params) (T, error) {
+ var response T
+ if res, err := client.Get(ctx, path, params, nil); err != nil {
+ return response, err
+ } else if err := rest.Decode(res.Body, &response); err != nil {
+ return response, err
+ } else {
+ return response, nil
+ }
+}
+
type azureClient struct {
msgraph rest.RestClient
resourceManager rest.RestClient
@@ -93,72 +182,43 @@ type azureClient struct {
}
type AzureGraphClient interface {
- GetAzureADApps(ctx context.Context, params query.GraphParams) (azure.ApplicationList, error)
- GetAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error)
- GetAzureADGroups(ctx context.Context, params query.GraphParams) (azure.GroupList, error)
GetAzureADOrganization(ctx context.Context, selectCols []string) (*azure.Organization, error)
- GetAzureADRoles(ctx context.Context, filter string) (azure.RoleList, error)
- GetAzureADRoleAssignments(ctx context.Context, params query.GraphParams) (azure.UnifiedRoleAssignmentList, error)
- GetAzureADServicePrincipalOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error)
- GetAzureADServicePrincipals(ctx context.Context, params query.GraphParams) (azure.ServicePrincipalList, error)
- GetAzureADUsers(ctx context.Context, params query.GraphParams) (azure.UserList, error)
- GetAzureDevices(ctx context.Context, params query.GraphParams) (azure.DeviceList, error)
- GetAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error)
- GetAzureADAppRoleAssignments(ctx context.Context, servicePrincipalId string, params query.GraphParams) (azure.AppRoleAssignmentList, error)
-
- // https://learn.microsoft.com/en-us/graph/api/group-list-members?view=graph-rest-beta
- GetAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) (azure.MemberObjectList, error)
- ListAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.MemberObjectResult
-
- ListAzureADUsers(ctx context.Context, params query.GraphParams) <-chan azure.UserResult
- ListAzureADApps(ctx context.Context, params query.GraphParams) <-chan azure.ApplicationResult
- ListAzureADAppOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.AppOwnerResult
- ListAzureADGroups(ctx context.Context, params query.GraphParams) <-chan azure.GroupResult
- ListAzureADRoleAssignments(ctx context.Context, params query.GraphParams) <-chan azure.UnifiedRoleAssignmentResult
- ListAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.GroupOwnerResult
- ListAzureADRoles(ctx context.Context, filter string) <-chan azure.RoleResult
- ListAzureADServicePrincipalOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.ServicePrincipalOwnerResult
- ListAzureADServicePrincipals(ctx context.Context, params query.GraphParams) <-chan azure.ServicePrincipalResult
- ListAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.DeviceRegisteredOwnerResult
- ListAzureDevices(ctx context.Context, params query.GraphParams) <-chan azure.DeviceResult
- ListAzureADAppRoleAssignments(ctx context.Context, servicePrincipal string, params query.GraphParams) <-chan azure.AppRoleAssignmentResult
+
+ ListAzureADGroups(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Group]
+ ListAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage]
+ ListAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage]
+ ListAzureADAppOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage]
+ ListAzureADApps(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Application]
+ ListAzureADUsers(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.User]
+ ListAzureADRoleAssignments(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.UnifiedRoleAssignment]
+ ListAzureADRoles(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Role]
+ ListAzureADServicePrincipalOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage]
+ ListAzureADServicePrincipals(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.ServicePrincipal]
+ ListAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage]
+ ListAzureDevices(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Device]
+ ListAzureADAppRoleAssignments(ctx context.Context, servicePrincipalId string, params query.GraphParams) <-chan azureResult[azure.AppRoleAssignment]
}
type AzureResourceManagerClient interface {
GetAzureADTenants(ctx context.Context, includeAllTenantCategories bool) (azure.TenantList, error)
- GetAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) (azure.KeyVaultList, error)
- GetAzureManagementGroups(ctx context.Context, skipToken string) (azure.ManagementGroupList, error)
- GetAzureResourceGroups(ctx context.Context, subscriptionId string, params query.RMParams) (azure.ResourceGroupList, error)
- GetAzureSubscriptions(ctx context.Context) (azure.SubscriptionList, error)
- GetAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) (azure.VirtualMachineList, error)
- GetAzureStorageAccounts(ctx context.Context, subscriptionId string) (azure.StorageAccountList, error)
- GetRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) (azure.RoleAssignmentList, error)
- GetAzureContainerRegistries(ctx context.Context, subscriptionId string) (azure.ContainerRegistryList, error)
- GetAzureWebApps(ctx context.Context, subscriptionId string) (azure.WebAppList, error)
- GetAzureVMScaleSets(ctx context.Context, subscriptionId string) (azure.VMScaleSetList, error)
- GetAzureStorageContainers(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, filter string, includeDeleted string, maxPageSize string) (azure.StorageContainerList, error)
- GetAzureAutomationAccounts(ctx context.Context, subscriptionId string) (azure.AutomationAccountList, error)
- GetAzureLogicApps(ctx context.Context, subscriptionId string, filter string, top int32) (azure.LogicAppList, error)
- GetAzureFunctionApps(ctx context.Context, subscriptionId string) (azure.FunctionAppList, error)
- GetAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) (azure.DescendantInfoList, error)
-
- ListAzureADTenants(ctx context.Context, includeAllTenantCategories bool) <-chan azure.TenantResult
- ListAzureContainerRegistries(ctx context.Context, subscriptionId string) <-chan azure.ContainerRegistryResult
- ListAzureWebApps(ctx context.Context, subscriptionId string) <-chan azure.WebAppResult
- ListAzureManagedClusters(ctx context.Context, subscriptionId string) <-chan azure.ManagedClusterResult
- ListAzureVMScaleSets(ctx context.Context, subscriptionId string) <-chan azure.VMScaleSetResult
- ListAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azure.KeyVaultResult
- ListAzureManagementGroups(ctx context.Context, skipToken string) <-chan azure.ManagementGroupResult
- ListAzureResourceGroups(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azure.ResourceGroupResult
- ListAzureSubscriptions(ctx context.Context) <-chan azure.SubscriptionResult
- ListAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azure.VirtualMachineResult
- ListAzureStorageAccounts(ctx context.Context, subscriptionId string) <-chan azure.StorageAccountResult
- ListAzureStorageContainers(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, filter string, includeDeleted string, maxPageSize string) <-chan azure.StorageContainerResult
- ListAzureAutomationAccounts(ctx context.Context, subscriptionId string) <-chan azure.AutomationAccountResult
- ListAzureLogicApps(ctx context.Context, subscriptionId string, filter string, top int32) <-chan azure.LogicAppResult
- ListAzureFunctionApps(ctx context.Context, subscriptionId string) <-chan azure.FunctionAppResult
- ListRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) <-chan azure.RoleAssignmentResult
- ListAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) <-chan azure.DescendantInfoResult
+
+ ListRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) <-chan azureResult[azure.RoleAssignment]
+ ListAzureADTenants(ctx context.Context, includeAllTenantCategories bool) <-chan azureResult[azure.Tenant]
+ ListAzureContainerRegistries(ctx context.Context, subscriptionId string) <-chan azureResult[azure.ContainerRegistry]
+ ListAzureWebApps(ctx context.Context, subscriptionId string) <-chan azureResult[azure.WebApp]
+ ListAzureManagedClusters(ctx context.Context, subscriptionId string) <-chan azureResult[azure.ManagedCluster]
+ ListAzureVMScaleSets(ctx context.Context, subscriptionId string) <-chan azureResult[azure.VMScaleSet]
+ ListAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azureResult[azure.KeyVault]
+ ListAzureManagementGroups(ctx context.Context, skipToken string) <-chan azureResult[azure.ManagementGroup]
+ ListAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) <-chan azureResult[azure.DescendantInfo]
+ ListAzureResourceGroups(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azureResult[azure.ResourceGroup]
+ ListAzureSubscriptions(ctx context.Context) <-chan azureResult[azure.Subscription]
+ ListAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azureResult[azure.VirtualMachine]
+ ListAzureStorageAccounts(ctx context.Context, subscriptionId string) <-chan azureResult[azure.StorageAccount]
+ ListAzureStorageContainers(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, filter string, includeDeleted string, maxPageSize string) <-chan azureResult[azure.StorageContainer]
+ ListAzureAutomationAccounts(ctx context.Context, subscriptionId string) <-chan azureResult[azure.AutomationAccount]
+ ListAzureLogicApps(ctx context.Context, subscriptionId string, filter string, top int32) <-chan azureResult[azure.LogicApp]
+ ListAzureFunctionApps(ctx context.Context, subscriptionId string) <-chan azureResult[azure.FunctionApp]
}
type AzureClient interface {
diff --git a/client/container_registries.go b/client/container_registries.go
index ca787d6..fba5830 100644
--- a/client/container_registries.go
+++ b/client/container_registries.go
@@ -20,97 +20,20 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureContainerRegistries(ctx context.Context, subscriptionId string) (azure.ContainerRegistryList, error) {
+// ListAzureContainerRegistries https://learn.microsoft.com/en-us/rest/api/containerregistry/registries/list?view=rest-containerregistry-2023-01-01-preview
+func (s *azureClient) ListAzureContainerRegistries(ctx context.Context, subscriptionId string) <-chan azureResult[azure.ContainerRegistry]{
var (
- path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.ContainerRegistry/registries", subscriptionId)
- params = query.RMParams{ApiVersion: "2023-01-01-preview"}
- response azure.ContainerRegistryList
+ out = make(chan azureResult[azure.ContainerRegistry])
+ path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.ContainerRegistry/registries", subscriptionId)
+ params = query.RMParams{ApiVersion: "2023-01-01-preview"}
)
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureContainerRegistries(ctx context.Context, subscriptionId string) <-chan azure.ContainerRegistryResult {
- out := make(chan azure.ContainerRegistryResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.ContainerRegistryResult{
- SubscriptionId: subscriptionId,
- }
- nextLink string
- )
-
- if result, err := s.GetAzureContainerRegistries(ctx, subscriptionId); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.ContainerRegistryResult{SubscriptionId: subscriptionId, Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.ContainerRegistry](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.ContainerRegistryList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.ContainerRegistryResult{
- SubscriptionId: "/subscriptions/" + subscriptionId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/devices.go b/client/devices.go
index e86d400..9cb51e8 100644
--- a/client/devices.go
+++ b/client/devices.go
@@ -19,183 +19,38 @@ package client
import (
"context"
+ "encoding/json"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/constants"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error) {
+// ListAzureDevices https://learn.microsoft.com/en-us/graph/api/device-list?view=graph-rest-1.0
+func (s *azureClient) ListAzureDevices(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Device]{
var (
- path = fmt.Sprintf("/%s/devices/%s/registeredOwners", constants.GraphApiBetaVersion, objectId)
- response azure.DirectoryObjectList
- )
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) GetAzureDevices(ctx context.Context, params query.GraphParams) (azure.DeviceList, error) {
- var (
- path = fmt.Sprintf("/%s/devices", constants.GraphApiVersion)
- response azure.DeviceList
+ out = make(chan azureResult[azure.Device])
+ path = fmt.Sprintf("/%s/devices", constants.GraphApiVersion)
)
if params.Top == 0 {
params.Top = 999
}
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-func (s *azureClient) ListAzureDevices(ctx context.Context, params query.GraphParams) <-chan azure.DeviceResult {
- out := make(chan azure.DeviceResult)
+ go getAzureObjectList[azure.Device](s.msgraph, ctx, path, params, out)
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.DeviceResult{}
- nextLink string
- )
-
- if list, err := s.GetAzureDevices(ctx, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.DeviceResult{Ok: u}); !ok {
- return
- }
- }
-
- nextLink = list.NextLink
- for nextLink != "" {
- var list azure.DeviceList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.msgraph.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.DeviceResult{Ok: u}); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
-func (s *azureClient) ListAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.DeviceRegisteredOwnerResult {
- out := make(chan azure.DeviceRegisteredOwnerResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.DeviceRegisteredOwnerResult{
- DeviceId: objectId,
- }
- nextLink string
- )
+// ListAzureDeviceRegisteredOwners https://learn.microsoft.com/en-us/graph/api/device-list-registeredowners?view=graph-rest-beta
+func (s *azureClient) ListAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage] {
+ var (
+ out = make(chan azureResult[json.RawMessage])
+ path = fmt.Sprintf("/%s/devices/%s/registeredOwners", constants.GraphApiBetaVersion, objectId)
+ )
- if list, err := s.GetAzureDeviceRegisteredOwners(ctx, objectId, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.DeviceRegisteredOwnerResult{
- DeviceId: objectId,
- Ok: u,
- }); !ok {
- return
- }
- }
+ go getAzureObjectList[json.RawMessage](s.msgraph, ctx, path, params, out)
- nextLink = list.NextLink
- for nextLink != "" {
- var list azure.DirectoryObjectList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.msgraph.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.DeviceRegisteredOwnerResult{
- DeviceId: objectId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/function_apps.go b/client/function_apps.go
index 296f789..eeb44e1 100644
--- a/client/function_apps.go
+++ b/client/function_apps.go
@@ -20,97 +20,20 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureFunctionApps(ctx context.Context, subscriptionId string) (azure.FunctionAppList, error) {
+// ListAzureFunctionApps
+func (s *azureClient) ListAzureFunctionApps(ctx context.Context, subscriptionId string) <-chan azureResult[azure.FunctionApp] {
var (
- path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Web/sites", subscriptionId)
- params = query.RMParams{ApiVersion: "2022-03-01"}
- response azure.FunctionAppList
+ out = make(chan azureResult[azure.FunctionApp])
+ path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Web/sites", subscriptionId)
+ params = query.RMParams{ApiVersion: "2022-03-01"}
)
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureFunctionApps(ctx context.Context, subscriptionId string) <-chan azure.FunctionAppResult {
- out := make(chan azure.FunctionAppResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.FunctionAppResult{
- SubscriptionId: subscriptionId,
- }
- nextLink string
- )
-
- if result, err := s.GetAzureFunctionApps(ctx, subscriptionId); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.FunctionAppResult{SubscriptionId: subscriptionId, Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.FunctionApp](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.FunctionAppList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.FunctionAppResult{
- SubscriptionId: "/subscriptions/" + subscriptionId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/groups.go b/client/groups.go
index ff86db0..130b96f 100644
--- a/client/groups.go
+++ b/client/groups.go
@@ -19,279 +19,54 @@ package client
import (
"context"
+ "encoding/json"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/constants"
- "github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-
-func (s *azureClient) GetAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error) {
+// ListAzureADGroups https://learn.microsoft.com/en-us/graph/api/group-list?view=graph-rest-beta
+func (s *azureClient) ListAzureADGroups(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Group] {
var (
- path = fmt.Sprintf("/%s/groups/%s/owners", constants.GraphApiBetaVersion, objectId)
- response azure.DirectoryObjectList
+ out = make(chan azureResult[azure.Group])
+ path = fmt.Sprintf("/%s/groups", constants.GraphApiVersion)
)
if params.Top == 0 {
params.Top = 99
}
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
+ go getAzureObjectList[azure.Group](s.msgraph, ctx, path, params, out)
-func (s *azureClient) GetAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) (azure.MemberObjectList, error) {
- var (
- path = fmt.Sprintf("/%s/groups/%s/members", constants.GraphApiBetaVersion, objectId)
- response azure.MemberObjectList
- )
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
+ return out
}
-func (s *azureClient) GetAzureADGroups(ctx context.Context, params query.GraphParams) (azure.GroupList, error) {
+// ListAzureADGroupOwners https://learn.microsoft.com/en-us/graph/api/group-list-owners?view=graph-rest-beta
+func (s *azureClient) ListAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage] {
var (
- path = fmt.Sprintf("/%s/groups", constants.GraphApiVersion)
- response azure.GroupList
+ out = make(chan azureResult[json.RawMessage])
+ path = fmt.Sprintf("/%s/groups/%s/owners", constants.GraphApiBetaVersion, objectId)
)
if params.Top == 0 {
params.Top = 99
}
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureADGroups(ctx context.Context, params query.GraphParams) <-chan azure.GroupResult {
- out := make(chan azure.GroupResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.GroupResult{}
- nextLink string
- )
+ go getAzureObjectList[json.RawMessage](s.msgraph, ctx, path, params, out)
- if list, err := s.GetAzureADGroups(ctx, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.GroupResult{Ok: u}); !ok {
- return
- }
- }
-
- nextLink = list.NextLink
- for nextLink != "" {
- var list azure.GroupList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.msgraph.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.GroupResult{Ok: u}); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
- return out
-}
-
-func (s *azureClient) ListAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.GroupOwnerResult {
- out := make(chan azure.GroupOwnerResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.GroupOwnerResult{}
- nextLink string
- )
-
- if list, err := s.GetAzureADGroupOwners(ctx, objectId, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.GroupOwnerResult{
- GroupId: objectId,
- Ok: u,
- }); !ok {
- return
- }
- }
-
- nextLink = list.NextLink
- for nextLink != "" {
- var list azure.DirectoryObjectList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.msgraph.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.GroupOwnerResult{
- GroupId: objectId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
-func (s *azureClient) ListAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.MemberObjectResult {
- out := make(chan azure.MemberObjectResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.MemberObjectResult{
- ParentId: objectId,
- ParentType: enums.EntityGroup,
- }
- nextLink string
- )
+// ListAzureADGroupMembers https://learn.microsoft.com/en-us/graph/api/group-list-members?view=graph-rest-beta
+func (s *azureClient) ListAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage] {
+ var (
+ out = make(chan azureResult[json.RawMessage])
+ path = fmt.Sprintf("/%s/groups/%s/members", constants.GraphApiBetaVersion, objectId)
+ )
- if list, err := s.GetAzureADGroupMembers(ctx, objectId, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.MemberObjectResult{
- ParentId: objectId,
- ParentType: string(enums.EntityGroup),
- Ok: u,
- }); !ok {
- return
- }
- }
+ go getAzureObjectList[json.RawMessage](s.msgraph, ctx, path, params, out)
- nextLink = list.NextLink
- for nextLink != "" {
- var list azure.MemberObjectList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.msgraph.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.MemberObjectResult{
- ParentId: objectId,
- ParentType: string(enums.EntityGroup),
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/keyvaults.go b/client/keyvaults.go
index c2442df..91b38cb 100644
--- a/client/keyvaults.go
+++ b/client/keyvaults.go
@@ -20,103 +20,23 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) (azure.KeyVaultList, error) {
+// ListAzureKeyVaults https://learn.microsoft.com/en-us/rest/api/keyvault/keyvault/vaults/list-by-subscription?view=rest-keyvault-keyvault-2019-09-01
+func (s *azureClient) ListAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azureResult[azure.KeyVault] {
var (
- path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.KeyVault/vaults", subscriptionId)
- response azure.KeyVaultList
+ out = make(chan azureResult[azure.KeyVault])
+ path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.KeyVault/vaults", subscriptionId)
)
if params.ApiVersion == "" {
params.ApiVersion = "2019-09-01"
}
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azure.KeyVaultResult {
- out := make(chan azure.KeyVaultResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.KeyVaultResult{
- SubscriptionId: subscriptionId,
- }
- nextLink string
- )
-
- if result, err := s.GetAzureKeyVaults(ctx, subscriptionId, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.KeyVaultResult{
- SubscriptionId: subscriptionId,
- Ok: u,
- }); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.KeyVault](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.KeyVaultList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.KeyVaultResult{
- SubscriptionId: subscriptionId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/logic_apps.go b/client/logic_apps.go
index d460574..202da2a 100644
--- a/client/logic_apps.go
+++ b/client/logic_apps.go
@@ -20,97 +20,20 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureLogicApps(ctx context.Context, subscriptionId string, filter string, top int32) (azure.LogicAppList, error) {
+// ListAzureLogicApps https://learn.microsoft.com/en-us/rest/api/logic/workflows/list-by-subscription?view=rest-logic-2016-06-01
+func (s *azureClient) ListAzureLogicApps(ctx context.Context, subscriptionId string, filter string, top int32) <-chan azureResult[azure.LogicApp] {
var (
+ out = make(chan azureResult[azure.LogicApp])
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Logic/workflows", subscriptionId)
params = query.RMParams{ApiVersion: "2016-06-01", Filter: filter, Top: top}
- response azure.LogicAppList
)
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureLogicApps(ctx context.Context, subscriptionId string, filter string, top int32) <-chan azure.LogicAppResult {
- out := make(chan azure.LogicAppResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.LogicAppResult{
- SubscriptionId: subscriptionId,
- }
- nextLink string
- )
-
- if result, err := s.GetAzureLogicApps(ctx, subscriptionId, filter, top); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.LogicAppResult{SubscriptionId: subscriptionId, Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.LogicApp](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.LogicAppList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.LogicAppResult{
- SubscriptionId: "/subscriptions/" + subscriptionId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/managed_clusters.go b/client/managed_clusters.go
index ea7ad7c..8c9d421 100644
--- a/client/managed_clusters.go
+++ b/client/managed_clusters.go
@@ -20,97 +20,20 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureManagedClusters(ctx context.Context, subscriptionId string) (azure.ManagedClusterList, error) {
+// ListAzureManagedClusters https://learn.microsoft.com/en-us/rest/api/servicefabric/managedclusters/managed-clusters/list-by-subscription?view=rest-servicefabric-managedclusters-2021-07-01
+func (s *azureClient) ListAzureManagedClusters(ctx context.Context, subscriptionId string) <-chan azureResult[azure.ManagedCluster] {
var (
- path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.ContainerService/managedClusters", subscriptionId)
- params = query.RMParams{ApiVersion: "2021-07-01"}
- response azure.ManagedClusterList
+ out = make(chan azureResult[azure.ManagedCluster])
+ path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.ContainerService/managedClusters", subscriptionId)
+ params = query.RMParams{ApiVersion: "2021-07-01"}
)
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureManagedClusters(ctx context.Context, subscriptionId string) <-chan azure.ManagedClusterResult {
- out := make(chan azure.ManagedClusterResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.ManagedClusterResult{
- SubscriptionId: subscriptionId,
- }
- nextLink string
- )
-
- if result, err := s.GetAzureManagedClusters(ctx, subscriptionId); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.ManagedClusterResult{SubscriptionId: subscriptionId, Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.ManagedCluster](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.ManagedClusterList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.ManagedClusterResult{
- SubscriptionId: "/subscriptions/" + subscriptionId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/management_groups.go b/client/management_groups.go
index ece4fe5..c2932a0 100644
--- a/client/management_groups.go
+++ b/client/management_groups.go
@@ -20,173 +20,33 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureManagementGroups(ctx context.Context, skipToken string) (azure.ManagementGroupList, error) {
+// ListAzureManagementGroups https://learn.microsoft.com/en-us/rest/api/managementgroups/management-groups/list?view=rest-managementgroups-2020-05-01
+func (s *azureClient) ListAzureManagementGroups(ctx context.Context, skipToken string) <-chan azureResult[azure.ManagementGroup] {
var (
- path = "/providers/Microsoft.Management/managementGroups"
- params = query.RMParams{ApiVersion: "2020-05-01", SkipToken: skipToken}
- response azure.ManagementGroupList
+ out = make(chan azureResult[azure.ManagementGroup])
+ path = "/providers/Microsoft.Management/managementGroups"
+ params = query.RMParams{ApiVersion: "2020-05-01", SkipToken: skipToken}
)
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) GetAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) (azure.DescendantInfoList, error) {
- var (
- path = fmt.Sprintf("/providers/Microsoft.Management/managementGroups/%s/descendants", groupId)
- params = query.RMParams{ApiVersion: "2020-05-01", Top: top}
- response azure.DescendantInfoList
- )
-
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureManagementGroups(ctx context.Context, skipToken string) <-chan azure.ManagementGroupResult {
- out := make(chan azure.ManagementGroupResult)
+ go getAzureObjectList[azure.ManagementGroup](s.resourceManager, ctx, path, params, out)
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.ManagementGroupResult{}
- nextLink string
- )
-
- if result, err := s.GetAzureManagementGroups(ctx, skipToken); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.ManagementGroupResult{Ok: u}); !ok {
- return
- }
- }
-
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.ManagementGroupList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.ManagementGroupResult{Ok: u}); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
-func (s *azureClient) ListAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) <-chan azure.DescendantInfoResult {
- out := make(chan azure.DescendantInfoResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.DescendantInfoResult{}
- nextLink string
- )
+// ListAzureManagementGroupDescendants https://learn.microsoft.com/en-us/rest/api/managementgroups/management-groups/get-descendants?view=rest-managementgroups-2020-05-01
+func (s *azureClient) ListAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) <-chan azureResult[azure.DescendantInfo] {
+ var (
+ out = make(chan azureResult[azure.DescendantInfo])
+ path = fmt.Sprintf("/providers/Microsoft.Management/managementGroups/%s/descendants", groupId)
+ params = query.RMParams{ApiVersion: "2020-05-01", Top: top}
+ )
- if result, err := s.GetAzureManagementGroupDescendants(ctx, groupId, top); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.DescendantInfoResult{Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.DescendantInfo](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.DescendantInfoList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.DescendantInfoResult{Ok: u}); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/mocks/client.go b/client/mocks/client.go
index 6ead097..ce00d37 100644
--- a/client/mocks/client.go
+++ b/client/mocks/client.go
@@ -48,81 +48,6 @@ func (mr *MockAzureClientMockRecorder) CloseIdleConnections() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CloseIdleConnections", reflect.TypeOf((*MockAzureClient)(nil).CloseIdleConnections))
}
-// GetAzureADAppRoleAssignments mocks base method.
-func (m *MockAzureClient) GetAzureADAppRoleAssignments(arg0 context.Context, arg1 string, arg2 query.GraphParams) (azure.AppRoleAssignmentList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADAppRoleAssignments", arg0, arg1, arg2)
- ret0, _ := ret[0].(azure.AppRoleAssignmentList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureADAppRoleAssignments indicates an expected call of GetAzureADAppRoleAssignments.
-func (mr *MockAzureClientMockRecorder) GetAzureADAppRoleAssignments(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADAppRoleAssignments", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADAppRoleAssignments), arg0, arg1, arg2)
-}
-
-// GetAzureADApps mocks base method.
-func (m *MockAzureClient) GetAzureADApps(arg0 context.Context, arg1 query.GraphParams) (azure.ApplicationList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADApps", arg0, arg1)
- ret0, _ := ret[0].(azure.ApplicationList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureADApps indicates an expected call of GetAzureADApps.
-func (mr *MockAzureClientMockRecorder) GetAzureADApps(arg0, arg1 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADApps", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADApps), arg0, arg1)
-}
-
-// GetAzureADGroupMembers mocks base method.
-func (m *MockAzureClient) GetAzureADGroupMembers(arg0 context.Context, arg1 string, arg2 query.GraphParams) (azure.MemberObjectList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADGroupMembers", arg0, arg1, arg2)
- ret0, _ := ret[0].(azure.MemberObjectList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureADGroupMembers indicates an expected call of GetAzureADGroupMembers.
-func (mr *MockAzureClientMockRecorder) GetAzureADGroupMembers(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADGroupMembers", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADGroupMembers), arg0, arg1, arg2)
-}
-
-// GetAzureADGroupOwners mocks base method.
-func (m *MockAzureClient) GetAzureADGroupOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) (azure.DirectoryObjectList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADGroupOwners", arg0, arg1, arg2)
- ret0, _ := ret[0].(azure.DirectoryObjectList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureADGroupOwners indicates an expected call of GetAzureADGroupOwners.
-func (mr *MockAzureClientMockRecorder) GetAzureADGroupOwners(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADGroupOwners", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADGroupOwners), arg0, arg1, arg2)
-}
-
-// GetAzureADGroups mocks base method.
-func (m *MockAzureClient) GetAzureADGroups(arg0 context.Context, arg1 query.GraphParams) (azure.GroupList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADGroups", arg0, arg1)
- ret0, _ := ret[0].(azure.GroupList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureADGroups indicates an expected call of GetAzureADGroups.
-func (mr *MockAzureClientMockRecorder) GetAzureADGroups(arg0, arg1 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADGroups", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADGroups), arg0, arg1)
-}
-
// GetAzureADOrganization mocks base method.
func (m *MockAzureClient) GetAzureADOrganization(arg0 context.Context, arg1 []string) (*azure.Organization, error) {
m.ctrl.T.Helper()
@@ -138,66 +63,6 @@ func (mr *MockAzureClientMockRecorder) GetAzureADOrganization(arg0, arg1 interfa
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADOrganization", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADOrganization), arg0, arg1)
}
-// GetAzureADRoleAssignments mocks base method.
-func (m *MockAzureClient) GetAzureADRoleAssignments(arg0 context.Context, arg1 query.GraphParams) (azure.UnifiedRoleAssignmentList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADRoleAssignments", arg0, arg1)
- ret0, _ := ret[0].(azure.UnifiedRoleAssignmentList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureADRoleAssignments indicates an expected call of GetAzureADRoleAssignments.
-func (mr *MockAzureClientMockRecorder) GetAzureADRoleAssignments(arg0, arg1 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADRoleAssignments", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADRoleAssignments), arg0, arg1)
-}
-
-// GetAzureADRoles mocks base method.
-func (m *MockAzureClient) GetAzureADRoles(arg0 context.Context, arg1 string) (azure.RoleList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADRoles", arg0, arg1)
- ret0, _ := ret[0].(azure.RoleList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureADRoles indicates an expected call of GetAzureADRoles.
-func (mr *MockAzureClientMockRecorder) GetAzureADRoles(arg0, arg1 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADRoles", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADRoles), arg0, arg1)
-}
-
-// GetAzureADServicePrincipalOwners mocks base method.
-func (m *MockAzureClient) GetAzureADServicePrincipalOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) (azure.DirectoryObjectList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADServicePrincipalOwners", arg0, arg1, arg2)
- ret0, _ := ret[0].(azure.DirectoryObjectList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureADServicePrincipalOwners indicates an expected call of GetAzureADServicePrincipalOwners.
-func (mr *MockAzureClientMockRecorder) GetAzureADServicePrincipalOwners(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADServicePrincipalOwners", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADServicePrincipalOwners), arg0, arg1, arg2)
-}
-
-// GetAzureADServicePrincipals mocks base method.
-func (m *MockAzureClient) GetAzureADServicePrincipals(arg0 context.Context, arg1 query.GraphParams) (azure.ServicePrincipalList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADServicePrincipals", arg0, arg1)
- ret0, _ := ret[0].(azure.ServicePrincipalList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureADServicePrincipals indicates an expected call of GetAzureADServicePrincipals.
-func (mr *MockAzureClientMockRecorder) GetAzureADServicePrincipals(arg0, arg1 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADServicePrincipals", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADServicePrincipals), arg0, arg1)
-}
-
// GetAzureADTenants mocks base method.
func (m *MockAzureClient) GetAzureADTenants(arg0 context.Context, arg1 bool) (azure.TenantList, error) {
m.ctrl.T.Helper()
@@ -213,276 +78,6 @@ func (mr *MockAzureClientMockRecorder) GetAzureADTenants(arg0, arg1 interface{})
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADTenants", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADTenants), arg0, arg1)
}
-// GetAzureADUsers mocks base method.
-func (m *MockAzureClient) GetAzureADUsers(arg0 context.Context, arg1 query.GraphParams) (azure.UserList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureADUsers", arg0, arg1)
- ret0, _ := ret[0].(azure.UserList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureADUsers indicates an expected call of GetAzureADUsers.
-func (mr *MockAzureClientMockRecorder) GetAzureADUsers(arg0, arg1 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureADUsers", reflect.TypeOf((*MockAzureClient)(nil).GetAzureADUsers), arg0, arg1)
-}
-
-// GetAzureAutomationAccounts mocks base method.
-func (m *MockAzureClient) GetAzureAutomationAccounts(arg0 context.Context, arg1 string) (azure.AutomationAccountList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureAutomationAccounts", arg0, arg1)
- ret0, _ := ret[0].(azure.AutomationAccountList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureAutomationAccounts indicates an expected call of GetAzureAutomationAccounts.
-func (mr *MockAzureClientMockRecorder) GetAzureAutomationAccounts(arg0, arg1 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureAutomationAccounts", reflect.TypeOf((*MockAzureClient)(nil).GetAzureAutomationAccounts), arg0, arg1)
-}
-
-// GetAzureContainerRegistries mocks base method.
-func (m *MockAzureClient) GetAzureContainerRegistries(arg0 context.Context, arg1 string) (azure.ContainerRegistryList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureContainerRegistries", arg0, arg1)
- ret0, _ := ret[0].(azure.ContainerRegistryList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureContainerRegistries indicates an expected call of GetAzureContainerRegistries.
-func (mr *MockAzureClientMockRecorder) GetAzureContainerRegistries(arg0, arg1 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureContainerRegistries", reflect.TypeOf((*MockAzureClient)(nil).GetAzureContainerRegistries), arg0, arg1)
-}
-
-// GetAzureDeviceRegisteredOwners mocks base method.
-func (m *MockAzureClient) GetAzureDeviceRegisteredOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) (azure.DirectoryObjectList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureDeviceRegisteredOwners", arg0, arg1, arg2)
- ret0, _ := ret[0].(azure.DirectoryObjectList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureDeviceRegisteredOwners indicates an expected call of GetAzureDeviceRegisteredOwners.
-func (mr *MockAzureClientMockRecorder) GetAzureDeviceRegisteredOwners(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureDeviceRegisteredOwners", reflect.TypeOf((*MockAzureClient)(nil).GetAzureDeviceRegisteredOwners), arg0, arg1, arg2)
-}
-
-// GetAzureDevices mocks base method.
-func (m *MockAzureClient) GetAzureDevices(arg0 context.Context, arg1 query.GraphParams) (azure.DeviceList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureDevices", arg0, arg1)
- ret0, _ := ret[0].(azure.DeviceList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureDevices indicates an expected call of GetAzureDevices.
-func (mr *MockAzureClientMockRecorder) GetAzureDevices(arg0, arg1 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureDevices", reflect.TypeOf((*MockAzureClient)(nil).GetAzureDevices), arg0, arg1)
-}
-
-// GetAzureFunctionApps mocks base method.
-func (m *MockAzureClient) GetAzureFunctionApps(arg0 context.Context, arg1 string) (azure.FunctionAppList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureFunctionApps", arg0, arg1)
- ret0, _ := ret[0].(azure.FunctionAppList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureFunctionApps indicates an expected call of GetAzureFunctionApps.
-func (mr *MockAzureClientMockRecorder) GetAzureFunctionApps(arg0, arg1 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureFunctionApps", reflect.TypeOf((*MockAzureClient)(nil).GetAzureFunctionApps), arg0, arg1)
-}
-
-// GetAzureKeyVaults mocks base method.
-func (m *MockAzureClient) GetAzureKeyVaults(arg0 context.Context, arg1 string, arg2 query.RMParams) (azure.KeyVaultList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureKeyVaults", arg0, arg1, arg2)
- ret0, _ := ret[0].(azure.KeyVaultList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureKeyVaults indicates an expected call of GetAzureKeyVaults.
-func (mr *MockAzureClientMockRecorder) GetAzureKeyVaults(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureKeyVaults", reflect.TypeOf((*MockAzureClient)(nil).GetAzureKeyVaults), arg0, arg1, arg2)
-}
-
-// GetAzureLogicApps mocks base method.
-func (m *MockAzureClient) GetAzureLogicApps(arg0 context.Context, arg1, arg2 string, arg3 int32) (azure.LogicAppList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureLogicApps", arg0, arg1, arg2, arg3)
- ret0, _ := ret[0].(azure.LogicAppList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureLogicApps indicates an expected call of GetAzureLogicApps.
-func (mr *MockAzureClientMockRecorder) GetAzureLogicApps(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureLogicApps", reflect.TypeOf((*MockAzureClient)(nil).GetAzureLogicApps), arg0, arg1, arg2, arg3)
-}
-
-// GetAzureManagementGroupDescendants mocks base method.
-func (m *MockAzureClient) GetAzureManagementGroupDescendants(arg0 context.Context, arg1 string, arg2 int32) (azure.DescendantInfoList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureManagementGroupDescendants", arg0, arg1, arg2)
- ret0, _ := ret[0].(azure.DescendantInfoList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureManagementGroupDescendants indicates an expected call of GetAzureManagementGroupDescendants.
-func (mr *MockAzureClientMockRecorder) GetAzureManagementGroupDescendants(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureManagementGroupDescendants", reflect.TypeOf((*MockAzureClient)(nil).GetAzureManagementGroupDescendants), arg0, arg1, arg2)
-}
-
-// GetAzureManagementGroups mocks base method.
-func (m *MockAzureClient) GetAzureManagementGroups(arg0 context.Context, arg1 string) (azure.ManagementGroupList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureManagementGroups", arg0, arg1)
- ret0, _ := ret[0].(azure.ManagementGroupList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureManagementGroups indicates an expected call of GetAzureManagementGroups.
-func (mr *MockAzureClientMockRecorder) GetAzureManagementGroups(arg0, arg1 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureManagementGroups", reflect.TypeOf((*MockAzureClient)(nil).GetAzureManagementGroups), arg0, arg1)
-}
-
-// GetAzureResourceGroups mocks base method.
-func (m *MockAzureClient) GetAzureResourceGroups(arg0 context.Context, arg1 string, arg2 query.RMParams) (azure.ResourceGroupList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureResourceGroups", arg0, arg1, arg2)
- ret0, _ := ret[0].(azure.ResourceGroupList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureResourceGroups indicates an expected call of GetAzureResourceGroups.
-func (mr *MockAzureClientMockRecorder) GetAzureResourceGroups(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureResourceGroups", reflect.TypeOf((*MockAzureClient)(nil).GetAzureResourceGroups), arg0, arg1, arg2)
-}
-
-// GetAzureStorageAccounts mocks base method.
-func (m *MockAzureClient) GetAzureStorageAccounts(arg0 context.Context, arg1 string) (azure.StorageAccountList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureStorageAccounts", arg0, arg1)
- ret0, _ := ret[0].(azure.StorageAccountList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureStorageAccounts indicates an expected call of GetAzureStorageAccounts.
-func (mr *MockAzureClientMockRecorder) GetAzureStorageAccounts(arg0, arg1 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureStorageAccounts", reflect.TypeOf((*MockAzureClient)(nil).GetAzureStorageAccounts), arg0, arg1)
-}
-
-// GetAzureStorageContainers mocks base method.
-func (m *MockAzureClient) GetAzureStorageContainers(arg0 context.Context, arg1, arg2, arg3, arg4, arg5, arg6 string) (azure.StorageContainerList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureStorageContainers", arg0, arg1, arg2, arg3, arg4, arg5, arg6)
- ret0, _ := ret[0].(azure.StorageContainerList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureStorageContainers indicates an expected call of GetAzureStorageContainers.
-func (mr *MockAzureClientMockRecorder) GetAzureStorageContainers(arg0, arg1, arg2, arg3, arg4, arg5, arg6 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureStorageContainers", reflect.TypeOf((*MockAzureClient)(nil).GetAzureStorageContainers), arg0, arg1, arg2, arg3, arg4, arg5, arg6)
-}
-
-// GetAzureSubscriptions mocks base method.
-func (m *MockAzureClient) GetAzureSubscriptions(arg0 context.Context) (azure.SubscriptionList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureSubscriptions", arg0)
- ret0, _ := ret[0].(azure.SubscriptionList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureSubscriptions indicates an expected call of GetAzureSubscriptions.
-func (mr *MockAzureClientMockRecorder) GetAzureSubscriptions(arg0 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureSubscriptions", reflect.TypeOf((*MockAzureClient)(nil).GetAzureSubscriptions), arg0)
-}
-
-// GetAzureVMScaleSets mocks base method.
-func (m *MockAzureClient) GetAzureVMScaleSets(arg0 context.Context, arg1 string) (azure.VMScaleSetList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureVMScaleSets", arg0, arg1)
- ret0, _ := ret[0].(azure.VMScaleSetList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureVMScaleSets indicates an expected call of GetAzureVMScaleSets.
-func (mr *MockAzureClientMockRecorder) GetAzureVMScaleSets(arg0, arg1 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureVMScaleSets", reflect.TypeOf((*MockAzureClient)(nil).GetAzureVMScaleSets), arg0, arg1)
-}
-
-// GetAzureVirtualMachines mocks base method.
-func (m *MockAzureClient) GetAzureVirtualMachines(arg0 context.Context, arg1 string, arg2 query.RMParams) (azure.VirtualMachineList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureVirtualMachines", arg0, arg1, arg2)
- ret0, _ := ret[0].(azure.VirtualMachineList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureVirtualMachines indicates an expected call of GetAzureVirtualMachines.
-func (mr *MockAzureClientMockRecorder) GetAzureVirtualMachines(arg0, arg1, arg2 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureVirtualMachines", reflect.TypeOf((*MockAzureClient)(nil).GetAzureVirtualMachines), arg0, arg1, arg2)
-}
-
-// GetAzureWebApps mocks base method.
-func (m *MockAzureClient) GetAzureWebApps(arg0 context.Context, arg1 string) (azure.WebAppList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetAzureWebApps", arg0, arg1)
- ret0, _ := ret[0].(azure.WebAppList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetAzureWebApps indicates an expected call of GetAzureWebApps.
-func (mr *MockAzureClientMockRecorder) GetAzureWebApps(arg0, arg1 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAzureWebApps", reflect.TypeOf((*MockAzureClient)(nil).GetAzureWebApps), arg0, arg1)
-}
-
-// GetRoleAssignmentsForResource mocks base method.
-func (m *MockAzureClient) GetRoleAssignmentsForResource(arg0 context.Context, arg1, arg2, arg3 string) (azure.RoleAssignmentList, error) {
- m.ctrl.T.Helper()
- ret := m.ctrl.Call(m, "GetRoleAssignmentsForResource", arg0, arg1, arg2, arg3)
- ret0, _ := ret[0].(azure.RoleAssignmentList)
- ret1, _ := ret[1].(error)
- return ret0, ret1
-}
-
-// GetRoleAssignmentsForResource indicates an expected call of GetRoleAssignmentsForResource.
-func (mr *MockAzureClientMockRecorder) GetRoleAssignmentsForResource(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
- mr.mock.ctrl.T.Helper()
- return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRoleAssignmentsForResource", reflect.TypeOf((*MockAzureClient)(nil).GetRoleAssignmentsForResource), arg0, arg1, arg2, arg3)
-}
-
// ListAzureADAppOwners mocks base method.
func (m *MockAzureClient) ListAzureADAppOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan azure.AppOwnerResult {
m.ctrl.T.Helper()
@@ -582,7 +177,7 @@ func (mr *MockAzureClientMockRecorder) ListAzureADRoleAssignments(arg0, arg1 int
}
// ListAzureADRoles mocks base method.
-func (m *MockAzureClient) ListAzureADRoles(arg0 context.Context, arg1 string) <-chan azure.RoleResult {
+func (m *MockAzureClient) ListAzureADRoles(arg0 context.Context, arg1 query.GraphParams) <-chan azure.RoleResult {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureADRoles", arg0, arg1)
ret0, _ := ret[0].(<-chan azure.RoleResult)
diff --git a/client/resource_groups.go b/client/resource_groups.go
index 543dfa8..ae3364c 100644
--- a/client/resource_groups.go
+++ b/client/resource_groups.go
@@ -20,102 +20,23 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureResourceGroups(ctx context.Context, subscriptionId string, params query.RMParams) (azure.ResourceGroupList, error) {
+// ListAzureResourceGroups https://learn.microsoft.com/en-us/rest/api/resources/resource-groups/list?view=rest-resources-2021-04-01
+func (s *azureClient) ListAzureResourceGroups(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azureResult[azure.ResourceGroup] {
var (
- path = fmt.Sprintf("/subscriptions/%s/resourcegroups", subscriptionId)
- response azure.ResourceGroupList
+ out = make(chan azureResult[azure.ResourceGroup])
+ path = fmt.Sprintf("/subscriptions/%s/resourcegroups", subscriptionId)
)
if params.ApiVersion == "" {
params.ApiVersion = "2021-04-01"
}
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureResourceGroups(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azure.ResourceGroupResult {
- out := make(chan azure.ResourceGroupResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- objectId = fmt.Sprintf("/subscriptions/%s", subscriptionId)
- errResult = azure.ResourceGroupResult{SubscriptionId: objectId}
- nextLink string
- )
-
- if result, err := s.GetAzureResourceGroups(ctx, subscriptionId, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.ResourceGroupResult{
- SubscriptionId: objectId,
- Ok: u,
- }); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.ResourceGroup](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.ResourceGroupList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.ResourceGroupResult{
- SubscriptionId: objectId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/role_assignments.go b/client/role_assignments.go
index ab6f873..5fa841d 100644
--- a/client/role_assignments.go
+++ b/client/role_assignments.go
@@ -20,184 +20,37 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/constants"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureADRoleAssignments(ctx context.Context, params query.GraphParams) (azure.UnifiedRoleAssignmentList, error) {
+// ListAzureADRoleAssignments https://learn.microsoft.com/en-us/graph/api/rbacapplication-list-roleassignments?view=graph-rest-beta
+func (s *azureClient) ListAzureADRoleAssignments(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.UnifiedRoleAssignment] {
var (
- path = fmt.Sprintf("/%s/roleManagement/directory/roleAssignments", constants.GraphApiVersion)
- response azure.UnifiedRoleAssignmentList
+ out = make(chan azureResult[azure.UnifiedRoleAssignment])
+ path = fmt.Sprintf("/%s/roleManagement/directory/roleAssignments", constants.GraphApiVersion)
+
)
if params.Top == 0 {
params.Top = 999
}
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureADRoleAssignments(ctx context.Context, params query.GraphParams) <-chan azure.UnifiedRoleAssignmentResult {
- out := make(chan azure.UnifiedRoleAssignmentResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.UnifiedRoleAssignmentResult{}
- nextLink string
- )
-
- if list, err := s.GetAzureADRoleAssignments(ctx, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.UnifiedRoleAssignmentResult{Ok: u}); !ok {
- return
- }
- }
-
- nextLink = list.NextLink
- for nextLink != "" {
- var list azure.UnifiedRoleAssignmentList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.msgraph.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.UnifiedRoleAssignmentResult{Ok: u}); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
+ go getAzureObjectList[azure.UnifiedRoleAssignment](s.msgraph, ctx, path, params, out)
return out
}
-func (s *azureClient) GetRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) (azure.RoleAssignmentList, error) {
+// ListRoleAssignmentsForResource https://learn.microsoft.com/en-us/rest/api/authorization/role-assignments/list-for-resource?view=rest-authorization-2015-07-01
+func (s *azureClient) ListRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) <-chan azureResult[azure.RoleAssignment] {
var (
- path = fmt.Sprintf("%s/providers/Microsoft.Authorization/roleAssignments", resourceId)
- params = query.RMParams{ApiVersion: "2015-07-01", Filter: filter, TenantId: tenantId}
- response azure.RoleAssignmentList
+ out = make(chan azureResult[azure.RoleAssignment])
+ path = fmt.Sprintf("%s/providers/Microsoft.Authorization/roleAssignments", resourceId)
+ params = query.RMParams{ApiVersion: "2015-07-01", Filter: filter, TenantId: tenantId}
)
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-
-}
-
-func (s *azureClient) ListRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) <-chan azure.RoleAssignmentResult {
- out := make(chan azure.RoleAssignmentResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.RoleAssignmentResult{ParentId: resourceId}
- nextLink string
- )
-
- if result, err := s.GetRoleAssignmentsForResource(ctx, resourceId, filter, tenantId); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.RoleAssignmentResult{
- ParentId: resourceId,
- Ok: u,
- }); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.RoleAssignment](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.RoleAssignmentList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.RoleAssignmentResult{
- ParentId: resourceId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/roles.go b/client/roles.go
index 87fccd6..3baea14 100644
--- a/client/roles.go
+++ b/client/roles.go
@@ -20,92 +20,20 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/constants"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureADRoles(ctx context.Context, filter string) (azure.RoleList, error) {
+// ListAzureADRoles https://learn.microsoft.com/en-us/graph/api/rbacapplication-list-roledefinitions?view=graph-rest-beta
+func (s *azureClient) ListAzureADRoles(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Role] {
var (
- path = fmt.Sprintf("/%s/roleManagement/directory/roleDefinitions", constants.GraphApiVersion)
- response azure.RoleList
+ out = make(chan azureResult[azure.Role])
+ path = fmt.Sprintf("/%s/roleManagement/directory/roleDefinitions", constants.GraphApiVersion)
)
- if res, err := s.msgraph.Get(ctx, path, query.GraphParams{Filter: filter}, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureADRoles(ctx context.Context, filter string) <-chan azure.RoleResult {
- out := make(chan azure.RoleResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.RoleResult{}
- nextLink string
- )
-
- if users, err := s.GetAzureADRoles(ctx, filter); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range users.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.RoleResult{Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.Role](s.msgraph, ctx, path, params, out)
- nextLink = users.NextLink
- for nextLink != "" {
- var users azure.RoleList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.msgraph.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &users); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range users.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.RoleResult{Ok: u}); !ok {
- return
- }
- }
- nextLink = users.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/service_principals.go b/client/service_principals.go
index 1067d39..cd474ed 100644
--- a/client/service_principals.go
+++ b/client/service_principals.go
@@ -19,189 +19,43 @@ package client
import (
"context"
+ "encoding/json"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/constants"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureADServicePrincipalOwners(ctx context.Context, objectId string, params query.GraphParams) (azure.DirectoryObjectList, error) {
+// ListAzureADServicePrincipals https://learn.microsoft.com/en-us/graph/api/serviceprincipal-list?view=graph-rest-beta
+func (s *azureClient) ListAzureADServicePrincipals(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.ServicePrincipal] {
var (
- path = fmt.Sprintf("/%s/servicePrincipals/%s/owners", constants.GraphApiBetaVersion, objectId)
- response azure.DirectoryObjectList
+ out = make(chan azureResult[azure.ServicePrincipal])
+ path = fmt.Sprintf("/%s/servicePrincipals", constants.GraphApiVersion)
+
)
if params.Top == 0 {
params.Top = 999
}
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
+ go getAzureObjectList[azure.ServicePrincipal](s.msgraph, ctx, path, params, out)
+
+ return out
}
-func (s *azureClient) GetAzureADServicePrincipals(ctx context.Context, params query.GraphParams) (azure.ServicePrincipalList, error) {
+// ListAzureADServicePrincipalOwners https://learn.microsoft.com/en-us/graph/api/serviceprincipal-list-owners?view=graph-rest-beta
+func (s *azureClient) ListAzureADServicePrincipalOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage] {
var (
- path = fmt.Sprintf("/%s/servicePrincipals", constants.GraphApiVersion)
- response azure.ServicePrincipalList
+ out = make(chan azureResult[json.RawMessage])
+ path = fmt.Sprintf("/%s/servicePrincipals/%s/owners", constants.GraphApiBetaVersion, objectId)
)
if params.Top == 0 {
params.Top = 999
}
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureADServicePrincipals(ctx context.Context, params query.GraphParams) <-chan azure.ServicePrincipalResult {
- out := make(chan azure.ServicePrincipalResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.ServicePrincipalResult{}
- nextLink string
- )
-
- if list, err := s.GetAzureADServicePrincipals(ctx, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.ServicePrincipalResult{Ok: u}); !ok {
- return
- }
- }
-
- nextLink = list.NextLink
- for nextLink != "" {
- var list azure.ServicePrincipalList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.msgraph.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.ServicePrincipalResult{Ok: u}); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
- return out
-}
-
-func (s *azureClient) ListAzureADServicePrincipalOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azure.ServicePrincipalOwnerResult {
- out := make(chan azure.ServicePrincipalOwnerResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.ServicePrincipalOwnerResult{
- ServicePrincipalId: objectId,
- }
- nextLink string
- )
-
- if list, err := s.GetAzureADServicePrincipalOwners(ctx, objectId, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.ServicePrincipalOwnerResult{
- ServicePrincipalId: objectId,
- Ok: u,
- }); !ok {
- return
- }
- }
+ go getAzureObjectList[json.RawMessage](s.msgraph, ctx, path, params, out)
- nextLink = list.NextLink
- for nextLink != "" {
- var list azure.DirectoryObjectList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.msgraph.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.ServicePrincipalOwnerResult{
- ServicePrincipalId: objectId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/storage_accounts.go b/client/storage_accounts.go
index e08eda5..5c2e565 100644
--- a/client/storage_accounts.go
+++ b/client/storage_accounts.go
@@ -20,97 +20,21 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureStorageAccounts(ctx context.Context, subscriptionId string) (azure.StorageAccountList, error) {
+// ListAzureStorageAccounts https://learn.microsoft.com/en-us/rest/api/storagerp/storage-accounts/list?view=rest-storagerp-2022-05-01
+func (s *azureClient) ListAzureStorageAccounts(ctx context.Context, subscriptionId string) <-chan azureResult[azure.StorageAccount] {
var (
- path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Storage/storageAccounts", subscriptionId)
- params = query.RMParams{ApiVersion: "2022-05-01"}
- response azure.StorageAccountList
+ out = make(chan azureResult[azure.StorageAccount])
+ path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Storage/storageAccounts", subscriptionId)
+ params = query.RMParams{ApiVersion: "2022-05-01"}
)
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureStorageAccounts(ctx context.Context, subscriptionId string) <-chan azure.StorageAccountResult {
- out := make(chan azure.StorageAccountResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.StorageAccountResult{
- SubscriptionId: subscriptionId,
- }
- nextLink string
- )
- if result, err := s.GetAzureStorageAccounts(ctx, subscriptionId); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.StorageAccountResult{SubscriptionId: subscriptionId, Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.StorageAccount](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.StorageAccountList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.StorageAccountResult{
- SubscriptionId: "/subscriptions/" + subscriptionId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
@@ -118,87 +42,15 @@ func (s *azureClient) ListAzureStorageAccounts(ctx context.Context, subscription
// Storage containers
// ==
-func (s *azureClient) GetAzureStorageContainers(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, filter string, includeDeleted string, maxPageSize string) (azure.StorageContainerList, error) {
+// ListAzureStorageContainers https://learn.microsoft.com/en-us/rest/api/storagerp/blob-containers/list?view=rest-storagerp-2022-05-01
+func (s *azureClient) ListAzureStorageContainers(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, filter string, includeDeleted string, maxPageSize string) <-chan azureResult[azure.StorageContainer] {
var (
- path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s/blobServices/default/containers", subscriptionId, resourceGroupName, saName)
- params = query.RMParams{ApiVersion: "2022-05-01", Filter: filter, IncludeDeleted: includeDeleted, MaxPageSize: maxPageSize}
- response azure.StorageContainerList
+ out = make(chan azureResult[azure.StorageContainer])
+ path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s/blobServices/default/containers", subscriptionId, resourceGroupName, saName)
+ params = query.RMParams{ApiVersion: "2022-05-01", Filter: filter, IncludeDeleted: includeDeleted, MaxPageSize: maxPageSize}
)
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureStorageContainers(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, filter string, includeDeleted string, maxPageSize string) <-chan azure.StorageContainerResult {
- out := make(chan azure.StorageContainerResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.StorageContainerResult{
- SubscriptionId: subscriptionId,
- }
- nextLink string
- )
- if result, err := s.GetAzureStorageContainers(ctx, subscriptionId, resourceGroupName, saName, filter, includeDeleted, maxPageSize); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.StorageContainerResult{SubscriptionId: subscriptionId, Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.StorageContainer](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.StorageContainerList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.StorageContainerResult{
- SubscriptionId: "/subscriptions/" + subscriptionId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/subscriptions.go b/client/subscriptions.go
index ed6b1fc..5f2387a 100644
--- a/client/subscriptions.go
+++ b/client/subscriptions.go
@@ -19,92 +19,20 @@ package client
import (
"context"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureSubscriptions(ctx context.Context) (azure.SubscriptionList, error) {
+// ListAzureSubscriptions https://learn.microsoft.com/en-us/rest/api/subscription/subscriptions/list?view=rest-subscription-2020-01-01
+func (s *azureClient) ListAzureSubscriptions(ctx context.Context) <-chan azureResult[azure.Subscription] {
var (
- path = "/subscriptions"
- params = query.RMParams{ApiVersion: "2020-01-01"}
- response azure.SubscriptionList
+ out = make(chan azureResult[azure.Subscription])
+ path = "/subscriptions"
+ params = query.RMParams{ApiVersion: "2020-01-01"}
)
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureSubscriptions(ctx context.Context) <-chan azure.SubscriptionResult {
- out := make(chan azure.SubscriptionResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.SubscriptionResult{}
- nextLink string
- )
-
- if result, err := s.GetAzureSubscriptions(ctx); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.SubscriptionResult{Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.Subscription](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.SubscriptionList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.SubscriptionResult{Ok: u}); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/tenants.go b/client/tenants.go
index 3963a29..0ed59d4 100644
--- a/client/tenants.go
+++ b/client/tenants.go
@@ -20,14 +20,11 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/constants"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
func (s *azureClient) GetAzureADOrganization(ctx context.Context, selectCols []string) (*azure.Organization, error) {
@@ -61,67 +58,15 @@ func (s *azureClient) GetAzureADTenants(ctx context.Context, includeAllTenantCat
}
}
-func (s *azureClient) ListAzureADTenants(ctx context.Context, includeAllTenantCategories bool) <-chan azure.TenantResult {
- out := make(chan azure.TenantResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.TenantResult{}
- nextLink string
- )
+// ListAzureADTenants https://learn.microsoft.com/en-us/rest/api/subscription/tenants/list?view=rest-subscription-2020-01-01
+func (s *azureClient) ListAzureADTenants(ctx context.Context, includeAllTenantCategories bool) <-chan azureResult[azure.Tenant] {
+ var (
+ out = make(chan azureResult[azure.Tenant])
+ path = "/tenants"
+ params = query.RMParams{ApiVersion: "2020-01-01", IncludeAllTenantCategories: includeAllTenantCategories}
+ )
- if result, err := s.GetAzureADTenants(ctx, includeAllTenantCategories); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.TenantResult{Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.Tenant](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.TenantList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.TenantResult{Ok: u}); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/users.go b/client/users.go
index 10a3913..8f203e4 100644
--- a/client/users.go
+++ b/client/users.go
@@ -20,94 +20,26 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/constants"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureADUsers(ctx context.Context, params query.GraphParams) (azure.UserList, error) {
+
+// ListAzureADUsers https://learn.microsoft.com/en-us/graph/api/user-list?view=graph-rest-beta
+func (s *azureClient) ListAzureADUsers(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.User]{
var (
+ out = make(chan azureResult[azure.User])
path = fmt.Sprintf("/%s/users", constants.GraphApiVersion)
- response azure.UserList
+
)
if params.Top == 0 {
params.Top = 999
}
- if res, err := s.msgraph.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureADUsers(ctx context.Context, params query.GraphParams) <-chan azure.UserResult {
- out := make(chan azure.UserResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
- var (
- errResult = azure.UserResult{}
- nextLink string
- )
- if users, err := s.GetAzureADUsers(ctx, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range users.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.UserResult{Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.User](s.msgraph, ctx, path, params, out)
- nextLink = users.NextLink
- for nextLink != "" {
- var users azure.UserList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.msgraph.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &users); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range users.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.UserResult{Ok: u}); !ok {
- return
- }
- }
- nextLink = users.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/virtual_machines.go b/client/virtual_machines.go
index a346cd8..417ce91 100644
--- a/client/virtual_machines.go
+++ b/client/virtual_machines.go
@@ -20,100 +20,23 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) (azure.VirtualMachineList, error) {
+// ListAzureVirtualMachines https://learn.microsoft.com/en-us/rest/api/compute/virtual-machines/list-all?view=rest-compute-2021-07-01
+func (s *azureClient) ListAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azureResult[azure.VirtualMachine] {
var (
- path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Compute/virtualMachines", subscriptionId)
- response azure.VirtualMachineList
+ out = make(chan azureResult[azure.VirtualMachine])
+ path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Compute/virtualMachines", subscriptionId)
)
if params.ApiVersion == "" {
params.ApiVersion = "2021-07-01"
}
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azure.VirtualMachineResult {
- out := make(chan azure.VirtualMachineResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.VirtualMachineResult{
- SubscriptionId: subscriptionId,
- }
- nextLink string
- )
-
- if result, err := s.GetAzureVirtualMachines(ctx, subscriptionId, params); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.VirtualMachineResult{SubscriptionId: subscriptionId, Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.VirtualMachine](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.VirtualMachineList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.VirtualMachineResult{
- SubscriptionId: "/subscriptions/" + subscriptionId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/vm_scale_sets.go b/client/vm_scale_sets.go
index 32b9b65..af79878 100644
--- a/client/vm_scale_sets.go
+++ b/client/vm_scale_sets.go
@@ -20,97 +20,20 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureVMScaleSets(ctx context.Context, subscriptionId string) (azure.VMScaleSetList, error) {
+// ListAzureVMScaleSets https://learn.microsoft.com/en-us/rest/api/compute/virtual-machine-scale-sets/list-all?view=rest-compute-2022-11-01
+func (s *azureClient) ListAzureVMScaleSets(ctx context.Context, subscriptionId string) <-chan azureResult[azure.VMScaleSet] {
var (
- path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Compute/virtualMachineScaleSets", subscriptionId)
- params = query.RMParams{ApiVersion: "2022-11-01"}
- response azure.VMScaleSetList
+ out = make(chan azureResult[azure.VMScaleSet])
+ path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Compute/virtualMachineScaleSets", subscriptionId)
+ params = query.RMParams{ApiVersion: "2022-11-01"}
)
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureVMScaleSets(ctx context.Context, subscriptionId string) <-chan azure.VMScaleSetResult {
- out := make(chan azure.VMScaleSetResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.VMScaleSetResult{
- SubscriptionId: subscriptionId,
- }
- nextLink string
- )
-
- if result, err := s.GetAzureVMScaleSets(ctx, subscriptionId); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.VMScaleSetResult{SubscriptionId: subscriptionId, Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.VMScaleSet](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.VMScaleSetList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.VMScaleSetResult{
- SubscriptionId: "/subscriptions/" + subscriptionId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/client/web_apps.go b/client/web_apps.go
index 696c881..20aa0c2 100644
--- a/client/web_apps.go
+++ b/client/web_apps.go
@@ -20,97 +20,20 @@ package client
import (
"context"
"fmt"
- "net/url"
"github.com/bloodhoundad/azurehound/v2/client/query"
- "github.com/bloodhoundad/azurehound/v2/client/rest"
"github.com/bloodhoundad/azurehound/v2/models/azure"
- "github.com/bloodhoundad/azurehound/v2/panicrecovery"
- "github.com/bloodhoundad/azurehound/v2/pipeline"
)
-func (s *azureClient) GetAzureWebApps(ctx context.Context, subscriptionId string) (azure.WebAppList, error) {
+// ListAzureWebApps https://learn.microsoft.com/en-us/rest/api/appservice/web-apps/list?view=rest-appservice-2022-03-01
+func (s *azureClient) ListAzureWebApps(ctx context.Context, subscriptionId string) <-chan azureResult[azure.WebApp] {
+ out := make(chan azureResult[azure.WebApp])
var (
- path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Web/sites", subscriptionId)
- params = query.RMParams{ApiVersion: "2022-03-01"}
- response azure.WebAppList
+ path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Web/sites", subscriptionId)
+ params = query.RMParams{ApiVersion: "2022-03-01"}
)
- if res, err := s.resourceManager.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
-func (s *azureClient) ListAzureWebApps(ctx context.Context, subscriptionId string) <-chan azure.WebAppResult {
- out := make(chan azure.WebAppResult)
-
- go func() {
- defer panicrecovery.PanicRecovery()
- defer close(out)
-
- var (
- errResult = azure.WebAppResult{
- SubscriptionId: subscriptionId,
- }
- nextLink string
- )
-
- if result, err := s.GetAzureWebApps(ctx, subscriptionId); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- } else {
- for _, u := range result.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.WebAppResult{SubscriptionId: subscriptionId, Ok: u}); !ok {
- return
- }
- }
+ go getAzureObjectList[azure.WebApp](s.resourceManager, ctx, path, params, out)
- nextLink = result.NextLink
- for nextLink != "" {
- var list azure.WebAppList
- if url, err := url.Parse(nextLink); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if req, err := rest.NewRequest(ctx, "GET", url, nil, nil, nil); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if res, err := s.resourceManager.Send(req); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else if err := rest.Decode(res.Body, &list); err != nil {
- errResult.Error = err
- if ok := pipeline.Send(ctx.Done(), out, errResult); !ok {
- return
- }
- nextLink = ""
- } else {
- for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azure.WebAppResult{
- SubscriptionId: "/subscriptions/" + subscriptionId,
- Ok: u,
- }); !ok {
- return
- }
- }
- nextLink = list.NextLink
- }
- }
- }
- }()
return out
}
diff --git a/cmd/list-app-owners.go b/cmd/list-app-owners.go
index 1faf8de..56df1b5 100644
--- a/cmd/list-app-owners.go
+++ b/cmd/list-app-owners.go
@@ -64,6 +64,7 @@ func listAppOwners(ctx context.Context, client client.AzureClient, apps <-chan a
out = make(chan azureWrapper[models.AppOwners])
streams = pipeline.Demux(ctx.Done(), apps, 25)
wg sync.WaitGroup
+ params = query.GraphParams{}
)
wg.Add(len(streams))
@@ -79,13 +80,13 @@ func listAppOwners(ctx context.Context, client client.AzureClient, apps <-chan a
}
count = 0
)
- for item := range client.ListAzureADAppOwners(ctx, app.Data.Id, query.GraphParams{}) {
+ for item := range client.ListAzureADAppOwners(ctx, app.Data.Id, params) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing owners for this app", "appId", app.Data.AppId)
} else {
appOwner := models.AppOwner{
Owner: item.Ok,
- AppId: item.AppId,
+ AppId: app.Data.Id,
}
log.V(2).Info("found app owner", "appOwner", appOwner)
count++
diff --git a/cmd/list-automation-account-role-assignments.go b/cmd/list-automation-account-role-assignments.go
index f5c6665..3a15f9d 100644
--- a/cmd/list-automation-account-role-assignments.go
+++ b/cmd/list-automation-account-role-assignments.go
@@ -106,7 +106,7 @@ func listAutomationAccountRoleAssignments(ctx context.Context, client client.Azu
automationAccountRoleAssignment := models.AzureRoleAssignment{
Assignee: item.Ok,
- ObjectId: item.ParentId,
+ ObjectId: id,
RoleDefinitionId: roleDefinitionId,
}
log.V(2).Info("found automation account role assignment", "automationAccountRoleAssignment", automationAccountRoleAssignment)
diff --git a/cmd/list-automation-accounts.go b/cmd/list-automation-accounts.go
index bd51f48..1887964 100644
--- a/cmd/list-automation-accounts.go
+++ b/cmd/list-automation-accounts.go
@@ -97,7 +97,7 @@ func listAutomationAccounts(ctx context.Context, client client.AzureClient, subs
resourceGroupId := item.Ok.ResourceGroupId()
automationAccount := models.AutomationAccount{
AutomationAccount: item.Ok,
- SubscriptionId: item.SubscriptionId,
+ SubscriptionId: "/subscriptions/" + id,
ResourceGroupId: resourceGroupId,
TenantId: client.TenantInfo().TenantId,
}
diff --git a/cmd/list-container-registries.go b/cmd/list-container-registries.go
index 93a0932..dcdc379 100644
--- a/cmd/list-container-registries.go
+++ b/cmd/list-container-registries.go
@@ -102,7 +102,7 @@ func listContainerRegistries(ctx context.Context, client client.AzureClient, sub
resourceGroupId := item.Ok.ResourceGroupId()
containerRegistry := models.ContainerRegistry{
ContainerRegistry: item.Ok,
- SubscriptionId: item.SubscriptionId,
+ SubscriptionId: "/subscriptions/" + id,
ResourceGroupId: resourceGroupId,
TenantId: client.TenantInfo().TenantId,
}
diff --git a/cmd/list-container-registry-role-assignments.go b/cmd/list-container-registry-role-assignments.go
index 170b098..8c3a44a 100644
--- a/cmd/list-container-registry-role-assignments.go
+++ b/cmd/list-container-registry-role-assignments.go
@@ -111,7 +111,7 @@ func listContainerRegistryRoleAssignments(ctx context.Context, client client.Azu
containerRegistryRoleAssignment := models.AzureRoleAssignment{
Assignee: item.Ok,
- ObjectId: item.ParentId,
+ ObjectId: id,
RoleDefinitionId: roleDefinitionId,
}
log.V(2).Info("found container registry role assignment", "containerRegistryRoleAssignment", containerRegistryRoleAssignment)
diff --git a/cmd/list-device-owners.go b/cmd/list-device-owners.go
index dee4c37..4fcc48d 100644
--- a/cmd/list-device-owners.go
+++ b/cmd/list-device-owners.go
@@ -102,7 +102,7 @@ func listDeviceOwners(ctx context.Context, client client.AzureClient, devices <-
} else {
deviceOwner := models.DeviceOwner{
Owner: item.Ok,
- DeviceId: item.DeviceId,
+ DeviceId: id,
}
log.V(2).Info("found device owner", "deviceOwner", deviceOwner)
count++
diff --git a/cmd/list-function-app-role-assignments.go b/cmd/list-function-app-role-assignments.go
index a92494c..56d5d9b 100644
--- a/cmd/list-function-app-role-assignments.go
+++ b/cmd/list-function-app-role-assignments.go
@@ -106,7 +106,7 @@ func listFunctionAppRoleAssignments(ctx context.Context, client client.AzureClie
functionAppRoleAssignment := models.AzureRoleAssignment{
Assignee: item.Ok,
- ObjectId: item.ParentId,
+ ObjectId: id,
RoleDefinitionId: roleDefinitionId,
}
log.V(2).Info("Found function app role asignment", "functionAppRoleAssignment", functionAppRoleAssignment)
diff --git a/cmd/list-function-apps.go b/cmd/list-function-apps.go
index d4e9b56..7f961ab 100644
--- a/cmd/list-function-apps.go
+++ b/cmd/list-function-apps.go
@@ -94,12 +94,12 @@ func listFunctionApps(ctx context.Context, client client.AzureClient, subscripti
if item.Error != nil {
log.Error(item.Error, "unable to continue processing function apps for this subscription", "subscriptionId", id)
} else {
- resourceGroupId := item.Ok.ResourceGroupId()
functionApp := models.FunctionApp{
- FunctionApp: item.Ok,
- SubscriptionId: item.SubscriptionId,
- ResourceGroupId: resourceGroupId,
- TenantId: client.TenantInfo().TenantId,
+ FunctionApp: item.Ok,
+ SubscriptionId: "/subscriptions/" + id,
+ ResourceGroupId: item.Ok.ResourceGroupId(),
+ ResourceGroupName: item.Ok.ResourceGroupName(),
+ TenantId: client.TenantInfo().TenantId,
}
if functionApp.Kind == "functionapp" {
log.V(2).Info("found function app", "functionApp", functionApp)
diff --git a/cmd/list-group-members.go b/cmd/list-group-members.go
index 84295b0..c465d6b 100644
--- a/cmd/list-group-members.go
+++ b/cmd/list-group-members.go
@@ -113,7 +113,7 @@ func listGroupMembers(ctx context.Context, client client.AzureClient, groups <-c
} else {
groupMember := models.GroupMember{
Member: item.Ok,
- GroupId: item.ParentId,
+ GroupId: id,
}
log.V(2).Info("found group member", "groupMember", groupMember)
count++
diff --git a/cmd/list-group-owners.go b/cmd/list-group-owners.go
index 7746812..ed077d7 100644
--- a/cmd/list-group-owners.go
+++ b/cmd/list-group-owners.go
@@ -65,6 +65,7 @@ func listGroupOwners(ctx context.Context, client client.AzureClient, groups <-ch
ids = make(chan string)
streams = pipeline.Demux(ctx.Done(), ids, 25)
wg sync.WaitGroup
+ params = query.GraphParams{}
)
go func() {
@@ -96,13 +97,13 @@ func listGroupOwners(ctx context.Context, client client.AzureClient, groups <-ch
}
count = 0
)
- for item := range client.ListAzureADGroupOwners(ctx, id, query.GraphParams{}) {
+ for item := range client.ListAzureADGroupOwners(ctx, id, params) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing owners for this group", "groupId", id)
} else {
groupOwner := models.GroupOwner{
Owner: item.Ok,
- GroupId: item.GroupId,
+ GroupId: id,
}
log.V(2).Info("found group owner", "groupOwner", groupOwner)
count++
diff --git a/cmd/list-groups.go b/cmd/list-groups.go
index 82ca789..0031d39 100644
--- a/cmd/list-groups.go
+++ b/cmd/list-groups.go
@@ -43,7 +43,7 @@ var listGroupsCmd = &cobra.Command{
SilenceUsage: true,
}
-func listGroupsCmdImpl(cmd *cobra.Command, args []string) {
+func listGroupsCmdImpl(cmd *cobra.Command, _ []string) {
ctx, stop := signal.NotifyContext(cmd.Context(), os.Interrupt, os.Kill)
defer gracefulShutdown(stop)
diff --git a/cmd/list-key-vault-role-assignments.go b/cmd/list-key-vault-role-assignments.go
index 0c6b322..0780c8b 100644
--- a/cmd/list-key-vault-role-assignments.go
+++ b/cmd/list-key-vault-role-assignments.go
@@ -102,7 +102,7 @@ func listKeyVaultRoleAssignments(ctx context.Context, client client.AzureClient,
log.Error(item.Error, "unable to continue processing role assignments for this key vault", "keyVaultId", id)
} else {
keyVaultRoleAssignment := models.KeyVaultRoleAssignment{
- KeyVaultId: item.ParentId,
+ KeyVaultId: id,
RoleAssignment: item.Ok,
}
log.V(2).Info("found key vault role assignment", "keyVaultRoleAssignment", keyVaultRoleAssignment)
diff --git a/cmd/list-key-vaults.go b/cmd/list-key-vaults.go
index 6e82e9f..6ea7641 100644
--- a/cmd/list-key-vaults.go
+++ b/cmd/list-key-vaults.go
@@ -96,13 +96,12 @@ func listKeyVaults(ctx context.Context, client client.AzureClient, subscriptions
if item.Error != nil {
log.Error(item.Error, "unable to continue processing key vaults for this subscription", "subscriptionId", id)
} else {
- resourceGroup := item.Ok.ResourceGroupId()
// the embedded struct's values override top-level properties so TenantId
// needs to be explicitly set.
keyVault := models.KeyVault{
KeyVault: item.Ok,
- SubscriptionId: item.SubscriptionId,
- ResourceGroup: resourceGroup,
+ SubscriptionId: id,
+ ResourceGroup: item.Ok.ResourceGroupId(),
TenantId: item.Ok.Properties.TenantId,
}
log.V(2).Info("found key vault", "keyVault", keyVault)
diff --git a/cmd/list-logic-app-role-assignments.go b/cmd/list-logic-app-role-assignments.go
index 973e735..8768970 100644
--- a/cmd/list-logic-app-role-assignments.go
+++ b/cmd/list-logic-app-role-assignments.go
@@ -111,7 +111,7 @@ func listLogicAppRoleAssignments(ctx context.Context, client client.AzureClient,
logicappRoleAssignment := models.AzureRoleAssignment{
Assignee: item.Ok,
- ObjectId: item.ParentId,
+ ObjectId: id,
RoleDefinitionId: roleDefinitionId,
}
log.V(2).Info("found logic app role assignment", "logicappRoleAssignment", logicappRoleAssignment)
diff --git a/cmd/list-logic-apps.go b/cmd/list-logic-apps.go
index 415168d..e60c26c 100644
--- a/cmd/list-logic-apps.go
+++ b/cmd/list-logic-apps.go
@@ -104,11 +104,10 @@ func listLogicApps(ctx context.Context, client client.AzureClient, subscriptions
if item.Error != nil {
log.Error(item.Error, "unable to continue processing logic apps for this subscription", "subscriptionId", id)
} else {
- resourceGroupId := item.Ok.ResourceGroupId()
logicapp := models.LogicApp{
LogicApp: item.Ok,
- SubscriptionId: item.SubscriptionId,
- ResourceGroupId: resourceGroupId,
+ SubscriptionId: "/subscriptions/" + id,
+ ResourceGroupId: item.Ok.ResourceGroupId(),
TenantId: client.TenantInfo().TenantId,
}
log.V(2).Info("found logicapp", "logicapp", logicapp)
diff --git a/cmd/list-managed-cluster-role-assignments.go b/cmd/list-managed-cluster-role-assignments.go
index 59c78c0..82e09a3 100644
--- a/cmd/list-managed-cluster-role-assignments.go
+++ b/cmd/list-managed-cluster-role-assignments.go
@@ -111,7 +111,7 @@ func listManagedClusterRoleAssignments(ctx context.Context, client client.AzureC
managedClusterRoleAssignment := models.AzureRoleAssignment{
Assignee: item.Ok,
- ObjectId: item.ParentId,
+ ObjectId: id,
RoleDefinitionId: roleDefinitionId,
}
log.V(2).Info("found managed cluster role assignment", "managedClusterRoleAssignment", managedClusterRoleAssignment)
diff --git a/cmd/list-managed-clusters.go b/cmd/list-managed-clusters.go
index becb7be..61fe220 100644
--- a/cmd/list-managed-clusters.go
+++ b/cmd/list-managed-clusters.go
@@ -99,11 +99,10 @@ func listManagedClusters(ctx context.Context, client client.AzureClient, subscri
if item.Error != nil {
log.Error(item.Error, "unable to continue processing managed clusters for this subscription", "subscriptionId", id)
} else {
- resourceGroupId := item.Ok.ResourceGroupId()
managedCluster := models.ManagedCluster{
ManagedCluster: item.Ok,
- SubscriptionId: item.SubscriptionId,
- ResourceGroupId: resourceGroupId,
+ SubscriptionId: "/subscriptions/" + id,
+ ResourceGroupId: item.Ok.ResourceGroupId(),
TenantId: client.TenantInfo().TenantId,
}
log.V(2).Info("found managed cluster", "managedCluster", managedCluster)
diff --git a/cmd/list-management-group-role-assignments.go b/cmd/list-management-group-role-assignments.go
index d48fecf..97009b4 100644
--- a/cmd/list-management-group-role-assignments.go
+++ b/cmd/list-management-group-role-assignments.go
@@ -102,7 +102,7 @@ func listManagementGroupRoleAssignments(ctx context.Context, client client.Azure
log.Error(item.Error, "unable to continue processing role assignments for this managementGroup", "managementGroupId", id)
} else {
managementGroupRoleAssignment := models.ManagementGroupRoleAssignment{
- ManagementGroupId: item.ParentId,
+ ManagementGroupId: id,
RoleAssignment: item.Ok,
}
log.V(2).Info("found managementGroup role assignment", "managementGroupRoleAssignment", managementGroupRoleAssignment)
diff --git a/cmd/list-resource-group-role-assignments.go b/cmd/list-resource-group-role-assignments.go
index 964c7bd..dc10820 100644
--- a/cmd/list-resource-group-role-assignments.go
+++ b/cmd/list-resource-group-role-assignments.go
@@ -103,7 +103,7 @@ func listResourceGroupRoleAssignments(ctx context.Context, client client.AzureCl
log.Error(item.Error, "unable to continue processing role assignments for this resourceGroup", "resourceGroupId", id)
} else {
resourceGroupRoleAssignment := models.ResourceGroupRoleAssignment{
- ResourceGroupId: item.ParentId,
+ ResourceGroupId: id,
RoleAssignment: item.Ok,
}
log.V(2).Info("found resourceGroup role assignment", "resourceGroupRoleAssignment", resourceGroupRoleAssignment)
diff --git a/cmd/list-resource-groups.go b/cmd/list-resource-groups.go
index d21de6e..c9b9516 100644
--- a/cmd/list-resource-groups.go
+++ b/cmd/list-resource-groups.go
@@ -98,7 +98,7 @@ func listResourceGroups(ctx context.Context, client client.AzureClient, subscrip
} else {
resourceGroup := models.ResourceGroup{
ResourceGroup: item.Ok,
- SubscriptionId: item.SubscriptionId,
+ SubscriptionId: "/subscriptions/"+id,
TenantId: client.TenantInfo().TenantId,
}
log.V(2).Info("found resource group", "resourceGroup", resourceGroup)
diff --git a/cmd/list-roles.go b/cmd/list-roles.go
index 427de4f..7a377c6 100644
--- a/cmd/list-roles.go
+++ b/cmd/list-roles.go
@@ -24,6 +24,7 @@ import (
"time"
"github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/panicrecovery"
@@ -64,7 +65,7 @@ func listRoles(ctx context.Context, client client.AzureClient) <-chan interface{
defer panicrecovery.PanicRecovery()
defer close(out)
count := 0
- for item := range client.ListAzureADRoles(ctx, "") {
+ for item := range client.ListAzureADRoles(ctx, query.GraphParams{}) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing roles")
return
diff --git a/cmd/list-service-principal-owners.go b/cmd/list-service-principal-owners.go
index b52d8b6..7c13810 100644
--- a/cmd/list-service-principal-owners.go
+++ b/cmd/list-service-principal-owners.go
@@ -103,7 +103,7 @@ func listServicePrincipalOwners(ctx context.Context, client client.AzureClient,
} else {
servicePrincipalOwner := models.ServicePrincipalOwner{
Owner: item.Ok,
- ServicePrincipalId: item.ServicePrincipalId,
+ ServicePrincipalId: id,
}
log.V(2).Info("found service principal owner", "servicePrincipalOwner", servicePrincipalOwner)
count++
diff --git a/cmd/list-storage-account-role-assignments.go b/cmd/list-storage-account-role-assignments.go
index 5b70911..a1b2546 100644
--- a/cmd/list-storage-account-role-assignments.go
+++ b/cmd/list-storage-account-role-assignments.go
@@ -106,7 +106,7 @@ func listStorageAccountRoleAssignments(ctx context.Context, client client.AzureC
storageAccountRoleAssignment := models.AzureRoleAssignment{
Assignee: item.Ok,
- ObjectId: item.ParentId,
+ ObjectId: id,
RoleDefinitionId: roleDefinitionId,
}
log.V(2).Info("found storage account role assignment", "storageAccountRoleAssignment", storageAccountRoleAssignment)
diff --git a/cmd/list-storage-accounts.go b/cmd/list-storage-accounts.go
index 8c91c71..000ae9c 100644
--- a/cmd/list-storage-accounts.go
+++ b/cmd/list-storage-accounts.go
@@ -94,13 +94,11 @@ func listStorageAccounts(ctx context.Context, client client.AzureClient, subscri
if item.Error != nil {
log.Error(item.Error, "unable to continue processing storage accounts for this subscription", "subscriptionId", id)
} else {
- resourceGroupId := item.Ok.ResourceGroupId()
- resourceGroupName := item.Ok.ResourceGroupName()
storageAccount := models.StorageAccount{
StorageAccount: item.Ok,
- SubscriptionId: item.SubscriptionId,
- ResourceGroupId: resourceGroupId,
- ResourceGroupName: resourceGroupName,
+ SubscriptionId: "/subscriptions/" + id,
+ ResourceGroupId: item.Ok.ResourceGroupId(),
+ ResourceGroupName: item.Ok.ResourceGroupName(),
TenantId: client.TenantInfo().TenantId,
}
log.V(2).Info("found storage account", "storageAccount", storageAccount)
diff --git a/cmd/list-storage-containers.go b/cmd/list-storage-containers.go
index 322f456..ff0a494 100644
--- a/cmd/list-storage-containers.go
+++ b/cmd/list-storage-containers.go
@@ -101,14 +101,12 @@ func listStorageContainers(ctx context.Context, client client.AzureClient, stora
if item.Error != nil {
log.Error(item.Error, "unable to continue processing storage containers for this subscription", "subscriptionId", stAccount.(models.StorageAccount).SubscriptionId, "storageAccountName", stAccount.(models.StorageAccount).Name)
} else {
- resourceGroupId := item.Ok.ResourceGroupId()
- resourceGroupName := item.Ok.ResourceGroupName()
storageContainer := models.StorageContainer{
StorageContainer: item.Ok,
StorageAccountId: stAccount.(models.StorageAccount).StorageAccount.Id,
- SubscriptionId: item.SubscriptionId,
- ResourceGroupId: resourceGroupId,
- ResourceGroupName: resourceGroupName,
+ SubscriptionId: "/subscriptions/"+stAccount.(models.StorageAccount).SubscriptionId,
+ ResourceGroupId: item.Ok.ResourceGroupId(),
+ ResourceGroupName: item.Ok.ResourceGroupName(),
TenantId: client.TenantInfo().TenantId,
}
log.V(2).Info("found storage container", "storageContainer", storageContainer)
diff --git a/cmd/list-subscription-role-assignments.go b/cmd/list-subscription-role-assignments.go
index 88ef907..b23421e 100644
--- a/cmd/list-subscription-role-assignments.go
+++ b/cmd/list-subscription-role-assignments.go
@@ -102,7 +102,7 @@ func listSubscriptionRoleAssignments(ctx context.Context, client client.AzureCli
log.Error(item.Error, "unable to continue processing role assignments for this subscription", "subscriptionId", id)
} else {
subscriptionRoleAssignment := models.SubscriptionRoleAssignment{
- SubscriptionId: item.ParentId,
+ SubscriptionId: id,
RoleAssignment: item.Ok,
}
log.V(2).Info("found subscription role assignment", "subscriptionRoleAssignment", subscriptionRoleAssignment)
diff --git a/cmd/list-users.go b/cmd/list-users.go
index 1ac8f87..be94d8a 100644
--- a/cmd/list-users.go
+++ b/cmd/list-users.go
@@ -43,7 +43,7 @@ var listUsersCmd = &cobra.Command{
SilenceUsage: true,
}
-func listUsersCmdImpl(cmd *cobra.Command, args []string) {
+func listUsersCmdImpl(cmd *cobra.Command, _ []string) {
ctx, stop := signal.NotifyContext(cmd.Context(), os.Interrupt, os.Kill)
defer gracefulShutdown(stop)
@@ -61,23 +61,25 @@ func listUsersCmdImpl(cmd *cobra.Command, args []string) {
func listUsers(ctx context.Context, client client.AzureClient) <-chan interface{} {
out := make(chan interface{})
+ params := query.GraphParams{Select: []string{
+ "accountEnabled",
+ "createdDateTime",
+ "displayName",
+ "jobTitle",
+ "lastPasswordChangeDateTime",
+ "mail",
+ "onPremisesSecurityIdentifier",
+ "onPremisesSyncEnabled",
+ "userPrincipalName",
+ "userType",
+ "id",
+ }}
+
go func() {
defer panicrecovery.PanicRecovery()
defer close(out)
count := 0
- for item := range client.ListAzureADUsers(ctx, query.GraphParams{Select: []string{
- "accountEnabled",
- "createdDateTime",
- "displayName",
- "jobTitle",
- "lastPasswordChangeDateTime",
- "mail",
- "onPremisesSecurityIdentifier",
- "onPremisesSyncEnabled",
- "userPrincipalName",
- "userType",
- "id",
- }}) {
+ for item := range client.ListAzureADUsers(ctx, params) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing users")
return
diff --git a/cmd/list-virtual-machine-role-assignments.go b/cmd/list-virtual-machine-role-assignments.go
index a077b03..389cafd 100644
--- a/cmd/list-virtual-machine-role-assignments.go
+++ b/cmd/list-virtual-machine-role-assignments.go
@@ -102,7 +102,7 @@ func listVirtualMachineRoleAssignments(ctx context.Context, client client.AzureC
log.Error(item.Error, "unable to continue processing role assignments for this virtual machine", "virtualMachineId", id)
} else {
virtualMachineRoleAssignment := models.VirtualMachineRoleAssignment{
- VirtualMachineId: item.ParentId,
+ VirtualMachineId: id,
RoleAssignment: item.Ok,
}
log.V(2).Info("found virtual machine role assignment", "virtualMachineRoleAssignment", virtualMachineRoleAssignment)
diff --git a/cmd/list-virtual-machines.go b/cmd/list-virtual-machines.go
index ee7c1a8..6e4c77e 100644
--- a/cmd/list-virtual-machines.go
+++ b/cmd/list-virtual-machines.go
@@ -95,11 +95,10 @@ func listVirtualMachines(ctx context.Context, client client.AzureClient, subscri
if item.Error != nil {
log.Error(item.Error, "unable to continue processing virtual machines for this subscription", "subscriptionId", id)
} else {
- resourceGroupId := item.Ok.ResourceGroupId()
virtualMachine := models.VirtualMachine{
VirtualMachine: item.Ok,
- SubscriptionId: item.SubscriptionId,
- ResourceGroupId: resourceGroupId,
+ SubscriptionId: "/subscriptions/" + id,
+ ResourceGroupId: item.Ok.ResourceGroupId(),
TenantId: client.TenantInfo().TenantId,
}
log.V(2).Info("found virtual machine", "virtualMachine", virtualMachine)
diff --git a/cmd/list-vm-scale-set-role-assignments.go b/cmd/list-vm-scale-set-role-assignments.go
index 491ef7e..34841c9 100644
--- a/cmd/list-vm-scale-set-role-assignments.go
+++ b/cmd/list-vm-scale-set-role-assignments.go
@@ -111,7 +111,7 @@ func listVMScaleSetRoleAssignments(ctx context.Context, client client.AzureClien
vmScaleSetRoleAssignment := models.AzureRoleAssignment{
Assignee: item.Ok,
- ObjectId: item.ParentId,
+ ObjectId: id,
RoleDefinitionId: roleDefinitionId,
}
log.V(2).Info("found vm scale set role assignment", "vmScaleSetRoleAssignment", vmScaleSetRoleAssignment)
diff --git a/cmd/list-vm-scale-sets.go b/cmd/list-vm-scale-sets.go
index 49e9eb1..2ace333 100644
--- a/cmd/list-vm-scale-sets.go
+++ b/cmd/list-vm-scale-sets.go
@@ -100,11 +100,10 @@ func listVMScaleSets(ctx context.Context, client client.AzureClient, subscriptio
if item.Error != nil {
log.Error(item.Error, "unable to continue processing virtual machine scale sets for this subscription", "subscriptionId", id)
} else {
- resourceGroupId := item.Ok.ResourceGroupId()
vmScaleSet := models.VMScaleSet{
VMScaleSet: item.Ok,
- SubscriptionId: item.SubscriptionId,
- ResourceGroupId: resourceGroupId,
+ SubscriptionId: "/subscriptions/"+id,
+ ResourceGroupId: item.Ok.ResourceGroupId(),
TenantId: client.TenantInfo().TenantId,
}
log.V(2).Info("found virtual machine scale set", "vmScaleSet", vmScaleSet)
diff --git a/cmd/list-web-app-role-assignments.go b/cmd/list-web-app-role-assignments.go
index 00f949b..e4d41c2 100644
--- a/cmd/list-web-app-role-assignments.go
+++ b/cmd/list-web-app-role-assignments.go
@@ -111,7 +111,7 @@ func listWebAppRoleAssignments(ctx context.Context, client client.AzureClient, w
webAppRoleAssignment := models.AzureRoleAssignment{
Assignee: item.Ok,
- ObjectId: item.ParentId,
+ ObjectId: id,
RoleDefinitionId: roleDefinitionId,
}
log.V(2).Info("Found web app role asignment", "webAppRoleAssignment", webAppRoleAssignment)
diff --git a/cmd/list-web-apps.go b/cmd/list-web-apps.go
index ac2aaec..ec53067 100644
--- a/cmd/list-web-apps.go
+++ b/cmd/list-web-apps.go
@@ -99,12 +99,12 @@ func listWebApps(ctx context.Context, client client.AzureClient, subscriptions <
if item.Error != nil {
log.Error(item.Error, "unable to continue processing web apps for this subscription", "subscriptionId", id)
} else {
- resourceGroupId := item.Ok.ResourceGroupId()
webApp := models.WebApp{
- WebApp: item.Ok,
- SubscriptionId: item.SubscriptionId,
- ResourceGroupId: resourceGroupId,
- TenantId: client.TenantInfo().TenantId,
+ WebApp: item.Ok,
+ SubscriptionId: "/subscriptions/" + id,
+ ResourceGroupId: item.Ok.ResourceGroupId(),
+ ResourceGroupName: item.Ok.ResourceGroupName(),
+ TenantId: client.TenantInfo().TenantId,
}
if webApp.Kind == "app" {
log.V(2).Info("found web app", "webApp", webApp)
diff --git a/models/azure/app_role_assignment.go b/models/azure/app_role_assignment.go
index 59c0234..708a4d8 100644
--- a/models/azure/app_role_assignment.go
+++ b/models/azure/app_role_assignment.go
@@ -37,15 +37,3 @@ type AppRoleAssignment struct {
ResourceDisplayName string `json:"resourceDisplayName,omitempty"`
ResourceId string `json:"resourceId,omitempty"`
}
-
-type AppRoleAssignmentList struct {
- Count int `json:"@odata.count,omitempty"` // The total count of all results
- NextLink string `json:"@odata.nextLink,omitempty"` // The URL to use for getting the next set of values.
- Context string `json:"@odata.context,omitempty"`
- Value []AppRoleAssignment `json:"value"` // A list of role assignments.
-}
-
-type AppRoleAssignmentResult struct {
- Error error
- Ok AppRoleAssignment
-}
diff --git a/models/azure/application.go b/models/azure/application.go
index cec69cf..a44a103 100644
--- a/models/azure/application.go
+++ b/models/azure/application.go
@@ -17,8 +17,6 @@
package azure
-import "encoding/json"
-
// Represents an application. Any application that outsources authentication to Azure Active Directory (Azure AD) must
// be registered in a directory. Application registration involves telling Azure AD about your application, including
// the URL where it's located, the URL to send replies after authentication, the URI to identify your application, and
@@ -171,20 +169,3 @@ type Application struct {
// Specifies settings for a web application.
Web WebApplication `json:"web,omitempty"`
}
-
-type ApplicationList struct {
- Count int `json:"@odata.count,omitempty"` // The total count of all results
- NextLink string `json:"@odata.nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []Application `json:"value"` // A list of applications.
-}
-
-type ApplicationResult struct {
- Error error
- Ok Application
-}
-
-type AppOwnerResult struct {
- AppId string
- Error error
- Ok json.RawMessage
-}
diff --git a/models/azure/automation_account.go b/models/azure/automation_account.go
index 9e494da..c952a38 100644
--- a/models/azure/automation_account.go
+++ b/models/azure/automation_account.go
@@ -50,14 +50,3 @@ func (s AutomationAccount) ResourceGroupId() string {
return ""
}
}
-
-type AutomationAccountList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []AutomationAccount `json:"value"` // A list of automation accounts.
-}
-
-type AutomationAccountResult struct {
- SubscriptionId string
- Error error
- Ok AutomationAccount
-}
diff --git a/models/azure/container_registry.go b/models/azure/container_registry.go
index 68d560f..d476d48 100644
--- a/models/azure/container_registry.go
+++ b/models/azure/container_registry.go
@@ -47,14 +47,3 @@ func (s ContainerRegistry) ResourceGroupId() string {
return ""
}
}
-
-type ContainerRegistryList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []ContainerRegistry `json:"value"` // A list of container registries.
-}
-
-type ContainerRegistryResult struct {
- SubscriptionId string
- Error error
- Ok ContainerRegistry
-}
diff --git a/models/azure/descendant-info.go b/models/azure/descendant-info.go
index 003cf91..7f2d400 100644
--- a/models/azure/descendant-info.go
+++ b/models/azure/descendant-info.go
@@ -60,13 +60,3 @@ type DescendantInfo struct {
// - /subscriptions
Type string `json:"type,omitempty"`
}
-
-type DescendantInfoList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []DescendantInfo `json:"value"` // A list of management group descendants.
-}
-
-type DescendantInfoResult struct {
- Error error
- Ok DescendantInfo
-}
diff --git a/models/azure/device.go b/models/azure/device.go
index 503f022..64fffe0 100644
--- a/models/azure/device.go
+++ b/models/azure/device.go
@@ -18,8 +18,6 @@
package azure
import (
- "encoding/json"
-
"github.com/bloodhoundad/azurehound/v2/enums"
)
@@ -131,20 +129,3 @@ type Device struct {
// Read-only.
TrustType enums.TrustType `json:"trustType,omitempty"`
}
-
-type DeviceList struct {
- Count int `json:"@odata.count,omitempty"` // The total count of all results
- NextLink string `json:"@odata.nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []Device `json:"value"` // A list of devices.
-}
-
-type DeviceResult struct {
- Error error
- Ok Device
-}
-
-type DeviceRegisteredOwnerResult struct {
- DeviceId string
- Error error
- Ok json.RawMessage
-}
diff --git a/models/azure/directory_object.go b/models/azure/directory_object.go
index 68e1aa7..149b62e 100644
--- a/models/azure/directory_object.go
+++ b/models/azure/directory_object.go
@@ -17,10 +17,6 @@
package azure
-import (
- "encoding/json"
-)
-
// Represents an Azure Active Directory object. The directoryObject type is the base type for many other directory entity types.
type DirectoryObject struct {
// The unique identifier for the object.
@@ -33,9 +29,3 @@ type DirectoryObject struct {
Type string `json:"@odata.type,omitempty"`
}
-
-type DirectoryObjectList struct {
- Count int `json:"@odata.count,omitempty"` // The total count of all results
- NextLink string `json:"@odata.nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []json.RawMessage `json:"value"` // A list of various Azure AD directory objects.
-}
diff --git a/models/azure/function_app.go b/models/azure/function_app.go
index 92f394e..ab1fc51 100644
--- a/models/azure/function_app.go
+++ b/models/azure/function_app.go
@@ -49,14 +49,3 @@ func (s FunctionApp) ResourceGroupId() string {
return ""
}
}
-
-type FunctionAppList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []FunctionApp `json:"value"` // A list of function apps
-}
-
-type FunctionAppResult struct {
- SubscriptionId string
- Error error
- Ok FunctionApp
-}
diff --git a/models/azure/group.go b/models/azure/group.go
index 28fb6d1..de58049 100644
--- a/models/azure/group.go
+++ b/models/azure/group.go
@@ -18,8 +18,6 @@
package azure
import (
- "encoding/json"
-
"github.com/bloodhoundad/azurehound/v2/enums"
)
@@ -281,20 +279,3 @@ type Group struct {
// Nullable.
Visibility enums.GroupVisibility `json:"visibility,omitempty"`
}
-
-type GroupList struct {
- Count int `json:"@odata.count,omitempty"` // The total count of all results
- NextLink string `json:"@odata.nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []Group `json:"value"` // A list of groups.
-}
-
-type GroupResult struct {
- Error error
- Ok Group
-}
-
-type GroupOwnerResult struct {
- Error error
- GroupId string
- Ok json.RawMessage
-}
diff --git a/models/azure/key_vault.go b/models/azure/key_vault.go
index 841eebe..0588310 100644
--- a/models/azure/key_vault.go
+++ b/models/azure/key_vault.go
@@ -56,14 +56,3 @@ func (s KeyVault) ResourceGroupId() string {
return ""
}
}
-
-type KeyVaultList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []KeyVault `json:"value"` // A list of key vaults.
-}
-
-type KeyVaultResult struct {
- SubscriptionId string
- Error error
- Ok KeyVault
-}
diff --git a/models/azure/logic_app.go b/models/azure/logic_app.go
index 3dcfa9a..67d8527 100644
--- a/models/azure/logic_app.go
+++ b/models/azure/logic_app.go
@@ -47,14 +47,3 @@ func (s LogicApp) ResourceGroupId() string {
return ""
}
}
-
-type LogicAppList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []LogicApp `json:"value"` // A list of logic apps.
-}
-
-type LogicAppResult struct {
- SubscriptionId string
- Error error
- Ok LogicApp
-}
diff --git a/models/azure/managed_cluster.go b/models/azure/managed_cluster.go
index 1502bbc..e0aa74c 100644
--- a/models/azure/managed_cluster.go
+++ b/models/azure/managed_cluster.go
@@ -50,14 +50,3 @@ func (s ManagedCluster) ResourceGroupId() string {
return ""
}
}
-
-type ManagedClusterList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []ManagedCluster `json:"value"` // A list of managed clusters.
-}
-
-type ManagedClusterResult struct {
- SubscriptionId string
- Error error
- Ok ManagedCluster
-}
diff --git a/models/azure/management_group.go b/models/azure/management_group.go
index 91f5231..761c7f5 100644
--- a/models/azure/management_group.go
+++ b/models/azure/management_group.go
@@ -29,13 +29,3 @@ type ManagementGroup struct {
// The type of resource: "Microsoft.Management/managementGroups"
Type string `json:"type,omitempty"`
}
-
-type ManagementGroupList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []ManagementGroup `json:"value"` // A list of tenants.
-}
-
-type ManagementGroupResult struct {
- Error error
- Ok ManagementGroup
-}
diff --git a/models/azure/member_object.go b/models/azure/member_object.go
deleted file mode 100644
index 40b14e5..0000000
--- a/models/azure/member_object.go
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (C) 2022 Specter Ops, Inc.
-//
-// This file is part of AzureHound.
-//
-// AzureHound is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// AzureHound 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 General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see .
-
-package azure
-
-import "encoding/json"
-
-type MemberObjectList struct {
- Count int `json:"@odata.count,omitempty"` // The total count of all results
- NextLink string `json:"@odata.nextLink,omitempty"` // The URL to use for getting the next set of values.
- Context string `json:"@odata.context,omitempty"`
- Value []json.RawMessage `json:"value"`
-}
-
-type MemberObjectResult struct {
- ParentId string
- ParentType string
- Error error
- Ok json.RawMessage
-}
diff --git a/models/azure/resource_group.go b/models/azure/resource_group.go
index 43604b0..3f73076 100644
--- a/models/azure/resource_group.go
+++ b/models/azure/resource_group.go
@@ -39,14 +39,3 @@ type ResourceGroup struct {
// The type of the resource group.
Type string `json:"type,omitempty"`
}
-
-type ResourceGroupList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []ResourceGroup `json:"value"` // A list of tenants.
-}
-
-type ResourceGroupResult struct {
- SubscriptionId string
- Error error
- Ok ResourceGroup
-}
diff --git a/models/azure/role.go b/models/azure/role.go
index 5f35dd0..30a25c1 100644
--- a/models/azure/role.go
+++ b/models/azure/role.go
@@ -67,14 +67,3 @@ type Role struct {
// Read-only when isBuiltIn is true
Version string `json:"version,omitempty"`
}
-
-type RoleList struct {
- Count int `json:"@odata.count,omitempty"` // The total count of all results
- NextLink string `json:"@odata.nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []Role `json:"value"` // A list of roles.
-}
-
-type RoleResult struct {
- Error error
- Ok Role
-}
diff --git a/models/azure/role_assignment.go b/models/azure/role_assignment.go
index 10948c3..07ea735 100644
--- a/models/azure/role_assignment.go
+++ b/models/azure/role_assignment.go
@@ -42,20 +42,6 @@ type RoleAssignment struct {
Properties RoleAssignmentPropertiesWithScope `json:"properties,omitempty"`
}
-type RoleAssignmentList struct {
- // The URL to use for getting the next set of results.
- NextLink string `json:"nextLink,omitempty"`
-
- // The role assignment list.
- Value []RoleAssignment `json:"value"`
-}
-
-type RoleAssignmentResult struct {
- ParentId string
- Error error
- Ok RoleAssignment
-}
-
func (s RoleAssignment) GetPrincipalId() string {
return s.Properties.PrincipalId
}
diff --git a/models/azure/service_principal.go b/models/azure/service_principal.go
index 3a422c0..5ba521b 100644
--- a/models/azure/service_principal.go
+++ b/models/azure/service_principal.go
@@ -18,8 +18,6 @@
package azure
import (
- "encoding/json"
-
"github.com/bloodhoundad/azurehound/v2/enums"
)
@@ -179,20 +177,3 @@ type ServicePrincipal struct {
// Specifies the verified publisher of the application which this service principal represents.
VerifiedPublisher VerifiedPublisher `json:"verifiedPublisher,omitempty"`
}
-
-type ServicePrincipalList struct {
- Count int `json:"@odata.count,omitempty"` // The total count of all results
- NextLink string `json:"@odata.nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []ServicePrincipal `json:"value"` // A list of ServicePrincipals.
-}
-
-type ServicePrincipalResult struct {
- Error error
- Ok ServicePrincipal
-}
-
-type ServicePrincipalOwnerResult struct {
- Error error
- ServicePrincipalId string
- Ok json.RawMessage
-}
diff --git a/models/azure/storage_account.go b/models/azure/storage_account.go
index 6e2d0ad..a422080 100644
--- a/models/azure/storage_account.go
+++ b/models/azure/storage_account.go
@@ -50,14 +50,3 @@ func (s StorageAccount) ResourceGroupId() string {
return ""
}
}
-
-type StorageAccountList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []StorageAccount `json:"value"` // A list of storage accounts.
-}
-
-type StorageAccountResult struct {
- SubscriptionId string
- Error error
- Ok StorageAccount
-}
diff --git a/models/azure/storage_container.go b/models/azure/storage_container.go
index 7e841cf..5a22612 100644
--- a/models/azure/storage_container.go
+++ b/models/azure/storage_container.go
@@ -63,14 +63,3 @@ func (s StorageContainer) StorageAccountId() string {
return ""
}
}
-
-type StorageContainerList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []StorageContainer `json:"value"` // A list of storage containers.
-}
-
-type StorageContainerResult struct {
- SubscriptionId string
- Error error
- Ok StorageContainer
-}
diff --git a/models/azure/subscription.go b/models/azure/subscription.go
index 30a710c..b7f32c0 100644
--- a/models/azure/subscription.go
+++ b/models/azure/subscription.go
@@ -49,13 +49,3 @@ type Subscription struct {
// The subscription tenant ID.
TenantId string `json:"tenantId,omitempty"`
}
-
-type SubscriptionList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []Subscription `json:"value"` // A list of subscriptions.
-}
-
-type SubscriptionResult struct {
- Error error
- Ok Subscription
-}
diff --git a/models/azure/tenant.go b/models/azure/tenant.go
index e0d5030..727e0c5 100644
--- a/models/azure/tenant.go
+++ b/models/azure/tenant.go
@@ -36,8 +36,3 @@ type TenantList struct {
NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
Value []Tenant `json:"value"` // A list of tenants.
}
-
-type TenantResult struct {
- Error error
- Ok Tenant
-}
diff --git a/models/azure/unified_role_assignment.go b/models/azure/unified_role_assignment.go
index 6027e59..fc60a5f 100644
--- a/models/azure/unified_role_assignment.go
+++ b/models/azure/unified_role_assignment.go
@@ -74,14 +74,3 @@ type UnifiedRoleAssignment struct {
// Supports $expand.
AppScope AppScope `json:"appScope,omitempty"`
}
-
-type UnifiedRoleAssignmentList struct {
- Count int `json:"@odata.count,omitempty"` // The total count of all results
- NextLink string `json:"@odata.nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []UnifiedRoleAssignment `json:"value"` // A list of role assignments.
-}
-
-type UnifiedRoleAssignmentResult struct {
- Error error
- Ok UnifiedRoleAssignment
-}
diff --git a/models/azure/user.go b/models/azure/user.go
index 8106d12..301b5d7 100644
--- a/models/azure/user.go
+++ b/models/azure/user.go
@@ -465,14 +465,3 @@ type User struct {
// Supports $filter (eq, ne, NOT, in).
UserType string `json:"userType,omitempty"`
}
-
-type UserList struct {
- Count int `json:"@odata.count,omitempty"` // The total count of all results
- NextLink string `json:"@odata.nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []User `json:"value"` // A list of users.
-}
-
-type UserResult struct {
- Error error
- Ok User
-}
diff --git a/models/azure/virtual_machine.go b/models/azure/virtual_machine.go
index 4c996b7..64cbb48 100644
--- a/models/azure/virtual_machine.go
+++ b/models/azure/virtual_machine.go
@@ -51,14 +51,3 @@ func (s VirtualMachine) ResourceGroupId() string {
return ""
}
}
-
-type VirtualMachineList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []VirtualMachine `json:"value"` // A list of virtual machines.
-}
-
-type VirtualMachineResult struct {
- SubscriptionId string
- Error error
- Ok VirtualMachine
-}
diff --git a/models/azure/vm_scale_set.go b/models/azure/vm_scale_set.go
index 59b8edd..3d89b1f 100644
--- a/models/azure/vm_scale_set.go
+++ b/models/azure/vm_scale_set.go
@@ -49,14 +49,3 @@ func (s VMScaleSet) ResourceGroupId() string {
return ""
}
}
-
-type VMScaleSetList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []VMScaleSet `json:"value"` // A list of virtual machine scale sets.
-}
-
-type VMScaleSetResult struct {
- SubscriptionId string
- Error error
- Ok VMScaleSet
-}
diff --git a/models/azure/web_app.go b/models/azure/web_app.go
index 128bc85..9ef401d 100644
--- a/models/azure/web_app.go
+++ b/models/azure/web_app.go
@@ -48,14 +48,3 @@ func (s WebApp) ResourceGroupId() string {
return ""
}
}
-
-type WebAppList struct {
- NextLink string `json:"nextLink,omitempty"` // The URL to use for getting the next set of values.
- Value []WebApp `json:"value"` // A list of web apps.
-}
-
-type WebAppResult struct {
- SubscriptionId string
- Error error
- Ok WebApp
-}
From b00b68368075df122a3325ee9fbfd4f46e3add13 Mon Sep 17 00:00:00 2001
From: Mistah J <26472282+mistahj67@users.noreply.github.com>
Date: Tue, 27 Aug 2024 13:35:56 -0700
Subject: [PATCH 5/8] chore: generate mocks
---
client/app_role_assignments.go | 4 +-
client/apps.go | 11 ++-
client/automation_accounts.go | 4 +-
client/client.go | 68 +++++++++---------
client/container_registries.go | 4 +-
client/devices.go | 8 +--
client/function_apps.go | 4 +-
client/groups.go | 12 ++--
client/keyvaults.go | 4 +-
client/logic_apps.go | 8 +--
client/managed_clusters.go | 4 +-
client/management_groups.go | 8 +--
client/mocks/client.go | 125 +++++++++++++++++----------------
client/resource_groups.go | 4 +-
client/role_assignments.go | 9 ++-
client/roles.go | 4 +-
client/service_principals.go | 9 ++-
client/storage_accounts.go | 8 +--
client/subscriptions.go | 4 +-
client/tenants.go | 8 +--
client/users.go | 8 +--
client/virtual_machines.go | 4 +-
client/vm_scale_sets.go | 4 +-
client/web_apps.go | 4 +-
24 files changed, 163 insertions(+), 167 deletions(-)
diff --git a/client/app_role_assignments.go b/client/app_role_assignments.go
index 8b1033b..c497724 100644
--- a/client/app_role_assignments.go
+++ b/client/app_role_assignments.go
@@ -27,9 +27,9 @@ import (
)
// GetAzureADAppRoleAssignments https://learn.microsoft.com/en-us/graph/api/serviceprincipal-list-approleassignedto?view=graph-rest-1.0
-func (s *azureClient) ListAzureADAppRoleAssignments(ctx context.Context, servicePrincipalId string, params query.GraphParams) <-chan azureResult[azure.AppRoleAssignment] {
+func (s *azureClient) ListAzureADAppRoleAssignments(ctx context.Context, servicePrincipalId string, params query.GraphParams) <-chan AzureResult[azure.AppRoleAssignment] {
var (
- out = make(chan azureResult[azure.AppRoleAssignment])
+ out = make(chan AzureResult[azure.AppRoleAssignment])
path = fmt.Sprintf("/%s/servicePrincipals/%s/appRoleAssignedTo", constants.GraphApiVersion, servicePrincipalId)
)
diff --git a/client/apps.go b/client/apps.go
index 4d191bc..80ce4fa 100644
--- a/client/apps.go
+++ b/client/apps.go
@@ -28,11 +28,10 @@ import (
)
// ListAzureADApps https://learn.microsoft.com/en-us/graph/api/application-list?view=graph-rest-beta
-func (s *azureClient) ListAzureADApps(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Application] {
+func (s *azureClient) ListAzureADApps(ctx context.Context, params query.GraphParams) <-chan AzureResult[azure.Application] {
var (
- out = make(chan azureResult[azure.Application])
- path = fmt.Sprintf("/%s/applications", constants.GraphApiVersion)
-
+ out = make(chan AzureResult[azure.Application])
+ path = fmt.Sprintf("/%s/applications", constants.GraphApiVersion)
)
if params.Top == 0 {
@@ -45,10 +44,10 @@ func (s *azureClient) ListAzureADApps(ctx context.Context, params query.GraphPar
}
// ListAzureADAppOwners https://learn.microsoft.com/en-us/graph/api/application-list-owners?view=graph-rest-beta
-func (s *azureClient) ListAzureADAppOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage] {
+func (s *azureClient) ListAzureADAppOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan AzureResult[json.RawMessage] {
var (
- out = make(chan azureResult[json.RawMessage])
+ out = make(chan AzureResult[json.RawMessage])
path = fmt.Sprintf("/%s/applications/%s/owners", constants.GraphApiBetaVersion, objectId)
)
diff --git a/client/automation_accounts.go b/client/automation_accounts.go
index ec47f5e..67e8a23 100644
--- a/client/automation_accounts.go
+++ b/client/automation_accounts.go
@@ -26,9 +26,9 @@ import (
)
// ListAzureAutomationAccounts https://learn.microsoft.com/en-us/rest/api/automation/automation-account/list?view=rest-automation-2021-06-22
-func (s *azureClient) ListAzureAutomationAccounts(ctx context.Context, subscriptionId string) <-chan azureResult[azure.AutomationAccount] {
+func (s *azureClient) ListAzureAutomationAccounts(ctx context.Context, subscriptionId string) <-chan AzureResult[azure.AutomationAccount] {
var (
- out = make(chan azureResult[azure.AutomationAccount])
+ out = make(chan AzureResult[azure.AutomationAccount])
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Automation/automationAccounts", subscriptionId)
params = query.RMParams{ApiVersion: "2021-06-22"}
)
diff --git a/client/client.go b/client/client.go
index d612508..12c0b0d 100644
--- a/client/client.go
+++ b/client/client.go
@@ -91,17 +91,17 @@ func initClientViaGraph(msgraph, resourceManager rest.RestClient) (AzureClient,
}
}
-type azureResult[T any] struct {
+type AzureResult[T any] struct {
Error error
Ok T
}
-func getAzureObjectList[T any](client rest.RestClient, ctx context.Context, path string, params query.Params, out chan azureResult[T]) {
+func getAzureObjectList[T any](client rest.RestClient, ctx context.Context, path string, params query.Params, out chan AzureResult[T]) {
defer panicrecovery.PanicRecovery()
defer close(out)
var (
- errResult azureResult[T]
+ errResult AzureResult[T]
nextLink string
)
@@ -148,7 +148,7 @@ func getAzureObjectList[T any](client rest.RestClient, ctx context.Context, path
return
} else {
for _, u := range list.Value {
- if ok := pipeline.Send(ctx.Done(), out, azureResult[T]{Ok: u}); !ok {
+ if ok := pipeline.Send(ctx.Done(), out, AzureResult[T]{Ok: u}); !ok {
return
}
}
@@ -184,41 +184,41 @@ type azureClient struct {
type AzureGraphClient interface {
GetAzureADOrganization(ctx context.Context, selectCols []string) (*azure.Organization, error)
- ListAzureADGroups(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Group]
- ListAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage]
- ListAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage]
- ListAzureADAppOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage]
- ListAzureADApps(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Application]
- ListAzureADUsers(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.User]
- ListAzureADRoleAssignments(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.UnifiedRoleAssignment]
- ListAzureADRoles(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Role]
- ListAzureADServicePrincipalOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage]
- ListAzureADServicePrincipals(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.ServicePrincipal]
- ListAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage]
- ListAzureDevices(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Device]
- ListAzureADAppRoleAssignments(ctx context.Context, servicePrincipalId string, params query.GraphParams) <-chan azureResult[azure.AppRoleAssignment]
+ ListAzureADGroups(ctx context.Context, params query.GraphParams) <-chan AzureResult[azure.Group]
+ ListAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) <-chan AzureResult[json.RawMessage]
+ ListAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan AzureResult[json.RawMessage]
+ ListAzureADAppOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan AzureResult[json.RawMessage]
+ ListAzureADApps(ctx context.Context, params query.GraphParams) <-chan AzureResult[azure.Application]
+ ListAzureADUsers(ctx context.Context, params query.GraphParams) <-chan AzureResult[azure.User]
+ ListAzureADRoleAssignments(ctx context.Context, params query.GraphParams) <-chan AzureResult[azure.UnifiedRoleAssignment]
+ ListAzureADRoles(ctx context.Context, params query.GraphParams) <-chan AzureResult[azure.Role]
+ ListAzureADServicePrincipalOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan AzureResult[json.RawMessage]
+ ListAzureADServicePrincipals(ctx context.Context, params query.GraphParams) <-chan AzureResult[azure.ServicePrincipal]
+ ListAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan AzureResult[json.RawMessage]
+ ListAzureDevices(ctx context.Context, params query.GraphParams) <-chan AzureResult[azure.Device]
+ ListAzureADAppRoleAssignments(ctx context.Context, servicePrincipalId string, params query.GraphParams) <-chan AzureResult[azure.AppRoleAssignment]
}
type AzureResourceManagerClient interface {
GetAzureADTenants(ctx context.Context, includeAllTenantCategories bool) (azure.TenantList, error)
- ListRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) <-chan azureResult[azure.RoleAssignment]
- ListAzureADTenants(ctx context.Context, includeAllTenantCategories bool) <-chan azureResult[azure.Tenant]
- ListAzureContainerRegistries(ctx context.Context, subscriptionId string) <-chan azureResult[azure.ContainerRegistry]
- ListAzureWebApps(ctx context.Context, subscriptionId string) <-chan azureResult[azure.WebApp]
- ListAzureManagedClusters(ctx context.Context, subscriptionId string) <-chan azureResult[azure.ManagedCluster]
- ListAzureVMScaleSets(ctx context.Context, subscriptionId string) <-chan azureResult[azure.VMScaleSet]
- ListAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azureResult[azure.KeyVault]
- ListAzureManagementGroups(ctx context.Context, skipToken string) <-chan azureResult[azure.ManagementGroup]
- ListAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) <-chan azureResult[azure.DescendantInfo]
- ListAzureResourceGroups(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azureResult[azure.ResourceGroup]
- ListAzureSubscriptions(ctx context.Context) <-chan azureResult[azure.Subscription]
- ListAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azureResult[azure.VirtualMachine]
- ListAzureStorageAccounts(ctx context.Context, subscriptionId string) <-chan azureResult[azure.StorageAccount]
- ListAzureStorageContainers(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, filter string, includeDeleted string, maxPageSize string) <-chan azureResult[azure.StorageContainer]
- ListAzureAutomationAccounts(ctx context.Context, subscriptionId string) <-chan azureResult[azure.AutomationAccount]
- ListAzureLogicApps(ctx context.Context, subscriptionId string, filter string, top int32) <-chan azureResult[azure.LogicApp]
- ListAzureFunctionApps(ctx context.Context, subscriptionId string) <-chan azureResult[azure.FunctionApp]
+ ListRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) <-chan AzureResult[azure.RoleAssignment]
+ ListAzureADTenants(ctx context.Context, includeAllTenantCategories bool) <-chan AzureResult[azure.Tenant]
+ ListAzureContainerRegistries(ctx context.Context, subscriptionId string) <-chan AzureResult[azure.ContainerRegistry]
+ ListAzureWebApps(ctx context.Context, subscriptionId string) <-chan AzureResult[azure.WebApp]
+ ListAzureManagedClusters(ctx context.Context, subscriptionId string) <-chan AzureResult[azure.ManagedCluster]
+ ListAzureVMScaleSets(ctx context.Context, subscriptionId string) <-chan AzureResult[azure.VMScaleSet]
+ ListAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) <-chan AzureResult[azure.KeyVault]
+ ListAzureManagementGroups(ctx context.Context, skipToken string) <-chan AzureResult[azure.ManagementGroup]
+ ListAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) <-chan AzureResult[azure.DescendantInfo]
+ ListAzureResourceGroups(ctx context.Context, subscriptionId string, params query.RMParams) <-chan AzureResult[azure.ResourceGroup]
+ ListAzureSubscriptions(ctx context.Context) <-chan AzureResult[azure.Subscription]
+ ListAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) <-chan AzureResult[azure.VirtualMachine]
+ ListAzureStorageAccounts(ctx context.Context, subscriptionId string) <-chan AzureResult[azure.StorageAccount]
+ ListAzureStorageContainers(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, filter string, includeDeleted string, maxPageSize string) <-chan AzureResult[azure.StorageContainer]
+ ListAzureAutomationAccounts(ctx context.Context, subscriptionId string) <-chan AzureResult[azure.AutomationAccount]
+ ListAzureLogicApps(ctx context.Context, subscriptionId string, filter string, top int32) <-chan AzureResult[azure.LogicApp]
+ ListAzureFunctionApps(ctx context.Context, subscriptionId string) <-chan AzureResult[azure.FunctionApp]
}
type AzureClient interface {
diff --git a/client/container_registries.go b/client/container_registries.go
index fba5830..cc7d1ed 100644
--- a/client/container_registries.go
+++ b/client/container_registries.go
@@ -26,9 +26,9 @@ import (
)
// ListAzureContainerRegistries https://learn.microsoft.com/en-us/rest/api/containerregistry/registries/list?view=rest-containerregistry-2023-01-01-preview
-func (s *azureClient) ListAzureContainerRegistries(ctx context.Context, subscriptionId string) <-chan azureResult[azure.ContainerRegistry]{
+func (s *azureClient) ListAzureContainerRegistries(ctx context.Context, subscriptionId string) <-chan AzureResult[azure.ContainerRegistry] {
var (
- out = make(chan azureResult[azure.ContainerRegistry])
+ out = make(chan AzureResult[azure.ContainerRegistry])
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.ContainerRegistry/registries", subscriptionId)
params = query.RMParams{ApiVersion: "2023-01-01-preview"}
)
diff --git a/client/devices.go b/client/devices.go
index 9cb51e8..d4935a2 100644
--- a/client/devices.go
+++ b/client/devices.go
@@ -28,9 +28,9 @@ import (
)
// ListAzureDevices https://learn.microsoft.com/en-us/graph/api/device-list?view=graph-rest-1.0
-func (s *azureClient) ListAzureDevices(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Device]{
+func (s *azureClient) ListAzureDevices(ctx context.Context, params query.GraphParams) <-chan AzureResult[azure.Device] {
var (
- out = make(chan azureResult[azure.Device])
+ out = make(chan AzureResult[azure.Device])
path = fmt.Sprintf("/%s/devices", constants.GraphApiVersion)
)
@@ -44,9 +44,9 @@ func (s *azureClient) ListAzureDevices(ctx context.Context, params query.GraphPa
}
// ListAzureDeviceRegisteredOwners https://learn.microsoft.com/en-us/graph/api/device-list-registeredowners?view=graph-rest-beta
-func (s *azureClient) ListAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage] {
+func (s *azureClient) ListAzureDeviceRegisteredOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan AzureResult[json.RawMessage] {
var (
- out = make(chan azureResult[json.RawMessage])
+ out = make(chan AzureResult[json.RawMessage])
path = fmt.Sprintf("/%s/devices/%s/registeredOwners", constants.GraphApiBetaVersion, objectId)
)
diff --git a/client/function_apps.go b/client/function_apps.go
index eeb44e1..9c924d0 100644
--- a/client/function_apps.go
+++ b/client/function_apps.go
@@ -26,9 +26,9 @@ import (
)
// ListAzureFunctionApps
-func (s *azureClient) ListAzureFunctionApps(ctx context.Context, subscriptionId string) <-chan azureResult[azure.FunctionApp] {
+func (s *azureClient) ListAzureFunctionApps(ctx context.Context, subscriptionId string) <-chan AzureResult[azure.FunctionApp] {
var (
- out = make(chan azureResult[azure.FunctionApp])
+ out = make(chan AzureResult[azure.FunctionApp])
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Web/sites", subscriptionId)
params = query.RMParams{ApiVersion: "2022-03-01"}
)
diff --git a/client/groups.go b/client/groups.go
index 130b96f..824c8fe 100644
--- a/client/groups.go
+++ b/client/groups.go
@@ -28,9 +28,9 @@ import (
)
// ListAzureADGroups https://learn.microsoft.com/en-us/graph/api/group-list?view=graph-rest-beta
-func (s *azureClient) ListAzureADGroups(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Group] {
+func (s *azureClient) ListAzureADGroups(ctx context.Context, params query.GraphParams) <-chan AzureResult[azure.Group] {
var (
- out = make(chan azureResult[azure.Group])
+ out = make(chan AzureResult[azure.Group])
path = fmt.Sprintf("/%s/groups", constants.GraphApiVersion)
)
@@ -44,9 +44,9 @@ func (s *azureClient) ListAzureADGroups(ctx context.Context, params query.GraphP
}
// ListAzureADGroupOwners https://learn.microsoft.com/en-us/graph/api/group-list-owners?view=graph-rest-beta
-func (s *azureClient) ListAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage] {
+func (s *azureClient) ListAzureADGroupOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan AzureResult[json.RawMessage] {
var (
- out = make(chan azureResult[json.RawMessage])
+ out = make(chan AzureResult[json.RawMessage])
path = fmt.Sprintf("/%s/groups/%s/owners", constants.GraphApiBetaVersion, objectId)
)
@@ -60,9 +60,9 @@ func (s *azureClient) ListAzureADGroupOwners(ctx context.Context, objectId strin
}
// ListAzureADGroupMembers https://learn.microsoft.com/en-us/graph/api/group-list-members?view=graph-rest-beta
-func (s *azureClient) ListAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage] {
+func (s *azureClient) ListAzureADGroupMembers(ctx context.Context, objectId string, params query.GraphParams) <-chan AzureResult[json.RawMessage] {
var (
- out = make(chan azureResult[json.RawMessage])
+ out = make(chan AzureResult[json.RawMessage])
path = fmt.Sprintf("/%s/groups/%s/members", constants.GraphApiBetaVersion, objectId)
)
diff --git a/client/keyvaults.go b/client/keyvaults.go
index 91b38cb..c7735c7 100644
--- a/client/keyvaults.go
+++ b/client/keyvaults.go
@@ -26,9 +26,9 @@ import (
)
// ListAzureKeyVaults https://learn.microsoft.com/en-us/rest/api/keyvault/keyvault/vaults/list-by-subscription?view=rest-keyvault-keyvault-2019-09-01
-func (s *azureClient) ListAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azureResult[azure.KeyVault] {
+func (s *azureClient) ListAzureKeyVaults(ctx context.Context, subscriptionId string, params query.RMParams) <-chan AzureResult[azure.KeyVault] {
var (
- out = make(chan azureResult[azure.KeyVault])
+ out = make(chan AzureResult[azure.KeyVault])
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.KeyVault/vaults", subscriptionId)
)
diff --git a/client/logic_apps.go b/client/logic_apps.go
index 202da2a..711bfe2 100644
--- a/client/logic_apps.go
+++ b/client/logic_apps.go
@@ -26,11 +26,11 @@ import (
)
// ListAzureLogicApps https://learn.microsoft.com/en-us/rest/api/logic/workflows/list-by-subscription?view=rest-logic-2016-06-01
-func (s *azureClient) ListAzureLogicApps(ctx context.Context, subscriptionId string, filter string, top int32) <-chan azureResult[azure.LogicApp] {
+func (s *azureClient) ListAzureLogicApps(ctx context.Context, subscriptionId string, filter string, top int32) <-chan AzureResult[azure.LogicApp] {
var (
- out = make(chan azureResult[azure.LogicApp])
- path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Logic/workflows", subscriptionId)
- params = query.RMParams{ApiVersion: "2016-06-01", Filter: filter, Top: top}
+ out = make(chan AzureResult[azure.LogicApp])
+ path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Logic/workflows", subscriptionId)
+ params = query.RMParams{ApiVersion: "2016-06-01", Filter: filter, Top: top}
)
go getAzureObjectList[azure.LogicApp](s.resourceManager, ctx, path, params, out)
diff --git a/client/managed_clusters.go b/client/managed_clusters.go
index 8c9d421..05c6b19 100644
--- a/client/managed_clusters.go
+++ b/client/managed_clusters.go
@@ -26,9 +26,9 @@ import (
)
// ListAzureManagedClusters https://learn.microsoft.com/en-us/rest/api/servicefabric/managedclusters/managed-clusters/list-by-subscription?view=rest-servicefabric-managedclusters-2021-07-01
-func (s *azureClient) ListAzureManagedClusters(ctx context.Context, subscriptionId string) <-chan azureResult[azure.ManagedCluster] {
+func (s *azureClient) ListAzureManagedClusters(ctx context.Context, subscriptionId string) <-chan AzureResult[azure.ManagedCluster] {
var (
- out = make(chan azureResult[azure.ManagedCluster])
+ out = make(chan AzureResult[azure.ManagedCluster])
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.ContainerService/managedClusters", subscriptionId)
params = query.RMParams{ApiVersion: "2021-07-01"}
)
diff --git a/client/management_groups.go b/client/management_groups.go
index c2932a0..a269b92 100644
--- a/client/management_groups.go
+++ b/client/management_groups.go
@@ -26,9 +26,9 @@ import (
)
// ListAzureManagementGroups https://learn.microsoft.com/en-us/rest/api/managementgroups/management-groups/list?view=rest-managementgroups-2020-05-01
-func (s *azureClient) ListAzureManagementGroups(ctx context.Context, skipToken string) <-chan azureResult[azure.ManagementGroup] {
+func (s *azureClient) ListAzureManagementGroups(ctx context.Context, skipToken string) <-chan AzureResult[azure.ManagementGroup] {
var (
- out = make(chan azureResult[azure.ManagementGroup])
+ out = make(chan AzureResult[azure.ManagementGroup])
path = "/providers/Microsoft.Management/managementGroups"
params = query.RMParams{ApiVersion: "2020-05-01", SkipToken: skipToken}
)
@@ -39,9 +39,9 @@ func (s *azureClient) ListAzureManagementGroups(ctx context.Context, skipToken s
}
// ListAzureManagementGroupDescendants https://learn.microsoft.com/en-us/rest/api/managementgroups/management-groups/get-descendants?view=rest-managementgroups-2020-05-01
-func (s *azureClient) ListAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) <-chan azureResult[azure.DescendantInfo] {
+func (s *azureClient) ListAzureManagementGroupDescendants(ctx context.Context, groupId string, top int32) <-chan AzureResult[azure.DescendantInfo] {
var (
- out = make(chan azureResult[azure.DescendantInfo])
+ out = make(chan AzureResult[azure.DescendantInfo])
path = fmt.Sprintf("/providers/Microsoft.Management/managementGroups/%s/descendants", groupId)
params = query.RMParams{ApiVersion: "2020-05-01", Top: top}
)
diff --git a/client/mocks/client.go b/client/mocks/client.go
index ce00d37..a621317 100644
--- a/client/mocks/client.go
+++ b/client/mocks/client.go
@@ -6,11 +6,12 @@ package mocks
import (
context "context"
- reflect "reflect"
-
+ json "encoding/json"
+ client "github.com/bloodhoundad/azurehound/v2/client"
query "github.com/bloodhoundad/azurehound/v2/client/query"
azure "github.com/bloodhoundad/azurehound/v2/models/azure"
gomock "go.uber.org/mock/gomock"
+ reflect "reflect"
)
// MockAzureClient is a mock of AzureClient interface.
@@ -79,10 +80,10 @@ func (mr *MockAzureClientMockRecorder) GetAzureADTenants(arg0, arg1 interface{})
}
// ListAzureADAppOwners mocks base method.
-func (m *MockAzureClient) ListAzureADAppOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan azure.AppOwnerResult {
+func (m *MockAzureClient) ListAzureADAppOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan client.AzureResult[json.RawMessage] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureADAppOwners", arg0, arg1, arg2)
- ret0, _ := ret[0].(<-chan azure.AppOwnerResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[json.RawMessage])
return ret0
}
@@ -93,10 +94,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureADAppOwners(arg0, arg1, arg2 int
}
// ListAzureADAppRoleAssignments mocks base method.
-func (m *MockAzureClient) ListAzureADAppRoleAssignments(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan azure.AppRoleAssignmentResult {
+func (m *MockAzureClient) ListAzureADAppRoleAssignments(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan client.AzureResult[azure.AppRoleAssignment] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureADAppRoleAssignments", arg0, arg1, arg2)
- ret0, _ := ret[0].(<-chan azure.AppRoleAssignmentResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.AppRoleAssignment])
return ret0
}
@@ -107,10 +108,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureADAppRoleAssignments(arg0, arg1,
}
// ListAzureADApps mocks base method.
-func (m *MockAzureClient) ListAzureADApps(arg0 context.Context, arg1 query.GraphParams) <-chan azure.ApplicationResult {
+func (m *MockAzureClient) ListAzureADApps(arg0 context.Context, arg1 query.GraphParams) <-chan client.AzureResult[azure.Application] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureADApps", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.ApplicationResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.Application])
return ret0
}
@@ -121,10 +122,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureADApps(arg0, arg1 interface{}) *
}
// ListAzureADGroupMembers mocks base method.
-func (m *MockAzureClient) ListAzureADGroupMembers(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan azure.MemberObjectResult {
+func (m *MockAzureClient) ListAzureADGroupMembers(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan client.AzureResult[json.RawMessage] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureADGroupMembers", arg0, arg1, arg2)
- ret0, _ := ret[0].(<-chan azure.MemberObjectResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[json.RawMessage])
return ret0
}
@@ -135,10 +136,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureADGroupMembers(arg0, arg1, arg2
}
// ListAzureADGroupOwners mocks base method.
-func (m *MockAzureClient) ListAzureADGroupOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan azure.GroupOwnerResult {
+func (m *MockAzureClient) ListAzureADGroupOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan client.AzureResult[json.RawMessage] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureADGroupOwners", arg0, arg1, arg2)
- ret0, _ := ret[0].(<-chan azure.GroupOwnerResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[json.RawMessage])
return ret0
}
@@ -149,10 +150,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureADGroupOwners(arg0, arg1, arg2 i
}
// ListAzureADGroups mocks base method.
-func (m *MockAzureClient) ListAzureADGroups(arg0 context.Context, arg1 query.GraphParams) <-chan azure.GroupResult {
+func (m *MockAzureClient) ListAzureADGroups(arg0 context.Context, arg1 query.GraphParams) <-chan client.AzureResult[azure.Group] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureADGroups", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.GroupResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.Group])
return ret0
}
@@ -163,10 +164,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureADGroups(arg0, arg1 interface{})
}
// ListAzureADRoleAssignments mocks base method.
-func (m *MockAzureClient) ListAzureADRoleAssignments(arg0 context.Context, arg1 query.GraphParams) <-chan azure.UnifiedRoleAssignmentResult {
+func (m *MockAzureClient) ListAzureADRoleAssignments(arg0 context.Context, arg1 query.GraphParams) <-chan client.AzureResult[azure.UnifiedRoleAssignment] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureADRoleAssignments", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.UnifiedRoleAssignmentResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.UnifiedRoleAssignment])
return ret0
}
@@ -177,10 +178,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureADRoleAssignments(arg0, arg1 int
}
// ListAzureADRoles mocks base method.
-func (m *MockAzureClient) ListAzureADRoles(arg0 context.Context, arg1 query.GraphParams) <-chan azure.RoleResult {
+func (m *MockAzureClient) ListAzureADRoles(arg0 context.Context, arg1 query.GraphParams) <-chan client.AzureResult[azure.Role] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureADRoles", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.RoleResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.Role])
return ret0
}
@@ -191,10 +192,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureADRoles(arg0, arg1 interface{})
}
// ListAzureADServicePrincipalOwners mocks base method.
-func (m *MockAzureClient) ListAzureADServicePrincipalOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan azure.ServicePrincipalOwnerResult {
+func (m *MockAzureClient) ListAzureADServicePrincipalOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan client.AzureResult[json.RawMessage] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureADServicePrincipalOwners", arg0, arg1, arg2)
- ret0, _ := ret[0].(<-chan azure.ServicePrincipalOwnerResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[json.RawMessage])
return ret0
}
@@ -205,10 +206,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureADServicePrincipalOwners(arg0, a
}
// ListAzureADServicePrincipals mocks base method.
-func (m *MockAzureClient) ListAzureADServicePrincipals(arg0 context.Context, arg1 query.GraphParams) <-chan azure.ServicePrincipalResult {
+func (m *MockAzureClient) ListAzureADServicePrincipals(arg0 context.Context, arg1 query.GraphParams) <-chan client.AzureResult[azure.ServicePrincipal] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureADServicePrincipals", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.ServicePrincipalResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.ServicePrincipal])
return ret0
}
@@ -219,10 +220,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureADServicePrincipals(arg0, arg1 i
}
// ListAzureADTenants mocks base method.
-func (m *MockAzureClient) ListAzureADTenants(arg0 context.Context, arg1 bool) <-chan azure.TenantResult {
+func (m *MockAzureClient) ListAzureADTenants(arg0 context.Context, arg1 bool) <-chan client.AzureResult[azure.Tenant] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureADTenants", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.TenantResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.Tenant])
return ret0
}
@@ -233,10 +234,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureADTenants(arg0, arg1 interface{}
}
// ListAzureADUsers mocks base method.
-func (m *MockAzureClient) ListAzureADUsers(arg0 context.Context, arg1 query.GraphParams) <-chan azure.UserResult {
+func (m *MockAzureClient) ListAzureADUsers(arg0 context.Context, arg1 query.GraphParams) <-chan client.AzureResult[azure.User] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureADUsers", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.UserResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.User])
return ret0
}
@@ -247,10 +248,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureADUsers(arg0, arg1 interface{})
}
// ListAzureAutomationAccounts mocks base method.
-func (m *MockAzureClient) ListAzureAutomationAccounts(arg0 context.Context, arg1 string) <-chan azure.AutomationAccountResult {
+func (m *MockAzureClient) ListAzureAutomationAccounts(arg0 context.Context, arg1 string) <-chan client.AzureResult[azure.AutomationAccount] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureAutomationAccounts", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.AutomationAccountResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.AutomationAccount])
return ret0
}
@@ -261,10 +262,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureAutomationAccounts(arg0, arg1 in
}
// ListAzureContainerRegistries mocks base method.
-func (m *MockAzureClient) ListAzureContainerRegistries(arg0 context.Context, arg1 string) <-chan azure.ContainerRegistryResult {
+func (m *MockAzureClient) ListAzureContainerRegistries(arg0 context.Context, arg1 string) <-chan client.AzureResult[azure.ContainerRegistry] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureContainerRegistries", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.ContainerRegistryResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.ContainerRegistry])
return ret0
}
@@ -275,10 +276,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureContainerRegistries(arg0, arg1 i
}
// ListAzureDeviceRegisteredOwners mocks base method.
-func (m *MockAzureClient) ListAzureDeviceRegisteredOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan azure.DeviceRegisteredOwnerResult {
+func (m *MockAzureClient) ListAzureDeviceRegisteredOwners(arg0 context.Context, arg1 string, arg2 query.GraphParams) <-chan client.AzureResult[json.RawMessage] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureDeviceRegisteredOwners", arg0, arg1, arg2)
- ret0, _ := ret[0].(<-chan azure.DeviceRegisteredOwnerResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[json.RawMessage])
return ret0
}
@@ -289,10 +290,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureDeviceRegisteredOwners(arg0, arg
}
// ListAzureDevices mocks base method.
-func (m *MockAzureClient) ListAzureDevices(arg0 context.Context, arg1 query.GraphParams) <-chan azure.DeviceResult {
+func (m *MockAzureClient) ListAzureDevices(arg0 context.Context, arg1 query.GraphParams) <-chan client.AzureResult[azure.Device] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureDevices", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.DeviceResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.Device])
return ret0
}
@@ -303,10 +304,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureDevices(arg0, arg1 interface{})
}
// ListAzureFunctionApps mocks base method.
-func (m *MockAzureClient) ListAzureFunctionApps(arg0 context.Context, arg1 string) <-chan azure.FunctionAppResult {
+func (m *MockAzureClient) ListAzureFunctionApps(arg0 context.Context, arg1 string) <-chan client.AzureResult[azure.FunctionApp] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureFunctionApps", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.FunctionAppResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.FunctionApp])
return ret0
}
@@ -317,10 +318,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureFunctionApps(arg0, arg1 interfac
}
// ListAzureKeyVaults mocks base method.
-func (m *MockAzureClient) ListAzureKeyVaults(arg0 context.Context, arg1 string, arg2 query.RMParams) <-chan azure.KeyVaultResult {
+func (m *MockAzureClient) ListAzureKeyVaults(arg0 context.Context, arg1 string, arg2 query.RMParams) <-chan client.AzureResult[azure.KeyVault] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureKeyVaults", arg0, arg1, arg2)
- ret0, _ := ret[0].(<-chan azure.KeyVaultResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.KeyVault])
return ret0
}
@@ -331,10 +332,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureKeyVaults(arg0, arg1, arg2 inter
}
// ListAzureLogicApps mocks base method.
-func (m *MockAzureClient) ListAzureLogicApps(arg0 context.Context, arg1, arg2 string, arg3 int32) <-chan azure.LogicAppResult {
+func (m *MockAzureClient) ListAzureLogicApps(arg0 context.Context, arg1, arg2 string, arg3 int32) <-chan client.AzureResult[azure.LogicApp] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureLogicApps", arg0, arg1, arg2, arg3)
- ret0, _ := ret[0].(<-chan azure.LogicAppResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.LogicApp])
return ret0
}
@@ -345,10 +346,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureLogicApps(arg0, arg1, arg2, arg3
}
// ListAzureManagedClusters mocks base method.
-func (m *MockAzureClient) ListAzureManagedClusters(arg0 context.Context, arg1 string) <-chan azure.ManagedClusterResult {
+func (m *MockAzureClient) ListAzureManagedClusters(arg0 context.Context, arg1 string) <-chan client.AzureResult[azure.ManagedCluster] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureManagedClusters", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.ManagedClusterResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.ManagedCluster])
return ret0
}
@@ -359,10 +360,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureManagedClusters(arg0, arg1 inter
}
// ListAzureManagementGroupDescendants mocks base method.
-func (m *MockAzureClient) ListAzureManagementGroupDescendants(arg0 context.Context, arg1 string, arg2 int32) <-chan azure.DescendantInfoResult {
+func (m *MockAzureClient) ListAzureManagementGroupDescendants(arg0 context.Context, arg1 string, arg2 int32) <-chan client.AzureResult[azure.DescendantInfo] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureManagementGroupDescendants", arg0, arg1, arg2)
- ret0, _ := ret[0].(<-chan azure.DescendantInfoResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.DescendantInfo])
return ret0
}
@@ -373,10 +374,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureManagementGroupDescendants(arg0,
}
// ListAzureManagementGroups mocks base method.
-func (m *MockAzureClient) ListAzureManagementGroups(arg0 context.Context, arg1 string) <-chan azure.ManagementGroupResult {
+func (m *MockAzureClient) ListAzureManagementGroups(arg0 context.Context, arg1 string) <-chan client.AzureResult[azure.ManagementGroup] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureManagementGroups", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.ManagementGroupResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.ManagementGroup])
return ret0
}
@@ -387,10 +388,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureManagementGroups(arg0, arg1 inte
}
// ListAzureResourceGroups mocks base method.
-func (m *MockAzureClient) ListAzureResourceGroups(arg0 context.Context, arg1 string, arg2 query.RMParams) <-chan azure.ResourceGroupResult {
+func (m *MockAzureClient) ListAzureResourceGroups(arg0 context.Context, arg1 string, arg2 query.RMParams) <-chan client.AzureResult[azure.ResourceGroup] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureResourceGroups", arg0, arg1, arg2)
- ret0, _ := ret[0].(<-chan azure.ResourceGroupResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.ResourceGroup])
return ret0
}
@@ -401,10 +402,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureResourceGroups(arg0, arg1, arg2
}
// ListAzureStorageAccounts mocks base method.
-func (m *MockAzureClient) ListAzureStorageAccounts(arg0 context.Context, arg1 string) <-chan azure.StorageAccountResult {
+func (m *MockAzureClient) ListAzureStorageAccounts(arg0 context.Context, arg1 string) <-chan client.AzureResult[azure.StorageAccount] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureStorageAccounts", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.StorageAccountResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.StorageAccount])
return ret0
}
@@ -415,10 +416,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureStorageAccounts(arg0, arg1 inter
}
// ListAzureStorageContainers mocks base method.
-func (m *MockAzureClient) ListAzureStorageContainers(arg0 context.Context, arg1, arg2, arg3, arg4, arg5, arg6 string) <-chan azure.StorageContainerResult {
+func (m *MockAzureClient) ListAzureStorageContainers(arg0 context.Context, arg1, arg2, arg3, arg4, arg5, arg6 string) <-chan client.AzureResult[azure.StorageContainer] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureStorageContainers", arg0, arg1, arg2, arg3, arg4, arg5, arg6)
- ret0, _ := ret[0].(<-chan azure.StorageContainerResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.StorageContainer])
return ret0
}
@@ -429,10 +430,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureStorageContainers(arg0, arg1, ar
}
// ListAzureSubscriptions mocks base method.
-func (m *MockAzureClient) ListAzureSubscriptions(arg0 context.Context) <-chan azure.SubscriptionResult {
+func (m *MockAzureClient) ListAzureSubscriptions(arg0 context.Context) <-chan client.AzureResult[azure.Subscription] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureSubscriptions", arg0)
- ret0, _ := ret[0].(<-chan azure.SubscriptionResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.Subscription])
return ret0
}
@@ -443,10 +444,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureSubscriptions(arg0 interface{})
}
// ListAzureVMScaleSets mocks base method.
-func (m *MockAzureClient) ListAzureVMScaleSets(arg0 context.Context, arg1 string) <-chan azure.VMScaleSetResult {
+func (m *MockAzureClient) ListAzureVMScaleSets(arg0 context.Context, arg1 string) <-chan client.AzureResult[azure.VMScaleSet] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureVMScaleSets", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.VMScaleSetResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.VMScaleSet])
return ret0
}
@@ -457,10 +458,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureVMScaleSets(arg0, arg1 interface
}
// ListAzureVirtualMachines mocks base method.
-func (m *MockAzureClient) ListAzureVirtualMachines(arg0 context.Context, arg1 string, arg2 query.RMParams) <-chan azure.VirtualMachineResult {
+func (m *MockAzureClient) ListAzureVirtualMachines(arg0 context.Context, arg1 string, arg2 query.RMParams) <-chan client.AzureResult[azure.VirtualMachine] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureVirtualMachines", arg0, arg1, arg2)
- ret0, _ := ret[0].(<-chan azure.VirtualMachineResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.VirtualMachine])
return ret0
}
@@ -471,10 +472,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureVirtualMachines(arg0, arg1, arg2
}
// ListAzureWebApps mocks base method.
-func (m *MockAzureClient) ListAzureWebApps(arg0 context.Context, arg1 string) <-chan azure.WebAppResult {
+func (m *MockAzureClient) ListAzureWebApps(arg0 context.Context, arg1 string) <-chan client.AzureResult[azure.WebApp] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListAzureWebApps", arg0, arg1)
- ret0, _ := ret[0].(<-chan azure.WebAppResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.WebApp])
return ret0
}
@@ -485,10 +486,10 @@ func (mr *MockAzureClientMockRecorder) ListAzureWebApps(arg0, arg1 interface{})
}
// ListRoleAssignmentsForResource mocks base method.
-func (m *MockAzureClient) ListRoleAssignmentsForResource(arg0 context.Context, arg1, arg2, arg3 string) <-chan azure.RoleAssignmentResult {
+func (m *MockAzureClient) ListRoleAssignmentsForResource(arg0 context.Context, arg1, arg2, arg3 string) <-chan client.AzureResult[azure.RoleAssignment] {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ListRoleAssignmentsForResource", arg0, arg1, arg2, arg3)
- ret0, _ := ret[0].(<-chan azure.RoleAssignmentResult)
+ ret0, _ := ret[0].(<-chan client.AzureResult[azure.RoleAssignment])
return ret0
}
diff --git a/client/resource_groups.go b/client/resource_groups.go
index ae3364c..cff4182 100644
--- a/client/resource_groups.go
+++ b/client/resource_groups.go
@@ -26,9 +26,9 @@ import (
)
// ListAzureResourceGroups https://learn.microsoft.com/en-us/rest/api/resources/resource-groups/list?view=rest-resources-2021-04-01
-func (s *azureClient) ListAzureResourceGroups(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azureResult[azure.ResourceGroup] {
+func (s *azureClient) ListAzureResourceGroups(ctx context.Context, subscriptionId string, params query.RMParams) <-chan AzureResult[azure.ResourceGroup] {
var (
- out = make(chan azureResult[azure.ResourceGroup])
+ out = make(chan AzureResult[azure.ResourceGroup])
path = fmt.Sprintf("/subscriptions/%s/resourcegroups", subscriptionId)
)
diff --git a/client/role_assignments.go b/client/role_assignments.go
index 5fa841d..f742f54 100644
--- a/client/role_assignments.go
+++ b/client/role_assignments.go
@@ -27,11 +27,10 @@ import (
)
// ListAzureADRoleAssignments https://learn.microsoft.com/en-us/graph/api/rbacapplication-list-roleassignments?view=graph-rest-beta
-func (s *azureClient) ListAzureADRoleAssignments(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.UnifiedRoleAssignment] {
+func (s *azureClient) ListAzureADRoleAssignments(ctx context.Context, params query.GraphParams) <-chan AzureResult[azure.UnifiedRoleAssignment] {
var (
- out = make(chan azureResult[azure.UnifiedRoleAssignment])
+ out = make(chan AzureResult[azure.UnifiedRoleAssignment])
path = fmt.Sprintf("/%s/roleManagement/directory/roleAssignments", constants.GraphApiVersion)
-
)
if params.Top == 0 {
@@ -43,9 +42,9 @@ func (s *azureClient) ListAzureADRoleAssignments(ctx context.Context, params que
}
// ListRoleAssignmentsForResource https://learn.microsoft.com/en-us/rest/api/authorization/role-assignments/list-for-resource?view=rest-authorization-2015-07-01
-func (s *azureClient) ListRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) <-chan azureResult[azure.RoleAssignment] {
+func (s *azureClient) ListRoleAssignmentsForResource(ctx context.Context, resourceId string, filter, tenantId string) <-chan AzureResult[azure.RoleAssignment] {
var (
- out = make(chan azureResult[azure.RoleAssignment])
+ out = make(chan AzureResult[azure.RoleAssignment])
path = fmt.Sprintf("%s/providers/Microsoft.Authorization/roleAssignments", resourceId)
params = query.RMParams{ApiVersion: "2015-07-01", Filter: filter, TenantId: tenantId}
)
diff --git a/client/roles.go b/client/roles.go
index 3baea14..6299ef2 100644
--- a/client/roles.go
+++ b/client/roles.go
@@ -27,9 +27,9 @@ import (
)
// ListAzureADRoles https://learn.microsoft.com/en-us/graph/api/rbacapplication-list-roledefinitions?view=graph-rest-beta
-func (s *azureClient) ListAzureADRoles(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.Role] {
+func (s *azureClient) ListAzureADRoles(ctx context.Context, params query.GraphParams) <-chan AzureResult[azure.Role] {
var (
- out = make(chan azureResult[azure.Role])
+ out = make(chan AzureResult[azure.Role])
path = fmt.Sprintf("/%s/roleManagement/directory/roleDefinitions", constants.GraphApiVersion)
)
diff --git a/client/service_principals.go b/client/service_principals.go
index cd474ed..0c56e8c 100644
--- a/client/service_principals.go
+++ b/client/service_principals.go
@@ -28,11 +28,10 @@ import (
)
// ListAzureADServicePrincipals https://learn.microsoft.com/en-us/graph/api/serviceprincipal-list?view=graph-rest-beta
-func (s *azureClient) ListAzureADServicePrincipals(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.ServicePrincipal] {
+func (s *azureClient) ListAzureADServicePrincipals(ctx context.Context, params query.GraphParams) <-chan AzureResult[azure.ServicePrincipal] {
var (
- out = make(chan azureResult[azure.ServicePrincipal])
+ out = make(chan AzureResult[azure.ServicePrincipal])
path = fmt.Sprintf("/%s/servicePrincipals", constants.GraphApiVersion)
-
)
if params.Top == 0 {
@@ -45,9 +44,9 @@ func (s *azureClient) ListAzureADServicePrincipals(ctx context.Context, params q
}
// ListAzureADServicePrincipalOwners https://learn.microsoft.com/en-us/graph/api/serviceprincipal-list-owners?view=graph-rest-beta
-func (s *azureClient) ListAzureADServicePrincipalOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan azureResult[json.RawMessage] {
+func (s *azureClient) ListAzureADServicePrincipalOwners(ctx context.Context, objectId string, params query.GraphParams) <-chan AzureResult[json.RawMessage] {
var (
- out = make(chan azureResult[json.RawMessage])
+ out = make(chan AzureResult[json.RawMessage])
path = fmt.Sprintf("/%s/servicePrincipals/%s/owners", constants.GraphApiBetaVersion, objectId)
)
diff --git a/client/storage_accounts.go b/client/storage_accounts.go
index 5c2e565..402d247 100644
--- a/client/storage_accounts.go
+++ b/client/storage_accounts.go
@@ -26,9 +26,9 @@ import (
)
// ListAzureStorageAccounts https://learn.microsoft.com/en-us/rest/api/storagerp/storage-accounts/list?view=rest-storagerp-2022-05-01
-func (s *azureClient) ListAzureStorageAccounts(ctx context.Context, subscriptionId string) <-chan azureResult[azure.StorageAccount] {
+func (s *azureClient) ListAzureStorageAccounts(ctx context.Context, subscriptionId string) <-chan AzureResult[azure.StorageAccount] {
var (
- out = make(chan azureResult[azure.StorageAccount])
+ out = make(chan AzureResult[azure.StorageAccount])
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Storage/storageAccounts", subscriptionId)
params = query.RMParams{ApiVersion: "2022-05-01"}
)
@@ -43,9 +43,9 @@ func (s *azureClient) ListAzureStorageAccounts(ctx context.Context, subscription
// ==
// ListAzureStorageContainers https://learn.microsoft.com/en-us/rest/api/storagerp/blob-containers/list?view=rest-storagerp-2022-05-01
-func (s *azureClient) ListAzureStorageContainers(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, filter string, includeDeleted string, maxPageSize string) <-chan azureResult[azure.StorageContainer] {
+func (s *azureClient) ListAzureStorageContainers(ctx context.Context, subscriptionId string, resourceGroupName string, saName string, filter string, includeDeleted string, maxPageSize string) <-chan AzureResult[azure.StorageContainer] {
var (
- out = make(chan azureResult[azure.StorageContainer])
+ out = make(chan AzureResult[azure.StorageContainer])
path = fmt.Sprintf("/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Storage/storageAccounts/%s/blobServices/default/containers", subscriptionId, resourceGroupName, saName)
params = query.RMParams{ApiVersion: "2022-05-01", Filter: filter, IncludeDeleted: includeDeleted, MaxPageSize: maxPageSize}
)
diff --git a/client/subscriptions.go b/client/subscriptions.go
index 5f2387a..0ed8933 100644
--- a/client/subscriptions.go
+++ b/client/subscriptions.go
@@ -25,9 +25,9 @@ import (
)
// ListAzureSubscriptions https://learn.microsoft.com/en-us/rest/api/subscription/subscriptions/list?view=rest-subscription-2020-01-01
-func (s *azureClient) ListAzureSubscriptions(ctx context.Context) <-chan azureResult[azure.Subscription] {
+func (s *azureClient) ListAzureSubscriptions(ctx context.Context) <-chan AzureResult[azure.Subscription] {
var (
- out = make(chan azureResult[azure.Subscription])
+ out = make(chan AzureResult[azure.Subscription])
path = "/subscriptions"
params = query.RMParams{ApiVersion: "2020-01-01"}
)
diff --git a/client/tenants.go b/client/tenants.go
index 0ed59d4..4aa8966 100644
--- a/client/tenants.go
+++ b/client/tenants.go
@@ -59,11 +59,11 @@ func (s *azureClient) GetAzureADTenants(ctx context.Context, includeAllTenantCat
}
// ListAzureADTenants https://learn.microsoft.com/en-us/rest/api/subscription/tenants/list?view=rest-subscription-2020-01-01
-func (s *azureClient) ListAzureADTenants(ctx context.Context, includeAllTenantCategories bool) <-chan azureResult[azure.Tenant] {
+func (s *azureClient) ListAzureADTenants(ctx context.Context, includeAllTenantCategories bool) <-chan AzureResult[azure.Tenant] {
var (
- out = make(chan azureResult[azure.Tenant])
- path = "/tenants"
- params = query.RMParams{ApiVersion: "2020-01-01", IncludeAllTenantCategories: includeAllTenantCategories}
+ out = make(chan AzureResult[azure.Tenant])
+ path = "/tenants"
+ params = query.RMParams{ApiVersion: "2020-01-01", IncludeAllTenantCategories: includeAllTenantCategories}
)
go getAzureObjectList[azure.Tenant](s.resourceManager, ctx, path, params, out)
diff --git a/client/users.go b/client/users.go
index 8f203e4..d20f4bf 100644
--- a/client/users.go
+++ b/client/users.go
@@ -26,13 +26,11 @@ import (
"github.com/bloodhoundad/azurehound/v2/models/azure"
)
-
// ListAzureADUsers https://learn.microsoft.com/en-us/graph/api/user-list?view=graph-rest-beta
-func (s *azureClient) ListAzureADUsers(ctx context.Context, params query.GraphParams) <-chan azureResult[azure.User]{
+func (s *azureClient) ListAzureADUsers(ctx context.Context, params query.GraphParams) <-chan AzureResult[azure.User] {
var (
- out = make(chan azureResult[azure.User])
- path = fmt.Sprintf("/%s/users", constants.GraphApiVersion)
-
+ out = make(chan AzureResult[azure.User])
+ path = fmt.Sprintf("/%s/users", constants.GraphApiVersion)
)
if params.Top == 0 {
diff --git a/client/virtual_machines.go b/client/virtual_machines.go
index 417ce91..673d36c 100644
--- a/client/virtual_machines.go
+++ b/client/virtual_machines.go
@@ -26,9 +26,9 @@ import (
)
// ListAzureVirtualMachines https://learn.microsoft.com/en-us/rest/api/compute/virtual-machines/list-all?view=rest-compute-2021-07-01
-func (s *azureClient) ListAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) <-chan azureResult[azure.VirtualMachine] {
+func (s *azureClient) ListAzureVirtualMachines(ctx context.Context, subscriptionId string, params query.RMParams) <-chan AzureResult[azure.VirtualMachine] {
var (
- out = make(chan azureResult[azure.VirtualMachine])
+ out = make(chan AzureResult[azure.VirtualMachine])
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Compute/virtualMachines", subscriptionId)
)
diff --git a/client/vm_scale_sets.go b/client/vm_scale_sets.go
index af79878..8ac1e42 100644
--- a/client/vm_scale_sets.go
+++ b/client/vm_scale_sets.go
@@ -26,9 +26,9 @@ import (
)
// ListAzureVMScaleSets https://learn.microsoft.com/en-us/rest/api/compute/virtual-machine-scale-sets/list-all?view=rest-compute-2022-11-01
-func (s *azureClient) ListAzureVMScaleSets(ctx context.Context, subscriptionId string) <-chan azureResult[azure.VMScaleSet] {
+func (s *azureClient) ListAzureVMScaleSets(ctx context.Context, subscriptionId string) <-chan AzureResult[azure.VMScaleSet] {
var (
- out = make(chan azureResult[azure.VMScaleSet])
+ out = make(chan AzureResult[azure.VMScaleSet])
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Compute/virtualMachineScaleSets", subscriptionId)
params = query.RMParams{ApiVersion: "2022-11-01"}
)
diff --git a/client/web_apps.go b/client/web_apps.go
index 20aa0c2..4ae12fc 100644
--- a/client/web_apps.go
+++ b/client/web_apps.go
@@ -26,8 +26,8 @@ import (
)
// ListAzureWebApps https://learn.microsoft.com/en-us/rest/api/appservice/web-apps/list?view=rest-appservice-2022-03-01
-func (s *azureClient) ListAzureWebApps(ctx context.Context, subscriptionId string) <-chan azureResult[azure.WebApp] {
- out := make(chan azureResult[azure.WebApp])
+func (s *azureClient) ListAzureWebApps(ctx context.Context, subscriptionId string) <-chan AzureResult[azure.WebApp] {
+ out := make(chan AzureResult[azure.WebApp])
var (
path = fmt.Sprintf("/subscriptions/%s/providers/Microsoft.Web/sites", subscriptionId)
params = query.RMParams{ApiVersion: "2022-03-01"}
From abb844525f37c4eeba916dbf2f2f24396624eb86 Mon Sep 17 00:00:00 2001
From: Mistah J <26472282+mistahj67@users.noreply.github.com>
Date: Tue, 27 Aug 2024 14:38:39 -0700
Subject: [PATCH 6/8] chore: fix tests
---
client/mocks/client.go | 15 ++++++++-------
cmd/list-app-owners_test.go | 13 +++++++------
cmd/list-apps_test.go | 9 +++++----
cmd/list-device-owners_test.go | 13 +++++++------
cmd/list-devices_test.go | 9 +++++----
cmd/list-group-members_test.go | 13 +++++++------
cmd/list-group-owners_test.go | 13 +++++++------
cmd/list-groups_test.go | 9 +++++----
cmd/list-key-vault-role-assignments_test.go | 13 +++++++------
cmd/list-key-vaults_test.go | 13 +++++++------
cmd/list-management-group-descendants_test.go | 13 +++++++------
...list-management-group-role-assignments_test.go | 13 +++++++------
cmd/list-management-groups_test.go | 9 +++++----
cmd/list-resource-group-role-assignments_test.go | 13 +++++++------
cmd/list-resource-groups_test.go | 13 +++++++------
cmd/list-roles_test.go | 9 +++++----
cmd/list-service-principal-owners_test.go | 13 +++++++------
cmd/list-service-principals_test.go | 9 +++++----
cmd/list-subscription-role-assignments_test.go | 13 +++++++------
cmd/list-subscriptions_test.go | 9 +++++----
cmd/list-tenants_test.go | 9 +++++----
cmd/list-users_test.go | 9 +++++----
cmd/list-virtual-machine-role-assignments_test.go | 13 +++++++------
cmd/list-virtual-machines_test.go | 13 +++++++------
24 files changed, 151 insertions(+), 127 deletions(-)
diff --git a/client/mocks/client.go b/client/mocks/client.go
index a621317..97dfeb3 100644
--- a/client/mocks/client.go
+++ b/client/mocks/client.go
@@ -5,13 +5,14 @@
package mocks
import (
- context "context"
- json "encoding/json"
- client "github.com/bloodhoundad/azurehound/v2/client"
- query "github.com/bloodhoundad/azurehound/v2/client/query"
- azure "github.com/bloodhoundad/azurehound/v2/models/azure"
- gomock "go.uber.org/mock/gomock"
- reflect "reflect"
+ "context"
+ "encoding/json"
+ "reflect"
+
+ "github.com/bloodhoundad/azurehound/v2/client"
+ "github.com/bloodhoundad/azurehound/v2/client/query"
+ "github.com/bloodhoundad/azurehound/v2/models/azure"
+ "go.uber.org/mock/gomock"
)
// MockAzureClient is a mock of AzureClient interface.
diff --git a/cmd/list-app-owners_test.go b/cmd/list-app-owners_test.go
index a5bb2e3..978b7a8 100644
--- a/cmd/list-app-owners_test.go
+++ b/cmd/list-app-owners_test.go
@@ -23,6 +23,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/enums"
"github.com/bloodhoundad/azurehound/v2/models"
@@ -42,8 +43,8 @@ func TestListAppOwners(t *testing.T) {
mockClient := mocks.NewMockAzureClient(ctrl)
mockAppsChannel := make(chan azureWrapper[models.App])
- mockAppOwnerChannel := make(chan azure.AppOwnerResult)
- mockAppOwnerChannel2 := make(chan azure.AppOwnerResult)
+ mockAppOwnerChannel := make(chan client.AzureResult[json.RawMessage])
+ mockAppOwnerChannel2 := make(chan client.AzureResult[json.RawMessage])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
@@ -59,19 +60,19 @@ func TestListAppOwners(t *testing.T) {
}()
go func() {
defer close(mockAppOwnerChannel)
- mockAppOwnerChannel <- azure.AppOwnerResult{
+ mockAppOwnerChannel <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
- mockAppOwnerChannel <- azure.AppOwnerResult{
+ mockAppOwnerChannel <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
}()
go func() {
defer close(mockAppOwnerChannel2)
- mockAppOwnerChannel2 <- azure.AppOwnerResult{
+ mockAppOwnerChannel2 <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
- mockAppOwnerChannel2 <- azure.AppOwnerResult{
+ mockAppOwnerChannel2 <- client.AzureResult[json.RawMessage]{
Error: mockError,
}
}()
diff --git a/cmd/list-apps_test.go b/cmd/list-apps_test.go
index 1a9b55a..136d8f0 100644
--- a/cmd/list-apps_test.go
+++ b/cmd/list-apps_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models/azure"
"go.uber.org/mock/gomock"
@@ -37,7 +38,7 @@ func TestListApps(t *testing.T) {
ctx := context.Background()
mockClient := mocks.NewMockAzureClient(ctrl)
- mockChannel := make(chan azure.ApplicationResult)
+ mockChannel := make(chan client.AzureResult[azure.Application])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
@@ -45,13 +46,13 @@ func TestListApps(t *testing.T) {
go func() {
defer close(mockChannel)
- mockChannel <- azure.ApplicationResult{
+ mockChannel <- client.AzureResult[azure.Application]{
Ok: azure.Application{},
}
- mockChannel <- azure.ApplicationResult{
+ mockChannel <- client.AzureResult[azure.Application]{
Error: mockError,
}
- mockChannel <- azure.ApplicationResult{
+ mockChannel <- client.AzureResult[azure.Application]{
Ok: azure.Application{},
}
}()
diff --git a/cmd/list-device-owners_test.go b/cmd/list-device-owners_test.go
index 5f0dc3e..87a2306 100644
--- a/cmd/list-device-owners_test.go
+++ b/cmd/list-device-owners_test.go
@@ -23,6 +23,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/models/azure"
@@ -41,8 +42,8 @@ func TestListDeviceOwners(t *testing.T) {
mockClient := mocks.NewMockAzureClient(ctrl)
mockDevicesChannel := make(chan interface{})
- mockDeviceOwnerChannel := make(chan azure.DeviceRegisteredOwnerResult)
- mockDeviceOwnerChannel2 := make(chan azure.DeviceRegisteredOwnerResult)
+ mockDeviceOwnerChannel := make(chan client.AzureResult[json.RawMessage])
+ mockDeviceOwnerChannel2 := make(chan client.AzureResult[json.RawMessage])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
@@ -62,19 +63,19 @@ func TestListDeviceOwners(t *testing.T) {
}()
go func() {
defer close(mockDeviceOwnerChannel)
- mockDeviceOwnerChannel <- azure.DeviceRegisteredOwnerResult{
+ mockDeviceOwnerChannel <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
- mockDeviceOwnerChannel <- azure.DeviceRegisteredOwnerResult{
+ mockDeviceOwnerChannel <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
}()
go func() {
defer close(mockDeviceOwnerChannel2)
- mockDeviceOwnerChannel2 <- azure.DeviceRegisteredOwnerResult{
+ mockDeviceOwnerChannel2 <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
- mockDeviceOwnerChannel2 <- azure.DeviceRegisteredOwnerResult{
+ mockDeviceOwnerChannel2 <- client.AzureResult[json.RawMessage]{
Error: mockError,
}
}()
diff --git a/cmd/list-devices_test.go b/cmd/list-devices_test.go
index 83fbf83..a2a19ed 100644
--- a/cmd/list-devices_test.go
+++ b/cmd/list-devices_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models/azure"
"go.uber.org/mock/gomock"
@@ -37,7 +38,7 @@ func TestListDevices(t *testing.T) {
ctx := context.Background()
mockClient := mocks.NewMockAzureClient(ctrl)
- mockChannel := make(chan azure.DeviceResult)
+ mockChannel := make(chan client.AzureResult[azure.Device])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
@@ -45,13 +46,13 @@ func TestListDevices(t *testing.T) {
go func() {
defer close(mockChannel)
- mockChannel <- azure.DeviceResult{
+ mockChannel <- client.AzureResult[azure.Device]{
Ok: azure.Device{},
}
- mockChannel <- azure.DeviceResult{
+ mockChannel <- client.AzureResult[azure.Device]{
Error: mockError,
}
- mockChannel <- azure.DeviceResult{
+ mockChannel <- client.AzureResult[azure.Device]{
Ok: azure.Device{},
}
}()
diff --git a/cmd/list-group-members_test.go b/cmd/list-group-members_test.go
index 0f3bff3..495d28f 100644
--- a/cmd/list-group-members_test.go
+++ b/cmd/list-group-members_test.go
@@ -23,6 +23,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/models/azure"
@@ -41,8 +42,8 @@ func TestListGroupMembers(t *testing.T) {
mockClient := mocks.NewMockAzureClient(ctrl)
mockGroupsChannel := make(chan interface{})
- mockGroupMemberChannel := make(chan azure.MemberObjectResult)
- mockGroupMemberChannel2 := make(chan azure.MemberObjectResult)
+ mockGroupMemberChannel := make(chan client.AzureResult[json.RawMessage])
+ mockGroupMemberChannel2 := make(chan client.AzureResult[json.RawMessage])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
@@ -62,19 +63,19 @@ func TestListGroupMembers(t *testing.T) {
}()
go func() {
defer close(mockGroupMemberChannel)
- mockGroupMemberChannel <- azure.MemberObjectResult{
+ mockGroupMemberChannel <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
- mockGroupMemberChannel <- azure.MemberObjectResult{
+ mockGroupMemberChannel <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
}()
go func() {
defer close(mockGroupMemberChannel2)
- mockGroupMemberChannel2 <- azure.MemberObjectResult{
+ mockGroupMemberChannel2 <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
- mockGroupMemberChannel2 <- azure.MemberObjectResult{
+ mockGroupMemberChannel2 <- client.AzureResult[json.RawMessage]{
Error: mockError,
}
}()
diff --git a/cmd/list-group-owners_test.go b/cmd/list-group-owners_test.go
index ae85f4e..57e8536 100644
--- a/cmd/list-group-owners_test.go
+++ b/cmd/list-group-owners_test.go
@@ -23,6 +23,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/models/azure"
@@ -41,8 +42,8 @@ func TestListGroupOwners(t *testing.T) {
mockClient := mocks.NewMockAzureClient(ctrl)
mockGroupsChannel := make(chan interface{})
- mockGroupOwnerChannel := make(chan azure.GroupOwnerResult)
- mockGroupOwnerChannel2 := make(chan azure.GroupOwnerResult)
+ mockGroupOwnerChannel := make(chan client.AzureResult[json.RawMessage])
+ mockGroupOwnerChannel2 := make(chan client.AzureResult[json.RawMessage])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
@@ -62,19 +63,19 @@ func TestListGroupOwners(t *testing.T) {
}()
go func() {
defer close(mockGroupOwnerChannel)
- mockGroupOwnerChannel <- azure.GroupOwnerResult{
+ mockGroupOwnerChannel <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
- mockGroupOwnerChannel <- azure.GroupOwnerResult{
+ mockGroupOwnerChannel <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
}()
go func() {
defer close(mockGroupOwnerChannel2)
- mockGroupOwnerChannel2 <- azure.GroupOwnerResult{
+ mockGroupOwnerChannel2 <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
- mockGroupOwnerChannel2 <- azure.GroupOwnerResult{
+ mockGroupOwnerChannel2 <- client.AzureResult[json.RawMessage]{
Error: mockError,
}
}()
diff --git a/cmd/list-groups_test.go b/cmd/list-groups_test.go
index fa1303f..175a74e 100644
--- a/cmd/list-groups_test.go
+++ b/cmd/list-groups_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models/azure"
"go.uber.org/mock/gomock"
@@ -38,7 +39,7 @@ func TestListGroups(t *testing.T) {
ctx := context.Background()
mockClient := mocks.NewMockAzureClient(ctrl)
- mockChannel := make(chan azure.GroupResult)
+ mockChannel := make(chan client.AzureResult[azure.Group])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
@@ -46,13 +47,13 @@ func TestListGroups(t *testing.T) {
go func() {
defer close(mockChannel)
- mockChannel <- azure.GroupResult{
+ mockChannel <- client.AzureResult[azure.Group]{
Ok: azure.Group{},
}
- mockChannel <- azure.GroupResult{
+ mockChannel <- client.AzureResult[azure.Group]{
Error: mockError,
}
- mockChannel <- azure.GroupResult{
+ mockChannel <- client.AzureResult[azure.Group]{
Ok: azure.Group{},
}
}()
diff --git a/cmd/list-key-vault-role-assignments_test.go b/cmd/list-key-vault-role-assignments_test.go
index 672d032..d94018e 100644
--- a/cmd/list-key-vault-role-assignments_test.go
+++ b/cmd/list-key-vault-role-assignments_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/constants"
"github.com/bloodhoundad/azurehound/v2/models"
@@ -41,8 +42,8 @@ func TestListKeyVaultRoleAssignments(t *testing.T) {
mockClient := mocks.NewMockAzureClient(ctrl)
mockKeyVaultsChannel := make(chan interface{})
- mockKeyVaultRoleAssignmentChannel := make(chan azure.RoleAssignmentResult)
- mockKeyVaultRoleAssignmentChannel2 := make(chan azure.RoleAssignmentResult)
+ mockKeyVaultRoleAssignmentChannel := make(chan client.AzureResult[azure.RoleAssignment])
+ mockKeyVaultRoleAssignmentChannel2 := make(chan client.AzureResult[azure.RoleAssignment])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
@@ -62,14 +63,14 @@ func TestListKeyVaultRoleAssignments(t *testing.T) {
}()
go func() {
defer close(mockKeyVaultRoleAssignmentChannel)
- mockKeyVaultRoleAssignmentChannel <- azure.RoleAssignmentResult{
+ mockKeyVaultRoleAssignmentChannel <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.KeyVaultContributorRoleID,
},
},
}
- mockKeyVaultRoleAssignmentChannel <- azure.RoleAssignmentResult{
+ mockKeyVaultRoleAssignmentChannel <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.ContributorRoleID,
@@ -79,14 +80,14 @@ func TestListKeyVaultRoleAssignments(t *testing.T) {
}()
go func() {
defer close(mockKeyVaultRoleAssignmentChannel2)
- mockKeyVaultRoleAssignmentChannel2 <- azure.RoleAssignmentResult{
+ mockKeyVaultRoleAssignmentChannel2 <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.KeyVaultAdministratorRoleID,
},
},
}
- mockKeyVaultRoleAssignmentChannel2 <- azure.RoleAssignmentResult{
+ mockKeyVaultRoleAssignmentChannel2 <- client.AzureResult[azure.RoleAssignment]{
Error: mockError,
}
}()
diff --git a/cmd/list-key-vaults_test.go b/cmd/list-key-vaults_test.go
index 269288a..9629d02 100644
--- a/cmd/list-key-vaults_test.go
+++ b/cmd/list-key-vaults_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/models/azure"
@@ -40,8 +41,8 @@ func TestListKeyVaults(t *testing.T) {
mockClient := mocks.NewMockAzureClient(ctrl)
mockSubscriptionsChannel := make(chan interface{})
- mockKeyVaultChannel := make(chan azure.KeyVaultResult)
- mockKeyVaultChannel2 := make(chan azure.KeyVaultResult)
+ mockKeyVaultChannel := make(chan client.AzureResult[azure.KeyVault])
+ mockKeyVaultChannel2 := make(chan client.AzureResult[azure.KeyVault])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
@@ -61,19 +62,19 @@ func TestListKeyVaults(t *testing.T) {
}()
go func() {
defer close(mockKeyVaultChannel)
- mockKeyVaultChannel <- azure.KeyVaultResult{
+ mockKeyVaultChannel <- client.AzureResult[azure.KeyVault]{
Ok: azure.KeyVault{},
}
- mockKeyVaultChannel <- azure.KeyVaultResult{
+ mockKeyVaultChannel <- client.AzureResult[azure.KeyVault]{
Ok: azure.KeyVault{},
}
}()
go func() {
defer close(mockKeyVaultChannel2)
- mockKeyVaultChannel2 <- azure.KeyVaultResult{
+ mockKeyVaultChannel2 <- client.AzureResult[azure.KeyVault]{
Ok: azure.KeyVault{},
}
- mockKeyVaultChannel2 <- azure.KeyVaultResult{
+ mockKeyVaultChannel2 <- client.AzureResult[azure.KeyVault]{
Error: mockError,
}
}()
diff --git a/cmd/list-management-group-descendants_test.go b/cmd/list-management-group-descendants_test.go
index ad5bf4c..3b3e53a 100644
--- a/cmd/list-management-group-descendants_test.go
+++ b/cmd/list-management-group-descendants_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/models/azure"
@@ -40,8 +41,8 @@ func TestListManagementGroupDescendants(t *testing.T) {
mockClient := mocks.NewMockAzureClient(ctrl)
mockManagementGroupsChannel := make(chan interface{})
- mockManagementGroupDescendantChannel := make(chan azure.DescendantInfoResult)
- mockManagementGroupDescendantChannel2 := make(chan azure.DescendantInfoResult)
+ mockManagementGroupDescendantChannel := make(chan client.AzureResult[azure.DescendantInfo])
+ mockManagementGroupDescendantChannel2 := make(chan client.AzureResult[azure.DescendantInfo])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
@@ -61,13 +62,13 @@ func TestListManagementGroupDescendants(t *testing.T) {
}()
go func() {
defer close(mockManagementGroupDescendantChannel)
- mockManagementGroupDescendantChannel <- azure.DescendantInfoResult{}
- mockManagementGroupDescendantChannel <- azure.DescendantInfoResult{}
+ mockManagementGroupDescendantChannel <- client.AzureResult[azure.DescendantInfo]{}
+ mockManagementGroupDescendantChannel <- client.AzureResult[azure.DescendantInfo]{}
}()
go func() {
defer close(mockManagementGroupDescendantChannel2)
- mockManagementGroupDescendantChannel2 <- azure.DescendantInfoResult{}
- mockManagementGroupDescendantChannel2 <- azure.DescendantInfoResult{
+ mockManagementGroupDescendantChannel2 <- client.AzureResult[azure.DescendantInfo]{}
+ mockManagementGroupDescendantChannel2 <- client.AzureResult[azure.DescendantInfo]{
Error: mockError,
}
}()
diff --git a/cmd/list-management-group-role-assignments_test.go b/cmd/list-management-group-role-assignments_test.go
index 321a1d4..7f21669 100644
--- a/cmd/list-management-group-role-assignments_test.go
+++ b/cmd/list-management-group-role-assignments_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/constants"
"github.com/bloodhoundad/azurehound/v2/models"
@@ -41,8 +42,8 @@ func TestListResourceGroupRoleAssignments(t *testing.T) {
mockClient := mocks.NewMockAzureClient(ctrl)
mockResourceGroupsChannel := make(chan interface{})
- mockResourceGroupRoleAssignmentChannel := make(chan azure.RoleAssignmentResult)
- mockResourceGroupRoleAssignmentChannel2 := make(chan azure.RoleAssignmentResult)
+ mockResourceGroupRoleAssignmentChannel := make(chan client.AzureResult[azure.RoleAssignment])
+ mockResourceGroupRoleAssignmentChannel2 := make(chan client.AzureResult[azure.RoleAssignment])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
@@ -62,14 +63,14 @@ func TestListResourceGroupRoleAssignments(t *testing.T) {
}()
go func() {
defer close(mockResourceGroupRoleAssignmentChannel)
- mockResourceGroupRoleAssignmentChannel <- azure.RoleAssignmentResult{
+ mockResourceGroupRoleAssignmentChannel <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.ContributorRoleID,
},
},
}
- mockResourceGroupRoleAssignmentChannel <- azure.RoleAssignmentResult{
+ mockResourceGroupRoleAssignmentChannel <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.OwnerRoleID,
@@ -79,14 +80,14 @@ func TestListResourceGroupRoleAssignments(t *testing.T) {
}()
go func() {
defer close(mockResourceGroupRoleAssignmentChannel2)
- mockResourceGroupRoleAssignmentChannel2 <- azure.RoleAssignmentResult{
+ mockResourceGroupRoleAssignmentChannel2 <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.OwnerRoleID,
},
},
}
- mockResourceGroupRoleAssignmentChannel2 <- azure.RoleAssignmentResult{
+ mockResourceGroupRoleAssignmentChannel2 <- client.AzureResult[azure.RoleAssignment]{
Error: mockError,
}
}()
diff --git a/cmd/list-management-groups_test.go b/cmd/list-management-groups_test.go
index 2a676db..72f980c 100644
--- a/cmd/list-management-groups_test.go
+++ b/cmd/list-management-groups_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models/azure"
"go.uber.org/mock/gomock"
@@ -37,7 +38,7 @@ func TestListManagementGroups(t *testing.T) {
ctx := context.Background()
mockClient := mocks.NewMockAzureClient(ctrl)
- mockChannel := make(chan azure.ManagementGroupResult)
+ mockChannel := make(chan client.AzureResult[azure.ManagementGroup])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
@@ -45,13 +46,13 @@ func TestListManagementGroups(t *testing.T) {
go func() {
defer close(mockChannel)
- mockChannel <- azure.ManagementGroupResult{
+ mockChannel <- client.AzureResult[azure.ManagementGroup]{
Ok: azure.ManagementGroup{},
}
- mockChannel <- azure.ManagementGroupResult{
+ mockChannel <- client.AzureResult[azure.ManagementGroup]{
Error: mockError,
}
- mockChannel <- azure.ManagementGroupResult{
+ mockChannel <- client.AzureResult[azure.ManagementGroup]{
Ok: azure.ManagementGroup{},
}
}()
diff --git a/cmd/list-resource-group-role-assignments_test.go b/cmd/list-resource-group-role-assignments_test.go
index 63b8c8e..8b1ac8d 100644
--- a/cmd/list-resource-group-role-assignments_test.go
+++ b/cmd/list-resource-group-role-assignments_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/constants"
"github.com/bloodhoundad/azurehound/v2/models"
@@ -41,8 +42,8 @@ func TestListManagementGroupRoleAssignments(t *testing.T) {
mockClient := mocks.NewMockAzureClient(ctrl)
mockManagementGroupsChannel := make(chan interface{})
- mockManagementGroupRoleAssignmentChannel := make(chan azure.RoleAssignmentResult)
- mockManagementGroupRoleAssignmentChannel2 := make(chan azure.RoleAssignmentResult)
+ mockManagementGroupRoleAssignmentChannel := make(chan client.AzureResult[azure.RoleAssignment])
+ mockManagementGroupRoleAssignmentChannel2 := make(chan client.AzureResult[azure.RoleAssignment])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
@@ -62,14 +63,14 @@ func TestListManagementGroupRoleAssignments(t *testing.T) {
}()
go func() {
defer close(mockManagementGroupRoleAssignmentChannel)
- mockManagementGroupRoleAssignmentChannel <- azure.RoleAssignmentResult{
+ mockManagementGroupRoleAssignmentChannel <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.ContributorRoleID,
},
},
}
- mockManagementGroupRoleAssignmentChannel <- azure.RoleAssignmentResult{
+ mockManagementGroupRoleAssignmentChannel <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.OwnerRoleID,
@@ -79,14 +80,14 @@ func TestListManagementGroupRoleAssignments(t *testing.T) {
}()
go func() {
defer close(mockManagementGroupRoleAssignmentChannel2)
- mockManagementGroupRoleAssignmentChannel2 <- azure.RoleAssignmentResult{
+ mockManagementGroupRoleAssignmentChannel2 <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.OwnerRoleID,
},
},
}
- mockManagementGroupRoleAssignmentChannel2 <- azure.RoleAssignmentResult{
+ mockManagementGroupRoleAssignmentChannel2 <- client.AzureResult[azure.RoleAssignment]{
Error: mockError,
}
}()
diff --git a/cmd/list-resource-groups_test.go b/cmd/list-resource-groups_test.go
index 78ac328..19009a6 100644
--- a/cmd/list-resource-groups_test.go
+++ b/cmd/list-resource-groups_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/models/azure"
@@ -40,8 +41,8 @@ func TestListResourceGroups(t *testing.T) {
mockClient := mocks.NewMockAzureClient(ctrl)
mockSubscriptionsChannel := make(chan interface{})
- mockResourceGroupChannel := make(chan azure.ResourceGroupResult)
- mockResourceGroupChannel2 := make(chan azure.ResourceGroupResult)
+ mockResourceGroupChannel := make(chan client.AzureResult[azure.ResourceGroup])
+ mockResourceGroupChannel2 := make(chan client.AzureResult[azure.ResourceGroup])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
@@ -61,19 +62,19 @@ func TestListResourceGroups(t *testing.T) {
}()
go func() {
defer close(mockResourceGroupChannel)
- mockResourceGroupChannel <- azure.ResourceGroupResult{
+ mockResourceGroupChannel <- client.AzureResult[azure.ResourceGroup]{
Ok: azure.ResourceGroup{},
}
- mockResourceGroupChannel <- azure.ResourceGroupResult{
+ mockResourceGroupChannel <- client.AzureResult[azure.ResourceGroup]{
Ok: azure.ResourceGroup{},
}
}()
go func() {
defer close(mockResourceGroupChannel2)
- mockResourceGroupChannel2 <- azure.ResourceGroupResult{
+ mockResourceGroupChannel2 <- client.AzureResult[azure.ResourceGroup]{
Ok: azure.ResourceGroup{},
}
- mockResourceGroupChannel2 <- azure.ResourceGroupResult{
+ mockResourceGroupChannel2 <- client.AzureResult[azure.ResourceGroup]{
Error: mockError,
}
}()
diff --git a/cmd/list-roles_test.go b/cmd/list-roles_test.go
index e049128..09cdcb5 100644
--- a/cmd/list-roles_test.go
+++ b/cmd/list-roles_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models/azure"
"go.uber.org/mock/gomock"
@@ -37,7 +38,7 @@ func TestListRoles(t *testing.T) {
ctx := context.Background()
mockClient := mocks.NewMockAzureClient(ctrl)
- mockChannel := make(chan azure.RoleResult)
+ mockChannel := make(chan client.AzureResult[azure.Role])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
@@ -45,13 +46,13 @@ func TestListRoles(t *testing.T) {
go func() {
defer close(mockChannel)
- mockChannel <- azure.RoleResult{
+ mockChannel <- client.AzureResult[azure.Role]{
Ok: azure.Role{},
}
- mockChannel <- azure.RoleResult{
+ mockChannel <- client.AzureResult[azure.Role]{
Error: mockError,
}
- mockChannel <- azure.RoleResult{
+ mockChannel <- client.AzureResult[azure.Role]{
Ok: azure.Role{},
}
}()
diff --git a/cmd/list-service-principal-owners_test.go b/cmd/list-service-principal-owners_test.go
index 7bf1811..61f6eb5 100644
--- a/cmd/list-service-principal-owners_test.go
+++ b/cmd/list-service-principal-owners_test.go
@@ -23,6 +23,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/models/azure"
@@ -41,8 +42,8 @@ func TestListServicePrincipalOwners(t *testing.T) {
mockClient := mocks.NewMockAzureClient(ctrl)
mockServicePrincipalsChannel := make(chan interface{})
- mockServicePrincipalOwnerChannel := make(chan azure.ServicePrincipalOwnerResult)
- mockServicePrincipalOwnerChannel2 := make(chan azure.ServicePrincipalOwnerResult)
+ mockServicePrincipalOwnerChannel := make(chan client.AzureResult[json.RawMessage])
+ mockServicePrincipalOwnerChannel2 := make(chan client.AzureResult[json.RawMessage])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
@@ -62,19 +63,19 @@ func TestListServicePrincipalOwners(t *testing.T) {
}()
go func() {
defer close(mockServicePrincipalOwnerChannel)
- mockServicePrincipalOwnerChannel <- azure.ServicePrincipalOwnerResult{
+ mockServicePrincipalOwnerChannel <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
- mockServicePrincipalOwnerChannel <- azure.ServicePrincipalOwnerResult{
+ mockServicePrincipalOwnerChannel <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
}()
go func() {
defer close(mockServicePrincipalOwnerChannel2)
- mockServicePrincipalOwnerChannel2 <- azure.ServicePrincipalOwnerResult{
+ mockServicePrincipalOwnerChannel2 <- client.AzureResult[json.RawMessage]{
Ok: json.RawMessage{},
}
- mockServicePrincipalOwnerChannel2 <- azure.ServicePrincipalOwnerResult{
+ mockServicePrincipalOwnerChannel2 <- client.AzureResult[json.RawMessage]{
Error: mockError,
}
}()
diff --git a/cmd/list-service-principals_test.go b/cmd/list-service-principals_test.go
index cb64655..b9058fa 100644
--- a/cmd/list-service-principals_test.go
+++ b/cmd/list-service-principals_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models/azure"
"go.uber.org/mock/gomock"
@@ -37,7 +38,7 @@ func TestListServicePrincipals(t *testing.T) {
ctx := context.Background()
mockClient := mocks.NewMockAzureClient(ctrl)
- mockChannel := make(chan azure.ServicePrincipalResult)
+ mockChannel := make(chan client.AzureResult[azure.ServicePrincipal])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
@@ -45,13 +46,13 @@ func TestListServicePrincipals(t *testing.T) {
go func() {
defer close(mockChannel)
- mockChannel <- azure.ServicePrincipalResult{
+ mockChannel <- client.AzureResult[azure.ServicePrincipal]{
Ok: azure.ServicePrincipal{},
}
- mockChannel <- azure.ServicePrincipalResult{
+ mockChannel <- client.AzureResult[azure.ServicePrincipal]{
Error: mockError,
}
- mockChannel <- azure.ServicePrincipalResult{
+ mockChannel <- client.AzureResult[azure.ServicePrincipal]{
Ok: azure.ServicePrincipal{},
}
}()
diff --git a/cmd/list-subscription-role-assignments_test.go b/cmd/list-subscription-role-assignments_test.go
index 308044e..73a74d8 100644
--- a/cmd/list-subscription-role-assignments_test.go
+++ b/cmd/list-subscription-role-assignments_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/constants"
"github.com/bloodhoundad/azurehound/v2/models"
@@ -41,8 +42,8 @@ func TestListSubscriptionRoleAssignments(t *testing.T) {
mockClient := mocks.NewMockAzureClient(ctrl)
mockSubscriptionsChannel := make(chan interface{})
- mockSubscriptionRoleAssignmentChannel := make(chan azure.RoleAssignmentResult)
- mockSubscriptionRoleAssignmentChannel2 := make(chan azure.RoleAssignmentResult)
+ mockSubscriptionRoleAssignmentChannel := make(chan client.AzureResult[azure.RoleAssignment])
+ mockSubscriptionRoleAssignmentChannel2 := make(chan client.AzureResult[azure.RoleAssignment])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
@@ -62,14 +63,14 @@ func TestListSubscriptionRoleAssignments(t *testing.T) {
}()
go func() {
defer close(mockSubscriptionRoleAssignmentChannel)
- mockSubscriptionRoleAssignmentChannel <- azure.RoleAssignmentResult{
+ mockSubscriptionRoleAssignmentChannel <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.ContributorRoleID,
},
},
}
- mockSubscriptionRoleAssignmentChannel <- azure.RoleAssignmentResult{
+ mockSubscriptionRoleAssignmentChannel <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.OwnerRoleID,
@@ -79,14 +80,14 @@ func TestListSubscriptionRoleAssignments(t *testing.T) {
}()
go func() {
defer close(mockSubscriptionRoleAssignmentChannel2)
- mockSubscriptionRoleAssignmentChannel2 <- azure.RoleAssignmentResult{
+ mockSubscriptionRoleAssignmentChannel2 <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.OwnerRoleID,
},
},
}
- mockSubscriptionRoleAssignmentChannel2 <- azure.RoleAssignmentResult{
+ mockSubscriptionRoleAssignmentChannel2 <- client.AzureResult[azure.RoleAssignment]{
Error: mockError,
}
}()
diff --git a/cmd/list-subscriptions_test.go b/cmd/list-subscriptions_test.go
index 51571c5..3e9f8be 100644
--- a/cmd/list-subscriptions_test.go
+++ b/cmd/list-subscriptions_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models/azure"
"go.uber.org/mock/gomock"
@@ -37,7 +38,7 @@ func TestListSubscriptions(t *testing.T) {
ctx := context.Background()
mockClient := mocks.NewMockAzureClient(ctrl)
- mockChannel := make(chan azure.SubscriptionResult)
+ mockChannel := make(chan client.AzureResult[azure.Subscription])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
@@ -45,13 +46,13 @@ func TestListSubscriptions(t *testing.T) {
go func() {
defer close(mockChannel)
- mockChannel <- azure.SubscriptionResult{
+ mockChannel <- client.AzureResult[azure.Subscription]{
Ok: azure.Subscription{},
}
- mockChannel <- azure.SubscriptionResult{
+ mockChannel <- client.AzureResult[azure.Subscription]{
Error: mockError,
}
- mockChannel <- azure.SubscriptionResult{
+ mockChannel <- client.AzureResult[azure.Subscription]{
Ok: azure.Subscription{},
}
}()
diff --git a/cmd/list-tenants_test.go b/cmd/list-tenants_test.go
index 5f22399..c0648e3 100644
--- a/cmd/list-tenants_test.go
+++ b/cmd/list-tenants_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models/azure"
"go.uber.org/mock/gomock"
@@ -37,7 +38,7 @@ func TestListTenants(t *testing.T) {
ctx := context.Background()
mockClient := mocks.NewMockAzureClient(ctrl)
- mockChannel := make(chan azure.TenantResult)
+ mockChannel := make(chan client.AzureResult[azure.Tenant])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
@@ -45,13 +46,13 @@ func TestListTenants(t *testing.T) {
go func() {
defer close(mockChannel)
- mockChannel <- azure.TenantResult{
+ mockChannel <- client.AzureResult[azure.Tenant]{
Ok: azure.Tenant{},
}
- mockChannel <- azure.TenantResult{
+ mockChannel <- client.AzureResult[azure.Tenant]{
Error: mockError,
}
- mockChannel <- azure.TenantResult{
+ mockChannel <- client.AzureResult[azure.Tenant]{
Ok: azure.Tenant{},
}
}()
diff --git a/cmd/list-users_test.go b/cmd/list-users_test.go
index 3a1deb6..59028e0 100644
--- a/cmd/list-users_test.go
+++ b/cmd/list-users_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models/azure"
"go.uber.org/mock/gomock"
@@ -38,7 +39,7 @@ func TestListUsers(t *testing.T) {
ctx := context.Background()
mockClient := mocks.NewMockAzureClient(ctrl)
- mockChannel := make(chan azure.UserResult)
+ mockChannel := make(chan client.AzureResult[azure.User])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
mockClient.EXPECT().TenantInfo().Return(mockTenant).AnyTimes()
@@ -46,13 +47,13 @@ func TestListUsers(t *testing.T) {
go func() {
defer close(mockChannel)
- mockChannel <- azure.UserResult{
+ mockChannel <- client.AzureResult[azure.User]{
Ok: azure.User{},
}
- mockChannel <- azure.UserResult{
+ mockChannel <- client.AzureResult[azure.User]{
Error: mockError,
}
- mockChannel <- azure.UserResult{
+ mockChannel <- client.AzureResult[azure.User]{
Ok: azure.User{},
}
}()
diff --git a/cmd/list-virtual-machine-role-assignments_test.go b/cmd/list-virtual-machine-role-assignments_test.go
index 110eea4..efd5112 100644
--- a/cmd/list-virtual-machine-role-assignments_test.go
+++ b/cmd/list-virtual-machine-role-assignments_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/constants"
"github.com/bloodhoundad/azurehound/v2/models"
@@ -41,8 +42,8 @@ func TestListVirtualMachineRoleAssignments(t *testing.T) {
mockClient := mocks.NewMockAzureClient(ctrl)
mockVirtualMachinesChannel := make(chan interface{})
- mockVirtualMachineRoleAssignmentChannel := make(chan azure.RoleAssignmentResult)
- mockVirtualMachineRoleAssignmentChannel2 := make(chan azure.RoleAssignmentResult)
+ mockVirtualMachineRoleAssignmentChannel := make(chan client.AzureResult[azure.RoleAssignment])
+ mockVirtualMachineRoleAssignmentChannel2 := make(chan client.AzureResult[azure.RoleAssignment])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
@@ -62,14 +63,14 @@ func TestListVirtualMachineRoleAssignments(t *testing.T) {
}()
go func() {
defer close(mockVirtualMachineRoleAssignmentChannel)
- mockVirtualMachineRoleAssignmentChannel <- azure.RoleAssignmentResult{
+ mockVirtualMachineRoleAssignmentChannel <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.VirtualMachineContributorRoleID,
},
},
}
- mockVirtualMachineRoleAssignmentChannel <- azure.RoleAssignmentResult{
+ mockVirtualMachineRoleAssignmentChannel <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.AvereContributorRoleID,
@@ -79,14 +80,14 @@ func TestListVirtualMachineRoleAssignments(t *testing.T) {
}()
go func() {
defer close(mockVirtualMachineRoleAssignmentChannel2)
- mockVirtualMachineRoleAssignmentChannel2 <- azure.RoleAssignmentResult{
+ mockVirtualMachineRoleAssignmentChannel2 <- client.AzureResult[azure.RoleAssignment]{
Ok: azure.RoleAssignment{
Properties: azure.RoleAssignmentPropertiesWithScope{
RoleDefinitionId: constants.VirtualMachineAdministratorLoginRoleID,
},
},
}
- mockVirtualMachineRoleAssignmentChannel2 <- azure.RoleAssignmentResult{
+ mockVirtualMachineRoleAssignmentChannel2 <- client.AzureResult[azure.RoleAssignment]{
Error: mockError,
}
}()
diff --git a/cmd/list-virtual-machines_test.go b/cmd/list-virtual-machines_test.go
index 58b9113..b955d84 100644
--- a/cmd/list-virtual-machines_test.go
+++ b/cmd/list-virtual-machines_test.go
@@ -22,6 +22,7 @@ import (
"fmt"
"testing"
+ "github.com/bloodhoundad/azurehound/v2/client"
"github.com/bloodhoundad/azurehound/v2/client/mocks"
"github.com/bloodhoundad/azurehound/v2/models"
"github.com/bloodhoundad/azurehound/v2/models/azure"
@@ -40,8 +41,8 @@ func TestListVirtualMachines(t *testing.T) {
mockClient := mocks.NewMockAzureClient(ctrl)
mockSubscriptionsChannel := make(chan interface{})
- mockVirtualMachineChannel := make(chan azure.VirtualMachineResult)
- mockVirtualMachineChannel2 := make(chan azure.VirtualMachineResult)
+ mockVirtualMachineChannel := make(chan client.AzureResult[azure.VirtualMachine])
+ mockVirtualMachineChannel2 := make(chan client.AzureResult[azure.VirtualMachine])
mockTenant := azure.Tenant{}
mockError := fmt.Errorf("I'm an error")
@@ -61,19 +62,19 @@ func TestListVirtualMachines(t *testing.T) {
}()
go func() {
defer close(mockVirtualMachineChannel)
- mockVirtualMachineChannel <- azure.VirtualMachineResult{
+ mockVirtualMachineChannel <- client.AzureResult[azure.VirtualMachine]{
Ok: azure.VirtualMachine{},
}
- mockVirtualMachineChannel <- azure.VirtualMachineResult{
+ mockVirtualMachineChannel <- client.AzureResult[azure.VirtualMachine]{
Ok: azure.VirtualMachine{},
}
}()
go func() {
defer close(mockVirtualMachineChannel2)
- mockVirtualMachineChannel2 <- azure.VirtualMachineResult{
+ mockVirtualMachineChannel2 <- client.AzureResult[azure.VirtualMachine]{
Ok: azure.VirtualMachine{},
}
- mockVirtualMachineChannel2 <- azure.VirtualMachineResult{
+ mockVirtualMachineChannel2 <- client.AzureResult[azure.VirtualMachine]{
Error: mockError,
}
}()
From e27373ea6a8530530ebbfa01f8b5e472ec975add Mon Sep 17 00:00:00 2001
From: Mistah J <26472282+mistahj67@users.noreply.github.com>
Date: Tue, 27 Aug 2024 16:54:40 -0700
Subject: [PATCH 7/8] chore: fix go.sum
---
go.sum | 1 +
1 file changed, 1 insertion(+)
diff --git a/go.sum b/go.sum
index 04b5d27..caf00fb 100644
--- a/go.sum
+++ b/go.sum
@@ -813,6 +813,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
From 5e157cfa0d25f431e0c004eb7cba71b955cf97d9 Mon Sep 17 00:00:00 2001
From: Mistah J <26472282+mistahj67@users.noreply.github.com>
Date: Wed, 28 Aug 2024 11:32:11 -0700
Subject: [PATCH 8/8] fix: missing nil checks
---
client/client.go | 17 +++++------------
client/rest/client.go | 38 +++++++++++++++++++++++++++++---------
2 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/client/client.go b/client/client.go
index 12c0b0d..80e6401 100644
--- a/client/client.go
+++ b/client/client.go
@@ -124,7 +124,11 @@ func getAzureObjectList[T any](client rest.RestClient, ctx context.Context, path
_ = pipeline.Send(ctx.Done(), out, errResult)
return
} else {
- if req, err := rest.NewRequest(ctx, "GET", nextUrl, nil, params.AsMap(), nil); err != nil {
+ paramsMap := make(map[string]string)
+ if params != nil {
+ paramsMap = params.AsMap()
+ }
+ if req, err := rest.NewRequest(ctx, "GET", nextUrl, nil, paramsMap, nil); err != nil {
errResult.Error = err
_ = pipeline.Send(ctx.Done(), out, errResult)
return
@@ -164,17 +168,6 @@ func getAzureObjectList[T any](client rest.RestClient, ctx context.Context, path
}
}
-func getAzureObject[T any](client rest.RestClient, ctx context.Context, path string, params query.Params) (T, error) {
- var response T
- if res, err := client.Get(ctx, path, params, nil); err != nil {
- return response, err
- } else if err := rest.Decode(res.Body, &response); err != nil {
- return response, err
- } else {
- return response, nil
- }
-}
-
type azureClient struct {
msgraph rest.RestClient
resourceManager rest.RestClient
diff --git a/client/rest/client.go b/client/rest/client.go
index 33b96ff..a403190 100644
--- a/client/rest/client.go
+++ b/client/rest/client.go
@@ -157,7 +157,11 @@ func (s *restClient) Authenticate() error {
func (s *restClient) Delete(ctx context.Context, path string, body interface{}, params query.Params, headers map[string]string) (*http.Response, error) {
endpoint := s.api.ResolveReference(&url.URL{Path: path})
- if req, err := NewRequest(ctx, http.MethodDelete, endpoint, body, params.AsMap(), headers); err != nil {
+ paramsMap := make(map[string]string)
+ if params != nil {
+ paramsMap = params.AsMap()
+ }
+ if req, err := NewRequest(ctx, http.MethodDelete, endpoint, body, paramsMap, headers); err != nil {
return nil, err
} else {
return s.Send(req)
@@ -166,15 +170,19 @@ func (s *restClient) Delete(ctx context.Context, path string, body interface{},
func (s *restClient) Get(ctx context.Context, path string, params query.Params, headers map[string]string) (*http.Response, error) {
endpoint := s.api.ResolveReference(&url.URL{Path: path})
+ paramsMap := make(map[string]string)
- if params.NeedsEventualConsistencyHeaderFlag() {
- if headers == nil {
- headers = make(map[string]string)
+ if params != nil {
+ paramsMap = params.AsMap()
+ if params.NeedsEventualConsistencyHeaderFlag() {
+ if headers == nil {
+ headers = make(map[string]string)
+ }
+ headers["ConsistencyLevel"] = "eventual"
}
- headers["ConsistencyLevel"] = "eventual"
}
- if req, err := NewRequest(ctx, http.MethodGet, endpoint, nil, params.AsMap(), headers); err != nil {
+ if req, err := NewRequest(ctx, http.MethodGet, endpoint, nil, paramsMap, headers); err != nil {
return nil, err
} else {
return s.Send(req)
@@ -183,7 +191,11 @@ func (s *restClient) Get(ctx context.Context, path string, params query.Params,
func (s *restClient) Patch(ctx context.Context, path string, body interface{}, params query.Params, headers map[string]string) (*http.Response, error) {
endpoint := s.api.ResolveReference(&url.URL{Path: path})
- if req, err := NewRequest(ctx, http.MethodPatch, endpoint, body, params.AsMap(), headers); err != nil {
+ paramsMap := make(map[string]string)
+ if params != nil {
+ paramsMap = params.AsMap()
+ }
+ if req, err := NewRequest(ctx, http.MethodPatch, endpoint, body, paramsMap, headers); err != nil {
return nil, err
} else {
return s.Send(req)
@@ -192,7 +204,11 @@ func (s *restClient) Patch(ctx context.Context, path string, body interface{}, p
func (s *restClient) Post(ctx context.Context, path string, body interface{}, params query.Params, headers map[string]string) (*http.Response, error) {
endpoint := s.api.ResolveReference(&url.URL{Path: path})
- if req, err := NewRequest(ctx, http.MethodPost, endpoint, body, params.AsMap(), headers); err != nil {
+ paramsMap := make(map[string]string)
+ if params != nil {
+ paramsMap = params.AsMap()
+ }
+ if req, err := NewRequest(ctx, http.MethodPost, endpoint, body, paramsMap, headers); err != nil {
return nil, err
} else {
return s.Send(req)
@@ -201,7 +217,11 @@ func (s *restClient) Post(ctx context.Context, path string, body interface{}, pa
func (s *restClient) Put(ctx context.Context, path string, body interface{}, params query.Params, headers map[string]string) (*http.Response, error) {
endpoint := s.api.ResolveReference(&url.URL{Path: path})
- if req, err := NewRequest(ctx, http.MethodPost, endpoint, body, params.AsMap(), headers); err != nil {
+ paramsMap := make(map[string]string)
+ if params != nil {
+ paramsMap = params.AsMap()
+ }
+ if req, err := NewRequest(ctx, http.MethodPost, endpoint, body, paramsMap, headers); err != nil {
return nil, err
} else {
return s.Send(req)