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.13-r529"
46 version_date
= "May 2017"
47 database_version
= 18 #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
()
103 self
.of_test_mode
= False
105 def _create_database_connection(self
):
106 db
= vim_db
.vim_db((self
.config
["network_vlan_range_start"], self
.config
["network_vlan_range_end"]),
107 self
.logger_name
+ ".db", self
.config
.get('log_level_db'))
108 if db
.connect(self
.config
['db_host'], self
.config
['db_user'], self
.config
['db_passwd'],
109 self
.config
['db_name']) == -1:
110 # self.logger.error("Cannot connect to database %s at %s@%s", self.config['db_name'], self.config['db_user'],
111 # self.config['db_host'])
112 raise ovimException("Cannot connect to database {} at {}@{}".format(self
.config
['db_name'],
113 self
.config
['db_user'],
114 self
.config
['db_host']) )
122 def get_version_date():
126 def get_database_version():
127 return database_version
130 def _check_dhcp_data_integrity(network
):
132 Check if all dhcp parameter for anet are valid, if not will be calculated from cidr value
133 :param network: list with user nets paramters
136 if "cidr" in network
:
137 cidr
= network
["cidr"]
138 ip_tools
= IPNetwork(cidr
)
139 cidr_len
= ip_tools
.prefixlen
143 ips
= IPNetwork(cidr
)
144 if "dhcp_first_ip" not in network
:
145 network
["dhcp_first_ip"] = str(ips
[2])
146 if "dhcp_last_ip" not in network
:
147 network
["dhcp_last_ip"] = str(ips
[-2])
148 if "gateway_ip" not in network
:
149 network
["gateway_ip"] = str(ips
[1])
156 def _check_valid_uuid(uuid
):
157 id_schema
= {"type": "string", "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"}
159 js_v(uuid
, id_schema
)
161 except js_e
.ValidationError
:
164 def start_service(self
):
169 global database_version
170 # if self.running_info:
171 # return #TODO service can be checked and rebuild broken threads
172 r
= self
.db
.get_db_version()
174 db_path
= db_path
[:db_path
.rfind("/")]
175 if os
.path
.exists(db_path
+ "/database_utils/migrate_vim_db.sh"):
176 db_path
+= "/database_utils"
178 db_path
+= "/../database_utils"
181 raise ovimException("DATABASE is not valid. If you think it is corrupted, you can init it with"
182 " '{db_path}/init_vim_db.sh' script".format(db_path
=db_path
))
183 elif r
[0] != database_version
:
184 raise ovimException("DATABASE wrong version '{current}'. Try to upgrade/downgrade to version '{target}'"
185 " with '{db_path}/migrate_vim_db.sh {target}'".format(
186 current
=r
[0], target
=database_version
, db_path
=db_path
))
187 self
.logger
.critical("Starting ovim server version: '{} {}' database version '{}'".format(
188 self
.get_version(), self
.get_version_date(), self
.get_database_version()))
189 # create database connection for openflow threads
190 self
.config
["db"] = self
._create
_database
_connection
()
191 self
.config
["db_lock"] = threading
.Lock()
193 self
.of_test_mode
= False if self
.config
['mode'] == 'normal' or self
.config
['mode'] == "OF only" else True
194 # precreate interfaces; [bridge:<host_bridge_name>, VLAN used at Host, uuid of network camping in this bridge,
197 self
.config
['dhcp_nets'] = []
198 self
.config
['bridge_nets'] = []
199 for bridge
, vlan_speed
in self
.config
["bridge_ifaces"].items():
200 # skip 'development_bridge'
201 if self
.config
['mode'] == 'development' and self
.config
['development_bridge'] == bridge
:
203 self
.config
['bridge_nets'].append([bridge
, vlan_speed
[0], vlan_speed
[1], None])
205 # check if this bridge is already used (present at database) for a network)
206 used_bridge_nets
= []
207 for brnet
in self
.config
['bridge_nets']:
208 r
, nets
= self
.db
.get_table(SELECT
=('uuid',), FROM
='nets', WHERE
={'provider': "bridge:" + brnet
[0]})
210 brnet
[3] = nets
[0]['uuid']
211 used_bridge_nets
.append(brnet
[0])
212 if self
.config
.get("dhcp_server"):
213 if brnet
[0] in self
.config
["dhcp_server"]["bridge_ifaces"]:
214 self
.config
['dhcp_nets'].append(nets
[0]['uuid'])
215 if len(used_bridge_nets
) > 0:
216 self
.logger
.info("found used bridge nets: " + ",".join(used_bridge_nets
))
217 # get nets used by dhcp
218 if self
.config
.get("dhcp_server"):
219 for net
in self
.config
["dhcp_server"].get("nets", ()):
220 r
, nets
= self
.db
.get_table(SELECT
=('uuid',), FROM
='nets', WHERE
={'name': net
})
222 self
.config
['dhcp_nets'].append(nets
[0]['uuid'])
225 self
._start
_ofc
_default
_task
()
227 # OFC per tenant in DB
228 self
._start
_of
_db
_tasks
()
230 # create dhcp_server thread
231 host_test_mode
= True if self
.config
['mode'] == 'test' or self
.config
['mode'] == "OF only" else False
232 dhcp_params
= self
.config
.get("dhcp_server")
234 thread
= dt
.dhcp_thread(dhcp_params
=dhcp_params
, test
=host_test_mode
, dhcp_nets
=self
.config
["dhcp_nets"],
235 db
=self
.config
["db"], db_lock
=self
.config
["db_lock"],
236 logger_name
=self
.logger_name
+ ".dhcp",
237 debug
=self
.config
.get('log_level_of'))
239 self
.config
['dhcp_thread'] = thread
241 # Create one thread for each host
242 host_test_mode
= True if self
.config
['mode'] == 'test' or self
.config
['mode'] == "OF only" else False
243 host_develop_mode
= True if self
.config
['mode'] == 'development' else False
244 host_develop_bridge_iface
= self
.config
.get('development_bridge', None)
246 # get host list from data base before starting threads
247 r
, hosts
= self
.db
.get_table(SELECT
=('name', 'ip_name', 'user', 'uuid'), FROM
='hosts', WHERE
={'status': 'ok'})
249 raise ovimException("Cannot get hosts from database {}".format(hosts
))
251 self
.config
['host_threads'] = {}
253 host
['image_path'] = '/opt/VNF/images/openvim'
254 thread
= ht
.host_thread(name
=host
['name'], user
=host
['user'], host
=host
['ip_name'], db
=self
.config
["db"],
255 db_lock
=self
.config
["db_lock"], test
=host_test_mode
,
256 image_path
=self
.config
['image_path'],
257 version
=self
.config
['version'], host_id
=host
['uuid'],
258 develop_mode
=host_develop_mode
,
259 develop_bridge_iface
=host_develop_bridge_iface
,
260 logger_name
=self
.logger_name
+ ".host." + host
['name'],
261 debug
=self
.config
.get('log_level_host'))
263 self
.config
['host_threads'][host
['uuid']] = thread
265 # create ovs dhcp thread
266 result
, content
= self
.db
.get_table(FROM
='nets')
268 self
.logger
.error("http_get_ports Error %d %s", result
, content
)
269 raise ovimException(str(content
), -result
)
272 net_type
= net
['type']
273 if (net_type
== 'bridge_data' or net_type
== 'bridge_man') \
274 and net
["provider"][:4] == 'OVS:' and net
["enable_dhcp"] == "true":
275 self
.launch_dhcp_server(net
['vlan'],
276 net
['dhcp_first_ip'],
281 def _start_of_db_tasks(self
):
283 Start ofc task for existing ofcs in database
288 ofcs
= self
.get_of_controllers()
291 of_conn
= self
._load
_of
_module
(ofc
)
292 # create ofc thread per of controller
293 self
._create
_ofc
_task
(ofc
['uuid'], ofc
['dpid'], of_conn
)
295 def _create_ofc_task(self
, ofc_uuid
, dpid
, of_conn
):
297 Create an ofc thread for handle each sdn controllers
298 :param ofc_uuid: sdn controller uuid
299 :param dpid: sdn controller dpid
300 :param of_conn: OF_conn module
303 if 'ofcs_thread' not in self
.config
and 'ofcs_thread_dpid' not in self
.config
:
305 ofcs_thread_dpid
= []
307 ofcs_threads
= self
.config
['ofcs_thread']
308 ofcs_thread_dpid
= self
.config
['ofcs_thread_dpid']
310 if ofc_uuid
not in ofcs_threads
:
311 ofc_thread
= self
._create
_ofc
_thread
(of_conn
, ofc_uuid
)
312 if ofc_uuid
== "Default":
313 self
.config
['of_thread'] = ofc_thread
315 ofcs_threads
[ofc_uuid
] = ofc_thread
316 self
.config
['ofcs_thread'] = ofcs_threads
318 ofcs_thread_dpid
.append({dpid
: ofc_thread
})
319 self
.config
['ofcs_thread_dpid'] = ofcs_thread_dpid
321 def _start_ofc_default_task(self
):
323 Create default ofc thread
325 if 'of_controller' not in self
.config \
326 and 'of_controller_ip' not in self
.config \
327 and 'of_controller_port' not in self
.config \
328 and 'of_controller_dpid' not in self
.config
:
333 db_config
['ip'] = self
.config
.get('of_controller_ip')
334 db_config
['port'] = self
.config
.get('of_controller_port')
335 db_config
['dpid'] = self
.config
.get('of_controller_dpid')
336 db_config
['type'] = self
.config
.get('of_controller')
337 db_config
['user'] = self
.config
.get('of_user')
338 db_config
['password'] = self
.config
.get('of_password')
340 # create connector to the openflow controller
341 # load other parameters starting by of_ from config dict in a temporal dict
343 of_conn
= self
._load
_of
_module
(db_config
)
344 # create openflow thread
345 self
._create
_ofc
_task
("Default", db_config
['dpid'], of_conn
)
347 def _load_of_module(self
, db_config
):
349 import python module for each SDN controller supported
350 :param db_config: SDN dn information
354 raise ovimException("No module found it", HTTP_Internal_Server_Error
)
359 if self
.of_test_mode
:
360 return openflow_conn
.OfTestConnector({"name": db_config
['type'],
361 "dpid": db_config
['dpid'],
362 "of_debug": self
.config
['log_level_of']})
366 temp_dict
['of_ip'] = db_config
['ip']
367 temp_dict
['of_port'] = db_config
['port']
368 temp_dict
['of_dpid'] = db_config
['dpid']
369 temp_dict
['of_controller'] = db_config
['type']
370 temp_dict
['of_user'] = db_config
.get('user')
371 temp_dict
['of_password'] = db_config
.get('password')
373 temp_dict
['of_debug'] = self
.config
['log_level_of']
375 if temp_dict
['of_controller'] == 'opendaylight':
378 module
= temp_dict
['of_controller']
380 if module
not in ovim
.of_module
:
381 for base
in ("", "osm_openvim.", "lib_osm_openvim."):
383 pkg
= __import__(base
+ module
)
385 of_conn_module
= getattr(pkg
, module
)
388 ovim
.of_module
[module
] = of_conn_module
389 self
.logger
.debug("Module load from {}".format(base
+ module
))
391 except Exception as e
:
392 self
.logger
.warning("Module {} not found {}".format(base
+ module
, e
))
394 self
.logger
.error("Cannot open openflow controller module of type '%s'", module
)
395 raise ovimException("Cannot open openflow controller of type module '{}'"
396 "Revise it is installed".format(module
),
397 HTTP_Internal_Server_Error
)
399 of_conn_module
= ovim
.of_module
[module
]
400 return of_conn_module
.OF_conn(temp_dict
)
401 except Exception as e
:
402 self
.logger
.error("Cannot open the Openflow controller '%s': %s", type(e
).__name
__, str(e
))
403 raise ovimException("Cannot open the Openflow controller '{}': '{}'".format(type(e
).__name
__, str(e
)),
404 HTTP_Internal_Server_Error
)
406 def _create_ofc_thread(self
, of_conn
, ofc_uuid
="Default"):
408 Create and launch a of thread
411 # create openflow thread
413 #if 'of_controller_nets_with_same_vlan' in self.config:
414 # ofc_net_same_vlan = self.config['of_controller_nets_with_same_vlan']
416 # ofc_net_same_vlan = False
417 ofc_net_same_vlan
= False
419 thread
= oft
.openflow_thread(ofc_uuid
, of_conn
, of_test
=self
.of_test_mode
, db
=self
.config
["db"],
420 db_lock
=self
.config
["db_lock"],
421 pmp_with_same_vlan
=ofc_net_same_vlan
,
422 logger_name
=self
.logger_name
+ ".ofc." + ofc_uuid
,
423 debug
=self
.config
.get('log_level_of'))
424 #r, c = thread.OF_connector.obtain_port_correspondence()
426 # raise ovimException("Cannot get openflow information %s", c)
430 def stop_service(self
):
431 threads
= self
.config
.get('host_threads', {})
432 if 'of_thread' in self
.config
:
433 threads
['of'] = (self
.config
['of_thread'])
434 if 'ofcs_thread' in self
.config
:
435 ofcs_thread
= self
.config
['ofcs_thread']
436 for ofc
in ofcs_thread
:
437 threads
[ofc
] = ofcs_thread
[ofc
]
439 if 'dhcp_thread' in self
.config
:
440 threads
['dhcp'] = (self
.config
['dhcp_thread'])
442 for thread
in threads
.values():
443 thread
.insert_task("exit")
444 for thread
in threads
.values():
447 def get_networks(self
, columns
=None, db_filter
={}, limit
=None):
449 Retreive networks available
450 :param columns: List with select query parameters
451 :param db_filter: List with where query parameters
452 :param limit: Query limit result
455 result
, content
= self
.db
.get_table(SELECT
=columns
, FROM
='nets', WHERE
=db_filter
, LIMIT
=limit
)
458 raise ovimException(str(content
), -result
)
460 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
464 def show_network(self
, network_id
, db_filter
={}):
466 Get network from DB by id
467 :param network_id: net Id
468 :param db_filter: List with where query parameters
473 raise ovimException("Not network id was not found")
474 db_filter
['uuid'] = network_id
476 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
=db_filter
, LIMIT
=100)
479 raise ovimException(str(content
), -result
)
481 raise ovimException("show_network network '%s' not found" % network_id
, -result
)
483 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
485 result
, ports
= self
.db
.get_table(FROM
='ports', SELECT
=('uuid as port_id',),
486 WHERE
={'net_id': network_id
}, LIMIT
=100)
488 content
[0]['ports'] = ports
490 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
493 def new_network(self
, network
):
498 tenant_id
= network
.get('tenant_id')
501 result
, _
= self
.db
.get_table(FROM
='tenants', SELECT
=('uuid',), WHERE
={'uuid': tenant_id
, "enabled": True})
503 raise ovimException("set_network error, no tenant founded", -result
)
507 net_provider
= network
.get('provider')
508 net_type
= network
.get('type')
509 net_vlan
= network
.get("vlan")
510 net_bind_net
= network
.get("bind_net")
511 net_bind_type
= network
.get("bind_type")
512 net_region
= network
.get("region")
513 name
= network
["name"]
515 # check if network name ends with :<vlan_tag> and network exist in order to make and automated bindning
516 vlan_index
= name
.rfind(":")
517 if not net_bind_net
and not net_bind_type
and vlan_index
> 1:
519 vlan_tag
= int(name
[vlan_index
+ 1:])
520 if not vlan_tag
and vlan_tag
< 4096:
521 net_bind_net
= name
[:vlan_index
]
522 net_bind_type
= "vlan:" + name
[vlan_index
+ 1:]
527 # look for a valid net
528 if self
._check
_valid
_uuid
(net_bind_net
):
529 net_bind_key
= "uuid"
531 net_bind_key
= "name"
532 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
={net_bind_key
: net_bind_net
})
534 raise ovimException(' getting nets from db ' + content
, HTTP_Internal_Server_Error
)
536 raise ovimException(" bind_net %s '%s'not found" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
538 raise ovimException(" more than one bind_net %s '%s' found, use uuid" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
539 network
["bind_net"] = content
[0]["uuid"]
542 if net_bind_type
[0:5] != "vlan:":
543 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>'", HTTP_Bad_Request
)
544 if int(net_bind_type
[5:]) > 4095 or int(net_bind_type
[5:]) <= 0:
545 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>' with a tag between 1 and 4095",
547 network
["bind_type"] = net_bind_type
550 if net_provider
[:9] == "openflow:":
552 if net_type
!= "ptp" and net_type
!= "data":
553 raise ovimException(" only 'ptp' or 'data' net types can be bound to 'openflow'",
559 if net_type
!= "bridge_man" and net_type
!= "bridge_data":
560 raise ovimException("Only 'bridge_man' or 'bridge_data' net types can be bound "
561 "to 'bridge', 'macvtap' or 'default", HTTP_Bad_Request
)
563 net_type
= 'bridge_man'
566 net_type
= 'bridge_man'
569 if net_provider
[:7] == 'bridge:':
570 # check it is one of the pre-provisioned bridges
571 bridge_net_name
= net_provider
[7:]
572 for brnet
in self
.config
['bridge_nets']:
573 if brnet
[0] == bridge_net_name
: # free
575 raise ovimException("invalid 'provider:physical', "
576 "bridge '%s' is already used" % bridge_net_name
, HTTP_Conflict
)
580 # if bridge_net==None:
581 # bottle.abort(HTTP_Bad_Request, "invalid 'provider:physical', bridge '%s' is not one of the
582 # provisioned 'bridge_ifaces' in the configuration file" % bridge_net_name)
585 elif self
.config
['network_type'] == 'bridge' and (net_type
== 'bridge_data' or net_type
== 'bridge_man'):
586 # look for a free precreated nets
587 for brnet
in self
.config
['bridge_nets']:
588 if not brnet
[3]: # free
590 if net_type
== 'bridge_man': # look for the smaller speed
591 if brnet
[2] < bridge_net
[2]:
593 else: # look for the larger speed
594 if brnet
[2] > bridge_net
[2]:
600 raise ovimException("Max limits of bridge networks reached. Future versions of VIM "
601 "will overcome this limit", HTTP_Bad_Request
)
603 self
.logger
.debug("using net " + bridge_net
)
604 net_provider
= "bridge:" + bridge_net
[0]
605 net_vlan
= bridge_net
[1]
606 elif net_type
== 'bridge_data' or net_type
== 'bridge_man' and self
.config
['network_type'] == 'ovs':
609 if net_type
== "data" or net_type
== "ptp":
610 net_region
= "__DATA__"
611 elif net_provider
== "OVS":
612 net_region
= "__OVS__"
613 if not net_vlan
and (net_type
== "data" or net_type
== "ptp" or net_provider
== "OVS"):
614 net_vlan
= self
.db
.get_free_net_vlan(net_region
)
616 raise ovimException("Error getting an available vlan", HTTP_Internal_Server_Error
)
617 if net_provider
== 'OVS':
618 net_provider
= 'OVS' + ":" + str(net_vlan
)
620 network
['provider'] = net_provider
621 network
['type'] = net_type
622 network
['vlan'] = net_vlan
623 network
['region'] = net_region
624 dhcp_integrity
= True
625 if 'enable_dhcp' in network
and network
['enable_dhcp']:
626 dhcp_integrity
= self
._check
_dhcp
_data
_integrity
(network
)
628 result
, content
= self
.db
.new_row('nets', network
, True, True)
630 if result
>= 0 and dhcp_integrity
:
632 bridge_net
[3] = content
633 if self
.config
.get("dhcp_server") and self
.config
['network_type'] == 'bridge':
634 if network
["name"] in self
.config
["dhcp_server"].get("nets", ()):
635 self
.config
["dhcp_nets"].append(content
)
636 self
.logger
.debug("dhcp_server: add new net", content
)
637 elif not bridge_net
and bridge_net
[0] in self
.config
["dhcp_server"].get("bridge_ifaces", ()):
638 self
.config
["dhcp_nets"].append(content
)
639 self
.logger
.debug("dhcp_server: add new net", content
, content
)
642 raise ovimException("Error posting network", HTTP_Internal_Server_Error
)
643 # TODO kei change update->edit
645 def edit_network(self
, network_id
, network
):
647 Update entwork data byt id
650 # Look for the previous data
651 where_
= {'uuid': network_id
}
652 result
, network_old
= self
.db
.get_table(FROM
='nets', WHERE
=where_
)
654 raise ovimException("Error updating network %s" % network_old
, HTTP_Internal_Server_Error
)
656 raise ovimException('network %s not found' % network_id
, HTTP_Not_Found
)
658 nbports
, content
= self
.db
.get_table(FROM
='ports', SELECT
=('uuid as port_id',),
659 WHERE
={'net_id': network_id
}, LIMIT
=100)
661 raise ovimException("http_put_network_id error %d %s" % (result
, network_old
), HTTP_Internal_Server_Error
)
663 if 'type' in network
and network
['type'] != network_old
[0]['type']:
664 raise ovimException("Can not change type of network while having ports attached",
665 HTTP_Method_Not_Allowed
)
666 if 'vlan' in network
and network
['vlan'] != network_old
[0]['vlan']:
667 raise ovimException("Can not change vlan of network while having ports attached",
668 HTTP_Method_Not_Allowed
)
671 net_provider
= network
.get('provider', network_old
[0]['provider'])
672 net_type
= network
.get('type', network_old
[0]['type'])
673 net_bind_net
= network
.get("bind_net")
674 net_bind_type
= network
.get("bind_type")
676 # look for a valid net
677 if self
._check
_valid
_uuid
(net_bind_net
):
678 net_bind_key
= "uuid"
680 net_bind_key
= "name"
681 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
={net_bind_key
: net_bind_net
})
683 raise ovimException('Getting nets from db ' + content
, HTTP_Internal_Server_Error
)
685 raise ovimException("bind_net %s '%s'not found" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
687 raise ovimException("More than one bind_net %s '%s' found, use uuid" % (net_bind_key
, net_bind_net
),
689 network
["bind_net"] = content
[0]["uuid"]
691 if net_bind_type
[0:5] != "vlan:":
692 raise ovimException("Bad format for 'bind_type', must be 'vlan:<tag>'", HTTP_Bad_Request
)
693 if int(net_bind_type
[5:]) > 4095 or int(net_bind_type
[5:]) <= 0:
694 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>' with a tag between 1 and 4095",
697 if net_provider
[:9] == "openflow:":
698 if net_type
!= "ptp" and net_type
!= "data":
699 raise ovimException("Only 'ptp' or 'data' net types can be bound to 'openflow'", HTTP_Bad_Request
)
701 if net_type
!= "bridge_man" and net_type
!= "bridge_data":
702 raise ovimException("Only 'bridge_man' or 'bridge_data' net types can be bound to "
703 "'bridge', 'macvtap' or 'default", HTTP_Bad_Request
)
705 # insert in data base
706 result
, content
= self
.db
.update_rows('nets', network
, WHERE
={'uuid': network_id
}, log
=True)
708 # if result > 0 and nbports>0 and 'admin_state_up' in network
709 # and network['admin_state_up'] != network_old[0]['admin_state_up']:
714 self
.net_update_ofc_thread(network_id
)
715 except ovimException
as e
:
716 raise ovimException("Error while launching openflow rules in network '{}' {}"
717 .format(network_id
, str(e
)), HTTP_Internal_Server_Error
)
718 except Exception as e
:
719 raise ovimException("Error while launching openflow rules in network '{}' {}"
720 .format(network_id
, str(e
)), HTTP_Internal_Server_Error
)
722 if self
.config
.get("dhcp_server"):
723 if network_id
in self
.config
["dhcp_nets"]:
724 self
.config
["dhcp_nets"].remove(network_id
)
725 if network
.get("name", network_old
[0]["name"]) in self
.config
["dhcp_server"].get("nets", ()):
726 self
.config
["dhcp_nets"].append(network_id
)
728 net_bind
= network
.get("bind_type", network_old
[0]["bind_type"])
729 if net_bind
and net_bind
and net_bind
[:7] == "bridge:" and net_bind
[7:] in self
.config
["dhcp_server"].get(
730 "bridge_ifaces", ()):
731 self
.config
["dhcp_nets"].append(network_id
)
734 raise ovimException(content
, -result
)
736 def delete_network(self
, network_id
):
738 Delete network by network id
739 :param network_id: network id
743 # delete from the data base
744 result
, content
= self
.db
.delete_row('nets', network_id
)
747 raise ovimException("Network %s not found " % network_id
, HTTP_Not_Found
)
749 for brnet
in self
.config
['bridge_nets']:
750 if brnet
[3] == network_id
:
753 if self
.config
.get("dhcp_server") and network_id
in self
.config
["dhcp_nets"]:
754 self
.config
["dhcp_nets"].remove(network_id
)
757 raise ovimException("Error deleting network %s" % network_id
, HTTP_Internal_Server_Error
)
759 def get_openflow_rules(self
, network_id
=None):
761 Get openflow id from DB
762 :param network_id: Network id, if none all networks will be retrieved
763 :return: Return a list with Openflow rules per net
769 where_
= {"net_id": network_id
}
770 result
, content
= self
.db
.get_table(
771 SELECT
=("name", "net_id", "ofc_id", "priority", "vlan_id", "ingress_port", "src_mac", "dst_mac", "actions"),
772 WHERE
=where_
, FROM
='of_flows')
775 raise ovimException(str(content
), -result
)
778 def edit_openflow_rules(self
, network_id
=None):
781 To make actions over the net. The action is to reinstall the openflow rules
782 network_id can be 'all'
783 :param network_id: Network id, if none all networks will be retrieved
784 :return : Number of nets updated
791 where_
= {"uuid": network_id
}
792 result
, content
= self
.db
.get_table(SELECT
=("uuid", "type"), WHERE
=where_
, FROM
='nets')
795 raise ovimException(str(content
), -result
)
798 if net
["type"] != "ptp" and net
["type"] != "data":
803 self
.net_update_ofc_thread(net
['uuid'])
804 except ovimException
as e
:
805 raise ovimException("Error updating network'{}' {}".format(net
['uuid'], str(e
)),
806 HTTP_Internal_Server_Error
)
807 except Exception as e
:
808 raise ovimException("Error updating network '{}' {}".format(net
['uuid'], str(e
)),
809 HTTP_Internal_Server_Error
)
813 def delete_openflow_rules(self
, ofc_id
=None):
815 To make actions over the net. The action is to delete ALL openflow rules
816 :return: return operation result
820 if 'Default' in self
.config
['ofcs_thread']:
821 r
, c
= self
.config
['ofcs_thread']['Default'].insert_task("clear-all")
823 raise ovimException("Default Openflow controller not not running", HTTP_Not_Found
)
825 elif ofc_id
in self
.config
['ofcs_thread']:
826 r
, c
= self
.config
['ofcs_thread'][ofc_id
].insert_task("clear-all")
830 raise ovimException(str(c
), -r
)
832 raise ovimException("Openflow controller not found with ofc_id={}".format(ofc_id
), HTTP_Not_Found
)
835 def get_openflow_ports(self
, ofc_id
=None):
837 Obtain switch ports names of openflow controller
838 :return: Return flow ports in DB
841 if 'Default' in self
.config
['ofcs_thread']:
842 conn
= self
.config
['ofcs_thread']['Default'].OF_connector
844 raise ovimException("Default Openflow controller not not running", HTTP_Not_Found
)
846 if ofc_id
in self
.config
['ofcs_thread']:
847 conn
= self
.config
['ofcs_thread'][ofc_id
].OF_connector
849 raise ovimException("Openflow controller not found with ofc_id={}".format(ofc_id
), HTTP_Not_Found
)
852 def get_ports(self
, columns
=None, filter={}, limit
=None):
853 # result, content = my.db.get_ports(where_)
854 result
, content
= self
.db
.get_table(SELECT
=columns
, WHERE
=filter, FROM
='ports', LIMIT
=limit
)
856 self
.logger
.error("http_get_ports Error %d %s", result
, content
)
857 raise ovimException(str(content
), -result
)
859 convert_boolean(content
, ('admin_state_up',))
862 def new_port(self
, port_data
):
863 port_data
['type'] = 'external'
864 if port_data
.get('net_id'):
865 # check that new net has the correct type
866 result
, new_net
= self
.db
.check_target_net(port_data
['net_id'], None, 'external')
868 raise ovimException(str(new_net
), -result
)
869 # insert in data base
870 result
, uuid
= self
.db
.new_row('ports', port_data
, True, True)
872 if 'net_id' in port_data
:
874 self
.net_update_ofc_thread(port_data
['net_id'])
875 except ovimException
as e
:
876 raise ovimException("Cannot insert a task for updating network '{}' {}"
877 .format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
878 except Exception as e
:
879 raise ovimException("Cannot insert a task for updating network '{}' {}"
880 .format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
884 raise ovimException(str(uuid
), -result
)
886 def new_external_port(self
, port_data
):
888 Create new external port and check port mapping correspondence
889 :param port_data: port_data = {
890 'region': 'datacenter region',
891 'compute_node': 'compute node id',
892 'pci': 'pci port address',
895 'tenant_id': 'tenant id',
898 'ip_address': 'ip address - optional'}
902 port_data
['type'] = 'external'
904 if port_data
.get('net_id'):
905 # check that new net has the correct type
906 result
, new_net
= self
.db
.check_target_net(port_data
['net_id'], None, 'external')
908 raise ovimException(str(new_net
), -result
)
909 # insert in data base
912 if port_data
.get('region'):
913 db_filter
['region'] = port_data
['region']
914 if port_data
.get('pci'):
915 db_filter
['pci'] = port_data
['pci']
916 if port_data
.get('compute_node'):
917 db_filter
['compute_node'] = port_data
['compute_node']
919 columns
= ['ofc_id', 'switch_dpid', 'switch_port', 'switch_mac', 'pci']
920 port_mapping_data
= self
.get_of_port_mappings(columns
, db_filter
)
922 if not len(port_mapping_data
):
923 raise ovimException("No port mapping founded for '{}'".format(str(db_filter
)),
925 elif len(port_mapping_data
) > 1:
926 raise ovimException("Wrong port data was given, please check pci, region & compute id data",
929 port_data
['ofc_id'] = port_mapping_data
[0]['ofc_id']
930 port_data
['switch_dpid'] = port_mapping_data
[0]['switch_dpid']
931 port_data
['switch_port'] = port_mapping_data
[0]['switch_port']
932 port_data
['switch_mac'] = port_mapping_data
[0]['switch_mac']
934 # remove from compute_node, region and pci of_port_data to adapt to 'ports' structure
935 if 'region' in port_data
:
936 del port_data
['region']
937 if 'pci' in port_data
:
939 if 'compute_node' in port_data
:
940 del port_data
['compute_node']
942 result
, uuid
= self
.db
.new_row('ports', port_data
, True, True)
945 self
.net_update_ofc_thread(port_data
['net_id'], port_data
['ofc_id'])
946 except ovimException
as e
:
947 raise ovimException("Cannot insert a task for updating network '{}' {}".
948 format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
949 except Exception as e
:
950 raise ovimException("Cannot insert a task for updating network '{}' {}"
951 .format(port_data
['net_id'], e
), HTTP_Internal_Server_Error
)
954 raise ovimException(str(uuid
), -result
)
956 def net_update_ofc_thread(self
, net_id
, ofc_id
=None, switch_dpid
=None):
958 Insert a update net task by net id or ofc_id for each ofc thread
959 :param net_id: network id
960 :param ofc_id: openflow controller id
961 :param switch_dpid: switch dpid
965 raise ovimException("No net_id received", HTTP_Internal_Server_Error
)
968 c
= 'No valid ofc_id or switch_dpid received'
971 ports
= self
.get_ports(filter={"net_id": net_id
})
973 port_ofc_id
= port
.get('ofc_id', None)
975 ofc_id
= port
['ofc_id']
976 switch_dpid
= port
['switch_dpid']
978 #TODO if not ofc_id: look at database table ofcs
981 # If no ofc_id found it, default ofc_id is used.
982 if not ofc_id
and not switch_dpid
:
985 if ofc_id
and ofc_id
in self
.config
['ofcs_thread']:
986 r
, c
= self
.config
['ofcs_thread'][ofc_id
].insert_task("update-net", net_id
)
989 ofcs_dpid_list
= self
.config
['ofcs_thread_dpid']
990 for ofc_t
in ofcs_dpid_list
:
991 if switch_dpid
in ofc_t
:
992 r
, c
= ofc_t
[switch_dpid
].insert_task("update-net", net_id
)
995 message
= "Cannot insert a task for updating network '{}', {}".format(net_id
, c
)
996 self
.logger
.error(message
)
997 raise ovimException(message
, HTTP_Internal_Server_Error
)
999 def delete_port(self
, port_id
):
1000 # Look for the previous port data
1001 result
, ports
= self
.db
.get_table(WHERE
={'uuid': port_id
, "type": "external"}, FROM
='ports')
1003 raise ovimException("Cannot get port info from database: {}".format(ports
), http_code
=-result
)
1004 # delete from the data base
1005 result
, content
= self
.db
.delete_row('ports', port_id
)
1007 raise ovimException("External port '{}' not found".format(port_id
), http_code
=HTTP_Not_Found
)
1009 raise ovimException("Cannot delete port from database: {}".format(content
), http_code
=-result
)
1011 network
= ports
[0].get('net_id', None)
1016 self
.net_update_ofc_thread(network
, ofc_id
=ports
[0]["ofc_id"], switch_dpid
=ports
[0]["switch_dpid"])
1017 except ovimException
as e
:
1018 raise ovimException("Cannot insert a task for delete network '{}' {}".format(network
, str(e
)),
1019 HTTP_Internal_Server_Error
)
1020 except Exception as e
:
1021 raise ovimException("Cannot insert a task for delete network '{}' {}".format(network
, str(e
)),
1022 HTTP_Internal_Server_Error
)
1026 def edit_port(self
, port_id
, port_data
, admin
=True):
1027 # Look for the previous port data
1028 result
, content
= self
.db
.get_table(FROM
="ports", WHERE
={'uuid': port_id
})
1030 raise ovimException("Cannot get port info from database: {}".format(content
), http_code
=-result
)
1032 raise ovimException("Port '{}' not found".format(port_id
), http_code
=HTTP_Not_Found
)
1037 if 'net_id' in port_data
:
1039 old_net
= port
.get('net_id', None)
1040 new_net
= port_data
['net_id']
1041 if old_net
!= new_net
:
1044 nets
.append(new_net
) # put first the new net, so that new openflow rules are created before removing the old ones
1046 nets
.append(old_net
)
1047 if port
['type'] == 'instance:bridge' or port
['type'] == 'instance:ovs':
1048 raise ovimException("bridge interfaces cannot be attached to a different net", http_code
=HTTP_Forbidden
)
1049 elif port
['type'] == 'external' and not admin
:
1050 raise ovimException("Needed admin privileges",http_code
=HTTP_Unauthorized
)
1052 # check that new net has the correct type
1053 result
, new_net_dict
= self
.db
.check_target_net(new_net
, None, port
['type'])
1055 raise ovimException("Error {}".format(new_net_dict
), http_code
=HTTP_Conflict
)
1056 # change VLAN for SR-IOV ports
1057 if result
>= 0 and port
["type"] == "instance:data" and port
["model"] == "VF": # TODO consider also VFnotShared
1059 port_data
["vlan"] = None
1061 port_data
["vlan"] = new_net_dict
["vlan"]
1062 # get host where this VM is allocated
1063 result
, content
= self
.db
.get_table(FROM
="instances", WHERE
={"uuid": port
["instance_id"]})
1065 host_id
= content
[0]["host_id"]
1067 # insert in data base
1069 result
, content
= self
.db
.update_rows('ports', port_data
, WHERE
={'uuid': port_id
}, log
=False)
1070 port
.update(port_data
)
1072 # Insert task to complete actions
1076 self
.net_update_ofc_thread(net_id
, port
["ofc_id"], switch_dpid
=port
["switch_dpid"])
1077 except ovimException
as e
:
1078 raise ovimException("Error updating network'{}' {}".format(net_id
, str(e
)),
1079 HTTP_Internal_Server_Error
)
1080 except Exception as e
:
1081 raise ovimException("Error updating network '{}' {}".format(net_id
, str(e
)),
1082 HTTP_Internal_Server_Error
)
1085 r
, v
= self
.config
['host_threads'][host_id
].insert_task("edit-iface", port_id
, old_net
, new_net
)
1087 self
.logger
.error("Error updating network '{}' {}".format(r
,v
))
1088 # TODO Do something if fails
1092 raise ovimException("Error {}".format(content
), http_code
=-result
)
1094 def new_of_controller(self
, ofc_data
):
1096 Create a new openflow controller into DB
1097 :param ofc_data: Dict openflow controller data
1098 :return: openflow controller dpid
1101 result
, ofc_uuid
= self
.db
.new_row('ofcs', ofc_data
, True, True)
1103 raise ovimException("New ofc Error %s" % ofc_uuid
, HTTP_Internal_Server_Error
)
1105 ofc_data
['uuid'] = ofc_uuid
1106 of_conn
= self
._load
_of
_module
(ofc_data
)
1107 self
._create
_ofc
_task
(ofc_uuid
, ofc_data
['dpid'], of_conn
)
1111 def edit_of_controller(self
, of_id
, ofc_data
):
1113 Edit an openflow controller entry from DB
1117 raise ovimException("No data received during uptade OF contorller", http_code
=HTTP_Internal_Server_Error
)
1119 old_of_controller
= self
.show_of_controller(of_id
)
1121 if old_of_controller
:
1122 result
, content
= self
.db
.update_rows('ofcs', ofc_data
, WHERE
={'uuid': of_id
}, log
=False)
1126 raise ovimException("Error uptating OF contorller with uuid {}".format(of_id
),
1129 raise ovimException("Error uptating OF contorller with uuid {}".format(of_id
),
1130 http_code
=HTTP_Internal_Server_Error
)
1132 def delete_of_controller(self
, of_id
):
1134 Delete an openflow controller from DB.
1135 :param of_id: openflow controller dpid
1139 ofc
= self
.show_of_controller(of_id
)
1141 result
, content
= self
.db
.delete_row("ofcs", of_id
)
1143 raise ovimException("Cannot delete ofc from database: {}".format(content
), http_code
=-result
)
1145 raise ovimException("ofc {} not found ".format(content
), http_code
=HTTP_Not_Found
)
1147 ofc_thread
= self
.config
['ofcs_thread'][of_id
]
1148 del self
.config
['ofcs_thread'][of_id
]
1149 for ofc_th
in self
.config
['ofcs_thread_dpid']:
1150 if ofc
['dpid'] in ofc_th
:
1151 self
.config
['ofcs_thread_dpid'].remove(ofc_th
)
1153 ofc_thread
.insert_task("exit")
1158 def show_of_controller(self
, uuid
):
1160 Show an openflow controller by dpid from DB.
1161 :param db_filter: List with where query parameters
1165 result
, content
= self
.db
.get_table(FROM
='ofcs', WHERE
={"uuid": uuid
}, LIMIT
=100)
1168 raise ovimException("Openflow controller with uuid '{}' not found".format(uuid
),
1169 http_code
=HTTP_Not_Found
)
1171 raise ovimException("Openflow controller with uuid '{}' error".format(uuid
),
1172 http_code
=HTTP_Internal_Server_Error
)
1175 def get_of_controllers(self
, columns
=None, db_filter
={}, limit
=None):
1177 Show an openflow controllers from DB.
1178 :param columns: List with SELECT query parameters
1179 :param db_filter: List with where query parameters
1180 :param limit: result Limit
1183 result
, content
= self
.db
.get_table(SELECT
=columns
, FROM
='ofcs', WHERE
=db_filter
, LIMIT
=limit
)
1186 raise ovimException(str(content
), -result
)
1190 def get_tenants(self
, columns
=None, db_filter
={}, limit
=None):
1192 Retrieve tenant list from DB
1193 :param columns: List with SELECT query parameters
1194 :param db_filter: List with where query parameters
1195 :param limit: result limit
1198 result
, content
= self
.db
.get_table(FROM
='tenants', SELECT
=columns
, WHERE
=db_filter
, LIMIT
=limit
)
1200 raise ovimException('get_tenatns Error {}'.format(str(content
)), -result
)
1202 convert_boolean(content
, ('enabled',))
1205 def show_tenant_id(self
, tenant_id
):
1207 Get tenant from DB by id
1208 :param tenant_id: tenant id
1211 result
, content
= self
.db
.get_table(FROM
='tenants', SELECT
=('uuid', 'name', 'description', 'enabled'),
1212 WHERE
={"uuid": tenant_id
})
1214 raise ovimException(str(content
), -result
)
1216 raise ovimException("tenant with uuid='{}' not found".format(tenant_id
), HTTP_Not_Found
)
1218 convert_boolean(content
, ('enabled',))
1221 def new_tentant(self
, tenant
):
1223 Create a tenant and store in DB
1224 :param tenant: Dictionary with tenant data
1225 :return: the uuid of created tenant. Raise exception upon error
1228 # insert in data base
1229 result
, tenant_uuid
= self
.db
.new_tenant(tenant
)
1234 raise ovimException(str(tenant_uuid
), -result
)
1236 def delete_tentant(self
, tenant_id
):
1238 Delete a tenant from the database.
1239 :param tenant_id: Tenant id
1240 :return: delete tenant id
1244 r
, tenants_flavors
= self
.db
.get_table(FROM
='tenants_flavors', SELECT
=('flavor_id', 'tenant_id'),
1245 WHERE
={'tenant_id': tenant_id
})
1247 tenants_flavors
= ()
1248 r
, tenants_images
= self
.db
.get_table(FROM
='tenants_images', SELECT
=('image_id', 'tenant_id'),
1249 WHERE
={'tenant_id': tenant_id
})
1253 result
, content
= self
.db
.delete_row('tenants', tenant_id
)
1255 raise ovimException("tenant '%s' not found" % tenant_id
, HTTP_Not_Found
)
1257 for flavor
in tenants_flavors
:
1258 self
.db
.delete_row_by_key("flavors", "uuid", flavor
['flavor_id'])
1259 for image
in tenants_images
:
1260 self
.db
.delete_row_by_key("images", "uuid", image
['image_id'])
1263 raise ovimException("Error deleting tenant '%s' " % tenant_id
, HTTP_Internal_Server_Error
)
1265 def edit_tenant(self
, tenant_id
, tenant_data
):
1267 Update a tenant data identified by tenant id
1268 :param tenant_id: tenant id
1269 :param tenant_data: Dictionary with tenant data
1273 # Look for the previous data
1274 result
, tenant_data_old
= self
.db
.get_table(FROM
='tenants', WHERE
={'uuid': tenant_id
})
1276 raise ovimException("Error updating tenant with uuid='{}': {}".format(tenant_id
, tenant_data_old
),
1277 HTTP_Internal_Server_Error
)
1279 raise ovimException("tenant with uuid='{}' not found".format(tenant_id
), HTTP_Not_Found
)
1281 # insert in data base
1282 result
, content
= self
.db
.update_rows('tenants', tenant_data
, WHERE
={'uuid': tenant_id
}, log
=True)
1286 raise ovimException(str(content
), -result
)
1288 def set_of_port_mapping(self
, of_maps
, ofc_id
=None, switch_dpid
=None, region
=None):
1290 Create new port mapping entry
1291 :param of_maps: List with port mapping information
1292 # maps =[{"ofc_id": <ofc_id>,"region": datacenter region,"compute_node": compute uuid,"pci": pci adress,
1293 "switch_dpid": swith dpid,"switch_port": port name,"switch_mac": mac}]
1294 :param ofc_id: ofc id
1295 :param switch_dpid: switch dpid
1296 :param region: datacenter region id
1302 map['ofc_id'] = ofc_id
1304 map['switch_dpid'] = switch_dpid
1306 map['region'] = region
1308 for of_map
in of_maps
:
1309 result
, uuid
= self
.db
.new_row('of_port_mappings', of_map
, True)
1311 of_map
["uuid"] = uuid
1313 raise ovimException(str(uuid
), -result
)
1316 def clear_of_port_mapping(self
, db_filter
={}):
1318 Clear port mapping filtering using db_filter dict
1319 :param db_filter: Parameter to filter during remove process
1322 result
, content
= self
.db
.delete_row_by_dict(FROM
='of_port_mappings', WHERE
=db_filter
)
1327 raise ovimException("Error deleting of_port_mappings with filter='{}'".format(str(db_filter
)),
1328 HTTP_Internal_Server_Error
)
1330 def get_of_port_mappings(self
, column
=None, db_filter
=None, db_limit
=None):
1332 Retrive port mapping from DB
1337 result
, content
= self
.db
.get_table(SELECT
=column
, WHERE
=db_filter
, FROM
='of_port_mappings', LIMIT
=db_limit
)
1340 self
.logger
.error("get_of_port_mappings Error %d %s", result
, content
)
1341 raise ovimException(str(content
), -result
)
1345 def get_dhcp_controller(self
):
1347 Create an host_thread object for manage openvim controller and not create a thread for itself
1348 :return: dhcp_host openvim controller object
1351 if 'openvim_controller' in self
.config
['host_threads']:
1352 return self
.config
['host_threads']['openvim_controller']
1355 controller_ip
= self
.config
['ovs_controller_ip']
1356 ovs_controller_user
= self
.config
['ovs_controller_user']
1358 host_test_mode
= True if self
.config
['mode'] == 'test' or self
.config
['mode'] == "OF only" else False
1359 host_develop_mode
= True if self
.config
['mode'] == 'development' else False
1361 dhcp_host
= ht
.host_thread(name
='openvim_controller', user
=ovs_controller_user
, host
=controller_ip
,
1362 db
=self
.config
["db"], db_lock
=self
.config
["db_lock"], test
=host_test_mode
,
1363 image_path
=self
.config
['image_path'], version
=self
.config
['version'],
1364 host_id
='openvim_controller', develop_mode
=host_develop_mode
,
1365 develop_bridge_iface
=bridge_ifaces
,
1366 logger_name
=self
.logger_name
+ ".host.controller",
1367 debug
=self
.config
.get('log_level_host'))
1369 self
.config
['host_threads']['openvim_controller'] = dhcp_host
1370 if not host_test_mode
:
1371 dhcp_host
.ssh_connect()
1374 def launch_dhcp_server(self
, vlan
, first_ip
, last_ip
, cidr
, gateway
):
1376 Launch a dhcpserver base on dnsmasq attached to the net base on vlan id across the the openvim computes
1377 :param vlan: vlan identifier
1378 :param first_ip: First dhcp range ip
1379 :param last_ip: Last dhcp range ip
1380 :param cidr: net cidr
1381 :param gateway: net gateway
1384 ip_tools
= IPNetwork(cidr
)
1385 dhcp_netmask
= str(ip_tools
.netmask
)
1386 ip_range
= [first_ip
, last_ip
]
1388 dhcp_path
= self
.config
['ovs_controller_file_path']
1390 controller_host
= self
.get_dhcp_controller()
1391 controller_host
.create_linux_bridge(vlan
)
1392 controller_host
.create_dhcp_interfaces(vlan
, first_ip
, dhcp_netmask
)
1393 controller_host
.launch_dhcp_server(vlan
, ip_range
, dhcp_netmask
, dhcp_path
, gateway
)
1395 if __name__
== "__main__":
1397 parser
= argparse
.ArgumentParser()
1398 parser
.add_argument("-v","--version", help="show ovim library version", action
="store_true")
1399 parser
.add_argument("--database-version", help="show required database version", action
="store_true")
1400 args
= parser
.parse_args()
1402 print ('openvimd version {} {}'.format(ovim
.get_version(), ovim
.get_version_date()))
1403 print ('(c) Copyright Telefonica')
1404 elif args
.database_version
:
1405 print ('required database version: {}'.format(ovim
.get_database_version()))