Skip to content

Commit

Permalink
Priyavij/sitework (#188)
Browse files Browse the repository at this point in the history
* adding SNS handler and input config

* adding SNS handler and input config

* fixed style error

* new recording of vnf test

* fixed validations

* fixed UT and deploy_all_parameter

* fixed history

---------

Co-authored-by: Priya Vijayaraghavan <priyavij@microsoft.com>
  • Loading branch information
priyavj08 and Priya Vijayaraghavan authored May 10, 2024
1 parent eb492b0 commit f943f99
Show file tree
Hide file tree
Showing 11 changed files with 812 additions and 458 deletions.
4 changes: 2 additions & 2 deletions src/aosm/HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Release History
===============
2.0.0b2
++++++++
* Added check to make sure resource type used in ARM template are in allowed list
* added sns generate-config command
* added a check to make sure resource type used in ARM template are in allowed list
* Fixed multi NF RETs issue in nsdvs

2.0.0b1
++++++++
* Renamed nfdvName to nfdv in CGVs
Expand Down
23 changes: 23 additions & 0 deletions src/aosm/azext_aosm/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,26 @@
- name: Publish a Network Service Design.
text: az aosm nsd publish --build-output-folder my-nsd-output-folder
"""

helps[
"aosm sns"
] = """
type: group
short-summary: Manage AOSM Site Network Services.
long-summary: |
A Site Network Service (SNS) is a collection of network functions along with platform that come together to offer a service..
"""

helps[
"aosm sns generate-config"
] = """
type: command
short-summary: Generate configuration file for building an AOSM SNS.
long-summary: |
Generates a configuration file that you can use to build an AOSM Site Network Service (SNS). The configuration file is a JSONC file that contains the required parameters for building the SNS. You must complete the configuration file with your specific values before building the SNS.
examples:
- name: Generate a configuration file for a Site Network Service.
text: az aosm sns generate-config
- name: Generate a configuration file for a Site Network Service and write to a specific file.
text: az aosm sns generate-config --output-file my-sns-input-config.jsonc
"""
18 changes: 18 additions & 0 deletions src/aosm/azext_aosm/_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,21 @@ def load_arguments(self: AzCommandsLoader, _):
"Requires Docker to be installed locally."
),
)

with self.argument_context("aosm sns") as c:
c.argument(
"output_file",
options_list=["--output-file"],
help="The name of the output file to write the generated config text to.",
required=False,
)
c.argument(
"config_file",
options_list=["--config-file", "-f"],
type=file_type,
completer=FilesCompleter(allowednames="*.jsonc"),
help=(
"The path to the configuration file. This is a JSONC file that contains"
" the required parameters for building the NSD."
),
)
93 changes: 93 additions & 0 deletions src/aosm/azext_aosm/cli_handlers/onboarding_sns_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
from __future__ import annotations

import json
from pathlib import Path
from typing import Optional

from knack.log import get_logger
from azext_aosm.cli_handlers.onboarding_nfd_base_handler import OnboardingBaseCLIHandler
from azext_aosm.common.constants import (
SNS_OUTPUT_FOLDER_FILENAME,
SNS_INPUT_FILENAME
)
from azext_aosm.configuration_models.common_parameters_config import (
SNSCommonParametersConfig,
)
from azext_aosm.definition_folder.builder.bicep_builder import (
BicepDefinitionElementBuilder,
)
from azext_aosm.definition_folder.builder.json_builder import (
JSONDefinitionElementBuilder,
)
from azext_aosm.configuration_models.onboarding_sns_input_config import SiteNetworkServicePropertiesConfig
logger = get_logger(__name__)


class SNSCLIHandler(OnboardingBaseCLIHandler):
"""CLI handler for SNS."""

config: SiteNetworkServicePropertiesConfig

@property
def default_config_file_name(self) -> str:
"""Get the default configuration file name."""
return SNS_INPUT_FILENAME

@property
def output_folder_file_name(self) -> str:
"""Get the output folder file name."""
return SNS_OUTPUT_FOLDER_FILENAME

def build(self):
"""Build the definition."""
self.definition_folder_builder.add_element(self.build_all_parameters_json())
self.definition_folder_builder.write()

def _get_input_config(self, input_config: Optional[dict] = None) -> SiteNetworkServicePropertiesConfig:
"""Get the configuration for the command."""
if input_config is None:
input_config = {}
return SiteNetworkServicePropertiesConfig(**input_config)

def _get_params_config(self, config_file: Path) -> SNSCommonParametersConfig:
"""Get the configuration for the command."""
with open(config_file, "r", encoding="utf-8") as _file:
params_dict = json.load(_file)
if params_dict is None:
params_dict = {}
return SNSCommonParametersConfig(**params_dict)

def build_base_bicep(self) -> BicepDefinitionElementBuilder:
pass

def build_all_parameters_json(self) -> JSONDefinitionElementBuilder:
"""Build all parameters json."""
params_content = {
"location": self.config.location,
"operatorResourceGroupName": self.config.operator_resource_group_name,
"siteName": self.config.site_name
}
base_file = JSONDefinitionElementBuilder(
Path(SNS_OUTPUT_FOLDER_FILENAME), json.dumps(params_content, indent=4)
)
return base_file

def _get_processor_list(self):
# Provide an implementation for this method
pass

def build_artifact_list(self):
# Provide an implementation for this method
pass

def build_manifest_bicep(self):
# Provide an implementation for this method
pass

def build_resource_bicep(self) -> BicepDefinitionElementBuilder:
# Provide an implementation for this method
pass
5 changes: 5 additions & 0 deletions src/aosm/azext_aosm/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,10 @@ def load_command_table(self: AzCommandsLoader, _):
g.custom_command("publish", "onboard_nsd_publish")
# g.custom_command("delete", "onboard_nsd_delete")

with self.command_group("aosm sns") as g:
# Add each command and bind it to a function in custom.py
g.custom_command("generate-config", "onboard_sns_generate_config")
g.custom_command("build", "onboard_sns_build")

with self.command_group("aosm", is_preview=True):
pass
3 changes: 3 additions & 0 deletions src/aosm/azext_aosm/common/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ class ManifestsExist(str, Enum):
'Microsoft.ManagedIdentity'
]

SNS_OUTPUT_FOLDER_FILENAME = "sns-cli-output"
SNS_INPUT_FILENAME = "sns-input.jsonc"

#################
# OLD CONSTANTS #
#################
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,11 @@ class NSDCommonParametersConfig(BaseCommonParametersConfig):
nsDesignGroup: str
nsDesignVersion: str
nfviSiteName: str


@dataclass(frozen=True)
class SNSCommonParametersConfig():
"""Common parameters configuration for SNS."""
location: str
operator_resource_group: str
site_name: str
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# --------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See License.txt in the project root for license information.
# --------------------------------------------------------------------------------------------
from __future__ import annotations

from dataclasses import dataclass, field

from azure.cli.core.azclierror import ValidationError
import semver


@dataclass
class SiteNetworkServicePropertiesConfig:
"""SNS Object."""
location: str = field(
default="",
metadata={
"comment": "Azure location to use when creating resources e.g uksouth"
},
)
operator_resource_group_name: str = field(
default="",
metadata={"comment": "The resource group that the operator resources will be hosted in."},
)
site_name: str = field(
default="",
metadata={"comment": "Name of the site."},
)
nsd_reference: NSDVReferenceConfig = (
field(
default=None,
metadata={
"comment": ("Information regarding NSDV to be used in SNS.")
},
)
)

def validate(self):
"""Validate the configuration."""
if not self.location:
raise ValidationError("Location must be set")
if not self.operator_resource_group_name:
raise ValidationError("Operator resource group name must be set")
if not self.site_name:
raise ValidationError(
"site name must be set"
)
if not self.nsd_reference:
raise ValidationError("At least one Network Service Design Version must be included.")
self.nsd_reference.validate()

def __post_init__(self):
if self.nsd_reference is None:
self.nsd_reference = {}
self.nsd_reference = NSDVReferenceConfig(**self.nsd_reference)


@dataclass
class NSDVReferenceConfig:
"""NSDV Reference."""
publisher_name: str = field(
default="",
metadata={
"comment": "Name of the Publisher resource where Network Service Design resource to be used in SNS exists"
},
)
publisher_resource_group_name: str = field(
default="",
metadata={"comment": "The resource group that the publisher NSDV is hosted in. "},
)
nsd_name: str = field(
default="",
metadata={"comment": "Network Service Design"
"(NSD) to be used from the publisher. This is the collection of Network Service Design Versions. "},
)
nsd_version: str = field(
default="",
metadata={"comment": "Version of the NSD to be used which is in the format A.B.C "},
)

def validate(self):
"""Validate the configuration."""
if not self.publisher_name:
raise ValidationError("Publisher Name must be set")
if not self.publisher_resource_group_name:
raise ValidationError("Publisher Resource Group must be set")
if not self.nsd_name:
raise ValidationError(
"NSD Name must be set"
)
if not self.nsd_version:
raise ValidationError(
"NSD Version must be set"
)
try:
semver.VersionInfo.parse(self.nsd_version)
except ValueError:
raise ValidationError(f"{self.nsd_version} is not a valid semantic version")

def to_dict(self):
return {
'publisher_name': self.publisher_name,
'publisher_resource_group_name': self.publisher_resource_group_name,
'nsd_name': self.nsd_name,
'nsd_version': self.nsd_version
}
14 changes: 14 additions & 0 deletions src/aosm/azext_aosm/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from azext_aosm.cli_handlers.onboarding_nsd_handler import OnboardingNSDCLIHandler
from azext_aosm.common.command_context import CommandContext
from azext_aosm.common.constants import ALL_PARAMETERS_FILE_NAME, CNF, VNF, VNF_NEXUS
from azext_aosm.cli_handlers.onboarding_sns_handler import SNSCLIHandler


def onboard_nfd_generate_config(definition_type: str, output_file: str | None):
Expand Down Expand Up @@ -130,6 +131,19 @@ def onboard_nsd_publish(
handler.publish(command_context=command_context)


def onboard_sns_generate_config(output_file: str | None):
"""Generate config file for onboarding SNS."""
handler = SNSCLIHandler()
handler.generate_config(output_file)


def onboard_sns_build(config_file: Path, cmd: AzCliCommand):
"""Build the Site Network Service."""
command_context = CommandContext(cli_ctx=cmd.cli_ctx)
handler = SNSCLIHandler(config_file_path=Path(config_file),
aosm_client=command_context.aosm_client)
handler.build()

# def onboard_nsd_delete(cmd: AzCliCommand, config_file: str):
# """Delete the NSD definition."""
# command_context = CommandContext(cmd.cli_ctx)
Expand Down
Loading

0 comments on commit f943f99

Please sign in to comment.