diff --git a/.gitignore b/.gitignore index 7365bc0..e95e8d5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ *.drawio* *.json *.exe +*.dot !example/example.json !example/example.drawio +!example/example.dot .cloudsketch \ No newline at end of file diff --git a/cmd/cloudsketch.go b/cmd/cloudsketch.go index 303e651..0d082c4 100644 --- a/cmd/cloudsketch.go +++ b/cmd/cloudsketch.go @@ -1,9 +1,14 @@ package cmd import ( - "cloudsketch/internal/drawio" - "cloudsketch/internal/drawio/models" + "cloudsketch/internal/datastructures/build_graph" + "cloudsketch/internal/frontends" + "cloudsketch/internal/frontends/dot" + "cloudsketch/internal/frontends/drawio" + frontendModels "cloudsketch/internal/frontends/models" + "cloudsketch/internal/list" "cloudsketch/internal/marshall" + "cloudsketch/internal/providers" "cloudsketch/internal/providers/azure" "context" "errors" @@ -14,6 +19,16 @@ import ( "github.com/urfave/cli/v3" ) +var ( + frontendmap map[string]frontends.Frontend = map[string]frontends.Frontend{ + "drawio": drawio.New(), + "dot": dot.New(), + } + providermap map[string]providers.Provider = map[string]providers.Provider{ + "azure": azure.NewProvider(), + } +) + func newCloudsketch(_ context.Context, command *cli.Command) error { args := command.Args().Slice() @@ -23,38 +38,58 @@ func newCloudsketch(_ context.Context, command *cli.Command) error { fileOrSubscriptionId := args[0] + frontendString := command.String("frontend") + + frontend, ok := frontendmap[frontendString] + + if !ok { + return fmt.Errorf("unknown frontend %s", frontendString) + } + + providerString := command.String("provider") + + provider, ok := providermap[providerString] + + if !ok { + return fmt.Errorf("unknown frontend %s", frontendString) + } + + log.Printf("target frontend is %s\n", frontendString) + log.Printf("target provider is %s\n", providerString) + + var resources []*providers.Resource + var filename string + // command can either be a subscription id or a file name if strings.HasSuffix(fileOrSubscriptionId, ".json") { // if the file ends in .json, assume its a valid json file that contains previously populated Azure resources - file := fileOrSubscriptionId + existingResources, existingFilename, err := useExistingFile(fileOrSubscriptionId, frontendString) - log.Printf("using existing file %s\n", file) + if err != nil { + return err + } - resources, err := marshall.UnmarshallResources[[]*models.Resource](file) + resources = existingResources + filename = existingFilename + } else { + // otherwise treat it as a subscription id + existingResources, existingFilename, err := createNewFile(fileOrSubscriptionId, frontendString, provider) if err != nil { return err } - outFile := strings.ReplaceAll(file, ".json", ".drawio") - - return drawio.New(*resources).WriteDiagram(outFile) + resources = existingResources + filename = existingFilename } - // otherwise treat it as a subscription id - subscriptionId := fileOrSubscriptionId - - provider := azure.NewProvider() - - resources, filename, err := provider.FetchResources(subscriptionId) + frontendResources, err := mapToDomainModels(resources) if err != nil { return err } - filename = fmt.Sprintf("%s.drawio", filename) - - if err := drawio.New(resources).WriteDiagram(filename); err != nil { + if err := frontend.WriteDiagram(frontendResources, filename); err != nil { return err } @@ -63,3 +98,76 @@ func newCloudsketch(_ context.Context, command *cli.Command) error { return nil } + +func useExistingFile(file, frontendString string) ([]*providers.Resource, string, error) { + log.Printf("using existing file %s\n", file) + + resources, err := marshall.UnmarshallResources[[]*providers.Resource](file) + + if err != nil { + return nil, "", err + } + + outFile := strings.ReplaceAll(file, ".json", fmt.Sprintf(".%s", frontendString)) + + return *resources, outFile, nil +} + +func createNewFile(subscriptionId, frontendString string, provider providers.Provider) ([]*providers.Resource, string, error) { + resources, filename, err := provider.FetchResources(subscriptionId) + + if err != nil { + return nil, "", err + } + + // cache resources for next run + err = marshall.MarshallResources(fmt.Sprintf("%s.json", filename), resources) + + filename = fmt.Sprintf("%s.%s", filename, frontendString) + + return resources, filename, err +} + +func mapToDomainModels(resources []*providers.Resource) ([]*frontendModels.Resource, error) { + resource_map := &map[string]*frontendModels.Resource{} + + tasks := list.Map(resources, func(r *providers.Resource) *build_graph.Task { + return build_graph.NewTask(r.Id, r.DependsOn, []string{}, []string{}, func() { addDependenciesFromIds(r, resource_map) }) + }) + + bg, err := build_graph.NewGraph(tasks) + + if err != nil { + return nil, fmt.Errorf("error during construction of dependency graph: %+v", err) + } + + for _, task := range tasks { + bg.Resolve(task) + } + + domainResources := []*frontendModels.Resource{} + for _, v := range *resource_map { + domainResources = append(domainResources, v) + } + + return domainResources, nil +} + +func addDependenciesFromIds(resource *providers.Resource, resource_map *map[string]*frontendModels.Resource) { + if (*resource_map)[resource.Id] != nil { + // resource already registered + return + } + + dependencies := list.Map(resource.DependsOn, func(d string) *frontendModels.Resource { + return (*resource_map)[d] + }) + + (*resource_map)[resource.Id] = &frontendModels.Resource{ + Id: resource.Id, + Type: resource.Type, + Name: resource.Name, + DependsOn: dependencies, + Properties: resource.Properties, + } +} diff --git a/cmd/cmd.go b/cmd/cmd.go index a679b8c..373e4bf 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -1,10 +1,12 @@ package cmd import ( + "cloudsketch/internal/list" "context" "fmt" "log" "os" + "strings" "github.com/urfave/cli/v3" ) @@ -16,6 +18,24 @@ func Execute() { Usage: "Azure to DrawIO", UsageText: fmt.Sprintf("%s ", name), Description: "convert a Azure subscription to a DrawIO diagram", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "frontend", + Usage: "visualization target", + Value: "drawio", + Validator: func(frontend string) error { + return isValidInput([]string{"drawio", "dot"}, frontend) + }, + }, + &cli.StringFlag{ + Name: "provider", + Usage: "resource source", + Value: "azure", + Validator: func(provider string) error { + return isValidInput([]string{"azure"}, provider) + }, + }, + }, Commands: []*cli.Command{ newVersion(), }, @@ -26,3 +46,15 @@ func Execute() { log.Fatal(err) } } + +func isValidInput(validInputs []string, input string) error { + valid := list.Contains(validInputs, func(validProvider string) bool { + return input == validProvider + }) + + if !valid { + return fmt.Errorf("%s is not a valid value. Valid target are %s", input, strings.Join(validInputs, ",")) + } + + return nil +} diff --git a/example/example.dot b/example/example.dot new file mode 100644 index 0000000..5d83c3b --- /dev/null +++ b/example/example.dot @@ -0,0 +1,11 @@ +digraph exampleexample { + examplevm -> examplenic; + examplevm -> examplesubscription; + examplesnet -> examplevnet; + examplesnet -> examplesubscription; + examplevmss -> examplesnet; + examplevmss -> examplesubscription; + examplenic -> examplesnet; + examplenic -> examplesubscription; + examplevnet -> examplesubscription; +} \ No newline at end of file diff --git a/example/example.drawio b/example/example.drawio index 3027dc6..e6abc21 100644 --- a/example/example.drawio +++ b/example/example.drawio @@ -1,37 +1,37 @@ - + - + - + - + - + - - + + - + - + - + - - + + - + diff --git a/example/example.json b/example/example.json index 3dfff9f..432d77c 100644 --- a/example/example.json +++ b/example/example.json @@ -3,7 +3,6 @@ "Id": "/subscriptions/00000000-0000-0000-0000-000000000000", "Type": "SUBSCRIPTION", "Name": "example-subscription", - "ResourceGroup": "", "DependsOn": null, "Properties": null }, @@ -11,32 +10,33 @@ "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/example-resource-group/providers/microsoft.network/virtualnetworks/example-vnet", "Type": "VIRTUAL_NETWORK", "Name": "example-vnet", - "ResourceGroup": "", "DependsOn": [ "/subscriptions/00000000-0000-0000-0000-000000000000" ], "Properties": { - "size": "21" + "size": [ + "21" + ] } }, { "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/example-resource-group/providers/microsoft.network/virtualnetworks/example-vnet/subnets/example-snet", "Type": "SUBNET", "Name": "example-snet", - "ResourceGroup": "", "DependsOn": [ "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/example-resource-group/providers/microsoft.network/virtualnetworks/example-vnet", "/subscriptions/00000000-0000-0000-0000-000000000000" ], "Properties": { - "size": "22" + "size": [ + "22" + ] } }, { "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/example-resource-group/providers/microsoft.compute/virtualmachinescalesets/example-vmss", "Type": "VIRTUAL_MACHINE_SCALE_SET", "Name": "example-vmss", - "ResourceGroup": "", "DependsOn": [ "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/example-resource-group/providers/microsoft.network/virtualnetworks/example-vnet/subnets/example-snet", "/subscriptions/00000000-0000-0000-0000-000000000000" @@ -47,20 +47,20 @@ "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/example-resource-group/providers/microsoft.network/networkinterfaces/example-nic", "Type": "NETWORK_INTERFACE", "Name": "example-nic", - "ResourceGroup": "", "DependsOn": [ "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/example-resource-group/providers/microsoft.network/virtualnetworks/example-vnet/subnets/example-snet", "/subscriptions/00000000-0000-0000-0000-000000000000" ], "Properties": { - "attachedTo": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/example-resource-group/providers/microsoft.compute/virtualmachines/example-vm" + "attachedTo": [ + "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/example-resource-group/providers/microsoft.compute/virtualmachines/example-vm" + ] } }, { "Id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/example-resource-group/providers/microsoft.compute/virtualmachines/example-vm", "Type": "VIRTUAL_MACHINE", "Name": "example-vm", - "ResourceGroup": "", "DependsOn": [ "/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/example-resource-group/providers/microsoft.network/networkinterfaces/example-nic", "/subscriptions/00000000-0000-0000-0000-000000000000" diff --git a/internal/datastructures/build_graph/build_graph.go b/internal/datastructures/build_graph/build_graph.go index 2bd66f3..8cd056a 100644 --- a/internal/datastructures/build_graph/build_graph.go +++ b/internal/datastructures/build_graph/build_graph.go @@ -1,149 +1,113 @@ package build_graph import ( - "bytes" "cloudsketch/internal/list" "errors" "fmt" "sort" - "strings" ) -type build_graph struct { - tasks []*Task - graph map[*Task][]*Task - inverse_graph map[*Task][]*Task +type Build_graph struct { + Tasks []*Task + Graph map[string][]*Task + Inverse_graph map[string][]*Task } -func NewGraph(tasks []*Task) (*build_graph, error) { +func NewGraph(tasks []*Task) (*Build_graph, error) { graph, inverse_graph, err := buildGraph(tasks) if err != nil { return nil, err } - return &build_graph{ - tasks: tasks, - graph: graph, - inverse_graph: inverse_graph, + return &Build_graph{ + Tasks: tasks, + Graph: graph, + Inverse_graph: inverse_graph, }, nil } type Task struct { - label string - references []string - inputs []string - outputs []string - action func() + Label string + References []string + Inputs []string + Outputs []string + Action func() } func NewTask(label string, references, inputs, outputs []string, action func()) *Task { return &Task{ - label: label, - references: references, - inputs: inputs, - outputs: outputs, - action: action, + Label: label, + References: references, + Inputs: inputs, + Outputs: outputs, + Action: action, } } -func buildGraph(tasks []*Task) (map[*Task][]*Task, map[*Task][]*Task, error) { - graph := map[*Task][]*Task{} - inverse_graph := map[*Task][]*Task{} +func buildGraph(tasks []*Task) (map[string][]*Task, map[string][]*Task, error) { + graph := map[string][]*Task{} + inverse_graph := map[string][]*Task{} // sort tasks lowest amount of dependencies first sort.Slice(tasks, func(i, j int) bool { - return len(tasks[i].references) > len(tasks[j].references) + return len(tasks[i].References) > len(tasks[j].References) }) // if the last entry has refernces the graph is cyclic - if len(tasks[len(tasks)-1].references) != 0 { + if len(tasks[len(tasks)-1].References) != 0 { return nil, nil, errors.New("cyclic graph detected") } for _, task := range tasks { - _, ok := graph[task] + _, ok := graph[task.Label] if !ok { - graph[task] = []*Task{} + graph[task.Label] = []*Task{} } - for _, reference := range task.references { + for _, reference := range task.References { dependentTask := list.FirstOrDefault(tasks, nil, func(t *Task) bool { - return t.label == reference + return t.Label == reference }) if dependentTask == nil { return nil, nil, fmt.Errorf("an unknown task was referenced %s", reference) } - graph[task] = append(graph[task], dependentTask) + graph[task.Label] = append(graph[task.Label], dependentTask) - _, ok := inverse_graph[task] + _, ok := inverse_graph[task.Label] if !ok { - inverse_graph[task] = []*Task{} + inverse_graph[task.Label] = []*Task{} } - inverse_graph[dependentTask] = append(inverse_graph[dependentTask], task) + inverse_graph[dependentTask.Label] = append(inverse_graph[dependentTask.Label], task) } } return graph, inverse_graph, nil } -func (g *build_graph) Resolve(t *Task) { - for _, ref := range g.inverse_graph[t] { +func (g *Build_graph) ResolveInverse(t *Task) { + e := g.Inverse_graph[t.Label] + + for _, ref := range e { // recursively resolve the tasks dependencies - g.Resolve(ref) + g.ResolveInverse(ref) } // when the task has no dependencies it can be resolved - t.action() -} - -func ReplaceMany(s string, old []string, new string) string { - for _, toReplace := range old { - s = strings.ReplaceAll(s, toReplace, new) - } - - return s -} - -func (g *build_graph) ToDotFile(name string) string { - var buffer bytes.Buffer - - buffer.WriteString(fmt.Sprintf("digraph %s {\n", name)) - - for _, task := range g.tasks { - writeInputNodes(&buffer, task.label, task.inputs) - - writeReferences(&buffer, task.label, task.references) - - writeOutputNodes(&buffer, task.label, task.outputs) - } - - buffer.WriteString("}") - - return buffer.String() + t.Action() } -func writeInputNodes(buffer *bytes.Buffer, label string, inputs []string) { - for _, input := range inputs { - buffer.WriteString("\t") - buffer.WriteString(fmt.Sprintf(`%s [label="%s" shape=plaintext];`, input, input)) - buffer.WriteString(fmt.Sprintf("\n\t%s -> %s;\n", input, label)) - } -} +func (g *Build_graph) Resolve(t *Task) { + e := g.Graph[t.Label] -func writeReferences(buffer *bytes.Buffer, label string, references []string) { - for _, reference := range references { - buffer.WriteString(fmt.Sprintf("\t%s -> %s;\n", label, reference)) + for _, ref := range e { + // recursively resolve the tasks dependencies + g.Resolve(ref) } -} -func writeOutputNodes(buffer *bytes.Buffer, label string, outputs []string) { - for _, output := range outputs { - buffer.WriteString("\t") - buffer.WriteString(fmt.Sprintf(`%s [label="%s" shape=plaintext];`, output, output)) - buffer.WriteString(fmt.Sprintf("\n\t%s -> %s;\n", label, output)) - } + // when the task has no dependencies it can be resolved + t.Action() } diff --git a/internal/frontends/dot/main.go b/internal/frontends/dot/main.go new file mode 100644 index 0000000..3811af9 --- /dev/null +++ b/internal/frontends/dot/main.go @@ -0,0 +1,124 @@ +package dot + +import ( + "bytes" + "cloudsketch/internal/datastructures/build_graph" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/list" + "fmt" + "os" + "strings" +) + +type dot struct { +} + +func New() *dot { + return &dot{} +} + +func removeChars(s string) string { + // dot format does not allow certain characters + r := []string{"-", "_", "/", "."} + + for _, c := range r { + s = strings.ReplaceAll(s, c, "") + } + + return s +} + +func (d *dot) WriteDiagram(resources []*models.Resource, filename string) error { + tasks := list.Map(resources, func(r *models.Resource) *build_graph.Task { + return build_graph.NewTask(r.Name, list.Map(r.DependsOn, func(r *models.Resource) string { return r.Name }), []string{}, []string{}, func() {}) + }) + + tasks = list.Map(tasks, func(task *build_graph.Task) *build_graph.Task { + return &build_graph.Task{ + Label: removeChars(task.Label), + References: list.Map(task.References, removeChars), + Inputs: list.Map(task.Inputs, removeChars), + Outputs: list.Map(task.Outputs, removeChars), + } + }) + + bg, err := build_graph.NewGraph(tasks) + + if err != nil { + return err + } + + graphName := graphName(filename) + + // directory + if strings.Contains("/", graphName) { + s := strings.Split(graphName, "/") + graphName = s[len(s)-1] + } + + content := ToDotFile(bg, graphName) + + f, err := os.Create(filename) + + if err != nil { + return err + } + + defer f.Close() + + _, err = f.WriteString(content) + + return err +} + +func graphName(filename string) string { + graphName := removeChars(strings.ReplaceAll(filename, ".dot", "")) + + // directory + if strings.Contains("/", graphName) { + s := strings.Split(graphName, "/") + graphName = s[len(s)-1] + } + + return graphName +} + +func ToDotFile(g *build_graph.Build_graph, name string) string { + var buffer bytes.Buffer + + buffer.WriteString(fmt.Sprintf("digraph %s {\n", name)) + + for _, task := range g.Tasks { + writeInputNodes(&buffer, task.Label, task.Inputs) + + writeReferences(&buffer, task.Label, task.References) + + writeOutputNodes(&buffer, task.Label, task.Outputs) + } + + buffer.WriteString("}") + + return buffer.String() +} + +func writeInputNodes(buffer *bytes.Buffer, label string, inputs []string) { + for _, input := range inputs { + buffer.WriteString("\t") + buffer.WriteString(fmt.Sprintf(`%s [label="%s" shape=plaintext];`, input, input)) + buffer.WriteString(fmt.Sprintf("\n\t%s -> %s;\n", input, label)) + } +} + +func writeReferences(buffer *bytes.Buffer, label string, references []string) { + for _, reference := range references { + buffer.WriteString(fmt.Sprintf("\t%s -> %s;\n", label, reference)) + } +} + +func writeOutputNodes(buffer *bytes.Buffer, label string, outputs []string) { + for _, output := range outputs { + buffer.WriteString("\t") + buffer.WriteString(fmt.Sprintf(`%s [label="%s" shape=plaintext];`, output, output)) + buffer.WriteString(fmt.Sprintf("\n\t%s -> %s;\n", label, output)) + } +} diff --git a/internal/drawio/handlers/ai_services/handler.go b/internal/frontends/drawio/handlers/ai_services/handler.go similarity index 84% rename from internal/drawio/handlers/ai_services/handler.go rename to internal/frontends/drawio/handlers/ai_services/handler.go index e47d918..552b5bf 100644 --- a/internal/drawio/handlers/ai_services/handler.go +++ b/internal/frontends/drawio/handlers/ai_services/handler.go @@ -1,10 +1,10 @@ package ai_services import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/app_service/handler.go b/internal/frontends/drawio/handlers/app_service/handler.go similarity index 84% rename from internal/drawio/handlers/app_service/handler.go rename to internal/frontends/drawio/handlers/app_service/handler.go index 70bc541..0df600d 100644 --- a/internal/drawio/handlers/app_service/handler.go +++ b/internal/frontends/drawio/handlers/app_service/handler.go @@ -1,10 +1,10 @@ package app_service import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/app_service_plan/handler.go b/internal/frontends/drawio/handlers/app_service_plan/handler.go similarity index 86% rename from internal/drawio/handlers/app_service_plan/handler.go rename to internal/frontends/drawio/handlers/app_service_plan/handler.go index 4afb91b..df888f0 100644 --- a/internal/drawio/handlers/app_service_plan/handler.go +++ b/internal/frontends/drawio/handlers/app_service_plan/handler.go @@ -2,11 +2,11 @@ package app_service_plan import ( "cloudsketch/internal/datastructures/set" - "cloudsketch/internal/drawio/handlers/diagram" - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/diagram" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" "log" ) @@ -68,7 +68,7 @@ func (*handler) GroupResources(appServicePlan *models.Resource, resources []*mod allAppServicesInSameSubnet := list.Fold(resourcesInAppServicePlan[1:], true, func(resource *node.ResourceAndNode, matches bool) bool { appServiceSubnet := getAppServiceSubnet(resource.Resource, resources) - return matches && appServiceSubnet == firstAppServiceSubnet + return matches && appServiceSubnet.Id == firstAppServiceSubnet.Id }) if !allAppServicesInSameSubnet { @@ -115,14 +115,14 @@ func (*handler) GroupResources(appServicePlan *models.Resource, resources []*mod node.SetIconRelativeTo(appServicePlanNode, box, node.BOTTOM_LEFT) // add an explicit dependency to the subnet - appServicePlan.DependsOn = append(appServicePlan.DependsOn, *firstAppServiceSubnet) + appServicePlan.DependsOn = append(appServicePlan.DependsOn, firstAppServiceSubnet) return []*node.Node{box} } func getResourcesInAppServicePlan(resources []*models.Resource, aspId string, resource_map *map[string]*node.ResourceAndNode) []*node.ResourceAndNode { azResourcesInAsp := list.Filter(resources, func(resource *models.Resource) bool { - return list.Contains(resource.DependsOn, func(dependency string) bool { return dependency == aspId }) + return list.Contains(resource.DependsOn, func(dependency *models.Resource) bool { return dependency.Id == aspId }) }) resourcesInAsp := list.Map(azResourcesInAsp, func(resource *models.Resource) *node.ResourceAndNode { return (*resource_map)[resource.Id] @@ -130,14 +130,14 @@ func getResourcesInAppServicePlan(resources []*models.Resource, aspId string, re return resourcesInAsp } -func getAppServiceSubnet(appService *models.Resource, resources []*models.Resource) *string { +func getAppServiceSubnet(appService *models.Resource, resources []*models.Resource) *models.Resource { for _, dependency := range appService.DependsOn { resource := list.First(resources, func(resource *models.Resource) bool { - return resource.Id == dependency + return resource.Id == dependency.Id }) if resource.Type == types.SUBNET { - return &resource.Id + return resource } } diff --git a/internal/drawio/handlers/application_gateway/handler.go b/internal/frontends/drawio/handlers/application_gateway/handler.go similarity index 81% rename from internal/drawio/handlers/application_gateway/handler.go rename to internal/frontends/drawio/handlers/application_gateway/handler.go index ad5733c..3644a87 100644 --- a/internal/drawio/handlers/application_gateway/handler.go +++ b/internal/frontends/drawio/handlers/application_gateway/handler.go @@ -1,10 +1,10 @@ package application_gateway import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" ) @@ -35,8 +35,8 @@ func (*handler) MapResource(resource *models.Resource) *node.Node { } func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *map[string]*node.ResourceAndNode) *node.Node { - publicIps := list.Filter(resource.Resource.DependsOn, func(dependency string) bool { - r, ok := (*resource_map)[dependency] + publicIps := list.Filter(resource.Resource.DependsOn, func(dependency *models.Resource) bool { + r, ok := (*resource_map)[dependency.Id] if !ok { return false @@ -46,7 +46,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma }) if len(publicIps) == 1 { - pipResource := (*resource_map)[publicIps[0]] + pipResource := (*resource_map)[publicIps[0].Id] return node.GroupIconsAndSetPosition(resource.Node, pipResource.Node, node.TOP_RIGHT) } diff --git a/internal/drawio/handlers/application_group/handler.go b/internal/frontends/drawio/handlers/application_group/handler.go similarity index 84% rename from internal/drawio/handlers/application_group/handler.go rename to internal/frontends/drawio/handlers/application_group/handler.go index 6240c5e..8bdc0b5 100644 --- a/internal/drawio/handlers/application_group/handler.go +++ b/internal/frontends/drawio/handlers/application_group/handler.go @@ -1,10 +1,10 @@ package application_group import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/application_insights/handler.go b/internal/frontends/drawio/handlers/application_insights/handler.go similarity index 84% rename from internal/drawio/handlers/application_insights/handler.go rename to internal/frontends/drawio/handlers/application_insights/handler.go index fd4ab48..f78c2cf 100644 --- a/internal/drawio/handlers/application_insights/handler.go +++ b/internal/frontends/drawio/handlers/application_insights/handler.go @@ -1,10 +1,10 @@ package application_insights import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/application_security_group/handler.go b/internal/frontends/drawio/handlers/application_security_group/handler.go similarity index 85% rename from internal/drawio/handlers/application_security_group/handler.go rename to internal/frontends/drawio/handlers/application_security_group/handler.go index ef6a967..9ca7923 100644 --- a/internal/drawio/handlers/application_security_group/handler.go +++ b/internal/frontends/drawio/handlers/application_security_group/handler.go @@ -1,10 +1,10 @@ package application_security_group import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/bastion/handler.go b/internal/frontends/drawio/handlers/bastion/handler.go similarity index 81% rename from internal/drawio/handlers/bastion/handler.go rename to internal/frontends/drawio/handlers/bastion/handler.go index 8a05604..1750971 100644 --- a/internal/drawio/handlers/bastion/handler.go +++ b/internal/frontends/drawio/handlers/bastion/handler.go @@ -1,10 +1,10 @@ package bastion import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" ) @@ -35,8 +35,8 @@ func (*handler) MapResource(resource *models.Resource) *node.Node { } func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *map[string]*node.ResourceAndNode) *node.Node { - publicIps := list.Filter(resource.Resource.DependsOn, func(dependency string) bool { - r, ok := (*resource_map)[dependency] + publicIps := list.Filter(resource.Resource.DependsOn, func(dependency *models.Resource) bool { + r, ok := (*resource_map)[dependency.Id] if !ok { return false @@ -46,7 +46,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma }) if len(publicIps) == 1 { - pipResource := (*resource_map)[publicIps[0]] + pipResource := (*resource_map)[publicIps[0].Id] return node.GroupIconsAndSetPosition(resource.Node, pipResource.Node, node.TOP_RIGHT) } diff --git a/internal/drawio/handlers/connection/handler.go b/internal/frontends/drawio/handlers/connection/handler.go similarity index 84% rename from internal/drawio/handlers/connection/handler.go rename to internal/frontends/drawio/handlers/connection/handler.go index defe1f2..6ba8e9a 100644 --- a/internal/drawio/handlers/connection/handler.go +++ b/internal/frontends/drawio/handlers/connection/handler.go @@ -1,10 +1,10 @@ package connection import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/container_registry/handler.go b/internal/frontends/drawio/handlers/container_registry/handler.go similarity index 84% rename from internal/drawio/handlers/container_registry/handler.go rename to internal/frontends/drawio/handlers/container_registry/handler.go index 18b46a1..ef3b26e 100644 --- a/internal/drawio/handlers/container_registry/handler.go +++ b/internal/frontends/drawio/handlers/container_registry/handler.go @@ -1,10 +1,10 @@ package container_registry import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/cosmos/handler.go b/internal/frontends/drawio/handlers/cosmos/handler.go similarity index 84% rename from internal/drawio/handlers/cosmos/handler.go rename to internal/frontends/drawio/handlers/cosmos/handler.go index a209c0a..232712f 100644 --- a/internal/drawio/handlers/cosmos/handler.go +++ b/internal/frontends/drawio/handlers/cosmos/handler.go @@ -1,10 +1,10 @@ package cosmos import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/data_factory/handler.go b/internal/frontends/drawio/handlers/data_factory/handler.go similarity index 90% rename from internal/drawio/handlers/data_factory/handler.go rename to internal/frontends/drawio/handlers/data_factory/handler.go index b461415..8790cf7 100644 --- a/internal/drawio/handlers/data_factory/handler.go +++ b/internal/frontends/drawio/handlers/data_factory/handler.go @@ -1,11 +1,11 @@ package data_factory import ( - "cloudsketch/internal/drawio/handlers/diagram" - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/diagram" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" ) @@ -105,7 +105,7 @@ func (*handler) GroupResources(dataFactory *models.Resource, resources []*models func getResourcesInDataFactory(resources []*models.Resource, adfId string, resource_map *map[string]*node.ResourceAndNode) []*node.ResourceAndNode { azResourcesInAsp := list.Filter(resources, func(resource *models.Resource) bool { - return list.Contains(resource.DependsOn, func(dependency string) bool { return dependency == adfId }) + return list.Contains(resource.DependsOn, func(dependency *models.Resource) bool { return dependency.Id == adfId }) }) resourcesInAsp := list.Map(azResourcesInAsp, func(resource *models.Resource) *node.ResourceAndNode { return (*resource_map)[resource.Id] diff --git a/internal/drawio/handlers/data_factory_integration_runtime/handler.go b/internal/frontends/drawio/handlers/data_factory_integration_runtime/handler.go similarity index 81% rename from internal/drawio/handlers/data_factory_integration_runtime/handler.go rename to internal/frontends/drawio/handlers/data_factory_integration_runtime/handler.go index 91c68b1..9e02872 100644 --- a/internal/drawio/handlers/data_factory_integration_runtime/handler.go +++ b/internal/frontends/drawio/handlers/data_factory_integration_runtime/handler.go @@ -1,11 +1,11 @@ package data_factory_integration_runtime import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/handlers/virtual_machine" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/handlers/virtual_machine" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/data_factory_managed_private_endpoint/handler.go b/internal/frontends/drawio/handlers/data_factory_managed_private_endpoint/handler.go similarity index 81% rename from internal/drawio/handlers/data_factory_managed_private_endpoint/handler.go rename to internal/frontends/drawio/handlers/data_factory_managed_private_endpoint/handler.go index 769c745..bd40ff4 100644 --- a/internal/drawio/handlers/data_factory_managed_private_endpoint/handler.go +++ b/internal/frontends/drawio/handlers/data_factory_managed_private_endpoint/handler.go @@ -1,11 +1,11 @@ package data_factory_managed_private_endpoint import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/handlers/private_endpoint" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/handlers/private_endpoint" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/databricks_workspace/handler.go b/internal/frontends/drawio/handlers/databricks_workspace/handler.go similarity index 84% rename from internal/drawio/handlers/databricks_workspace/handler.go rename to internal/frontends/drawio/handlers/databricks_workspace/handler.go index ffa4e4a..4b260a4 100644 --- a/internal/drawio/handlers/databricks_workspace/handler.go +++ b/internal/frontends/drawio/handlers/databricks_workspace/handler.go @@ -1,10 +1,10 @@ package databricks_workspace import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/diagram/diagram.go b/internal/frontends/drawio/handlers/diagram/diagram.go similarity index 100% rename from internal/drawio/handlers/diagram/diagram.go rename to internal/frontends/drawio/handlers/diagram/diagram.go diff --git a/internal/drawio/handlers/dns_record/handler.go b/internal/frontends/drawio/handlers/dns_record/handler.go similarity index 93% rename from internal/drawio/handlers/dns_record/handler.go rename to internal/frontends/drawio/handlers/dns_record/handler.go index 1d9ef9c..94a39c9 100644 --- a/internal/drawio/handlers/dns_record/handler.go +++ b/internal/frontends/drawio/handlers/dns_record/handler.go @@ -1,9 +1,9 @@ package dns_record import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" ) diff --git a/internal/drawio/handlers/express_route_circuit/handler.go b/internal/frontends/drawio/handlers/express_route_circuit/handler.go similarity index 92% rename from internal/drawio/handlers/express_route_circuit/handler.go rename to internal/frontends/drawio/handlers/express_route_circuit/handler.go index 7692211..fbec45e 100644 --- a/internal/drawio/handlers/express_route_circuit/handler.go +++ b/internal/frontends/drawio/handlers/express_route_circuit/handler.go @@ -1,10 +1,10 @@ package express_route_circuit import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" ) diff --git a/internal/drawio/handlers/express_route_gateway/handler.go b/internal/frontends/drawio/handlers/express_route_gateway/handler.go similarity index 84% rename from internal/drawio/handlers/express_route_gateway/handler.go rename to internal/frontends/drawio/handlers/express_route_gateway/handler.go index e70990a..dbf0551 100644 --- a/internal/drawio/handlers/express_route_gateway/handler.go +++ b/internal/frontends/drawio/handlers/express_route_gateway/handler.go @@ -1,10 +1,10 @@ package express_route_gateway import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/function_app/handler.go b/internal/frontends/drawio/handlers/function_app/handler.go similarity index 93% rename from internal/drawio/handlers/function_app/handler.go rename to internal/frontends/drawio/handlers/function_app/handler.go index f93b485..779ecf6 100644 --- a/internal/drawio/handlers/function_app/handler.go +++ b/internal/frontends/drawio/handlers/function_app/handler.go @@ -1,10 +1,10 @@ package function_app import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" "strings" ) diff --git a/internal/drawio/handlers/host_pool/handler.go b/internal/frontends/drawio/handlers/host_pool/handler.go similarity index 89% rename from internal/drawio/handlers/host_pool/handler.go rename to internal/frontends/drawio/handlers/host_pool/handler.go index 87858f9..56b6a05 100644 --- a/internal/drawio/handlers/host_pool/handler.go +++ b/internal/frontends/drawio/handlers/host_pool/handler.go @@ -1,10 +1,10 @@ package host_pool import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" ) diff --git a/internal/drawio/handlers/key_vault/handler.go b/internal/frontends/drawio/handlers/key_vault/handler.go similarity index 84% rename from internal/drawio/handlers/key_vault/handler.go rename to internal/frontends/drawio/handlers/key_vault/handler.go index d08fc8a..09bf1ac 100644 --- a/internal/drawio/handlers/key_vault/handler.go +++ b/internal/frontends/drawio/handlers/key_vault/handler.go @@ -1,10 +1,10 @@ package key_vault import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/load_balancer/handler.go b/internal/frontends/drawio/handlers/load_balancer/handler.go similarity index 84% rename from internal/drawio/handlers/load_balancer/handler.go rename to internal/frontends/drawio/handlers/load_balancer/handler.go index b4879f7..11f9370 100644 --- a/internal/drawio/handlers/load_balancer/handler.go +++ b/internal/frontends/drawio/handlers/load_balancer/handler.go @@ -1,10 +1,10 @@ package load_balancer import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/load_balancer_frontend/handler.go b/internal/frontends/drawio/handlers/load_balancer_frontend/handler.go similarity index 85% rename from internal/drawio/handlers/load_balancer_frontend/handler.go rename to internal/frontends/drawio/handlers/load_balancer_frontend/handler.go index a3aba95..99cb8c0 100644 --- a/internal/drawio/handlers/load_balancer_frontend/handler.go +++ b/internal/frontends/drawio/handlers/load_balancer_frontend/handler.go @@ -1,10 +1,10 @@ package load_balancer_frontend import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/log_analytics/handler.go b/internal/frontends/drawio/handlers/log_analytics/handler.go similarity index 84% rename from internal/drawio/handlers/log_analytics/handler.go rename to internal/frontends/drawio/handlers/log_analytics/handler.go index fce3d71..e9e1e23 100644 --- a/internal/drawio/handlers/log_analytics/handler.go +++ b/internal/frontends/drawio/handlers/log_analytics/handler.go @@ -1,10 +1,10 @@ package log_analytics import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/logic_app/handler.go b/internal/frontends/drawio/handlers/logic_app/handler.go similarity index 89% rename from internal/drawio/handlers/logic_app/handler.go rename to internal/frontends/drawio/handlers/logic_app/handler.go index 62e04bc..ba84bfa 100644 --- a/internal/drawio/handlers/logic_app/handler.go +++ b/internal/frontends/drawio/handlers/logic_app/handler.go @@ -1,10 +1,10 @@ package logic_app import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/machine_learning_workspace/handler.go b/internal/frontends/drawio/handlers/machine_learning_workspace/handler.go similarity index 85% rename from internal/drawio/handlers/machine_learning_workspace/handler.go rename to internal/frontends/drawio/handlers/machine_learning_workspace/handler.go index 29b959c..26318b2 100644 --- a/internal/drawio/handlers/machine_learning_workspace/handler.go +++ b/internal/frontends/drawio/handlers/machine_learning_workspace/handler.go @@ -1,10 +1,10 @@ package machine_learning_workspace import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/nat_gateway/handler.go b/internal/frontends/drawio/handlers/nat_gateway/handler.go similarity index 81% rename from internal/drawio/handlers/nat_gateway/handler.go rename to internal/frontends/drawio/handlers/nat_gateway/handler.go index 23366a4..1e14218 100644 --- a/internal/drawio/handlers/nat_gateway/handler.go +++ b/internal/frontends/drawio/handlers/nat_gateway/handler.go @@ -1,10 +1,10 @@ package nat_gateway import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" ) @@ -35,8 +35,8 @@ func (*handler) MapResource(resource *models.Resource) *node.Node { } func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *map[string]*node.ResourceAndNode) *node.Node { - publicIps := list.Filter(resource.Resource.DependsOn, func(dependency string) bool { - r, ok := (*resource_map)[dependency] + publicIps := list.Filter(resource.Resource.DependsOn, func(dependency *models.Resource) bool { + r, ok := (*resource_map)[dependency.Id] if !ok { return false @@ -46,7 +46,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma }) if len(publicIps) == 1 { - pipResource := (*resource_map)[publicIps[0]] + pipResource := (*resource_map)[publicIps[0].Id] return node.GroupIconsAndSetPosition(resource.Node, pipResource.Node, node.TOP_RIGHT) } diff --git a/internal/drawio/handlers/network_interface/handler.go b/internal/frontends/drawio/handlers/network_interface/handler.go similarity index 83% rename from internal/drawio/handlers/network_interface/handler.go rename to internal/frontends/drawio/handlers/network_interface/handler.go index dbb83ea..c1f32fb 100644 --- a/internal/drawio/handlers/network_interface/handler.go +++ b/internal/frontends/drawio/handlers/network_interface/handler.go @@ -1,10 +1,10 @@ package network_interface import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" ) @@ -35,7 +35,13 @@ func (*handler) MapResource(resource *models.Resource) *node.Node { } func (*handler) PostProcessIcon(nic *node.ResourceAndNode, resource_map *map[string]*node.ResourceAndNode) *node.Node { - attachedTo, ok := (*resource_map)[nic.Resource.Properties["attachedTo"][0]] + attachedToIds, ok := nic.Resource.Properties["attachedTo"] + + if !ok { + return nil + } + + attachedTo, ok := (*resource_map)[attachedToIds[0]] // dont draw NICs if they are attached to a blacklisted resource if !ok || isBlacklistedResource(attachedTo.Resource.Type) { @@ -72,7 +78,13 @@ func getNICsPointingToResource(resource_map *map[string]*node.ResourceAndNode, a continue } - if v.Resource.Properties["attachedTo"][0] != attachedResource.Id { + attachedTo, ok := v.Resource.Properties["attachedTo"] + + if !ok { + continue + } + + if attachedTo[0] != attachedResource.Id { continue } diff --git a/internal/drawio/handlers/network_security_group/handler.go b/internal/frontends/drawio/handlers/network_security_group/handler.go similarity index 84% rename from internal/drawio/handlers/network_security_group/handler.go rename to internal/frontends/drawio/handlers/network_security_group/handler.go index 84d6f3b..72f50bd 100644 --- a/internal/drawio/handlers/network_security_group/handler.go +++ b/internal/frontends/drawio/handlers/network_security_group/handler.go @@ -1,10 +1,10 @@ package network_security_group import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/node/arrow.go b/internal/frontends/drawio/handlers/node/arrow.go similarity index 100% rename from internal/drawio/handlers/node/arrow.go rename to internal/frontends/drawio/handlers/node/arrow.go diff --git a/internal/drawio/handlers/node/common.go b/internal/frontends/drawio/handlers/node/common.go similarity index 98% rename from internal/drawio/handlers/node/common.go rename to internal/frontends/drawio/handlers/node/common.go index e5cfe99..8a65d18 100644 --- a/internal/drawio/handlers/node/common.go +++ b/internal/frontends/drawio/handlers/node/common.go @@ -1,8 +1,8 @@ package node import ( - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" "log" "math" diff --git a/internal/drawio/handlers/node/node.go b/internal/frontends/drawio/handlers/node/node.go similarity index 100% rename from internal/drawio/handlers/node/node.go rename to internal/frontends/drawio/handlers/node/node.go diff --git a/internal/drawio/handlers/node/types.go b/internal/frontends/drawio/handlers/node/types.go similarity index 75% rename from internal/drawio/handlers/node/types.go rename to internal/frontends/drawio/handlers/node/types.go index 298e8a6..bbe1310 100644 --- a/internal/drawio/handlers/node/types.go +++ b/internal/frontends/drawio/handlers/node/types.go @@ -1,6 +1,6 @@ package node -import "cloudsketch/internal/drawio/models" +import "cloudsketch/internal/frontends/models" type Geometry struct { X, Y, Width, Height int diff --git a/internal/drawio/handlers/postgres_sql_server/handler.go b/internal/frontends/drawio/handlers/postgres_sql_server/handler.go similarity index 81% rename from internal/drawio/handlers/postgres_sql_server/handler.go rename to internal/frontends/drawio/handlers/postgres_sql_server/handler.go index 66f8631..3637c10 100644 --- a/internal/drawio/handlers/postgres_sql_server/handler.go +++ b/internal/frontends/drawio/handlers/postgres_sql_server/handler.go @@ -1,11 +1,11 @@ package postgres_sql_server import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/handlers/sql_server" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/handlers/sql_server" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/private_dns_resolver/handler.go b/internal/frontends/drawio/handlers/private_dns_resolver/handler.go similarity index 84% rename from internal/drawio/handlers/private_dns_resolver/handler.go rename to internal/frontends/drawio/handlers/private_dns_resolver/handler.go index ab665b0..6a00c56 100644 --- a/internal/drawio/handlers/private_dns_resolver/handler.go +++ b/internal/frontends/drawio/handlers/private_dns_resolver/handler.go @@ -1,10 +1,10 @@ package private_dns_resolver import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/private_dns_zone/handler.go b/internal/frontends/drawio/handlers/private_dns_zone/handler.go similarity index 87% rename from internal/drawio/handlers/private_dns_zone/handler.go rename to internal/frontends/drawio/handlers/private_dns_zone/handler.go index 8bbdbcb..479d3cc 100644 --- a/internal/drawio/handlers/private_dns_zone/handler.go +++ b/internal/frontends/drawio/handlers/private_dns_zone/handler.go @@ -1,11 +1,11 @@ package private_dns_zone import ( - "cloudsketch/internal/drawio/handlers/diagram" - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/diagram" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" ) @@ -83,7 +83,7 @@ func (*handler) GroupResources(privateDNSZone *models.Resource, resources []*mod func getResourcesInPrivateDNSZone(resources []*models.Resource, adfId string, resource_map *map[string]*node.ResourceAndNode) []*node.ResourceAndNode { azResourcesInAsp := list.Filter(resources, func(resource *models.Resource) bool { - return list.Contains(resource.DependsOn, func(dependency string) bool { return dependency == adfId }) + return list.Contains(resource.DependsOn, func(dependency *models.Resource) bool { return dependency.Id == adfId }) }) resourcesInAsp := list.Map(azResourcesInAsp, func(resource *models.Resource) *node.ResourceAndNode { return (*resource_map)[resource.Id] diff --git a/internal/drawio/handlers/private_endpoint/handler.go b/internal/frontends/drawio/handlers/private_endpoint/handler.go similarity index 94% rename from internal/drawio/handlers/private_endpoint/handler.go rename to internal/frontends/drawio/handlers/private_endpoint/handler.go index 63a1cc6..a3918c9 100644 --- a/internal/drawio/handlers/private_endpoint/handler.go +++ b/internal/frontends/drawio/handlers/private_endpoint/handler.go @@ -1,10 +1,10 @@ package private_endpoint import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" ) @@ -88,7 +88,7 @@ func (*handler) PostProcessIcon(privateEndpoint *node.ResourceAndNode, resource_ func getPrivateEndpointSubnet(resource *models.Resource, resources []*models.Resource) *string { for _, dependency := range resource.DependsOn { resource := list.FirstOrDefault(resources, nil, func(resource *models.Resource) bool { - return resource.Id == dependency + return resource.Id == dependency.Id }) if resource == nil { @@ -108,7 +108,7 @@ func addImplicitDependencyToFunctionApp(privateEndpoint, functionApp *models.Res // resources inside the plan. If the resource this Private Endpoint is attached to, is a function app // an implicit dependency is added to the App Service to reference for _, dependency := range privateEndpoint.DependsOn { - dependentResource := (*resource_map)[dependency] + dependentResource := (*resource_map)[dependency.Id] if dependentResource == nil { continue diff --git a/internal/drawio/handlers/private_link_service/handler.go b/internal/frontends/drawio/handlers/private_link_service/handler.go similarity index 84% rename from internal/drawio/handlers/private_link_service/handler.go rename to internal/frontends/drawio/handlers/private_link_service/handler.go index 44fc173..ac1f466 100644 --- a/internal/drawio/handlers/private_link_service/handler.go +++ b/internal/frontends/drawio/handlers/private_link_service/handler.go @@ -1,10 +1,10 @@ package private_link_service import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/public_ip_address/handler.go b/internal/frontends/drawio/handlers/public_ip_address/handler.go similarity index 84% rename from internal/drawio/handlers/public_ip_address/handler.go rename to internal/frontends/drawio/handlers/public_ip_address/handler.go index d17ddc4..0c76d11 100644 --- a/internal/drawio/handlers/public_ip_address/handler.go +++ b/internal/frontends/drawio/handlers/public_ip_address/handler.go @@ -1,10 +1,10 @@ package public_ip_address import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/recovery_service_vault/handler.go b/internal/frontends/drawio/handlers/recovery_service_vault/handler.go similarity index 84% rename from internal/drawio/handlers/recovery_service_vault/handler.go rename to internal/frontends/drawio/handlers/recovery_service_vault/handler.go index 2820ee3..a7b95fd 100644 --- a/internal/drawio/handlers/recovery_service_vault/handler.go +++ b/internal/frontends/drawio/handlers/recovery_service_vault/handler.go @@ -1,10 +1,10 @@ package recovery_service_vault import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/redis/handler.go b/internal/frontends/drawio/handlers/redis/handler.go similarity index 84% rename from internal/drawio/handlers/redis/handler.go rename to internal/frontends/drawio/handlers/redis/handler.go index 3bdf49b..04caeb5 100644 --- a/internal/drawio/handlers/redis/handler.go +++ b/internal/frontends/drawio/handlers/redis/handler.go @@ -1,10 +1,10 @@ package redis import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/route_table/handler.go b/internal/frontends/drawio/handlers/route_table/handler.go similarity index 84% rename from internal/drawio/handlers/route_table/handler.go rename to internal/frontends/drawio/handlers/route_table/handler.go index d2f4f4b..91fbeaf 100644 --- a/internal/drawio/handlers/route_table/handler.go +++ b/internal/frontends/drawio/handlers/route_table/handler.go @@ -1,10 +1,10 @@ package route_table import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/search_service/handler.go b/internal/frontends/drawio/handlers/search_service/handler.go similarity index 84% rename from internal/drawio/handlers/search_service/handler.go rename to internal/frontends/drawio/handlers/search_service/handler.go index 9ae6f94..e7ca0df 100644 --- a/internal/drawio/handlers/search_service/handler.go +++ b/internal/frontends/drawio/handlers/search_service/handler.go @@ -1,10 +1,10 @@ package search_service import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/signalr/handler.go b/internal/frontends/drawio/handlers/signalr/handler.go similarity index 84% rename from internal/drawio/handlers/signalr/handler.go rename to internal/frontends/drawio/handlers/signalr/handler.go index 4c6e5b2..fbb33a6 100644 --- a/internal/drawio/handlers/signalr/handler.go +++ b/internal/frontends/drawio/handlers/signalr/handler.go @@ -1,10 +1,10 @@ package signalr import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/sql_database/handler.go b/internal/frontends/drawio/handlers/sql_database/handler.go similarity index 84% rename from internal/drawio/handlers/sql_database/handler.go rename to internal/frontends/drawio/handlers/sql_database/handler.go index 215b7ee..8d13e04 100644 --- a/internal/drawio/handlers/sql_database/handler.go +++ b/internal/frontends/drawio/handlers/sql_database/handler.go @@ -1,10 +1,10 @@ package sql_database import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/sql_server/handler.go b/internal/frontends/drawio/handlers/sql_server/handler.go similarity index 84% rename from internal/drawio/handlers/sql_server/handler.go rename to internal/frontends/drawio/handlers/sql_server/handler.go index e063c5c..99f7f6d 100644 --- a/internal/drawio/handlers/sql_server/handler.go +++ b/internal/frontends/drawio/handlers/sql_server/handler.go @@ -1,10 +1,10 @@ package sql_server import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/static_web_app/handler.go b/internal/frontends/drawio/handlers/static_web_app/handler.go similarity index 84% rename from internal/drawio/handlers/static_web_app/handler.go rename to internal/frontends/drawio/handlers/static_web_app/handler.go index a3021a0..08234cf 100644 --- a/internal/drawio/handlers/static_web_app/handler.go +++ b/internal/frontends/drawio/handlers/static_web_app/handler.go @@ -1,10 +1,10 @@ package static_web_app import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/storage_account/handler.go b/internal/frontends/drawio/handlers/storage_account/handler.go similarity index 84% rename from internal/drawio/handlers/storage_account/handler.go rename to internal/frontends/drawio/handlers/storage_account/handler.go index 21b9492..5b25b1d 100644 --- a/internal/drawio/handlers/storage_account/handler.go +++ b/internal/frontends/drawio/handlers/storage_account/handler.go @@ -1,10 +1,10 @@ package storage_account import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/subnet/handler.go b/internal/frontends/drawio/handlers/subnet/handler.go similarity index 84% rename from internal/drawio/handlers/subnet/handler.go rename to internal/frontends/drawio/handlers/subnet/handler.go index 891ca3e..efec81d 100644 --- a/internal/drawio/handlers/subnet/handler.go +++ b/internal/frontends/drawio/handlers/subnet/handler.go @@ -2,11 +2,11 @@ package subnet import ( "cloudsketch/internal/datastructures/set" - "cloudsketch/internal/drawio/handlers/diagram" - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/diagram" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" "fmt" ) @@ -36,7 +36,7 @@ func (*handler) MapResource(resource *models.Resource) *node.Node { Height: HEIGHT, } - subnetSize := resource.Properties["size"] + subnetSize := resource.Properties["size"][0] name := fmt.Sprintf("%s/%s", resource.Name, subnetSize) @@ -45,9 +45,9 @@ func (*handler) MapResource(resource *models.Resource) *node.Node { return node.NewIcon(IMAGE, name, &geometry, link) } -func getResourcseOfType(resource *models.Resource, resource_map *map[string]*node.ResourceAndNode, typ string) []string { - return list.Filter(resource.DependsOn, func(dependency string) bool { - r, ok := (*resource_map)[dependency] +func getResourcseOfType(resource *models.Resource, resource_map *map[string]*node.ResourceAndNode, typ string) []*models.Resource { + return list.Filter(resource.DependsOn, func(dependency *models.Resource) bool { + r, ok := (*resource_map)[dependency.Id] if !ok { return false @@ -62,7 +62,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma routeTables := getResourcseOfType(resource.Resource, resource_map, types.ROUTE_TABLE) if len(routeTables) == 1 { - routeTable := (*resource_map)[routeTables[0]] + routeTable := (*resource_map)[routeTables[0].Id] parentGroup = node.GroupIconsAndSetPosition(resource.Node, routeTable.Node, node.TOP_LEFT) } @@ -70,7 +70,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma networkSecurityGroups := getResourcseOfType(resource.Resource, resource_map, types.NETWORK_SECURITY_GROUP) if len(networkSecurityGroups) == 1 { - networkSecurityGroup := (*resource_map)[networkSecurityGroups[0]] + networkSecurityGroup := (*resource_map)[networkSecurityGroups[0].Id] // other subnets might point to the same NSG. If they do, ignore the merging if snets := resourcesWithReferencesTo(resource_map, networkSecurityGroup.Resource.Id); snets != 1 { @@ -100,8 +100,8 @@ func resourcesWithReferencesTo(resource_map *map[string]*node.ResourceAndNode, r count := 0 for _, v := range *resource_map { - if list.Contains(v.Resource.DependsOn, func(d string) bool { - return d == resourceId + if list.Contains(v.Resource.DependsOn, func(d *models.Resource) bool { + return d.Id == resourceId }) { count++ } @@ -158,7 +158,7 @@ func (*handler) GroupResources(subnet *models.Resource, resources []*models.Reso func getResourcesInSubnet(resources []*models.Resource, subnetId string, resource_map *map[string]*node.ResourceAndNode) []*node.Node { azResourcesInSubnet := list.Filter(resources, func(resource *models.Resource) bool { - return list.Contains(resource.DependsOn, func(dependency string) bool { return dependency == subnetId }) + return list.Contains(resource.DependsOn, func(dependency *models.Resource) bool { return dependency.Id == subnetId }) }) resourcesInSubnet := list.Map(azResourcesInSubnet, func(resource *models.Resource) *node.Node { return (*resource_map)[resource.Id].Node.GetParentOrThis() diff --git a/internal/drawio/handlers/subscription/handler.go b/internal/frontends/drawio/handlers/subscription/handler.go similarity index 86% rename from internal/drawio/handlers/subscription/handler.go rename to internal/frontends/drawio/handlers/subscription/handler.go index ffb2276..74e0b6c 100644 --- a/internal/drawio/handlers/subscription/handler.go +++ b/internal/frontends/drawio/handlers/subscription/handler.go @@ -2,11 +2,11 @@ package subscription import ( "cloudsketch/internal/datastructures/set" - "cloudsketch/internal/drawio/handlers/diagram" - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/diagram" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" ) @@ -82,8 +82,8 @@ func (*handler) GroupResources(resource *models.Resource, resources []*models.Re func getAllResourcesInSubscription(resourceId string, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { subscriptionResources := list.Filter(resources, func(r *models.Resource) bool { - return list.Contains(r.DependsOn, func(dependency string) bool { - return dependency == resourceId + return list.Contains(r.DependsOn, func(dependency *models.Resource) bool { + return dependency.Id == resourceId }) }) diff --git a/internal/drawio/handlers/user_assigned_identity/handler.go b/internal/frontends/drawio/handlers/user_assigned_identity/handler.go similarity index 84% rename from internal/drawio/handlers/user_assigned_identity/handler.go rename to internal/frontends/drawio/handlers/user_assigned_identity/handler.go index cf18608..7daec16 100644 --- a/internal/drawio/handlers/user_assigned_identity/handler.go +++ b/internal/frontends/drawio/handlers/user_assigned_identity/handler.go @@ -1,10 +1,10 @@ package user_assigned_identity import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/virtual_hub/handler.go b/internal/frontends/drawio/handlers/virtual_hub/handler.go similarity index 84% rename from internal/drawio/handlers/virtual_hub/handler.go rename to internal/frontends/drawio/handlers/virtual_hub/handler.go index b2649a7..a367a3d 100644 --- a/internal/drawio/handlers/virtual_hub/handler.go +++ b/internal/frontends/drawio/handlers/virtual_hub/handler.go @@ -1,10 +1,10 @@ package virtual_hub import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/virtual_machine/handler.go b/internal/frontends/drawio/handlers/virtual_machine/handler.go similarity index 84% rename from internal/drawio/handlers/virtual_machine/handler.go rename to internal/frontends/drawio/handlers/virtual_machine/handler.go index 2e08ed5..8d5de2a 100644 --- a/internal/drawio/handlers/virtual_machine/handler.go +++ b/internal/frontends/drawio/handlers/virtual_machine/handler.go @@ -1,10 +1,10 @@ package virtual_machine import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/virtual_machine_scale_set/handler.go b/internal/frontends/drawio/handlers/virtual_machine_scale_set/handler.go similarity index 85% rename from internal/drawio/handlers/virtual_machine_scale_set/handler.go rename to internal/frontends/drawio/handlers/virtual_machine_scale_set/handler.go index 4fdeda9..ed22eb4 100644 --- a/internal/drawio/handlers/virtual_machine_scale_set/handler.go +++ b/internal/frontends/drawio/handlers/virtual_machine_scale_set/handler.go @@ -1,10 +1,10 @@ package virtual_machine_scale_set import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/virtual_network/handler.go b/internal/frontends/drawio/handlers/virtual_network/handler.go similarity index 85% rename from internal/drawio/handlers/virtual_network/handler.go rename to internal/frontends/drawio/handlers/virtual_network/handler.go index 116b64f..44488ac 100644 --- a/internal/drawio/handlers/virtual_network/handler.go +++ b/internal/frontends/drawio/handlers/virtual_network/handler.go @@ -2,11 +2,11 @@ package virtual_network import ( "cloudsketch/internal/datastructures/set" - "cloudsketch/internal/drawio/handlers/diagram" - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/diagram" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" "cloudsketch/internal/list" "fmt" ) @@ -44,7 +44,7 @@ func (*handler) MapResource(resource *models.Resource) *node.Node { return node.NewIcon(IMAGE, resource.Name, &geometry, link) } - name := fmt.Sprintf("%s/%s", resource.Name, vnetSize) + name := fmt.Sprintf("%s/%s", resource.Name, vnetSize[0]) return node.NewIcon(IMAGE, name, &geometry, link) } @@ -98,8 +98,8 @@ func (*handler) GroupResources(vnet *models.Resource, resources []*models.Resour func getAllResourcesInVnet(vnetId string, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { subnets := list.Filter(resources, func(r *models.Resource) bool { - return list.Contains(r.DependsOn, func(dependency string) bool { - return dependency == vnetId + return list.Contains(r.DependsOn, func(dependency *models.Resource) bool { + return dependency.Id == vnetId }) }) diff --git a/internal/drawio/handlers/virtual_network_gateway/handler.go b/internal/frontends/drawio/handlers/virtual_network_gateway/handler.go similarity index 84% rename from internal/drawio/handlers/virtual_network_gateway/handler.go rename to internal/frontends/drawio/handlers/virtual_network_gateway/handler.go index ae2e401..24d3325 100644 --- a/internal/drawio/handlers/virtual_network_gateway/handler.go +++ b/internal/frontends/drawio/handlers/virtual_network_gateway/handler.go @@ -1,10 +1,10 @@ package virtual_network_gateway import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/virtual_wan/handler.go b/internal/frontends/drawio/handlers/virtual_wan/handler.go similarity index 84% rename from internal/drawio/handlers/virtual_wan/handler.go rename to internal/frontends/drawio/handlers/virtual_wan/handler.go index 7385d65..caac1e5 100644 --- a/internal/drawio/handlers/virtual_wan/handler.go +++ b/internal/frontends/drawio/handlers/virtual_wan/handler.go @@ -1,10 +1,10 @@ package virtual_wan import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/handlers/workspace/handler.go b/internal/frontends/drawio/handlers/workspace/handler.go similarity index 84% rename from internal/drawio/handlers/workspace/handler.go rename to internal/frontends/drawio/handlers/workspace/handler.go index 9d9514f..4e2ce8e 100644 --- a/internal/drawio/handlers/workspace/handler.go +++ b/internal/frontends/drawio/handlers/workspace/handler.go @@ -1,10 +1,10 @@ package workspace import ( - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/images" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/images" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" ) type handler struct{} diff --git a/internal/drawio/images/images.go b/internal/frontends/drawio/images/images.go similarity index 100% rename from internal/drawio/images/images.go rename to internal/frontends/drawio/images/images.go diff --git a/internal/drawio/drawio.go b/internal/frontends/drawio/main.go similarity index 69% rename from internal/drawio/drawio.go rename to internal/frontends/drawio/main.go index 8739701..219501d 100644 --- a/internal/drawio/drawio.go +++ b/internal/frontends/drawio/main.go @@ -4,64 +4,65 @@ import ( "cloudsketch/internal/config" "cloudsketch/internal/datastructures/build_graph" "cloudsketch/internal/datastructures/set" - "cloudsketch/internal/drawio/handlers/ai_services" - "cloudsketch/internal/drawio/handlers/app_service" - "cloudsketch/internal/drawio/handlers/app_service_plan" - "cloudsketch/internal/drawio/handlers/application_gateway" - "cloudsketch/internal/drawio/handlers/application_group" - "cloudsketch/internal/drawio/handlers/application_insights" - "cloudsketch/internal/drawio/handlers/application_security_group" - "cloudsketch/internal/drawio/handlers/bastion" - "cloudsketch/internal/drawio/handlers/connection" - "cloudsketch/internal/drawio/handlers/container_registry" - "cloudsketch/internal/drawio/handlers/cosmos" - "cloudsketch/internal/drawio/handlers/data_factory" - "cloudsketch/internal/drawio/handlers/data_factory_integration_runtime" - "cloudsketch/internal/drawio/handlers/data_factory_managed_private_endpoint" - "cloudsketch/internal/drawio/handlers/databricks_workspace" - "cloudsketch/internal/drawio/handlers/diagram" - "cloudsketch/internal/drawio/handlers/dns_record" - "cloudsketch/internal/drawio/handlers/express_route_circuit" - "cloudsketch/internal/drawio/handlers/express_route_gateway" - "cloudsketch/internal/drawio/handlers/function_app" - "cloudsketch/internal/drawio/handlers/host_pool" - "cloudsketch/internal/drawio/handlers/key_vault" - "cloudsketch/internal/drawio/handlers/load_balancer" - "cloudsketch/internal/drawio/handlers/load_balancer_frontend" - "cloudsketch/internal/drawio/handlers/log_analytics" - "cloudsketch/internal/drawio/handlers/logic_app" - "cloudsketch/internal/drawio/handlers/machine_learning_workspace" - "cloudsketch/internal/drawio/handlers/nat_gateway" - "cloudsketch/internal/drawio/handlers/network_interface" - "cloudsketch/internal/drawio/handlers/network_security_group" - "cloudsketch/internal/drawio/handlers/node" - "cloudsketch/internal/drawio/handlers/postgres_sql_server" - "cloudsketch/internal/drawio/handlers/private_dns_resolver" - "cloudsketch/internal/drawio/handlers/private_dns_zone" - "cloudsketch/internal/drawio/handlers/private_endpoint" - "cloudsketch/internal/drawio/handlers/private_link_service" - "cloudsketch/internal/drawio/handlers/public_ip_address" - "cloudsketch/internal/drawio/handlers/recovery_service_vault" - "cloudsketch/internal/drawio/handlers/redis" - "cloudsketch/internal/drawio/handlers/route_table" - "cloudsketch/internal/drawio/handlers/search_service" - "cloudsketch/internal/drawio/handlers/signalr" - "cloudsketch/internal/drawio/handlers/sql_database" - "cloudsketch/internal/drawio/handlers/sql_server" - "cloudsketch/internal/drawio/handlers/static_web_app" - "cloudsketch/internal/drawio/handlers/storage_account" - "cloudsketch/internal/drawio/handlers/subnet" - "cloudsketch/internal/drawio/handlers/subscription" - "cloudsketch/internal/drawio/handlers/user_assigned_identity" - "cloudsketch/internal/drawio/handlers/virtual_hub" - "cloudsketch/internal/drawio/handlers/virtual_machine" - "cloudsketch/internal/drawio/handlers/virtual_machine_scale_set" - "cloudsketch/internal/drawio/handlers/virtual_network" - "cloudsketch/internal/drawio/handlers/virtual_network_gateway" - "cloudsketch/internal/drawio/handlers/virtual_wan" - "cloudsketch/internal/drawio/handlers/workspace" - "cloudsketch/internal/drawio/models" - "cloudsketch/internal/drawio/types" + "cloudsketch/internal/frontends/drawio/handlers/ai_services" + "cloudsketch/internal/frontends/drawio/handlers/app_service" + "cloudsketch/internal/frontends/drawio/handlers/app_service_plan" + "cloudsketch/internal/frontends/drawio/handlers/application_gateway" + "cloudsketch/internal/frontends/drawio/handlers/application_group" + "cloudsketch/internal/frontends/drawio/handlers/application_insights" + "cloudsketch/internal/frontends/drawio/handlers/application_security_group" + "cloudsketch/internal/frontends/drawio/handlers/bastion" + "cloudsketch/internal/frontends/drawio/handlers/connection" + "cloudsketch/internal/frontends/drawio/handlers/container_registry" + "cloudsketch/internal/frontends/drawio/handlers/cosmos" + "cloudsketch/internal/frontends/drawio/handlers/data_factory" + "cloudsketch/internal/frontends/drawio/handlers/data_factory_integration_runtime" + "cloudsketch/internal/frontends/drawio/handlers/data_factory_managed_private_endpoint" + "cloudsketch/internal/frontends/drawio/handlers/databricks_workspace" + "cloudsketch/internal/frontends/drawio/handlers/diagram" + "cloudsketch/internal/frontends/drawio/handlers/dns_record" + "cloudsketch/internal/frontends/drawio/handlers/express_route_circuit" + "cloudsketch/internal/frontends/drawio/handlers/express_route_gateway" + "cloudsketch/internal/frontends/drawio/handlers/function_app" + "cloudsketch/internal/frontends/drawio/handlers/host_pool" + "cloudsketch/internal/frontends/drawio/handlers/key_vault" + "cloudsketch/internal/frontends/drawio/handlers/load_balancer" + "cloudsketch/internal/frontends/drawio/handlers/load_balancer_frontend" + "cloudsketch/internal/frontends/drawio/handlers/log_analytics" + "cloudsketch/internal/frontends/drawio/handlers/logic_app" + "cloudsketch/internal/frontends/drawio/handlers/machine_learning_workspace" + "cloudsketch/internal/frontends/drawio/handlers/nat_gateway" + "cloudsketch/internal/frontends/drawio/handlers/network_interface" + "cloudsketch/internal/frontends/drawio/handlers/network_security_group" + "cloudsketch/internal/frontends/drawio/handlers/node" + "cloudsketch/internal/frontends/drawio/handlers/postgres_sql_server" + "cloudsketch/internal/frontends/drawio/handlers/private_dns_resolver" + "cloudsketch/internal/frontends/drawio/handlers/private_dns_zone" + "cloudsketch/internal/frontends/drawio/handlers/private_endpoint" + "cloudsketch/internal/frontends/drawio/handlers/private_link_service" + "cloudsketch/internal/frontends/drawio/handlers/public_ip_address" + "cloudsketch/internal/frontends/drawio/handlers/recovery_service_vault" + "cloudsketch/internal/frontends/drawio/handlers/redis" + "cloudsketch/internal/frontends/drawio/handlers/route_table" + "cloudsketch/internal/frontends/drawio/handlers/search_service" + "cloudsketch/internal/frontends/drawio/handlers/signalr" + "cloudsketch/internal/frontends/drawio/handlers/sql_database" + "cloudsketch/internal/frontends/drawio/handlers/sql_server" + "cloudsketch/internal/frontends/drawio/handlers/static_web_app" + "cloudsketch/internal/frontends/drawio/handlers/storage_account" + "cloudsketch/internal/frontends/drawio/handlers/subnet" + "cloudsketch/internal/frontends/drawio/handlers/subscription" + "cloudsketch/internal/frontends/drawio/handlers/user_assigned_identity" + "cloudsketch/internal/frontends/drawio/handlers/virtual_hub" + "cloudsketch/internal/frontends/drawio/handlers/virtual_machine" + "cloudsketch/internal/frontends/drawio/handlers/virtual_machine_scale_set" + "cloudsketch/internal/frontends/drawio/handlers/virtual_network" + "cloudsketch/internal/frontends/drawio/handlers/virtual_network_gateway" + "cloudsketch/internal/frontends/drawio/handlers/virtual_wan" + "cloudsketch/internal/frontends/drawio/handlers/workspace" + "cloudsketch/internal/frontends/models" + "cloudsketch/internal/frontends/types" + "cloudsketch/internal/list" "fmt" "log" @@ -134,13 +135,10 @@ var ( ) type drawio struct { - resources []*models.Resource } -func New(resources []*models.Resource) *drawio { - return &drawio{ - resources: resources, - } +func New() *drawio { + return &drawio{} } func removeBlacklistedHandlers() { @@ -156,11 +154,11 @@ func removeBlacklistedHandlers() { } } -func (d *drawio) WriteDiagram(filename string) error { +func (d *drawio) WriteDiagram(resources []*models.Resource, filename string) error { removeBlacklistedHandlers() // at this point only the Azure resources are known - this function adds the corresponding DrawIO icons - resource_map, err := populateResourceMap(d.resources) + resource_map, err := populateResourceMap(resources) if err != nil { return err @@ -208,29 +206,12 @@ func (d *drawio) WriteDiagram(filename string) error { return dgrm.Write(filename) } -func filterUnknownDependencies(resources []*models.Resource) []*models.Resource { - for _, resource := range resources { - resource.DependsOn = list.Filter(resource.DependsOn, func(d string) bool { - dependency := list.FirstOrDefault(resources, nil, func(r *models.Resource) bool { - return r.Id == d - }) - - return dependency != nil - }) - } - - return resources -} - func populateResourceMap(resources []*models.Resource) (*map[string]*node.ResourceAndNode, error) { resource_map := &map[string]*node.ResourceAndNode{} unhandled_resources := set.New[string]() - // input resources can contain references to resources that do not exist (in other subscriptions for example). These need to be removed - resources = filterUnknownDependencies(resources) - tasks := list.Map(resources, func(r *models.Resource) *build_graph.Task { - return build_graph.NewTask(r.Id, r.DependsOn, []string{}, []string{}, func() { drawResource(r, unhandled_resources, resource_map) }) + return build_graph.NewTask(r.Id, list.Map(r.DependsOn, func(m *models.Resource) string { return m.Id }), []string{}, []string{}, func() { drawResource(r, unhandled_resources, resource_map) }) }) bg, err := build_graph.NewGraph(tasks) @@ -239,8 +220,9 @@ func populateResourceMap(resources []*models.Resource) (*map[string]*node.Resour return nil, fmt.Errorf("error during construction of dependency graph: %+v", err) } + // ensure all resources that depend on this have been draw for _, task := range tasks { - bg.Resolve(task) + bg.ResolveInverse(task) } return resource_map, nil @@ -302,18 +284,18 @@ func addDependencies(resource_map *map[string]*node.ResourceAndNode) []*node.Arr log.Fatalf("type %s has not been registered for rendering", resource.Type) } - dependencyIds := list.Filter(resource.DependsOn, func(dependency string) bool { - targetMissing := (*resource_map)[dependency] == nil || (*resource_map)[dependency].Node == nil + dependencyIds := list.Filter(resource.DependsOn, func(dependency *models.Resource) bool { + targetMissing := (*resource_map)[dependency.Id] == nil || (*resource_map)[dependency.Id].Node == nil if targetMissing { - log.Printf("target %s was not drawn, skipping", dependency) + log.Printf("target %s was not drawn, skipping", dependency.Id) return false } return true }) - resources := list.Map(dependencyIds, func(dependency string) *models.Resource { - return (*resource_map)[dependency].Resource + resources := list.Map(dependencyIds, func(dependency *models.Resource) *models.Resource { + return (*resource_map)[dependency.Id].Resource }) arrowsToAdd := f.DrawDependencies(resource, resources, resource_map) diff --git a/internal/frontends/frontend.go b/internal/frontends/frontend.go new file mode 100644 index 0000000..2a5089e --- /dev/null +++ b/internal/frontends/frontend.go @@ -0,0 +1,7 @@ +package frontends + +import "cloudsketch/internal/frontends/models" + +type Frontend interface { + WriteDiagram(resources []*models.Resource, filename string) error +} diff --git a/internal/drawio/models/resource.go b/internal/frontends/models/resource.go similarity index 89% rename from internal/drawio/models/resource.go rename to internal/frontends/models/resource.go index 400d687..31aba0a 100644 --- a/internal/drawio/models/resource.go +++ b/internal/frontends/models/resource.go @@ -2,7 +2,7 @@ package models type Resource struct { Id, Type, Name string - DependsOn []string + DependsOn []*Resource Properties map[string][]string } diff --git a/internal/drawio/types/types.go b/internal/frontends/types/types.go similarity index 100% rename from internal/drawio/types/types.go rename to internal/frontends/types/types.go diff --git a/internal/providers/azure/provider.go b/internal/providers/azure/main.go similarity index 84% rename from internal/providers/azure/provider.go rename to internal/providers/azure/main.go index 3f34b59..bfacf18 100644 --- a/internal/providers/azure/provider.go +++ b/internal/providers/azure/main.go @@ -5,6 +5,7 @@ import ( "cloudsketch/internal/datastructures/set" "cloudsketch/internal/list" "cloudsketch/internal/marshall" + "cloudsketch/internal/providers" azContext "cloudsketch/internal/providers/azure/context" "cloudsketch/internal/providers/azure/handlers/application_gateway" "cloudsketch/internal/providers/azure/handlers/application_group" @@ -36,8 +37,7 @@ import ( "log" "strings" - domainModels "cloudsketch/internal/drawio/models" - domainTypes "cloudsketch/internal/drawio/types" + domainTypes "cloudsketch/internal/frontends/types" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" ) @@ -80,7 +80,7 @@ func NewProvider() *azureProvider { return &azureProvider{} } -func (h *azureProvider) FetchResources(subscriptionId string) ([]*domainModels.Resource, string, error) { +func (h *azureProvider) FetchResources(subscriptionId string) ([]*providers.Resource, string, error) { credentials, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { @@ -102,12 +102,12 @@ func (h *azureProvider) FetchResources(subscriptionId string) ([]*domainModels.R filename := fmt.Sprintf("%s_%s", subscription.Name, subscription.Id) filenameWithSuffix := fmt.Sprintf("%s.json", filename) - cachedResources, ok := marshall.UnmarshalIfExists[[]*domainModels.Resource](filenameWithSuffix) + cachedResources, ok := marshall.UnmarshalIfExists[[]*models.Resource](filenameWithSuffix) if ok { log.Printf("using existing file %s\n", filenameWithSuffix) - return *cachedResources, filename, nil + return mapToProviderModel(*cachedResources), filename, nil } resources, err := fetchResources(subscription, ctx) @@ -118,20 +118,62 @@ func (h *azureProvider) FetchResources(subscriptionId string) ([]*domainModels.R postProcess(resources) - domainModels, err := mapResources(resources, subscription, ctx) + addDependencyToSubscriptions(resources, subscription) - if err != nil { - return nil, "", err - } + resources = normalize(resources, ctx.TenantId, set.New[string]()) - // cache resources for next run - err = marshall.MarshallResources(filenameWithSuffix, domainModels) + // input resources can contain references to resources that do not exist (in other subscriptions for example). These need to be removed + resources = filterUnknownDependencies(resources) - if err != nil { - return nil, "", err + return mapToProviderModel(resources), filename, nil +} + +func mapToProviderModel(resources []*models.Resource) []*providers.Resource { + return list.Map(resources, func(m *models.Resource) *providers.Resource { + return &providers.Resource{ + Id: m.Id, + Name: m.Name, + Type: m.Type, + DependsOn: m.DependsOn, + Properties: m.Properties, + } + }) +} + +func normalize(resources []*models.Resource, tenantId string, unhandled_types *set.Set[string]) []*models.Resource { + return list.Map(resources, func(resource *models.Resource) *models.Resource { + return &models.Resource{ + Id: strings.ToLower(resource.Id), // Azure is not consistent regarding casing. Ensure all id's are lowercase + Type: mapTypeToDomainType(resource.Type, unhandled_types), + Name: resource.Name, + DependsOn: list.Map(resource.DependsOn, strings.ToLower), + Properties: linkOrDefault(resource, tenantId), + } + }) +} + +func linkOrDefault(resource *models.Resource, tenantId string) map[string][]string { + properties := resource.Properties + + if properties == nil { + properties = map[string][]string{} } - return domainModels, filename, nil + link := generateAzurePortalLink(resource, tenantId) + properties["link"] = []string{link} + + return properties +} + +func addDependencyToSubscriptions(resources []*models.Resource, subscription *azContext.SubscriptionContext) { + // all resources should have a dependency on the subscription. Except the subscription itself + for _, resource := range resources { + if resource.Id == subscription.ResourceId { + continue + } + + resource.DependsOn = append(resource.DependsOn, subscription.ResourceId) + } } func fetchResources(subscription *azContext.SubscriptionContext, ctx *azContext.Context) ([]*models.Resource, error) { @@ -195,44 +237,6 @@ func postProcess(resources []*models.Resource) { } } -func mapResources(resources []*models.Resource, subscription *azContext.SubscriptionContext, ctx *azContext.Context) ([]*domainModels.Resource, error) { - // all resources should have a dependency on the subscription. Except the subscription itself - for _, resource := range resources { - if resource.Id == subscription.ResourceId { - continue - } - - resource.DependsOn = append(resource.DependsOn, subscription.ResourceId) - } - - unhandled_types := set.New[string]() - domainResources := list.Map(resources, func(r *models.Resource) *domainModels.Resource { - return mapToDomainResource(r, ctx.TenantId, unhandled_types) - }) - - return domainResources, nil -} - -func mapToDomainResource(resource *models.Resource, tenantId string, unhandled_types *set.Set[string]) *domainModels.Resource { - properties := resource.Properties - - if properties == nil { - properties = map[string][]string{} - } - - link := generateAzurePortalLink(resource, tenantId) - properties["link"] = []string{link} - - // Azure is not consistent regarding casing. Ensure all id's are lowercase - return &domainModels.Resource{ - Id: strings.ToLower(resource.Id), - Type: mapTypeToDomainType(resource.Type, unhandled_types), - Name: resource.Name, - DependsOn: list.Map(resource.DependsOn, strings.ToLower), - Properties: properties, - } -} - func generateAzurePortalLink(resource *models.Resource, tenant string) string { // https://portal.azure.com/#@/resource/ return fmt.Sprintf("https://portal.azure.com/#@%s/resource%s", tenant, resource.Id) @@ -312,3 +316,17 @@ func mapTypeToDomainType(azType string, unhandled_types *set.Set[string]) string return domainType } + +func filterUnknownDependencies(resources []*models.Resource) []*models.Resource { + for _, resource := range resources { + resource.DependsOn = list.Filter(resource.DependsOn, func(d string) bool { + dependency := list.FirstOrDefault(resources, nil, func(r *models.Resource) bool { + return r.Id == d + }) + + return dependency != nil + }) + } + + return resources +} diff --git a/internal/providers/azure/types/types.go b/internal/providers/azure/types/types.go index a09ee1d..8646987 100644 --- a/internal/providers/azure/types/types.go +++ b/internal/providers/azure/types/types.go @@ -5,7 +5,7 @@ const ( APP_SERVICE = "Cloudsketch/appservice" APP_SERVICE_PLAN = "Microsoft.Web/serverFarms" APPLICATION_GATEWAY = "Microsoft.Network/applicationGateways" - APPLICATION_GROUP = "APPLICATION_GROUP" + APPLICATION_GROUP = "Microsoft.DesktopVirtualization/applicationgroups" APPLICATION_INSIGHTS = "Microsoft.Insights/components" APPLICATION_SECURITY_GROUP = "Microsoft.Network/applicationSecurityGroups" BASTION = "Microsoft.Network/bastionHosts" @@ -20,7 +20,7 @@ const ( EXPRESS_ROUTE_CIRCUIT = "Microsoft.Network/expressRouteCircuits" EXPRESS_ROUTE_GATEWAY = "Microsoft.Network/expressRouteGateways" FUNCTION_APP = "Cloudsketch/functionapp" - HOST_POOL = "HOST_POOL" + HOST_POOL = "Microsoft.DesktopVirtualization/hostpools" KEY_VAULT = "Microsoft.KeyVault/vaults" LOAD_BALANCER = "Microsoft.Network/loadBalancers" LOAD_BALANCER_FRONTEND = "Microsoft.Network/loadBalancers/frontendIPConfigurations" @@ -55,5 +55,5 @@ const ( VIRTUAL_NETWORK_GATEWAY = "Microsoft.Network/virtualNetworkGateways" VIRTUAL_WAN = "Microsoft.Network/virtualWans" WEB_SITES = "Microsoft.Web/sites" - WORKSPACE = "WORKSPACE" + WORKSPACE = "Microsoft.DesktopVirtualization/workspaces" ) diff --git a/internal/providers/provider.go b/internal/providers/provider.go new file mode 100644 index 0000000..bd5d959 --- /dev/null +++ b/internal/providers/provider.go @@ -0,0 +1,5 @@ +package providers + +type Provider interface { + FetchResources(subscriptionId string) ([]*Resource, string, error) +} diff --git a/internal/providers/resource.go b/internal/providers/resource.go new file mode 100644 index 0000000..8c3b47d --- /dev/null +++ b/internal/providers/resource.go @@ -0,0 +1,7 @@ +package providers + +type Resource struct { + Id, Type, Name string + DependsOn []string + Properties map[string][]string +}