Skip to content

Commit 4b9b718

Browse files
authored
[azure][feat] Add WebApp (#2164)
1 parent 00b9581 commit 4b9b718

26 files changed

+2723
-297
lines changed

plugins/azure/fix_plugin_azure/collector.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from typing import Any, Optional, Type, List, Dict
66

77
from azure.core.utils import CaseInsensitiveDict
8+
89
from fix_plugin_azure.azure_client import MicrosoftClient, RestApiSpec
910
from fix_plugin_azure.config import AzureConfig, AzureCredentials
1011
from fix_plugin_azure.resource.authorization import resources as authorization_resources
@@ -22,27 +23,28 @@
2223
resources as compute_resources,
2324
)
2425
from fix_plugin_azure.resource.containerservice import resources as aks_resources
25-
from fix_plugin_azure.resource.security import resources as security_resources
26+
from fix_plugin_azure.resource.keyvault import resources as keyvault_resources
2627
from fix_plugin_azure.resource.microsoft_graph import (
2728
MicrosoftGraphOrganization,
2829
resources as graph_resources,
2930
MicrosoftGraphOrganizationRoot,
3031
)
3132
from fix_plugin_azure.resource.monitor import resources as monitor_resources
33+
from fix_plugin_azure.resource.mysql import AzureMysqlServerType, resources as mysql_resources
3234
from fix_plugin_azure.resource.network import (
3335
AzureExpressRoutePortsLocation,
3436
AzureNetworkVirtualApplianceSku,
3537
AzureNetworkUsage,
3638
resources as network_resources,
3739
)
38-
from fix_plugin_azure.resource.mysql import AzureMysqlServerType, resources as mysql_resources
39-
from fix_plugin_azure.resource.keyvault import resources as keyvault_resources
40-
from fix_plugin_azure.resource.sql_server import resources as sql_resources
4140
from fix_plugin_azure.resource.postgresql import (
4241
AzurePostgresqlServerType,
4342
resources as postgresql_resources,
4443
)
44+
from fix_plugin_azure.resource.security import resources as security_resources
45+
from fix_plugin_azure.resource.sql_server import resources as sql_resources
4546
from fix_plugin_azure.resource.storage import AzureStorageAccountUsage, AzureStorageSku, resources as storage_resources
47+
from fix_plugin_azure.resource.web import resources as web_resources
4648
from fixlib.baseresources import Cloud, GraphRoot, BaseAccount, BaseRegion
4749
from fixlib.core.actions import CoreFeedback, ErrorAccumulator
4850
from fixlib.graph import Graph
@@ -61,17 +63,18 @@ def resource_with_params(clazz: Type[MicrosoftResource], param: str) -> bool:
6163

6264
subscription_resources: List[Type[MicrosoftResource]] = (
6365
base_resources
66+
+ aks_resources
6467
+ authorization_resources
6568
+ compute_resources
69+
+ keyvault_resources
70+
+ monitor_resources
71+
+ mysql_resources
6672
+ network_resources
67-
+ aks_resources
73+
+ postgresql_resources
6874
+ security_resources
69-
+ storage_resources
7075
+ sql_resources
71-
+ mysql_resources
72-
+ postgresql_resources
73-
+ monitor_resources
74-
+ keyvault_resources
76+
+ storage_resources
77+
+ web_resources
7578
)
7679
all_resources = subscription_resources + graph_resources # defines all resource kinds. used in model check
7780

plugins/azure/fix_plugin_azure/resource/authorization.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import re
12
from datetime import datetime
23
from typing import ClassVar, Dict, Optional, List, Type
34

@@ -8,6 +9,7 @@
89
MicrosoftResource,
910
GraphBuilder,
1011
AzureSubscription,
12+
AzureSystemData,
1113
)
1214
from fix_plugin_azure.resource.microsoft_graph import (
1315
MicrosoftGraphUser,
@@ -18,7 +20,7 @@
1820
)
1921
from fixlib.baseresources import BaseRole, ModelReference
2022
from fixlib.graph import BySearchCriteria
21-
from fixlib.json_bender import Bender, S, ForallBend
23+
from fixlib.json_bender import Bender, S, ForallBend, Bend
2224
from fixlib.types import Json
2325

2426

@@ -239,8 +241,42 @@ class AzureRoleDefinition(MicrosoftResource, BaseRole):
239241
updated_on: Optional[datetime] = field(default=None, metadata={"description": "Time it was updated"})
240242

241243

