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
:
382 pkg
= __import__("osm_openvim." + module
)
383 of_conn_module
= getattr(pkg
, module
)
384 ovim
.of_module
[module
] = of_conn_module
385 self
.logger
.debug("Module load from {}".format("osm_openvim." + module
))
386 except Exception as e
:
387 self
.logger
.error("Cannot open openflow controller module of type '%s'", module
)
388 raise ovimException("Cannot open openflow controller of type module '{}'"
389 "Revise it is installed".format(module
),
390 HTTP_Internal_Server_Error
)
392 of_conn_module
= ovim
.of_module
[module
]
393 return of_conn_module
.OF_conn(temp_dict
)
394 except Exception as e
:
395 self
.logger
.error("Cannot open the Openflow controller '%s': %s", type(e
).__name
__, str(e
))
396 raise ovimException("Cannot open the Openflow controller '{}': '{}'".format(type(e
).__name
__, str(e
)),
397 HTTP_Internal_Server_Error
)
399 def _create_ofc_thread(self
, of_conn
, ofc_uuid
="Default"):
401 Create and launch a of thread
404 # create openflow thread
406 #if 'of_controller_nets_with_same_vlan' in self.config:
407 # ofc_net_same_vlan = self.config['of_controller_nets_with_same_vlan']
409 # ofc_net_same_vlan = False
410 ofc_net_same_vlan
= False
412 thread
= oft
.openflow_thread(ofc_uuid
, of_conn
, of_test
=self
.of_test_mode
, db
=self
.config
["db"],
413 db_lock
=self
.config
["db_lock"],
414 pmp_with_same_vlan
=ofc_net_same_vlan
,
415 logger_name
=self
.logger_name
+ ".ofc." + ofc_uuid
,
416 debug
=self
.config
.get('log_level_of'))
417 #r, c = thread.OF_connector.obtain_port_correspondence()
419 # raise ovimException("Cannot get openflow information %s", c)
423 def stop_service(self
):
424 threads
= self
.config
.get('host_threads', {})
425 if 'of_thread' in self
.config
:
426 threads
['of'] = (self
.config
['of_thread'])
427 if 'ofcs_thread' in self
.config
:
428 ofcs_thread
= self
.config
['ofcs_thread']
429 for ofc
in ofcs_thread
:
430 threads
[ofc
] = ofcs_thread
[ofc
]
432 if 'dhcp_thread' in self
.config
:
433 threads
['dhcp'] = (self
.config
['dhcp_thread'])
435 for thread
in threads
.values():
436 thread
.insert_task("exit")
437 for thread
in threads
.values():
440 def get_networks(self
, columns
=None, db_filter
={}, limit
=None):
442 Retreive networks available
443 :param columns: List with select query parameters
444 :param db_filter: List with where query parameters
445 :param limit: Query limit result
448 result
, content
= self
.db
.get_table(SELECT
=columns
, FROM
='nets', WHERE
=db_filter
, LIMIT
=limit
)
451 raise ovimException(str(content
), -result
)
453 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
457 def show_network(self
, network_id
, db_filter
={}):
459 Get network from DB by id
460 :param network_id: net Id
461 :param db_filter: List with where query parameters
466 raise ovimException("Not network id was not found")
467 db_filter
['uuid'] = network_id
469 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
=db_filter
, LIMIT
=100)
472 raise ovimException(str(content
), -result
)
474 raise ovimException("show_network network '%s' not found" % network_id
, -result
)
476 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
478 result
, ports
= self
.db
.get_table(FROM
='ports', SELECT
=('uuid as port_id',),
479 WHERE
={'net_id': network_id
}, LIMIT
=100)
481 content
[0]['ports'] = ports
483 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
486 def new_network(self
, network
):
491 tenant_id
= network
.get('tenant_id')
494 result
, _
= self
.db
.get_table(FROM
='tenants', SELECT
=('uuid',), WHERE
={'uuid': tenant_id
, "enabled": True})
496 raise ovimException("set_network error, no tenant founded", -result
)
500 net_provider
= network
.get('provider')
501 net_type
= network
.get('type')
502 net_vlan
= network
.get("vlan")
503 net_bind_net
= network
.get("bind_net")
504 net_bind_type
= network
.get("bind_type")
505 net_region
= network
.get("region")
506 name
= network
["name"]
508 # check if network name ends with :<vlan_tag> and network exist in order to make and automated bindning
509 vlan_index
= name
.rfind(":")
510 if not net_bind_net
and not net_bind_type
and vlan_index
> 1:
512 vlan_tag
= int(name
[vlan_index
+ 1:])
513 if not vlan_tag
and vlan_tag
< 4096:
514 net_bind_net
= name
[:vlan_index
]
515 net_bind_type
= "vlan:" + name
[vlan_index
+ 1:]
520 # look for a valid net
521 if self
._check
_valid
_uuid
(net_bind_net
):
522 net_bind_key
= "uuid"
524 net_bind_key
= "name"
525 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
={net_bind_key
: net_bind_net
})
527 raise ovimException(' getting nets from db ' + content
, HTTP_Internal_Server_Error
)
529 raise ovimException(" bind_net %s '%s'not found" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
531 raise ovimException(" more than one bind_net %s '%s' found, use uuid" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
532 network
["bind_net"] = content
[0]["uuid"]
535 if net_bind_type
[0:5] != "vlan:":
536 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>'", HTTP_Bad_Request
)
537 if int(net_bind_type
[5:]) > 4095 or int(net_bind_type
[5:]) <= 0:
538 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>' with a tag between 1 and 4095",
540 network
["bind_type"] = net_bind_type
543 if net_provider
[:9] == "openflow:":
545 if net_type
!= "ptp" and net_type
!= "data":
546 raise ovimException(" only 'ptp' or 'data' net types can be bound to 'openflow'",
552 if net_type
!= "bridge_man" and net_type
!= "bridge_data":
553 raise ovimException("Only 'bridge_man' or 'bridge_data' net types can be bound "
554 "to 'bridge', 'macvtap' or 'default", HTTP_Bad_Request
)
556 net_type
= 'bridge_man'
559 net_type
= 'bridge_man'
562 if net_provider
[:7] == 'bridge:':
563 # check it is one of the pre-provisioned bridges
564 bridge_net_name
= net_provider
[7:]
565 for brnet
in self
.config
['bridge_nets']:
566 if brnet
[0] == bridge_net_name
: # free
568 raise ovimException("invalid 'provider:physical', "
569 "bridge '%s' is already used" % bridge_net_name
, HTTP_Conflict
)
573 # if bridge_net==None:
574 # bottle.abort(HTTP_Bad_Request, "invalid 'provider:physical', bridge '%s' is not one of the
575 # provisioned 'bridge_ifaces' in the configuration file" % bridge_net_name)
578 elif self
.config
['network_type'] == 'bridge' and (net_type
== 'bridge_data' or net_type
== 'bridge_man'):
579 # look for a free precreated nets
580 for brnet
in self
.config
['bridge_nets']:
581 if not brnet
[3]: # free
583 if net_type
== 'bridge_man': # look for the smaller speed
584 if brnet
[2] < bridge_net
[2]:
586 else: # look for the larger speed
587 if brnet
[2] > bridge_net
[2]:
593 raise ovimException("Max limits of bridge networks reached. Future versions of VIM "
594 "will overcome this limit", HTTP_Bad_Request
)
596 self
.logger
.debug("using net " + bridge_net
)
597 net_provider
= "bridge:" + bridge_net
[0]
598 net_vlan
= bridge_net
[1]
599 elif net_type
== 'bridge_data' or net_type
== 'bridge_man' and self
.config
['network_type'] == 'ovs':
602 if net_type
== "data" or net_type
== "ptp":
603 net_region
= "__DATA__"
604 elif net_provider
== "OVS":
605 net_region
= "__OVS__"
606 if not net_vlan
and (net_type
== "data" or net_type
== "ptp" or net_provider
== "OVS"):
607 net_vlan
= self
.db
.get_free_net_vlan(net_region
)
609 raise ovimException("Error getting an available vlan", HTTP_Internal_Server_Error
)
610 if net_provider
== 'OVS':
611 net_provider
= 'OVS' + ":" + str(net_vlan
)
613 network
['provider'] = net_provider
614 network
['type'] = net_type
615 network
['vlan'] = net_vlan
616 network
['region'] = net_region
617 dhcp_integrity
= True
618 if 'enable_dhcp' in network
and network
['enable_dhcp']:
619 dhcp_integrity
= self
._check
_dhcp
_data
_integrity
(network
)
621 result
, content
= self
.db
.new_row('nets', network
, True, True)
623 if result
>= 0 and dhcp_integrity
:
625 bridge_net
[3] = content
626 if self
.config
.get("dhcp_server") and self
.config
['network_type'] == 'bridge':
627 if network
["name"] in self
.config
["dhcp_server"].get("nets", ()):
628 self
.config
["dhcp_nets"].append(content
)
629 self
.logger
.debug("dhcp_server: add new net", content
)
630 elif not bridge_net
and bridge_net
[0] in self
.config
["dhcp_server"].get("bridge_ifaces", ()):
631 self
.config
["dhcp_nets"].append(content
)
632 self
.logger
.debug("dhcp_server: add new net", content
, content
)
635 raise ovimException("Error posting network", HTTP_Internal_Server_Error
)
636 # TODO kei change update->edit
638 def edit_network(self
, network_id
, network
):
640 Update entwork data byt id
643 # Look for the previous data
644 where_
= {'uuid': network_id
}
645 result
, network_old
= self
.db
.get_table(FROM
='nets', WHERE
=where_
)
647 raise ovimException("Error updating network %s" % network_old
, HTTP_Internal_Server_Error
)
649 raise ovimException('network %s not found' % network_id
, HTTP_Not_Found
)
651 nbports
, content
= self
.db
.get_table(FROM
='ports', SELECT
=('uuid as port_id',),
652 WHERE
={'net_id': network_id
}, LIMIT
=100)
654 raise ovimException("http_put_network_id error %d %s" % (result
, network_old
), HTTP_Internal_Server_Error
)
656 if 'type' in network
and network
['type'] != network_old
[0]['type']:
657 raise ovimException("Can not change type of network while having ports attached",
658 HTTP_Method_Not_Allowed
)
659 if 'vlan' in network
and network
['vlan'] != network_old
[0]['vlan']:
660 raise ovimException("Can not change vlan of network while having ports attached",
661 HTTP_Method_Not_Allowed
)
664 net_provider
= network
.get('provider', network_old
[0]['provider'])
665 net_type
= network
.get('type', network_old
[0]['type'])
666 net_bind_net
= network
.get("bind_net")
667 net_bind_type
= network
.get("bind_type")
669 # look for a valid net
670 if self
._check
_valid
_uuid
(net_bind_net
):
671 net_bind_key
= "uuid"
673 net_bind_key
= "name"
674 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
={net_bind_key
: net_bind_net
})
676 raise ovimException('Getting nets from db ' + content
, HTTP_Internal_Server_Error
)
678 raise ovimException("bind_net %s '%s'not found" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
680 raise ovimException("More than one bind_net %s '%s' found, use uuid" % (net_bind_key
, net_bind_net
),
682 network
["bind_net"] = content
[0]["uuid"]
684 if net_bind_type
[0:5] != "vlan:":
685 raise ovimException("Bad format for 'bind_type', must be 'vlan:<tag>'", HTTP_Bad_Request
)
686 if int(net_bind_type
[5:]) > 4095 or int(net_bind_type
[5:]) <= 0:
687 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>' with a tag between 1 and 4095",
690 if net_provider
[:9] == "openflow:":
691 if net_type
!= "ptp" and net_type
!= "data":
692 raise ovimException("Only 'ptp' or 'data' net types can be bound to 'openflow'", HTTP_Bad_Request
)
694 if net_type
!= "bridge_man" and net_type
!= "bridge_data":
695 raise ovimException("Only 'bridge_man' or 'bridge_data' net types can be bound to "
696 "'bridge', 'macvtap' or 'default", HTTP_Bad_Request
)
698 # insert in data base
699 result
, content
= self
.db
.update_rows('nets', network
, WHERE
={'uuid': network_id
}, log
=True)
701 # if result > 0 and nbports>0 and 'admin_state_up' in network
702 # and network['admin_state_up'] != network_old[0]['admin_state_up']:
707 self
.net_update_ofc_thread(network_id
)
708 except ovimException
as e
:
709 raise ovimException("Error while launching openflow rules in network '{}' {}"
710 .format(network_id
, str(e
)), HTTP_Internal_Server_Error
)
711 except Exception as e
:
712 raise ovimException("Error while launching openflow rules in network '{}' {}"
713 .format(network_id
, str(e
)), HTTP_Internal_Server_Error
)
715 if self
.config
.get("dhcp_server"):
716 if network_id
in self
.config
["dhcp_nets"]:
717 self
.config
["dhcp_nets"].remove(network_id
)
718 if network
.get("name", network_old
[0]["name"]) in self
.config
["dhcp_server"].get("nets", ()):
719 self
.config
["dhcp_nets"].append(network_id
)
721 net_bind
= network
.get("bind_type", network_old
[0]["bind_type"])
722 if net_bind
and net_bind
and net_bind
[:7] == "bridge:" and net_bind
[7:] in self
.config
["dhcp_server"].get(
723 "bridge_ifaces", ()):
724 self
.config
["dhcp_nets"].append(network_id
)
727 raise ovimException(content
, -result
)
729 def delete_network(self
, network_id
):
731 Delete network by network id
732 :param network_id: network id
736 # delete from the data base
737 result
, content
= self
.db
.delete_row('nets', network_id
)
740 raise ovimException("Network %s not found " % network_id
, HTTP_Not_Found
)
742 for brnet
in self
.config
['bridge_nets']:
743 if brnet
[3] == network_id
:
746 if self
.config
.get("dhcp_server") and network_id
in self
.config
["dhcp_nets"]:
747 self
.config
["dhcp_nets"].remove(network_id
)
750 raise ovimException("Error deleting network %s" % network_id
, HTTP_Internal_Server_Error
)
752 def get_openflow_rules(self
, network_id
=None):
754 Get openflow id from DB
755 :param network_id: Network id, if none all networks will be retrieved
756 :return: Return a list with Openflow rules per net
762 where_
= {"net_id": network_id
}
763 result
, content
= self
.db
.get_table(
764 SELECT
=("name", "net_id", "ofc_id", "priority", "vlan_id", "ingress_port", "src_mac", "dst_mac", "actions"),
765 WHERE
=where_
, FROM
='of_flows')
768 raise ovimException(str(content
), -result
)
771 def edit_openflow_rules(self
, network_id
=None):
774 To make actions over the net. The action is to reinstall the openflow rules
775 network_id can be 'all'
776 :param network_id: Network id, if none all networks will be retrieved
777 :return : Number of nets updated
784 where_
= {"uuid": network_id
}
785 result
, content
= self
.db
.get_table(SELECT
=("uuid", "type"), WHERE
=where_
, FROM
='nets')
788 raise ovimException(str(content
), -result
)
791 if net
["type"] != "ptp" and net
["type"] != "data":
796 self
.net_update_ofc_thread(net
['uuid'])
797 except ovimException
as e
:
798 raise ovimException("Error updating network'{}' {}".format(net
['uuid'], str(e
)),
799 HTTP_Internal_Server_Error
)
800 except Exception as e
:
801 raise ovimException("Error updating network '{}' {}".format(net
['uuid'], str(e
)),
802 HTTP_Internal_Server_Error
)
806 def delete_openflow_rules(self
, ofc_id
=None):
808 To make actions over the net. The action is to delete ALL openflow rules
809 :return: return operation result
813 if 'Default' in self
.config
['ofcs_thread']:
814 r
, c
= self
.config
['ofcs_thread']['Default'].insert_task("clear-all")
816 raise ovimException("Default Openflow controller not not running", HTTP_Not_Found
)
818 elif ofc_id
in self
.config
['ofcs_thread']:
819 r
, c
= self
.config
['ofcs_thread'][ofc_id
].insert_task("clear-all")
823 raise ovimException(str(c
), -r
)
825 raise ovimException("Openflow controller not found with ofc_id={}".format(ofc_id
), HTTP_Not_Found
)
828 def get_openflow_ports(self
, ofc_id
=None):
830 Obtain switch ports names of openflow controller
831 :return: Return flow ports in DB
834 if 'Default' in self
.config
['ofcs_thread']:
835 conn
= self
.config
['ofcs_thread']['Default'].OF_connector
837 raise ovimException("Default Openflow controller not not running", HTTP_Not_Found
)
839 if ofc_id
in self
.config
['ofcs_thread']:
840 conn
= self
.config
['ofcs_thread'][ofc_id
].OF_connector
842 raise ovimException("Openflow controller not found with ofc_id={}".format(ofc_id
), HTTP_Not_Found
)
845 def get_ports(self
, columns
=None, filter={}, limit
=None):
846 # result, content = my.db.get_ports(where_)
847 result
, content
= self
.db
.get_table(SELECT
=columns
, WHERE
=filter, FROM
='ports', LIMIT
=limit
)
849 self
.logger
.error("http_get_ports Error %d %s", result
, content
)
850 raise ovimException(str(content
), -result
)
852 convert_boolean(content
, ('admin_state_up',))
855 def new_port(self
, port_data
):
856 port_data
['type'] = 'external'
857 if port_data
.get('net_id'):
858 # check that new net has the correct type
859 result
, new_net
= self
.db
.check_target_net(port_data
['net_id'], None, 'external')
861 raise ovimException(str(new_net
), -result
)
862 # insert in data base
863 result
, uuid
= self
.db
.new_row('ports', port_data
, True, True)
865 if 'net_id' in port_data
:
867 self
.net_update_ofc_thread(port_data
['net_id'])
868 except ovimException
as e
:
869 raise ovimException("Cannot insert a task for updating network '{}' {}"
870 .format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
871 except Exception as e
:
872 raise ovimException("Cannot insert a task for updating network '{}' {}"
873 .format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
877 raise ovimException(str(uuid
), -result
)
879 def new_external_port(self
, port_data
):
881 Create new external port and check port mapping correspondence
882 :param port_data: port_data = {
883 'region': 'datacenter region',
884 'compute_node': 'compute node id',
885 'pci': 'pci port address',
888 'tenant_id': 'tenant id',
891 'ip_address': 'ip address - optional'}
895 port_data
['type'] = 'external'
897 if port_data
.get('net_id'):
898 # check that new net has the correct type
899 result
, new_net
= self
.db
.check_target_net(port_data
['net_id'], None, 'external')
901 raise ovimException(str(new_net
), -result
)
902 # insert in data base
905 if port_data
.get('region'):
906 db_filter
['region'] = port_data
['region']
907 if port_data
.get('pci'):
908 db_filter
['pci'] = port_data
['pci']
909 if port_data
.get('compute_node'):
910 db_filter
['compute_node'] = port_data
['compute_node']
912 columns
= ['ofc_id', 'switch_dpid', 'switch_port', 'switch_mac', 'pci']
913 port_mapping_data
= self
.get_of_port_mappings(columns
, db_filter
)
915 if not len(port_mapping_data
):
916 raise ovimException("No port mapping founded for '{}'".format(str(db_filter
)),
918 elif len(port_mapping_data
) > 1:
919 raise ovimException("Wrong port data was given, please check pci, region & compute id data",
922 port_data
['ofc_id'] = port_mapping_data
[0]['ofc_id']
923 port_data
['switch_dpid'] = port_mapping_data
[0]['switch_dpid']
924 port_data
['switch_port'] = port_mapping_data
[0]['switch_port']
925 port_data
['switch_mac'] = port_mapping_data
[0]['switch_mac']
927 # remove from compute_node, region and pci of_port_data to adapt to 'ports' structure
928 if 'region' in port_data
:
929 del port_data
['region']
930 if 'pci' in port_data
:
932 if 'compute_node' in port_data
:
933 del port_data
['compute_node']
935 result
, uuid
= self
.db
.new_row('ports', port_data
, True, True)
938 self
.net_update_ofc_thread(port_data
['net_id'], port_data
['ofc_id'])
939 except ovimException
as e
:
940 raise ovimException("Cannot insert a task for updating network '{}' {}".
941 format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
942 except Exception as e
:
943 raise ovimException("Cannot insert a task for updating network '{}' {}"
944 .format(port_data
['net_id'], e
), HTTP_Internal_Server_Error
)
947 raise ovimException(str(uuid
), -result
)
949 def net_update_ofc_thread(self
, net_id
, ofc_id
=None, switch_dpid
=None):
951 Insert a update net task by net id or ofc_id for each ofc thread
952 :param net_id: network id
953 :param ofc_id: openflow controller id
954 :param switch_dpid: switch dpid
958 raise ovimException("No net_id received", HTTP_Internal_Server_Error
)
961 c
= 'No valid ofc_id or switch_dpid received'
964 ports
= self
.get_ports(filter={"net_id": net_id
})
966 port_ofc_id
= port
.get('ofc_id', None)
968 ofc_id
= port
['ofc_id']
969 switch_dpid
= port
['switch_dpid']
971 #TODO if not ofc_id: look at database table ofcs
974 # If no ofc_id found it, default ofc_id is used.
975 if not ofc_id
and not switch_dpid
:
978 if ofc_id
and ofc_id
in self
.config
['ofcs_thread']:
979 r
, c
= self
.config
['ofcs_thread'][ofc_id
].insert_task("update-net", net_id
)
982 ofcs_dpid_list
= self
.config
['ofcs_thread_dpid']
983 for ofc_t
in ofcs_dpid_list
:
984 if switch_dpid
in ofc_t
:
985 r
, c
= ofc_t
[switch_dpid
].insert_task("update-net", net_id
)
988 message
= "Cannot insert a task for updating network '{}', {}".format(net_id
, c
)
989 self
.logger
.error(message
)
990 raise ovimException(message
, HTTP_Internal_Server_Error
)
992 def delete_port(self
, port_id
):
993 # Look for the previous port data
994 result
, ports
= self
.db
.get_table(WHERE
={'uuid': port_id
, "type": "external"}, FROM
='ports')
996 raise ovimException("Cannot get port info from database: {}".format(ports
), http_code
=-result
)
997 # delete from the data base
998 result
, content
= self
.db
.delete_row('ports', port_id
)
1000 raise ovimException("External port '{}' not found".format(port_id
), http_code
=HTTP_Not_Found
)
1002 raise ovimException("Cannot delete port from database: {}".format(content
), http_code
=-result
)
1004 network
= ports
[0].get('net_id', None)
1009 self
.net_update_ofc_thread(network
, ofc_id
=ports
[0]["ofc_id"], switch_dpid
=ports
[0]["switch_dpid"])
1010 except ovimException
as e
:
1011 raise ovimException("Cannot insert a task for delete network '{}' {}".format(network
, str(e
)),
1012 HTTP_Internal_Server_Error
)
1013 except Exception as e
:
1014 raise ovimException("Cannot insert a task for delete network '{}' {}".format(network
, str(e
)),
1015 HTTP_Internal_Server_Error
)
1019 def edit_port(self
, port_id
, port_data
, admin
=True):
1020 # Look for the previous port data
1021 result
, content
= self
.db
.get_table(FROM
="ports", WHERE
={'uuid': port_id
})
1023 raise ovimException("Cannot get port info from database: {}".format(content
), http_code
=-result
)
1025 raise ovimException("Port '{}' not found".format(port_id
), http_code
=HTTP_Not_Found
)
1030 if 'net_id' in port_data
:
1032 old_net
= port
.get('net_id', None)
1033 new_net
= port_data
['net_id']
1034 if old_net
!= new_net
:
1037 nets
.append(new_net
) # put first the new net, so that new openflow rules are created before removing the old ones
1039 nets
.append(old_net
)
1040 if port
['type'] == 'instance:bridge' or port
['type'] == 'instance:ovs':
1041 raise ovimException("bridge interfaces cannot be attached to a different net", http_code
=HTTP_Forbidden
)
1042 elif port
['type'] == 'external' and not admin
:
1043 raise ovimException("Needed admin privileges",http_code
=HTTP_Unauthorized
)
1045 # check that new net has the correct type
1046 result
, new_net_dict
= self
.db
.check_target_net(new_net
, None, port
['type'])
1048 raise ovimException("Error {}".format(new_net_dict
), http_code
=HTTP_Conflict
)
1049 # change VLAN for SR-IOV ports
1050 if result
>= 0 and port
["type"] == "instance:data" and port
["model"] == "VF": # TODO consider also VFnotShared
1052 port_data
["vlan"] = None
1054 port_data
["vlan"] = new_net_dict
["vlan"]
1055 # get host where this VM is allocated
1056 result
, content
= self
.db
.get_table(FROM
="instances", WHERE
={"uuid": port
["instance_id"]})
1058 host_id
= content
[0]["host_id"]
1060 # insert in data base
1062 result
, content
= self
.db
.update_rows('ports', port_data
, WHERE
={'uuid': port_id
}, log
=False)
1063 port
.update(port_data
)
1065 # Insert task to complete actions
1069 self
.net_update_ofc_thread(net_id
, port
["ofc_id"], switch_dpid
=port
["switch_dpid"])
1070 except ovimException
as e
:
1071 raise ovimException("Error updating network'{}' {}".format(net_id
, str(e
)),
1072 HTTP_Internal_Server_Error
)
1073 except Exception as e
:
1074 raise ovimException("Error updating network '{}' {}".format(net_id
, str(e
)),
1075 HTTP_Internal_Server_Error
)
1078 r
, v
= self
.config
['host_threads'][host_id
].insert_task("edit-iface", port_id
, old_net
, new_net
)
1080 self
.logger
.error("Error updating network '{}' {}".format(r
,v
))
1081 # TODO Do something if fails
1085 raise ovimException("Error {}".format(content
), http_code
=-result
)
1087 def new_of_controller(self
, ofc_data
):
1089 Create a new openflow controller into DB
1090 :param ofc_data: Dict openflow controller data
1091 :return: openflow controller dpid
1094 result
, ofc_uuid
= self
.db
.new_row('ofcs', ofc_data
, True, True)
1096 raise ovimException("New ofc Error %s" % ofc_uuid
, HTTP_Internal_Server_Error
)
1098 ofc_data
['uuid'] = ofc_uuid
1099 of_conn
= self
._load
_of
_module
(ofc_data
)
1100 self
._create
_ofc
_task
(ofc_uuid
, ofc_data
['dpid'], of_conn
)
1104 def edit_of_controller(self
, of_id
, ofc_data
):
1106 Edit an openflow controller entry from DB
1110 raise ovimException("No data received during uptade OF contorller", http_code
=HTTP_Internal_Server_Error
)
1112 old_of_controller
= self
.show_of_controller(of_id
)
1114 if old_of_controller
:
1115 result
, content
= self
.db
.update_rows('ofcs', ofc_data
, WHERE
={'uuid': of_id
}, log
=False)
1119 raise ovimException("Error uptating OF contorller with uuid {}".format(of_id
),
1122 raise ovimException("Error uptating OF contorller with uuid {}".format(of_id
),
1123 http_code
=HTTP_Internal_Server_Error
)
1125 def delete_of_controller(self
, of_id
):
1127 Delete an openflow controller from DB.
1128 :param of_id: openflow controller dpid
1132 ofc
= self
.show_of_controller(of_id
)
1134 result
, content
= self
.db
.delete_row("ofcs", of_id
)
1136 raise ovimException("Cannot delete ofc from database: {}".format(content
), http_code
=-result
)
1138 raise ovimException("ofc {} not found ".format(content
), http_code
=HTTP_Not_Found
)
1140 ofc_thread
= self
.config
['ofcs_thread'][of_id
]
1141 del self
.config
['ofcs_thread'][of_id
]
1142 for ofc_th
in self
.config
['ofcs_thread_dpid']:
1143 if ofc
['dpid'] in ofc_th
:
1144 self
.config
['ofcs_thread_dpid'].remove(ofc_th
)
1146 ofc_thread
.insert_task("exit")
1151 def show_of_controller(self
, uuid
):
1153 Show an openflow controller by dpid from DB.
1154 :param db_filter: List with where query parameters
1158 result
, content
= self
.db
.get_table(FROM
='ofcs', WHERE
={"uuid": uuid
}, LIMIT
=100)
1161 raise ovimException("Openflow controller with uuid '{}' not found".format(uuid
),
1162 http_code
=HTTP_Not_Found
)
1164 raise ovimException("Openflow controller with uuid '{}' error".format(uuid
),
1165 http_code
=HTTP_Internal_Server_Error
)
1168 def get_of_controllers(self
, columns
=None, db_filter
={}, limit
=None):
1170 Show an openflow controllers from DB.
1171 :param columns: List with SELECT query parameters
1172 :param db_filter: List with where query parameters
1173 :param limit: result Limit
1176 result
, content
= self
.db
.get_table(SELECT
=columns
, FROM
='ofcs', WHERE
=db_filter
, LIMIT
=limit
)
1179 raise ovimException(str(content
), -result
)
1183 def get_tenants(self
, columns
=None, db_filter
={}, limit
=None):
1185 Retrieve tenant list from DB
1186 :param columns: List with SELECT query parameters
1187 :param db_filter: List with where query parameters
1188 :param limit: result limit
1191 result
, content
= self
.db
.get_table(FROM
='tenants', SELECT
=columns
, WHERE
=db_filter
, LIMIT
=limit
)
1193 raise ovimException('get_tenatns Error {}'.format(str(content
)), -result
)
1195 convert_boolean(content
, ('enabled',))
1198 def show_tenant_id(self
, tenant_id
):
1200 Get tenant from DB by id
1201 :param tenant_id: tenant id
1204 result
, content
= self
.db
.get_table(FROM
='tenants', SELECT
=('uuid', 'name', 'description', 'enabled'),
1205 WHERE
={"uuid": tenant_id
})
1207 raise ovimException(str(content
), -result
)
1209 raise ovimException("tenant with uuid='{}' not found".format(tenant_id
), HTTP_Not_Found
)
1211 convert_boolean(content
, ('enabled',))
1214 def new_tentant(self
, tenant
):
1216 Create a tenant and store in DB
1217 :param tenant: Dictionary with tenant data
1218 :return: the uuid of created tenant. Raise exception upon error
1221 # insert in data base
1222 result
, tenant_uuid
= self
.db
.new_tenant(tenant
)
1227 raise ovimException(str(tenant_uuid
), -result
)
1229 def delete_tentant(self
, tenant_id
):
1231 Delete a tenant from the database.
1232 :param tenant_id: Tenant id
1233 :return: delete tenant id
1237 r
, tenants_flavors
= self
.db
.get_table(FROM
='tenants_flavors', SELECT
=('flavor_id', 'tenant_id'),
1238 WHERE
={'tenant_id': tenant_id
})
1240 tenants_flavors
= ()
1241 r
, tenants_images
= self
.db
.get_table(FROM
='tenants_images', SELECT
=('image_id', 'tenant_id'),
1242 WHERE
={'tenant_id': tenant_id
})
1246 result
, content
= self
.db
.delete_row('tenants', tenant_id
)
1248 raise ovimException("tenant '%s' not found" % tenant_id
, HTTP_Not_Found
)
1250 for flavor
in tenants_flavors
:
1251 self
.db
.delete_row_by_key("flavors", "uuid", flavor
['flavor_id'])
1252 for image
in tenants_images
:
1253 self
.db
.delete_row_by_key("images", "uuid", image
['image_id'])
1256 raise ovimException("Error deleting tenant '%s' " % tenant_id
, HTTP_Internal_Server_Error
)
1258 def edit_tenant(self
, tenant_id
, tenant_data
):
1260 Update a tenant data identified by tenant id
1261 :param tenant_id: tenant id
1262 :param tenant_data: Dictionary with tenant data
1266 # Look for the previous data
1267 result
, tenant_data_old
= self
.db
.get_table(FROM
='tenants', WHERE
={'uuid': tenant_id
})
1269 raise ovimException("Error updating tenant with uuid='{}': {}".format(tenant_id
, tenant_data_old
),
1270 HTTP_Internal_Server_Error
)
1272 raise ovimException("tenant with uuid='{}' not found".format(tenant_id
), HTTP_Not_Found
)
1274 # insert in data base
1275 result
, content
= self
.db
.update_rows('tenants', tenant_data
, WHERE
={'uuid': tenant_id
}, log
=True)
1279 raise ovimException(str(content
), -result
)
1281 def set_of_port_mapping(self
, of_maps
, ofc_id
=None, switch_dpid
=None, region
=None):
1283 Create new port mapping entry
1284 :param of_maps: List with port mapping information
1285 # maps =[{"ofc_id": <ofc_id>,"region": datacenter region,"compute_node": compute uuid,"pci": pci adress,
1286 "switch_dpid": swith dpid,"switch_port": port name,"switch_mac": mac}]
1287 :param ofc_id: ofc id
1288 :param switch_dpid: switch dpid
1289 :param region: datacenter region id
1295 map['ofc_id'] = ofc_id
1297 map['switch_dpid'] = switch_dpid
1299 map['region'] = region
1301 for of_map
in of_maps
:
1302 result
, uuid
= self
.db
.new_row('of_port_mappings', of_map
, True)
1304 of_map
["uuid"] = uuid
1306 raise ovimException(str(uuid
), -result
)
1309 def clear_of_port_mapping(self
, db_filter
={}):
1311 Clear port mapping filtering using db_filter dict
1312 :param db_filter: Parameter to filter during remove process
1315 result
, content
= self
.db
.delete_row_by_dict(FROM
='of_port_mappings', WHERE
=db_filter
)
1320 raise ovimException("Error deleting of_port_mappings with filter='{}'".format(str(db_filter
)),
1321 HTTP_Internal_Server_Error
)
1323 def get_of_port_mappings(self
, column
=None, db_filter
=None, db_limit
=None):
1325 Retrive port mapping from DB
1330 result
, content
= self
.db
.get_table(SELECT
=column
, WHERE
=db_filter
, FROM
='of_port_mappings', LIMIT
=db_limit
)
1333 self
.logger
.error("get_of_port_mappings Error %d %s", result
, content
)
1334 raise ovimException(str(content
), -result
)
1338 def get_dhcp_controller(self
):
1340 Create an host_thread object for manage openvim controller and not create a thread for itself
1341 :return: dhcp_host openvim controller object
1344 if 'openvim_controller' in self
.config
['host_threads']:
1345 return self
.config
['host_threads']['openvim_controller']
1348 controller_ip
= self
.config
['ovs_controller_ip']
1349 ovs_controller_user
= self
.config
['ovs_controller_user']
1351 host_test_mode
= True if self
.config
['mode'] == 'test' or self
.config
['mode'] == "OF only" else False
1352 host_develop_mode
= True if self
.config
['mode'] == 'development' else False
1354 dhcp_host
= ht
.host_thread(name
='openvim_controller', user
=ovs_controller_user
, host
=controller_ip
,
1355 db
=self
.config
["db"], db_lock
=self
.config
["db_lock"], test
=host_test_mode
,
1356 image_path
=self
.config
['image_path'], version
=self
.config
['version'],
1357 host_id
='openvim_controller', develop_mode
=host_develop_mode
,
1358 develop_bridge_iface
=bridge_ifaces
,
1359 logger_name
=self
.logger_name
+ ".host.controller",
1360 debug
=self
.config
.get('log_level_host'))
1362 self
.config
['host_threads']['openvim_controller'] = dhcp_host
1363 if not host_test_mode
:
1364 dhcp_host
.ssh_connect()
1367 def launch_dhcp_server(self
, vlan
, first_ip
, last_ip
, cidr
, gateway
):
1369 Launch a dhcpserver base on dnsmasq attached to the net base on vlan id across the the openvim computes
1370 :param vlan: vlan identifier
1371 :param first_ip: First dhcp range ip
1372 :param last_ip: Last dhcp range ip
1373 :param cidr: net cidr
1374 :param gateway: net gateway
1377 ip_tools
= IPNetwork(cidr
)
1378 dhcp_netmask
= str(ip_tools
.netmask
)
1379 ip_range
= [first_ip
, last_ip
]
1381 dhcp_path
= self
.config
['ovs_controller_file_path']
1383 controller_host
= self
.get_dhcp_controller()
1384 controller_host
.create_linux_bridge(vlan
)
1385 controller_host
.create_dhcp_interfaces(vlan
, first_ip
, dhcp_netmask
)
1386 controller_host
.launch_dhcp_server(vlan
, ip_range
, dhcp_netmask
, dhcp_path
, gateway
)
1388 if __name__
== "__main__":
1390 parser
= argparse
.ArgumentParser()
1391 parser
.add_argument("-v","--version", help="show ovim library version", action
="store_true")
1392 parser
.add_argument("--database-version", help="show required database version", action
="store_true")
1393 args
= parser
.parse_args()
1395 print ('openvimd version {} {}'.format(ovim
.get_version(), ovim
.get_version_date()))
1396 print ('(c) Copyright Telefonica')
1397 elif args
.database_version
:
1398 print ('required database version: {}'.format(ovim
.get_database_version()))