2 # -*- coding: utf-8 -*-
5 # Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
6 # This file is part of openmano
9 # Licensed under the Apache License, Version 2.0 (the "License"); you may
10 # not use this file except in compliance with the License. You may obtain
11 # a copy of the License at
13 # http://www.apache.org/licenses/LICENSE-2.0
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18 # License for the specific language governing permissions and limitations
21 # For those usages not covered by the Apache License, Version 2.0 please
22 # contact with: nfvlabs@tid.es
27 Main program that implements a reference NFVO (Network Functions Virtualisation Orchestrator).
28 It interfaces with an NFV VIM through its API and offers a northbound interface, based on REST (openmano API),
29 where NFV services are offered including the creation and deletion of VNF templates, VNF instances,
30 network service templates and network service instances.
32 It loads the configuration file and launches the http_server thread that will listen requests using openmano API.
34 __author__
="Alfonso Tierno, Gerardo Garcia, Pablo Montes"
35 __date__
="$26-aug-2014 11:09:29$"
36 __version__
="0.4.36-r467"
37 version_date
="Mar 2016"
38 database_version
="0.10" #expected database schema version
47 from jsonschema
import validate
as js_v
, exceptions
as js_e
49 from openmano_schemas
import config_schema
54 def load_configuration(configuration_file
):
55 default_tokens
={'http_port':9090, 'http_host':'localhost'}
57 #Check config file exists
58 if not os
.path
.isfile(configuration_file
):
59 return (False, "Error: Configuration file '"+configuration_file
+"' does not exists.")
62 (return_status
, code
) = utils
.read_file(configuration_file
)
64 return (return_status
, "Error loading configuration file '"+configuration_file
+"': "+code
)
65 #Parse configuration file
67 config
= yaml
.load(code
)
68 except yaml
.YAMLError
, exc
:
70 if hasattr(exc
, 'problem_mark'):
71 mark
= exc
.problem_mark
72 error_pos
= " at position: (%s:%s)" % (mark
.line
+1, mark
.column
+1)
73 return (False, "Error loading configuration file '"+configuration_file
+"'"+error_pos
+": content format error: Failed to parse yaml format")
75 #Validate configuration file with the config_schema
77 js_v(config
, config_schema
)
78 except js_e
.ValidationError
, exc
:
80 if len(exc
.path
)>0: error_pos
=" at '" + ":".join(map(str, exc
.path
))+"'"
81 return False, "Error loading configuration file '"+configuration_file
+"'"+error_pos
+": "+exc
.message
83 #Check default values tokens
84 for k
,v
in default_tokens
.items():
85 if k
not in config
: config
[k
]=v
88 return (False, "Error loading configuration file '"+configuration_file
+"': "+str(e
))
92 def console_port_iterator():
93 '''this iterator deals with the http_console_ports
94 returning the ports one by one
97 while index
< len(global_config
["http_console_ports"]):
98 port
= global_config
["http_console_ports"][index
]
99 #print "ports -> ", port
100 if type(port
) is int:
102 else: #this is dictionary with from to keys
104 #print "ports -> ", port, port2
105 while port2
<= port
["to"]:
106 print "ports -> ", port
, port2
113 print "Usage: ", sys
.argv
[0], "[options]"
114 print " -v|--version: prints current version"
115 print " -c|--config [configuration_file]: loads the configuration file (default: openmanod.cfg)"
116 print " -h|--help: shows this help"
117 print " -p|--port [port_number]: changes port number and overrides the port number in the configuration file (default: 9090)"
118 print " -P|--adminport [port_number]: changes admin port number and overrides the port number in the configuration file (default: 9095)"
119 print " -V|--vnf-repository: changes the path of the vnf-repository and overrides the path in the configuration file"
122 if __name__
=="__main__":
123 # Read parameters and configuration file
125 opts
, args
= getopt
.getopt(sys
.argv
[1:], "hvc:V:p:P:", ["config", "help", "version", "port", "vnf-repository", "adminport"])
126 except getopt
.GetoptError
, err
:
127 # print help information and exit:
128 print "Error:", err
# will print something like "option -a not recognized"
134 config_file
= 'openmanod.cfg'
135 vnf_repository
= None
138 if o
in ("-v", "--version"):
139 print "openmanod version", __version__
, version_date
140 print "(c) Copyright Telefonica"
142 elif o
in ("-h", "--help"):
145 elif o
in ("-V", "--vnf-repository"):
147 elif o
in ("-c", "--config"):
149 elif o
in ("-p", "--port"):
151 elif o
in ("-P", "--adminport"):
154 assert False, "Unhandled option"
157 r
, global_config
= load_configuration(config_file
)
162 # Override parameters obtained by command line
163 if port
is not None: global_config
['http_port'] = port
164 if port_admin
is not None: global_config
['http_admin_port'] = port_admin
165 if vnf_repository
is not None:
166 global_config
['vnf_repository'] = vnf_repository
168 if not 'vnf_repository' in global_config
:
170 global_config
['vnf_repository'] = os
.getcwd()+'/vnfrepo'
173 if not os
.path
.exists(global_config
['vnf_repository']):
174 print "Creating folder vnf_repository folder: '%s'." % global_config
['vnf_repository']
176 os
.makedirs(global_config
['vnf_repository'])
178 print "Error '%s'. Ensure the path 'vnf_repository' is properly set at %s" %(e
.args
[1], config_file
)
181 global_config
["console_port_iterator"] = console_port_iterator
182 global_config
["console_thread"]={}
183 global_config
["console_ports"]={}
184 # Initialize DB connection
185 mydb
= nfvo_db
.nfvo_db();
186 if mydb
.connect(global_config
['db_host'], global_config
['db_user'], global_config
['db_passwd'], global_config
['db_name']) == -1:
187 print "Error connecting to database", global_config
['db_name'], "at", global_config
['db_user'], "@", global_config
['db_host']
189 r
= mydb
.get_db_version()
191 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
193 elif r
[1]!=database_version
:
194 print "Error DATABASE wrong version '%s'. Try to upgrade/downgrade to version '%s' with './database_utils/migrate_mano_db.sh'" % (r
[1], database_version
)
197 nfvo
.global_config
=global_config
199 httpthread
= httpserver
.httpserver(mydb
, False, global_config
['http_host'], global_config
['http_port'])
202 if 'http_admin_port' in global_config
:
203 httpthreadadmin
= httpserver
.httpserver(mydb
, True, global_config
['http_host'], global_config
['http_admin_port'])
204 httpthreadadmin
.start()
206 print 'Waiting for http clients'
207 print 'openmanod ready'
208 print '===================='
212 #TODO: Interactive console must be implemented here instead of join or sleep
215 #if 'http_admin_port' in global_config:
216 # httpthreadadmin.join()
219 for thread
in global_config
["console_thread"]:
220 thread
.terminate
= True
222 except (KeyboardInterrupt, SystemExit):
223 print 'Exiting openmanod'