From 9dcb7a55557daa9bc347c173967cd59e12194eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kuba=20Sobo=C5=84?= Date: Tue, 25 Feb 2025 17:49:37 +0100 Subject: [PATCH] [Asset Inventory][Azure] Fix empty `entity.name` field for some resources (#3049) fix empty names for some Azure resources (cherry picked from commit cdb87271d2604956bdd933c686afc1a8482a74a2) # Conflicts: # internal/inventory/azurefetcher/fetcher_activedirectory.go # internal/inventory/azurefetcher/fetcher_resource_graph.go --- internal/inventory/azurefetcher/common.go | 27 +++++ .../inventory/azurefetcher/fetcher_account.go | 2 +- .../azurefetcher/fetcher_activedirectory.go | 102 +++++++++++++++++- .../azurefetcher/fetcher_resource_graph.go | 6 +- .../inventory/azurefetcher/fetcher_storage.go | 2 +- 5 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 internal/inventory/azurefetcher/common.go diff --git a/internal/inventory/azurefetcher/common.go b/internal/inventory/azurefetcher/common.go new file mode 100644 index 0000000000..304886bbd2 --- /dev/null +++ b/internal/inventory/azurefetcher/common.go @@ -0,0 +1,27 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package azurefetcher + +func pickName(sortedOptions ...string) string { + for _, option := range sortedOptions { + if option != "" { + return option + } + } + return "" +} diff --git a/internal/inventory/azurefetcher/fetcher_account.go b/internal/inventory/azurefetcher/fetcher_account.go index 4293b5bb5f..b4de19788f 100644 --- a/internal/inventory/azurefetcher/fetcher_account.go +++ b/internal/inventory/azurefetcher/fetcher_account.go @@ -73,7 +73,7 @@ func (f *accountFetcher) fetch(ctx context.Context, resourceName string, functio assetChan <- inventory.NewAssetEvent( classification, item.Id, - item.DisplayName, + pickName(item.DisplayName, item.Name, item.Id), inventory.WithRawAsset(item), inventory.WithCloud(inventory.Cloud{ Provider: inventory.AzureCloudProvider, diff --git a/internal/inventory/azurefetcher/fetcher_activedirectory.go b/internal/inventory/azurefetcher/fetcher_activedirectory.go index ad837e3a01..0f4688550c 100644 --- a/internal/inventory/azurefetcher/fetcher_activedirectory.go +++ b/internal/inventory/azurefetcher/fetcher_activedirectory.go @@ -66,7 +66,7 @@ func (f *activedirectoryFetcher) fetchServicePrincipals(ctx context.Context, ass assetChan <- inventory.NewAssetEvent( inventory.AssetClassificationAzureServicePrincipal, pointers.Deref(item.GetId()), - pointers.Deref(item.GetDisplayName()), + pickName(pointers.Deref(item.GetDisplayName()), pointers.Deref(item.GetId())), inventory.WithRawAsset( item.GetBackingStore().Enumerate(), ), @@ -75,6 +75,106 @@ func (f *activedirectoryFetcher) fetchServicePrincipals(ctx context.Context, ass AccountID: tenantId, ServiceName: "Azure", }), +<<<<<<< HEAD +======= + inventory.WithTags(item.GetTags()), + ) + } +} + +func (f *activedirectoryFetcher) fetchDirectoryRoles(ctx context.Context, assetChan chan<- inventory.AssetEvent) { + f.logger.Info("Fetching Directory Roles") + defer f.logger.Info("Fetching Directory Roles - Finished") + + items, err := f.provider.ListDirectoryRoles(ctx) + if err != nil { + f.logger.Errorf("Could not fetch Directory Roles: %v", err) + } + + for _, item := range items { + assetChan <- inventory.NewAssetEvent( + inventory.AssetClassificationAzureRoleDefinition, + pointers.Deref(item.GetId()), + pickName(pointers.Deref(item.GetDisplayName()), pointers.Deref(item.GetId())), + inventory.WithRawAsset( + item.GetBackingStore().Enumerate(), + ), + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + AccountID: f.tenantID, + ServiceName: "Azure", + }), + inventory.WithUser(inventory.User{ + ID: pointers.Deref(item.GetId()), + Name: pointers.Deref(item.GetDisplayName()), + }), + ) + } +} + +func (f *activedirectoryFetcher) fetchGroups(ctx context.Context, assetChan chan<- inventory.AssetEvent) { + f.logger.Info("Fetching Groups") + defer f.logger.Info("Fetching Groups - Finished") + + items, err := f.provider.ListGroups(ctx) + if err != nil { + f.logger.Errorf("Could not fetch Groups: %v", err) + } + + for _, item := range items { + // TODO(kuba): How to test this without being able to test Groups? + // var labels map[string]string + // for _, l := range item.GetAssignedLabels() { + // fmt.Println(l) + // } + assetChan <- inventory.NewAssetEvent( + inventory.AssetClassificationAzureEntraGroup, + pointers.Deref(item.GetId()), + pickName(pointers.Deref(item.GetDisplayName()), pointers.Deref(item.GetId())), + inventory.WithRawAsset( + item.GetBackingStore().Enumerate(), + ), + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + AccountID: f.tenantID, + ServiceName: "Azure", + }), + inventory.WithGroup(inventory.Group{ + ID: pointers.Deref(item.GetId()), + Name: pointers.Deref(item.GetDisplayName()), + }), + // inventory.WithLabels(labels), + ) + } +} + +func (f *activedirectoryFetcher) fetchUsers(ctx context.Context, assetChan chan<- inventory.AssetEvent) { + f.logger.Info("Fetching Users") + defer f.logger.Info("Fetching Users - Finished") + + items, err := f.provider.ListUsers(ctx) + if err != nil { + f.logger.Errorf("Could not fetch Users: %v", err) + } + + for _, item := range items { + assetChan <- inventory.NewAssetEvent( + inventory.AssetClassificationAzureEntraUser, + pointers.Deref(item.GetId()), + pickName(pointers.Deref(item.GetDisplayName()), pointers.Deref(item.GetId())), + inventory.WithRawAsset( + item.GetBackingStore().Enumerate(), + ), + inventory.WithCloud(inventory.Cloud{ + Provider: inventory.AzureCloudProvider, + AccountID: f.tenantID, + ServiceName: "Azure", + }), + inventory.WithUser(inventory.User{ + ID: pointers.Deref(item.GetId()), + Name: pointers.Deref(item.GetDisplayName()), + }), +>>>>>>> cdb8727 ([Asset Inventory][Azure] Fix empty `entity.name` field for some resources (#3049)) ) } } diff --git a/internal/inventory/azurefetcher/fetcher_resource_graph.go b/internal/inventory/azurefetcher/fetcher_resource_graph.go index 9ee4f44cbf..5db6930990 100644 --- a/internal/inventory/azurefetcher/fetcher_resource_graph.go +++ b/internal/inventory/azurefetcher/fetcher_resource_graph.go @@ -79,14 +79,18 @@ func (f *resourceGraphFetcher) fetch(ctx context.Context, resourceName, resource } for _, item := range azureAssets { +<<<<<<< HEAD name := item.Name if name == "" { name = item.DisplayName } assetChan <- inventory.NewAssetEvent( +======= + asset := inventory.NewAssetEvent( +>>>>>>> cdb8727 ([Asset Inventory][Azure] Fix empty `entity.name` field for some resources (#3049)) classification, item.Id, - name, + pickName(item.Name, item.DisplayName, item.Id), inventory.WithRawAsset(item), inventory.WithCloud(inventory.Cloud{ Provider: inventory.AzureCloudProvider, diff --git a/internal/inventory/azurefetcher/fetcher_storage.go b/internal/inventory/azurefetcher/fetcher_storage.go index 6046f0e961..2970a6f6b1 100644 --- a/internal/inventory/azurefetcher/fetcher_storage.go +++ b/internal/inventory/azurefetcher/fetcher_storage.go @@ -114,7 +114,7 @@ func (f *storageFetcher) fetch(ctx context.Context, storageAccounts []azurelib.A assetChan <- inventory.NewAssetEvent( classification, item.Id, - item.DisplayName, + pickName(item.DisplayName, item.Name, item.Id), inventory.WithRawAsset(item), inventory.WithCloud(inventory.Cloud{ Provider: inventory.AzureCloudProvider,