From 78b6e6df5f70557276fa4814327c9237520f9ec2 Mon Sep 17 00:00:00 2001 From: David Garcia Date: Fri, 29 Apr 2022 05:50:46 +0200 Subject: [PATCH] Add implicit osm-config configuration parameter to charm - feature 10800: day-2 primitives for Helm Charts - osm-config is only used for now in KDUs Change-Id: I7c8c3f8d4c7d5281038b243de48d704f781b5d47 Signed-off-by: David Garcia --- osm_lcm/data_utils/vnfd.py | 10 ++++++ osm_lcm/ns.py | 34 ++++++++++++++++++-- osm_lcm/osm_config.py | 64 ++++++++++++++++++++++++++++++++++++++ requirements.in | 1 + requirements.txt | 2 ++ 5 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 osm_lcm/osm_config.py diff --git a/osm_lcm/data_utils/vnfd.py b/osm_lcm/data_utils/vnfd.py index 714487c..f8c11ca 100644 --- a/osm_lcm/data_utils/vnfd.py +++ b/osm_lcm/data_utils/vnfd.py @@ -37,6 +37,16 @@ def get_kdu_list(vnfd): return vnfd.get("kdu", ()) +def get_kdu(vnfd, kdu_name): + return list_utils.find_in_list( + get_kdu_list(vnfd), lambda kdu: kdu["name"] == kdu_name + ) + + +def get_kdu_services(kdu): + return kdu.get("service", []) + + def get_ee_sorted_initial_config_primitive_list( primitive_list, vca_deployed, ee_descriptor_id ): diff --git a/osm_lcm/ns.py b/osm_lcm/ns.py index 5bbbb21..901954e 100644 --- a/osm_lcm/ns.py +++ b/osm_lcm/ns.py @@ -62,6 +62,8 @@ from osm_lcm.data_utils.nsd import ( get_vnf_profiles, ) from osm_lcm.data_utils.vnfd import ( + get_kdu, + get_kdu_services, get_relation_list, get_vdu_list, get_vdu_profile, @@ -96,6 +98,7 @@ from n2vc.n2vc_juju_conn import N2VCJujuConnector from n2vc.exceptions import N2VCException, N2VCNotFound, K8sException from osm_lcm.lcm_helm_conn import LCMHelmConn +from osm_lcm.osm_config import OsmConfigBuilder from osm_lcm.prometheus import parse_job from copy import copy, deepcopy @@ -1419,7 +1422,7 @@ class NsLcm(LcmBase): :param nsr_id: :param vnfr_id: :param kdu_name: - :return: IP address + :return: IP address, K8s services """ # self.logger.debug(logging_text + "Starting wait_kdu_up") @@ -1441,7 +1444,7 @@ class NsLcm(LcmBase): ) if kdur.get("status"): if kdur["status"] in ("READY", "ENABLED"): - return kdur.get("ip-address") + return kdur.get("ip-address"), kdur.get("services") else: raise LcmException( "target KDU={} is in error state".format(kdu_name) @@ -1984,9 +1987,33 @@ class NsLcm(LcmBase): # wait for RO (ip-address) Insert pub_key into VM if vnfr_id: if kdu_name: - rw_mgmt_ip = await self.wait_kdu_up( + rw_mgmt_ip, services = await self.wait_kdu_up( logging_text, nsr_id, vnfr_id, kdu_name ) + vnfd = self.db.get_one( + "vnfds_revisions", + {"_id": f'{db_vnfr["vnfd-id"]}:{db_vnfr["revision"]}'}, + ) + kdu = get_kdu(vnfd, kdu_name) + kdu_services = [ + service["name"] for service in get_kdu_services(kdu) + ] + exposed_services = [] + for service in services: + if any(s in service["name"] for s in kdu_services): + exposed_services.append(service) + await self.vca_map[vca_type].exec_primitive( + ee_id=ee_id, + primitive_name="config", + params_dict={ + "osm-config": json.dumps( + OsmConfigBuilder( + k8s={"services": exposed_services} + ).build() + ) + }, + vca_id=vca_id, + ) else: rw_mgmt_ip = await self.wait_vm_up_insert_key_ro( logging_text, @@ -1997,6 +2024,7 @@ class NsLcm(LcmBase): user=user, pub_key=pub_key, ) + else: rw_mgmt_ip = None # This is for a NS configuration diff --git a/osm_lcm/osm_config.py b/osm_lcm/osm_config.py new file mode 100644 index 0000000..7dd8f63 --- /dev/null +++ b/osm_lcm/osm_config.py @@ -0,0 +1,64 @@ +# Copyright 2022 Canonical Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Any, Dict, List, Optional +from pydantic import BaseModel, validator + + +def _get_ip_from_service(service: Dict[str, Any]) -> List[str]: + return ( + [service["cluster_ip"]] + if service["type"] == "ClusterIP" + else service["external_ip"] + ) + + +class K8sConfigV0(BaseModel): + services: List[Dict] + + @validator("services") + def parse_services(cls, services: Dict[str, Any]): + return { + service["name"]: { + "type": service["type"], + "ip": _get_ip_from_service(service), + "ports": { + port["name"]: { + "port": port["port"], + "protocol": port["protocol"], + } + for port in service["ports"] + }, + } + for service in services + } + + +class OsmConfigV0(BaseModel): + k8s: Optional[K8sConfigV0] + + +class OsmConfig(BaseModel): + v0: OsmConfigV0 + + +class OsmConfigBuilder: + def __init__(self, k8s: Dict[str, Any] = {}) -> None: + self._k8s = k8s + self._configs = {} + if k8s: + self._configs["k8s"] = k8s + + def build(self) -> Dict[str, Any]: + return OsmConfig(v0=OsmConfigV0(**self._configs)).dict() diff --git a/requirements.in b/requirements.in index 3b86ffc..6efebb2 100644 --- a/requirements.in +++ b/requirements.in @@ -19,3 +19,4 @@ grpclib idna jinja2 pyyaml==5.4.1 +pydantic diff --git a/requirements.txt b/requirements.txt index 46bfd9b..0756c97 100644 --- a/requirements.txt +++ b/requirements.txt @@ -51,6 +51,8 @@ multidict==5.2.0 # yarl protobuf==3.19.3 # via grpcio-tools +pydantic==1.9.0 + # via -r requirements.in pyyaml==5.4.1 # via -r requirements.in six==1.16.0 -- 2.25.1