Skip to content
This repository has been archived by the owner on Nov 1, 2023. It is now read-only.

Commit

Permalink
Delete NSG if no resources associated with it (#1358)
Browse files Browse the repository at this point in the history
Co-authored-by: stas <statis@microsoft.com>
  • Loading branch information
stishkin and stas committed Oct 27, 2021
1 parent 29f8633 commit 684b3d8
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/api-service/__app__/onefuzzlib/azure/nsg.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import logging
import os
from typing import Dict, List, Optional, Union, cast
from typing import Dict, List, Optional, Set, Union, cast

from azure.core.exceptions import HttpResponseError, ResourceNotFoundError
from azure.mgmt.network.models import (
Expand Down Expand Up @@ -72,6 +72,12 @@ def create_nsg(name: str, location: Region) -> Union[None, Error]:
return None


def list_nsgs() -> List[NetworkSecurityGroup]:
resource_group = get_base_resource_group()
network_client = get_network_client()
return list(network_client.network_security_groups.list(resource_group))


def update_nsg(nsg: NetworkSecurityGroup) -> Union[None, Error]:
resource_group = get_base_resource_group()

Expand All @@ -95,6 +101,10 @@ def update_nsg(nsg: NetworkSecurityGroup) -> Union[None, Error]:
return None


def ok_to_delete(active_regions: Set[Region], nsg_region: str, nsg_name: str) -> bool:
return nsg_region not in active_regions and nsg_region == nsg_name


def delete_nsg(name: str) -> bool:
# NSG can be only deleted if no other resource is associated with it
resource_group = get_base_resource_group()
Expand Down
8 changes: 8 additions & 0 deletions src/api-service/__app__/timer_proxy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import azure.functions as func
from onefuzztypes.enums import VmState

from ..onefuzzlib.azure.nsg import delete_nsg, list_nsgs, ok_to_delete
from ..onefuzzlib.orm import process_state_updates
from ..onefuzzlib.proxy import PROXY_LOG_PREFIX, Proxy
from ..onefuzzlib.workers.scalesets import Scaleset
Expand Down Expand Up @@ -50,3 +51,10 @@ def main(mytimer: func.TimerRequest) -> None: # noqa: F841
for region in regions:
if all(x.outdated for x in proxies if x.region == region):
Proxy.get_or_create(region)

# if there are NSGs with name same as the region that they are allocated
# and have no NIC associated with it then delete the NSG
for nsg in list_nsgs():
if ok_to_delete(regions, nsg.location, nsg.name):
if nsg.network_interfaces is None:
delete_nsg(nsg.name)
32 changes: 32 additions & 0 deletions src/api-service/tests/test_nsg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env python
#
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

from typing import Set, Tuple

import pytest
from onefuzztypes.primitives import Region

from __app__.onefuzzlib.azure.nsg import ok_to_delete

# Active regions, NSG region, NSG name, expected result
NsgOkToDeleteTestCase = Tuple[Set[Region], str, str, bool]

NSG_OK_TO_DELETE_TEST_CASES = [
# OK to delete
(set([Region("def"), Region("ghk")]), "abc", "abc", True),
# Not OK to delete
# region set has same region as NSG
(set([Region("abc"), Region("def"), Region("ghk")]), "abc", "abc", False),
# NSG region does not match it's name
(set([Region("abc"), Region("def"), Region("ghk")]), "abc", "cba", False),
(set([Region("def"), Region("ghk")]), "abc", "cba", False),
]


@pytest.mark.parametrize("nsg_ok_to_delete_test_case", NSG_OK_TO_DELETE_TEST_CASES)
def test_is_ok_to_delete_nsg(nsg_ok_to_delete_test_case: NsgOkToDeleteTestCase) -> None:
regions, nsg_location, nsg_name, expected = nsg_ok_to_delete_test_case
result = ok_to_delete(regions, nsg_location, nsg_name)
assert result == expected

0 comments on commit 684b3d8

Please sign in to comment.