X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=openmanod;fp=openmanod;h=0000000000000000000000000000000000000000;hb=7d782eff123e5b44d41437377ccca66ad1e8b21b;hp=ecd9972099af21b4cae3c813f9f65f62cad8ac09;hpb=5db670b68349fd1f00a5efc8c0ccd0ef9d073dca;p=osm%2FRO.git diff --git a/openmanod b/openmanod deleted file mode 100755 index ecd99720..00000000 --- a/openmanod +++ /dev/null @@ -1,379 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -## -# Copyright 2015 Telefonica Investigacion y Desarrollo, S.A.U. -# This file is part of openmano -# All Rights Reserved. -# -# 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. -# -# For those usages not covered by the Apache License, Version 2.0 please -# contact with: nfvlabs@tid.es -## - -""" -openmano server. -Main program that implements a reference NFVO (Network Functions Virtualisation Orchestrator). -It interfaces with an NFV VIM through its API and offers a northbound interface, based on REST (openmano API), -where NFV services are offered including the creation and deletion of VNF templates, VNF instances, -network service templates and network service instances. - -It loads the configuration file and launches the http_server thread that will listen requests using openmano API. -""" - -import time -import sys -import getopt -import yaml -from os import environ, path as os_path -from jsonschema import validate as js_v, exceptions as js_e -import logging -import logging.handlers as log_handlers -import socket - -from yaml import MarkedYAMLError - -from osm_ro import httpserver, nfvo, nfvo_db -from osm_ro.openmano_schemas import config_schema -from osm_ro.db_base import db_base_Exception -from osm_ro.wim.engine import WimEngine -from osm_ro.wim.persistence import WimPersistence -import osm_ro - -__author__ = "Alfonso Tierno, Gerardo Garcia, Pablo Montes" -__date__ = "$26-aug-2014 11:09:29$" -__version__ = "6.0.2.post2" -version_date = "Sep 2019" -database_version = 39 # expected database schema version - -global global_config -global logger - - -class LoadConfigurationException(Exception): - pass - - -def load_configuration(configuration_file): - default_tokens = {'http_port': 9090, - 'http_host': 'localhost', - 'http_console_proxy': True, - 'http_console_host': None, - 'log_level': 'DEBUG', - 'log_socket_port': 9022, - 'auto_push_VNF_to_VIMs': True, - 'db_host': 'localhost', - 'db_ovim_host': 'localhost' - } - try: - # Check config file exists - with open(configuration_file, 'r') as f: - config_str = f.read() - # Parse configuration file - config = yaml.load(config_str) - # Validate configuration file with the config_schema - js_v(config, config_schema) - - # Add default values tokens - for k, v in default_tokens.items(): - if k not in config: - config[k] = v - return config - - except yaml.YAMLError as e: - error_pos = "" - if isinstance(e, MarkedYAMLError): - mark = e.problem_mark - error_pos = " at line:{} column:{}".format(mark.line + 1, mark.column + 1) - raise LoadConfigurationException("Bad YAML format at configuration file '{file}'{pos}: {message}".format( - file=configuration_file, pos=error_pos, message=e)) - except js_e.ValidationError as e: - error_pos = "" - if e.path: - error_pos = " at '" + ":".join(map(str, e.path)) + "'" - raise LoadConfigurationException("Invalid field at configuration file '{file}'{pos} {message}".format( - file=configuration_file, pos=error_pos, message=e)) - except Exception as e: - raise LoadConfigurationException("Cannot load configuration file '{file}' {message}".format( - file=configuration_file, message=e)) - - -def console_port_iterator(): - """ - this iterator deals with the http_console_ports - returning the ports one by one - """ - index = 0 - while index < len(global_config["http_console_ports"]): - port = global_config["http_console_ports"][index] - if type(port) is int: - yield port - else: # this is dictionary with from to keys - port2 = port["from"] - while port2 <= port["to"]: - yield port2 - port2 += 1 - index += 1 - - -def usage(): - print("Usage: ", sys.argv[0], "[options]") - print(" -v|--version: prints current version") - print(" -c|--config [configuration_file]: loads the configuration file (default: openmanod.cfg)") - print(" -h|--help: shows this help") - print( - " -p|--port [port_number]: changes port number and overrides the port number in the configuration file (default: 9090)") - print( - " -P|--adminport [port_number]: changes admin port number and overrides the port number in the configuration file (default: 9095)") - print(" --log-socket-host HOST: send logs to this host") - print(" --log-socket-port PORT: send logs using this port (default: 9022)") - print(" --log-file FILE: send logs to this file") - print( - " --create-tenant NAME: Try to creates this tenant name before starting, ignoring any errors as e.g. conflict") - return - - -def set_logging_file(log_file): - try: - file_handler = logging.handlers.RotatingFileHandler(log_file, maxBytes=100e6, backupCount=9, delay=0) - file_handler.setFormatter(log_formatter_simple) - logger.addHandler(file_handler) - # remove initial stream handler - logging.root.removeHandler(logging.root.handlers[0]) - print ("logging on '{}'".format(log_file)) - except IOError as e: - raise LoadConfigurationException( - "Cannot open logging file '{}': {}. Check folder exist and permissions".format(log_file, e)) - - -if __name__ == "__main__": - # env2config contains environ variable names and the correspondence with configuration file openmanod.cfg keys. - # If this environ is defined, this value is taken instead of the one at at configuration file - env2config = { - 'RO_DB_HOST': 'db_host', - 'RO_DB_NAME': 'db_name', - 'RO_DB_USER': 'db_user', - 'RO_DB_PASSWORD': 'db_passwd', - 'RO_DB_OVIM_HOST': 'db_ovim_host', - 'RO_DB_OVIM_NAME': 'db_ovim_name', - 'RO_DB_OVIM_USER': 'db_ovim_user', - 'RO_DB_OVIM_PASSWORD': 'db_ovim_passwd', - 'RO_LOG_LEVEL': 'log_level', - 'RO_LOG_FILE': 'log_file', - } - # Configure logging step 1 - hostname = socket.gethostname() - log_formatter_str = '%(asctime)s.%(msecs)03d00Z[{host}@openmanod] %(filename)s:%(lineno)s severity:%(levelname)s logger:%(name)s log:%(message)s' - log_formatter_complete = logging.Formatter(log_formatter_str.format(host=hostname), datefmt='%Y-%m-%dT%H:%M:%S') - log_format_simple = "%(asctime)s %(levelname)s %(name)s %(thread)d %(filename)s:%(lineno)s %(message)s" - log_formatter_simple = logging.Formatter(log_format_simple, datefmt='%Y-%m-%dT%H:%M:%S') - logging.basicConfig(format=log_format_simple, level=logging.DEBUG) - logger = logging.getLogger('openmano') - logger.setLevel(logging.DEBUG) - socket_handler = None - # Read parameters and configuration file - httpthread = None - try: - # load parameters and configuration - opts, args = getopt.getopt(sys.argv[1:], "hvc:V:p:P:", - ["config=", "help", "version", "port=", "vnf-repository=", "adminport=", - "log-socket-host=", "log-socket-port=", "log-file=", "create-tenant="]) - port = None - port_admin = None - config_file = 'osm_ro/openmanod.cfg' - vnf_repository = None - log_file = None - log_socket_host = None - log_socket_port = None - create_tenant = None - - for o, a in opts: - if o in ("-v", "--version"): - print ("openmanod version " + __version__ + ' ' + version_date) - print ("(c) Copyright Telefonica") - sys.exit() - elif o in ("-h", "--help"): - usage() - sys.exit() - elif o in ("-V", "--vnf-repository"): - vnf_repository = a - elif o in ("-c", "--config"): - config_file = a - elif o in ("-p", "--port"): - port = a - elif o in ("-P", "--adminport"): - port_admin = a - elif o == "--log-socket-port": - log_socket_port = a - elif o == "--log-socket-host": - log_socket_host = a - elif o == "--log-file": - log_file = a - elif o == "--create-tenant": - create_tenant = a - else: - assert False, "Unhandled option" - if log_file: - set_logging_file(log_file) - global_config = load_configuration(config_file) - global_config["version"] = __version__ - global_config["version_date"] = version_date - # Override parameters obtained by command line on ENV - if port: - global_config['http_port'] = port - if port_admin: - global_config['http_admin_port'] = port_admin - if log_socket_host: - global_config['log_socket_host'] = log_socket_host - if log_socket_port: - global_config['log_socket_port'] = log_socket_port - - # override with ENV - for env_k, env_v in environ.items(): - try: - if not env_k.startswith("RO_") or env_k not in env2config or not env_v: - continue - global_config[env2config[env_k]] = env_v - if env_k.endswith("PORT"): # convert to int, skip if not possible - global_config[env2config[env_k]] = int(env_v) - except Exception as e: - logger.warn("skipping environ '{}={}' because exception '{}'".format(env_k, env_v, e)) - - global_config["console_port_iterator"] = console_port_iterator - global_config["console_thread"] = {} - global_config["console_ports"] = {} - if not global_config["http_console_host"]: - global_config["http_console_host"] = global_config["http_host"] - if global_config["http_host"] == "0.0.0.0": - global_config["http_console_host"] = socket.gethostname() - - # Configure logging STEP 2 - if "log_host" in global_config: - socket_handler = log_handlers.SocketHandler(global_config["log_socket_host"], - global_config["log_socket_port"]) - socket_handler.setFormatter(log_formatter_complete) - if global_config.get("log_socket_level") \ - and global_config["log_socket_level"] != global_config["log_level"]: - socket_handler.setLevel(global_config["log_socket_level"]) - logger.addHandler(socket_handler) - - if log_file: - global_config['log_file'] = log_file - elif global_config.get('log_file'): - set_logging_file(global_config['log_file']) - - logger.setLevel(getattr(logging, global_config['log_level'])) - logger.critical("Starting openmano server version: '%s %s' command: '%s'", - __version__, version_date, " ".join(sys.argv)) - - for log_module in ("nfvo", "http", "vim", "wim", "db", "console", "ovim"): - log_level_module = "log_level_" + log_module - log_file_module = "log_file_" + log_module - logger_module = logging.getLogger('openmano.' + log_module) - if log_level_module in global_config: - logger_module.setLevel(global_config[log_level_module]) - if log_file_module in global_config: - try: - file_handler = logging.handlers.RotatingFileHandler(global_config[log_file_module], - maxBytes=100e6, backupCount=9, delay=0) - file_handler.setFormatter(log_formatter_simple) - logger_module.addHandler(file_handler) - except IOError as e: - raise LoadConfigurationException( - "Cannot open logging file '{}': {}. Check folder exist and permissions".format( - global_config[log_file_module], str(e))) - global_config["logger_" + log_module] = logger_module - - # Initialize DB connection - mydb = nfvo_db.nfvo_db() - mydb.connect(global_config['db_host'], global_config['db_user'], global_config['db_passwd'], - global_config['db_name']) - db_path = osm_ro.__path__[0] + "/database_utils" - if not os_path.exists(db_path + "/migrate_mano_db.sh"): - db_path = osm_ro.__path__[0] + "/../database_utils" - try: - r = mydb.get_db_version() - if r[0] != database_version: - logger.critical("DATABASE wrong version '{current}'. Try to upgrade/downgrade to version '{target}'" - " with '{db_path}/migrate_mano_db.sh {target}'".format(current=r[0], - target=database_version, - db_path=db_path)) - exit(-1) - except db_base_Exception as e: - logger.critical("DATABASE is not valid. If you think it is corrupted, you can init it with" - " '{db_path}/init_mano_db.sh' script".format(db_path=db_path)) - exit(-1) - - nfvo.global_config = global_config - if create_tenant: - try: - nfvo.new_tenant(mydb, {"name": create_tenant}) - except Exception as e: - if isinstance(e, nfvo.NfvoException) and e.http_code == 409: - pass # if tenant exist (NfvoException error 409), ignore - else: # otherwise print and error and continue - logger.error("Cannot create tenant '{}': {}".format(create_tenant, e)) - - # WIM module - wim_persistence = WimPersistence(mydb) - wim_engine = WimEngine(wim_persistence) - # --- - nfvo.start_service(mydb, wim_persistence, wim_engine) - - httpthread = httpserver.httpserver( - mydb, False, - global_config['http_host'], global_config['http_port'], - wim_persistence, wim_engine - ) - - httpthread.start() - if 'http_admin_port' in global_config: - httpthreadadmin = httpserver.httpserver(mydb, True, global_config['http_host'], - global_config['http_admin_port']) - httpthreadadmin.start() - time.sleep(1) - logger.info('Waiting for http clients') - print('Waiting for http clients') - print('openmanod ready') - print('====================') - time.sleep(20) - sys.stdout.flush() - - # TODO: Interactive console must be implemented here instead of join or sleep - - # httpthread.join() - # if 'http_admin_port' in global_config: - # httpthreadadmin.join() - while True: - time.sleep(86400) - - except KeyboardInterrupt as e: - logger.info(str(e)) - except SystemExit: - pass - except getopt.GetoptError as e: - logger.critical(str(e)) # will print something like "option -a not recognized" - exit(-1) - except LoadConfigurationException as e: - logger.critical(str(e)) - exit(-1) - except db_base_Exception as e: - logger.critical(str(e)) - exit(-1) - except nfvo.NfvoException as e: - logger.critical(str(e), exc_info=True) - exit(-1) - nfvo.stop_service() - if httpthread: - httpthread.join(1)