mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-16 11:58:09 +00:00
enable configurable virtual network ranges (#1268)
This commit is contained in:
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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"]}
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
Reference in New Issue
Block a user