Skip to content

Commit

Permalink
Merge pull request Azure#12 from jddarby/jl/post-review-fixes
Browse files Browse the repository at this point in the history
Jl/post review fixes
  • Loading branch information
jordlay authored May 25, 2023
2 parents a79ef57 + e63f199 commit c26369a
Show file tree
Hide file tree
Showing 11 changed files with 307 additions and 228 deletions.
38 changes: 25 additions & 13 deletions src/aosm/azext_aosm/_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
from typing import Dict, Optional, Any, List
from pathlib import Path
from azure.cli.core.azclierror import ValidationError, InvalidArgumentValueError
from azext_aosm.util.constants import VNF_DEFINITION_OUTPUT_BICEP_PREFIX, VNF, CNF, NSD
from azext_aosm.util.constants import DEFINITION_OUTPUT_BICEP_PREFIX, VNF, CNF, NSD

DESCRIPTION_MAP: Dict[str, str] = {
"publisher_resource_group_name": (
"Resource group for the Publisher resource. Will be "
"created if it does not exist."
),
"publisher_name": ("Name of the Publisher resource you want your definition "
"published to. Will be created if it does not exist."
"publisher_name": (
"Name of the Publisher resource you want your definition "
"published to. Will be created if it does not exist."
),
"nf_name": "Name of NF definition",
"version": "Version of the NF definition",
Expand All @@ -30,6 +31,14 @@
"Version of the artifact. For VHDs this must be in format A-B-C. "
"For ARM templates this must be in format A.B.C"
),
"helm_package_name": "Name of the Helm package",
"path_to_chart": (
"File path of Helm Chart on local disk. Accepts .tgz, .tar or .tar.gz"
),
"helm_depends_on": (
"Names of the Helm packages this package depends on. "
"Leave as an empty array if no dependencies"
)
}


Expand Down Expand Up @@ -114,7 +123,7 @@ def validate(self) -> None:
raise ValidationError(
"Config validation error. VHD config must have either a local filepath or a blob SAS URL"
)

if filepath_set:
# Explicitly set the blob SAS URL to None to avoid other code having to
# check if the value is the default description
Expand All @@ -126,19 +135,24 @@ def validate(self) -> None:
def sa_manifest_name(self) -> str:
"""Return the Storage account manifest name from the NFD name."""
return f"{self.nf_name}-sa-manifest-{self.version.replace('.', '-')}"

@property
def build_output_folder_name(self) -> str:
"""Return the local folder for generating the bicep template to."""
arm_template_path = self.arm_template.file_path
return (
f"{VNF_DEFINITION_OUTPUT_BICEP_PREFIX}{Path(str(arm_template_path)).stem}"
f"{DEFINITION_OUTPUT_BICEP_PREFIX}{Path(str(arm_template_path)).stem}"
)


@dataclass
class HelmPackageConfig:
name: str = "Name of the Helm package"
path_to_chart: str = "Path to the Helm chart"
depends_on: List[str] = field(default_factory=lambda: ["Names of the Helm packages this package depends on"])
name: str = DESCRIPTION_MAP["helm_package_name"]
path_to_chart: str = DESCRIPTION_MAP["path_to_chart"]
depends_on: List[str] = field(
default_factory=lambda: [DESCRIPTION_MAP["helm_depends_on"]]
)


@dataclass
class CNFConfiguration(NFConfiguration):
Expand All @@ -147,7 +161,7 @@ class CNFConfiguration(NFConfiguration):
def __post_init__(self):
"""
Cope with deserializing subclasses from dicts to HelmPackageConfig.
Used when creating CNFConfiguration object from a loaded json config file.
"""
for package in self.helm_packages:
Expand All @@ -157,9 +171,8 @@ def __post_init__(self):
@property
def build_output_folder_name(self) -> str:
"""Return the local folder for generating the bicep template to."""
return (
f"{VNF_DEFINITION_OUTPUT_BICEP_PREFIX}{self.nf_name}"
)
return f"{DEFINITION_OUTPUT_BICEP_PREFIX}{self.nf_name}"


