openmano first code upload
Signed-off-by: tierno <alfonso.tiernosepulveda@telefonica.com>
diff --git a/openmanod.py b/openmanod.py
new file mode 100755
index 0000000..522a657
--- /dev/null
+++ b/openmanod.py
@@ -0,0 +1,226 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+##
+# Copyright 2015 Telefónica Investigación 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.
+'''
+__author__="Alfonso Tierno, Gerardo Garcia, Pablo Montes"
+__date__ ="$26-aug-2014 11:09:29$"
+__version__="0.4.36-r467"
+version_date="Mar 2016"
+database_version="0.10" #expected database schema version
+
+import httpserver
+import time
+import os
+import sys
+import getopt
+import yaml
+import nfvo_db
+from jsonschema import validate as js_v, exceptions as js_e
+from utils import auxiliary_functions as af
+from openmano_schemas import config_schema
+import nfvo
+
+global global_config
+
+def load_configuration(configuration_file):
+ default_tokens ={'http_port':9090, 'http_host':'localhost'}
+ try:
+ #Check config file exists
+ if not os.path.isfile(configuration_file):
+ return (False, "Error: Configuration file '"+configuration_file+"' does not exists.")
+
+ #Read file
+ (return_status, code) = af.read_file(configuration_file)
+ if not return_status:
+ return (return_status, "Error loading configuration file '"+configuration_file+"': "+code)
+ #Parse configuration file
+ try:
+ config = yaml.load(code)
+ except yaml.YAMLError, exc:
+ error_pos = ""
+ if hasattr(exc, 'problem_mark'):
+ mark = exc.problem_mark
+ error_pos = " at position: (%s:%s)" % (mark.line+1, mark.column+1)
+ return (False, "Error loading configuration file '"+configuration_file+"'"+error_pos+": content format error: Failed to parse yaml format")
+
+ #Validate configuration file with the config_schema
+ try:
+ js_v(config, config_schema)
+ except js_e.ValidationError, exc:
+ error_pos = ""
+ if len(exc.path)>0: error_pos=" at '" + ":".join(map(str, exc.path))+"'"
+ return False, "Error loading configuration file '"+configuration_file+"'"+error_pos+": "+exc.message
+
+ #Check default values tokens
+ for k,v in default_tokens.items():
+ if k not in config: config[k]=v
+
+ except Exception,e:
+ return (False, "Error loading configuration file '"+configuration_file+"': "+str(e))
+
+ return (True, config)
+
+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]
+ #print "ports -> ", port
+ if type(port) is int:
+ yield port
+ else: #this is dictionary with from to keys
+ port2 = port["from"]
+ #print "ports -> ", port, port2
+ while port2 <= port["to"]:
+ print "ports -> ", port, port2
+ 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 " -V|--vnf-repository: changes the path of the vnf-repository and overrides the path in the configuration file"
+ return
+
+if __name__=="__main__":
+ # Read parameters and configuration file
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], "hvc:V:p:P:", ["config", "help", "version", "port", "vnf-repository", "adminport"])
+ except getopt.GetoptError, err:
+ # print help information and exit:
+ print "Error:", err # will print something like "option -a not recognized"
+ usage()
+ sys.exit(2)
+
+ port=None
+ port_admin = None
+ config_file = 'openmanod.cfg'
+ vnf_repository = 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
+ else:
+ assert False, "Unhandled option"
+
+ try:
+ r, global_config = load_configuration(config_file)
+ #print global_config
+ if not r:
+ print global_config
+ exit(-1)
+ # Override parameters obtained by command line
+ if port is not None: global_config['http_port'] = port
+ if port_admin is not None: global_config['http_admin_port'] = port_admin
+ if vnf_repository is not None:
+ global_config['vnf_repository'] = vnf_repository
+ else:
+ if not 'vnf_repository' in global_config:
+ print os.getcwd()
+ global_config['vnf_repository'] = os.getcwd()+'/vnfrepo'
+ #print global_config
+
+ if not os.path.exists(global_config['vnf_repository']):
+ print "Creating folder vnf_repository folder: '%s'." % global_config['vnf_repository']
+ try:
+ os.makedirs(global_config['vnf_repository'])
+ except Exception,e:
+ print "Error '%s'. Ensure the path 'vnf_repository' is properly set at %s" %(e.args[1], config_file)
+ exit(-1)
+
+ global_config["console_port_iterator"] = console_port_iterator
+ global_config["console_thread"]={}
+ global_config["console_ports"]={}
+ # Initialize DB connection
+ mydb = nfvo_db.nfvo_db();
+ if mydb.connect(global_config['db_host'], global_config['db_user'], global_config['db_passwd'], global_config['db_name']) == -1:
+ print "Error connecting to database", global_config['db_name'], "at", global_config['db_user'], "@", global_config['db_host']
+ exit(-1)
+ r = mydb.get_db_version()
+ if r[0]<0:
+ print "Error DATABASE is not a MANO one or it is a '0.0' version. Try to upgrade to version '%s' with './database_utils/migrate_mano_db.sh'" % database_version
+ exit(-1)
+ elif r[1]!=database_version:
+ print "Error DATABASE wrong version '%s'. Try to upgrade/downgrade to version '%s' with './database_utils/migrate_mano_db.sh'" % (r[1], database_version)
+ exit(-1)
+
+ nfvo.global_config=global_config
+
+ httpthread = httpserver.httpserver(mydb, False, global_config['http_host'], global_config['http_port'])
+
+ 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)
+ 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)
+ for thread in global_config["console_thread"]:
+ thread.terminate = True
+
+ except (KeyboardInterrupt, SystemExit):
+ print 'Exiting openmanod'
+ exit()
+
+