2 # -*- coding: utf-8 -*-
5 # Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
6 # This file is part of openvim
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
26 This is the thread for the http server North API.
27 Two thread will be launched, with normal and administrative permissions.
36 from netaddr
import IPNetwork
37 from jsonschema
import validate
as js_v
, exceptions
as js_e
38 import host_thread
as ht
39 import dhcp_thread
as dt
40 import openflow_thread
as oft
43 __author__
= "Alfonso Tierno, Leonardo Mirabal"
44 __date__
= "$06-Feb-2017 12:07:15$"
45 __version__
= "0.5.12-r528"
46 version_date
= "May 2017"
47 database_version
= 17 #needed database schema version
49 HTTP_Bad_Request
= 400
50 HTTP_Unauthorized
= 401
53 HTTP_Method_Not_Allowed
= 405
54 HTTP_Not_Acceptable
= 406
55 HTTP_Request_Timeout
= 408
57 HTTP_Service_Unavailable
= 503
58 HTTP_Internal_Server_Error
= 500
61 def convert_boolean(data
, items
):
62 '''Check recursively the content of data, and if there is an key contained in items, convert value from string to boolean
63 It assumes that bandwidth is well formed
65 'data': dictionary bottle.FormsDict variable to be checked. None or empty is consideted valid
66 'items': tuple of keys to convert
70 if type(data
) is dict:
72 if type(data
[k
]) is dict or type(data
[k
]) is tuple or type(data
[k
]) is list:
73 convert_boolean(data
[k
], items
)
75 if type(data
[k
]) is str:
76 if data
[k
] == "false":
78 elif data
[k
] == "true":
80 if type(data
) is tuple or type(data
) is list:
82 if type(k
) is dict or type(k
) is tuple or type(k
) is list:
83 convert_boolean(k
, items
)
87 class ovimException(Exception):
88 def __init__(self
, message
, http_code
=HTTP_Bad_Request
):
89 self
.http_code
= http_code
90 Exception.__init
__(self
, message
)
94 running_info
= {} #TODO OVIM move the info of running threads from config_dic to this static variable
97 def __init__(self
, configuration
):
98 self
.config
= configuration
99 self
.logger_name
= configuration
.get("logger_name", "openvim")
100 self
.logger
= logging
.getLogger(self
.logger_name
)
102 self
.db
= self
._create
_database
_connection
()
105 self
.of_test_mode
= False
107 def _create_database_connection(self
):
108 db
= vim_db
.vim_db((self
.config
["network_vlan_range_start"], self
.config
["network_vlan_range_end"]),
109 self
.logger_name
+ ".db", self
.config
.get('log_level_db'))
110 if db
.connect(self
.config
['db_host'], self
.config
['db_user'], self
.config
['db_passwd'],
111 self
.config
['db_name']) == -1:
112 # self.logger.error("Cannot connect to database %s at %s@%s", self.config['db_name'], self.config['db_user'],
113 # self.config['db_host'])
114 raise ovimException("Cannot connect to database {} at {}@{}".format(self
.config
['db_name'],
115 self
.config
['db_user'],
116 self
.config
['db_host']) )
124 def get_version_date():
128 def get_database_version():
129 return database_version
132 def _check_dhcp_data_integrity(network
):
134 Check if all dhcp parameter for anet are valid, if not will be calculated from cidr value
135 :param network: list with user nets paramters
138 if "cidr" in network
:
139 cidr
= network
["cidr"]
140 ip_tools
= IPNetwork(cidr
)
141 cidr_len
= ip_tools
.prefixlen
145 ips
= IPNetwork(cidr
)
146 if "dhcp_first_ip" not in network
:
147 network
["dhcp_first_ip"] = str(ips
[2])
148 if "dhcp_last_ip" not in network
:
149 network
["dhcp_last_ip"] = str(ips
[-2])
150 if "gateway_ip" not in network
:
151 network
["gateway_ip"] = str(ips
[1])
158 def _check_valid_uuid(uuid
):
159 id_schema
= {"type": "string", "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"}
161 js_v(uuid
, id_schema
)
163 except js_e
.ValidationError
:
166 def start_service(self
):
171 global database_version
172 # if self.running_info:
173 # return #TODO service can be checked and rebuild broken threads
174 r
= self
.db
.get_db_version()
176 db_path
= db_path
[:db_path
.rfind("/")]
177 if os
.path
.exists(db_path
+ "/database_utils/migrate_vim_db.sh"):
178 db_path
+= "/database_utils"
180 db_path
+= "/../database_utils"
183 raise ovimException("DATABASE is not valid. If you think it is corrupted, you can init it with"
184 " '{db_path}/init_vim_db.sh' script".format(db_path
=db_path
))
185 elif r
[0] != database_version
:
186 raise ovimException("DATABASE wrong version '{current}'. Try to upgrade/downgrade to version '{target}'"
187 " with '{db_path}/migrate_vim_db.sh {target}'".format(
188 current
=r
[0], target
=database_version
, db_path
=db_path
))
189 self
.logger
.critical("Starting ovim server version: '{} {}' database version '{}'".format(
190 self
.get_version(), self
.get_version_date(), self
.get_database_version()))
191 # create database connection for openflow threads
192 self
.db_of
= self
._create
_database
_connection
()
193 self
.config
["db"] = self
.db_of
194 self
.db_lock
= threading
.Lock()
195 self
.config
["db_lock"] = self
.db_lock
197 self
.of_test_mode
= False if self
.config
['mode'] == 'normal' or self
.config
['mode'] == "OF only" else True
198 # precreate interfaces; [bridge:<host_bridge_name>, VLAN used at Host, uuid of network camping in this bridge,
201 self
.config
['dhcp_nets'] = []
202 self
.config
['bridge_nets'] = []
203 for bridge
, vlan_speed
in self
.config
["bridge_ifaces"].items():
204 # skip 'development_bridge'
205 if self
.config
['mode'] == 'development' and self
.config
['development_bridge'] == bridge
:
207 self
.config
['bridge_nets'].append([bridge
, vlan_speed
[0], vlan_speed
[1], None])
209 # check if this bridge is already used (present at database) for a network)
210 used_bridge_nets
= []
211 for brnet
in self
.config
['bridge_nets']:
212 r
, nets
= self
.db
.get_table(SELECT
=('uuid',), FROM
='nets', WHERE
={'provider': "bridge:" + brnet
[0]})
214 brnet
[3] = nets
[0]['uuid']
215 used_bridge_nets
.append(brnet
[0])
216 if self
.config
.get("dhcp_server"):
217 if brnet
[0] in self
.config
["dhcp_server"]["bridge_ifaces"]:
218 self
.config
['dhcp_nets'].append(nets
[0]['uuid'])
219 if len(used_bridge_nets
) > 0:
220 self
.logger
.info("found used bridge nets: " + ",".join(used_bridge_nets
))
221 # get nets used by dhcp
222 if self
.config
.get("dhcp_server"):
223 for net
in self
.config
["dhcp_server"].get("nets", ()):
224 r
, nets
= self
.db
.get_table(SELECT
=('uuid',), FROM
='nets', WHERE
={'name': net
})
226 self
.config
['dhcp_nets'].append(nets
[0]['uuid'])
229 self
._start
_ofc
_default
_task
()
231 # OFC per tenant in DB
232 self
._start
_of
_db
_tasks
()
234 # create dhcp_server thread
235 host_test_mode
= True if self
.config
['mode'] == 'test' or self
.config
['mode'] == "OF only" else False
236 dhcp_params
= self
.config
.get("dhcp_server")
238 thread
= dt
.dhcp_thread(dhcp_params
=dhcp_params
, test
=host_test_mode
, dhcp_nets
=self
.config
["dhcp_nets"],
239 db
=self
.db_of
, db_lock
=self
.db_lock
, logger_name
=self
.logger_name
+ ".dhcp",
240 debug
=self
.config
.get('log_level_of'))
242 self
.config
['dhcp_thread'] = thread
244 # Create one thread for each host
245 host_test_mode
= True if self
.config
['mode'] == 'test' or self
.config
['mode'] == "OF only" else False
246 host_develop_mode
= True if self
.config
['mode'] == 'development' else False
247 host_develop_bridge_iface
= self
.config
.get('development_bridge', None)
249 # get host list from data base before starting threads
250 r
, hosts
= self
.db
.get_table(SELECT
=('name', 'ip_name', 'user', 'uuid'), FROM
='hosts', WHERE
={'status': 'ok'})
252 raise ovimException("Cannot get hosts from database {}".format(hosts
))
254 self
.config
['host_threads'] = {}
256 host
['image_path'] = '/opt/VNF/images/openvim'
257 thread
= ht
.host_thread(name
=host
['name'], user
=host
['user'], host
=host
['ip_name'], db
=self
.db_of
,
258 db_lock
=self
.db_lock
, test
=host_test_mode
, image_path
=self
.config
['image_path'],
259 version
=self
.config
['version'], host_id
=host
['uuid'], develop_mode
=host_develop_mode
,
260 develop_bridge_iface
=host_develop_bridge_iface
,
261 logger_name
=self
.logger_name
+ ".host." + host
['name'],
262 debug
=self
.config
.get('log_level_host'))
264 self
.config
['host_threads'][host
['uuid']] = thread
266 # create ovs dhcp thread
267 result
, content
= self
.db
.get_table(FROM
='nets')
269 self
.logger
.error("http_get_ports Error %d %s", result
, content
)
270 raise ovimException(str(content
), -result
)
273 net_type
= net
['type']
274 if (net_type
== 'bridge_data' or net_type
== 'bridge_man') \
275 and net
["provider"][:4] == 'OVS:' and net
["enable_dhcp"] == "true":
276 self
.launch_dhcp_server(net
['vlan'],
277 net
['dhcp_first_ip'],
282 def _start_of_db_tasks(self
):
284 Start ofc task for existing ofcs in database
289 ofcs
= self
.get_of_controllers()
292 of_conn
= self
._load
_of
_module
(ofc
)
293 # create ofc thread per of controller
294 self
._create
_ofc
_task
(ofc
['uuid'], ofc
['dpid'], of_conn
)
296 def _create_ofc_task(self
, ofc_uuid
, dpid
, of_conn
):
298 Create an ofc thread for handle each sdn controllers
299 :param ofc_uuid: sdn controller uuid
300 :param dpid: sdn controller dpid
301 :param of_conn: OF_conn module
304 if 'ofcs_thread' not in self
.config
and 'ofcs_thread_dpid' not in self
.config
:
306 ofcs_thread_dpid
= []
308 ofcs_threads
= self
.config
['ofcs_thread']
309 ofcs_thread_dpid
= self
.config
['ofcs_thread_dpid']
311 if ofc_uuid
not in ofcs_threads
:
312 ofc_thread
= self
._create
_ofc
_thread
(of_conn
, ofc_uuid
)
313 if ofc_uuid
== "Default":
314 self
.config
['of_thread'] = ofc_thread
316 ofcs_threads
[ofc_uuid
] = ofc_thread
317 self
.config
['ofcs_thread'] = ofcs_threads
319 ofcs_thread_dpid
.append({dpid
: ofc_thread
})
320 self
.config
['ofcs_thread_dpid'] = ofcs_thread_dpid
322 def _start_ofc_default_task(self
):
324 Create default ofc thread
326 if 'of_controller' not in self
.config \
327 and 'of_controller_ip' not in self
.config \
328 and 'of_controller_port' not in self
.config \
329 and 'of_controller_dpid' not in self
.config
:
334 db_config
['ip'] = self
.config
.get('of_controller_ip')
335 db_config
['port'] = self
.config
.get('of_controller_port')
336 db_config
['dpid'] = self
.config
.get('of_controller_dpid')
337 db_config
['type'] = self
.config
.get('of_controller')
338 db_config
['user'] = self
.config
.get('of_user')
339 db_config
['password'] = self
.config
.get('of_password')
341 # create connector to the openflow controller
342 # load other parameters starting by of_ from config dict in a temporal dict
344 of_conn
= self
._load
_of
_module
(db_config
)
345 # create openflow thread
346 self
._create
_ofc
_task
("Default", db_config
['dpid'], of_conn
)
348 def _load_of_module(self
, db_config
):
350 import python module for each SDN controller supported
351 :param db_config: SDN dn information
355 raise ovimException("No module found it", HTTP_Internal_Server_Error
)
360 if self
.of_test_mode
:
361 return openflow_conn
.OfTestConnector({"name": db_config
['type'],
362 "dpid": db_config
['dpid'],
363 "of_debug": self
.config
['log_level_of']})
367 temp_dict
['of_ip'] = db_config
['ip']
368 temp_dict
['of_port'] = db_config
['port']
369 temp_dict
['of_dpid'] = db_config
['dpid']
370 temp_dict
['of_controller'] = db_config
['type']
371 temp_dict
['of_user'] = db_config
.get('user')
372 temp_dict
['of_password'] = db_config
.get('password')
374 temp_dict
['of_debug'] = self
.config
['log_level_of']
376 if temp_dict
['of_controller'] == 'opendaylight':
379 module
= temp_dict
['of_controller']
381 if module
not in ovim
.of_module
:
382 for base
in ("", "osm_openvim.", "lib_osm_openvim."):
384 pkg
= __import__(base
+ module
)
386 of_conn_module
= getattr(pkg
, module
)
389 ovim
.of_module
[module
] = of_conn_module
390 self
.logger
.debug("Module load from {}".format(base
+ module
))
392 except Exception as e
:
393 self
.logger
.warning("Module {} not found {}".format(base
+ module
, e
))
395 self
.logger
.error("Cannot open openflow controller module of type '%s'", module
)
396 raise ovimException("Cannot open openflow controller of type module '{}'"
397 "Revise it is installed".format(module
),
398 HTTP_Internal_Server_Error
)
400 of_conn_module
= ovim
.of_module
[module
]
401 return of_conn_module
.OF_conn(temp_dict
)
402 except Exception as e
:
403 self
.logger
.error("Cannot open the Openflow controller '%s': %s", type(e
).__name
__, str(e
))
404 raise ovimException("Cannot open the Openflow controller '{}': '{}'".format(type(e
).__name
__, str(e
)),
405 HTTP_Internal_Server_Error
)
407 def _create_ofc_thread(self
, of_conn
, ofc_uuid
="Default"):
409 Create and launch a of thread
412 # create openflow thread
414 #if 'of_controller_nets_with_same_vlan' in self.config:
415 # ofc_net_same_vlan = self.config['of_controller_nets_with_same_vlan']
417 # ofc_net_same_vlan = False
418 ofc_net_same_vlan
= False
420 thread
= oft
.openflow_thread(ofc_uuid
, of_conn
, of_test
=self
.of_test_mode
, db
=self
.db_of
, db_lock
=self
.db_lock
,
421 pmp_with_same_vlan
=ofc_net_same_vlan
, debug
=self
.config
['log_level_of'])
422 #r, c = thread.OF_connector.obtain_port_correspondence()
424 # raise ovimException("Cannot get openflow information %s", c)
428 def stop_service(self
):
429 threads
= self
.config
.get('host_threads', {})
430 if 'of_thread' in self
.config
:
431 threads
['of'] = (self
.config
['of_thread'])
432 if 'ofcs_thread' in self
.config
:
433 ofcs_thread
= self
.config
['ofcs_thread']
434 for ofc
in ofcs_thread
:
435 threads
[ofc
] = ofcs_thread
[ofc
]
437 if 'dhcp_thread' in self
.config
:
438 threads
['dhcp'] = (self
.config
['dhcp_thread'])
440 for thread
in threads
.values():
441 thread
.insert_task("exit")
442 for thread
in threads
.values():
445 def get_networks(self
, columns
=None, db_filter
={}, limit
=None):
447 Retreive networks available
448 :param columns: List with select query parameters
449 :param db_filter: List with where query parameters
450 :param limit: Query limit result
453 result
, content
= self
.db
.get_table(SELECT
=columns
, FROM
='nets', WHERE
=db_filter
, LIMIT
=limit
)
456 raise ovimException(str(content
), -result
)
458 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
462 def show_network(self
, network_id
, db_filter
={}):
464 Get network from DB by id
465 :param network_id: net Id
466 :param db_filter: List with where query parameters
471 raise ovimException("Not network id was not found")
472 db_filter
['uuid'] = network_id
474 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
=db_filter
, LIMIT
=100)
477 raise ovimException(str(content
), -result
)
479 raise ovimException("show_network network '%s' not found" % network_id
, -result
)
481 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
483 result
, ports
= self
.db
.get_table(FROM
='ports', SELECT
=('uuid as port_id',),
484 WHERE
={'net_id': network_id
}, LIMIT
=100)
486 content
[0]['ports'] = ports
488 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
491 def new_network(self
, network
):
496 tenant_id
= network
.get('tenant_id')
499 result
, _
= self
.db
.get_table(FROM
='tenants', SELECT
=('uuid',), WHERE
={'uuid': tenant_id
, "enabled": True})
501 raise ovimException("set_network error, no tenant founded", -result
)
505 net_provider
= network
.get('provider')
506 net_type
= network
.get('type')
507 net_vlan
= network
.get("vlan")
508 net_bind_net
= network
.get("bind_net")
509 net_bind_type
= network
.get("bind_type")
510 name
= network
["name"]
512 # check if network name ends with :<vlan_tag> and network exist in order to make and automated bindning
513 vlan_index
= name
.rfind(":")
514 if not net_bind_net
and not net_bind_type
and vlan_index
> 1:
516 vlan_tag
= int(name
[vlan_index
+ 1:])
517 if not vlan_tag
and vlan_tag
< 4096:
518 net_bind_net
= name
[:vlan_index
]
519 net_bind_type
= "vlan:" + name
[vlan_index
+ 1:]
524 # look for a valid net
525 if self
._check
_valid
_uuid
(net_bind_net
):
526 net_bind_key
= "uuid"
528 net_bind_key
= "name"
529 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
={net_bind_key
: net_bind_net
})
531 raise ovimException(' getting nets from db ' + content
, HTTP_Internal_Server_Error
)
533 raise ovimException(" bind_net %s '%s'not found" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
535 raise ovimException(" more than one bind_net %s '%s' found, use uuid" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
536 network
["bind_net"] = content
[0]["uuid"]
539 if net_bind_type
[0:5] != "vlan:":
540 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>'", HTTP_Bad_Request
)
541 if int(net_bind_type
[5:]) > 4095 or int(net_bind_type
[5:]) <= 0:
542 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>' with a tag between 1 and 4095",
544 network
["bind_type"] = net_bind_type
547 if net_provider
[:9] == "openflow:":
549 if net_type
!= "ptp" and net_type
!= "data":
550 raise ovimException(" only 'ptp' or 'data' net types can be bound to 'openflow'",
556 if net_type
!= "bridge_man" and net_type
!= "bridge_data":
557 raise ovimException("Only 'bridge_man' or 'bridge_data' net types can be bound "
558 "to 'bridge', 'macvtap' or 'default", HTTP_Bad_Request
)
560 net_type
= 'bridge_man'
563 net_type
= 'bridge_man'
566 if net_provider
[:7] == 'bridge:':
567 # check it is one of the pre-provisioned bridges
568 bridge_net_name
= net_provider
[7:]
569 for brnet
in self
.config
['bridge_nets']:
570 if brnet
[0] == bridge_net_name
: # free
572 raise ovimException("invalid 'provider:physical', "
573 "bridge '%s' is already used" % bridge_net_name
, HTTP_Conflict
)
577 # if bridge_net==None:
578 # bottle.abort(HTTP_Bad_Request, "invalid 'provider:physical', bridge '%s' is not one of the
579 # provisioned 'bridge_ifaces' in the configuration file" % bridge_net_name)
582 elif self
.config
['network_type'] == 'bridge' and (net_type
== 'bridge_data' or net_type
== 'bridge_man'):
583 # look for a free precreated nets
584 for brnet
in self
.config
['bridge_nets']:
585 if not brnet
[3]: # free
587 if net_type
== 'bridge_man': # look for the smaller speed
588 if brnet
[2] < bridge_net
[2]:
590 else: # look for the larger speed
591 if brnet
[2] > bridge_net
[2]:
597 raise ovimException("Max limits of bridge networks reached. Future versions of VIM "
598 "will overcome this limit", HTTP_Bad_Request
)
600 self
.logger
.debug("using net " + bridge_net
)
601 net_provider
= "bridge:" + bridge_net
[0]
602 net_vlan
= bridge_net
[1]
603 elif net_type
== 'bridge_data' or net_type
== 'bridge_man' and self
.config
['network_type'] == 'ovs':
605 if not net_vlan
and (net_type
== "data" or net_type
== "ptp" or net_provider
== "OVS"):
606 net_vlan
= self
.db
.get_free_net_vlan()
608 raise ovimException("Error getting an available vlan", HTTP_Internal_Server_Error
)
609 if net_provider
== 'OVS':
610 net_provider
= 'OVS' + ":" + str(net_vlan
)
612 network
['provider'] = net_provider
613 network
['type'] = net_type
614 network
['vlan'] = net_vlan
615 dhcp_integrity
= True
616 if 'enable_dhcp' in network
and network
['enable_dhcp']:
617 dhcp_integrity
= self
._check
_dhcp
_data
_integrity
(network
)
619 result
, content
= self
.db
.new_row('nets', network
, True, True)
621 if result
>= 0 and dhcp_integrity
:
623 bridge_net
[3] = content
624 if self
.config
.get("dhcp_server") and self
.config
['network_type'] == 'bridge':
625 if network
["name"] in self
.config
["dhcp_server"].get("nets", ()):
626 self
.config
["dhcp_nets"].append(content
)
627 self
.logger
.debug("dhcp_server: add new net", content
)
628 elif not bridge_net
and bridge_net
[0] in self
.config
["dhcp_server"].get("bridge_ifaces", ()):
629 self
.config
["dhcp_nets"].append(content
)
630 self
.logger
.debug("dhcp_server: add new net", content
, content
)
633 raise ovimException("Error posting network", HTTP_Internal_Server_Error
)
634 # TODO kei change update->edit
636 def edit_network(self
, network_id
, network
):
638 Update entwork data byt id
641 # Look for the previous data
642 where_
= {'uuid': network_id
}
643 result
, network_old
= self
.db
.get_table(FROM
='nets', WHERE
=where_
)
645 raise ovimException("Error updating network %s" % network_old
, HTTP_Internal_Server_Error
)
647 raise ovimException('network %s not found' % network_id
, HTTP_Not_Found
)
649 nbports
, content
= self
.db
.get_table(FROM
='ports', SELECT
=('uuid as port_id',),
650 WHERE
={'net_id': network_id
}, LIMIT
=100)
652 raise ovimException("http_put_network_id error %d %s" % (result
, network_old
), HTTP_Internal_Server_Error
)
654 if 'type' in network
and network
['type'] != network_old
[0]['type']:
655 raise ovimException("Can not change type of network while having ports attached",
656 HTTP_Method_Not_Allowed
)
657 if 'vlan' in network
and network
['vlan'] != network_old
[0]['vlan']:
658 raise ovimException("Can not change vlan of network while having ports attached",
659 HTTP_Method_Not_Allowed
)
662 net_provider
= network
.get('provider', network_old
[0]['provider'])
663 net_type
= network
.get('type', network_old
[0]['type'])
664 net_bind_net
= network
.get("bind_net")
665 net_bind_type
= network
.get("bind_type")
667 # look for a valid net
668 if self
._check
_valid
_uuid
(net_bind_net
):
669 net_bind_key
= "uuid"
671 net_bind_key
= "name"
672 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
={net_bind_key
: net_bind_net
})
674 raise ovimException('Getting nets from db ' + content
, HTTP_Internal_Server_Error
)
676 raise ovimException("bind_net %s '%s'not found" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
678 raise ovimException("More than one bind_net %s '%s' found, use uuid" % (net_bind_key
, net_bind_net
),
680 network
["bind_net"] = content
[0]["uuid"]
682 if net_bind_type
[0:5] != "vlan:":
683 raise ovimException("Bad format for 'bind_type', must be 'vlan:<tag>'", HTTP_Bad_Request
)
684 if int(net_bind_type
[5:]) > 4095 or int(net_bind_type
[5:]) <= 0:
685 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>' with a tag between 1 and 4095",
688 if net_provider
[:9] == "openflow:":
689 if net_type
!= "ptp" and net_type
!= "data":
690 raise ovimException("Only 'ptp' or 'data' net types can be bound to 'openflow'", HTTP_Bad_Request
)
692 if net_type
!= "bridge_man" and net_type
!= "bridge_data":
693 raise ovimException("Only 'bridge_man' or 'bridge_data' net types can be bound to "
694 "'bridge', 'macvtap' or 'default", HTTP_Bad_Request
)
696 # insert in data base
697 result
, content
= self
.db
.update_rows('nets', network
, WHERE
={'uuid': network_id
}, log
=True)
699 # if result > 0 and nbports>0 and 'admin_state_up' in network
700 # and network['admin_state_up'] != network_old[0]['admin_state_up']:
705 self
.net_update_ofc_thread(network_id
)
706 except ovimException
as e
:
707 raise ovimException("Error while launching openflow rules in network '{}' {}"
708 .format(network_id
, str(e
)), HTTP_Internal_Server_Error
)
709 except Exception as e
:
710 raise ovimException("Error while launching openflow rules in network '{}' {}"
711 .format(network_id
, str(e
)), HTTP_Internal_Server_Error
)
713 if self
.config
.get("dhcp_server"):
714 if network_id
in self
.config
["dhcp_nets"]:
715 self
.config
["dhcp_nets"].remove(network_id
)
716 if network
.get("name", network_old
[0]["name"]) in self
.config
["dhcp_server"].get("nets", ()):
717 self
.config
["dhcp_nets"].append(network_id
)
719 net_bind
= network
.get("bind_type", network_old
[0]["bind_type"])
720 if net_bind
and net_bind
and net_bind
[:7] == "bridge:" and net_bind
[7:] in self
.config
["dhcp_server"].get(
721 "bridge_ifaces", ()):
722 self
.config
["dhcp_nets"].append(network_id
)
725 raise ovimException(content
, -result
)
727 def delete_network(self
, network_id
):
729 Delete network by network id
730 :param network_id: network id
734 # delete from the data base
735 result
, content
= self
.db
.delete_row('nets', network_id
)
738 raise ovimException("Network %s not found " % network_id
, HTTP_Not_Found
)
740 for brnet
in self
.config
['bridge_nets']:
741 if brnet
[3] == network_id
:
744 if self
.config
.get("dhcp_server") and network_id
in self
.config
["dhcp_nets"]:
745 self
.config
["dhcp_nets"].remove(network_id
)
748 raise ovimException("Error deleting network %s" % network_id
, HTTP_Internal_Server_Error
)
750 def get_openflow_rules(self
, network_id
=None):
752 Get openflow id from DB
753 :param network_id: Network id, if none all networks will be retrieved
754 :return: Return a list with Openflow rules per net
760 where_
= {"net_id": network_id
}
761 result
, content
= self
.db
.get_table(
762 SELECT
=("name", "net_id", "ofc_id", "priority", "vlan_id", "ingress_port", "src_mac", "dst_mac", "actions"),
763 WHERE
=where_
, FROM
='of_flows')
766 raise ovimException(str(content
), -result
)
769 def edit_openflow_rules(self
, network_id
=None):
772 To make actions over the net. The action is to reinstall the openflow rules
773 network_id can be 'all'
774 :param network_id: Network id, if none all networks will be retrieved
775 :return : Number of nets updated
782 where_
= {"uuid": network_id
}
783 result
, content
= self
.db
.get_table(SELECT
=("uuid", "type"), WHERE
=where_
, FROM
='nets')
786 raise ovimException(str(content
), -result
)
789 if net
["type"] != "ptp" and net
["type"] != "data":
794 self
.net_update_ofc_thread(net
['uuid'])
795 except ovimException
as e
:
796 raise ovimException("Error updating network'{}' {}".format(net
['uuid'], str(e
)),
797 HTTP_Internal_Server_Error
)
798 except Exception as e
:
799 raise ovimException("Error updating network '{}' {}".format(net
['uuid'], str(e
)),
800 HTTP_Internal_Server_Error
)
804 def delete_openflow_rules(self
, ofc_id
=None):
806 To make actions over the net. The action is to delete ALL openflow rules
807 :return: return operation result
811 if 'Default' in self
.config
['ofcs_thread']:
812 r
, c
= self
.config
['ofcs_thread']['Default'].insert_task("clear-all")
814 raise ovimException("Default Openflow controller not not running", HTTP_Not_Found
)
816 elif ofc_id
in self
.config
['ofcs_thread']:
817 r
, c
= self
.config
['ofcs_thread'][ofc_id
].insert_task("clear-all")
821 raise ovimException(str(c
), -r
)
823 raise ovimException("Openflow controller not found with ofc_id={}".format(ofc_id
), HTTP_Not_Found
)
826 def get_openflow_ports(self
, ofc_id
=None):
828 Obtain switch ports names of openflow controller
829 :return: Return flow ports in DB
832 if 'Default' in self
.config
['ofcs_thread']:
833 conn
= self
.config
['ofcs_thread']['Default'].OF_connector
835 raise ovimException("Default Openflow controller not not running", HTTP_Not_Found
)
837 if ofc_id
in self
.config
['ofcs_thread']:
838 conn
= self
.config
['ofcs_thread'][ofc_id
].OF_connector
840 raise ovimException("Openflow controller not found with ofc_id={}".format(ofc_id
), HTTP_Not_Found
)
843 def get_ports(self
, columns
=None, filter={}, limit
=None):
844 # result, content = my.db.get_ports(where_)
845 result
, content
= self
.db
.get_table(SELECT
=columns
, WHERE
=filter, FROM
='ports', LIMIT
=limit
)
847 self
.logger
.error("http_get_ports Error %d %s", result
, content
)
848 raise ovimException(str(content
), -result
)
850 convert_boolean(content
, ('admin_state_up',))
853 def new_port(self
, port_data
):
854 port_data
['type'] = 'external'
855 if port_data
.get('net_id'):
856 # check that new net has the correct type
857 result
, new_net
= self
.db
.check_target_net(port_data
['net_id'], None, 'external')
859 raise ovimException(str(new_net
), -result
)
860 # insert in data base
861 result
, uuid
= self
.db
.new_row('ports', port_data
, True, True)
863 if 'net_id' in port_data
:
865 self
.net_update_ofc_thread(port_data
['net_id'])
866 except ovimException
as e
:
867 raise ovimException("Cannot insert a task for updating network '{}' {}"
868 .format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
869 except Exception as e
:
870 raise ovimException("Cannot insert a task for updating network '{}' {}"
871 .format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
875 raise ovimException(str(uuid
), -result
)
877 def new_external_port(self
, port_data
):
879 Create new external port and check port mapping correspondence
880 :param port_data: port_data = {
881 'region': 'datacenter region',
882 'compute_node': 'compute node id',
883 'pci': 'pci port address',
886 'tenant_id': 'tenant id',
889 'ip_address': 'ip address - optional'}
893 port_data
['type'] = 'external'
895 if port_data
.get('net_id'):
896 # check that new net has the correct type
897 result
, new_net
= self
.db
.check_target_net(port_data
['net_id'], None, 'external')
899 raise ovimException(str(new_net
), -result
)
900 # insert in data base
903 if port_data
.get('region'):
904 db_filter
['region'] = port_data
['region']
905 if port_data
.get('pci'):
906 db_filter
['pci'] = port_data
['pci']
907 if port_data
.get('compute_node'):
908 db_filter
['compute_node'] = port_data
['compute_node']
910 columns
= ['ofc_id', 'switch_dpid', 'switch_port', 'switch_mac', 'pci']
911 port_mapping_data
= self
.get_of_port_mappings(columns
, db_filter
)
913 if not len(port_mapping_data
):
914 raise ovimException("No port mapping founded for '{}'".format(str(db_filter
)),
916 elif len(port_mapping_data
) > 1:
917 raise ovimException("Wrong port data was given, please check pci, region & compute id data",
920 port_data
['ofc_id'] = port_mapping_data
[0]['ofc_id']
921 port_data
['switch_dpid'] = port_mapping_data
[0]['switch_dpid']
922 port_data
['switch_port'] = port_mapping_data
[0]['switch_port']
923 port_data
['switch_mac'] = port_mapping_data
[0]['switch_mac']
925 # remove from compute_node, region and pci of_port_data to adapt to 'ports' structure
926 if 'region' in port_data
:
927 del port_data
['region']
928 if 'pci' in port_data
:
930 if 'compute_node' in port_data
:
931 del port_data
['compute_node']
933 result
, uuid
= self
.db
.new_row('ports', port_data
, True, True)
936 self
.net_update_ofc_thread(port_data
['net_id'], port_data
['ofc_id'])
937 except ovimException
as e
:
938 raise ovimException("Cannot insert a task for updating network '{}' {}".
939 format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
940 except Exception as e
:
941 raise ovimException("Cannot insert a task for updating network '{}' {}"
942 .format(port_data
['net_id'], e
), HTTP_Internal_Server_Error
)
945 raise ovimException(str(uuid
), -result
)
947 def net_update_ofc_thread(self
, net_id
, ofc_id
=None, switch_dpid
=None):
949 Insert a update net task by net id or ofc_id for each ofc thread
950 :param net_id: network id
951 :param ofc_id: openflow controller id
952 :param switch_dpid: switch dpid
956 raise ovimException("No net_id received", HTTP_Internal_Server_Error
)
959 c
= 'No valid ofc_id or switch_dpid received'
962 ports
= self
.get_ports(filter={"net_id": net_id
})
964 port_ofc_id
= port
.get('ofc_id', None)
966 ofc_id
= port
['ofc_id']
967 switch_dpid
= port
['switch_dpid']
969 #TODO if not ofc_id: look at database table ofcs
972 # If no ofc_id found it, default ofc_id is used.
973 if not ofc_id
and not switch_dpid
:
976 if ofc_id
and ofc_id
in self
.config
['ofcs_thread']:
977 r
, c
= self
.config
['ofcs_thread'][ofc_id
].insert_task("update-net", net_id
)
980 ofcs_dpid_list
= self
.config
['ofcs_thread_dpid']
981 for ofc_t
in ofcs_dpid_list
:
982 if switch_dpid
in ofc_t
:
983 r
, c
= ofc_t
[switch_dpid
].insert_task("update-net", net_id
)
986 message
= "Cannot insert a task for updating network '{}', {}".format(net_id
, c
)
987 self
.logger
.error(message
)
988 raise ovimException(message
, HTTP_Internal_Server_Error
)
990 def delete_port(self
, port_id
):
991 # Look for the previous port data
992 result
, ports
= self
.db
.get_table(WHERE
={'uuid': port_id
, "type": "external"}, FROM
='ports')
994 raise ovimException("Cannot get port info from database: {}".format(ports
), http_code
=-result
)
995 # delete from the data base
996 result
, content
= self
.db
.delete_row('ports', port_id
)
998 raise ovimException("External port '{}' not found".format(port_id
), http_code
=HTTP_Not_Found
)
1000 raise ovimException("Cannot delete port from database: {}".format(content
), http_code
=-result
)
1002 network
= ports
[0].get('net_id', None)
1007 self
.net_update_ofc_thread(network
, ofc_id
=ports
[0]["ofc_id"], switch_dpid
=ports
[0]["switch_dpid"])
1008 except ovimException
as e
:
1009 raise ovimException("Cannot insert a task for delete network '{}' {}".format(network
, str(e
)),
1010 HTTP_Internal_Server_Error
)
1011 except Exception as e
:
1012 raise ovimException("Cannot insert a task for delete network '{}' {}".format(network
, str(e
)),
1013 HTTP_Internal_Server_Error
)
1017 def edit_port(self
, port_id
, port_data
, admin
=True):
1018 # Look for the previous port data
1019 result
, content
= self
.db
.get_table(FROM
="ports", WHERE
={'uuid': port_id
})
1021 raise ovimException("Cannot get port info from database: {}".format(content
), http_code
=-result
)
1023 raise ovimException("Port '{}' not found".format(port_id
), http_code
=HTTP_Not_Found
)
1028 if 'net_id' in port_data
:
1030 old_net
= port
.get('net_id', None)
1031 new_net
= port_data
['net_id']
1032 if old_net
!= new_net
:
1035 nets
.append(new_net
) # put first the new net, so that new openflow rules are created before removing the old ones
1037 nets
.append(old_net
)
1038 if port
['type'] == 'instance:bridge' or port
['type'] == 'instance:ovs':
1039 raise ovimException("bridge interfaces cannot be attached to a different net", http_code
=HTTP_Forbidden
)
1040 elif port
['type'] == 'external' and not admin
:
1041 raise ovimException("Needed admin privileges",http_code
=HTTP_Unauthorized
)
1043 # check that new net has the correct type
1044 result
, new_net_dict
= self
.db
.check_target_net(new_net
, None, port
['type'])
1046 raise ovimException("Error {}".format(new_net_dict
), http_code
=HTTP_Conflict
)
1047 # change VLAN for SR-IOV ports
1048 if result
>= 0 and port
["type"] == "instance:data" and port
["model"] == "VF": # TODO consider also VFnotShared
1050 port_data
["vlan"] = None
1052 port_data
["vlan"] = new_net_dict
["vlan"]
1053 # get host where this VM is allocated
1054 result
, content
= self
.db
.get_table(FROM
="instances", WHERE
={"uuid": port
["instance_id"]})
1056 host_id
= content
[0]["host_id"]
1058 # insert in data base
1060 result
, content
= self
.db
.update_rows('ports', port_data
, WHERE
={'uuid': port_id
}, log
=False)
1061 port
.update(port_data
)
1063 # Insert task to complete actions
1067 self
.net_update_ofc_thread(net_id
, port
["ofc_id"], switch_dpid
=port
["switch_dpid"])
1068 except ovimException
as e
:
1069 raise ovimException("Error updating network'{}' {}".format(net_id
, str(e
)),
1070 HTTP_Internal_Server_Error
)
1071 except Exception as e
:
1072 raise ovimException("Error updating network '{}' {}".format(net_id
, str(e
)),
1073 HTTP_Internal_Server_Error
)
1076 r
, v
= self
.config
['host_threads'][host_id
].insert_task("edit-iface", port_id
, old_net
, new_net
)
1078 self
.logger
.error("Error updating network '{}' {}".format(r
,v
))
1079 # TODO Do something if fails
1083 raise ovimException("Error {}".format(content
), http_code
=-result
)
1085 def new_of_controller(self
, ofc_data
):
1087 Create a new openflow controller into DB
1088 :param ofc_data: Dict openflow controller data
1089 :return: openflow controller dpid
1092 result
, ofc_uuid
= self
.db
.new_row('ofcs', ofc_data
, True, True)
1094 raise ovimException("New ofc Error %s" % ofc_uuid
, HTTP_Internal_Server_Error
)
1096 ofc_data
['uuid'] = ofc_uuid
1097 of_conn
= self
._load
_of
_module
(ofc_data
)
1098 self
._create
_ofc
_task
(ofc_uuid
, ofc_data
['dpid'], of_conn
)
1102 def edit_of_controller(self
, of_id
, ofc_data
):
1104 Edit an openflow controller entry from DB
1108 raise ovimException("No data received during uptade OF contorller", http_code
=HTTP_Internal_Server_Error
)
1110 old_of_controller
= self
.show_of_controller(of_id
)
1112 if old_of_controller
:
1113 result
, content
= self
.db
.update_rows('ofcs', ofc_data
, WHERE
={'uuid': of_id
}, log
=False)
1117 raise ovimException("Error uptating OF contorller with uuid {}".format(of_id
),
1120 raise ovimException("Error uptating OF contorller with uuid {}".format(of_id
),
1121 http_code
=HTTP_Internal_Server_Error
)
1123 def delete_of_controller(self
, of_id
):
1125 Delete an openflow controller from DB.
1126 :param of_id: openflow controller dpid
1130 ofc
= self
.show_of_controller(of_id
)
1132 result
, content
= self
.db
.delete_row("ofcs", of_id
)
1134 raise ovimException("Cannot delete ofc from database: {}".format(content
), http_code
=-result
)
1136 raise ovimException("ofc {} not found ".format(content
), http_code
=HTTP_Not_Found
)
1138 ofc_thread
= self
.config
['ofcs_thread'][of_id
]
1139 del self
.config
['ofcs_thread'][of_id
]
1140 for ofc_th
in self
.config
['ofcs_thread_dpid']:
1141 if ofc
['dpid'] in ofc_th
:
1142 self
.config
['ofcs_thread_dpid'].remove(ofc_th
)
1144 ofc_thread
.insert_task("exit")
1149 def show_of_controller(self
, uuid
):
1151 Show an openflow controller by dpid from DB.
1152 :param db_filter: List with where query parameters
1156 result
, content
= self
.db
.get_table(FROM
='ofcs', WHERE
={"uuid": uuid
}, LIMIT
=100)
1159 raise ovimException("Openflow controller with uuid '{}' not found".format(uuid
),
1160 http_code
=HTTP_Not_Found
)
1162 raise ovimException("Openflow controller with uuid '{}' error".format(uuid
),
1163 http_code
=HTTP_Internal_Server_Error
)
1166 def get_of_controllers(self
, columns
=None, db_filter
={}, limit
=None):
1168 Show an openflow controllers from DB.
1169 :param columns: List with SELECT query parameters
1170 :param db_filter: List with where query parameters
1171 :param limit: result Limit
1174 result
, content
= self
.db
.get_table(SELECT
=columns
, FROM
='ofcs', WHERE
=db_filter
, LIMIT
=limit
)
1177 raise ovimException(str(content
), -result
)
1181 def get_tenants(self
, columns
=None, db_filter
={}, limit
=None):
1183 Retrieve tenant list from DB
1184 :param columns: List with SELECT query parameters
1185 :param db_filter: List with where query parameters
1186 :param limit: result limit
1189 result
, content
= self
.db
.get_table(FROM
='tenants', SELECT
=columns
, WHERE
=db_filter
, LIMIT
=limit
)
1191 raise ovimException('get_tenatns Error {}'.format(str(content
)), -result
)
1193 convert_boolean(content
, ('enabled',))
1196 def show_tenant_id(self
, tenant_id
):
1198 Get tenant from DB by id
1199 :param tenant_id: tenant id
1202 result
, content
= self
.db
.get_table(FROM
='tenants', SELECT
=('uuid', 'name', 'description', 'enabled'),
1203 WHERE
={"uuid": tenant_id
})
1205 raise ovimException(str(content
), -result
)
1207 raise ovimException("tenant with uuid='{}' not found".format(tenant_id
), HTTP_Not_Found
)
1209 convert_boolean(content
, ('enabled',))
1212 def new_tentant(self
, tenant
):
1214 Create a tenant and store in DB
1215 :param tenant: Dictionary with tenant data
1216 :return: the uuid of created tenant. Raise exception upon error
1219 # insert in data base
1220 result
, tenant_uuid
= self
.db
.new_tenant(tenant
)
1225 raise ovimException(str(tenant_uuid
), -result
)
1227 def delete_tentant(self
, tenant_id
):
1229 Delete a tenant from the database.
1230 :param tenant_id: Tenant id
1231 :return: delete tenant id
1235 r
, tenants_flavors
= self
.db
.get_table(FROM
='tenants_flavors', SELECT
=('flavor_id', 'tenant_id'),
1236 WHERE
={'tenant_id': tenant_id
})
1238 tenants_flavors
= ()
1239 r
, tenants_images
= self
.db
.get_table(FROM
='tenants_images', SELECT
=('image_id', 'tenant_id'),
1240 WHERE
={'tenant_id': tenant_id
})
1244 result
, content
= self
.db
.delete_row('tenants', tenant_id
)
1246 raise ovimException("tenant '%s' not found" % tenant_id
, HTTP_Not_Found
)
1248 for flavor
in tenants_flavors
:
1249 self
.db
.delete_row_by_key("flavors", "uuid", flavor
['flavor_id'])
1250 for image
in tenants_images
:
1251 self
.db
.delete_row_by_key("images", "uuid", image
['image_id'])
1254 raise ovimException("Error deleting tenant '%s' " % tenant_id
, HTTP_Internal_Server_Error
)
1256 def edit_tenant(self
, tenant_id
, tenant_data
):
1258 Update a tenant data identified by tenant id
1259 :param tenant_id: tenant id
1260 :param tenant_data: Dictionary with tenant data
1264 # Look for the previous data
1265 result
, tenant_data_old
= self
.db
.get_table(FROM
='tenants', WHERE
={'uuid': tenant_id
})
1267 raise ovimException("Error updating tenant with uuid='{}': {}".format(tenant_id
, tenant_data_old
),
1268 HTTP_Internal_Server_Error
)
1270 raise ovimException("tenant with uuid='{}' not found".format(tenant_id
), HTTP_Not_Found
)
1272 # insert in data base
1273 result
, content
= self
.db
.update_rows('tenants', tenant_data
, WHERE
={'uuid': tenant_id
}, log
=True)
1277 raise ovimException(str(content
), -result
)
1279 def set_of_port_mapping(self
, of_maps
, ofc_id
=None, switch_dpid
=None, region
=None):
1281 Create new port mapping entry
1282 :param of_maps: List with port mapping information
1283 # maps =[{"ofc_id": <ofc_id>,"region": datacenter region,"compute_node": compute uuid,"pci": pci adress,
1284 "switch_dpid": swith dpid,"switch_port": port name,"switch_mac": mac}]
1285 :param ofc_id: ofc id
1286 :param switch_dpid: switch dpid
1287 :param region: datacenter region id
1293 map['ofc_id'] = ofc_id
1295 map['switch_dpid'] = switch_dpid
1297 map['region'] = region
1299 for of_map
in of_maps
:
1300 result
, uuid
= self
.db
.new_row('of_port_mappings', of_map
, True)
1302 of_map
["uuid"] = uuid
1304 raise ovimException(str(uuid
), -result
)
1307 def clear_of_port_mapping(self
, db_filter
={}):
1309 Clear port mapping filtering using db_filter dict
1310 :param db_filter: Parameter to filter during remove process
1313 result
, content
= self
.db
.delete_row_by_dict(FROM
='of_port_mappings', WHERE
=db_filter
)
1318 raise ovimException("Error deleting of_port_mappings with filter='{}'".format(str(db_filter
)),
1319 HTTP_Internal_Server_Error
)
1321 def get_of_port_mappings(self
, column
=None, db_filter
=None, db_limit
=None):
1323 Retrive port mapping from DB
1328 result
, content
= self
.db
.get_table(SELECT
=column
, WHERE
=db_filter
, FROM
='of_port_mappings', LIMIT
=db_limit
)
1331 self
.logger
.error("get_of_port_mappings Error %d %s", result
, content
)
1332 raise ovimException(str(content
), -result
)
1336 def get_dhcp_controller(self
):
1338 Create an host_thread object for manage openvim controller and not create a thread for itself
1339 :return: dhcp_host openvim controller object
1342 if 'openvim_controller' in self
.config
['host_threads']:
1343 return self
.config
['host_threads']['openvim_controller']
1346 controller_ip
= self
.config
['ovs_controller_ip']
1347 ovs_controller_user
= self
.config
['ovs_controller_user']
1349 host_test_mode
= True if self
.config
['mode'] == 'test' or self
.config
['mode'] == "OF only" else False
1350 host_develop_mode
= True if self
.config
['mode'] == 'development' else False
1352 dhcp_host
= ht
.host_thread(name
='openvim_controller', user
=ovs_controller_user
, host
=controller_ip
,
1354 db_lock
=self
.db_lock
, test
=host_test_mode
,
1355 image_path
=self
.config
['image_path'], version
=self
.config
['version'],
1356 host_id
='openvim_controller', develop_mode
=host_develop_mode
,
1357 develop_bridge_iface
=bridge_ifaces
, logger_name
=self
.logger_name
+ ".host.controller",
1358 debug
=self
.config
.get('log_level_host'))
1360 self
.config
['host_threads']['openvim_controller'] = dhcp_host
1361 if not host_test_mode
:
1362 dhcp_host
.ssh_connect()
1365 def launch_dhcp_server(self
, vlan
, first_ip
, last_ip
, cidr
, gateway
):
1367 Launch a dhcpserver base on dnsmasq attached to the net base on vlan id across the the openvim computes
1368 :param vlan: vlan identifier
1369 :param first_ip: First dhcp range ip
1370 :param last_ip: Last dhcp range ip
1371 :param cidr: net cidr
1372 :param gateway: net gateway
1375 ip_tools
= IPNetwork(cidr
)
1376 dhcp_netmask
= str(ip_tools
.netmask
)
1377 ip_range
= [first_ip
, last_ip
]
1379 dhcp_path
= self
.config
['ovs_controller_file_path']
1381 controller_host
= self
.get_dhcp_controller()
1382 controller_host
.create_linux_bridge(vlan
)
1383 controller_host
.create_dhcp_interfaces(vlan
, first_ip
, dhcp_netmask
)
1384 controller_host
.launch_dhcp_server(vlan
, ip_range
, dhcp_netmask
, dhcp_path
, gateway
)
1386 if __name__
== "__main__":
1388 parser
= argparse
.ArgumentParser()
1389 parser
.add_argument("-v","--version", help="show ovim library version", action
="store_true")
1390 parser
.add_argument("--database-version", help="show required database version", action
="store_true")
1391 args
= parser
.parse_args()
1393 print ('openvimd version {} {}'.format(ovim
.get_version(), ovim
.get_version_date()))
1394 print ('(c) Copyright Telefonica')
1395 elif args
.database_version
:
1396 print ('required database version: {}'.format(ovim
.get_database_version()))