244+
@define(eq=False, slots=False)
245+
class AzureManagementLock(MicrosoftResource):
246+
kind: ClassVar[str] = "azure_management_lock"
247+
api_spec: ClassVar[AzureResourceSpec] = AzureResourceSpec(
248+
service="resources",
249+
version="2020-05-01",
250+
path="/subscriptions/{subscriptionId}/providers/Microsoft.Authorization/locks",
251+
path_parameters=["subscriptionId"],
252+
query_parameters=["api-version"],
253+
access_path="value",
254+
expect_array=True,
255+
)
256+
mapping: ClassVar[Dict[str, Bender]] = {
257+
"id": S("id"),
258+
"tags": S("tags", default={}),
259+
"name": S("name"),
260+
"ctime": S("systemData", "createdAt"),
261+
"mtime": S("systemData", "lastModifiedAt"),
262+
"level": S("properties", "level"),
263+
"notes": S("properties", "notes"),
264+
"owners": S("properties") >> S("owners", default=[]) >> ForallBend(S("applicationId")),
265+
"system_data": S("systemData") >> Bend(AzureSystemData.mapping),
266+
}
267+
level: Optional[str] = field(default=None, metadata={'description': 'The level of the lock. Possible values are: NotSpecified, CanNotDelete, ReadOnly. CanNotDelete means authorized users are able to read and modify the resources, but not delete. ReadOnly means authorized users can only read from a resource, but they can t modify or delete it.'}) # fmt: skip
268+
notes: Optional[str] = field(default=None, metadata={'description': 'Notes about the lock. Maximum of 512 characters.'}) # fmt: skip
269+
owners: Optional[List[str]] = field(default=None, metadata={"description": "The owners of the lock."})
270+
system_data: Optional[AzureSystemData] = field(default=None, metadata={'description': 'Metadata pertaining to creation and last modification of the resource.'}) # fmt: skip
271+
272+
def connect_in_graph(self, builder: GraphBuilder, source: Json) -> None:
273+
resource_id = re.sub(r"/providers/Microsoft.Authorization/locks/.*$", "", self.id)
274+
builder.add_edge(self, id=resource_id)
275+
276+
242277
resources: List[Type[MicrosoftResource]] = [
243278
AzureDenyAssignment,
279+
AzureManagementLock,
244280
AzureRoleAssignment,
245281
AzureRoleDefinition,
246282
]

plugins/azure/fix_plugin_azure/resource/base.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ class AzureProxyResource:
629629

630630

