diff --git a/.gitignore b/.gitignore index 1b054aa..7365bc0 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ *.json *.exe !example/example.json -!example/example.drawio \ No newline at end of file +!example/example.drawio +.cloudsketch \ No newline at end of file diff --git a/README.md b/README.md index 66a3303..005f4cc 100644 --- a/README.md +++ b/README.md @@ -9,3 +9,15 @@ Ensure the executable has been added to your PATH, and run it with the ID of the ```terminal cloudsketch ``` + +## Filtering unwanted resource + +To remove unwanted resources from the final diagram, it is possible to provide a configuration file that must be placed in the same directory as the Cloudsketch executable. This configuration file must be called `.cloudsketch.json` and should be structured as follows: + +```json +{ + "blacklist": [] +} +``` + +In the `blacklist` property it is possible to specify resources that should not be included in the final diagram. Accepted values can be found [here](https://github.com/fremartini/cloudsketch/blob/main/internal/drawio/types/types.go) diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..91d290d --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,15 @@ +package config + +import "cloudsketch/internal/marshall" + +const ( + CONFIG_FILE = ".cloudsketch.json" +) + +type config struct { + Blacklist []string +} + +func Read() (*config, bool) { + return marshall.UnmarshalIfExists[config](CONFIG_FILE) +} diff --git a/internal/drawio/drawio.go b/internal/drawio/drawio.go index 2a28084..c4c6f1c 100644 --- a/internal/drawio/drawio.go +++ b/internal/drawio/drawio.go @@ -1,8 +1,10 @@ package drawio 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" @@ -23,6 +25,7 @@ import ( "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" @@ -35,6 +38,7 @@ import ( "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" @@ -63,6 +67,7 @@ type handler interface { var ( commands handleFuncMap = handleFuncMap{ + ai_services.TYPE: ai_services.New(), app_service.TYPE: app_service.New(), app_service_plan.TYPE: app_service_plan.New(), application_gateway.TYPE: application_gateway.New(), @@ -82,6 +87,7 @@ var ( load_balancer_frontend.TYPE: load_balancer_frontend.New(), log_analytics.TYPE: log_analytics.New(), logic_app.TYPE: logic_app.New(), + machine_learning_workspace.TYPE: machine_learning_workspace.New(), nat_gateway.TYPE: nat_gateway.New(), network_interface.TYPE: network_interface.New(), network_security_group.TYPE: network_security_group.New(), @@ -93,6 +99,7 @@ var ( recovery_service_vault.TYPE: recovery_service_vault.New(), redis.TYPE: redis.New(), route_table.TYPE: route_table.New(), + search_service.TYPE: search_service.New(), signalr.TYPE: signalr.New(), sql_database.TYPE: sql_database.New(), sql_server.TYPE: sql_server.New(), @@ -113,7 +120,22 @@ func New() *drawio { return &drawio{} } +func removeBlacklistedHandlers() { + config, ok := config.Read() + + if !ok { + return + } + + // remove entries on the blacklist + for _, blacklistedItem := range config.Blacklist { + delete(commands, blacklistedItem) + } +} + func (d *drawio) WriteDiagram(filename string, resources []*models.Resource) error { + removeBlacklistedHandlers() + // at this point only the Azure resources are known - this function adds the corresponding DrawIO icons resource_map, err := populateResourceMap(resources) @@ -135,14 +157,9 @@ func (d *drawio) WriteDiagram(filename string, resources []*models.Resource) err allResources = append(allResources, resource) } - // private endpoints and NICs are typically used as icons attached to other icons and should therefore be rendered in front - // TODO: implement a better solution? - allResourcesThatShouldGoInBack := list.Filter(allResources, func(n *node.ResourceAndNode) bool { - return n.Resource.Type != types.PRIVATE_ENDPOINT && n.Resource.Type != types.NETWORK_INTERFACE && n.Resource.Type != types.PUBLIC_IP_ADDRESS - }) - - allResourcesThatShouldGoInFront := list.Filter(allResources, func(n *node.ResourceAndNode) bool { - return n.Resource.Type == types.PRIVATE_ENDPOINT || n.Resource.Type == types.NETWORK_INTERFACE || n.Resource.Type == types.PUBLIC_IP_ADDRESS + // private endpoints, NICs, PIPs and NSGs are typically used as icons attached to other icons and should therefore be rendered in front of them + allResourcesThatShouldGoInFront, allResourcesThatShouldGoInBack := list.GroupBy(allResources, func(n *node.ResourceAndNode) bool { + return n.Resource.Type == types.PRIVATE_ENDPOINT || n.Resource.Type == types.NETWORK_INTERFACE || n.Resource.Type == types.PUBLIC_IP_ADDRESS || n.Resource.Type == types.NETWORK_SECURITY_GROUP }) allResources = append(allResourcesThatShouldGoInBack, allResourcesThatShouldGoInFront...) @@ -296,8 +313,8 @@ func addBoxes(resource_map *map[string]*node.ResourceAndNode) []*node.Node { }) // virtual netwoks and subnets needs to be handled last since they "depend" on all other resources - subnets := DrawGroupForResourceType(resources, types.SUBNET, resource_map) - vnets := DrawGroupForResourceType(resources, types.VIRTUAL_NETWORK, resource_map) + subnets := drawGroupForResourceType(resources, types.SUBNET, resource_map) + vnets := drawGroupForResourceType(resources, types.VIRTUAL_NETWORK, resource_map) // return vnets first so they are rendered in the background nodes := append(vnets, append(subnets, boxes...)...) @@ -305,7 +322,7 @@ func addBoxes(resource_map *map[string]*node.ResourceAndNode) []*node.Node { return nodes } -func DrawGroupForResourceType(resources []*models.Resource, typ string, resource_map *map[string]*node.ResourceAndNode) []*node.Node { +func drawGroupForResourceType(resources []*models.Resource, typ string, resource_map *map[string]*node.ResourceAndNode) []*node.Node { nodes := []*node.Node{} resourcesWithType := list.Filter(resources, func(r *models.Resource) bool { diff --git a/internal/drawio/handlers/ai_services/handler.go b/internal/drawio/handlers/ai_services/handler.go new file mode 100644 index 0000000..1ff5020 --- /dev/null +++ b/internal/drawio/handlers/ai_services/handler.go @@ -0,0 +1,46 @@ +package ai_services + +import ( + "cloudsketch/internal/drawio/handlers/node" + "cloudsketch/internal/drawio/images" + "cloudsketch/internal/drawio/models" + "cloudsketch/internal/drawio/types" +) + +type handler struct{} + +const ( + TYPE = types.AI_SERVICES + IMAGE = images.AI_SERVICES + WIDTH = 64 + HEIGHT = 68 +) + +func New() *handler { + return &handler{} +} + +func (*handler) MapResource(resource *models.Resource) *node.Node { + geometry := node.Geometry{ + X: 0, + Y: 0, + Width: WIDTH, + Height: HEIGHT, + } + + link := resource.GetLinkOrDefault() + + return node.NewIcon(IMAGE, resource.Name, &geometry, link) +} + +func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *map[string]*node.ResourceAndNode) *node.Node { + return nil +} + +func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) +} + +func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { + return []*node.Node{} +} diff --git a/internal/drawio/handlers/app_service/handler.go b/internal/drawio/handlers/app_service/handler.go index c86a078..237d773 100644 --- a/internal/drawio/handlers/app_service/handler.go +++ b/internal/drawio/handlers/app_service/handler.go @@ -38,29 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceNode := (*resource_map)[source.Id].Node - - for _, target := range targets { - // don't draw arrows to subnets - if target.Type == types.SUBNET { - continue - } - - targetNode := (*resource_map)[target.Id].Node - - // if they are in the same group, don't draw the arrow - if sourceNode.ContainedIn != nil && targetNode.ContainedIn != nil { - if sourceNode.GetParentOrThis() == targetNode.GetParentOrThis() { - continue - } - } - - arrows = append(arrows, node.NewArrow(sourceNode.Id(), targetNode.Id(), nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{types.SUBNET}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/app_service_plan/handler.go b/internal/drawio/handlers/app_service_plan/handler.go index 2998351..d96e524 100644 --- a/internal/drawio/handlers/app_service_plan/handler.go +++ b/internal/drawio/handlers/app_service_plan/handler.go @@ -45,22 +45,8 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - // app service plans have an implicit dependency to a subnet. Don't draw these - if target.Type == types.SUBNET { - continue - } - - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + // app service plans have an implicit dependency to a subnet. Don't draw these + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{types.SUBNET}) } func (*handler) GroupResources(appServicePlan *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/application_gateway/handler.go b/internal/drawio/handlers/application_gateway/handler.go index 4a3001f..e605a48 100644 --- a/internal/drawio/handlers/application_gateway/handler.go +++ b/internal/drawio/handlers/application_gateway/handler.go @@ -54,28 +54,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - // don't draw arrows to subnets - if target.Type == types.SUBNET { - continue - } - - // don't draw arrows to public ips - if target.Type == types.PUBLIC_IP_ADDRESS { - continue - } - - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows - + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{types.SUBNET, types.PUBLIC_IP_ADDRESS}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/application_insights/handler.go b/internal/drawio/handlers/application_insights/handler.go index 52a503d..9cfb020 100644 --- a/internal/drawio/handlers/application_insights/handler.go +++ b/internal/drawio/handlers/application_insights/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/application_security_group/handler.go b/internal/drawio/handlers/application_security_group/handler.go index d427033..d7438cd 100644 --- a/internal/drawio/handlers/application_security_group/handler.go +++ b/internal/drawio/handlers/application_security_group/handler.go @@ -38,18 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/bastion/handler.go b/internal/drawio/handlers/bastion/handler.go index 42379a4..5aa14a9 100644 --- a/internal/drawio/handlers/bastion/handler.go +++ b/internal/drawio/handlers/bastion/handler.go @@ -54,27 +54,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - // don't draw arrows to subnets - if target.Type == types.SUBNET { - continue - } - - // don't draw arrows to public ips - if target.Type == types.PUBLIC_IP_ADDRESS { - continue - } - - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{types.SUBNET, types.PUBLIC_IP_ADDRESS}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/container_registry/handler.go b/internal/drawio/handlers/container_registry/handler.go index 41c8172..c5ee97b 100644 --- a/internal/drawio/handlers/container_registry/handler.go +++ b/internal/drawio/handlers/container_registry/handler.go @@ -39,17 +39,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/cosmos/handler.go b/internal/drawio/handlers/cosmos/handler.go index 2df39b0..db35957 100644 --- a/internal/drawio/handlers/cosmos/handler.go +++ b/internal/drawio/handlers/cosmos/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/data_factory/handler.go b/internal/drawio/handlers/data_factory/handler.go index 01c2298..a3223f2 100644 --- a/internal/drawio/handlers/data_factory/handler.go +++ b/internal/drawio/handlers/data_factory/handler.go @@ -45,17 +45,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(dataFactory *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/data_factory_integration_runtime/handler.go b/internal/drawio/handlers/data_factory_integration_runtime/handler.go index f163d80..4dbd56b 100644 --- a/internal/drawio/handlers/data_factory_integration_runtime/handler.go +++ b/internal/drawio/handlers/data_factory_integration_runtime/handler.go @@ -39,22 +39,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceNode := (*resource_map)[source.Id].Node - - for _, target := range targets { - targetNode := (*resource_map)[target.Id].Node - - // ADF IR can be contained inside an ADF. Don't draw these - if sourceNode.ContainedIn == targetNode.ContainedIn { - continue - } - - arrows = append(arrows, node.NewArrow(sourceNode.Id(), targetNode.Id(), nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/data_factory_managed_private_endpoint/handler.go b/internal/drawio/handlers/data_factory_managed_private_endpoint/handler.go index 45ec120..61ae519 100644 --- a/internal/drawio/handlers/data_factory_managed_private_endpoint/handler.go +++ b/internal/drawio/handlers/data_factory_managed_private_endpoint/handler.go @@ -39,23 +39,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceNode := (*resource_map)[source.Id].Node - - for _, target := range targets { - targetNode := (*resource_map)[target.Id].Node - - // ADF MPE can be contained inside an ADF. Don't draw these - if sourceNode.ContainedIn == targetNode.ContainedIn { - continue - } - - arrows = append(arrows, node.NewArrow(sourceNode.Id(), targetNode.Id(), nil)) - } - - return arrows - + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/databricks_workspace/handler.go b/internal/drawio/handlers/databricks_workspace/handler.go index 93957cb..f0f1bbb 100644 --- a/internal/drawio/handlers/databricks_workspace/handler.go +++ b/internal/drawio/handlers/databricks_workspace/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/dns_record/handler.go b/internal/drawio/handlers/dns_record/handler.go index 47d6fcf..d4358db 100644 --- a/internal/drawio/handlers/dns_record/handler.go +++ b/internal/drawio/handlers/dns_record/handler.go @@ -37,22 +37,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceNode := (*resource_map)[source.Id].Node - - for _, target := range targets { - targetNode := (*resource_map)[target.Id].Node - - // dns records can be contained inside aprivate DNS Zone. Don't draw these - if sourceNode.ContainedIn == targetNode.ContainedIn { - continue - } - - arrows = append(arrows, node.NewArrow(sourceNode.Id(), targetNode.Id(), nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/function_app/handler.go b/internal/drawio/handlers/function_app/handler.go index 04dda9d..acb5fc4 100644 --- a/internal/drawio/handlers/function_app/handler.go +++ b/internal/drawio/handlers/function_app/handler.go @@ -40,27 +40,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceNode := (*resource_map)[source.Id].Node - - for _, target := range targets { - // don't draw arrows to subnets - if target.Type == types.SUBNET { - continue - } - - targetNode := (*resource_map)[target.Id].Node - - // if they are in the same group, don't draw the arrow - if sourceNode.ContainedIn != nil && targetNode.ContainedIn != nil { - if sourceNode.GetParentOrThis() == targetNode.GetParentOrThis() { - continue - } - } - - arrows = append(arrows, node.NewArrow(sourceNode.Id(), targetNode.Id(), nil)) - } + arrows := node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) // add a dependency to the associated storage account. // this property only contains the name of the storage account @@ -76,6 +56,8 @@ func (*handler) DrawDependency(source *models.Resource, targets []*models.Resour return ran.Resource.Type == types.STORAGE_ACCOUNT && strings.Contains(ran.Resource.Name, storageAccountName) }) + sourceNode := (*resource_map)[source.Id].Node + arrows = append(arrows, node.NewArrow(sourceNode.Id(), resources[0].Node.Id(), nil)) // add a dependency to the outbound subnet diff --git a/internal/drawio/handlers/key_vault/handler.go b/internal/drawio/handlers/key_vault/handler.go index e05a86c..b7863d4 100644 --- a/internal/drawio/handlers/key_vault/handler.go +++ b/internal/drawio/handlers/key_vault/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/load_balancer/handler.go b/internal/drawio/handlers/load_balancer/handler.go index 12a8405..492c15f 100644 --- a/internal/drawio/handlers/load_balancer/handler.go +++ b/internal/drawio/handlers/load_balancer/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/load_balancer_frontend/handler.go b/internal/drawio/handlers/load_balancer_frontend/handler.go index da2306d..7636247 100644 --- a/internal/drawio/handlers/load_balancer_frontend/handler.go +++ b/internal/drawio/handlers/load_balancer_frontend/handler.go @@ -38,22 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - // don't draw arrows to subnets - if target.Type == types.SUBNET { - continue - } - - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{types.SUBNET}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/log_analytics/handler.go b/internal/drawio/handlers/log_analytics/handler.go index b5b9575..fa8712d 100644 --- a/internal/drawio/handlers/log_analytics/handler.go +++ b/internal/drawio/handlers/log_analytics/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/logic_app/handler.go b/internal/drawio/handlers/logic_app/handler.go index e6a3b06..db341d0 100644 --- a/internal/drawio/handlers/logic_app/handler.go +++ b/internal/drawio/handlers/logic_app/handler.go @@ -38,33 +38,15 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceNode := (*resource_map)[source.Id].Node - - for _, target := range targets { - // don't draw arrows to subnets - if target.Type == types.SUBNET { - continue - } - - targetNode := (*resource_map)[target.Id].Node - - // if they are in the same group, don't draw the arrow - if sourceNode.ContainedIn != nil && targetNode.ContainedIn != nil { - if sourceNode.GetParentOrThis() == targetNode.GetParentOrThis() { - continue - } - } - - arrows = append(arrows, node.NewArrow(sourceNode.Id(), targetNode.Id(), nil)) - } + arrows := node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{types.SUBNET}) // add a dependency to the outbound subnet dashed := "dashed=1" outboundSubnet := source.Properties["outboundSubnet"] outboundSubnetNode := (*resource_map)[outboundSubnet].Node + + sourceNode := (*resource_map)[source.Id].Node arrows = append(arrows, node.NewArrow(sourceNode.Id(), outboundSubnetNode.Id(), &dashed)) return arrows diff --git a/internal/drawio/handlers/machine_learning_workspace/handler.go b/internal/drawio/handlers/machine_learning_workspace/handler.go new file mode 100644 index 0000000..3a558da --- /dev/null +++ b/internal/drawio/handlers/machine_learning_workspace/handler.go @@ -0,0 +1,46 @@ +package machine_learning_workspace + +import ( + "cloudsketch/internal/drawio/handlers/node" + "cloudsketch/internal/drawio/images" + "cloudsketch/internal/drawio/models" + "cloudsketch/internal/drawio/types" +) + +type handler struct{} + +const ( + TYPE = types.MACHINE_LEARNING_WORKSPACE + IMAGE = images.MACHINE_LEARNING_WORKSPACE + WIDTH = 64 + HEIGHT = 68 +) + +func New() *handler { + return &handler{} +} + +func (*handler) MapResource(resource *models.Resource) *node.Node { + geometry := node.Geometry{ + X: 0, + Y: 0, + Width: WIDTH, + Height: HEIGHT, + } + + link := resource.GetLinkOrDefault() + + return node.NewIcon(IMAGE, resource.Name, &geometry, link) +} + +func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *map[string]*node.ResourceAndNode) *node.Node { + return nil +} + +func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{types.SUBNET}) +} + +func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { + return []*node.Node{} +} diff --git a/internal/drawio/handlers/nat_gateway/handler.go b/internal/drawio/handlers/nat_gateway/handler.go index 3953961..735d617 100644 --- a/internal/drawio/handlers/nat_gateway/handler.go +++ b/internal/drawio/handlers/nat_gateway/handler.go @@ -54,27 +54,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - // don't draw arrows to subnets - if target.Type == types.SUBNET { - continue - } - - // don't draw arrows to public ips - if target.Type == types.PUBLIC_IP_ADDRESS { - continue - } - - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{types.SUBNET, types.PUBLIC_IP_ADDRESS}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/network_interface/handler.go b/internal/drawio/handlers/network_interface/handler.go index de99807..60402d6 100644 --- a/internal/drawio/handlers/network_interface/handler.go +++ b/internal/drawio/handlers/network_interface/handler.go @@ -35,10 +35,10 @@ func (*handler) MapResource(resource *models.Resource) *node.Node { } func (*handler) PostProcessIcon(nic *node.ResourceAndNode, resource_map *map[string]*node.ResourceAndNode) *node.Node { - attachedTo := (*resource_map)[nic.Resource.Properties["attachedTo"]] + attachedTo, ok := (*resource_map)[nic.Resource.Properties["attachedTo"]] // dont draw NICs if they are attached to a blacklisted resource - if attachedTo == nil || isBlacklistedResource(attachedTo.Resource.Type) { + if !ok || isBlacklistedResource(attachedTo.Resource.Type) { delete(*resource_map, nic.Resource.Id) return nil } @@ -86,22 +86,7 @@ func getNICsPointingToResource(resource_map *map[string]*node.ResourceAndNode, a } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceNode := (*resource_map)[source.Id].Node - - for _, target := range targets { - // don't draw arrows to subnets - if target.Type == types.SUBNET { - continue - } - - targetNode := (*resource_map)[target.Id].Node - - arrows = append(arrows, node.NewArrow(sourceNode.Id(), targetNode.Id(), nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{types.SUBNET}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/network_security_group/handler.go b/internal/drawio/handlers/network_security_group/handler.go index 5c29c16..2fdf313 100644 --- a/internal/drawio/handlers/network_security_group/handler.go +++ b/internal/drawio/handlers/network_security_group/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/node/common.go b/internal/drawio/handlers/node/common.go index aed6a9c..8077c47 100644 --- a/internal/drawio/handlers/node/common.go +++ b/internal/drawio/handlers/node/common.go @@ -1,6 +1,7 @@ package node import ( + "cloudsketch/internal/drawio/models" "cloudsketch/internal/list" "log" "math" @@ -225,3 +226,36 @@ func fillResourcesInBoxSquare(box *Node, nodes []*Node, padding int) { boxGeometry.Height += nodes[len(nodes)-1].GetGeometry().Height + padding boxGeometry.Width += padding } + +func DrawDependencyArrowsToTarget(source *models.Resource, targets []*models.Resource, resource_map *map[string]*ResourceAndNode, typeBlacklist []string) []*Arrow { + sourceNode := (*resource_map)[source.Id].Node + + targetResources := list.Map(targets, func(target *models.Resource) *ResourceAndNode { + return (*resource_map)[target.Id] + }) + + // remove entries from the blacklist + targetResources = list.Filter(targetResources, func(target *ResourceAndNode) bool { + return !list.Contains(typeBlacklist, func(t string) bool { + return target.Resource.Type == t + }) + }) + + // remove entries that are in the same group + targetResources = list.Filter(targetResources, func(target *ResourceAndNode) bool { + + if sourceNode.ContainedIn == nil || target.Node.ContainedIn == nil { + return true + } + + hasSameGroup := sourceNode.GetParentOrThis() == target.Node.GetParentOrThis() + + return !hasSameGroup + }) + + arrows := list.Fold(targetResources, []*Arrow{}, func(target *ResourceAndNode, acc []*Arrow) []*Arrow { + return append(acc, NewArrow(sourceNode.Id(), target.Node.Id(), nil)) + }) + + return arrows +} diff --git a/internal/drawio/handlers/postgres_sql_server/handler.go b/internal/drawio/handlers/postgres_sql_server/handler.go index 96e31c6..cdd2933 100644 --- a/internal/drawio/handlers/postgres_sql_server/handler.go +++ b/internal/drawio/handlers/postgres_sql_server/handler.go @@ -39,17 +39,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/private_dns_zone/handler.go b/internal/drawio/handlers/private_dns_zone/handler.go index 7a153fa..36aab72 100644 --- a/internal/drawio/handlers/private_dns_zone/handler.go +++ b/internal/drawio/handlers/private_dns_zone/handler.go @@ -44,24 +44,16 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(privateDNSZone *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { - nodes := []*node.Node{} - resourcesInPrivateDNSZone := getResourcesInPrivateDNSZone(resources, privateDNSZone.Id, resource_map) + if len(resourcesInPrivateDNSZone) == 0 { + return []*node.Node{} + } + privateDNSZoneNode := (*resource_map)[privateDNSZone.Id].Node privateDNSZoneNodeGeometry := privateDNSZoneNode.GetGeometry() @@ -85,9 +77,7 @@ func (*handler) GroupResources(privateDNSZone *models.Resource, resources []*mod node.ScaleDownAndSetIconRelativeTo(privateDNSZoneNode, box, node.BOTTOM_LEFT) - nodes = append(nodes, box) - - return nodes + return []*node.Node{box} } func getResourcesInPrivateDNSZone(resources []*models.Resource, adfId string, resource_map *map[string]*node.ResourceAndNode) []*node.ResourceAndNode { diff --git a/internal/drawio/handlers/private_endpoint/handler.go b/internal/drawio/handlers/private_endpoint/handler.go index 8cbd630..5d71652 100644 --- a/internal/drawio/handlers/private_endpoint/handler.go +++ b/internal/drawio/handlers/private_endpoint/handler.go @@ -147,29 +147,7 @@ func getPrivateEndpointPointingToResource(resource_map *map[string]*node.Resourc } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceNode := (*resource_map)[source.Id].Node - - for _, target := range targets { - // don't draw arrows to subnets - if target.Type == types.SUBNET { - continue - } - - targetNode := (*resource_map)[target.Id].Node - - // if they are in the same group, don't draw the arrow - if sourceNode.ContainedIn != nil && targetNode.ContainedIn != nil { - if sourceNode.ContainedIn == targetNode.ContainedIn { - continue - } - } - - arrows = append(arrows, node.NewArrow(sourceNode.Id(), targetNode.Id(), nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{types.SUBNET}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/private_link_service/handler.go b/internal/drawio/handlers/private_link_service/handler.go index f9f3482..2699961 100644 --- a/internal/drawio/handlers/private_link_service/handler.go +++ b/internal/drawio/handlers/private_link_service/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/public_ip_address/handler.go b/internal/drawio/handlers/public_ip_address/handler.go index 0f2fd19..baa40ea 100644 --- a/internal/drawio/handlers/public_ip_address/handler.go +++ b/internal/drawio/handlers/public_ip_address/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/recovery_service_vault/handler.go b/internal/drawio/handlers/recovery_service_vault/handler.go index 8ad3401..6018704 100644 --- a/internal/drawio/handlers/recovery_service_vault/handler.go +++ b/internal/drawio/handlers/recovery_service_vault/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/redis/handler.go b/internal/drawio/handlers/redis/handler.go index 59a0708..02744ce 100644 --- a/internal/drawio/handlers/redis/handler.go +++ b/internal/drawio/handlers/redis/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/route_table/handler.go b/internal/drawio/handlers/route_table/handler.go index d97b36e..c8e311a 100644 --- a/internal/drawio/handlers/route_table/handler.go +++ b/internal/drawio/handlers/route_table/handler.go @@ -41,7 +41,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - return []*node.Arrow{} + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/search_service/handler.go b/internal/drawio/handlers/search_service/handler.go new file mode 100644 index 0000000..1b635b5 --- /dev/null +++ b/internal/drawio/handlers/search_service/handler.go @@ -0,0 +1,46 @@ +package search_service + +import ( + "cloudsketch/internal/drawio/handlers/node" + "cloudsketch/internal/drawio/images" + "cloudsketch/internal/drawio/models" + "cloudsketch/internal/drawio/types" +) + +type handler struct{} + +const ( + TYPE = types.SEARCH_SERVICE + IMAGE = images.SEARCH_SERVICE + WIDTH = 72 + HEIGHT = 52 +) + +func New() *handler { + return &handler{} +} + +func (*handler) MapResource(resource *models.Resource) *node.Node { + geometry := node.Geometry{ + X: 0, + Y: 0, + Width: WIDTH, + Height: HEIGHT, + } + + link := resource.GetLinkOrDefault() + + return node.NewIcon(IMAGE, resource.Name, &geometry, link) +} + +func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *map[string]*node.ResourceAndNode) *node.Node { + return nil +} + +func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) +} + +func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { + return []*node.Node{} +} diff --git a/internal/drawio/handlers/signalr/handler.go b/internal/drawio/handlers/signalr/handler.go index c16cea0..5ac88a9 100644 --- a/internal/drawio/handlers/signalr/handler.go +++ b/internal/drawio/handlers/signalr/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/sql_database/handler.go b/internal/drawio/handlers/sql_database/handler.go index 5610984..214f89a 100644 --- a/internal/drawio/handlers/sql_database/handler.go +++ b/internal/drawio/handlers/sql_database/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/sql_server/handler.go b/internal/drawio/handlers/sql_server/handler.go index da950e7..a925d2a 100644 --- a/internal/drawio/handlers/sql_server/handler.go +++ b/internal/drawio/handlers/sql_server/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/static_web_app/handler.go b/internal/drawio/handlers/static_web_app/handler.go index 7a3a464..9980d77 100644 --- a/internal/drawio/handlers/static_web_app/handler.go +++ b/internal/drawio/handlers/static_web_app/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/storage_account/handler.go b/internal/drawio/handlers/storage_account/handler.go index 2d94428..b464bdf 100644 --- a/internal/drawio/handlers/storage_account/handler.go +++ b/internal/drawio/handlers/storage_account/handler.go @@ -38,17 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/subnet/handler.go b/internal/drawio/handlers/subnet/handler.go index 82bc870..d9d8b3f 100644 --- a/internal/drawio/handlers/subnet/handler.go +++ b/internal/drawio/handlers/subnet/handler.go @@ -44,56 +44,51 @@ func (*handler) MapResource(resource *models.Resource) *node.Node { return node.NewIcon(IMAGE, name, &geometry, link) } -func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *map[string]*node.ResourceAndNode) *node.Node { - var tmp *node.Node = nil - - routeTables := list.Filter(resource.Resource.DependsOn, func(dependency string) bool { +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] if !ok { return false } - return r.Resource.Type == types.ROUTE_TABLE + return r.Resource.Type == typ }) +} +func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *map[string]*node.ResourceAndNode) *node.Node { + var parentGroup *node.Node = nil + + routeTables := getResourcseOfType(resource.Resource, resource_map, types.ROUTE_TABLE) if len(routeTables) == 1 { routeTable := (*resource_map)[routeTables[0]] - tmp = node.SetIcon(resource.Node, routeTable.Node, node.TOP_LEFT) + parentGroup = node.SetIcon(resource.Node, routeTable.Node, node.TOP_LEFT) } - networkSecurityGroups := list.Filter(resource.Resource.DependsOn, func(dependency string) bool { - r, ok := (*resource_map)[dependency] - - if !ok { - return false - } - - return r.Resource.Type == types.NETWORK_SECURITY_GROUP - }) + networkSecurityGroups := getResourcseOfType(resource.Resource, resource_map, types.NETWORK_SECURITY_GROUP) if len(networkSecurityGroups) == 1 { networkSecurityGroup := (*resource_map)[networkSecurityGroups[0]] // other subnets might point to the same NSG. If they do, ignore the merging if snets := resourcesWithReferencesTo(resource_map, networkSecurityGroup.Resource.Id); snets != 1 { - return tmp + return parentGroup } - if tmp == nil { + if parentGroup == nil { // route table icon was not set return node.SetIcon(resource.Node, networkSecurityGroup.Node, node.TOP_RIGHT) } // route table icon was set - networkSecurityGroup.Node.SetProperty("parent", tmp.Id()) + networkSecurityGroup.Node.SetProperty("parent", parentGroup.Id()) node.ScaleDownAndSetIconRelativeTo(networkSecurityGroup.Node, resource.Node.GetParentOrThis(), node.TOP_RIGHT) - networkSecurityGroup.Node.ContainedIn = tmp + networkSecurityGroup.Node.ContainedIn = parentGroup networkSecurityGroup.Node.SetProperty("value", "") } - return tmp + return parentGroup } func resourcesWithReferencesTo(resource_map *map[string]*node.ResourceAndNode, resourceId string) int { @@ -111,29 +106,7 @@ func resourcesWithReferencesTo(resource_map *map[string]*node.ResourceAndNode, r } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceNode := (*resource_map)[source.Id].Node - - for _, target := range targets { - // don't draw arrows to virtual networks - if target.Type == types.VIRTUAL_NETWORK { - continue - } - - targetNode := (*resource_map)[target.Id].Node - - // if they are in the same group, don't draw the arrow - if sourceNode.ContainedIn != nil && targetNode.ContainedIn != nil { - if sourceNode.ContainedIn == targetNode.ContainedIn { - continue - } - } - - arrows = append(arrows, node.NewArrow(sourceNode.Id(), targetNode.Id(), nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{types.VIRTUAL_NETWORK}) } func (*handler) GroupResources(subnet *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/subscription/handler.go b/internal/drawio/handlers/subscription/handler.go index cbae625..a614ddd 100644 --- a/internal/drawio/handlers/subscription/handler.go +++ b/internal/drawio/handlers/subscription/handler.go @@ -39,7 +39,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - return []*node.Arrow{} + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/virtual_machine/handler.go b/internal/drawio/handlers/virtual_machine/handler.go index 297a2be..e1c37ca 100644 --- a/internal/drawio/handlers/virtual_machine/handler.go +++ b/internal/drawio/handlers/virtual_machine/handler.go @@ -38,25 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceNode := (*resource_map)[source.Id].Node - - for _, target := range targets { - - targetNode := (*resource_map)[target.Id].Node - - // if they are in the same group, don't draw the arrow - if sourceNode.ContainedIn != nil && targetNode.ContainedIn != nil { - if sourceNode.ContainedIn == targetNode.ContainedIn { - continue - } - } - - arrows = append(arrows, node.NewArrow(sourceNode.Id(), targetNode.Id(), nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/virtual_machine_scale_set/handler.go b/internal/drawio/handlers/virtual_machine_scale_set/handler.go index f17dad4..40f74f6 100644 --- a/internal/drawio/handlers/virtual_machine_scale_set/handler.go +++ b/internal/drawio/handlers/virtual_machine_scale_set/handler.go @@ -38,22 +38,7 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - arrows := []*node.Arrow{} - - sourceId := (*resource_map)[source.Id].Node.Id() - - for _, target := range targets { - // don't draw arrows to subnets - if target.Type == types.SUBNET { - continue - } - - targetId := (*resource_map)[target.Id].Node.Id() - - arrows = append(arrows, node.NewArrow(sourceId, targetId, nil)) - } - - return arrows + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(_ *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { diff --git a/internal/drawio/handlers/virtual_network/handler.go b/internal/drawio/handlers/virtual_network/handler.go index 8ebf793..dfb1e6b 100644 --- a/internal/drawio/handlers/virtual_network/handler.go +++ b/internal/drawio/handlers/virtual_network/handler.go @@ -53,11 +53,11 @@ func (*handler) PostProcessIcon(resource *node.ResourceAndNode, resource_map *ma } func (*handler) DrawDependency(source *models.Resource, targets []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Arrow { - return []*node.Arrow{} + return node.DrawDependencyArrowsToTarget(source, targets, resource_map, []string{}) } func (*handler) GroupResources(vnet *models.Resource, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { - subnets := getAllSubnetsInVnet(vnet.Id, resources, resource_map) + subnets := getAllResourcesInVnet(vnet.Id, resources, resource_map) vnetNode := (*resource_map)[vnet.Id].Node vnetNodegeometry := vnetNode.GetGeometry() @@ -78,12 +78,8 @@ func (*handler) GroupResources(vnet *models.Resource, resources []*models.Resour return []*node.Node{box} } -func getAllSubnetsInVnet(vnetId string, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { +func getAllResourcesInVnet(vnetId string, resources []*models.Resource, resource_map *map[string]*node.ResourceAndNode) []*node.Node { subnets := list.Filter(resources, func(r *models.Resource) bool { - if r.Type != types.SUBNET { - return false - } - return list.Contains(r.DependsOn, func(dependency string) bool { return dependency == vnetId }) diff --git a/internal/drawio/images/images.go b/internal/drawio/images/images.go index 9b56fef..8f04268 100644 --- a/internal/drawio/images/images.go +++ b/internal/drawio/images/images.go @@ -1,6 +1,7 @@ package images const ( + AI_SERVICES = "img/lib/azure2/ai_machine_learning/AI_Studio.svg" APP_SERVICE = "img/lib/azure2/app_services/App_Services.svg" APP_SERVICE_PLAN = "img/lib/azure2/app_services/App_Service_Plans.svg" APPLICATION_GATEWAY = "img/lib/azure2/networking/Application_Gateways.svg" @@ -19,6 +20,7 @@ const ( LOAD_BALANCER_FRONTEND = PUBLIC_IP_ADDRESS LOG_ANALYTICS = "img/lib/azure2/management_governance/Log_Analytics_Workspaces.svg" LOGIC_APP = "img/lib/azure2/integration/Logic_Apps.svg" + MACHINE_LEARNING_WORKSPACE = "img/lib/azure2/ai_machine_learning/Machine_Learning.svg" NAT_GATEWAY = "img/lib/azure2/networking/NAT.svg" NETWORK_INTERFACE = "img/lib/azure2/networking/Network_Interfaces.svg" NETWORK_SECURITY_GROUP = "img/lib/azure2/networking/Network_Security_Groups.svg" @@ -29,6 +31,7 @@ const ( PUBLIC_IP_ADDRESS = "img/lib/azure2/networking/Public_IP_Addresses.svg" RECOVERY_SERVICE_VAULT = "img/lib/azure2/storage/Recovery_Services_Vaults.svg" REDIS = "img/lib/azure2/databases/Cache_Redis.svg" + SEARCH_SERVICE = "img/lib/azure2/app_services/Search_Services.svg" SIGNALR = "img/lib/azure2/web/SignalR.svg" SUBSCRIPTION = "img/lib/azure2/general/Subscriptions.svg" SQL_DATABASE = "img/lib/azure2/databases/SQL_Database.svg" diff --git a/internal/drawio/types/types.go b/internal/drawio/types/types.go index 4304777..0c32b65 100644 --- a/internal/drawio/types/types.go +++ b/internal/drawio/types/types.go @@ -1,6 +1,7 @@ package types const ( + AI_SERVICES = "AI_SERVICES" APP_SERVICE = "APP_SERVICE" APP_SERVICE_PLAN = "APP_SERVICE_PLAN" APPLICATION_GATEWAY = "APPLICATION_GATEWAY" @@ -20,6 +21,7 @@ const ( LOAD_BALANCER_FRONTEND = "LOAD_BALANCER_FRONTEND" LOG_ANALYTICS = "LOG_ANALYTICS" LOGIC_APP = "LOGIC_APP" + MACHINE_LEARNING_WORKSPACE = "MACHINE_LEARNING_WORKSPACE" NAT_GATEWAY = "NAT_GATEWAY" NETWORK_INTERFACE = "NETWORK_INTERFACE" NETWORK_SECURITY_GROUP = "NETWORK_SECURITY_GROUP" @@ -32,6 +34,7 @@ const ( REDIS = "REDIS" SIGNALR = "SIGNALR" ROUTE_TABLE = "ROUTE_TABLE" + SEARCH_SERVICE = "SEARCH_SERVICE" SQL_DATABASE = "SQL_DATABASE" SQL_SERVER = "SQL_SERVER" STATIC_WEB_APP = "STATIC_WEB_APP" diff --git a/internal/list/list.go b/internal/list/list.go index fe7bd74..308b75b 100644 --- a/internal/list/list.go +++ b/internal/list/list.go @@ -63,3 +63,13 @@ func Fold[T, K any](v []T, acc K, f func(T, K) K) K { } return acc } + +func GroupBy[T any](v []T, f func(T) bool) ([]T, []T) { + bucketA := Filter(v, f) + + bucketB := Filter(v, func(e T) bool { + return !f(e) + }) + + return bucketA, bucketB +} diff --git a/internal/marshall/marshall.go b/internal/marshall/marshall.go index 32d9c26..3a8bc90 100644 --- a/internal/marshall/marshall.go +++ b/internal/marshall/marshall.go @@ -1,25 +1,24 @@ package marshall import ( - "cloudsketch/internal/drawio/models" "encoding/json" "errors" "log" "os" ) -func UnmarshalIfExists(file string) ([]*models.Resource, bool) { +func UnmarshalIfExists[T any](file string) (*T, bool) { if !FileExists(file) { return nil, false } - resources, err := UnmarshallResources(file) + r, err := UnmarshallResources[T](file) if err != nil { panic(err) } - return resources, true + return r, true } func FileExists(file string) bool { @@ -28,8 +27,8 @@ func FileExists(file string) bool { return !errors.Is(err, os.ErrNotExist) } -func MarshallResources(file string, resources []*models.Resource) error { - bytes, err := json.MarshalIndent(resources, "", "\t") +func MarshallResources[T any](file string, r T) error { + bytes, err := json.MarshalIndent(r, "", "\t") if err != nil { log.Fatal(err) @@ -48,16 +47,16 @@ func MarshallResources(file string, resources []*models.Resource) error { return err } -func UnmarshallResources(file string) ([]*models.Resource, error) { +func UnmarshallResources[T any](file string) (*T, error) { bytes, err := os.ReadFile(file) if err != nil { log.Fatal(err) } - var resources []*models.Resource + var r *T - err = json.Unmarshal(bytes, &resources) + err = json.Unmarshal(bytes, &r) - return resources, err + return r, err } diff --git a/internal/providers/azure/handlers/private_dns_zone/handler.go b/internal/providers/azure/handlers/private_dns_zone/handler.go index cd382c2..ef3e65d 100644 --- a/internal/providers/azure/handlers/private_dns_zone/handler.go +++ b/internal/providers/azure/handlers/private_dns_zone/handler.go @@ -23,24 +23,22 @@ func (h *handler) Handle(ctx *azContext.Context) ([]*models.Resource, error) { return nil, err } - client := clientFactory.NewPrivateZonesClient() - - dns_zone, err := client.Get(context.Background(), ctx.ResourceGroupName, ctx.ResourceName, nil) + dnsZone, err := clientFactory.NewPrivateZonesClient().Get(context.Background(), ctx.ResourceGroupName, ctx.ResourceName, nil) if err != nil { return nil, err } resource := &models.Resource{ - Id: *dns_zone.ID, - Name: *dns_zone.Name, - Type: *dns_zone.Type, + Id: *dnsZone.ID, + Name: *dnsZone.Name, + Type: *dnsZone.Type, DependsOn: []string{}, } resources := []*models.Resource{resource} - records, err := getRecordSet(clientFactory, ctx, dns_zone.ID) + records, err := getRecordSet(clientFactory, ctx, *dnsZone.ID) if err != nil { return nil, err @@ -48,10 +46,38 @@ func (h *handler) Handle(ctx *azContext.Context) ([]*models.Resource, error) { resources = append(resources, records...) + vnetLinks, err := getVnetLinks(clientFactory, ctx, *dnsZone.Name) + + if err != nil { + return nil, err + } + + resource.DependsOn = append(resource.DependsOn, vnetLinks...) + return resources, nil } -func getRecordSet(clientFactory *armprivatedns.ClientFactory, ctx *azContext.Context, dnsZoneId *string) ([]*models.Resource, error) { +func getVnetLinks(clientFactory *armprivatedns.ClientFactory, ctx *azContext.Context, dnsZoneName string) ([]string, error) { + pager := clientFactory.NewVirtualNetworkLinksClient().NewListPager(ctx.ResourceGroupName, dnsZoneName, nil) + + var links []*armprivatedns.VirtualNetworkLink + for pager.More() { + resp, err := pager.NextPage(context.Background()) + if err != nil { + return nil, err + } + + if resp.VirtualNetworkLinkListResult.Value != nil { + links = append(links, resp.VirtualNetworkLinkListResult.Value...) + } + } + + return list.Map(links, func(l *armprivatedns.VirtualNetworkLink) string { + return *l.Properties.VirtualNetwork.ID + }), nil +} + +func getRecordSet(clientFactory *armprivatedns.ClientFactory, ctx *azContext.Context, dnsZoneId string) ([]*models.Resource, error) { client := clientFactory.NewRecordSetsClient() pager := client.NewListPager(ctx.ResourceGroupName, ctx.ResourceName, nil) @@ -73,7 +99,7 @@ func getRecordSet(clientFactory *armprivatedns.ClientFactory, ctx *azContext.Con Id: *record.ID, Name: *record.Name, Type: types.DNS_RECORD, - DependsOn: []string{*dnsZoneId}, + DependsOn: []string{dnsZoneId}, } }) diff --git a/internal/providers/azure/provider.go b/internal/providers/azure/provider.go index 9c8f164..d146bf2 100644 --- a/internal/providers/azure/provider.go +++ b/internal/providers/azure/provider.go @@ -85,12 +85,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(filenameWithSuffix) + cachedResources, ok := marshall.UnmarshalIfExists[[]*domainModels.Resource](filenameWithSuffix) if ok { log.Printf("using existing file %s\n", filenameWithSuffix) - return cachedResources, filename, nil + return *cachedResources, filename, nil } allResources, err := resource_group.New().Handle(ctx) @@ -179,6 +179,7 @@ func generateAzurePortalLink(resource *models.Resource, tenant string) string { func mapTypeToDomainType(azType string, seen_unhandled_types *set.Set[string]) string { domainTypes := map[string]string{ + types.AI_SERVICES: domainTypes.AI_SERVICES, types.APP_SERVICE: domainTypes.APP_SERVICE, types.APP_SERVICE_PLAN: domainTypes.APP_SERVICE_PLAN, types.APPLICATION_GATEWAY: domainTypes.APPLICATION_GATEWAY, @@ -198,6 +199,7 @@ func mapTypeToDomainType(azType string, seen_unhandled_types *set.Set[string]) s types.LOAD_BALANCER_FRONTEND: domainTypes.LOAD_BALANCER_FRONTEND, types.LOG_ANALYTICS: domainTypes.LOG_ANALYTICS, types.LOGIC_APP: domainTypes.LOGIC_APP, + types.MACHINE_LEARNING_WORKSPACE: domainTypes.MACHINE_LEARNING_WORKSPACE, types.NAT_GATEWAY: domainTypes.NAT_GATEWAY, types.NETWORK_INTERFACE: domainTypes.NETWORK_INTERFACE, types.NETWORK_SECURITY_GROUP: domainTypes.NETWORK_SECURITY_GROUP, @@ -209,6 +211,7 @@ func mapTypeToDomainType(azType string, seen_unhandled_types *set.Set[string]) s types.RECOVERY_SERVICE_VAULT: domainTypes.RECOVERY_SERVICE_VAULT, types.REDIS: domainTypes.REDIS, types.ROUTE_TABLE: domainTypes.ROUTE_TABLE, + types.SEARCH_SERVICE: domainTypes.SEARCH_SERVICE, types.SIGNALR: domainTypes.SIGNALR, types.SQL_DATABASE: domainTypes.SQL_DATABASE, types.SQL_SERVER: domainTypes.SQL_SERVER, diff --git a/internal/providers/azure/types/types.go b/internal/providers/azure/types/types.go index c72661c..61ac0b3 100644 --- a/internal/providers/azure/types/types.go +++ b/internal/providers/azure/types/types.go @@ -1,6 +1,7 @@ package types const ( + AI_SERVICES = "Microsoft.CognitiveServices/accounts" APP_SERVICE = "Cloudsketch/appservice" APP_SERVICE_PLAN = "Microsoft.Web/serverFarms" APPLICATION_GATEWAY = "Microsoft.Network/applicationGateways" @@ -20,6 +21,7 @@ const ( LOAD_BALANCER_FRONTEND = "Microsoft.Network/loadBalancers/frontendIPConfigurations" LOG_ANALYTICS = "Microsoft.OperationalInsights/workspaces" LOGIC_APP = "Cloudsketch/logicapp" + MACHINE_LEARNING_WORKSPACE = "Microsoft.MachineLearningServices/workspaces" NAT_GATEWAY = "Microsoft.Network/natGateways" NETWORK_INTERFACE = "Microsoft.Network/networkInterfaces" NETWORK_SECURITY_GROUP = "Microsoft.Network/networkSecurityGroups" @@ -31,6 +33,7 @@ const ( RECOVERY_SERVICE_VAULT = "Microsoft.RecoveryServices/vaults" REDIS = "Microsoft.Cache/Redis" ROUTE_TABLE = "Microsoft.Network/routeTables" + SEARCH_SERVICE = "Microsoft.Search/searchServices" SIGNALR = "Microsoft.SignalRService/SignalR" SQL_DATABASE = "Microsoft.Sql/servers/databases" SQL_SERVER = "Microsoft.Sql/servers" diff --git a/main.go b/main.go index 028f306..fa74420 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "cloudsketch/internal/drawio" + "cloudsketch/internal/drawio/models" "cloudsketch/internal/marshall" "cloudsketch/internal/providers/azure" "context" @@ -51,7 +52,7 @@ func main() { log.Printf("using existing file %s\n", file) - resources, err := marshall.UnmarshallResources(file) + resources, err := marshall.UnmarshallResources[[]*models.Resource](file) if err != nil { return err @@ -59,7 +60,7 @@ func main() { outFile := strings.ReplaceAll(file, ".json", ".drawio") - return drawio.New().WriteDiagram(outFile, resources) + return drawio.New().WriteDiagram(outFile, *resources) } // otherwise treat it as a subscription id