From c6d6680f9c75e8d4ccfef3d5a731a5b2de657459 Mon Sep 17 00:00:00 2001 From: sunnycarter <36891339+sunnycarter@users.noreply.github.com> Date: Wed, 24 May 2023 11:54:32 +0100 Subject: [PATCH] Refactor commands to az aosm nfd|nsd build (#10) * Refactor commands to az aosm nfd|nsd build * setup.py version * Version was wrong * remove publish option from build * lint * wrong params --- src/aosm/HISTORY.rst | 10 +- src/aosm/README.md | 28 ++-- src/aosm/azext_aosm/_params.py | 24 ++-- src/aosm/azext_aosm/commands.py | 9 +- src/aosm/azext_aosm/custom.py | 126 +++++++++++++----- .../generate_nfd/vnf_bicep_nfd_generator.py | 7 +- src/aosm/setup.py | 2 +- 7 files changed, 141 insertions(+), 65 deletions(-) diff --git a/src/aosm/HISTORY.rst b/src/aosm/HISTORY.rst index 8c34bccfff8..e5bcecabf4b 100644 --- a/src/aosm/HISTORY.rst +++ b/src/aosm/HISTORY.rst @@ -3,6 +3,14 @@ Release History =============== +0.2.0 +++++++ +Breaking change to commands - now use `nfd` instead of `definition`. Publish option removed from build. +* `az aosm nfd generate-config` for vnf and cnf. This is for NFDVs +* `az aosm nfd build|publish|delete --definition-type vnf|cnf` for vnf and `build` only for cnf. This is for NFDVs + 0.1.0 ++++++ -* Initial release. \ No newline at end of file +* Initial release - alpha quality + * `az aosm definition generate-config` for vnf and cnf. This is for NFDVs + * `az aosm definition build|publish|delete` for vnf and `build` only for cnf. This is for NFDVs diff --git a/src/aosm/README.md b/src/aosm/README.md index b8c13cbf599..7cc02dce08f 100644 --- a/src/aosm/README.md +++ b/src/aosm/README.md @@ -17,10 +17,10 @@ Eventually the extension will be published through the usual process and it will installed as usual, via `az extension add --name aosm` Until then, the latest development version can be found here: -https://github.com/jddarby/azure-cli-extensions/releases/download/aosm-extension/aosm-0.1.0-py2.py3-none-any.whl +https://github.com/jddarby/azure-cli-extensions/releases/download/aosm-extension/aosm-0.2.0-py2.py3-none-any.whl To install, download this wheel and run: -`az extension add --source path/to/aosm-0.1.0-py2.py3-none-any.whl` +`az extension add --source path/to/aosm-0.2.0-py2.py3-none-any.whl` ## Updating @@ -77,38 +77,40 @@ For CNFs, you must provide helm packages with an associated schema. When filling Get help on command arguments -`az aosm -h` -`az aosm definition -h` -`az aosm definition build -h` +`az aosm -h` +`az aosm nfd -h` +`az aosm nfd build -h` etc... -All these commands take a `--definition-type` argument of `vnf`, `cnf` or `nsd` +All these commands take a `--definition-type` argument of `vnf` or `cnf` Create an example config file for building a definition -`az aosm definition generate-config` +`az aosm nfd generate-config` This will output a file called `input.json` which must be filled in. Once the config file has been filled in the following commands can be run. -Build a definition locally +Build an nfd definition locally -`az aosm definition build --config-file input.json` +`az aosm nfd build --config-file input.json` Build and publish a definition -`az aosm definition build --config-file input.json --publish` +`az aosm nfd build --config-file input.json --publish` Publish a pre-built definition -`az aosm definition publish --config-file input.json` +`az aosm nfd publish --config-file input.json` Delete a published definition -`az aosm definition delete --config-file input.json` +`az aosm nfd delete --config-file input.json` Delete a published definition and the publisher, artifact stores and NFD group -`az aosm definition delete --config-file input.json --clean` +`az aosm nfd delete --config-file input.json --clean` +Coming soon: +`az aosm nsd build` and further nsd commands. diff --git a/src/aosm/azext_aosm/_params.py b/src/aosm/azext_aosm/_params.py index 1b9bcf60651..2098f52876e 100644 --- a/src/aosm/azext_aosm/_params.py +++ b/src/aosm/azext_aosm/_params.py @@ -17,11 +17,11 @@ def load_arguments(self: AzCommandsLoader, _): get_three_state_flag, ) - definition_type = get_enum_type([VNF, CNF, NSD]) + definition_type = get_enum_type([VNF, CNF]) # Set the argument context so these options are only available when this specific command # is called. - with self.argument_context("aosm definition") as c: + with self.argument_context("aosm nfd") as c: c.argument( "definition_type", arg_type=definition_type, help="Type of AOSM definition." ) @@ -32,11 +32,6 @@ def load_arguments(self: AzCommandsLoader, _): completer=FilesCompleter(allowednames="*.json"), help="The path to the configuration file.", ) - c.argument( - "publish", - arg_type=get_three_state_flag(), - help="Publishes generated AOSM definition.", - ) c.argument( "clean", arg_type=get_three_state_flag(), @@ -71,9 +66,16 @@ def load_arguments(self: AzCommandsLoader, _): help="Optional path to a parameters file for the manifest definition file. Use to override publish of the built definition and config with alternative parameters.", ) - with self.argument_context("aosm generate-config") as c: + with self.argument_context("aosm nsd") as c: c.argument( - "definition_type", - arg_type=definition_type, - help="Type of AOSM definition config to generate.", + "config_file", + options_list=["--config-file", "-f"], + type=file_type, + completer=FilesCompleter(allowednames="*.json"), + help="The path to the configuration file.", + ) + c.argument( + "clean", + arg_type=get_three_state_flag(), + help="Also delete artifact stores, NFD Group and Publisher. Use with care.", ) diff --git a/src/aosm/azext_aosm/commands.py b/src/aosm/azext_aosm/commands.py index a25fcf9d2c4..8fd99d31c23 100644 --- a/src/aosm/azext_aosm/commands.py +++ b/src/aosm/azext_aosm/commands.py @@ -10,13 +10,18 @@ def load_command_table(self: AzCommandsLoader, _): - with self.command_group("aosm definition", client_factory=cf_aosm) as g: + with self.command_group("aosm nfd", client_factory=cf_aosm) as g: # Add each command and bind it to a function in custom.py g.custom_command("generate-config", "generate_definition_config") g.custom_command("build", "build_definition") g.custom_command("delete", "delete_published_definition") - g.custom_command("show", "show_publisher") g.custom_command("publish", "publish_definition") + with self.command_group("aosm nsd", client_factory=cf_aosm) as g: + # Add each command and bind it to a function in custom.py + g.custom_command("generate-config", "generate_design_config") + g.custom_command("build", "build_design") + g.custom_command("delete", "delete_published_design") + g.custom_command("publish", "publish_design") with self.command_group("aosm", is_preview=True): pass diff --git a/src/aosm/azext_aosm/custom.py b/src/aosm/azext_aosm/custom.py index b7d7bce7097..3e0731b571d 100644 --- a/src/aosm/azext_aosm/custom.py +++ b/src/aosm/azext_aosm/custom.py @@ -14,7 +14,7 @@ from azext_aosm.generate_nfd.vnf_bicep_nfd_generator import VnfBicepNfdGenerator 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 +from azext_aosm.util.constants import VNF, CNF, NSD from azext_aosm.util.management_clients import ApiClients from azext_aosm.vendored_sdks import HybridNetworkManagementClient from azext_aosm._client_factory import cf_resources @@ -28,43 +28,20 @@ logger = get_logger(__name__) -def build_definition( - cmd, - client: HybridNetworkManagementClient, - definition_type: str, - config_file: str, - publish=False, -): +def build_definition(cmd, definition_type: str, config_file: str): """ Build and optionally publish a definition. :param cmd: - :type cmd: _type_ - :param client: - :type client: HybridNetworkManagementClient :param config_file: path to the file - :param definition_type: VNF, CNF or NSD - :param publish: _description_, defaults to False - :type publish: bool, optional + :param definition_type: VNF or CNF """ - api_clients = ApiClients( - aosm_client=client, resource_client=cf_resources(cmd.cli_ctx) - ) - # Read the config from the given file config = _get_config_from_file(config_file, definition_type) - # Generate the NFD/NSD and the artifact manifest. + # Generate the NFD and the artifact manifest. _generate_nfd(definition_type=definition_type, config=config) - # Publish the definition if publish is true - if publish: - if definition_type == VNF: - deployer = DeployerViaArm(api_clients, config=config) - deployer.deploy_vnfd_from_bicep() - else: - print("TODO - cannot publish CNF or NSD yet.") - def generate_definition_config(definition_type: str, output_file: str = "input.json"): """ @@ -74,13 +51,7 @@ def generate_definition_config(definition_type: str, output_file: str = "input.j :param output_file: path to output config file, defaults to "input.json" :type output_file: str, optional """ - config = get_configuration(definition_type) - config_as_dict = json.dumps(asdict(config), indent=4) - - with open(output_file, "w", encoding="utf-8") as f: - f.write(config_as_dict) - print(f"Empty definition configuration has been written to {output_file}") - logger.info(f"Empty definition configuration has been written to {output_file}") + _generate_config(definition_type, output_file) def _get_config_from_file(config_file: str, definition_type: str) -> NFConfiguration: @@ -160,6 +131,10 @@ def publish_definition( manifest_bicep_path=manifest_file, manifest_parameters_json_file=manifest_parameters_json_file, ) + else: + raise NotImplementedError( + "Publishing of CNF definitions is not yet implemented." + ) def delete_published_definition( @@ -187,7 +162,86 @@ def delete_published_definition( delly = ResourceDeleter(api_clients, config) if definition_type == VNF: delly.delete_vnf(clean=clean) + else: + raise NotImplementedError( + "Deleting of published CNF definitions is not yet implemented." + ) + + +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: str, optional + """ + _generate_config(NSD, output_file) + +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: str, optional + """ + config = get_configuration(definition_type) + config_as_dict = json.dumps(asdict(config), indent=4) -def show_publisher(): - pass + with open(output_file, "w", encoding="utf-8") as f: + f.write(config_as_dict) + if definition_type == CNF or definition_type == VNF: + prtName = "definition" + else: + prtName = "design" + print(f"Empty {prtName} configuration has been written to {output_file}") + logger.info(f"Empty {prtName} configuration has been written to {output_file}") + + +def build_design(cmd, client: HybridNetworkManagementClient, config_file: str): + """ + Build and optionally publish a Network Service Design. + + :param cmd: + :type cmd: _type_ + :param client: + :type client: HybridNetworkManagementClient + :param config_file: path to the file + """ + raise NotImplementedError("Build design is not yet implented for NSD") + + +def delete_published_design( + cmd, + client: HybridNetworkManagementClient, + config_file, + clean=False, +): + """ + Delete a published NSD. + + :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. + """ + raise NotImplementedError("Delete published design is not yet implented for NSD") + + +def publish_design( + cmd, + client: HybridNetworkManagementClient, + config_file, +): + """ + Publish a generated design. + + :param cmd: + :param client: + :type client: HybridNetworkManagementClient + :param definition_type: VNF or CNF + :param config_file: Path to the config file for the NFDV + """ + raise NotImplementedError("Publishing design is not yet implemented for NSD") diff --git a/src/aosm/azext_aosm/generate_nfd/vnf_bicep_nfd_generator.py b/src/aosm/azext_aosm/generate_nfd/vnf_bicep_nfd_generator.py index 482a50b3c73..d3bab0a6a95 100644 --- a/src/aosm/azext_aosm/generate_nfd/vnf_bicep_nfd_generator.py +++ b/src/aosm/azext_aosm/generate_nfd/vnf_bicep_nfd_generator.py @@ -50,6 +50,7 @@ def __init__(self, config: VNFConfiguration): ) def generate_nfd(self) -> None: + """Create a bicep template for an NFD from the ARM template for the VNF.""" """ Generate a VNF NFD which comprises an group, an Artifact Manifest and a NFDV. Create a bicep template for an NFD from the ARM template for the VNF. @@ -60,7 +61,11 @@ def generate_nfd(self) -> None: self._create_nfd_folder() self.create_parameter_files() self.copy_bicep() - print(f"Generated NFD bicep template created in {self.folder_name}") + print(f"Generated NFD bicep templates created in {self.folder_name}") + print( + "Please review these templates. When you are happy with them run " + "`az aosm nfd publish` with the same arguments." + ) @property def bicep_path(self) -> Optional[str]: diff --git a/src/aosm/setup.py b/src/aosm/setup.py index 873894c392d..9cd195a21b2 100644 --- a/src/aosm/setup.py +++ b/src/aosm/setup.py @@ -18,7 +18,7 @@ # TODO: Confirm this is the right version number you want and it matches your # HISTORY.rst entry. -VERSION = "0.1.0" +VERSION = "0.2.0" # The full list of classifiers is available at # https://pypi.python.org/pypi?%3Aaction=list_classifiers