Skip to content

Commit

Permalink
[azure] [fix] Fixed collecting network resources + added tests (#1810)
Browse files Browse the repository at this point in the history
  • Loading branch information
1101-1 committed Oct 30, 2023
1 parent 827a778 commit b4c4fb1
Show file tree
Hide file tree
Showing 42 changed files with 3,619 additions and 16 deletions.
3 changes: 2 additions & 1 deletion plugins/azure/resoto_plugin_azure/collector.py
Expand Up @@ -12,6 +12,7 @@
AzureResource,
resources as base_resources,
)
from resoto_plugin_azure.resource.network import resources as network_resources
from resotolib.baseresources import Cloud, GraphRoot
from resotolib.core.actions import CoreFeedback
from resotolib.graph import Graph
Expand All @@ -27,7 +28,7 @@ def resource_with_params(clazz: Type[AzureResource], params: Set[str], includes_
return cp.issubset(params) and (not includes_all or params.issubset(cp))


all_resources: List[Type[AzureResource]] = base_resources + compute_resources
all_resources: List[Type[AzureResource]] = base_resources + compute_resources + network_resources
global_resources = [r for r in all_resources if resource_with_params(r, {"subscriptionId"})]
regional_resources = [r for r in all_resources if resource_with_params(r, {"subscriptionId", "location"}, True)]

Expand Down
9 changes: 5 additions & 4 deletions plugins/azure/resoto_plugin_azure/resource/compute.py
Expand Up @@ -2149,8 +2149,8 @@ class AzureVirtualMachineNetworkInterfaceConfiguration:


@define(eq=False, slots=False)
class AzureNetworkProfile:
kind: ClassVar[str] = "azure_network_profile"
class AzureVirtualMachineNetworkProfile:
kind: ClassVar[str] = "azure_virtual_machine_network_profile"
mapping: ClassVar[Dict[str, Bender]] = {
"network_api_version": S("networkApiVersion"),
"network_interface_configurations": S("networkInterfaceConfigurations")
Expand Down Expand Up @@ -2552,7 +2552,8 @@ class AzureVirtualMachine(AzureResource, BaseInstance):
"virtual_machine_instance_view": S("properties", "instanceView")
>> Bend(AzureVirtualMachineInstanceView.mapping),
"license_type": S("properties", "licenseType"),
"virtual_machine_network_profile": S("properties", "networkProfile") >> Bend(AzureNetworkProfile.mapping),
"virtual_machine_network_profile": S("properties", "networkProfile")
>> Bend(AzureVirtualMachineNetworkProfile.mapping),
"virtual_machine_os_profile": S("properties", "osProfile") >> Bend(AzureOSProfile.mapping),
"azure_plan": S("plan") >> Bend(AzurePlan.mapping),
"platform_fault_domain": S("properties", "platformFaultDomain"),
Expand Down Expand Up @@ -2587,7 +2588,7 @@ class AzureVirtualMachine(AzureResource, BaseInstance):
virtual_machine_identity: Optional[AzureVirtualMachineIdentity] = field(default=None, metadata={'description': 'Identity for the virtual machine.'}) # fmt: skip
virtual_machine_instance_view: Optional[AzureVirtualMachineInstanceView] = field(default=None, metadata={'description': 'The instance view of a virtual machine.'}) # fmt: skip
license_type: Optional[str] = field(default=None, metadata={'description': 'Specifies that the image or disk that is being used was licensed on-premises. Possible values for windows server operating system are: windows_client windows_server possible values for linux server operating system are: rhel_byos (for rhel) sles_byos (for suse) for more information, see [azure hybrid use benefit for windows server](https://docs. Microsoft. Com/azure/virtual-machines/windows/hybrid-use-benefit-licensing) [azure hybrid use benefit for linux server](https://docs. Microsoft. Com/azure/virtual-machines/linux/azure-hybrid-benefit-linux) minimum api-version: 2015-06-15.'}) # fmt: skip
virtual_machine_network_profile: Optional[AzureNetworkProfile] = field(default=None, metadata={'description': 'Specifies the network interfaces or the networking configuration of the virtual machine.'}) # fmt: skip
virtual_machine_network_profile: Optional[AzureVirtualMachineNetworkProfile] = field(default=None, metadata={'description': 'Specifies the network interfaces or the networking configuration of the virtual machine.'}) # fmt: skip
virtual_machine_os_profile: Optional[AzureOSProfile] = field(default=None, metadata={'description': 'Specifies the operating system settings for the virtual machine. Some of the settings cannot be changed once vm is provisioned.'}) # fmt: skip
azure_plan: Optional[AzurePlan] = field(default=None, metadata={'description': 'Specifies information about the marketplace image used to create the virtual machine. This element is only used for marketplace images. Before you can use a marketplace image from an api, you must enable the image for programmatic use. In the azure portal, find the marketplace image that you want to use and then click **want to deploy programmatically, get started ->**. Enter any required information and then click **save**.'}) # fmt: skip
platform_fault_domain: Optional[int] = field(default=None, metadata={'description': 'Specifies the scale set logical fault domain into which the virtual machine will be created. By default, the virtual machine will by automatically assigned to a fault domain that best maintains balance across available fault domains. This is applicable only if the virtualmachinescaleset property of this virtual machine is set. The virtual machine scale set that is referenced, must have platformfaultdomaincount greater than 1. This property cannot be updated once the virtual machine is created. Fault domain assignment can be viewed in the virtual machine instance view. Minimum api‐version: 2020‐12‐01.'}) # fmt: skip
Expand Down
20 changes: 11 additions & 9 deletions plugins/azure/resoto_plugin_azure/resource/network.py
Expand Up @@ -4,7 +4,7 @@

from resoto_plugin_azure.azure_client import AzureApiSpec
from resoto_plugin_azure.resource.base import AzureResource, AzureSubResource, AzureSku
from resotolib.json_bender import Bender, S, Bend, ForallBend, K
from resotolib.json_bender import Bender, S, Bend, ForallBend, K, AsInt, StringToUnitNumber


@define(eq=False, slots=False)
Expand Down Expand Up @@ -1173,15 +1173,13 @@ class AzureAutoApprovedPrivateLinkService(AzureResource):
expect_array=True,
)
mapping: ClassVar[Dict[str, Bender]] = {
"id": K(None),
"id": S("privateLinkService"),
"tags": S("tags", default={}),
"name": K(None),
"ctime": K(None),
"mtime": K(None),
"atime": K(None),
"private_link_service": S("privateLinkService"),
}
private_link_service: Optional[str] = field(default=None, metadata={'description': 'The id of the private link service resource.'}) # fmt: skip


@define(eq=False, slots=False)
Expand Down Expand Up @@ -3242,7 +3240,7 @@ class AzureExpressRoutePort(AzureResource):
"ether_type": S("properties", "etherType"),
"identity": S("identity") >> Bend(AzureManagedServiceIdentity.mapping),
"links": S("properties", "links") >> ForallBend(AzureExpressRouteLink.mapping),
"mtu_string": S("properties", "mtu"), # TODO: check if this string is actually an int?
"mtu": S("properties", "mtu") >> AsInt(),
"peering_location": S("properties", "peeringLocation"),
"provisioned_bandwidth_in_gbps": S("properties", "provisionedBandwidthInGbps"),
"provisioning_state": S("properties", "provisioningState"),
Expand All @@ -3257,7 +3255,7 @@ class AzureExpressRoutePort(AzureResource):
ether_type: Optional[str] = field(default=None, metadata={"description": "Ether type of the physical port."})
identity: Optional[AzureManagedServiceIdentity] = field(default=None, metadata={'description': 'Identity for the resource.'}) # fmt: skip
links: Optional[List[AzureExpressRouteLink]] = field(default=None, metadata={'description': 'The set of physical links of the ExpressRoutePort resource.'}) # fmt: skip
mtu_string: Optional[str] = field(default=None, metadata={'description': 'Maximum transmission unit of the physical port pair(s).'}) # fmt: skip
mtu: Optional[int] = field(default=None, metadata={'description': 'Maximum transmission unit of the physical port pair(s).'}) # fmt: skip
peering_location: Optional[str] = field(default=None, metadata={'description': 'The name of the peering location that the ExpressRoutePort is mapped to physically.'}) # fmt: skip
provisioned_bandwidth_in_gbps: Optional[float] = field(default=None, metadata={'description': 'Aggregate Gbps of associated circuit bandwidths.'}) # fmt: skip
provisioning_state: Optional[str] = field(default=None, metadata={'description': 'The current provisioning state.'}) # fmt: skip
Expand Down Expand Up @@ -3491,7 +3489,7 @@ class AzureFirewallPolicy(AzureResource):
>> Bend(AzureFirewallPolicyIntrusionDetection.mapping),
"provisioning_state": S("properties", "provisioningState"),
"rule_collection_groups": S("properties") >> S("ruleCollectionGroups", default=[]) >> ForallBend(S("id")),
"size_string": S("properties", "size"), # TODO: check if this is actually an int?
"size": S("properties", "size") >> StringToUnitNumber("B", expected=int),
"sku": S("properties", "sku", "tier"),
"snat": S("properties", "snat") >> Bend(AzureFirewallPolicySNAT.mapping),
"sql": S("properties", "sql", "allowSqlRedirect"),
Expand All @@ -3512,7 +3510,7 @@ class AzureFirewallPolicy(AzureResource):
intrusion_detection: Optional[AzureFirewallPolicyIntrusionDetection] = field(default=None, metadata={'description': 'Configuration for intrusion detection mode and rules.'}) # fmt: skip
provisioning_state: Optional[str] = field(default=None, metadata={'description': 'The current provisioning state.'}) # fmt: skip
rule_collection_groups: Optional[List[str]] = field(default=None, metadata={'description': 'List of references to FirewallPolicyRuleCollectionGroups.'}) # fmt: skip
size_string: Optional[str] = field(default=None, metadata={'description': 'A read-only string that represents the size of the FirewallPolicyPropertiesFormat in MB. (ex 0.5MB)'}) # fmt: skip
size: Optional[int] = field(default=None, metadata={'description': 'A read-only string that represents the size of the FirewallPolicyPropertiesFormat in MB. (ex 0.5MB)'}) # fmt: skip
sku: Optional[str] = field(default=None, metadata={"description": "SKU of Firewall policy."})
snat: Optional[AzureFirewallPolicySNAT] = field(default=None, metadata={'description': 'The private IP addresses/IP ranges to which traffic will not be SNAT.'}) # fmt: skip
sql: Optional[bool] = field(default=None, metadata={"description": "SQL Settings in Firewall Policy."})
Expand Down Expand Up @@ -4448,14 +4446,18 @@ class AzureUsage(AzureResource):
mapping: ClassVar[Dict[str, Bender]] = {
"id": S("id"),
"tags": S("tags", default={}),
"name": S("name"),
"name": K(None),
"usage_name": S("name") >> Bend(AzureUsageName.mapping),
"ctime": K(None),
"mtime": K(None),
"atime": K(None),
"current_value": S("currentValue"),
"limit": S("limit"),
"unit": S("unit"),
}
usage_name: Optional[AzureUsageName] = field(
default=None, metadata={"description": "The name of the type of usage."}
)
current_value: Optional[int] = field(default=None, metadata={"description": "The current value of the usage."})
limit: Optional[int] = field(default=None, metadata={"description": "The limit of usage."})
unit: Optional[str] = field(default=None, metadata={"description": "An enum describing the unit of measurement."})
Expand Down
4 changes: 2 additions & 2 deletions plugins/azure/test/collector_test.py
Expand Up @@ -15,5 +15,5 @@ def test_collect(
) -> None:
collector = AzureSubscriptionCollector(config, Cloud(id="azure"), azure_subscription, credentials, core_feedback)
collector.collect()
assert len(collector.graph.nodes) == 62
assert len(collector.graph.edges) == 80
assert len(collector.graph.nodes) == 454
assert len(collector.graph.edges) == 472
@@ -0,0 +1,149 @@
{
"value": [
{
"name": "Policy1",
"id": "/subscriptions/subid/resourceGroups/rg1/providers/Microsoft.Network/ApplicationGatewayWebApplicationFirewallPolicies/Policy1",
"type": "Microsoft.Network/applicationgatewaywebapplicationfirewallpolicies",
"tags": {
"key1": "value1",
"key2": "value2"
},
"location": "WestUs",
"properties": {
"resourceState": "Enabled",
"provisioningState": "Succeeded",
"policySettings": {
"state": "Enabled",
"mode": "Prevention",
"requestBodyEnforcement": true,
"maxRequestBodySizeInKb": 2000,
"requestBodyInspectLimitInKB": 2000,
"fileUploadEnforcement": true,
"fileUploadLimitInMb": 4000,
"requestBodyCheck": true,
"customBlockResponseStatusCode": 405,
"customBlockResponseBody": "SGVsbG8=",
"logScrubbing": {
"state": "Enabled",
"scrubbingRules": [
{
"state": "Enabled",
"matchVariable": "RequestArgNames",
"selectorMatchOperator": "Equals",
"selector": "test"
},
{
"state": "Enabled",
"matchVariable": "RequestIPAddress",
"selectorMatchOperator": "EqualsAny",
"selector": "*"
}
]
}
},
"customRules": [
{
"name": "Rule1",
"priority": 1,
"state": "Enabled",
"ruleType": "MatchRule",
"matchConditions": [
{
"matchVariables": [
{
"variableName": "RemoteAddr",
"selector": null
}
],
"operator": "IPMatch",
"negationConditon": false,
"matchValues": [
"192.168.1.0/24",
"10.0.0.0/24"
],
"transforms": []
}
],
"action": "Block"
},
{
"name": "Rule2",
"priority": 2,
"state": "Enabled",
"ruleType": "MatchRule",
"matchConditions": [
{
"matchVariables": [
{
"variableName": "RemoteAddr",
"selector": null
}
],
"operator": "IPMatch",
"negationConditon": false,
"matchValues": [
"192.168.1.0/24"
]
},
{
"matchVariables": [
{
"variableName": "RequestHeader",
"selector": "UserAgent"
}
],
"operator": "Contains",
"negationConditon": false,
"matchValues": [
"Windows"
]
}
],
"action": "Block"
},
{
"name": "RateLimitRule3",
"priority": 3,
"rateLimitDuration": "OneMin",
"rateLimitThreshold": 10,
"ruleType": "RateLimitRule",
"matchConditions": [
{
"matchVariables": [
{
"variableName": "RemoteAddr",
"selector": null
}
],
"operator": "IPMatch",
"negationConditon": true,
"matchValues": [
"192.168.1.0/24",
"10.0.0.0/24"
]
}
],
"groupByUserSession": [
{
"groupByVariables": [
{
"variableName": "ClientAddr"
}
]
}
],
"action": "Block"
}
],
"managedRules": {
"managedRuleSets": [
{
"ruleSetType": "OWASP",
"ruleSetVersion": "3.2"
}
]
}
}
}
]
}
52 changes: 52 additions & 0 deletions plugins/azure/test/files/network/ExpressRoutePorts.json
@@ -0,0 +1,52 @@
{
"value": [
{
"name": "portName",
"id": "/subscriptions/subid/resourceGroups/rg1/providers/Microsoft.Network/expressRoutePorts/portName",
"type": "Microsoft.Network/expressRoutePorts",
"location": "westus",
"properties": {
"provisioningState": "Succeeded",
"peeringLocation": "peeringLocationName",
"bandwidthInGbps": 100,
"provisionedBandwidthInGbps": 0,
"mtu": "1500",
"encapsulation": "QinQ",
"billingType": "UnlimitedData",
"etherType": "0x8100",
"allocationDate": "Friday, July 1, 2018",
"links": [
{
"id": "/subscriptions/subid/resourceGroups/rg1/providers/Microsoft.Network/expressRoutePorts/portName/links/link1",
"name": "link1",
"properties": {
"provisioningState": "Succeeded",
"routerName": "router1",
"interfaceName": "Ethernet 0/0",
"patchPanelId": "patchPanelId1",
"rackId": "rackId1",
"coloLocation": "coloLocation1",
"connectorType": "LC",
"adminState": "Disabled"
}
},
{
"id": "/subscriptions/subid/resourceGroups/rg1/providers/Microsoft.Network/expressRoutePorts/portName/links/link2",
"name": "link2",
"properties": {
"provisioningState": "Succeeded",
"routerName": "router2",
"interfaceName": "Ethernet 0/0",
"patchPanelId": "patchPanelId2",
"rackId": "rackId2",
"coloLocation": "coloLocation2",
"connectorType": "LC",
"adminState": "Disabled"
}
}
],
"circuits": []
}
}
]
}

0 comments on commit b4c4fb1

Please sign in to comment.