Skip to content

Commit

Permalink
feat: establish azure resource relationship to resource group &
Browse files Browse the repository at this point in the history
subscription
  • Loading branch information
adityathebe authored and moshloop committed Dec 5, 2023
1 parent b13a4df commit 72e711a
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 1 deletion.
63 changes: 62 additions & 1 deletion scrapers/azure/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/trafficmanager/armtrafficmanager"
"github.com/flanksource/commons/logger"
"github.com/flanksource/duty/models"

"github.com/flanksource/config-db/api"
v1 "github.com/flanksource/config-db/api/v1"
)

const ConfigTypePrefix = "Azure::"

type Scraper struct {
ctx context.Context
cred *azidentity.ClientSecretCredential
Expand Down Expand Up @@ -102,6 +106,45 @@ func (azure Scraper) Scrape(ctx api.ScrapeContext) v1.ScrapeResults {
results = append(results, azure.fetchAdvisorAnalysis()...)
}

// Establish relationship of all resources to the corresponding subscription & resource group
for i, r := range results {
if r.ID == "" {
continue
}

var relateSubscription, relateResourceGroup bool
switch r.Type {
case ConfigTypePrefix + "SUBSCRIPTION":
continue

case ConfigTypePrefix + "MICROSOFT.RESOURCES/RESOURCEGROUPS":
relateSubscription = true

default:
relateSubscription = true
relateResourceGroup = true
}

if relateSubscription {
results[i].RelationshipResults = append(results[i].RelationshipResults, v1.RelationshipResult{
ConfigExternalID: v1.ExternalID{ExternalID: []string{r.ID}, ConfigType: r.Type},
RelatedExternalID: v1.ExternalID{ExternalID: []string{"/subscriptions/" + azure.config.SubscriptionID}, ConfigType: ConfigTypePrefix + "SUBSCRIPTION"},
Relationship: "Subscription" + strings.TrimPrefix(r.Type, ConfigTypePrefix),
})
}

if relateResourceGroup && extractResourceGroup(r.ID) != "" {
results[i].RelationshipResults = append(results[i].RelationshipResults, v1.RelationshipResult{
ConfigExternalID: v1.ExternalID{ExternalID: []string{r.ID}, ConfigType: r.Type},
RelatedExternalID: v1.ExternalID{
ExternalID: []string{fmt.Sprintf("/subscriptions/%s/resourcegroups/%s", azure.config.SubscriptionID, extractResourceGroup(r.ID))},
ConfigType: ConfigTypePrefix + "MICROSOFT.RESOURCES/RESOURCEGROUPS",
},
Relationship: "Resourcegroup" + strings.TrimPrefix(r.Type, ConfigTypePrefix),
})
}
}

return results
}

Expand Down Expand Up @@ -313,11 +356,12 @@ func (azure Scraper) fetchVirtualMachines() v1.ScrapeResults {
ID: getARMID(v.ID),
Name: deref(v.Name),
Config: v,
ConfigClass: "VirtualMachine",
ConfigClass: models.ConfigClassVirtualMachine,
Type: getARMType(v.Type),
})
}
}

return results
}

Expand Down Expand Up @@ -628,3 +672,20 @@ func getARMType(rType *string) string {
// This is required to match config analysis with the config item.
return "Azure::" + strings.ToUpper(deref(rType))
}

func extractResourceGroup(resourceID string) string {
resourceID = strings.Trim(resourceID, " ")
resourceID = strings.TrimPrefix(resourceID, "/")

segments := strings.Split(resourceID, "/")
if len(segments) < 4 {
return ""
}

if segments[2] != "resourcegroups" {
return ""
}

// The resource group is the third segment
return segments[3]
}
29 changes: 29 additions & 0 deletions scrapers/azure/azure_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package azure

import "testing"

func TestExtractResourceGroup(t *testing.T) {
tests := []struct {
input string
expectedOutput string
}{
// Valid input cases
{"/subscriptions/0cd017bb-aa54-5121-b21f-ecf8daee0624/resourcegroups/mc_demo_demo_francecentral", "mc_demo_demo_francecentral"},
{"/subscriptions/0cd017bb-aa54-5121-b21f-ecf8daee0624/resourcegroups/crossplane", "crossplane"},
{"/subscriptions/0cd017bb-aa54-5121-b21f-ecf8daee0624/resourcegroups/crossplane/providers/microsoft.containerservice/managedclusters/workload-prod-eu-01", "crossplane"},
{"/subscriptions/0cd017bb-aa54-5121-b21f-ecf8daee0624/resourcegroups/internal-prod/providers/microsoft.storage/storageaccounts/flanksourcebackups", "internal-prod"},
{"/subscriptions/0cd017bb-aa54-5121-b21f-ecf8daee0624/resourcegroups/mc_crossplane_crossplane-master_northeurope/providers/microsoft.network/loadbalancers/kubernetes", "mc_crossplane_crossplane-master_northeurope"},

// Invalid input cases
{"", ""},
{"/subscriptions/123", ""},
{"/subscriptions/456/notresourcegroup/test", ""},
}

for _, test := range tests {
result := extractResourceGroup(test.input)
if result != test.expectedOutput {
t.Errorf("Input: %s, Expected: %s, Got: %s", test.input, test.expectedOutput, result)
}
}
}

0 comments on commit 72e711a

Please sign in to comment.