631631
@define(eq=False, slots=False)
632-
class AzureIdentity:
632+
class AzureManagedServiceIdentity:
633633
kind: ClassVar[str] = "azure_identity"
634634
mapping: ClassVar[Dict[str, Bender]] = {
635635
"client_id": S("clientId"),
@@ -645,15 +645,44 @@ class AzureIdentity:
645645
user_assigned_identities: Optional[Dict[str, AzureUserAssignedIdentity]] = field(default=None, metadata={'description': 'The list of user identities associated with the resource. The user identity dictionary key references will be ARM resource ids in the form: /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identityName} .'}) # fmt: skip
646646

647647

648+
@define(eq=False, slots=False)
649+
class AzureSkuCapacity:
650+
kind: ClassVar[str] = "azure_sku_capacity"
651+
mapping: ClassVar[Dict[str, Bender]] = {
652+
"default": S("default"),
653+
"elastic_maximum": S("elasticMaximum"),
654+
"maximum": S("maximum"),
655+
"minimum": S("minimum"),
656+
"scale_type": S("scaleType"),
657+
}
658+
default: Optional[int] = field(default=None, metadata={'description': 'Default number of workers for this App Service plan SKU.'}) # fmt: skip
659+
elastic_maximum: Optional[int] = field(default=None, metadata={'description': 'Maximum number of Elastic workers for this App Service plan SKU.'}) # fmt: skip
660+
maximum: Optional[int] = field(default=None, metadata={'description': 'Maximum number of workers for this App Service plan SKU.'}) # fmt: skip
661+
minimum: Optional[int] = field(default=None, metadata={'description': 'Minimum number of workers for this App Service plan SKU.'}) # fmt: skip
662+
scale_type: Optional[str] = field(default=None, metadata={'description': 'Available scale configurations for an App Service plan.'}) # fmt: skip
663+
664+
665+
@define(eq=False, slots=False)
666+
class AzureCapability:
667+
kind: ClassVar[str] = "azure_capability"
668+
mapping: ClassVar[Dict[str, Bender]] = {"name": S("name"), "reason": S("reason"), "value": S("value")}
669+
name: Optional[str] = field(default=None, metadata={"description": "Name of the SKU capability."})
670+
reason: Optional[str] = field(default=None, metadata={"description": "Reason of the SKU capability."})
671+
value: Optional[str] = field(default=None, metadata={"description": "Value of the SKU capability."})
672+
673+
648674
@define(eq=False, slots=False)
649675
class AzureSku:
650676
kind: ClassVar[str] = "azure_sku"
651677
mapping: ClassVar[Dict[str, Bender]] = {
678+
"capabilities": S("capabilities") >> ForallBend(AzureCapability.mapping),
652679
"capacity": S("capacity"),
653680
"name": S("name"),
654681
"tier": S("tier"),
655682
"family": S("family"),
656683
"size": S("size"),
684+
"locations": S("locations"),
685+
"sku_capacity": S("skuCapacity") >> Bend(AzureSkuCapacity.mapping),
657686
}
658687
capacity: Optional[int] = field(default=None, metadata={'description': 'Specifies the number of virtual machines in the scale set.'}) # fmt: skip
659688
family: Optional[str] = field(default=None, metadata={"description": "The family of the sku."})
@@ -662,6 +691,29 @@ class AzureSku:
662691
size: Optional[str] = field(default=None, metadata={"description": "Size of the particular SKU"})
663692

664693

694+
@define(eq=False, slots=False)
695+
class AzurePrivateEndpointConnection:
696+
kind: ClassVar[str] = "azure_private_endpoint_connection"
697+
mapping: ClassVar[Dict[str, Bender]] = {
698+
"group_ids": S("properties", "groupIds"),
699+
"id": S("id"),
700+
"name": S("name"),
701+
"private_endpoint": S("properties", "privateEndpoint", "id"),
702+
"private_link_service_connection_state": S("properties", "privateLinkServiceConnectionState")
703+
>> Bend(AzurePrivateLinkServiceConnectionState.mapping),
704+
"provisioning_state": S("properties", "provisioningState"),
705+
"system_data": S("systemData") >> Bend(AzureSystemData.mapping),
706+
"type": S("type"),
707+
}
708+
group_ids: Optional[List[str]] = field(default=None, metadata={'description': 'The group ids for the private endpoint resource.'}) # fmt: skip
709+
id: Optional[str] = field(default=None, metadata={'description': 'Fully qualified resource ID for the resource. E.g. /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName} '}) # fmt: skip
710+
name: Optional[str] = field(default=None, metadata={"description": "The name of the resource"})
711+
private_endpoint: Optional[str] = field(default=None, metadata={"description": "The private endpoint resource."})
712+
private_link_service_connection_state: Optional[AzurePrivateLinkServiceConnectionState] = field(default=None, metadata={'description': 'A collection of information about the state of the connection between service consumer and provider.'}) # fmt: skip
713+
system_data: Optional[AzureSystemData] = field(default=None, metadata={'description': 'Metadata pertaining to creation and last modification of the resource.'}) # fmt: skip
714+
type: Optional[str] = field(default=None, metadata={'description': 'The type of the resource. E.g. Microsoft.Compute/virtualMachines or Microsoft.Storage/storageAccounts '}) # fmt: skip
715+
716+
665717
class GraphBuilder:
666718
def __init__(
667719
self,

plugins/azure/fix_plugin_azure/resource/compute.py

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
AzureSku,
1616
AzureExtendedLocation,
1717
AzurePrincipalClient,
18-
AzurePrivateLinkServiceConnectionState,
18+
AzurePrivateEndpointConnection,
1919
)
2020
from fix_plugin_azure.resource.metrics import AzureMetricData, AzureMetricQuery, update_resource_metrics
2121
from fix_plugin_azure.resource.network import (
@@ -1211,26 +1211,6 @@ def connect_in_graph(self, builder: GraphBuilder, source: Json) -> None:
12111211
builder.add_edge(self, edge_type=EdgeType.default, clazz=AzureDiskEncryptionSet, id=disk_en_set_id)
12121212

12131213

1214-
@define(eq=False, slots=False)
1215-
class AzureDiskAccessPrivateEndpointConnection:
1216-
kind: ClassVar[str] = "azure_disk_access_private_endpoint_connection"
1217-
mapping: ClassVar[Dict[str, Bender]] = {
1218-
"id": S("id"),
1219-
"name": S("name"),
1220-
"private_endpoint": S("properties", "privateEndpoint", "id"),
1221-
"private_link_service_connection_state": S("properties", "privateLinkServiceConnectionState")
1222-
>> Bend(AzurePrivateLinkServiceConnectionState.mapping),
1223-
"provisioning_state": S("properties", "provisioningState"),
1224-
"type": S("type"),
1225-
}
1226-
id: Optional[str] = field(default=None, metadata={"description": "Private endpoint connection id."})
1227-
name: Optional[str] = field(default=None, metadata={"description": "Private endpoint connection name."})
1228-
private_endpoint: Optional[str] = field(default=None, metadata={"description": "The private endpoint resource."})
1229-
private_link_service_connection_state: Optional[AzurePrivateLinkServiceConnectionState] = field(default=None, metadata={'description': 'A collection of information about the state of the connection between service consumer and provider.'}) # fmt: skip
1230-
provisioning_state: Optional[str] = field(default=None, metadata={'description': 'The current provisioning state.'}) # fmt: skip
1231-
type: Optional[str] = field(default=None, metadata={"description": "Private endpoint connection type."})
1232-
1233-
12341214
@define(eq=False, slots=False)
12351215
class AzureDiskAccess(MicrosoftResource):
12361216
kind: ClassVar[str] = "azure_disk_access"
@@ -1250,12 +1230,12 @@ class AzureDiskAccess(MicrosoftResource):
12501230
"ctime": S("time_created"),
12511231
"extended_location": S("extendedLocation") >> Bend(AzureExtendedLocation.mapping),
12521232
"private_endpoint_connections": S("properties", "privateEndpointConnections")
1253-
>> ForallBend(AzureDiskAccessPrivateEndpointConnection.mapping),
1233+
>> ForallBend(AzurePrivateEndpointConnection.mapping),
12541234
"provisioning_state": S("properties", "provisioningState"),
12551235
"time_created": S("properties", "timeCreated"),
12561236
}
12571237
extended_location: Optional[AzureExtendedLocation] = field(default=None, metadata={'description': 'The complex type of the extended location.'}) # fmt: skip
1258-
private_endpoint_connections: Optional[List[AzureDiskAccessPrivateEndpointConnection]] = field(default=None, metadata={'description': 'A readonly collection of private endpoint connections created on the disk. Currently only one endpoint connection is supported.'}) # fmt: skip
1238+
private_endpoint_connections: Optional[List[AzurePrivateEndpointConnection]] = field(default=None, metadata={'description': 'A readonly collection of private endpoint connections created on the disk. Currently only one endpoint connection is supported.'}) # fmt: skip
12591239
time_created: Optional[datetime] = field(default=None, metadata={'description': 'The time when the disk access was created.'}) # fmt: skip
12601240

12611241

plugins/azure/fix_plugin_azure/resource/containerservice.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
AzureExtendedLocation,
1313
AzureUserAssignedIdentity,
1414
AzurePrincipalClient,
15-
AzureIdentity,
15+
AzureManagedServiceIdentity,
1616
)
1717
from fixlib.baseresources import BaseManagedKubernetesClusterProvider, BaseSnapshot, EdgeType, ModelReference
1818
from fixlib.json_bender import Bender, S, Bend, ForallBend
@@ -86,12 +86,12 @@ class AzureFleet(MicrosoftResource):
8686
"e_tag": S("eTag"),
8787
"resource_group": S("resourceGroup"),
8888
"hub_profile": S("properties", "hubProfile") >> Bend(AzureFleetHubProfile.mapping),
89-
"azure_fleet_identity": S("identity") >> Bend(AzureIdentity.mapping),
89+
"azure_fleet_identity": S("identity") >> Bend(AzureManagedServiceIdentity.mapping),
9090
"provisioning_state": S("properties", "provisioningState"),
9191
}
9292
e_tag: Optional[str] = field(default=None, metadata={'description': 'If eTag is provided in the response body, it may also be provided as a header per the normal etag convention. Entity tags are used for comparing two or more entities from the same requested resource. HTTP/1.1 uses entity tags in the etag (section 14.19), If-Match (section 14.24), If-None-Match (section 14.26), and If-Range (section 14.27) header fields.'}) # fmt: skip
9393
hub_profile: Optional[AzureFleetHubProfile] = field(default=None, metadata={'description': 'The FleetHubProfile configures the fleet hub.'}) # fmt: skip
94-
azure_fleet_identity: Optional[AzureIdentity] = field(default=None, metadata={'description': 'Managed service identity (system assigned and/or user assigned identities)'}) # fmt: skip
94+
azure_fleet_identity: Optional[AzureManagedServiceIdentity] = field(default=None, metadata={'description': 'Managed service identity (system assigned and/or user assigned identities)'}) # fmt: skip
9595
resource_group: Optional[str] = field(default=None, metadata={"description": "Resource group name"})
9696
_cluster_resource_ids: Optional[List[str]] = field(
9797
default=None, metadata={"description": "Reference to the cluster IDs"}

0 commit comments

Comments
 (0)