diff options
95 files changed, 2420 insertions, 10 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..864f9ee --- /dev/null +++ b/.gitignore @@ -0,0 +1,110 @@ +# Copied from https://raw.githubusercontent.com/github/gitignore/master/Python.gitignore +# Copy as of 2018-02-08 +# github/gitignore is licensed under the +# Creative Commons Zero v1.0 Universal + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +.static_storage/ +.media/ +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..fffadb0 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,26 @@ + +The following licence applies to all files in this and subdirectories. Licences +are included in individual source files where appropriate, and if it differs +from this text, it supersedes this. Any file that does not have licence text +defaults to being covered by this text; not all files support the addition of +licenses. + +# +# ------------------------------------------------------------------------- +# Copyright (c) 2015-2017 AT&T Intellectual Property +# +# 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. +# +# ------------------------------------------------------------------------- +# + diff --git a/config/common_config.yaml b/config/common_config.yaml new file mode 100644 index 0000000..d8f467b --- /dev/null +++ b/config/common_config.yaml @@ -0,0 +1,43 @@ +osdf_system: + libpath: /opt/app/osdf/libs + sniro_ports: + internal: 24699 # inside the Docker container, the app listens to this port + external: 14699 # clients use this port on DockerHost + # Important Note: At deployment time, we need to ensure the port mapping is done + ssl_context: ['./../etc/sniromanager.crt', './../etc/sniromanager.key'] + +osdf_temp: # hacks required for "workarounds" or testing + local_policies: + global_disabled: True + local_placement_policies_enabled: True + placement_policy_files_vcpe: # workaroud for policy platform glitches (or "work-arounds" for other components) + - CloudAttributePolicy_vGMuxInfra_1.json + - CloudAttributePolicy_vG_1.json + - DistanceToLocationPolicy_vGMuxInfra_1.json + - DistanceToLocationPolicy_vG_1.json + - InventoryGroup_vGMuxInfra_1.json + - InventoryGroup_vG_1.json + - PlacementOptimizationPolicy.json + - ResourceInstancePolicy_vG_1.json + - VNFPolicy_vGMuxInfra_1.json + - VNFPolicy_vG_1.json + - ZonePolicy_vGMuxInfra_1.json + - ZonePolicy_vG_1.json + +service_info: + vCPE: + vcpeHostName: requestParameters.vcpeHostName + e2eVpnKey: requestParameters.e2eVpnKey + +policy_info: + placement: + policy_fetch: by_scope + policy_scope: + default_scope: OSDF_R2 + scope_vcpe: OSDF_R2 + service_name: placementInfo.serviceModelInfo.modelName + policy_subscriber: SubscriberPolicy + subscriber_name: placementInfo.subscriberInfo.subscriberName + default: # if no explicit service related information is needed + policy_fetch: by_name + policy_scope: none diff --git a/config/osdf_config.yaml b/config/osdf_config.yaml new file mode 100755 index 0000000..69ebdf0 --- /dev/null +++ b/config/osdf_config.yaml @@ -0,0 +1,34 @@ +osdfUserNameForSO: "" # The OSDF Manager username for MSO. +odfPasswordForSO: "" # The OSDF Manager password for MSO. + +# msoUrl: "" # The SO url for call back. This will be part of the request, so no need +soUsername: "" # SO username for call back. +soPassword: "" # SO password for call back. + +conductorUrl: "https://OOF-HAS-CONDUCTOR-HOST:8091" +conductorUsername: "CONDUCTOR-USER" +conductorPassword: "CONDUCTOR-PASSWD" +conductorPingWaitTime: 60 # seconds to wait before calling the conductor retry URL +conductorMaxRetries: 30 # if we don't get something in 30 minutes, give up + +# Policy Platform -- requires ClientAuth, Authorization, and Environment +policyPlatformUrl: https://POLICY-URL:8081/pdp/getConfig # Policy Dev platform URL +policyPlatformEnv: TEST # Environment for policy platform +policyPlatformUsername: POLICY-USER # Policy platform username. +policyPlatformPassword: POLICY-PASSWD # Policy platform password. +policyClientUsername: POLICY-CLIENT-USER # For use with ClientAuth +policyClientPassword: POLICY-CLIENT-PASSWD # For use with ClientAuth + +messageReaderHosts: https://DMAAP-HOST1:3905,https://DMAAP-HOST2:3905,https://DMAAP-HOST3:3905 +messageReaderTopic: org.onap.oof.osdf.multicloud +messageReaderAafUserId: DMAAP-OSDF-MC-USER +messageReaderAafPassword: DMAAP-OSDF-MC-PASSWD + +sdcUrl: https://SDC-HOST:8443/sdc/v1/catalog +sdcUsername: SDC-OSDF-USER +sdcPassword: SDC-OSDF-PASSWD +sdcONAPInstanceID: ONAP-OSDF + +osdfPlacementUrl: "http://127.0.0.1:24699/osdf/api/v2/placement" +osdfPlacementUsername: "test" +osdfPlacementPassword: "testpwd" diff --git a/__init__.py b/osdf/__init__.py index d0993ae..d0993ae 100755 --- a/__init__.py +++ b/osdf/__init__.py diff --git a/adapters/__init__.py b/osdf/adapters/__init__.py index e69de29..e69de29 100644 --- a/adapters/__init__.py +++ b/osdf/adapters/__init__.py diff --git a/adapters/database/OracleDB.py b/osdf/adapters/database/OracleDB.py index 655dd27..655dd27 100644 --- a/adapters/database/OracleDB.py +++ b/osdf/adapters/database/OracleDB.py diff --git a/adapters/database/PostgresDB.py b/osdf/adapters/database/PostgresDB.py index 6689566..6689566 100644 --- a/adapters/database/PostgresDB.py +++ b/osdf/adapters/database/PostgresDB.py diff --git a/adapters/database/VerticaDB.py b/osdf/adapters/database/VerticaDB.py index ad961d7..ad961d7 100644 --- a/adapters/database/VerticaDB.py +++ b/osdf/adapters/database/VerticaDB.py diff --git a/adapters/database/__init__.py b/osdf/adapters/database/__init__.py index e69de29..e69de29 100644 --- a/adapters/database/__init__.py +++ b/osdf/adapters/database/__init__.py diff --git a/adapters/dcae/__init__.py b/osdf/adapters/dcae/__init__.py index e69de29..e69de29 100644 --- a/adapters/dcae/__init__.py +++ b/osdf/adapters/dcae/__init__.py diff --git a/adapters/dcae/message_router.py b/osdf/adapters/dcae/message_router.py index e495331..e495331 100755 --- a/adapters/dcae/message_router.py +++ b/osdf/adapters/dcae/message_router.py diff --git a/adapters/local_data/__init__.py b/osdf/adapters/local_data/__init__.py index e69de29..e69de29 100644 --- a/adapters/local_data/__init__.py +++ b/osdf/adapters/local_data/__init__.py diff --git a/adapters/local_data/local_policies.py b/osdf/adapters/local_data/local_policies.py index c63ae5a..c63ae5a 100644 --- a/adapters/local_data/local_policies.py +++ b/osdf/adapters/local_data/local_policies.py diff --git a/adapters/policy/__init__.py b/osdf/adapters/policy/__init__.py index e69de29..e69de29 100644 --- a/adapters/policy/__init__.py +++ b/osdf/adapters/policy/__init__.py diff --git a/adapters/policy/interface.py b/osdf/adapters/policy/interface.py index ee45051..4ddee15 100644 --- a/adapters/policy/interface.py +++ b/osdf/adapters/policy/interface.py @@ -29,7 +29,7 @@ from osdf.config.base import osdf_config from osdf.logging.osdf_logging import audit_log, MH, metrics_log, error_log, debug_log from osdf.utils.interfaces import RestClient from osdf.optimizers.placementopt.conductor.api_builder import retrieve_node -from osdf.utils import data_mapping +# from osdf.utils import data_mapping def get_by_name(rest_client, policy_name_list, wildcards=True): @@ -109,9 +109,10 @@ def get_by_scope(rest_client, req, config_local, type_service): pscope = pmain['policy_scope'] model_name = retrieve_node(req, pscope['service_name']) - service_name = data_mapping.get_request_service_type(req) - if service_name is None: - service_name = data_mapping.get_service_type(model_name) + service_name = model_name + # service_name = data_mapping.get_request_service_type(req) + # if service_name is None: + # service_name = data_mapping.get_service_type(model_name) scope = pscope['scope_{}'.format(service_name.lower())] subscriber_role, prov_status = get_subscriber_role(rest_client, req, pmain, service_name, scope) policy_type_list = pmain['policy_type_{}'.format(service_name.lower())] diff --git a/adapters/policy/utils.py b/osdf/adapters/policy/utils.py index a006f12..a006f12 100644 --- a/adapters/policy/utils.py +++ b/osdf/adapters/policy/utils.py diff --git a/adapters/request_parsing/__init__.py b/osdf/adapters/request_parsing/__init__.py index e69de29..e69de29 100644 --- a/adapters/request_parsing/__init__.py +++ b/osdf/adapters/request_parsing/__init__.py diff --git a/adapters/request_parsing/placement.py b/osdf/adapters/request_parsing/placement.py index d7a6575..d7a6575 100644 --- a/adapters/request_parsing/placement.py +++ b/osdf/adapters/request_parsing/placement.py diff --git a/adapters/sdc/__init__.py b/osdf/adapters/sdc/__init__.py index e69de29..e69de29 100644 --- a/adapters/sdc/__init__.py +++ b/osdf/adapters/sdc/__init__.py diff --git a/adapters/sdc/asdc.py b/osdf/adapters/sdc/asdc.py index 43932ba..43932ba 100755 --- a/adapters/sdc/asdc.py +++ b/osdf/adapters/sdc/asdc.py diff --git a/adapters/sdc/constraint_handler.py b/osdf/adapters/sdc/constraint_handler.py index 2aae9a0..2aae9a0 100644 --- a/adapters/sdc/constraint_handler.py +++ b/osdf/adapters/sdc/constraint_handler.py diff --git a/config/__init__.py b/osdf/config/__init__.py index 303a8ce..303a8ce 100644 --- a/config/__init__.py +++ b/osdf/config/__init__.py diff --git a/config/base.py b/osdf/config/base.py index b8aacff..b8aacff 100644 --- a/config/base.py +++ b/osdf/config/base.py diff --git a/config/credentials.py b/osdf/config/credentials.py index e5a6399..e5a6399 100644 --- a/config/credentials.py +++ b/osdf/config/credentials.py diff --git a/config/loader.py b/osdf/config/loader.py index 7cb363a..7cb363a 100644 --- a/config/loader.py +++ b/osdf/config/loader.py diff --git a/operation/__init__.py b/osdf/logging/__init__.py index e69de29..e69de29 100644 --- a/operation/__init__.py +++ b/osdf/logging/__init__.py diff --git a/osdf/logging/osdf_logging.py b/osdf/logging/osdf_logging.py new file mode 100755 index 0000000..9a6ff4e --- /dev/null +++ b/osdf/logging/osdf_logging.py @@ -0,0 +1,229 @@ +import logging +import traceback +import uuid + +import logging +from logging.handlers import RotatingFileHandler +from osdf.utils.programming_utils import MetaSingleton + + +def log_handlers_pre_onap(config_file="config/pre_onap_logging_common_v1.config", + service_name="OOF_OSDF"): + """ + Convenience handlers for logging to different log files + + :param config_file: configuration file (properties file) that specifies log location, rotation, etc. + :param service_name: name for this service + :return: dictionary of log objects: "error", "metrics", "audit", "debug" + + We can use the returned values as follows: + X["error"].fatal("a FATAL message for the error log") + X["error"].error("an ERROR message for the error log") + X["error"].warn("a WARN message for the error log") + X["audit"].info("an INFO message for the audit log") + X["metrics"].info("an INFO message for the metrics log") + X["debug"].debug("a DEBUG message for the debug log") + """ + # Keeping main_params as a place-holder for ONAP related logging needs + # main_params = dict(instanceUUID=uuid.uuid1(), serviceName=service_name, configFile=config_file) + return dict((x, logging.getLogger(x)) # keep **main_params as a placeholder for ONAP fields + for x in ["error", "metrics", "audit", "debug"]) + + +def format_exception(err, prefix=None): + """Format operation for use with ecomp logging + :param err: exception object + :param prefix: prefix string message + :return: formatted exception (via repr(traceback.format_tb(err.__traceback__)) + """ + exception_lines = traceback.format_exception(err.__class__, err, err.__traceback__) + exception_desc = "".join(exception_lines) + return exception_desc if not prefix else prefix + ": " + exception_desc + + +class OOF_OSDFLogMessageHelper(metaclass=MetaSingleton): + """Provides loggers as a singleton (otherwise, we end up with duplicate messages). + Provides error_log, metric_log, audit_log, and debug_log (in that order) + Additionally can provide specific log handlers too + """ + log_handlers = None + default_levels = ["error", "metrics", "audit", "debug"] + + def _setup_handlers(self, log_version="pre_onap", config_file=None, service_name=None): + """return error_log, metrics_log, audit_log, debug_log""" + if self.log_handlers is None: + params = {} + params.update({"config_file": config_file} if config_file else {}) + params.update({"service_name": service_name} if service_name else {}) + + if log_version == "pre_onap": + self.log_handlers = log_handlers_pre_onap(**params) + + def get_handlers(self, levels=None, log_version="pre_onap", config_file=None, service_name=None): + """Return ONAP-compliant log handlers for different levels. Each "level" ends up in a different log file + with a prefix of that level. + + For example: error_log, metrics_log, audit_log, debug_log in that order + :param levels: None or list of levels subset of self.default_levels (["error", "metrics", "audit", "debug"]) + :param log_version: Currently only pre_onap is supported + :param config_file: Logging configuration file for ONAP compliant logging + :param service_name: Name of the service + :return: list of log_handlers in the order of levels requested. + if levels is None: we return handlers for self.default_levels + if levels is ["error", "audit"], we return log handlers for that. + """ + self._setup_handlers(log_version="pre_onap", config_file=config_file, service_name=service_name) + wanted_levels = self.default_levels if levels is None else levels + return [self.log_handlers.get(x) for x in wanted_levels] + + +class OOF_OSDFLogMessageFormatter(object): + + @staticmethod + def accepted_valid_request(req_id, request): + return "Accepted valid request for ID: {} for endpoint: {}".format( + req_id, request.url) + + @staticmethod + def invalid_request(req_id, err): + return "Invalid request for request ID: {}; cause: {}".format( + req_id, format_exception(err)) + + @staticmethod + def invalid_response(req_id, err): + return "Invalid response for request ID: {}; cause: {}".format( + req_id, format_exception(err)) + + @staticmethod + def malformed_request(request, err): + return "Malformed request for URL {}, from {}; cause: {}".format( + request.url, request.remote_address, format_exception(err)) + + @staticmethod + def malformed_response(response, client, err): + return "Malformed response {} for client {}; cause: {}".format( + response, client, format_exception(err)) + + @staticmethod + def need_policies(req_id): + return "Policies required but found no policies for request ID: {}".format(req_id) + + @staticmethod + def policy_service_error(url, req_id, err): + return "Unable to call policy for {} for request ID: {}; cause: {}".format( + url, req_id, format_exception(err)) + + @staticmethod + def requesting_url(url, req_id): + return "Making a call to URL {} for request ID: {}".format(url, req_id) + + @staticmethod + def requesting(service_name, req_id): + return "Making a call to service {} for request ID: {}".format(service_name, req_id) + + @staticmethod + def error_requesting(service_name, req_id, err): + return "Error while requesting service {} for request ID: {}; cause: {}".format( + service_name, req_id, format_exception(err)) + + @staticmethod + def calling_back(req_id, callback_url): + return "Posting result to callback URL for request ID: {}; callback URL={}".format( + req_id, callback_url) + + @staticmethod + def calling_back_with_body(req_id, callback_url, body): + return "Posting result to callback URL for request ID: {}; callback URL={} body={}".format( + req_id, callback_url, body) + + @staticmethod + def error_calling_back(req_id, callback_url, err): + return "Error while posting result to callback URL {} for request ID: {}; cause: {}".format( + req_id, callback_url, format_exception(err)) + + @staticmethod + def received_request(url, remote_addr, json_body): + return "Received a call to {} from {} {}".format(url, remote_addr, json_body) + + @staticmethod + def new_worker_thread(req_id, extra_msg=""): + res = "Initiating new worker thread for request ID: {}".format(req_id) + return res + extra_msg + + @staticmethod + def inside_worker_thread(req_id, extra_msg=""): + res = "Inside worker thread for request ID: {}".format(req_id) + return res + extra_msg + + @staticmethod + def processing(req_id, desc): + return "Processing request ID: {} -- {}".format(req_id, desc) + + @staticmethod + def processed(req_id, desc): + return "Processed request ID: {} -- {}".format(req_id, desc) + + @staticmethod + def error_while_processing(req_id, desc, err): + return "Error while processing request ID: {} -- {}; cause: {}".format( + req_id, desc, format_exception(err)) + + @staticmethod + def creating_local_env(req_id): + return "Creating local environment request ID: {}".format( + req_id) + + @staticmethod + def error_local_env(req_id, desc, err): + return "Error while creating local environment for request ID: {} -- {}; cause: {}".format( + req_id, desc, err.__traceback__) + + @staticmethod + def inside_new_thread(req_id, extra_msg=""): + res = "Spinning up a new thread for request ID: {}".format(req_id) + return res + " " + extra_msg + + @staticmethod + def error_response_posting(req_id, desc, err): + return "Error while posting a response for a request ID: {} -- {}; cause: {}".format( + req_id, desc, err.__traceback__) + + @staticmethod + def received_http_response(resp): + return "Received response [code: {}, headers: {}, data: {}]".format( + resp.status_code, resp.headers, resp.__dict__) + + @staticmethod + def sending_response(req_id, desc): + return "Response is sent for request ID: {} -- {}".format( + req_id, desc) + + @staticmethod + def listening_response(req_id, desc): + return "Response is sent for request ID: {} -- {}".format( + req_id, desc) + + @staticmethod + def items_received(item_num, item_type, desc="Received"): + return "{} {} {}".format(desc, item_num, item_type) + + @staticmethod + def items_sent(item_num, item_type, desc="Published"): + return "{} {} {}".format(desc, item_num, item_type) + + +MH = OOF_OSDFLogMessageFormatter +error_log, metrics_log, audit_log, debug_log = OOF_OSDFLogMessageHelper().get_handlers() + +def warn_audit_error(msg): + """Log the message to error_log.warn and audit_log.warn""" + log_message_multi(msg, audit_log.warn, error_log.warn) + + +def log_message_multi(msg, *logger_methods): + """Log the msg to multiple loggers + :param msg: message to log + :param logger_methods: e.g. error_log.warn, audit_log.warn, etc. + """ + for log_method in logger_methods: + log_method(msg) diff --git a/models/api/common.py b/osdf/models/api/common.py index 0d2d0eb..0d2d0eb 100755 --- a/models/api/common.py +++ b/osdf/models/api/common.py diff --git a/models/api/placementRequest.py b/osdf/models/api/placementRequest.py index 73eac75..73eac75 100644 --- a/models/api/placementRequest.py +++ b/osdf/models/api/placementRequest.py diff --git a/models/api/placementResponse.py b/osdf/models/api/placementResponse.py index e9746d6..e9746d6 100644 --- a/models/api/placementResponse.py +++ b/osdf/models/api/placementResponse.py diff --git a/models/policy/cmso/xacml/placementPolicies.xcore b/osdf/models/policy/cmso/xacml/placementPolicies.xcore index 3348cb0..3348cb0 100644 --- a/models/policy/cmso/xacml/placementPolicies.xcore +++ b/osdf/models/policy/cmso/xacml/placementPolicies.xcore diff --git a/models/policy/placement/xacml/placementPolicies.xcore b/osdf/models/policy/placement/xacml/placementPolicies.xcore index 866488e..866488e 100644 --- a/models/policy/placement/xacml/placementPolicies.xcore +++ b/osdf/models/policy/placement/xacml/placementPolicies.xcore diff --git a/optimizers/__init__.py b/osdf/operation/__init__.py index e69de29..e69de29 100644 --- a/optimizers/__init__.py +++ b/osdf/operation/__init__.py diff --git a/operation/error_handling.py b/osdf/operation/error_handling.py index dfb0848..dfb0848 100644 --- a/operation/error_handling.py +++ b/osdf/operation/error_handling.py diff --git a/operation/exceptions.py b/osdf/operation/exceptions.py index 5277b01..5277b01 100644 --- a/operation/exceptions.py +++ b/osdf/operation/exceptions.py diff --git a/operation/responses.py b/osdf/operation/responses.py index 22a94f7..22a94f7 100644 --- a/operation/responses.py +++ b/osdf/operation/responses.py diff --git a/optimizers/licenseopt/__init__.py b/osdf/optimizers/__init__.py index e69de29..e69de29 100644 --- a/optimizers/licenseopt/__init__.py +++ b/osdf/optimizers/__init__.py diff --git a/optimizers/placementopt/__init__.py b/osdf/optimizers/licenseopt/__init__.py index e69de29..e69de29 100644 --- a/optimizers/placementopt/__init__.py +++ b/osdf/optimizers/licenseopt/__init__.py diff --git a/optimizers/licenseopt/simple_license_allocation.py b/osdf/optimizers/licenseopt/simple_license_allocation.py index 1b5b670..1b5b670 100644 --- a/optimizers/licenseopt/simple_license_allocation.py +++ b/osdf/optimizers/licenseopt/simple_license_allocation.py diff --git a/optimizers/placementopt/conductor/__init__.py b/osdf/optimizers/placementopt/__init__.py index e69de29..e69de29 100644 --- a/optimizers/placementopt/conductor/__init__.py +++ b/osdf/optimizers/placementopt/__init__.py diff --git a/utils/__init__.py b/osdf/optimizers/placementopt/conductor/__init__.py index e69de29..e69de29 100644 --- a/utils/__init__.py +++ b/osdf/optimizers/placementopt/conductor/__init__.py diff --git a/optimizers/placementopt/conductor/api_builder.py b/osdf/optimizers/placementopt/conductor/api_builder.py index c0281fe..0a874f7 100644 --- a/optimizers/placementopt/conductor/api_builder.py +++ b/osdf/optimizers/placementopt/conductor/api_builder.py @@ -18,7 +18,7 @@ import copy import json -from osdf.utils import data_mapping +# from osdf.utils import data_mapping from jinja2 import Template from osdf.utils.programming_utils import list_flatten, dot_notation import osdf.optimizers.placementopt.conductor.translation as tr @@ -61,8 +61,10 @@ def conductor_api_builder(request_json, flat_policies: list, local_config, prov_ reservation_groups = list_flatten(reservation_policies) req_info = request_json['requestInfo'] model_name = request_json['placementInfo']['serviceModelInfo']['modelName'] - service_type = data_mapping.get_service_type(model_name) + service_type = model_name + # service_type = data_mapping.get_service_type(model_name) service_info = local_config.get('service_info', {}).get(service_type, {}) + order_info = {} if 'orderInfo' in request_json["placementInfo"]: order_info = json.loads(request_json["placementInfo"]["orderInfo"]) request_type = req_info.get('requestType', None) @@ -70,7 +72,7 @@ def conductor_api_builder(request_json, flat_policies: list, local_config, prov_ if 'subscriberInfo' in request_json['placementInfo']: subs_com_site_id = request_json['placementInfo']['subscriberInfo'].get('subscriberCommonSiteId', "") if service_type == 'vCPE': - data_mapping.normalize_user_params(order_info) + # data_mapping.normalize_user_params(order_info) rendered_req = templ.render( requestType=request_type, chosenComplex=subs_com_site_id, @@ -83,7 +85,7 @@ def conductor_api_builder(request_json, flat_policies: list, local_config, prov_ serviceType=service_type, serviceInstance=request_json['placementInfo']['serviceInstanceId'], provStatus = prov_status, - chosenRegion=order_info['requestParameters']['lcpCloudRegionId'], + chosenRegion=order_info.get('requestParameters',{}).get('lcpCloudRegionId'), json=json) elif service_type == 'UNKNOWN': rendered_req = templ.render( diff --git a/optimizers/placementopt/conductor/conductor.py b/osdf/optimizers/placementopt/conductor/conductor.py index bdc7f17..bdc7f17 100644 --- a/optimizers/placementopt/conductor/conductor.py +++ b/osdf/optimizers/placementopt/conductor/conductor.py diff --git a/optimizers/placementopt/conductor/remote_opt_processor.py b/osdf/optimizers/placementopt/conductor/remote_opt_processor.py index f753a70..f753a70 100644 --- a/optimizers/placementopt/conductor/remote_opt_processor.py +++ b/osdf/optimizers/placementopt/conductor/remote_opt_processor.py diff --git a/optimizers/placementopt/conductor/translation.py b/osdf/optimizers/placementopt/conductor/translation.py index 036398a..262fa86 100644 --- a/optimizers/placementopt/conductor/translation.py +++ b/osdf/optimizers/placementopt/conductor/translation.py @@ -18,7 +18,7 @@ import json from osdf.utils.data_conversion import text_to_symbol -from osdf.utils import data_mapping +# from osdf.utils import data_mapping def gen_optimization_policy(vnf_list, optimization_policy): """Generate optimization policy details to pass to Conductor @@ -183,7 +183,8 @@ def get_demand_properties(demand, policies): if 'attributes' in x: attributes = {} for k,v in x['attributes'].items(): - key=data_mapping.convert(k) + # key=data_mapping.convert(k) + key = k attributes[key] = v if(key=="model-invariant-id"): attributes[key]=demand['resourceModelInfo']['modelInvariantId'] diff --git a/osdf/templates/cms_opt_request.jsont b/osdf/templates/cms_opt_request.jsont new file mode 100755 index 0000000..006562b --- /dev/null +++ b/osdf/templates/cms_opt_request.jsont @@ -0,0 +1,35 @@ +{ + "transaction_id": "{{ transaction_id }}", + "request_id": "{{ request_id }}", + "start_date" : "{{ start_time }}", + "end_date" : "{{ end_time }}", + "change_elements" : {{ json.dumps(change_elements) }}, + "constraints" : [ + { + "type" : "general_concurrency_limit", + "parameters": [{{ concurrency_limit }}] + }, + + { + "type" : "allowed_forbidden_periods", + "parameters" : {{ json.dumps(allowed_periods) }} + } + + {% if spatial_conflicts is defined and spatial_conflicts|length > 0 %} + , + { + "type" : "spatial_conflict", + "parameters": {{ json.dumps(spatial_conflicts) }} + } + {% endif %} + + + {% if critical_periods is defined and spatial_conflicts|length > 0 %} + , + { + "type" : "critical_periods", + "parameters": {{ json.dumps(critical_periods) }} + } + {% endif %} + ] +} diff --git a/osdf/templates/cms_opt_request.jsont_1707_v1 b/osdf/templates/cms_opt_request.jsont_1707_v1 new file mode 100755 index 0000000..75ecbe5 --- /dev/null +++ b/osdf/templates/cms_opt_request.jsont_1707_v1 @@ -0,0 +1,67 @@ +{ + "transaction_id": "{{ transaction_id }}", + "request_id": "{{ request_id }}", + "start_date" : "{{ start_time }}", + "end_date" : "{{ end_time }}", + + "change_elements" : [ + {% set comma = joiner(",") -%} + {% for element in all_upgrades -%} {{ comma() }} + { + "id" : "{{ element.id }}", + "failback_duration": {{ element.failback_duration }}, + {% if element.group_id -%} + "group_id": "{{ element.group_id }}", + {% endif %} + {% if element.scheduled_on -%} + "scheduled_on": "{{ element.scheduled_on }}", + {% endif %} + "duration": {{ element.duration }} + } + {% endfor -%} + ], + + "constraints" : [ + { + "type" : "general_concurrency_limit", + "parameters": [{{ concurrency_limit }}] + }, + + { + "type" : "allowed_forbidden_periods", + "parameters" : [ + {% set comma = joiner(",") -%} + {% for idx in all_pending -%} {{ comma() }} + { "id" : "{{ idx.id }}", + "allowed_periods": [ {{ allowed_periods }}] + } + {% endfor -%} + ] + }, + { + "type" : "spatial_conflict", + "parameters": [ + {% set comma = joiner(",") -%} + {% for pserver, vce_list in vce_pserver_mapping.items() -%} {{ comma() }} + { + "spatial_entity": "{{ pserver }}", + "affected_entities": {{ vce_list }} + } + {% endfor -%} + ] + }, + + { + "type" : "critical_periods", + "parameters": [ + {% set comma = joiner(",") -%} + {% for element, conflict_period in conflict_interval.items() -%} {{ comma() }} + { + "id" : "{{ element }}", + "periods": [{{ conflict_period }}] + } + {% endfor -%} + ] + } + ] +} diff --git a/osdf/templates/cms_opt_request_1702.jsont b/osdf/templates/cms_opt_request_1702.jsont new file mode 100755 index 0000000..bcafa45 --- /dev/null +++ b/osdf/templates/cms_opt_request_1702.jsont @@ -0,0 +1,63 @@ +{ + "request_id": "{{ request_id }}", + "startdate" : "{{ start_time }}", + "enddate" : "{{ end_time }}", + + "change_elements" : [ +{% set comma = joiner(",") -%} +{% for element in all_upgrades -%} {{ comma() }} + { "id" : "{{ element.id }}", + {% if element.scheduled -%} "scheduled_on": "{{ element.scheduled }}", {% endif -%} + "duration": {{ element.duration }}, {# duration in seconds #} + "failback_duration": {{ element.failback_duration }}, {# duration in seconds #} + "group_id": {{ element.group_id }}, {# duration in seconds #} + }{% endfor -%} + ], + + "constraints" : [ + { + "type" : "general_concurrency_limit", + "parameters" : [ {{ general_concurrency_limit }} ] + }, + + { + "type" : "allowed_forbidden_periods", + "parameters" : [ +{% set comma = joiner(",") -%} +{% for idx in all_pending -%} {{ comma() }} + { "id" : "{{ idx.id }}", + "allowed_periods": [ {% set comma2 = joiner(",") -%} + {% for period in allowed_periods -%} {{ comma2() }} [{{ json.dumps(period[0]) }}, {{ json.dumps(period[1]) }}] + {% endfor -%} ] }{% endfor -%} + ] + } + +{% if p_v_conflict is defined and p_v_conflict|length > 0 %} + , + { + "type" : "critical_periods", + "description" : "Simultaneous upgrades", + "parameters" : [ +{% set comma2 = joiner(",") -%} +{% for element in p_v_conflict -%} {{ comma2() }} + { + "id" : "{{ element[0] }}", + "periods" : [{{ json.dumps(element[0]) }}, {{ json.dumps(element[1]) }}] + } +{% endfor -%} +{% endif %} + +{% for pserver, vce_group in grouped_vces.items() -%} {{ comma() }} + , + { + "id" : "{{ pserver }}", + "name" : "VCE's on pserver {{ pserver }}", + "description": "Only some VCEs on a pserver can be upgraded at a time", + "max_num_upgrades" : {{ max_num_upgrades(vce_group) }}, + "upgrades" : {{ json.dumps(vce_group) }} + } +{% endfor -%} + ] + } + ] +} diff --git a/osdf/templates/cms_opt_response.jsont b/osdf/templates/cms_opt_response.jsont new file mode 100644 index 0000000..a8817df --- /dev/null +++ b/osdf/templates/cms_opt_response.jsont @@ -0,0 +1,8 @@ +{ + "transactionId": "{{transaction_id}}", + "scheduleId":"{{schedule_id}}", + "requestState": "{{request_state}}", + "status": "{{status}}", + "description": "{{description}}", + "schedule": {{schedule}} +}
\ No newline at end of file diff --git a/osdf/templates/conductor_interface.json b/osdf/templates/conductor_interface.json new file mode 100755 index 0000000..2b48647 --- /dev/null +++ b/osdf/templates/conductor_interface.json @@ -0,0 +1,81 @@ +{
+ "name": "{{ name }}",
+ "files": {},
+ "timeout": {{ timeout }},
+ "limit": {{ limit }},
+ "template": {
+ "conductor_template_version": "2018-02-01",
+ "parameters": {
+ "REQUEST_TYPE": "{{ requestType }}",
+ "CHOSEN_REGION": "{{ chosenRegion }}",
+ "LATITUDE": "{{ latitude }}",
+ "LONGITUDE": "{{ longitude }}",
+ {% if serviceType == 'DHV' %}
+ "E2EVPNKEY": "{{ e2eVpnKey }}",
+ "UCPEHOST": "{{ ucpeHostName }}",
+ "EFFECTIVE_BANDWIDTH": "{{ effectiveBandwidth }}",
+ "WAN_PORT1_UP": "{{ ipsec_bw_up }}",
+ "WAN_PORT1_DOWN": "{{ ipsec_bw_down }}",
+ "WAN_PORT2_UP": "{{ ipsec2_bw_up }}",
+ "WAN_PORT2_DOWN": "{{ ipsec2_bw_down }}",
+ {% endif %}
+ {% if serviceType != 'DHV' %}
+ "GW_TENANT_ID": "{{ gwTenantId }}",
+ "PORTAL_TENANT_ID": "{{ portalTenantId }}",
+ {% endif %}
+ "CHOSEN_COMPLEX": "{{ chosenComplex }}",
+ {% if serviceType == 'ADIOD' or serviceType == 'VPE' %}
+ "BANDWIDTH": "{{ bandwidth }}",
+ "UNIT": "{{ bandwidth_unit }}",
+ {% endif %}
+ "SERVICE_INST": "{{ serviceInstance }}",
+ "PROV_STATUS": {{ json.dumps(provStatus) }}
+ },
+ "locations": {
+ {% if serviceType == 'DHV' %}
+ "customer_loc": {
+ "host_name": { "get_param": "UCPEHOST" }
+ }
+ {% elif serviceType == 'ADIOD' %}
+ "customer_pref_location": {
+ "clli_code": { "get_param": "CHOSEN_COMPLEX" }
+ }
+ {% elif serviceType == 'NETBOND' %}
+ "peering_point": {
+ "latitude": { "get_param": "LATITUDE" },
+ "longitude": { "get_param": "LONGITUDE" }
+ }
+ {% else %}
+ "customer_pref_loc": {
+ "clli_code": { "get_param": "CHOSEN_COMPLEX" }
+ }
+ {% endif %}
+ },
+ "demands": {{ json.dumps(demand_list) }},
+ {% set comma_main = joiner(",") %}
+ "constraints": {
+ {% set comma=joiner(",") %}
+ {% for elem in policy_groups %} {{ comma() }}
+ {% for key, value in elem.items() %}
+ "{{key}}": {{ json.dumps(value) }}
+ {% endfor %}
+ {% endfor %}
+ },
+ "reservation": {
+ {% set comma=joiner(",") %}
+ {% for elem in reservation_groups %} {{ comma() }}
+ {% for key, value in elem.items() %}
+ "{{key}}": {{ json.dumps(value) }}
+ {% endfor %}
+ {% endfor %}
+ },
+ "optimization": {
+ {% set comma=joiner(",") %}
+ {% for elem in optimization_policies %} {{ comma() }}
+ {% for key, value in elem.items() %}
+ "{{key}}": {{ json.dumps(value) }}
+ {% endfor %}
+ {% endfor %}
+ }
+ }
+}
\ No newline at end of file diff --git a/osdf/templates/license_opt_request.jsont b/osdf/templates/license_opt_request.jsont new file mode 100644 index 0000000..7baa759 --- /dev/null +++ b/osdf/templates/license_opt_request.jsont @@ -0,0 +1,6 @@ +{ + "transactionId": "{{transaction_id}}", + "requestId": "{{request_id}}", + "partNumber": "{{part_number}}", + "licenseModel" : "{{artifact}}" +}
\ No newline at end of file diff --git a/osdf/templates/plc_opt_request.jsont b/osdf/templates/plc_opt_request.jsont new file mode 100755 index 0000000..cd78b3e --- /dev/null +++ b/osdf/templates/plc_opt_request.jsont @@ -0,0 +1,142 @@ +{
+ "name": "{{ name }}",
+ "files": "{{ files }}",
+ "timeout": "{{ timeout }}",
+ "limit": "{{ limit }}",
+ "template": {
+ "CUST_ID": "{{ cust_id }}",
+ "E2EVPNKEY": "{{ e2evpnkey }}",
+ "UCPEHOST": "{{ ucpehost }}",
+ "WAN_PORT1_UP": "{{ wan_port1_up }}",
+ "WAN_PORT1_DOWN": "{{ wan_port1_down }}",
+ "EFFECTIVE_BANDWIDTH": "{{ effective_bandwidth }}",
+ "SERVICE_INST": "{{ service_inst }}",
+ "locations": {
+ "customer_loc": {
+ "host_name": "{{ ucpehost }}"
+ }
+ },
+ "demands": [
+ {% set comma=joiner(",") %}
+ {% for demand in demand_list %} {{ comma() }}
+ {
+ "{{ demand.vnf_name }}": [
+ {% set comma2=joiner(",") %}
+ {% for property in demand.property %}
+ "inventory_provider": {{ property.inventory_provider }},
+ "inventory_type": {{ property.inventory_type }},
+ "service_type": {{ property.service_type }},
+ "customer_id": {{ property.customer_id }},
+ "candidate_id": {{ property.candidate_id }}
+ {% endfor %}
+ ]
+ }
+ {% endfor %}
+ ],
+ "constraints": {
+ {% set comma_main=joiner(",") %}
+
+ {% if attribute_policy_list %} {{ comma_main() }} {% endif %}
+ {% set comma=joiner(",") %}
+ {% for attribute in attribute_policy_list %} {{ comma() }}
+ attribute['identity'] : {
+ "type": {{ attribute['type'] }},
+ "demands": {{ attribute['demands'] }},
+ "properties": {
+ "evaluate": {
+ "hypervisor": {{ attribute['property']['hypervisor'] }},
+ "aic_version": {{ attribute['property']['aicVersion'] }},
+ "aic_type": {{ attribute['property']['aicType'] }},
+ "dataplane": {{ attribute['property']['datatype'] }},
+ "network_roles": {{ attribute['property']['networkRoles'] }},
+ "complex": {{ attribute['property']['complex'] }}
+ }
+ }
+ }
+ {% endfor %}
+
+ {% if distance_to_location_policy_list %} {{ comma_main() }} {% endif %}
+ {% set comma=joiner(",") %}
+ {% for distance_location in distance_to_location_policy_list %} {{ comma() }}
+ distance_location['identity'] : {
+ "type": {{ distance_location['type'] }},
+ "demands": {{ distance_location['demands'] }},
+ "properties": {
+ "distance": {{ distance_location['property']['distance'] }},
+ "location": {{ distance_location['property']['location'] }}
+ }
+ }
+ {% endfor %}
+
+ {% if inventory_policy_list %} {{ comma_main() }} {% endif %}
+ {% set comma=joiner(",") %}
+ {% for inventory in inventory_policy_list %} {{ comma() }}
+ inventory['identity'] : {
+ "type": {{ inventory['type'] }},
+ "demands": {{ inventory['demands'] }}
+ }
+ {% endfor %}
+
+ {% if resource_instance_policy_list %} {{ comma_main() }} {% endif %}
+ {% set comma=joiner(",") %}
+ {% for resource_instance in resource_instance_policy_list %} {{ comma() }}
+ resource_instance['identity'] : {
+ "type": {{ resource_instance['type'] }},
+ "demands": {{ resource_instance['demands'] }},
+ "properties": {
+ "controller": {{ resource_instance['property']['controller'] }},
+ "request": {{ resource_instance['property']['request'] }}
+ }
+ }
+ {% endfor %}
+
+ {% if resource_region_policy_list %} {{ comma_main() }} {% endif %}
+ {% set comma=joiner(",") %}
+ {% for resource_region in resource_region_policy_list %} {{ comma() }}
+ resource_region['identity'] : {
+ "type": {{ resource_region['type'] }},
+ "demands": {{ resource_region['demands'] }},
+ "properties": {
+ "controller": {{ resource_region['property']['controller'] }},
+ "request": {{ resource_region['property']['request'] }}
+ }
+ }
+ {% endfor %}
+
+ {% if zone_policy_list %} {{ comma_main() }} {% endif %}
+ {% set comma=joiner(",") %}
+ {% for zone in zone_policy_list %} {{ comma() }}
+ zone['identity'] : {
+ "type": {{ zone['type'] }},
+ "demands": {{ zone['demands'] }},
+ "properties": {
+ "qualifier": {{ resource_region['property']['qualifier'] }},
+ "category": {{ resource_region['property']['category'] }}
+ }
+ }
+ {% endfor %}
+
+ {% if optmization_policy_list %} {{ comma_main() }} {% endif %}
+ {% set comma=joiner(",") %}
+ {% for optimization in optimization_policy_list %} {{ comma() }}
+ "optimization" : {
+ {{ optimization['objective'] }}: {
+ "sum": [
+ {% set comma2=joiner(",") %}
+ {% for parameter in optimization['parameter'] %} {{ comma() }}
+ {
+ "product": [
+ {{ parameter['weight'] }},
+ {
+ "distance_between": [{{ parameter['customerLocation'] }},{{ parameter['demand'] }}]
+ }
+ ]
+ }
+ {% endfor %}
+ ]
+ }
+ }
+ {% endfor %}
+ }
+ }
+}
\ No newline at end of file diff --git a/osdf/templates/plc_opt_response.jsont b/osdf/templates/plc_opt_response.jsont new file mode 100755 index 0000000..aa678b5 --- /dev/null +++ b/osdf/templates/plc_opt_response.jsont @@ -0,0 +1,14 @@ +{ + "requestId": "{{requestId}}", + "transactionId": "{{transacationId}}", + "startTime": "{{startTime}}", + "responseTime": "{{responseTime}}", + "requestType": "{{requestType}}", + "requestState": "{{requestState}}", + "statusMessage": "{{statusMessage}}", + "percentProgress": "{{percentProgress}}", + "solutionInfo": { + "placement": {{ json.dumps(composite_solutions) }}, + "licenseInfo":{ "featureGroupId": "{{featureGroupId}}" } + } +} diff --git a/osdf/templates/policy_request.jsont b/osdf/templates/policy_request.jsont new file mode 100755 index 0000000..3a9e201 --- /dev/null +++ b/osdf/templates/policy_request.jsont @@ -0,0 +1,3 @@ +{ + "policyName": "{{policy_name}}" {# we currently only support query by policy name only -- policyName #} +} diff --git a/osdf/templates/test_cms_nb_req_from_client.jsont b/osdf/templates/test_cms_nb_req_from_client.jsont new file mode 100755 index 0000000..a60c8ff --- /dev/null +++ b/osdf/templates/test_cms_nb_req_from_client.jsont @@ -0,0 +1,19 @@ +{ + "schedulingInfo": { + "change_management_id": "{{ change_management_id }}", + "start_time": "{{ start_time }}", + "end_time": "{{ end_time }}", + "policy_id": {{ json.dumps(policy_id) }}, {# a list of policy Ids #} + "service_type": "{{ service_type }}", + "workflow_type": "{{ workflow_type }}", + "upgrades": {{ json.dumps(upgrades) }} {# a list of node Ids #} + }, + "requestInfo": { + "requestId": "{{ requestId }}", + "sourceId": "{{ sourceId }}", + "optimizer": "{{ optimizer }}", + "numSolutions": "{{ numSolutions }}", + "callbackUrl" : "{{ callbackUrl }}" + } +} + diff --git a/osdf/templates/test_plc_nb_req_from_client.jsont b/osdf/templates/test_plc_nb_req_from_client.jsont new file mode 100755 index 0000000..998ffb3 --- /dev/null +++ b/osdf/templates/test_plc_nb_req_from_client.jsont @@ -0,0 +1,52 @@ +{
+ "requestInfo": {
+ "requestId": "{{requestId}}",
+ "sourceId": "{{sourceId}}",
+ "optimizer": "{{optimizer}}",
+ "numSolutions": {{numSolutions}},
+ "timeout": {{timeout}},
+ "callbackUrl" : "{{callbackUrl}}"
+ },
+ "placementInfo": {
+ "modelInfo": {
+ "modelType": "{{modelType}}",
+ "modelInvariant": "{{modelInvariantId}}",
+ "modelVersionId": "{{modelVersionId}}",
+ "modelName": "{{modelName}}",
+ "modelVersion": "{{modelVersion}}",
+ "modelCustomizationId": "{{modelCustomizationId}}"
+ },
+ "subscriberInfo": {
+ "globalSubscriberId": "{{globalSubscriberId}}",
+ "subscriberName": "{{subscriberName}}",
+ "subscriberCommonSiteId": "{{subscriberCommonSiteId}}",
+ "ucpeHostName": "{{ucpeHostName}}"
+ },
+ "policyId": {{json.dumps(policyId)}},
+ "vnfInfo": {
+ "vnfType": "{{vnfType}}",
+ "vnfPartNumber": "{{vnfPartNumber}}",
+ "nominalThroughput": "{{nominalThroughput}}",
+ "vnfSoftwareVersion": "{{vnfSoftwareVersion}}",
+ "vnfManagementOption": "{{vnfManagementOption}}"
+ },
+ "vpnInfo": {
+ "vpnId": "{{vpnId}}",
+ "pvcId": "{{pvcId}}"
+ },
+ "serviceInfo": {
+ "dhvServiceInfo": {
+ "serviceInstanceId": "{{serviceInstanceId}}",
+ "serviceType": "{{serviceType}}",
+ "e2evpnkey": "{{e2evpnkey}}",
+ "dhvSiteEffectiveTransportBandwidth": {{dhvSiteEffectiveTransportBandwidth}},
+ "dhvIPSecTransportBandwidthUp": {{dhvIPSecTransportBandwidthUp}},
+ "dhvIPSecTransportBandwidthDown": {{dhvIPSecTransportBandwidthDown}},
+ "dhvIPSec2TransportBandwidthUp": {{dhvIPSec2TransportBandwidthUp}},
+ "dhvIPSec2TransportBandwidthDown": {{dhvIPSec2TransportBandwidthDown}},
+ "dhvVendorName": "{{dhvVendorName}}"
+ }
+ },
+ "demandInfo": {{json.dumps(demandInfo)}}
+ }
+}
diff --git a/webapp/__init__.py b/osdf/utils/__init__.py index e69de29..e69de29 100644 --- a/webapp/__init__.py +++ b/osdf/utils/__init__.py diff --git a/utils/data_conversion.py b/osdf/utils/data_conversion.py index 2f678fa..2f678fa 100644 --- a/utils/data_conversion.py +++ b/osdf/utils/data_conversion.py diff --git a/utils/data_types.py b/osdf/utils/data_types.py index 877d4a1..877d4a1 100644 --- a/utils/data_types.py +++ b/osdf/utils/data_types.py diff --git a/utils/interfaces.py b/osdf/utils/interfaces.py index 7a0e3a9..7a0e3a9 100644 --- a/utils/interfaces.py +++ b/osdf/utils/interfaces.py diff --git a/utils/local_processing.py b/osdf/utils/local_processing.py index 6768839..6768839 100644 --- a/utils/local_processing.py +++ b/osdf/utils/local_processing.py diff --git a/utils/programming_utils.py b/osdf/utils/programming_utils.py index a0a8fde..a0a8fde 100644 --- a/utils/programming_utils.py +++ b/osdf/utils/programming_utils.py diff --git a/osdf/webapp/__init__.py b/osdf/webapp/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/osdf/webapp/__init__.py diff --git a/webapp/appcontroller.py b/osdf/webapp/appcontroller.py index 49f84ff..49f84ff 100644 --- a/webapp/appcontroller.py +++ b/osdf/webapp/appcontroller.py diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..351f97e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,13 @@ +docutils>=0.12 +docopt>=0.6.2 +Flask>=0.11.1 +Flask-HTTPAuth>=3.2.2 +jsonschema>=2.5.1 +lxml>=3.6.4 +nose>=1.3.7 +python-dateutil>=2.5.3 +PyYAML>=3.12 +requests>=2.14.2 +schematics>=2.0.0 +docopt>=0.6.2 +pydevd>=1.0.0 diff --git a/test/bad_test_Utils.py b/test/bad_test_Utils.py new file mode 100644 index 0000000..3e5cecd --- /dev/null +++ b/test/bad_test_Utils.py @@ -0,0 +1,21 @@ +import unittest +import json + +from osdf.config.base import osdf_config +from osdf.utils.programming_utils import dot_notation + + +class TestUtils(unittest.TestCase): + + def test_metrics(self): + with open('test/placement-tests/request.json', 'r') as f: + data = json.load(f) + placementInfo = data["placementInfo"] + config_local = osdf_config.core + self.assertEqual("USOSTCDALTX0101UJZZ11", dot_notation(placementInfo, config_local['service_info']['vCPE']['vcpeHostName'])) + self.assertEqual("200", dot_notation(placementInfo, config_local['service_info']['vCPE']['e2eVpnKey'])) + self.assertEqual(['vGMuxInfra', 'vG'], dot_notation(placementInfo, 'demandInfo.placementDemand.resourceModuleName')) + + +if __name__ == '__main__': + unittest.main() diff --git a/test/dummy_test_dummy.py b/test/dummy_test_dummy.py new file mode 100644 index 0000000..dc46d50 --- /dev/null +++ b/test/dummy_test_dummy.py @@ -0,0 +1,14 @@ +import osdf +# import osdfapp +from osdf.config.loader import load_config_file + + +def test_dummy(): + """Generate time constraints from cm-request.json and cm-policy-response.json""" + try: + load_config_file("DUMMY") + except: + pass + return 1 + + diff --git a/test/placement-tests/request.json b/test/placement-tests/request.json new file mode 100644 index 0000000..2fd425c --- /dev/null +++ b/test/placement-tests/request.json @@ -0,0 +1,87 @@ +{
+ "requestInfo": {
+ "transactionId": "xxx-xxx-xxxx",
+ "requestId": "yyy-yyy-yyyy",
+ "callbackUrl": "https://test.url.com:5000/callback/",
+ "sourceId": "so",
+ "optimizers": ["placement"],
+ "numSolutions": 1,
+ "timeout": 600
+ },
+ "placementInfo": {
+ "serviceModelInfo": {
+ "modelType": "service",
+ "modelInvariantId": "fad5f4d5-1c94-4890-927d-9cec6e82997f",
+ "modelVersionId": "6e13c5e1-f172-436c-9cc4-0d64c94eb7f4",
+ "modelName": "vCPE",
+ "modelVersion": "1.0"
+ },
+ "subscriberInfo": {
+ "globalSubscriberId": "SUB12_0325_UD_0833",
+ "subscriberName": "SUB_12_0325_UD_0833",
+ "subscriberCommonSiteId": "DALTX0101"
+ },
+ "demandInfo": {
+ "placementDemand": [{
+ "resourceInstanceType": "allotted",
+ "serviceResourceId": "61d563e8-e714-4393-8f99-cc480144a05e",
+ "resourceModuleName": "vGMuxInfra",
+ "exclusionCandidateInfo": [{
+ "candidateType": "cloud",
+ "candidates": ["MDT54NJ", "BDM78NJ"]
+ }, {
+ "candidateType": "service",
+ "candidates": ["RT76U8F789", "PO098HJG"]
+ }
+ ],
+ "requiredCandidateInfo": [{
+ "candidateType": "cloud",
+ "candidates": ["DHU87NY"]
+ }, {
+ "candidateType": "service",
+ "candidates": ["YHT675YH"]
+ }
+ ],
+ "resourceModelInfo": {
+ "modelCustomizationId": "",
+ "modelInvariantId": "h59988ce-3d81-4e07-81b5-53d3aa821134",
+ "modelName": "",
+ "modelVersion": "2.0",
+ "modelVersionId": "51d563e8-e714-4393-8f99-cc480144a05e",
+ "modelType": "allotted"
+ },
+ "tenantId": "",
+ "tenantName": ""
+ }, {
+ "resourceInstanceType": "allotted",
+ "serviceResourceId": "71d563e8-e714-4393-8f99-cc480144a05e",
+ "resourceModuleName": "vG",
+ "resourceModelInfo": {
+ "modelCustomizationId": "",
+ "modelInvariantId": "a59988ce-3d81-4e07-81b5-53d3aa821134",
+ "modelName": "",
+ "modelVersion": "2.0",
+ "modelVersionId": "91d563e8-e714-4393-8f99-cc480144a05e",
+ "modelType": "allotted"
+ },
+ "tenantId": "",
+ "tenantName": ""
+ }
+ ],
+ "licenseDemand": []
+ },
+ "policyId": [
+ ""
+ ],
+ "serviceInstanceId": "1234-fsdf-23sdf-24kjnk",
+ "requestParameters": {
+
+ "commonSiteId": "DALTX0101",
+ "vendorName": "xyz",
+ "e2eVpnKey": "200",
+ "vcpeHostName": "USOSTCDALTX0101UJZZ11"
+
+ }
+
+ }
+}
\ No newline at end of file diff --git a/test/placement-tests/request_mso.json b/test/placement-tests/request_mso.json new file mode 100644 index 0000000..2d854cb --- /dev/null +++ b/test/placement-tests/request_mso.json @@ -0,0 +1,63 @@ +{ + "requestInfo": { + "transactionId": "1b98ee53-3fbd-48ca-9b85-302792bf5918", + "requestId": "1b98ee53-3fbd-48ca-9b85-302792bf5918", + "callbackUrl": "http://127.0.0.1:7001", + "sourceId": "mso", + "optimizer": [ + "placement", + "license" + ], + "numSolutions": 1, + "timeout": 600 + }, + "placementInfo": { + "serviceModelInfo": { + "modelType": "", + "modelInvariantId": "598e3f9e-3244-4d8f-a8e0-0e5d7a29eda9", + "modelVersionId": "b8c45108-68df-48c5-8d58-c8dd4de833bb", + "modelName": "ADIOD vMX vPE_BV Service 488", + "modelVersion": "1.0" + }, + "subscriberInfo": { + "globalSubscriberId": "21014aa2-526b-11e6-beb8-9e71128cae77", + "subscriberName": "Avteet_Chayal", + "subscriberCommonSiteId": "MDTWNJ2B17" + }, + "demandInfo": { + "placementDemand": [{ + "resourceInstanceType": "VNF", + "serviceResourceId": "6ea4128a-ba41-4872-a1f8-2748d0e1c361", + "resourceModuleName": "2017-488_ADIOD-vPE 0", + "resourceModelInfo": { + "modelCustomizationId": "06ed941b-1d83-4132-8a1d-1874f4f4b89b", + "modelInvariantId": "5be7e99e-8eb2-4d97-be63-8081ff3cd10e", + "modelName": "2017-488_ADIOD-vPE", + "modelVersion": "1.0", + "modelVersionId": "7cd2d399-2bcb-4ecf-bd32-c36cdca7aa03", + "modelType": "" + }, + "tenantId": "", + "tenantName": "" + } + ], + "licenseDemand": [{ + "resourceInstanceType": "VNF", + "serviceResourceId": "6ea4128a-ba41-4872-a1f8-2748d0e1c361", + "resourceModuleName": "2017-488_ADIOD-vPE 0", + "resourceModelInfo": { + "modelCustomizationId": "06ed941b-1d83-4132-8a1d-1874f4f4b89b", + "modelInvariantId": "5be7e99e-8eb2-4d97-be63-8081ff3cd10e", + "modelName": "2017-488_ADIOD-vPE", + "modelVersion": "1.0", + "modelVersionId": "7cd2d399-2bcb-4ecf-bd32-c36cdca7aa03", + "modelType": "" + } + } + ] + }, + "policyId": [], + "serviceInstanceId": "28014cbe-b334-4d5c-839d-980157929b0b", + "orderInfo": "{\"requestParameters\": {\"aLaCarte\":false,\"usePreload\":true,\"subscriptionServiceType\":\"VPE\",\"alaCarteSet\":true,\"rebuildVolumeGroups\":false,\"userParams\":[{\"name\":\"2017488_adiodvpe0_vnf_config_template_version\",\"value\":\"17.2\"},{\"name\":\"2017488_adiodvpe0_bandwidth_units\",\"value\":\"Gbps\"},{\"name\":\"2017488_adiodvpe0_bandwidth\",\"value\":\"10\"},{\"name\":\"2017488_adiodvpe0_AIC_CLLI\",\"value\":\"MDTWNJ2B17\"},{\"name\":\"2017488_adiodvpe0_vnf_instance_name\",\"value\":\"mtnj309me6\"}],\"autoBuildVfModules\":false,\"cascadeDelete\":false}}" + } +} diff --git a/test/placement-tests/request_mso_subs_name_blank.json b/test/placement-tests/request_mso_subs_name_blank.json new file mode 100644 index 0000000..3195786 --- /dev/null +++ b/test/placement-tests/request_mso_subs_name_blank.json @@ -0,0 +1,63 @@ +{ + "requestInfo": { + "transactionId": "1b98ee53-3fbd-48ca-9b85-302792bf5918", + "requestId": "1b98ee53-3fbd-48ca-9b85-302792bf5918", + "callbackUrl": "http://127.0.0.1:7001", + "sourceId": "mso", + "optimizer": [ + "placement", + "license" + ], + "numSolutions": 1, + "timeout": 600 + }, + "placementInfo": { + "serviceModelInfo": { + "modelType": "", + "modelInvariantId": "598e3f9e-3244-4d8f-a8e0-0e5d7a29eda9", + "modelVersionId": "b8c45108-68df-48c5-8d58-c8dd4de833bb", + "modelName": "ADIOD vMX vPE_BV Service 488", + "modelVersion": "1.0" + }, + "subscriberInfo": { + "globalSubscriberId": "21014aa2-526b-11e6-beb8-9e71128cae77", + "subscriberName": "", + "subscriberCommonSiteId": "MDTWNJ2B17" + }, + "demandInfo": { + "placementDemand": [{ + "resourceInstanceType": "VNF", + "serviceResourceId": "6ea4128a-ba41-4872-a1f8-2748d0e1c361", + "resourceModuleName": "2017-488_ADIOD-vPE 0", + "resourceModelInfo": { + "modelCustomizationId": "06ed941b-1d83-4132-8a1d-1874f4f4b89b", + "modelInvariantId": "5be7e99e-8eb2-4d97-be63-8081ff3cd10e", + "modelName": "2017-488_ADIOD-vPE", + "modelVersion": "1.0", + "modelVersionId": "7cd2d399-2bcb-4ecf-bd32-c36cdca7aa03", + "modelType": "" + }, + "tenantId": "", + "tenantName": "" + } + ], + "licenseDemand": [{ + "resourceInstanceType": "VNF", + "serviceResourceId": "6ea4128a-ba41-4872-a1f8-2748d0e1c361", + "resourceModuleName": "2017-488_ADIOD-vPE 0", + "resourceModelInfo": { + "modelCustomizationId": "06ed941b-1d83-4132-8a1d-1874f4f4b89b", + "modelInvariantId": "5be7e99e-8eb2-4d97-be63-8081ff3cd10e", + "modelName": "2017-488_ADIOD-vPE", + "modelVersion": "1.0", + "modelVersionId": "7cd2d399-2bcb-4ecf-bd32-c36cdca7aa03", + "modelType": "" + } + } + ] + }, + "policyId": [], + "serviceInstanceId": "28014cbe-b334-4d5c-839d-980157929b0b", + "orderInfo": "{\"requestParameters\": {\"aLaCarte\":false,\"usePreload\":true,\"subscriptionServiceType\":\"VPE\",\"alaCarteSet\":true,\"rebuildVolumeGroups\":false,\"userParams\":[{\"name\":\"2017488_adiodvpe0_vnf_config_template_version\",\"value\":\"17.2\"},{\"name\":\"2017488_adiodvpe0_bandwidth_units\",\"value\":\"Gbps\"},{\"name\":\"2017488_adiodvpe0_bandwidth\",\"value\":\"10\"},{\"name\":\"2017488_adiodvpe0_AIC_CLLI\",\"value\":\"MDTWNJ2B17\"},{\"name\":\"2017488_adiodvpe0_vnf_instance_name\",\"value\":\"mtnj309me6\"}],\"autoBuildVfModules\":false,\"cascadeDelete\":false}}" + } +} diff --git a/test/placement-tests/request_mso_subs_name_default.json b/test/placement-tests/request_mso_subs_name_default.json new file mode 100644 index 0000000..86e2f82 --- /dev/null +++ b/test/placement-tests/request_mso_subs_name_default.json @@ -0,0 +1,63 @@ +{ + "requestInfo": { + "transactionId": "1b98ee53-3fbd-48ca-9b85-302792bf5918", + "requestId": "1b98ee53-3fbd-48ca-9b85-302792bf5918", + "callbackUrl": "http://127.0.0.1:7001", + "sourceId": "mso", + "optimizer": [ + "placement", + "license" + ], + "numSolutions": 1, + "timeout": 600 + }, + "placementInfo": { + "serviceModelInfo": { + "modelType": "", + "modelInvariantId": "598e3f9e-3244-4d8f-a8e0-0e5d7a29eda9", + "modelVersionId": "b8c45108-68df-48c5-8d58-c8dd4de833bb", + "modelName": "ADIOD vMX vPE_BV Service 488", + "modelVersion": "1.0" + }, + "subscriberInfo": { + "globalSubscriberId": "21014aa2-526b-11e6-beb8-9e71128cae77", + "subscriberName": "default", + "subscriberCommonSiteId": "MDTWNJ2B17" + }, + "demandInfo": { + "placementDemand": [{ + "resourceInstanceType": "VNF", + "serviceResourceId": "6ea4128a-ba41-4872-a1f8-2748d0e1c361", + "resourceModuleName": "2017-488_ADIOD-vPE 0", + "resourceModelInfo": { + "modelCustomizationId": "06ed941b-1d83-4132-8a1d-1874f4f4b89b", + "modelInvariantId": "5be7e99e-8eb2-4d97-be63-8081ff3cd10e", + "modelName": "2017-488_ADIOD-vPE", + "modelVersion": "1.0", + "modelVersionId": "7cd2d399-2bcb-4ecf-bd32-c36cdca7aa03", + "modelType": "" + }, + "tenantId": "", + "tenantName": "" + } + ], + "licenseDemand": [{ + "resourceInstanceType": "VNF", + "serviceResourceId": "6ea4128a-ba41-4872-a1f8-2748d0e1c361", + "resourceModuleName": "2017-488_ADIOD-vPE 0", + "resourceModelInfo": { + "modelCustomizationId": "06ed941b-1d83-4132-8a1d-1874f4f4b89b", + "modelInvariantId": "5be7e99e-8eb2-4d97-be63-8081ff3cd10e", + "modelName": "2017-488_ADIOD-vPE", + "modelVersion": "1.0", + "modelVersionId": "7cd2d399-2bcb-4ecf-bd32-c36cdca7aa03", + "modelType": "" + } + } + ] + }, + "policyId": [], + "serviceInstanceId": "28014cbe-b334-4d5c-839d-980157929b0b", + "orderInfo": "{\"requestParameters\": {\"aLaCarte\":false,\"usePreload\":true,\"subscriptionServiceType\":\"VPE\",\"alaCarteSet\":true,\"rebuildVolumeGroups\":false,\"userParams\":[{\"name\":\"2017488_adiodvpe0_vnf_config_template_version\",\"value\":\"17.2\"},{\"name\":\"2017488_adiodvpe0_bandwidth_units\",\"value\":\"Gbps\"},{\"name\":\"2017488_adiodvpe0_bandwidth\",\"value\":\"10\"},{\"name\":\"2017488_adiodvpe0_AIC_CLLI\",\"value\":\"MDTWNJ2B17\"},{\"name\":\"2017488_adiodvpe0_vnf_instance_name\",\"value\":\"mtnj309me6\"}],\"autoBuildVfModules\":false,\"cascadeDelete\":false}}" + } +} diff --git a/test/placement-tests/request_mso_subs_name_none.json b/test/placement-tests/request_mso_subs_name_none.json new file mode 100644 index 0000000..214e011 --- /dev/null +++ b/test/placement-tests/request_mso_subs_name_none.json @@ -0,0 +1,62 @@ +{ + "requestInfo": { + "transactionId": "1b98ee53-3fbd-48ca-9b85-302792bf5918", + "requestId": "1b98ee53-3fbd-48ca-9b85-302792bf5918", + "callbackUrl": "http://127.0.0.1:7001", + "sourceId": "mso", + "optimizer": [ + "placement", + "license" + ], + "numSolutions": 1, + "timeout": 600 + }, + "placementInfo": { + "serviceModelInfo": { + "modelType": "", + "modelInvariantId": "598e3f9e-3244-4d8f-a8e0-0e5d7a29eda9", + "modelVersionId": "b8c45108-68df-48c5-8d58-c8dd4de833bb", + "modelName": "ADIOD vMX vPE_BV Service 488", + "modelVersion": "1.0" + }, + "subscriberInfo": { + "globalSubscriberId": "21014aa2-526b-11e6-beb8-9e71128cae77", + "subscriberCommonSiteId": "MDTWNJ2B17" + }, + "demandInfo": { + "placementDemand": [{ + "resourceInstanceType": "VNF", + "serviceResourceId": "6ea4128a-ba41-4872-a1f8-2748d0e1c361", + "resourceModuleName": "2017-488_ADIOD-vPE 0", + "resourceModelInfo": { + "modelCustomizationId": "06ed941b-1d83-4132-8a1d-1874f4f4b89b", + "modelInvariantId": "5be7e99e-8eb2-4d97-be63-8081ff3cd10e", + "modelName": "2017-488_ADIOD-vPE", + "modelVersion": "1.0", + "modelVersionId": "7cd2d399-2bcb-4ecf-bd32-c36cdca7aa03", + "modelType": "" + }, + "tenantId": "", + "tenantName": "" + } + ], + "licenseDemand": [{ + "resourceInstanceType": "VNF", + "serviceResourceId": "6ea4128a-ba41-4872-a1f8-2748d0e1c361", + "resourceModuleName": "2017-488_ADIOD-vPE 0", + "resourceModelInfo": { + "modelCustomizationId": "06ed941b-1d83-4132-8a1d-1874f4f4b89b", + "modelInvariantId": "5be7e99e-8eb2-4d97-be63-8081ff3cd10e", + "modelName": "2017-488_ADIOD-vPE", + "modelVersion": "1.0", + "modelVersionId": "7cd2d399-2bcb-4ecf-bd32-c36cdca7aa03", + "modelType": "" + } + } + ] + }, + "policyId": [], + "serviceInstanceId": "28014cbe-b334-4d5c-839d-980157929b0b", + "orderInfo": "{\"requestParameters\": {\"aLaCarte\":false,\"usePreload\":true,\"subscriptionServiceType\":\"VPE\",\"alaCarteSet\":true,\"rebuildVolumeGroups\":false,\"userParams\":[{\"name\":\"2017488_adiodvpe0_vnf_config_template_version\",\"value\":\"17.2\"},{\"name\":\"2017488_adiodvpe0_bandwidth_units\",\"value\":\"Gbps\"},{\"name\":\"2017488_adiodvpe0_bandwidth\",\"value\":\"10\"},{\"name\":\"2017488_adiodvpe0_AIC_CLLI\",\"value\":\"MDTWNJ2B17\"},{\"name\":\"2017488_adiodvpe0_vnf_instance_name\",\"value\":\"mtnj309me6\"}],\"autoBuildVfModules\":false,\"cascadeDelete\":false}}" + } +} diff --git a/test/placement-tests/request_mso_subs_name_null.json b/test/placement-tests/request_mso_subs_name_null.json new file mode 100644 index 0000000..df7ae8f --- /dev/null +++ b/test/placement-tests/request_mso_subs_name_null.json @@ -0,0 +1,63 @@ +{ + "requestInfo": { + "transactionId": "1b98ee53-3fbd-48ca-9b85-302792bf5918", + "requestId": "1b98ee53-3fbd-48ca-9b85-302792bf5918", + "callbackUrl": "http://127.0.0.1:7001", + "sourceId": "mso", + "optimizer": [ + "placement", + "license" + ], + "numSolutions": 1, + "timeout": 600 + }, + "placementInfo": { + "serviceModelInfo": { + "modelType": "", + "modelInvariantId": "598e3f9e-3244-4d8f-a8e0-0e5d7a29eda9", + "modelVersionId": "b8c45108-68df-48c5-8d58-c8dd4de833bb", + "modelName": "ADIOD vMX vPE_BV Service 488", + "modelVersion": "1.0" + }, + "subscriberInfo": { + "globalSubscriberId": "21014aa2-526b-11e6-beb8-9e71128cae77", + "subscriberName": "null", + "subscriberCommonSiteId": "MDTWNJ2B17" + }, + "demandInfo": { + "placementDemand": [{ + "resourceInstanceType": "VNF", + "serviceResourceId": "6ea4128a-ba41-4872-a1f8-2748d0e1c361", + "resourceModuleName": "2017-488_ADIOD-vPE 0", + "resourceModelInfo": { + "modelCustomizationId": "06ed941b-1d83-4132-8a1d-1874f4f4b89b", + "modelInvariantId": "5be7e99e-8eb2-4d97-be63-8081ff3cd10e", + "modelName": "2017-488_ADIOD-vPE", + "modelVersion": "1.0", + "modelVersionId": "7cd2d399-2bcb-4ecf-bd32-c36cdca7aa03", + "modelType": "" + }, + "tenantId": "", + "tenantName": "" + } + ], + "licenseDemand": [{ + "resourceInstanceType": "VNF", + "serviceResourceId": "6ea4128a-ba41-4872-a1f8-2748d0e1c361", + "resourceModuleName": "2017-488_ADIOD-vPE 0", + "resourceModelInfo": { + "modelCustomizationId": "06ed941b-1d83-4132-8a1d-1874f4f4b89b", + "modelInvariantId": "5be7e99e-8eb2-4d97-be63-8081ff3cd10e", + "modelName": "2017-488_ADIOD-vPE", + "modelVersion": "1.0", + "modelVersionId": "7cd2d399-2bcb-4ecf-bd32-c36cdca7aa03", + "modelType": "" + } + } + ] + }, + "policyId": [], + "serviceInstanceId": "28014cbe-b334-4d5c-839d-980157929b0b", + "orderInfo": "{\"requestParameters\": {\"aLaCarte\":false,\"usePreload\":true,\"subscriptionServiceType\":\"VPE\",\"alaCarteSet\":true,\"rebuildVolumeGroups\":false,\"userParams\":[{\"name\":\"2017488_adiodvpe0_vnf_config_template_version\",\"value\":\"17.2\"},{\"name\":\"2017488_adiodvpe0_bandwidth_units\",\"value\":\"Gbps\"},{\"name\":\"2017488_adiodvpe0_bandwidth\",\"value\":\"10\"},{\"name\":\"2017488_adiodvpe0_AIC_CLLI\",\"value\":\"MDTWNJ2B17\"},{\"name\":\"2017488_adiodvpe0_vnf_instance_name\",\"value\":\"mtnj309me6\"}],\"autoBuildVfModules\":false,\"cascadeDelete\":false}}" + } +} diff --git a/test/placement-tests/request_vCPE.json b/test/placement-tests/request_vCPE.json new file mode 100644 index 0000000..03e32d9 --- /dev/null +++ b/test/placement-tests/request_vCPE.json @@ -0,0 +1,105 @@ +{ + "requestInfo": { + "transactionId": "xxx-xxx-xxxx", + "requestId": "yyy-yyy-yyyy", + "callbackUrl": "https://so:5000/callbackUrl", + "sourceId": "SO", + "requestType": "create", + "numSolutions": 1, + "optimizers": ["placement"], + "timeout": 600 + }, + "requestParameters": { + "customerLatitude": 32.897480, + "customerLongitude": -97.040443, + "customerName": "xyz" + }, + "placementDemands": [ + { + "resourceModuleName": "vGMuxInfra", + "serviceResourceId": "vGMuxInfra-xx", + "tenantId": "vGMuxInfra-tenant", + "resourceModelInfo": { + "modelInvariantId": "vGMuxInfra-modelInvariantId", + "modelVersionId": "vGMuxInfra-versionId", + "modelName": "vGMuxInfra-model", + "modelType": "resource", + "modelVersion": "1.0", + "modelCustomizationName": "vGMuxInfra-customeModelName" + }, + "existingCandidates": { + "identifierType": "service_instance_id", + "identifiers": ["87257b49-9602-4ca1-9817-094e52bc873b"] + }, + "excludedCandidates": { + "identifierType": "service_instance_id", + "identifiers": ["1ac71fb8-ad43-4e16-9459-c3f372b8236d"] + }, + "requiredCandidates": { + "identifierType": "service_instance_id", + "identifiers": ["7e6c3e57-62cd-44f6-aa88-d0896998f7ec"] + } + }, + { + "resourceModuleName": "vG", + "serviceResourceId": "71d563e8-e714-4393-8f99-cc480144a05e", + "tenantId": "vG-tenant", + "resourceModelInfo": { + "modelInvariantId": "vG-modelInvariantId", + "modelVersionId": "vG-versionId", + "modelName": "vG-model", + "modelType": "resource", + "modelVersion": "1.0", + "modelCustomizationName": "vG-customeModelName" + }, + "existingCandidates": { + "identifierType": "service_instance_id", + "identifiers": ["21d5f3e8-e714-4383-8f99-cc480144505a"] + }, + "excludedCandidates": { + "identifierType": "service_instance_id", + "identifiers": ["1ac71fb8-ad43-4e16-9459-c3f372b8236d"] + }, + "requiredCandidates": { + "identifierType": "cloud_region_id", + "identifiers": ["TXAUS219"] + } + } + ], + "serviceInfo": { + "serviceInstanceId": "d61b2543-5914-4b8f-8e81-81e38575b8ec", + "serviceModelInfo": { + "modelInvariantId": "vCPE-invariantId", + "modelVersionId": "vCPE-versionId", + "modelName": "vCPE-model", + "modelType": "service", + "modelVersion": "1.0", + "modelCustomizationName": "vCPE-customeModelName" + } + }, + "licenseDemands": [ + { + "resourceModuleName": "vGMuxInfra", + "serviceResourceId": "vGMuxInfra-xx", + "tenantId": "vGMuxInfra-tenant", + "resourceModelInfo": { + "modelInvariantId": "vGMuxInfra-modelInvariantId", + "modelVersionId": "vGMuxInfra-versionId", + "modelName": "vGMuxInfra-model", + "modelType": "resource", + "modelVersion": "1.0", + "modelCustomizationName": "vGMuxInfra-customeModelName" + }, + "existingLicenses": { + "entitlementPoolUUID": [ + "87257b49-9602-4ca1-9817-094e52bc873b", + "43257b49-9602-4fe5-9337-094e52bc9435" + ], + "licenseKeyGroupUUID": [ + "87257b49-9602-4ca1-9817-094e52bc873b", + "43257b49-9602-4fe5-9337-094e52bc9435" + ] + } + } + ] +} diff --git a/test/placement-tests/scopePolicies.json b/test/placement-tests/scopePolicies.json new file mode 100644 index 0000000..123c8e2 --- /dev/null +++ b/test/placement-tests/scopePolicies.json @@ -0,0 +1,21 @@ + {
+ "policyConfigMessage": "Config Retrieved! ",
+ "policyConfigStatus": "CONFIG_RETRIEVED",
+ "type": "JSON",
+ "config": "{\"service\":\"ResourceRegionPolicy\",\"policyName\":\"bg4702.ResourceRegionPolicy_vhnportal_v1\",\"description\":\"ResourceRegionPolicy@CreatedBy:mh7921\",\"templateVersion\":\"1802V01\",\"version\":\"1802V01\",\"priority\":\"1\",\"riskType\":\"test\",\"riskLevel\":\"3\",\"guard\":\"False\",\"content\":{\"identity\":\"vhnPortalResourceRegion\",\"policyScope\":{\"serviceType\":[\"DHV\"],\"geoRegion\":[\"US\",\"INTERNATIONAL\"],\"subscriberRole\":[\"FFA Homing\"],\"networkType\":[\"ip\"],\"resourceInstanceType\":[\"Primary Service_Admin\",\"Secondary Service_Admin\"]},\"resourceRegionProperty\":{\"request\":\"{\\\"dhv_service_instance\\\": {\\\"get_param\\\": \\\"SERVICE_INST\\\"}, \\\"service_type\\\": \\\"vHNPortal\\\", \\\"e2evpnkey\\\": {\\\"get_param\\\": \\\"E2EVPNKEY\\\"}}\",\"controller\":\"SDN-C\"},\"type\":\"region_fit\",\"resourceInstanceType\":[\"Primary Service_Admin\",\"Secondary Service_Admin\"]}}",
+ "policyName": "bg4702.Config_MS_ResourceRegionPolicy_vhnportal_v1.1.xml",
+ "policyVersion": "1",
+ "matchingConditions": {
+ "serviceType": "DHV",
+ "ECOMPName": "SNIRO-Placement",
+ "ONAPName": "SNIRO-Placement",
+ "geoRegion": "US,INTERNATIONAL",
+ "service": "ResourceRegionPolicy",
+ "subscriberRole": "FFA Homing",
+ "type": "region_fit",
+ "networkType": "ip",
+ "resourceInstanceType": "Primary Service_Admin,Secondary Service_Admin"
+ },
+ "responseAttributes": {},
+ "property": null
+ }
\ No newline at end of file diff --git a/test/placement-tests/testScoperequest.json b/test/placement-tests/testScoperequest.json new file mode 100644 index 0000000..36f0c17 --- /dev/null +++ b/test/placement-tests/testScoperequest.json @@ -0,0 +1,144 @@ +{
+ "placementInfo": {
+ "serviceModelInfo": {
+ "modelVersion": "1.0",
+ "modelName": "vCPE",
+ "modelInvariantId": "250c90b4-42f9-4cd9-9270-fd33a0676f92",
+ "modelVersionId": "c233e7f3-bd70-4a2c-a88f-4f5743109e8d",
+ "modelType": "service"
+ },
+ "orderInfo":" { \"requestParameters\": { \"e2eVpnKey\": \"VPNL61657\", \"dhvVendorName\": \"VELOCLOUD\", \"dhvIPSec2TransportBandwidthUp\": \"10\", \"vpnList\": [ { \"vpnInfo\": { \"pvcId\": \"5952413\", \"vpnId\": \"61657\" } } ], \"dhvSiteEffectiveTransportBandwidth\": \"10\", \"ucpeHostName\": \"US292IORLFL0102UJZZ01\", \"commonSiteId\": \"90101124\", \"dhvIPSec2TransportBandwidthDown\": \"10\", \"vnfList\": [ { \"vnfInfo\": { \"vnfType\": \"HN\", \"veloCloudNominalThroughput\": \"100\", \"vnfHostName\": \"US292IORLFL0102UVHN01\", \"vnfPartNumber\": \"DHV-VNF-VC-10M\", \"vnfManagementOption\": \"ATT\", \"vnfSoftwareVersion\": \"2.4.1\" } } ] } }",
+ "serviceInstanceId": "4701bd3c-b722-4d07-abc0-183ea398fac5",
+ "demandInfo": {
+ "placementDemand": [
+ {
+ "tenantName": "",
+ "tenantId": "",
+ "serviceResourceId": "a297f69d-4d68-4d1f-8b06-be61bddf9e7f",
+ "resourceInstanceType": "vVIGaaS",
+ "resourceModuleName": "Primary Tunnel_XConn for DHV Testing_1 0",
+ "resourceModelInfo": {
+ "modelVersion": "1.0",
+ "modelName": "Tunnel_XConn for DHV Testing_1",
+ "modelInvariantId": "b2ac0b6a-c157-4f27-a226-4fc6c1d5b08c",
+ "modelCustomizationId": "8ade4a5f-a446-4b14-9d12-3ccdd80ef55c",
+ "modelVersionId": "c3c3531a-a0c6-498f-8512-03793f7772fa",
+ "modelType": "allottedResource"
+ }
+ },
+ {
+ "tenantName": "",
+ "tenantId": "",
+ "serviceResourceId": "73190cfb-e9de-4185-8f18-cb339df6b92a",
+ "resourceInstanceType": "vVIGaaS",
+ "resourceModuleName": "Secondary Tunnel_XConn for DHV Testing_1 1",
+ "resourceModelInfo": {
+ "modelVersion": "1.0",
+ "modelName": "Tunnel_XConn for DHV Testing_1",
+ "modelInvariantId": "b2ac0b6a-c157-4f27-a226-4fc6c1d5b08c",
+ "modelCustomizationId": "32b80123-84ea-4bda-82d9-4c70e812b450",
+ "modelVersionId": "c3c3531a-a0c6-498f-8512-03793f7772fa",
+ "modelType": "allottedResource"
+ }
+ },
+ {
+ "tenantName": "",
+ "tenantId": "",
+ "serviceResourceId": "f8489f98-db3d-4e84-9ec7-7f7b17b9857f",
+ "resourceInstanceType": "vHNPortalaaS",
+ "resourceModuleName": "Primary Service_Admin for DHV Test_1 0",
+ "resourceModelInfo": {
+ "modelVersion": "1.0",
+ "modelName": "Service_Admin for DHV Test_1",
+ "modelInvariantId": "a8031455-34bc-4608-b731-973c258822d2",
+ "modelCustomizationId": "bace7e9f-c0e7-4479-93df-aa10d387038b",
+ "modelVersionId": "0e830d97-39fc-4310-a11d-ebab6c71b35e",
+ "modelType": "allottedResource"
+ }
+ },
+ {
+ "tenantName": "",
+ "tenantId": "",
+ "serviceResourceId": "8a8973d4-3a91-4fe6-a846-6f4c282f9005",
+ "resourceInstanceType": "vHNPortalaaS",
+ "resourceModuleName": "Secondary Service_Admin for DHV Test_1 1",
+ "resourceModelInfo": {
+ "modelVersion": "1.0",
+ "modelName": "Service_Admin for DHV Test_1",
+ "modelInvariantId": "a8031455-34bc-4608-b731-973c258822d2",
+ "modelCustomizationId": "cb6d359d-8f83-41b6-b0cc-fb3cdf978e25",
+ "modelVersionId": "0e830d97-39fc-4310-a11d-ebab6c71b35e",
+ "modelType": "allottedResource"
+ }
+ },
+ {
+ "tenantName": "",
+ "tenantId": "",
+ "serviceResourceId": "3f2b0c6d-6867-4369-b597-d929305da414",
+ "resourceInstanceType": "vHNGWaaS",
+ "resourceModuleName": "Primary IP_Mux_Demux updated_1 0",
+ "resourceModelInfo": {
+ "modelVersion": "1.0",
+ "modelName": "IP_Mux_Demux updated_1",
+ "modelInvariantId": "72ad23e8-575d-4bc1-a88d-bb63ca66b85f",
+ "modelCustomizationId": "925db703-945a-4b14-aafa-607c99c32f46",
+ "modelVersionId": "cb760674-1c09-4316-837f-1ee1e816c26f",
+ "modelType": "allottedResource"
+ }
+ },
+ {
+ "tenantName": "",
+ "tenantId": "",
+ "serviceResourceId": "caea369e-90e6-4bf0-9aa4-c80ffb10c77e",
+ "resourceInstanceType": "vHNGWaaS",
+ "resourceModuleName": "Secondary IP_Mux_Demux updated_1 1",
+ "resourceModelInfo": {
+ "modelVersion": "1.0",
+ "modelName": "IP_Mux_Demux updated_1",
+ "modelInvariantId": "72ad23e8-575d-4bc1-a88d-bb63ca66b85f",
+ "modelCustomizationId": "5f5793d7-843c-4f8e-b01d-35ece0b17ead",
+ "modelVersionId": "cb760674-1c09-4316-837f-1ee1e816c26f",
+ "modelType": "allottedResource"
+ }
+ }
+ ]
+ },
+ "subscriberInfo": {
+ "subscriberCommonSiteId": null,
+ "globalSubscriberId": "300NCQ",
+ "subscriberName": "Test Customer"
+ },
+ "policyId": [
+ "SNIRO.DistanceToLocationPolicy_vhngw",
+ "SNIRO.VNFPolicy_vhngatewayprimary1_v1",
+ "SNIRO.ResourceInstancePolicy_hngateway",
+ "SNIRO.ResourceRegionPolicy_hngateway_v1",
+ "SNIRO.VNFPolicy_vhngatewaysecondary1_v1",
+ "SNIRO.ZonePolicy_vhngw",
+ "SNIRO.PlacementOptimizationPolicy_dhv_v3",
+ "SNIRO.VNFPolicy_vhnportal_primary1_v1",
+ "SNIRO.ResourceInstancePolicy_vhnportal_v3",
+ "SNIRO.ResourceRegionPolicy_vhnportal_v1",
+ "SNIRO.VNFPolicy_vhnportalsecondary1_v1",
+ "SNIRO.ZonePolicy_vhnportal",
+ "SNIRO.DistanceToLocationPolicy_vvig",
+ "SNIRO.InventoryGroupPolicy_vvig",
+ "SNIRO.VNFPolicy_vvigprimary1_v1",
+ "SNIRO.ResourceInstancePolicy_vvig",
+ "SNIRO.VNFPolicy_vvigsecondary1_v1"
+ ]
+ },
+ "requestInfo": {
+ "transactionId": "264e9db9-6d59-4888-9c90-51245d7c811f",
+ "sourceId": "mso",
+ "requestType": "initial",
+ "callbackUrl": "http://127.0.0.1:7001",
+ "requestId": "264e9db9-6d59-4888-9c90-51245d7c811f",
+ "optimizer": [
+ "placement",
+ "license"
+ ],
+ "numSolutions": 1,
+ "timeout": 1800
+ }
+}
diff --git a/test/placement-tests/test_by_scope.yaml b/test/placement-tests/test_by_scope.yaml new file mode 100644 index 0000000..0b53e5f --- /dev/null +++ b/test/placement-tests/test_by_scope.yaml @@ -0,0 +1,20 @@ +policy_info: + placement: + policy_fetch: by_scope + policy_scope: + default_scope: XXX_1802 + scope_vcpe: oof_beijing + service_name: placementInfo.serviceModelInfo.modelName + policy_subscriber: SubscriberPolicy + subscriber_name: placementInfo.subscriberInfo.subscriberName + policy_type_vcpe: + - CloudAttributePolicy + - DistanceToLocationPolicy + - instanceReservationPolicy + - PlacementOptimizationPolicy + - ResourceInstancePolicy + - VNFPolicy + - ZonePolicy + default: # if no explicit service related information is needed + policy_fetch: by_name + policy_scope: none diff --git a/test/placement-tests/vnfGroupPolicies.txt b/test/placement-tests/vnfGroupPolicies.txt new file mode 100644 index 0000000..16aca6c --- /dev/null +++ b/test/placement-tests/vnfGroupPolicies.txt @@ -0,0 +1,197 @@ +[
+ {
+ "content": {
+ "identity": "vhngateway-pri-sec-1",
+ "policyScope": {
+ "geoRegion": [
+ "US",
+ "INTERNATIONAL"
+ ],
+ "networkType": [
+ "ip"
+ ],
+ "resourceInstanceType": [
+ "Primary IP_Mux_Demux",
+ "Secondary IP_Mux_Demux"
+ ],
+ "serviceType": [
+ "DHV"
+ ],
+ "subscriberRole": [
+ "FFA Homing"
+ ]
+ },
+ "property": [
+ {
+ "attributes": {
+ "equipmentRole": "",
+ "globalCustomerId": "",
+ "modelInvariantId": "",
+ "modelVersionId": "",
+ "operationalStatus": "out-of-service-path",
+ "orchestrationStatus": [
+ "Activate",
+ "Activated"
+ ]
+ },
+ "inventoryProvider": "aai",
+ "inventoryType": "cloud"
+ },
+ {
+ "attributes": {
+ "equipmentRole": "",
+ "globalCustomerId": "21014aa2-526b-11e6-beb8-9e71128cae77",
+ "modelInvariantId": "",
+ "modelVersionId": "",
+ "operationalStatus": "out-of-service-path",
+ "orchestrationStatus": [
+ "Activate",
+ "Activated"
+ ]
+ },
+ "inventoryProvider": "aai",
+ "inventoryType": "service"
+ }
+ ],
+ "resourceInstanceType": [
+ "Primary IP_Mux_Demux",
+ "Secondary IP_Mux_Demux"
+ ],
+ "type": "vnfPolicy"
+ },
+ "description": "VNFPolicy@CreatedBy:mh7921",
+ "guard": "False",
+ "policyName": "bg4702.VNFPolicy_vhngatewayprimary_v1",
+ "priority": "1",
+ "riskLevel": "3",
+ "riskType": "test",
+ "service": "VNFPolicy",
+ "templateVersion": "1802V01",
+ "version": "1802V01"
+ },
+ {
+ "content": {
+ "identity": "vhnportal-pri-sec-1",
+ "policyScope": {
+ "geoRegion": [
+ "US",
+ "INTERNATIONAL"
+ ],
+ "networkType": [
+ "ip"
+ ],
+ "resourceInstanceType": [
+ "Primary Service_Admin",
+ "Secondary Service_Admin"
+ ],
+ "serviceType": [
+ "DHV"
+ ],
+ "subscriberRole": [
+ "FFA Homing"
+ ]
+ },
+ "property": [
+ {
+ "attributes": {
+ "equipmentRole": "",
+ "globalCustomerId": "",
+ "modelInvariantId": "",
+ "modelVersionId": "",
+ "operationalStatus": "out-of-service-path",
+ "orchestrationStatus": [
+ "Activate",
+ "Activated"
+ ]
+ },
+ "inventoryProvider": "aai",
+ "inventoryType": "cloud"
+ },
+ {
+ "attributes": {
+ "equipmentRole": "",
+ "globalCustomerId": "21014aa2-526b-11e6-beb8-9e71128cae77",
+ "modelInvariantId": "",
+ "modelVersionId": "",
+ "operationalStatus": "out-of-service-path",
+ "orchestrationStatus": [
+ "Activate",
+ "Activated"
+ ]
+ },
+ "inventoryProvider": "aai",
+ "inventoryType": "service"
+ }
+ ],
+ "resourceInstanceType": [
+ "Primary Service_Admin",
+ "Secondary Service_Admin"
+ ],
+ "type": "vnfPolicy"
+ },
+ "description": "VNFPolicy@CreatedBy:mh7921",
+ "guard": "False",
+ "policyName": "bg4702.VNFPolicy_vhnportal_primary_v1",
+ "priority": "1",
+ "riskLevel": "3",
+ "riskType": "test",
+ "service": "VNFPolicy",
+ "templateVersion": "1802V01",
+ "version": "1802V01"
+ },
+ {
+ "content": {
+ "identity": "vvig-pri-sec-1",
+ "policyScope": {
+ "geoRegion": [
+ "US",
+ "INTERNATIONAL"
+ ],
+ "networkType": [
+ "ip"
+ ],
+ "resourceInstanceType": [
+ "Primary Tunnel_XConn",
+ "Secondary Tunnel_XConn"
+ ],
+ "serviceType": [
+ "DHV"
+ ],
+ "subscriberRole": [
+ "FFA Homing"
+ ]
+ },
+ "property": [
+ {
+ "attributes": {
+ "equipmentRole": "",
+ "globalCustomerId": "21014aa2-526b-11e6-beb8-9e71128cae77",
+ "modelInvariantId": "",
+ "modelVersionId": "",
+ "operationalStatus": "out-of-service-path",
+ "orchestrationStatus": [
+ "Activate",
+ "Activated"
+ ]
+ },
+ "inventoryProvider": "aai",
+ "inventoryType": "service"
+ }
+ ],
+ "resourceInstanceType": [
+ "Primary Tunnel_XConn",
+ "Secondary Tunnel_XConn"
+ ],
+ "type": "vnfPolicy"
+ },
+ "description": "VNFPolicy@CreatedBy:mh7921",
+ "guard": "False",
+ "policyName": "bg4702.VNFPolicy_vvig1_v1",
+ "priority": "1",
+ "riskLevel": "3",
+ "riskType": "test",
+ "service": "VNFPolicy",
+ "templateVersion": "1802V01",
+ "version": "1802V01"
+ }
+]
\ No newline at end of file diff --git a/test/policy-local-files/CloudAttributePolicy_vGMuxInfra_1.json b/test/policy-local-files/CloudAttributePolicy_vGMuxInfra_1.json new file mode 100644 index 0000000..57c0039 --- /dev/null +++ b/test/policy-local-files/CloudAttributePolicy_vGMuxInfra_1.json @@ -0,0 +1,34 @@ +{ + "service": "CloudAttributePolicy", + "policyName": "CloudAttributePolicy_vGMuxInfra", + "description": "Attribute policy", + "templateVersion": "1702.03", + "version": "1707", + "priority": "3", + "riskType": "test", + "riskLevel": "3", + "guard": "False", + "content": { + "identity": "vGMuxInfra_cloud_attributes", + "policyScope": { + "serviceType": ["vCPE"], + "geoRegion": ["US", "INTERNATIONAL"], + "networkType": ["ip"], + "resourceInstanceType": ["vGMuxInfra"] + }, + "cloudAttributeProperty": { + "networkRoles": { + "all": [ + "vGMuxInfra.OAM", + "vGMuxInfra.SR_IOV_Provider2_1", + "vGMuxInfra.SR_IOV_Provider2_2" + ] + }, + "complex": { + "any": [ ] + } + }, + "type": "attribute", + "resourceInstanceType": ["vGMuxInfra"] + } +} diff --git a/test/policy-local-files/CloudAttributePolicy_vG_1.json b/test/policy-local-files/CloudAttributePolicy_vG_1.json new file mode 100644 index 0000000..cbe2a88 --- /dev/null +++ b/test/policy-local-files/CloudAttributePolicy_vG_1.json @@ -0,0 +1,34 @@ +{ + "service": "CloudAttributePolicy", + "policyName": "cloud AttributePolicy_vG", + "description": "Attribute policy", + "templateVersion": "1702.03", + "version": "1707", + "priority": "10", + "riskType": "test", + "riskLevel": "3", + "guard": "False", + "content": { + "identity": "vG_cloud_attributes", + "policyScope": { + "serviceType": ["vCPE"], + "geoRegion": ["US", "INTERNATIONAL"], + "networkType": ["ip"], + "resourceInstanceType": ["vG"] + }, + "cloudAttributeProperty": { + "networkRoles": { + "all": [ + "vG.OAM", + "vG.SR_IOV_Provider2_1", + "vG.SR_IOV_Provider2_2" + ] + }, + "complex": { + "any": [ ] + } + }, + "type": "attribute", + "resourceInstanceType": ["vG"] + } +} diff --git a/test/policy-local-files/DistanceToLocationPolicy_vGMuxInfra_1.json b/test/policy-local-files/DistanceToLocationPolicy_vGMuxInfra_1.json new file mode 100644 index 0000000..414c167 --- /dev/null +++ b/test/policy-local-files/DistanceToLocationPolicy_vGMuxInfra_1.json @@ -0,0 +1,30 @@ +{ + "service": "DistanceToLocationPolicy", + "policyName": "DistanceToLocationPolicy_vGMuxInfra", + "description": "DistanceToLocationPolicy", + "templateVersion": "1702.03", + "version": "1707", + "priority": "3", + "riskType": "test", + "riskLevel": "2", + "guard": "False", + "content": { + "distanceToLocationProperty": { + "locationInfo": "customer_loc", + "distanceCondition": { + "parameter": "distance", + "value": "50000 km", + "operator": "less" + } + }, + "identity": "distance-vGMuxInfra", + "policyScope": { + "serviceType": ["vCPE"], + "geoRegion": ["US", "INTERNATIONAL"], + "networkType": ["ip"], + "resourceInstanceType": ["vGMuxInfra"] + }, + "type": "distance_to_location", + "resourceInstanceType": ["vGMuxInfra"] + } +} diff --git a/test/policy-local-files/DistanceToLocationPolicy_vG_1.json b/test/policy-local-files/DistanceToLocationPolicy_vG_1.json new file mode 100644 index 0000000..737ee19 --- /dev/null +++ b/test/policy-local-files/DistanceToLocationPolicy_vG_1.json @@ -0,0 +1,30 @@ +{ + "service": "DistanceToLocationPolicy", + "policyName": "DistanceToLocationPolicy_vG", + "description": "DistanceToLocationPolicy", + "templateVersion": "1702.03", + "version": "1707", + "priority": "3", + "riskType": "test", + "riskLevel": "2", + "guard": "False", + "content": { + "distanceToLocationProperty": { + "locationInfo": "customer_loc", + "distanceCondition": { + "parameter": "distance", + "value": "50000 km", + "operator": "less" + } + }, + "identity": "distance-vG", + "policyScope": { + "serviceType": ["vCPE"], + "geoRegion": ["US", "INTERNATIONAL"], + "networkType": ["ip"], + "resourceInstanceType": ["vG"] + }, + "type": "distance_to_location", + "resourceInstanceType": ["vG"] + } +} diff --git a/test/policy-local-files/InventoryGroup_vGMuxInfra_1.json b/test/policy-local-files/InventoryGroup_vGMuxInfra_1.json new file mode 100644 index 0000000..20ff7f7 --- /dev/null +++ b/test/policy-local-files/InventoryGroup_vGMuxInfra_1.json @@ -0,0 +1,22 @@ +{ + "service": "InventoryGroupPolicy", + "policyName": "InventoryGroupPolicy_vGMuxInfra", + "description": "InventoryGroupPolicy", + "templateVersion": "1702.03", + "version": "1707", + "priority": "6", + "riskType": "test", + "riskLevel": "3", + "guard": "False", + "content": { + "identity": "vGMuxInfra-pri-sec-2", + "policyScope": { + "serviceType": ["vCPE"], + "geoRegion": ["US", "INTERNATIONAL"], + "networkType": ["ip"], + "resourceInstanceType": ["vGMuxInfra"] + }, + "type": "inventory_group", + "resourceInstanceType": ["vGMuxInfra"] + } +} diff --git a/test/policy-local-files/InventoryGroup_vG_1.json b/test/policy-local-files/InventoryGroup_vG_1.json new file mode 100644 index 0000000..99ae309 --- /dev/null +++ b/test/policy-local-files/InventoryGroup_vG_1.json @@ -0,0 +1,22 @@ +{ + "service": "InventoryGroupPolicy", + "policyName": "InventoryGroupPolicy_vG", + "description": "InventoryGroupPolicy", + "templateVersion": "1702.03", + "version": "1707", + "priority": "6", + "riskType": "test", + "riskLevel": "3", + "guard": "False", + "content": { + "identity": "vG-pri-sec-1", + "policyScope": { + "serviceType": ["vCPE"], + "geoRegion": ["US", "INTERNATIONAL"], + "networkType": ["ip"], + "resourceInstanceType": ["vG"] + }, + "type": "inventory_group", + "resourceInstanceType": ["vG"] + } +} diff --git a/test/policy-local-files/PlacementOptimizationPolicy.json b/test/policy-local-files/PlacementOptimizationPolicy.json new file mode 100644 index 0000000..7c43435 --- /dev/null +++ b/test/policy-local-files/PlacementOptimizationPolicy.json @@ -0,0 +1,41 @@ +{ + "service": "PlacementOptimizationPolicy", + "policyName": "PlacementOptimizationPolicy", + "description": "PlacementOptimizationPolicy", + "templateVersion": "1702.03", + "version": "1707", + "priority": "5", + "riskType": "test", + "riskLevel": "3", + "guard": "False", + "content": { + "objectiveParameter": { + "parameterAttributes": [ + { + "resource": ["vGMuxInfra"], + "customerLocationInfo": "customer_loc", + "parameter": "distance", + "weight": "2", + "operator": "product" + }, + { + "resource": ["vG"], + "customerLocationInfo": "customer_loc", + "parameter": "distance", + "weight": "1", + "operator": "product" + } + ], + "operator": "sum" + }, + "identity": "optimization", + "policyScope": { + "serviceType": ["vCPE"], + "geoRegion": ["US", "INTERNATIONAL"], + "networkType": ["ip"], + "resourceInstanceType": ["vGMuxInfra","vG"] + }, + "type": "placementOptimization", + "objective": "minimize" + } +} diff --git a/test/policy-local-files/ResourceInstancePolicy_vG_1.json b/test/policy-local-files/ResourceInstancePolicy_vG_1.json new file mode 100644 index 0000000..21ae0e4 --- /dev/null +++ b/test/policy-local-files/ResourceInstancePolicy_vG_1.json @@ -0,0 +1,26 @@ +{ + "service": "ResourceInstancePolicy", + "policyName": "ResourceInstancePolicy_vG", + "description": "ResourceInstancePolicy", + "templateVersion": "1702.03", + "version": "1707", + "priority": "5", + "riskType": "test", + "riskLevel": "3", + "guard": "False", + "content": { + "identity": "vG-resourceInstance", + "policyScope": { + "serviceType": ["vCPE"], + "geoRegion": ["US", "INTERNATIONAL"], + "networkType": ["ip"], + "resourceInstanceType": ["vG", "vGMuxInfra"] + }, + "resourceInstanceProperty": { + "request": "{\"test\": \"123\"}", + "controller": "SDN-C" + }, + "type": "instance_fit", + "resourceInstanceType": ["vG", "vGMuxInfra"] + } +} diff --git a/test/policy-local-files/VNFPolicy_vGMuxInfra_1.json b/test/policy-local-files/VNFPolicy_vGMuxInfra_1.json new file mode 100644 index 0000000..b0963d6 --- /dev/null +++ b/test/policy-local-files/VNFPolicy_vGMuxInfra_1.json @@ -0,0 +1,36 @@ +{ + "service": "VNFPolicy", + "policyName": "VNFPolicy_vGMuxInfra", + "description": "VNFPolicy", + "templateVersion": "1702.03", + "version": "1707", + "priority": "6", + "riskType": "test", + "riskLevel": "3", + "guard": "False", + "content": { + "identity": "vGMuxInfra-pri-sec-1", + "policyScope": { + "serviceType": ["vCPE"], + "geoRegion": ["US", "INTERNATIONAL"], + "networkType": ["ip"], + "resourceInstanceType": ["vGMuxInfra"] + }, + "property": [ + { + "inventoryProvider": "aai", + "serviceType": "", + "inventoryType": "cloud", + "customerId": "" + }, + { + "inventoryProvider": "aai", + "serviceType": "vGMuxInfraaaS", + "inventoryType": "service", + "customerId": "21014aa2-526b-11e6-beb8-9e71128cae77" + } + ], + "type": "vnfPolicy", + "resourceInstanceType": ["vGMuxInfra"] + } +} diff --git a/test/policy-local-files/VNFPolicy_vG_1.json b/test/policy-local-files/VNFPolicy_vG_1.json new file mode 100644 index 0000000..de0a158 --- /dev/null +++ b/test/policy-local-files/VNFPolicy_vG_1.json @@ -0,0 +1,36 @@ +{ + "service": "VNFPolicy", + "policyName": "VNFPolicy_vG", + "description": "VNFPolicy", + "templateVersion": "1702.03", + "version": "1707", + "priority": "6", + "riskType": "test", + "riskLevel": "3", + "guard": "False", + "content": { + "identity": "vG-pri-sec-1", + "policyScope": { + "serviceType": ["vCPE"], + "geoRegion": ["US", "INTERNATIONAL"], + "networkType": ["ip"], + "resourceInstanceType": ["vG"] + }, + "property": [ + { + "inventoryProvider": "aai", + "serviceType": "", + "inventoryType": "cloud", + "customerId": " " + }, + { + "inventoryProvider": "aai", + "serviceType": "vGaaS", + "inventoryType": "service", + "customerId": "21014aa2-526b-11e6-beb8-9e71128cae77" + } + ], + "type": "vnfPolicy", + "resourceInstanceType": ["vG"] + } +} diff --git a/test/policy-local-files/ZonePolicy_vGMuxInfra_1.json b/test/policy-local-files/ZonePolicy_vGMuxInfra_1.json new file mode 100644 index 0000000..9f941e4 --- /dev/null +++ b/test/policy-local-files/ZonePolicy_vGMuxInfra_1.json @@ -0,0 +1,26 @@ +{ + "service": "ZonePolicy", + "policyName": "ZonePolicy_vGMuxInfra", + "description": "ZonePolicy", + "templateVersion": "1702.03", + "version": "1707", + "priority": "5", + "riskType": "test", + "riskLevel": "2", + "guard": "False", + "content": { + "identity": "zone-vGMuxInfra", + "policyScope": { + "serviceType": ["vCPE"], + "geoRegion": ["US", "INTERNATIONAL"], + "networkType": ["ip"], + "resourceInstanceType": ["vGMuxInfra"] + }, + "zoneProperty": { + "qualifier": "different", + "category": "complex" + }, + "type": "zone", + "resourceInstanceType": ["vGMuxInfra"] + } +} diff --git a/test/policy-local-files/ZonePolicy_vG_1.json b/test/policy-local-files/ZonePolicy_vG_1.json new file mode 100644 index 0000000..8104f6b --- /dev/null +++ b/test/policy-local-files/ZonePolicy_vG_1.json @@ -0,0 +1,26 @@ +{ + "service": "ZonePolicy", + "policyName": "ZonePolicy_vG", + "description": "ZonePolicy", + "templateVersion": "1702.03", + "version": "1707", + "priority": "5", + "riskType": "test", + "riskLevel": "2", + "guard": "False", + "content": { + "identity": "zone-vG", + "policyScope": { + "serviceType": ["vCPE"], + "geoRegion": ["US", "INTERNATIONAL"], + "networkType": ["ip"], + "resourceInstanceType": ["vG"] + }, + "zoneProperty": { + "qualifier": "different", + "category": "complex" + }, + "type": "zone", + "resourceInstanceType": ["vG"] + } +} diff --git a/test/test-requirements.txt b/test/test-requirements.txt new file mode 100644 index 0000000..b16a37e --- /dev/null +++ b/test/test-requirements.txt @@ -0,0 +1,4 @@ +coverage +moto +pytest +pytest-tap diff --git a/test/test_ConductorApiBuilder.py b/test/test_ConductorApiBuilder.py new file mode 100644 index 0000000..b988efa --- /dev/null +++ b/test/test_ConductorApiBuilder.py @@ -0,0 +1,39 @@ +import unittest +import json +import yaml +from osdf.optimizers.placementopt.conductor.api_builder import conductor_api_builder + + +class TestConductorApiBuilder(unittest.TestCase): + + def test_conductor_api_call_builder(self): + #main_dir = ".." + main_dir = "" + conductor_api_template = main_dir + "osdf/templates/conductor_interface.json" + parameter_data_file = main_dir + "test/placement-tests/request.json" + policy_data_path = main_dir + "test/policy-local-files/" + local_config_file = main_dir + "config/common_config.yaml" + + policy_data_files = ["CloudAttributePolicy_vGMuxInfra_1.json", + "CloudAttributePolicy_vG_1.json", + "DistanceToLocationPolicy_vGMuxInfra_1.json", + "DistanceToLocationPolicy_vG_1.json", + "InventoryGroup_vGMuxInfra_1.json", + "InventoryGroup_vG_1.json", + "PlacementOptimizationPolicy.json", + "ResourceInstancePolicy_vG_1.json", + "VNFPolicy_vGMuxInfra_1.json", + "VNFPolicy_vG_1.json", + "ZonePolicy_vGMuxInfra_1.json", + "ZonePolicy_vG_1.json"] + request_json = json.loads(open(parameter_data_file).read()) + policies = [json.loads(open(policy_data_path + file).read()) for file in policy_data_files] + local_config = yaml.load(open(local_config_file)) + templ_string = conductor_api_builder(request_json, policies, local_config, [], conductor_api_template) + templ_json = json.loads(templ_string) + self.assertEqual(templ_json["name"], "yyy-yyy-yyyy") + + +if __name__ == "__main__": + unittest.main() + diff --git a/test/test_PolicyCalls.py b/test/test_PolicyCalls.py new file mode 100644 index 0000000..b05b6dc --- /dev/null +++ b/test/test_PolicyCalls.py @@ -0,0 +1,115 @@ +import json +import unittest + +from osdf.config.base import osdf_config +from osdf.adapters.policy import interface +from osdf.utils.interfaces import RestClient +import yaml +from mock import patch +from osdf.optimizers.placementopt.conductor import translation + + +class TestPolicyCalls(unittest.TestCase): + + def test_get_subscriber_name(self): + req_json_obj = json.loads(open("./test/placement-tests/request_mso.json").read()) + config_core = osdf_config.core + pmain = config_core['policy_info']['placement'] + print(pmain) + subs_name = interface.get_subscriber_name(req_json_obj, pmain) + print("subscriber_name=", subs_name) + self.assertEquals(subs_name, "Avteet_Chayal") + + + def test_get_subscriber_name_null(self): + req_json_file = "./test/placement-tests/request_mso_subs_name_null.json" + req_json_obj = json.loads(open(req_json_file).read()) + config_core = osdf_config.core + + pmain = config_core['policy_info']['placement'] + print(pmain) + subs_name = interface.get_subscriber_name(req_json_obj, pmain) + print("subscriber_name=", subs_name) + self.assertEquals(subs_name, "DEFAULT") + + + def test_get_subscriber_name_blank(self): + req_json_file = "./test/placement-tests/request_mso_subs_name_blank.json" + req_json_obj = json.loads(open(req_json_file).read()) + config_core = osdf_config.core + + pmain = config_core['policy_info']['placement'] + print(pmain) + subs_name = interface.get_subscriber_name(req_json_obj, pmain) + print("subscriber_name=", subs_name) + self.assertEquals(subs_name, "DEFAULT") + + + def test_get_subscriber_name_default(self): + req_json_file = "./test/placement-tests/request_mso_subs_name_default.json" + req_json_obj = json.loads(open(req_json_file).read()) + config_core = osdf_config.core + + pmain = config_core['policy_info']['placement'] + print(pmain) + subs_name = interface.get_subscriber_name(req_json_obj, pmain) + print("subscriber_name=", subs_name) + self.assertEquals(subs_name, "DEFAULT") + + + def test_get_subscriber_name_none(self): + req_json_file = "./test/placement-tests/request_mso_subs_name_none.json" + req_json_obj = json.loads(open(req_json_file).read()) + config_core = osdf_config.core + + pmain = config_core['policy_info']['placement'] + print(pmain) + subs_name = interface.get_subscriber_name(req_json_obj, pmain) + print("subscriber_name=", subs_name) + self.assertEquals(subs_name, "DEFAULT") + + + def test_get_by_scope(self): + req_json_file = "./test/placement-tests/testScoperequest.json" + allPolicies = "./test/placement-tests/scopePolicies.json" + req_json_obj = json.loads(open(req_json_file).read()) + req_json_obj2 = json.loads(open(allPolicies).read()) + config_core = osdf_config.core + yamlFile = "./test/placement-tests/test_by_scope.yaml" + + with open(yamlFile) as yamlFile2: + policyConfigFile = yaml.load(yamlFile2) + with patch('osdf.adapters.policy.interface.get_subscriber_role', return_value=('FFA Homing', [])) as mock_open: + with patch('osdf.utils.interfaces.RestClient.request', return_value = req_json_obj2): + policiesList = interface.get_by_scope(RestClient, req_json_obj, policyConfigFile, 'placement') + print(policiesList) + #catches Exception if policiesList is null + self.assertTrue(policiesList, 'is null') + self.assertRaises(Exception) + + def test_gen_demands(self): + actionsList = [] + genDemandslist = [] + req_json = "./test/placement-tests/testScoperequest.json" + policiesList = "./test/placement-tests/vnfGroupPolicies.txt" + fh = json.loads(open(policiesList).read()) + #print(fh) + req_json = json.loads(open(req_json).read()) + config_core = osdf_config.core + service_type = req_json['placementInfo'].get('serviceType', None) + # service_type = data_mapping.get_request_service_type(req_json_file) + genDemands = translation.gen_demands(req_json['placementInfo']['demandInfo'], fh) + #print(genDemands) + #print(req_json_file['placementInfo']['demandInfo']['placementDemand'][0]) + for action in req_json['placementInfo']['demandInfo']['placementDemand']: + #print(action['resourceModuleName']) + actionsList.append(action['resourceModuleName']) + for key2,value in genDemands.items(): + #print(key2) + genDemandslist.append(key2) + #genDemandslist.remove('Primary IP_Mux_Demux updated_1 0') + #catches Exception if lists are not equal + self.assertListEqual(genDemandslist, actionsList, 'generated demands are not equal to the passed input [placementDemand][resourceModuleName] list') + +if __name__ == '__main__': + unittest.main() @@ -0,0 +1,17 @@ + +[tox] +skipsdist=True +envlist = py3 + +[testenv] +distribute = False +commands = + coverage run --module pytest + coverage report --omit=".tox/py3/*","test/*" + # TODO: need to update the above "omit" when we package osdf as pip-installable + # coverage html --omit=.tox/py3/* -d htmlcov +deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/test/test-requirements.txt + +[testenv:py3] +basepython=python3.6 |