def get_configuration(
definition_type: str, config_as_dict: Optional[Dict[Any, Any]] = None
Expand All @@ -179,4 +192,3 @@ def get_configuration(
)

return config

91 changes: 65 additions & 26 deletions src/aosm/azext_aosm/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@

import json
import os
import shutil
from dataclasses import asdict
from typing import Optional
from knack.log import get_logger
from azure.cli.core.azclierror import CLIInternalError, InvalidArgumentValueError, UnclassifiedUserFault

from azext_aosm.generate_nfd.cnf_nfd_generator import CnfNfdGenerator
from azext_aosm.generate_nfd.nfd_generator_base import NFDGenerator
from azext_aosm.generate_nfd.vnf_bicep_nfd_generator import VnfBicepNfdGenerator
from azext_aosm.generate_nfd.vnf_nfd_generator import VnfNfdGenerator
from azext_aosm.delete.delete import ResourceDeleter
from azext_aosm.deploy.deploy_with_arm import DeployerViaArm
from azext_aosm.util.constants import VNF, CNF, NSD
Expand All @@ -22,7 +24,6 @@
get_configuration,
NFConfiguration,
)
from azure.cli.core.azclierror import InvalidTemplateError, CLIInternalError


logger = get_logger(__name__)
Expand All @@ -32,7 +33,7 @@ def build_definition(cmd, definition_type: str, config_file: str):
"""
Build and optionally publish a definition.
:param cmd:
:param cmd:
:param config_file: path to the file
:param definition_type: VNF or CNF
"""
Expand All @@ -47,6 +48,9 @@ def generate_definition_config(definition_type: str, output_file: str = "input.j
"""
Generate an example config file for building a definition.
:param definition_type: CNF, VNF or NSD :param output_file: path to output config
file, defaults to "input.json" :type output_
file:
:param definition_type: CNF, VNF or NSD
:param output_file: path to output config file, defaults to "input.json"
:type output_file: str, optional
Expand All @@ -62,6 +66,10 @@ def _get_config_from_file(config_file: str, definition_type: str) -> NFConfigura
:param definition_type: VNF, CNF or NSD
:rtype: Configuration
"""

if not os.path.exists(config_file):
raise InvalidArgumentValueError(f"Config file {config_file} not found. Please specify a valid config file path.")

with open(config_file, "r", encoding="utf-8") as f:
config_as_dict = json.loads(f.read())

Expand All @@ -73,19 +81,22 @@ def _generate_nfd(definition_type, config):
"""Generate a Network Function Definition for the given type and config."""
nfd_generator: NFDGenerator
if definition_type == VNF:
nfd_generator = VnfBicepNfdGenerator(config)
nfd_generator = VnfNfdGenerator(config)
elif definition_type == CNF:
nfd_generator = CnfNfdGenerator(config)
else:
raise CLIInternalError(
"Generate NFD called for unrecognised definition_type. Only VNF and CNF have been implemented."
)
if nfd_generator.bicep_path:
raise InvalidTemplateError(
f"ERROR: Using the existing NFD bicep template {nfd_generator.bicep_path}.\nTo generate a new NFD, delete the folder {os.path.dirname(nfd_generator.bicep_path)} and re-run this command."
)
else:
nfd_generator.generate_nfd()
carry_on = input(
f"The folder {os.path.dirname(nfd_generator.bicep_path)} already exists - delete it and continue? (y/n)"
)
if carry_on != "y":
raise UnclassifiedUserFault("User aborted! ")

shutil.rmtree(os.path.dirname(nfd_generator.bicep_path))
nfd_generator.generate_nfd()


def publish_definition(
Expand All @@ -101,22 +112,37 @@ def publish_definition(
"""
Publish a generated definition.
:param cmd: :param client: :type client: HybridNetworkManagementClient :param
definition_type: VNF or CNF :param config_
file:
Path to the config file for the NFDV :param definition_file: Optional path to a
bicep template to deploy, in case the user wants to edit the
built NFDV template. If omitted, the default built NFDV
template will be used. :param parameters_json_
file:
Optional path to a parameters file for the bicep file, in case
the user wants to edit the built NFDV template. If omitted,
parameters from config will be turned into parameters for the
bicep file :param manifest_
file:
Optional path to an override bicep template to deploy
manifests :param manifest_parameters_json_
file:
:param cmd:
:param client:
:type client: HybridNetworkManagementClient
:param definition_type: VNF or CNF
:param config_file: Path to the config file for the NFDV
:param definition_file: Optional path to a bicep template to deploy, in case the user
wants to edit the built NFDV template. If omitted, the default
built NFDV template will be used.
:param definition_file: Optional path to a bicep template to deploy, in case the
user wants to edit the built NFDV template. If omitted, the default
built NFDV template will be used.
:param parameters_json_file: Optional path to a parameters file for the bicep file,
in case the user wants to edit the built NFDV template. If
omitted, parameters from config will be turned into parameters
for the bicep file
in case the user wants to edit the built NFDV template. If omitted,
parameters from config will be turned into parameters for the bicep file
:param manifest_file: Optional path to an override bicep template to deploy
manifests
manifests
:param manifest_parameters_json_file: Optional path to an override bicep parameters
file for manifest parameters
file for manifest parameters
"""
print("Publishing definition.")
api_clients = ApiClients(
Expand All @@ -133,7 +159,8 @@ def publish_definition(
)
else:
raise NotImplementedError(
"Publishing of CNF definitions is not yet implemented."
"Publishing of CNF definitions is not yet implemented. \
You should manually deploy your bicep file and upload charts and images to your artifact store. "
)


Expand All @@ -150,8 +177,8 @@ def delete_published_definition(
:param definition_type: CNF or VNF
:param config_file: Path to the config file
:param clean: if True, will delete the NFDG, artifact stores and publisher too.
Defaults to False. Only works if no resources have those as a parent.
Use with care.
Defaults to False. Only works if no resources have those as a parent. Use
with care.
"""
config = _get_config_from_file(config_file, definition_type)

Expand All @@ -172,6 +199,9 @@ def generate_design_config(output_file: str = "input.json"):
"""
Generate an example config file for building a NSD.
:param output_file: path to output config file, defaults to "input.json" :type
output_
file:
:param output_file: path to output config file, defaults to "input.json"
:type output_file: str, optional
"""
Expand All @@ -182,6 +212,9 @@ def _generate_config(definition_type: str, output_file: str = "input.json"):
"""
Generic generate config function for NFDs and NSDs.
:param definition_type: CNF, VNF or NSD :param output_file: path to output config
file, defaults to "input.json" :type output_
file:
:param definition_type: CNF, VNF or NSD
:param output_file: path to output config file, defaults to "input.json"
:type output_file: str, optional
Expand All @@ -203,9 +236,12 @@ def build_design(cmd, client: HybridNetworkManagementClient, config_file: str):
"""
Build and optionally publish a Network Service Design.
:param cmd:
:param cmd: :type cmd: _type_ :param client: :type client:
HybridNetworkManagementClient :param config_
file:
:param cmd:
:type cmd: _type_
:param client:
:param client:
:type client: HybridNetworkManagementClient
:param config_file: path to the file
"""
Expand All @@ -224,8 +260,8 @@ def delete_published_design(
:param definition_type: CNF or VNF
:param config_file: Path to the config file
:param clean: if True, will delete the NFDG, artifact stores and publisher too.
Defaults to False. Only works if no resources have those as a parent.
Use with care.
Defaults to False. Only works if no resources have those as a parent. Use
with care.
"""
raise NotImplementedError("Delete published design is not yet implented for NSD")

Expand All @@ -238,8 +274,11 @@ def publish_design(
"""
Publish a generated design.
:param cmd:
:param client:
:param cmd: :param client: :type client: HybridNetworkManagementClient :param
definition_type: VNF or CNF :param config_
file:
:param cmd:
:param client:
:type client: HybridNetworkManagementClient
:param definition_type: VNF or CNF
:param config_file: Path to the config file for the NFDV
Expand Down
12 changes: 5 additions & 7 deletions src/aosm/azext_aosm/delete/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ def delete_vnf(self, clean: bool = False):
Delete the NFDV and manifests. If they don't exist it still reports them as
deleted.
:param clean: Delete the NFDG, artifact stores and publisher too.
defaults to False
Use with care.
:param clean: Delete the NFDG, artifact stores and publisher too. defaults
to False Use with care.
"""
assert isinstance(self.config, VNFConfiguration)
if clean:
Expand Down Expand Up @@ -99,8 +98,8 @@ def delete_artifact_manifest(self, store_type: str) -> None:
_summary_
:param store_type: "sa" or "acr"
:raises CLIInternalError: If called with any other store type
:raises Exception if delete throws an exception
:raises CLIInternalError: If called with any other store type :raises
Exception if delete throws an exception
"""
if store_type == "sa":
assert isinstance(self.config, VNFConfiguration)
Expand Down Expand Up @@ -156,8 +155,7 @@ def delete_artifact_store(self, store_type: str) -> None:
"""Delete an artifact store
:param store_type: "sa" or "acr"
:raises CLIInternalError: If called with any other store type
:raises Exception if delete throws an exception
"""
:raises Exception if delete throws an exception."""
if store_type == "sa":
assert isinstance(self.config, VNFConfiguration)
store_name = self.config.blob_artifact_store_name
Expand Down
Loading

0 comments on commit c26369a

Please sign in to comment.