enable configurable virtual network ranges (#1268)

This commit is contained in:
bmc-msft
2021-09-27 14:01:32 -04:00
committed by GitHub
parent 47bb2ce187
commit 22b2d62e29
7 changed files with 118 additions and 37 deletions

View File

@ -13,10 +13,11 @@ from msrestazure.azure_exceptions import CloudError
from msrestazure.tools import parse_resource_id
from onefuzztypes.enums import ErrorCode
from onefuzztypes.models import Error
from onefuzztypes.primitives import Region
from .creds import get_base_resource_group
from .network import Network
from .network_mgmt_client import get_network_client
from .subnet import create_virtual_network, get_subnet_id
from .vmss import get_instance_id
@ -63,12 +64,12 @@ def delete_ip(resource_group: str, name: str) -> Any:
return network_client.public_ip_addresses.begin_delete(resource_group, name)
def create_ip(resource_group: str, name: str, location: str) -> Any:
logging.info("creating ip for %s:%s in %s", resource_group, name, location)
def create_ip(resource_group: str, name: str, region: Region) -> Any:
logging.info("creating ip for %s:%s in %s", resource_group, name, region)
network_client = get_network_client()
params: Dict[str, Union[str, Dict[str, str]]] = {
"location": location,
"location": region,
"public_ip_allocation_method": "Dynamic",
}
if "ONEFUZZ_OWNER" in os.environ:
@ -93,21 +94,24 @@ def delete_nic(resource_group: str, name: str) -> Optional[Any]:
return network_client.network_interfaces.begin_delete(resource_group, name)
def create_public_nic(resource_group: str, name: str, location: str) -> Optional[Error]:
logging.info("creating nic for %s:%s in %s", resource_group, name, location)
def create_public_nic(
resource_group: str, name: str, region: Region
) -> Optional[Error]:
logging.info("creating nic for %s:%s in %s", resource_group, name, region)
network_client = get_network_client()
subnet_id = get_subnet_id(resource_group, location)
if not subnet_id:
return create_virtual_network(resource_group, location, location)
network = Network(region)
subnet_id = network.get_id()
if subnet_id is None:
network.create()
return None
ip = get_ip(resource_group, name)
if not ip:
create_ip(resource_group, name, location)
create_ip(resource_group, name, region)
return None
params = {
"location": location,
"location": region,
"ip_configurations": [
{
"name": "myIPConfig",
@ -119,6 +123,7 @@ def create_public_nic(resource_group: str, name: str, location: str) -> Optional
if "ONEFUZZ_OWNER" in os.environ:
params["tags"] = {"OWNER": os.environ["ONEFUZZ_OWNER"]}
network_client = get_network_client()
try:
network_client.network_interfaces.begin_create_or_update(
resource_group, name, params

View File

@ -4,43 +4,68 @@
# Licensed under the MIT License.
import logging
import uuid
from typing import Optional, Union
from msrestazure.azure_exceptions import CloudError
from onefuzztypes.enums import ErrorCode
from onefuzztypes.models import Error
from onefuzztypes.models import Error, NetworkConfig
from onefuzztypes.primitives import Region
from ..config import InstanceConfig
from .creds import get_base_resource_group
from .subnet import create_virtual_network, delete_subnet, get_subnet_id
from .subnet import create_virtual_network, get_subnet_id
# This was generated randomly and should be preserved moving forwards
NETWORK_GUID_NAMESPACE = uuid.UUID("372977ad-b533-416a-b1b4-f770898e0b11")
class Network:
def __init__(self, region: Region):
self.group = get_base_resource_group()
self.region = region
self.network_config = InstanceConfig.fetch().network_config
# Network names will be calculated from the address_space/subnet
# *except* if they are the original values. This allows backwards
# compatibility to existing configs if you don't change the network
# configs.
if (
self.network_config.address_space
== NetworkConfig.__fields__["address_space"].default
and self.network_config.subnet == NetworkConfig.__fields__["subnet"].default
):
self.name: str = self.region
else:
network_id = uuid.uuid5(
NETWORK_GUID_NAMESPACE,
"|".join(
[self.network_config.address_space, self.network_config.subnet]
),
)
self.name = f"{self.region}-{network_id}"
def exists(self) -> bool:
return self.get_id() is not None
def get_id(self) -> Optional[str]:
return get_subnet_id(self.group, self.region)
return get_subnet_id(self.group, self.name, self.name)
def create(self) -> Union[None, Error]:
if not self.exists():
result = create_virtual_network(self.group, self.region, self.region)
result = create_virtual_network(
self.group, self.name, self.region, self.network_config
)
if isinstance(result, CloudError):
error = Error(
code=ErrorCode.UNABLE_TO_CREATE_NETWORK, errors=[result.message]
)
logging.error(
"network creation failed: %s- %s",
"network creation failed: %s:%s- %s",
self.name,
self.region,
error,
)
return error
return None
def delete(self) -> None:
delete_subnet(self.group, self.region)

View File

@ -10,21 +10,23 @@ from typing import Any, Optional, Union, cast
from azure.core.exceptions import ResourceNotFoundError
from msrestazure.azure_exceptions import CloudError
from onefuzztypes.enums import ErrorCode
from onefuzztypes.models import Error
from onefuzztypes.models import Error, NetworkConfig
from onefuzztypes.primitives import Region
from .network_mgmt_client import get_network_client
def get_subnet_id(resource_group: str, name: str) -> Optional[str]:
def get_subnet_id(resource_group: str, name: str, subnet_name: str) -> Optional[str]:
network_client = get_network_client()
try:
subnet = network_client.subnets.get(resource_group, name, name)
subnet = network_client.subnets.get(resource_group, name, subnet_name)
return cast(str, subnet.id)
except (CloudError, ResourceNotFoundError):
logging.info(
"subnet missing: resource group: %s name: %s",
"subnet missing: resource group:%s name:%s subnet_name:%s",
resource_group,
name,
subnet_name,
)
return None
@ -43,20 +45,23 @@ def delete_subnet(resource_group: str, name: str) -> Union[None, CloudError, Any
def create_virtual_network(
resource_group: str, name: str, location: str
resource_group: str,
name: str,
region: Region,
network_config: NetworkConfig,
) -> Optional[Error]:
logging.info(
"creating subnet - resource group: %s name: %s location: %s",
"creating subnet - resource group:%s name:%s region:%s",
resource_group,
name,
location,
region,
)
network_client = get_network_client()
params = {
"location": location,
"address_space": {"address_prefixes": ["10.0.0.0/8"]},
"subnets": [{"name": name, "address_prefix": "10.0.0.0/16"}],
"location": region,
"address_space": {"address_prefixes": [network_config.address_space]},
"subnets": [{"name": name, "address_prefix": network_config.subnet}],
}
if "ONEFUZZ_OWNER" in os.environ:
params["tags"] = {"OWNER": os.environ["ONEFUZZ_OWNER"]}

View File

@ -399,11 +399,11 @@ def create_vmss(
@cached(ttl=60)
@retry_on_auth_failure()
def list_available_skus(location: str) -> List[str]:
def list_available_skus(region: Region) -> List[str]:
compute_client = get_compute_client()
skus: List[ResourceSku] = list(
compute_client.resource_skus.list(filter="location eq '%s'" % location)
compute_client.resource_skus.list(filter="location eq '%s'" % region)
)
sku_names: List[str] = []
for sku in skus:
@ -411,7 +411,7 @@ def list_available_skus(location: str) -> List[str]:
if sku.restrictions is not None:
for restriction in sku.restrictions:
if restriction.type == ResourceSkuRestrictionsType.location and (
location.upper() in [v.upper() for v in restriction.values]
region.upper() in [v.upper() for v in restriction.values]
):
available = False
break

View File

@ -92,8 +92,8 @@ def not_ok(
)
def redirect(location: str) -> HttpResponse:
return HttpResponse(status_code=302, headers={"Location": location})
def redirect(url: str) -> HttpResponse:
return HttpResponse(status_code=302, headers={"Location": url})
def convert_error(err: ValidationError) -> Error: