We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
azure add feature to get vm extensions 
**Is your feature request related to a problem? Please describe.**
We need to evaluate the list of extensions deployed on a Azure VM and generate a compliance report.

**Describe the solution you'd like**
Add new filter to retrieve extensions attached to the VM

**Describe alternatives you've considered**
NA

**Additional context**
Resource Type: `Microsoft.Compute/virtualMachines/extensions`
https://docs.microsoft.com/en-us/azure/templates/microsoft.compute/virtualmachines/extensions?tabs=json

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `tools/c7n_azure/c7n_azure/resources/vm.py`
Content:
```
1 # Copyright The Cloud Custodian Authors.
2 # SPDX-License-Identifier: Apache-2.0
3 from azure.mgmt.compute.models import HardwareProfile, VirtualMachineUpdate
4 from c7n_azure.actions.base import AzureBaseAction
5 from c7n_azure.provider import resources
6 from c7n_azure.resources.arm import ArmResourceManager
7 
8 from c7n.filters.core import ValueFilter, type_schema
9 from c7n.filters.related import RelatedResourceFilter
10 
11 
12 @resources.register('vm')
13 class VirtualMachine(ArmResourceManager):
14     """Virtual Machine Resource
15 
16     :example:
17 
18     Stop all running VMs
19 
20     .. code-block:: yaml
21 
22         policies:
23           - name: stop-running-vms
24             resource: azure.vm
25             filters:
26               - type: instance-view
27                 key: statuses[].code
28                 op: in
29                 value_type: swap
30                 value: PowerState/running
31             actions:
32               - type: stop
33 
34     :example:
35 
36     Start all VMs
37 
38     .. code-block:: yaml
39 
40         policies:
41           - name: start-vms
42             resource: azure.vm
43             actions:
44               - type: start
45 
46     :example:
47 
48     Restart all VMs
49 
50     .. code-block:: yaml
51 
52         policies:
53           - name: start-vms
54             resource: azure.vm
55             actions:
56               - type: restart
57 
58     :example:
59 
60     Resize specific VM by name
61 
62     .. code-block:: yaml
63 
64         policies:
65           - name: resize-vm
66             resource: azure.vm
67             filters:
68               - type: value
69                 key: name
70                 op: eq
71                 value_type: normalize
72                 value: fake_vm_name
73             actions:
74               - type: resize
75                 vmSize: Standard_A2_v2
76 
77     :example:
78 
79     Delete specific VM by name
80 
81     .. code-block:: yaml
82 
83         policies:
84           - name: delete-vm
85             resource: azure.vm
86             filters:
87               - type: value
88                 key: name
89                 op: eq
90                 value_type: normalize
91                 value: fake_vm_name
92             actions:
93               - type: delete
94 
95     :example:
96 
97     Find all VMs with a Public IP address
98 
99     .. code-block:: yaml
100 
101         policies:
102           - name: vms-with-public-ip
103             resource: azure.vm
104             filters:
105               - type: network-interface
106                 key: 'properties.ipConfigurations[].properties.publicIPAddress.id'
107                 value: not-null
108 
109     :example:
110 
111     This policy will find all VMs that have Percentage CPU usage >= 75% over the last 72 hours
112 
113     .. code-block:: yaml
114 
115         policies:
116           - name: busy-vms
117             resource: azure.vm
118             filters:
119               - type: metric
120                 metric: Percentage CPU
121                 op: ge
122                 aggregation: average
123                 threshold: 75
124                 timeframe: 72
125 
126     :example:
127 
128     This policy will find all VMs that have Percentage CPU usage <= 1% over the last 72 hours,
129     mark for deletion in 7 days
130 
131     .. code-block:: yaml
132 
133         policies:
134           - name: delete-unused-vms
135             resource: azure.vm
136             filters:
137               - type: metric
138                 metric: Percentage CPU
139                 op: le
140                 aggregation: average
141                 threshold: 1
142                 timeframe: 72
143              actions:
144               - type: mark-for-op
145                 op: delete
146                 days: 7
147 
148     """
149 
150     class resource_type(ArmResourceManager.resource_type):
151         doc_groups = ['Compute']
152 
153         service = 'azure.mgmt.compute'
154         client = 'ComputeManagementClient'
155         enum_spec = ('virtual_machines', 'list_all', None)
156         diagnostic_settings_enabled = False
157         default_report_fields = (
158             'name',
159             'location',
160             'resourceGroup',
161             'properties.hardwareProfile.vmSize',
162         )
163         resource_type = 'Microsoft.Compute/virtualMachines'
164 
165 
166 @VirtualMachine.filter_registry.register('instance-view')
167 class InstanceViewFilter(ValueFilter):
168     schema = type_schema('instance-view', rinherit=ValueFilter.schema)
169 
170     def __call__(self, i):
171         if 'instanceView' not in i:
172             client = self.manager.get_client()
173             instance = (
174                 client.virtual_machines
175                 .get(i['resourceGroup'], i['name'], expand='instanceview')
176                 .instance_view
177             )
178             i['instanceView'] = instance.serialize()
179 
180         return super(InstanceViewFilter, self).__call__(i['instanceView'])
181 
182 
183 @VirtualMachine.filter_registry.register('network-interface')
184 class NetworkInterfaceFilter(RelatedResourceFilter):
185 
186     schema = type_schema('network-interface', rinherit=ValueFilter.schema)
187 
188     RelatedResource = "c7n_azure.resources.network_interface.NetworkInterface"
189     RelatedIdsExpression = "properties.networkProfile.networkInterfaces[0].id"
190 
191 
192 @VirtualMachine.action_registry.register('poweroff')
193 class VmPowerOffAction(AzureBaseAction):
194 
195     schema = type_schema('poweroff')
196 
197     def _prepare_processing(self,):
198         self.client = self.manager.get_client()
199 
200     def _process_resource(self, resource):
201         self.client.virtual_machines.begin_power_off(resource['resourceGroup'], resource['name'])
202 
203 
204 @VirtualMachine.action_registry.register('stop')
205 class VmStopAction(AzureBaseAction):
206 
207     schema = type_schema('stop')
208 
209     def _prepare_processing(self,):
210         self.client = self.manager.get_client()
211 
212     def _process_resource(self, resource):
213         self.client.virtual_machines.begin_deallocate(resource['resourceGroup'], resource['name'])
214 
215 
216 @VirtualMachine.action_registry.register('start')
217 class VmStartAction(AzureBaseAction):
218 
219     schema = type_schema('start')
220 
221     def _prepare_processing(self,):
222         self.client = self.manager.get_client()
223 
224     def _process_resource(self, resource):
225         self.client.virtual_machines.begin_start(resource['resourceGroup'], resource['name'])
226 
227 
228 @VirtualMachine.action_registry.register('restart')
229 class VmRestartAction(AzureBaseAction):
230 
231     schema = type_schema('restart')
232 
233     def _prepare_processing(self,):
234         self.client = self.manager.get_client()
235 
236     def _process_resource(self, resource):
237         self.client.virtual_machines.begin_restart(resource['resourceGroup'], resource['name'])
238 
239 
240 @VirtualMachine.action_registry.register('resize')
241 class VmResizeAction(AzureBaseAction):
242 
243     """Change a VM's size
244 
245     :example:
246 
247     Resize specific VM by name
248 
249     .. code-block:: yaml
250 
251         policies:
252           - name: resize-vm
253             resource: azure.vm
254             filters:
255               - type: value
256                 key: name
257                 op: eq
258                 value_type: normalize
259                 value: fake_vm_name
260             actions:
261               - type: resize
262                 vmSize: Standard_A2_v2
263     """
264 
265     schema = type_schema(
266         'resize',
267         required=['vmSize'],
268         **{
269             'vmSize': {'type': 'string'}
270         })
271 
272     def __init__(self, data, manager=None):
273         super(VmResizeAction, self).__init__(data, manager)
274         self.vm_size = self.data['vmSize']
275 
276     def _prepare_processing(self):
277         self.client = self.manager.get_client()
278 
279     def _process_resource(self, resource):
280         hardware_profile = HardwareProfile(vm_size=self.vm_size)
281 
282         self.client.virtual_machines.begin_update(
283             resource['resourceGroup'],
284             resource['name'],
285             VirtualMachineUpdate(hardware_profile=hardware_profile)
286         )
287
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/tools/c7n_azure/c7n_azure/resources/vm.py b/tools/c7n_azure/c7n_azure/resources/vm.py
--- a/tools/c7n_azure/c7n_azure/resources/vm.py
+++ b/tools/c7n_azure/c7n_azure/resources/vm.py
@@ -180,6 +180,87 @@
         return super(InstanceViewFilter, self).__call__(i['instanceView'])
 
 
+@VirtualMachine.filter_registry.register('vm-extensions')
+class VMExtensionsFilter(ValueFilter):
+    """
+        Provides a value filter targetting the virtual machine
+        extensions array.  Requires an additional API call per
+        virtual machine to retrieve the extensions.
+
+        Here is an example of the data returned:
+
+        .. code-block:: json
+
+          [{
+            "id": "/subscriptions/...",
+            "name": "CustomScript",
+            "type": "Microsoft.Compute/virtualMachines/extensions",
+            "location": "centralus",
+            "properties": {
+              "publisher": "Microsoft.Azure.Extensions",
+              "type": "CustomScript",
+              "typeHandlerVersion": "2.0",
+              "autoUpgradeMinorVersion": true,
+              "settings": {
+                "fileUris": []
+              },
+              "provisioningState": "Succeeded"
+            }
+          }]
+
+        :examples:
+
+        Find VM's with Custom Script extensions
+
+        .. code-block:: yaml
+
+            policies:
+              - name: vm-with-customscript
+                description: |
+                  Find all virtual machines with a custom
+                  script extension installed.
+                resource: azure.vm
+                filters:
+                  - type: vm-extensions
+                    op: in
+                    key: "[].properties.type"
+                    value: CustomScript
+                    value_type: swap
+
+
+        Find VM's without the OMS agent installed
+
+        .. code-block:: yaml
+
+            policies:
+              - name: vm-without-oms
+                description: |
+                  Find all virtual machines without the
+                  OMS agent installed.
+                resource: azure.vm
+                filters:
+                  - type: vm-extensions
+                    op: not-in
+                    key: "[].properties.type"
+                    value: OmsAgentForLinux
+                    value_type: swap
+
+        """
+    schema = type_schema('vm-extensions', rinherit=ValueFilter.schema)
+    annotate = False  # cannot annotate arrays
+
+    def __call__(self, i):
+        if 'c7n:vm-extensions' not in i:
+            client = self.manager.get_client()
+            extensions = (
+                client.virtual_machine_extensions
+                .list(i['resourceGroup'], i['name'])
+            )
+            i['c7n:vm-extensions'] = [e.serialize(True) for e in extensions.value]
+
+        return super(VMExtensionsFilter, self).__call__(i['c7n:vm-extensions'])
+
+
 @VirtualMachine.filter_registry.register('network-interface')
 class NetworkInterfaceFilter(RelatedResourceFilter):

{"golden_diff": "diff --git a/tools/c7n_azure/c7n_azure/resources/vm.py b/tools/c7n_azure/c7n_azure/resources/vm.py\n--- a/tools/c7n_azure/c7n_azure/resources/vm.py\n+++ b/tools/c7n_azure/c7n_azure/resources/vm.py\n@@ -180,6 +180,87 @@\n         return super(InstanceViewFilter, self).__call__(i['instanceView'])\n \n \n+@VirtualMachine.filter_registry.register('vm-extensions')\n+class VMExtensionsFilter(ValueFilter):\n+    \"\"\"\n+        Provides a value filter targetting the virtual machine\n+        extensions array.  Requires an additional API call per\n+        virtual machine to retrieve the extensions.\n+\n+        Here is an example of the data returned:\n+\n+        .. code-block:: json\n+\n+          [{\n+            \"id\": \"/subscriptions/...\",\n+            \"name\": \"CustomScript\",\n+            \"type\": \"Microsoft.Compute/virtualMachines/extensions\",\n+            \"location\": \"centralus\",\n+            \"properties\": {\n+              \"publisher\": \"Microsoft.Azure.Extensions\",\n+              \"type\": \"CustomScript\",\n+              \"typeHandlerVersion\": \"2.0\",\n+              \"autoUpgradeMinorVersion\": true,\n+              \"settings\": {\n+                \"fileUris\": []\n+              },\n+              \"provisioningState\": \"Succeeded\"\n+            }\n+          }]\n+\n+        :examples:\n+\n+        Find VM's with Custom Script extensions\n+\n+        .. code-block:: yaml\n+\n+            policies:\n+              - name: vm-with-customscript\n+                description: |\n+                  Find all virtual machines with a custom\n+                  script extension installed.\n+                resource: azure.vm\n+                filters:\n+                  - type: vm-extensions\n+                    op: in\n+                    key: \"[].properties.type\"\n+                    value: CustomScript\n+                    value_type: swap\n+\n+\n+        Find VM's without the OMS agent installed\n+\n+        .. code-block:: yaml\n+\n+            policies:\n+              - name: vm-without-oms\n+                description: |\n+                  Find all virtual machines without the\n+                  OMS agent installed.\n+                resource: azure.vm\n+                filters:\n+                  - type: vm-extensions\n+                    op: not-in\n+                    key: \"[].properties.type\"\n+                    value: OmsAgentForLinux\n+                    value_type: swap\n+\n+        \"\"\"\n+    schema = type_schema('vm-extensions', rinherit=ValueFilter.schema)\n+    annotate = False  # cannot annotate arrays\n+\n+    def __call__(self, i):\n+        if 'c7n:vm-extensions' not in i:\n+            client = self.manager.get_client()\n+            extensions = (\n+                client.virtual_machine_extensions\n+                .list(i['resourceGroup'], i['name'])\n+            )\n+            i['c7n:vm-extensions'] = [e.serialize(True) for e in extensions.value]\n+\n+        return super(VMExtensionsFilter, self).__call__(i['c7n:vm-extensions'])\n+\n+\n @VirtualMachine.filter_registry.register('network-interface')\n class NetworkInterfaceFilter(RelatedResourceFilter):\n", "issue": "azure add feature to get vm extensions \n**Is your feature request related to a problem? Please describe.**\r\nWe need to evaluate the list of extensions deployed on a Azure VM and generate a compliance report.\r\n\r\n**Describe the solution you'd like**\r\nAdd new filter to retrieve extensions attached to the VM\r\n\r\n**Describe alternatives you've considered**\r\nNA\r\n\r\n**Additional context**\r\nResource Type: `Microsoft.Compute/virtualMachines/extensions`\r\nhttps://docs.microsoft.com/en-us/azure/templates/microsoft.compute/virtualmachines/extensions?tabs=json\n", "before_files": [{"content": "# Copyright The Cloud Custodian Authors.\n# SPDX-License-Identifier: Apache-2.0\nfrom azure.mgmt.compute.models import HardwareProfile, VirtualMachineUpdate\nfrom c7n_azure.actions.base import AzureBaseAction\nfrom c7n_azure.provider import resources\nfrom c7n_azure.resources.arm import ArmResourceManager\n\nfrom c7n.filters.core import ValueFilter, type_schema\nfrom c7n.filters.related import RelatedResourceFilter\n\n\n@resources.register('vm')\nclass VirtualMachine(ArmResourceManager):\n    \"\"\"Virtual Machine Resource\n\n    :example:\n\n    Stop all running VMs\n\n    .. code-block:: yaml\n\n        policies:\n          - name: stop-running-vms\n            resource: azure.vm\n            filters:\n              - type: instance-view\n                key: statuses[].code\n                op: in\n                value_type: swap\n                value: PowerState/running\n            actions:\n              - type: stop\n\n    :example:\n\n    Start all VMs\n\n    .. code-block:: yaml\n\n        policies:\n          - name: start-vms\n            resource: azure.vm\n            actions:\n              - type: start\n\n    :example:\n\n    Restart all VMs\n\n    .. code-block:: yaml\n\n        policies:\n          - name: start-vms\n            resource: azure.vm\n            actions:\n              - type: restart\n\n    :example:\n\n    Resize specific VM by name\n\n    .. code-block:: yaml\n\n        policies:\n          - name: resize-vm\n            resource: azure.vm\n            filters:\n              - type: value\n                key: name\n                op: eq\n                value_type: normalize\n                value: fake_vm_name\n            actions:\n              - type: resize\n                vmSize: Standard_A2_v2\n\n    :example:\n\n    Delete specific VM by name\n\n    .. code-block:: yaml\n\n        policies:\n          - name: delete-vm\n            resource: azure.vm\n            filters:\n              - type: value\n                key: name\n                op: eq\n                value_type: normalize\n                value: fake_vm_name\n            actions:\n              - type: delete\n\n    :example:\n\n    Find all VMs with a Public IP address\n\n    .. code-block:: yaml\n\n        policies:\n          - name: vms-with-public-ip\n            resource: azure.vm\n            filters:\n              - type: network-interface\n                key: 'properties.ipConfigurations[].properties.publicIPAddress.id'\n                value: not-null\n\n    :example:\n\n    This policy will find all VMs that have Percentage CPU usage >= 75% over the last 72 hours\n\n    .. code-block:: yaml\n\n        policies:\n          - name: busy-vms\n            resource: azure.vm\n            filters:\n              - type: metric\n                metric: Percentage CPU\n                op: ge\n                aggregation: average\n                threshold: 75\n                timeframe: 72\n\n    :example:\n\n    This policy will find all VMs that have Percentage CPU usage <= 1% over the last 72 hours,\n    mark for deletion in 7 days\n\n    .. code-block:: yaml\n\n        policies:\n          - name: delete-unused-vms\n            resource: azure.vm\n            filters:\n              - type: metric\n                metric: Percentage CPU\n                op: le\n                aggregation: average\n                threshold: 1\n                timeframe: 72\n             actions:\n              - type: mark-for-op\n                op: delete\n                days: 7\n\n    \"\"\"\n\n    class resource_type(ArmResourceManager.resource_type):\n        doc_groups = ['Compute']\n\n        service = 'azure.mgmt.compute'\n        client = 'ComputeManagementClient'\n        enum_spec = ('virtual_machines', 'list_all', None)\n        diagnostic_settings_enabled = False\n        default_report_fields = (\n            'name',\n            'location',\n            'resourceGroup',\n            'properties.hardwareProfile.vmSize',\n        )\n        resource_type = 'Microsoft.Compute/virtualMachines'\n\n\n@VirtualMachine.filter_registry.register('instance-view')\nclass InstanceViewFilter(ValueFilter):\n    schema = type_schema('instance-view', rinherit=ValueFilter.schema)\n\n    def __call__(self, i):\n        if 'instanceView' not in i:\n            client = self.manager.get_client()\n            instance = (\n                client.virtual_machines\n                .get(i['resourceGroup'], i['name'], expand='instanceview')\n                .instance_view\n            )\n            i['instanceView'] = instance.serialize()\n\n        return super(InstanceViewFilter, self).__call__(i['instanceView'])\n\n\n@VirtualMachine.filter_registry.register('network-interface')\nclass NetworkInterfaceFilter(RelatedResourceFilter):\n\n    schema = type_schema('network-interface', rinherit=ValueFilter.schema)\n\n    RelatedResource = \"c7n_azure.resources.network_interface.NetworkInterface\"\n    RelatedIdsExpression = \"properties.networkProfile.networkInterfaces[0].id\"\n\n\n@VirtualMachine.action_registry.register('poweroff')\nclass VmPowerOffAction(AzureBaseAction):\n\n    schema = type_schema('poweroff')\n\n    def _prepare_processing(self,):\n        self.client = self.manager.get_client()\n\n    def _process_resource(self, resource):\n        self.client.virtual_machines.begin_power_off(resource['resourceGroup'], resource['name'])\n\n\n@VirtualMachine.action_registry.register('stop')\nclass VmStopAction(AzureBaseAction):\n\n    schema = type_schema('stop')\n\n    def _prepare_processing(self,):\n        self.client = self.manager.get_client()\n\n    def _process_resource(self, resource):\n        self.client.virtual_machines.begin_deallocate(resource['resourceGroup'], resource['name'])\n\n\n@VirtualMachine.action_registry.register('start')\nclass VmStartAction(AzureBaseAction):\n\n    schema = type_schema('start')\n\n    def _prepare_processing(self,):\n        self.client = self.manager.get_client()\n\n    def _process_resource(self, resource):\n        self.client.virtual_machines.begin_start(resource['resourceGroup'], resource['name'])\n\n\n@VirtualMachine.action_registry.register('restart')\nclass VmRestartAction(AzureBaseAction):\n\n    schema = type_schema('restart')\n\n    def _prepare_processing(self,):\n        self.client = self.manager.get_client()\n\n    def _process_resource(self, resource):\n        self.client.virtual_machines.begin_restart(resource['resourceGroup'], resource['name'])\n\n\n@VirtualMachine.action_registry.register('resize')\nclass VmResizeAction(AzureBaseAction):\n\n    \"\"\"Change a VM's size\n\n    :example:\n\n    Resize specific VM by name\n\n    .. code-block:: yaml\n\n        policies:\n          - name: resize-vm\n            resource: azure.vm\n            filters:\n              - type: value\n                key: name\n                op: eq\n                value_type: normalize\n                value: fake_vm_name\n            actions:\n              - type: resize\n                vmSize: Standard_A2_v2\n    \"\"\"\n\n    schema = type_schema(\n        'resize',\n        required=['vmSize'],\n        **{\n            'vmSize': {'type': 'string'}\n        })\n\n    def __init__(self, data, manager=None):\n        super(VmResizeAction, self).__init__(data, manager)\n        self.vm_size = self.data['vmSize']\n\n    def _prepare_processing(self):\n        self.client = self.manager.get_client()\n\n    def _process_resource(self, resource):\n        hardware_profile = HardwareProfile(vm_size=self.vm_size)\n\n        self.client.virtual_machines.begin_update(\n            resource['resourceGroup'],\n            resource['name'],\n            VirtualMachineUpdate(hardware_profile=hardware_profile)\n        )\n", "path": "tools/c7n_azure/c7n_azure/resources/vm.py"}], "after_files": [{"content": "# Copyright The Cloud Custodian Authors.\n# SPDX-License-Identifier: Apache-2.0\nfrom azure.mgmt.compute.models import HardwareProfile, VirtualMachineUpdate\nfrom c7n_azure.actions.base import AzureBaseAction\nfrom c7n_azure.provider import resources\nfrom c7n_azure.resources.arm import ArmResourceManager\n\nfrom c7n.filters.core import ValueFilter, type_schema\nfrom c7n.filters.related import RelatedResourceFilter\n\n\n@resources.register('vm')\nclass VirtualMachine(ArmResourceManager):\n    \"\"\"Virtual Machine Resource\n\n    :example:\n\n    Stop all running VMs\n\n    .. code-block:: yaml\n\n        policies:\n          - name: stop-running-vms\n            resource: azure.vm\n            filters:\n              - type: instance-view\n                key: statuses[].code\n                op: in\n                value_type: swap\n                value: PowerState/running\n            actions:\n              - type: stop\n\n    :example:\n\n    Start all VMs\n\n    .. code-block:: yaml\n\n        policies:\n          - name: start-vms\n            resource: azure.vm\n            actions:\n              - type: start\n\n    :example:\n\n    Restart all VMs\n\n    .. code-block:: yaml\n\n        policies:\n          - name: start-vms\n            resource: azure.vm\n            actions:\n              - type: restart\n\n    :example:\n\n    Resize specific VM by name\n\n    .. code-block:: yaml\n\n        policies:\n          - name: resize-vm\n            resource: azure.vm\n            filters:\n              - type: value\n                key: name\n                op: eq\n                value_type: normalize\n                value: fake_vm_name\n            actions:\n              - type: resize\n                vmSize: Standard_A2_v2\n\n    :example:\n\n    Delete specific VM by name\n\n    .. code-block:: yaml\n\n        policies:\n          - name: delete-vm\n            resource: azure.vm\n            filters:\n              - type: value\n                key: name\n                op: eq\n                value_type: normalize\n                value: fake_vm_name\n            actions:\n              - type: delete\n\n    :example:\n\n    Find all VMs with a Public IP address\n\n    .. code-block:: yaml\n\n        policies:\n          - name: vms-with-public-ip\n            resource: azure.vm\n            filters:\n              - type: network-interface\n                key: 'properties.ipConfigurations[].properties.publicIPAddress.id'\n                value: not-null\n\n    :example:\n\n    This policy will find all VMs that have Percentage CPU usage >= 75% over the last 72 hours\n\n    .. code-block:: yaml\n\n        policies:\n          - name: busy-vms\n            resource: azure.vm\n            filters:\n              - type: metric\n                metric: Percentage CPU\n                op: ge\n                aggregation: average\n                threshold: 75\n                timeframe: 72\n\n    :example:\n\n    This policy will find all VMs that have Percentage CPU usage <= 1% over the last 72 hours,\n    mark for deletion in 7 days\n\n    .. code-block:: yaml\n\n        policies:\n          - name: delete-unused-vms\n            resource: azure.vm\n            filters:\n              - type: metric\n                metric: Percentage CPU\n                op: le\n                aggregation: average\n                threshold: 1\n                timeframe: 72\n             actions:\n              - type: mark-for-op\n                op: delete\n                days: 7\n\n    \"\"\"\n\n    class resource_type(ArmResourceManager.resource_type):\n        doc_groups = ['Compute']\n\n        service = 'azure.mgmt.compute'\n        client = 'ComputeManagementClient'\n        enum_spec = ('virtual_machines', 'list_all', None)\n        diagnostic_settings_enabled = False\n        default_report_fields = (\n            'name',\n            'location',\n            'resourceGroup',\n            'properties.hardwareProfile.vmSize',\n        )\n        resource_type = 'Microsoft.Compute/virtualMachines'\n\n\n@VirtualMachine.filter_registry.register('instance-view')\nclass InstanceViewFilter(ValueFilter):\n    schema = type_schema('instance-view', rinherit=ValueFilter.schema)\n\n    def __call__(self, i):\n        if 'instanceView' not in i:\n            client = self.manager.get_client()\n            instance = (\n                client.virtual_machines\n                .get(i['resourceGroup'], i['name'], expand='instanceview')\n                .instance_view\n            )\n            i['instanceView'] = instance.serialize()\n\n        return super(InstanceViewFilter, self).__call__(i['instanceView'])\n\n\n@VirtualMachine.filter_registry.register('vm-extensions')\nclass VMExtensionsFilter(ValueFilter):\n    \"\"\"\n        Provides a value filter targetting the virtual machine\n        extensions array.  Requires an additional API call per\n        virtual machine to retrieve the extensions.\n\n        Here is an example of the data returned:\n\n        .. code-block:: json\n\n          [{\n            \"id\": \"/subscriptions/...\",\n            \"name\": \"CustomScript\",\n            \"type\": \"Microsoft.Compute/virtualMachines/extensions\",\n            \"location\": \"centralus\",\n            \"properties\": {\n              \"publisher\": \"Microsoft.Azure.Extensions\",\n              \"type\": \"CustomScript\",\n              \"typeHandlerVersion\": \"2.0\",\n              \"autoUpgradeMinorVersion\": true,\n              \"settings\": {\n                \"fileUris\": []\n              },\n              \"provisioningState\": \"Succeeded\"\n            }\n          }]\n\n        :examples:\n\n        Find VM's with Custom Script extensions\n\n        .. code-block:: yaml\n\n            policies:\n              - name: vm-with-customscript\n                description: |\n                  Find all virtual machines with a custom\n                  script extension installed.\n                resource: azure.vm\n                filters:\n                  - type: vm-extensions\n                    op: in\n                    key: \"[].properties.type\"\n                    value: CustomScript\n                    value_type: swap\n\n\n        Find VM's without the OMS agent installed\n\n        .. code-block:: yaml\n\n            policies:\n              - name: vm-without-oms\n                description: |\n                  Find all virtual machines without the\n                  OMS agent installed.\n                resource: azure.vm\n                filters:\n                  - type: vm-extensions\n                    op: not-in\n                    key: \"[].properties.type\"\n                    value: OmsAgentForLinux\n                    value_type: swap\n\n        \"\"\"\n    schema = type_schema('vm-extensions', rinherit=ValueFilter.schema)\n    annotate = False  # cannot annotate arrays\n\n    def __call__(self, i):\n        if 'c7n:vm-extensions' not in i:\n            client = self.manager.get_client()\n            extensions = (\n                client.virtual_machine_extensions\n                .list(i['resourceGroup'], i['name'])\n            )\n            i['c7n:vm-extensions'] = [e.serialize(True) for e in extensions.value]\n\n        return super(VMExtensionsFilter, self).__call__(i['c7n:vm-extensions'])\n\n\n@VirtualMachine.filter_registry.register('network-interface')\nclass NetworkInterfaceFilter(RelatedResourceFilter):\n\n    schema = type_schema('network-interface', rinherit=ValueFilter.schema)\n\n    RelatedResource = \"c7n_azure.resources.network_interface.NetworkInterface\"\n    RelatedIdsExpression = \"properties.networkProfile.networkInterfaces[0].id\"\n\n\n@VirtualMachine.action_registry.register('poweroff')\nclass VmPowerOffAction(AzureBaseAction):\n\n    schema = type_schema('poweroff')\n\n    def _prepare_processing(self,):\n        self.client = self.manager.get_client()\n\n    def _process_resource(self, resource):\n        self.client.virtual_machines.begin_power_off(resource['resourceGroup'], resource['name'])\n\n\n@VirtualMachine.action_registry.register('stop')\nclass VmStopAction(AzureBaseAction):\n\n    schema = type_schema('stop')\n\n    def _prepare_processing(self,):\n        self.client = self.manager.get_client()\n\n    def _process_resource(self, resource):\n        self.client.virtual_machines.begin_deallocate(resource['resourceGroup'], resource['name'])\n\n\n@VirtualMachine.action_registry.register('start')\nclass VmStartAction(AzureBaseAction):\n\n    schema = type_schema('start')\n\n    def _prepare_processing(self,):\n        self.client = self.manager.get_client()\n\n    def _process_resource(self, resource):\n        self.client.virtual_machines.begin_start(resource['resourceGroup'], resource['name'])\n\n\n@VirtualMachine.action_registry.register('restart')\nclass VmRestartAction(AzureBaseAction):\n\n    schema = type_schema('restart')\n\n    def _prepare_processing(self,):\n        self.client = self.manager.get_client()\n\n    def _process_resource(self, resource):\n        self.client.virtual_machines.begin_restart(resource['resourceGroup'], resource['name'])\n\n\n@VirtualMachine.action_registry.register('resize')\nclass VmResizeAction(AzureBaseAction):\n\n    \"\"\"Change a VM's size\n\n    :example:\n\n    Resize specific VM by name\n\n    .. code-block:: yaml\n\n        policies:\n          - name: resize-vm\n            resource: azure.vm\n            filters:\n              - type: value\n                key: name\n                op: eq\n                value_type: normalize\n                value: fake_vm_name\n            actions:\n              - type: resize\n                vmSize: Standard_A2_v2\n    \"\"\"\n\n    schema = type_schema(\n        'resize',\n        required=['vmSize'],\n        **{\n            'vmSize': {'type': 'string'}\n        })\n\n    def __init__(self, data, manager=None):\n        super(VmResizeAction, self).__init__(data, manager)\n        self.vm_size = self.data['vmSize']\n\n    def _prepare_processing(self):\n        self.client = self.manager.get_client()\n\n    def _process_resource(self, resource):\n        hardware_profile = HardwareProfile(vm_size=self.vm_size)\n\n        self.client.virtual_machines.begin_update(\n            resource['resourceGroup'],\n            resource['name'],\n            VirtualMachineUpdate(hardware_profile=hardware_profile)\n        )\n", "path": "tools/c7n_azure/c7n_azure/resources/vm.py"}]}