diff options
author | Eli Halych <illia.halych@t-mobile.pl> | 2020-11-25 10:52:03 +0000 |
---|---|---|
committer | Eli Halych <illia.halych@t-mobile.pl> | 2020-12-14 15:14:25 +0000 |
commit | 95843eb0910fc9a0f05fc680160c5dec2aba1ba2 (patch) | |
tree | 645100af5ba0713b5116c4a30ec1e2d955907818 | |
parent | a6fe8be6c1d1eb9e7293ed1c3bb63a76646fe22c (diff) |
Add PNF simulator execution and cleanup as a BaseStep
1. The simulator is the masspnfsim from integration project. Added as a git submodule.
2. The flow: build image, bootstrap simulator, run simulator, stop simulator,
remove simulator, remove image (only simulator).
3. Additionally trigger (sending a message to VES) is handled in pnf/utils.py. To send a request to VES,
vesip in settings.PNF_VES_CONFIG should be set to the one accessible from simulator container. Default one
(172.17.0.1) communicates with the machine the simulator runs at.
4. commonEventHeader's fields can be overridden in settings.py (here sourceName, reportingEntityName)
Issue-ID: TEST-278
Signed-off-by: Eli Halych <illia.halych@t-mobile.pl>
Change-Id: Id77dc8c517a30458abd81f2aadc416204be522b5
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | requirements.txt | 1 | ||||
m--------- | src/onaptests/integration | 0 | ||||
-rw-r--r-- | src/onaptests/steps/simulator/pnf/__init__.py | 0 | ||||
-rw-r--r-- | src/onaptests/steps/simulator/pnf/pnf_config.yaml | 16 | ||||
-rw-r--r-- | src/onaptests/steps/simulator/pnf/pnf_instantiate.py | 30 | ||||
-rw-r--r-- | src/onaptests/steps/simulator/pnf/pnf_register.py | 38 | ||||
-rw-r--r-- | src/onaptests/steps/simulator/pnf/utils.py | 153 |
9 files changed, 242 insertions, 0 deletions
@@ -31,3 +31,4 @@ csit/ benchmark/ .tox/ **/__pycache__/ +*.pyc diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..bf396ae --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "src/onaptests/integration"] + path = src/onaptests/integration + url = ../../integration diff --git a/requirements.txt b/requirements.txt index f56f12e..ead56f4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ openstacksdk onapsdk>=7.1.0 jinja2 kubernetes +docker
\ No newline at end of file diff --git a/src/onaptests/integration b/src/onaptests/integration new file mode 160000 +Subproject b01945987f9a0ab3ac5f4895ffd03c8e975036b diff --git a/src/onaptests/steps/simulator/pnf/__init__.py b/src/onaptests/steps/simulator/pnf/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/onaptests/steps/simulator/pnf/__init__.py diff --git a/src/onaptests/steps/simulator/pnf/pnf_config.yaml b/src/onaptests/steps/simulator/pnf/pnf_config.yaml new file mode 100644 index 0000000..13b0289 --- /dev/null +++ b/src/onaptests/steps/simulator/pnf/pnf_config.yaml @@ -0,0 +1,16 @@ +setup: + count: 1 + vesprotocol: http # use `https` for the real VES + vesip: 172.17.0.1 # use 172.17.0.1 to communicate with localhost + vesport: 10000 + vesresource: eventListener + vesversion: v7 + ipstart: 10.11.0.16 + user: "" + password: "" + ipfileserver: 127.0.0.1 + typefileserver: sftp +data: + commonEventHeaderParams: + sourceName: pyint-000 + reportingEntityName: pyint-000 diff --git a/src/onaptests/steps/simulator/pnf/pnf_instantiate.py b/src/onaptests/steps/simulator/pnf/pnf_instantiate.py new file mode 100644 index 0000000..31ea6bf --- /dev/null +++ b/src/onaptests/steps/simulator/pnf/pnf_instantiate.py @@ -0,0 +1,30 @@ +"""Base step that runs a PNF simulator.""" +from onaptests.steps.simulator.pnf import utils +from onaptests.steps.base import BaseStep + +class PNFInstanceStep(BaseStep): + """Run PNF simulator containers.""" + + @property + def description(self) -> str: + """Step description.""" + return "Run PNF simulator containers." + + @property + def component(self) -> str: + """Component name.""" + return "Environment" + + @BaseStep.store_state + def execute(self) -> None: + """Run PNF simulator containers.""" + utils.build_image() + utils.bootstrap_simulator() + utils.run_container() + + @BaseStep.store_state + def cleanup(self) -> None: + """Remove containers and images.""" + utils.stop_container() + utils.remove_simulator() + utils.remove_image() diff --git a/src/onaptests/steps/simulator/pnf/pnf_register.py b/src/onaptests/steps/simulator/pnf/pnf_register.py new file mode 100644 index 0000000..8d5467a --- /dev/null +++ b/src/onaptests/steps/simulator/pnf/pnf_register.py @@ -0,0 +1,38 @@ +"""Base step that runs a PNF simulator.""" +from onaptests.steps.simulator.pnf import utils +from onaptests.steps.base import BaseStep +from onaptests.steps.simulator.pnf.pnf_instantiate import PNFInstanceStep + +class PNFRegisterStep(BaseStep): + """Run PNF simulator containers.""" + + def __init__(self, cleanup=True): + """Initialize step. + + Substeps: + - PNFInstanceStep + + """ + super().__init__(cleanup=cleanup) + self.add_step(PNFInstanceStep(cleanup=cleanup)) + + @property + def description(self) -> str: + """Step description.""" + return "Register PNF with VES." + + @property + def component(self) -> str: + """Component name.""" + return "Environment" + + @BaseStep.store_state + def execute(self) -> None: + """Register with VES.""" + super().execute() + utils.register() + + @BaseStep.store_state + def cleanup(self) -> None: + """Substeps cleanup - no unregister.""" + super().cleanup() diff --git a/src/onaptests/steps/simulator/pnf/utils.py b/src/onaptests/steps/simulator/pnf/utils.py new file mode 100644 index 0000000..3f9b233 --- /dev/null +++ b/src/onaptests/steps/simulator/pnf/utils.py @@ -0,0 +1,153 @@ +"""Utility functions that invoke operations of simulator script.""" +import os +import sys +import time +import yaml +from ipaddress import ip_address +from typing import Dict, Optional +from decorator import decorator +import docker +from onaptests.integration.test.mocks.masspnfsim.MassPnfSim import ( + MassPnfSim, get_parser +) + +def get_config() -> Dict: + """Read a config YAML file.""" + config = None + dir_path = os.path.dirname(os.path.realpath(__file__)) + with open(f"{dir_path}/pnf_config.yaml", "r") as ymlfile: + config = yaml.load(ymlfile) + return config + +def get_default_args() -> None: + """Prepare default arguments for required operations. + + Returns: + args (argparse.Namespace): default arguments. + + """ + parser = get_parser() + args = parser.parse_args('') + return args + +def switch_workdir(back_pwd: str = None) -> Optional[str]: + """Switch work directory temporarily for PNF simulator operations. + + When `back_pwd` path is provided, it means go back tp the repository + you came from. + + Arguments: + back_pwd: path to go back to. + + Returns: + old_pwd (str): previous path. + + """ + sim_file_path = sys.modules[MassPnfSim.__module__].__file__ + sim_dir_path = os.path.dirname(sim_file_path) + + old_pwd = os.getcwd() + + if not back_pwd: + curr_pwd = sim_dir_path + else: + curr_pwd = back_pwd + + os.chdir(curr_pwd) + return old_pwd + +@decorator +def chdir(func, *args, **kwargs): + """Switches to and from the simulator workspace.""" + old_pwd = switch_workdir() + ret = func(*args, **kwargs) + switch_workdir(old_pwd) + return ret + +@chdir +def build_image() -> None: + """Build simulator image.""" + build = getattr(MassPnfSim(), "build") + args = get_default_args() + build(args) + +@chdir +def remove_image() -> None: + """Remove simulator image(s).""" + client = docker.from_env() + sim_image_name = "nexus3.onap.org:10003/onap/masspnf-simulator" + images = client.images.list(sim_image_name) + for obj in images: + client.images.remove(obj.id, force=True) + +@chdir +def bootstrap_simulator() -> None: + """Setup simulator(s) repo, data and configs.""" + args = get_default_args() + config = get_config() + + # collect settings that will be placed in the simulator directory + vesprotocol = config["setup"].get('vesprotocol', "http") + vesip = config["setup"].get('vesip', "") + vesport = config["setup"].get('vesport', "") + vesresource = config["setup"].get('vesresource', "") + vesversion = config["setup"].get('vesversion', "") + + urlves = f"{vesprotocol}://{vesip}:{vesport}/{vesresource}/{vesversion}" + + # assign to simulator's arguments + args.count = config["setup"].get('count', 1) + args.urlves = urlves + args.ipstart = ip_address(config["setup"].get('ipstart', '')) + args.ipfileserver = config["setup"].get('ipfileserver', '') + args.typefileserver = config["setup"].get('typefileserver', '') + args.user = config["setup"].get('user', '') + args.password = config["setup"].get('password', '') + + # bootstrap with assigned arguments + bootstrap = getattr(MassPnfSim(), "bootstrap") + bootstrap(args) + +@chdir +def run_container() -> None: + """Run simulator container(s).""" + start = getattr(MassPnfSim(), "start") + args = get_default_args() + start(args) + +@chdir +def register() -> None: + """Send an event to VES. + + Use time.sleep(seconds) if registering with VES right after run_container(). + Containers take a few seconds to run properly. Normally 5 seconds should be + enough. + + """ + time.sleep(5) + config = get_config() + trigger = getattr(MassPnfSim(), "trigger") + args = get_default_args() + + args.user = config['setup'].get('user', '') + args.password = config['setup'].get('password', '') + + custom_data = config['data'] + if custom_data: + args.data = custom_data + + trigger(args) + +@chdir +def stop_container() -> None: + """Stop simulator container(s).""" + stop = getattr(MassPnfSim(), "stop") + args = get_default_args() + stop(args) + +@chdir +def remove_simulator() -> None: + """Remove simulator container(s).""" + clean = getattr(MassPnfSim(), "clean") + args = get_default_args() + clean(args) |