Skip to content

Commit

Permalink
Add Publish command to the CNF azure CLI (Azure#24)
Browse files Browse the repository at this point in the history
* Working publish

* Fix the artifact upload

* Working image copy

* minor fix

* Minor fixes

* sunny merge add-aosm-extension into patryk's branch (Azure#25)

* Sunny/choose deploy parameters (Azure#23)

* choose-deploy-parameters

* optioned deployParameters for CNF

* lint

* lint2

* docs

* docs

* lint

* 9.82 score

* Fix bugs

* more useful debug logs

* Fix bugs and logging

* lint

* markups

* comment out breaking line

* minor TODOs

* deleted comment

* fix bring your own parameters

* Markups

* Fix the helm upload

* Minor markups

* Change error message

---------

Co-authored-by: sunnycarter <36891339+sunnycarter@users.noreply.github.com>
Co-authored-by: Sunny Carter <sunny.carter@metaswitch.com>
  • Loading branch information
3 people authored Jun 23, 2023
1 parent 4013895 commit 689acf4
Show file tree
Hide file tree
Showing 13 changed files with 496 additions and 96 deletions.
1 change: 1 addition & 0 deletions src/aosm/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Release History
unreleased
++++++++++
* `az aosm nfd build` options `--order-params` and `--interactive` to help users choose which NF parameters to expose as deployParameters. Feature added that allows CNF value mappings file to be generated if none is supplied.
* `az aosm nfd publish` option added for `--definition-type cnf` to publish the CNF bicep templates, upload helm charts from disk to the ACR and copy the images from a source ACR to the target ACR.

0.2.0
++++++
Expand Down
43 changes: 23 additions & 20 deletions src/aosm/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,28 +67,31 @@ image that would be used for the VNF Virtual Machine.

#### CNFs

For CNFs, you must provide helm packages with an associated schema.
Optionally, you can provide a file path_to_mappings which is a copy of values.yaml with your chosen values replaced by deployment parameters, thus exposing them as parameters to the CNF. You can get this file auto-generated by leaving the value as a blank string, either having every value as
a deployment parameter, or using --interactive to interactively choose.
For CNFs you must have the `helm` package installed on the machine you are running the CLI from. Instructions on how to do this can be found [here](https://helm.sh/docs/intro/install/).

For CNFs, you must provide:
* helm packages with an associated schema. These files must be on your disk and will be referenced in the `input.json` config file.
* a reference to an existing Azure Container Registry which contains the images for your CNF. Currently, only one ACR is supported per CNF. The images to be copied from this ACR are populated automatically based on the helm package schema.
* optionally, you can provide a file (on disk) path_to_mappings which is a copy of values.yaml with your chosen values replaced by deployment parameters, thus exposing them as parameters to the CNF. You can get this file auto-generated by leaving the value as a blank string, either having every value as a deployment parameter, or using `--interactive` to interactively choose.
When filling in the input.json file, you must list helm packages in the order they are to be deployed. For example, if A must be deployed before B, your input.json should look something like this:

"helm_packages": [
{
"name": "A",
"path_to_chart": "Path to package A",
"path_to_mappings": "Path to package A mappings",
"depends_on": [
"Names of the Helm packages this package depends on"
]
},
{
"name": "B",
"path_to_chart": "Path to package B",
"path_to_mappings": "Path to package B mappings",
"depends_on": [
"Names of the Helm packages this package depends on"
]
},
"helm_packages": [
{
"name": "A",
"path_to_chart": "Path to package A",
"path_to_mappings": "Path to package A mappings",
"depends_on": [
"Names of the Helm packages this package depends on"
]
},
{
"name": "B",
"path_to_chart": "Path to package B",
"path_to_mappings": "Path to package B mappings",
"depends_on": [
"Names of the Helm packages this package depends on"
]
},

#### NSDs
For NSDs, you will need to have a Resource Group with a deployed Publisher, Artifact Store, Network Function Definition and Network Function Definition Version. You can use the `az aosm nfd` commands to create all of these resources.
Expand Down
13 changes: 13 additions & 0 deletions src/aosm/azext_aosm/_client_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from azure.cli.core.profiles import ResourceType

from .vendored_sdks import HybridNetworkManagementClient
from azure.mgmt.containerregistry import ContainerRegistryManagementClient


def cf_aosm(cli_ctx, *_) -> HybridNetworkManagementClient:
Expand All @@ -17,3 +18,15 @@ def cf_resources(cli_ctx, subscription_id=None):
return get_mgmt_service_client(
cli_ctx, ResourceType.MGMT_RESOURCE_RESOURCES, subscription_id=subscription_id
)


def cf_acr_registries(cli_ctx, *_) -> ContainerRegistryManagementClient:
"""
Returns the client for managing container registries.
:param cli_ctx: CLI context
:return: ContainerRegistryManagementClient object
"""
return get_mgmt_service_client(
cli_ctx, ResourceType.MGMT_CONTAINERREGISTRY
).registries
43 changes: 23 additions & 20 deletions src/aosm/azext_aosm/_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,20 @@
"Name of the storage account Artifact Store resource. Will be created if it "
"does not exist.",
"artifact_name": "Name of the artifact",
"file_path":
"Optional. File path of the artifact you wish to upload from your local disk. "
"Delete if not required.",
"blob_sas_url":
"Optional. SAS URL of the blob artifact you wish to copy to your Artifact Store. "
"Delete if not required.",
"artifact_version":
"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",
"file_path": "Optional. File path of the artifact you wish to upload from your local disk. "
"Delete if not required.",
"blob_sas_url": "Optional. SAS URL of the blob artifact you wish to copy to your Artifact Store. "
"Delete if not required.",
"artifact_version": "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",
"nsdv_description": "Description of the NSDV",
"nsdg_name":
"Network Service Design Group Name. This is the collection of Network Service Design Versions. "
"Will be created if it does not exist.",
"nsdg_name": "Network Service Design Group Name. This is the collection of Network Service Design Versions. "
"Will be created if it does not exist.",
"nsd_version": "Version of the NSD to be created. This should be in the format A.B.C",
"network_function_definition_group_name":
"Exising Network Function Definition Group Name. "
"This can be created using the 'az aosm nfd' commands.",
"network_function_definition_version_name":
"Exising Network Function Definition Version Name. "
"This can be created using the 'az aosm nfd' commands.",
"network_function_definition_group_name": "Exising Network Function Definition Group Name. "
"This can be created using the 'az aosm nfd' commands.",
"network_function_definition_version_name": "Exising Network Function Definition Version Name. "
"This can be created using the 'az aosm nfd' commands.",
"network_function_definition_offering_location": "Offering location of the Network Function Definition",
"network_function_type": "Type of nf in the definition. Valid values are 'cnf' or 'vnf'",
"helm_package_name": "Name of the Helm package",
Expand All @@ -72,6 +66,7 @@
"helm_depends_on":
"Names of the Helm packages this package depends on. "
"Leave as an empty array if no dependencies",
"source_registry_id": "Resource ID of the source acr registry from which to pull the image",
}


Expand Down Expand Up @@ -303,6 +298,7 @@ class HelmPackageConfig:

@dataclass
class CNFConfiguration(NFConfiguration):
source_registry_id: str = DESCRIPTION_MAP["source_registry_id"]
helm_packages: List[Any] = field(default_factory=lambda: [HelmPackageConfig()])

def __post_init__(self):
Expand All @@ -311,9 +307,9 @@ def __post_init__(self):
Used when creating CNFConfiguration object from a loaded json config file.
"""
for package in self.helm_packages:
for package_index, package in enumerate(self.helm_packages):
if isinstance(package, dict):
package = HelmPackageConfig(**dict(package))
self.helm_packages[package_index] = HelmPackageConfig(**dict(package))

@property
def build_output_folder_name(self) -> str:
Expand All @@ -324,6 +320,13 @@ def build_output_folder_name(self) -> str:
def get_configuration(
configuration_type: str, config_as_dict: Optional[Dict[Any, Any]] = None
) -> NFConfiguration or NSConfiguration:
"""
Return the correct configuration object based on the type.
:param configuration_type: The type of configuration to return
:param config_as_dict: The configuration as a dictionary
:return: The configuration object
"""
if config_as_dict is None:
config_as_dict = {}

Expand Down
30 changes: 22 additions & 8 deletions src/aosm/azext_aosm/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
)
from knack.log import get_logger

from azext_aosm._client_factory import cf_resources
from azext_aosm._client_factory import cf_resources, cf_acr_registries
from azext_aosm._configuration import (
CNFConfiguration,
NFConfiguration,
Expand Down Expand Up @@ -156,11 +156,15 @@ def publish_definition(
"""
print("Publishing definition.")
api_clients = ApiClients(
aosm_client=client, resource_client=cf_resources(cmd.cli_ctx)
aosm_client=client,
resource_client=cf_resources(cmd.cli_ctx),
container_registry_client=cf_acr_registries(cmd.cli_ctx),
)

config = _get_config_from_file(
config_file=config_file, configuration_type=definition_type
)

if definition_type == VNF:
deployer = DeployerViaArm(api_clients, config=config)
deployer.deploy_vnfd_from_bicep(
Expand All @@ -169,10 +173,18 @@ def publish_definition(
manifest_bicep_path=manifest_file,
manifest_parameters_json_file=manifest_parameters_json_file,
)
elif definition_type == CNF:
deployer = DeployerViaArm(api_clients, config=config)
deployer.deploy_cnfd_from_bicep(
cli_ctx=cmd.cli_ctx,
bicep_path=definition_file,
parameters_json_file=parameters_json_file,
manifest_bicep_path=manifest_file,
manifest_parameters_json_file=manifest_parameters_json_file,
)
else:
raise NotImplementedError(
"Publishing of CNF definitions is not yet implemented. \
You should manually deploy your bicep file and upload charts and images to your artifact store. "
raise ValueError(
f"Definition type must be either 'vnf' or 'cnf'. Definition type {definition_type} is not recognised."
)


Expand Down Expand Up @@ -202,10 +214,12 @@ def delete_published_definition(

delly = ResourceDeleter(api_clients, config)
if definition_type == VNF:
delly.delete_vnf(clean=clean)
delly.delete_nfd(clean=clean)
elif definition_type == CNF:
delly.delete_nfd(clean=clean)
else:
raise NotImplementedError(
"Deleting of published CNF definitions is not yet implemented."
raise ValueError(
f"Definition type must be either 'vnf' or 'cnf'. Definition type {definition_type} is not recognised."
)


Expand Down
15 changes: 9 additions & 6 deletions src/aosm/azext_aosm/delete/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ def __init__(
self.api_clients = api_clients
self.config = config

def delete_vnf(self, clean: bool = False):
def delete_nfd(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:
print(
f"Are you sure you want to delete all resources associated with NFD {self.config.nf_name} including the artifact stores and publisher {self.config.publisher_name}?"
Expand All @@ -63,14 +63,17 @@ def delete_vnf(self, clean: bool = False):
return

self.delete_nfdv()
self.delete_artifact_manifest("sa")

if isinstance(self.config, VNFConfiguration):
self.delete_artifact_manifest("sa")
self.delete_artifact_manifest("acr")

if clean:
logger.info("Delete called for all resources.")
self.delete_nfdg()
self.delete_artifact_store("acr")
self.delete_artifact_store("sa")
if isinstance(self.config, VNFConfiguration):
self.delete_artifact_store("sa")
self.delete_publisher()

def delete_nsd(self):
Expand Down
Loading

0 comments on commit 689acf4

Please sign in to comment.