mirror of
https://github.com/microsoft/onefuzz.git
synced 2025-06-14 11:08:06 +00:00
port arm template to bicep (#1724)
* port template to bicep * Update src/deployment/azuredeploy.bicep Co-authored-by: Teo Voinea <58236992+tevoinea@users.noreply.github.com> * port template to bicep * adding type annotation * apply changes from #1679 Co-authored-by: stas <statis@microsoft.com> Co-authored-by: Teo Voinea <58236992+tevoinea@users.noreply.github.com>
This commit is contained in:
@ -101,6 +101,31 @@ def gen_guid() -> str:
|
||||
return str(uuid.uuid4())
|
||||
|
||||
|
||||
def bicep_to_arm(bicep_template: str) -> str:
|
||||
from azure.cli.core import get_default_cli
|
||||
|
||||
az_cli = get_default_cli()
|
||||
az_cli.invoke(["bicep", "install"])
|
||||
az_cli.invoke(
|
||||
[
|
||||
"bicep",
|
||||
"build",
|
||||
"--file",
|
||||
bicep_template,
|
||||
"--outfile",
|
||||
"azuredeploy-bicep.json",
|
||||
]
|
||||
)
|
||||
from importlib import reload
|
||||
|
||||
# az_cli hijacks logging, so need to reset it
|
||||
logging.shutdown()
|
||||
reload(logging)
|
||||
global logger
|
||||
logger = logging.getLogger("deploy")
|
||||
return "azuredeploy-bicep.json"
|
||||
|
||||
|
||||
class Client:
|
||||
def __init__(
|
||||
self,
|
||||
@ -116,7 +141,7 @@ class Client:
|
||||
tools: str,
|
||||
instance_specific: str,
|
||||
third_party: str,
|
||||
arm_template: str,
|
||||
arm_or_bicep_template: str,
|
||||
workbook_data: str,
|
||||
create_registration: bool,
|
||||
migrations: List[str],
|
||||
@ -129,7 +154,6 @@ class Client:
|
||||
):
|
||||
self.subscription_id = subscription_id
|
||||
self.resource_group = resource_group
|
||||
self.arm_template = arm_template
|
||||
self.location = location
|
||||
self.application_name = application_name
|
||||
self.owner = owner
|
||||
@ -158,6 +182,13 @@ class Client:
|
||||
self.admins = admins
|
||||
self.allowed_aad_tenants = allowed_aad_tenants
|
||||
|
||||
if arm_or_bicep_template:
|
||||
file_name, file_extension = os.path.splitext(arm_or_bicep_template)
|
||||
if file_extension == ".bicep":
|
||||
self.arm_template = bicep_to_arm(arm_or_bicep_template)
|
||||
else:
|
||||
self.arm_template = arm_or_bicep_template
|
||||
|
||||
machine = platform.machine()
|
||||
system = platform.system()
|
||||
|
||||
@ -211,37 +242,42 @@ class Client:
|
||||
client = ResourceManagementClient(
|
||||
credential, subscription_id=self.get_subscription_id()
|
||||
)
|
||||
providers = {x.namespace: x for x in client.providers.list()}
|
||||
|
||||
providers = {x.namespace.lower(): x for x in client.providers.list()}
|
||||
unsupported = []
|
||||
|
||||
# we cannot validate site/config resources since they require resource group
|
||||
# to exist. check_region only validates subscription level resources.
|
||||
resource_group_level_resources = ["sites/config"]
|
||||
|
||||
for resource in arm["resources"]:
|
||||
namespace, name = resource["type"].split("/", 1)
|
||||
namespace, name = resource["type"].lower().split("/", 1)
|
||||
|
||||
# resource types are in the form of a/b/c....
|
||||
# only the top two are listed as resource types within providers
|
||||
name = "/".join(name.split("/")[:2])
|
||||
|
||||
if namespace not in providers:
|
||||
unsupported.append("Unsupported provider: %s" % namespace)
|
||||
continue
|
||||
|
||||
provider = providers[namespace]
|
||||
resource_types = {x.resource_type: x for x in provider.resource_types}
|
||||
if name not in resource_types:
|
||||
unsupported.append(
|
||||
"Unsupported resource type: %s/%s" % (namespace, name)
|
||||
)
|
||||
continue
|
||||
resource_types = {
|
||||
x.resource_type.lower(): x for x in provider.resource_types
|
||||
}
|
||||
if name not in resource_group_level_resources:
|
||||
if name not in resource_types:
|
||||
unsupported.append(
|
||||
"Unsupported resource type: %s/%s" % (namespace, name)
|
||||
)
|
||||
continue
|
||||
|
||||
resource_type = resource_types[name]
|
||||
if (
|
||||
location not in resource_type.locations
|
||||
and len(resource_type.locations) > 0
|
||||
):
|
||||
unsupported.append(
|
||||
"%s/%s is unsupported in %s" % (namespace, name, self.location)
|
||||
)
|
||||
resource_type = resource_types[name]
|
||||
if (
|
||||
location not in resource_type.locations
|
||||
and len(resource_type.locations) > 0
|
||||
):
|
||||
unsupported.append(
|
||||
"%s/%s is unsupported in %s" % (namespace, name, self.location)
|
||||
)
|
||||
|
||||
if unsupported:
|
||||
print("The following resources required by onefuzz are not supported:")
|
||||
@ -605,7 +641,7 @@ class Client:
|
||||
logger.info("assigning the user managed identity role")
|
||||
assign_instance_app_role(
|
||||
self.application_name,
|
||||
self.results["deploy"]["scaleset-identity"]["value"],
|
||||
self.results["deploy"]["scaleset_identity"]["value"],
|
||||
self.get_subscription_id(),
|
||||
OnefuzzAppRole.ManagedNode,
|
||||
)
|
||||
@ -646,15 +682,15 @@ class Client:
|
||||
|
||||
def apply_migrations(self) -> None:
|
||||
logger.info("applying database migrations")
|
||||
name = self.results["deploy"]["func-name"]["value"]
|
||||
key = self.results["deploy"]["func-key"]["value"]
|
||||
name = self.results["deploy"]["func_name"]["value"]
|
||||
key = self.results["deploy"]["func_key"]["value"]
|
||||
table_service = TableService(account_name=name, account_key=key)
|
||||
migrate(table_service, self.migrations)
|
||||
|
||||
def set_instance_config(self) -> None:
|
||||
logger.info("setting instance config")
|
||||
name = self.results["deploy"]["func-name"]["value"]
|
||||
key = self.results["deploy"]["func-key"]["value"]
|
||||
name = self.results["deploy"]["func_name"]["value"]
|
||||
key = self.results["deploy"]["func_key"]["value"]
|
||||
tenant = UUID(self.results["deploy"]["tenant_id"]["value"])
|
||||
table_service = TableService(account_name=name, account_key=key)
|
||||
|
||||
@ -747,8 +783,8 @@ class Client:
|
||||
|
||||
container_name = "base-config"
|
||||
blob_name = "instance_id"
|
||||
account_name = self.results["deploy"]["func-name"]["value"]
|
||||
key = self.results["deploy"]["func-key"]["value"]
|
||||
account_name = self.results["deploy"]["func_name"]["value"]
|
||||
key = self.results["deploy"]["func_key"]["value"]
|
||||
account_url = "https://%s.blob.core.windows.net" % account_name
|
||||
client = BlobServiceClient(account_url, credential=key)
|
||||
if container_name not in [x["name"] for x in client.list_containers()]:
|
||||
@ -773,8 +809,8 @@ class Client:
|
||||
container_name = "app-insights"
|
||||
|
||||
logger.info("adding appinsight log export")
|
||||
account_name = self.results["deploy"]["func-name"]["value"]
|
||||
key = self.results["deploy"]["func-key"]["value"]
|
||||
account_name = self.results["deploy"]["func_name"]["value"]
|
||||
key = self.results["deploy"]["func_key"]["value"]
|
||||
account_url = "https://%s.blob.core.windows.net" % account_name
|
||||
client = BlobServiceClient(account_url, credential=key)
|
||||
if container_name not in [x["name"] for x in client.list_containers()]:
|
||||
@ -833,8 +869,8 @@ class Client:
|
||||
|
||||
def upload_tools(self) -> None:
|
||||
logger.info("uploading tools from %s", self.tools)
|
||||
account_name = self.results["deploy"]["func-name"]["value"]
|
||||
key = self.results["deploy"]["func-key"]["value"]
|
||||
account_name = self.results["deploy"]["func_name"]["value"]
|
||||
key = self.results["deploy"]["func_key"]["value"]
|
||||
account_url = "https://%s.blob.core.windows.net" % account_name
|
||||
client = BlobServiceClient(account_url, credential=key)
|
||||
if "tools" not in [x["name"] for x in client.list_containers()]:
|
||||
@ -870,8 +906,8 @@ class Client:
|
||||
|
||||
def upload_instance_setup(self) -> None:
|
||||
logger.info("uploading instance-specific-setup from %s", self.instance_specific)
|
||||
account_name = self.results["deploy"]["func-name"]["value"]
|
||||
key = self.results["deploy"]["func-key"]["value"]
|
||||
account_name = self.results["deploy"]["func_name"]["value"]
|
||||
key = self.results["deploy"]["func_key"]["value"]
|
||||
account_url = "https://%s.blob.core.windows.net" % account_name
|
||||
client = BlobServiceClient(account_url, credential=key)
|
||||
if "instance-specific-setup" not in [
|
||||
@ -916,8 +952,8 @@ class Client:
|
||||
|
||||
def upload_third_party(self) -> None:
|
||||
logger.info("uploading third-party tools from %s", self.third_party)
|
||||
account_name = self.results["deploy"]["fuzz-name"]["value"]
|
||||
key = self.results["deploy"]["fuzz-key"]["value"]
|
||||
account_name = self.results["deploy"]["fuzz_name"]["value"]
|
||||
key = self.results["deploy"]["fuzz_key"]["value"]
|
||||
account_url = "https://%s.blob.core.windows.net" % account_name
|
||||
|
||||
client = BlobServiceClient(account_url, credential=key)
|
||||
@ -1067,9 +1103,9 @@ def main() -> None:
|
||||
parser.add_argument("owner")
|
||||
parser.add_argument("nsg_config")
|
||||
parser.add_argument(
|
||||
"--arm-template",
|
||||
"--arm-or-bicep-template",
|
||||
type=arg_file,
|
||||
default="azuredeploy.json",
|
||||
default="azuredeploy.bicep",
|
||||
help="(default: %(default)s)",
|
||||
)
|
||||
parser.add_argument(
|
||||
@ -1180,7 +1216,7 @@ def main() -> None:
|
||||
tools=args.tools,
|
||||
instance_specific=args.instance_specific,
|
||||
third_party=args.third_party,
|
||||
arm_template=args.arm_template,
|
||||
arm_or_bicep_template=args.arm_or_bicep_template,
|
||||
workbook_data=args.workbook_data,
|
||||
create_registration=args.create_pool_registration,
|
||||
migrations=args.apply_migrations,
|
||||
|
Reference in New Issue
Block a user