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.17-r533"
46 version_date
= "Jun 2017"
47 database_version
= 20 #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
[3])
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
[2])
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
195 # Create one thread for each host
196 host_test_mode
= True if self
.config
['mode'] == 'test' or self
.config
['mode'] == "OF only" else False
197 host_develop_mode
= True if self
.config
['mode'] == 'development' else False
198 host_develop_bridge_iface
= self
.config
.get('development_bridge', None)
200 # get host list from data base before starting threads
201 r
, hosts
= self
.db
.get_table(SELECT
=('name', 'ip_name', 'user', 'uuid', 'password', 'keyfile'),
202 FROM
='hosts', WHERE
={'status': 'ok'})
204 raise ovimException("Cannot get hosts from database {}".format(hosts
))
206 self
.config
['host_threads'] = {}
209 thread
= ht
.host_thread(name
=host
['name'], user
=host
['user'], host
=host
['ip_name'], db
=self
.config
["db"],
210 password
=host
['password'],
211 keyfile
=host
.get('keyfile', self
.config
["host_ssh_keyfile"]),
212 db_lock
=self
.config
["db_lock"], test
=host_test_mode
,
213 image_path
=self
.config
['host_image_path'],
214 version
=self
.config
['version'], host_id
=host
['uuid'],
215 develop_mode
=host_develop_mode
,
216 develop_bridge_iface
=host_develop_bridge_iface
,
217 logger_name
=self
.logger_name
+ ".host." + host
['name'],
218 debug
=self
.config
.get('log_level_host'))
221 thread
.check_connectivity()
222 except Exception as e
:
223 self
.logger
.critical('Error detected for compute = {} with ip = {}'
224 .format(host
['name'], host
['ip_name']))
226 self
.config
['host_threads'][host
['uuid']] = thread
228 # precreate interfaces; [bridge:<host_bridge_name>, VLAN used at Host, uuid of network camping in this bridge,
231 self
.config
['dhcp_nets'] = []
232 self
.config
['bridge_nets'] = []
233 for bridge
, vlan_speed
in self
.config
["bridge_ifaces"].items():
234 # skip 'development_bridge'
235 if self
.config
['mode'] == 'development' and self
.config
['development_bridge'] == bridge
:
237 self
.config
['bridge_nets'].append([bridge
, vlan_speed
[0], vlan_speed
[1], None])
239 # check if this bridge is already used (present at database) for a network)
240 used_bridge_nets
= []
241 for brnet
in self
.config
['bridge_nets']:
242 r
, nets
= self
.db
.get_table(SELECT
=('uuid',), FROM
='nets', WHERE
={'provider': "bridge:" + brnet
[0]})
244 brnet
[3] = nets
[0]['uuid']
245 used_bridge_nets
.append(brnet
[0])
246 if self
.config
.get("dhcp_server"):
247 if brnet
[0] in self
.config
["dhcp_server"]["bridge_ifaces"]:
248 self
.config
['dhcp_nets'].append(nets
[0]['uuid'])
249 if len(used_bridge_nets
) > 0:
250 self
.logger
.info("found used bridge nets: " + ",".join(used_bridge_nets
))
251 # get nets used by dhcp
252 if self
.config
.get("dhcp_server"):
253 for net
in self
.config
["dhcp_server"].get("nets", ()):
254 r
, nets
= self
.db
.get_table(SELECT
=('uuid',), FROM
='nets', WHERE
={'name': net
})
256 self
.config
['dhcp_nets'].append(nets
[0]['uuid'])
259 self
._start
_ofc
_default
_task
()
261 # OFC per tenant in DB
262 self
._start
_of
_db
_tasks
()
264 # create dhcp_server thread
265 host_test_mode
= True if self
.config
['mode'] == 'test' or self
.config
['mode'] == "OF only" else False
266 dhcp_params
= self
.config
.get("dhcp_server")
268 thread
= dt
.dhcp_thread(dhcp_params
=dhcp_params
, test
=host_test_mode
, dhcp_nets
=self
.config
["dhcp_nets"],
269 db
=self
.config
["db"], db_lock
=self
.config
["db_lock"],
270 logger_name
=self
.logger_name
+ ".dhcp",
271 debug
=self
.config
.get('log_level_of'))
273 self
.config
['dhcp_thread'] = thread
277 # create ovs dhcp thread
278 result
, content
= self
.db
.get_table(FROM
='nets')
280 self
.logger
.error("http_get_ports Error %d %s", result
, content
)
281 raise ovimException(str(content
), -result
)
284 net_type
= net
['type']
285 if (net_type
== 'bridge_data' or net_type
== 'bridge_man') and \
286 net
["provider"][:4] == 'OVS:' and net
["enable_dhcp"] == "true":
288 self
.launch_dhcp_server(net
['vlan'],
289 net
['dhcp_first_ip'],
293 except Exception as e
:
294 self
.logger
.error("Fail at launching dhcp server for net_id='%s' net_name='%s': %s",
295 net
["uuid"], net
["name"], str(e
))
296 self
.db
.update_rows("nets", {"status": "ERROR",
297 "last_error": "Fail at launching dhcp server: " + str(e
)},
298 {"uuid": net
["uuid"]})
300 def _start_of_db_tasks(self
):
302 Start ofc task for existing ofcs in database
307 ofcs
= self
.get_of_controllers()
310 of_conn
= self
._load
_of
_module
(ofc
)
311 # create ofc thread per of controller
312 self
._create
_ofc
_task
(ofc
['uuid'], ofc
['dpid'], of_conn
)
314 def _create_ofc_task(self
, ofc_uuid
, dpid
, of_conn
):
316 Create an ofc thread for handle each sdn controllers
317 :param ofc_uuid: sdn controller uuid
318 :param dpid: sdn controller dpid
319 :param of_conn: OF_conn module
322 if 'ofcs_thread' not in self
.config
and 'ofcs_thread_dpid' not in self
.config
:
324 ofcs_thread_dpid
= []
326 ofcs_threads
= self
.config
['ofcs_thread']
327 ofcs_thread_dpid
= self
.config
['ofcs_thread_dpid']
329 if ofc_uuid
not in ofcs_threads
:
330 ofc_thread
= self
._create
_ofc
_thread
(of_conn
, ofc_uuid
)
331 if ofc_uuid
== "Default":
332 self
.config
['of_thread'] = ofc_thread
334 ofcs_threads
[ofc_uuid
] = ofc_thread
335 self
.config
['ofcs_thread'] = ofcs_threads
337 ofcs_thread_dpid
.append({dpid
: ofc_thread
})
338 self
.config
['ofcs_thread_dpid'] = ofcs_thread_dpid
340 def _start_ofc_default_task(self
):
342 Create default ofc thread
344 if 'of_controller' not in self
.config \
345 and 'of_controller_ip' not in self
.config \
346 and 'of_controller_port' not in self
.config \
347 and 'of_controller_dpid' not in self
.config
:
352 db_config
['ip'] = self
.config
.get('of_controller_ip')
353 db_config
['port'] = self
.config
.get('of_controller_port')
354 db_config
['dpid'] = self
.config
.get('of_controller_dpid')
355 db_config
['type'] = self
.config
.get('of_controller')
356 db_config
['user'] = self
.config
.get('of_user')
357 db_config
['password'] = self
.config
.get('of_password')
359 # create connector to the openflow controller
360 # load other parameters starting by of_ from config dict in a temporal dict
362 of_conn
= self
._load
_of
_module
(db_config
)
363 # create openflow thread
364 self
._create
_ofc
_task
("Default", db_config
['dpid'], of_conn
)
366 def _load_of_module(self
, db_config
):
368 import python module for each SDN controller supported
369 :param db_config: SDN dn information
373 raise ovimException("No module found it", HTTP_Internal_Server_Error
)
378 if self
.of_test_mode
:
379 return openflow_conn
.OfTestConnector({"name": db_config
['type'],
380 "dpid": db_config
['dpid'],
381 "of_debug": self
.config
['log_level_of']})
385 temp_dict
['of_ip'] = db_config
['ip']
386 temp_dict
['of_port'] = db_config
['port']
387 temp_dict
['of_dpid'] = db_config
['dpid']
388 temp_dict
['of_controller'] = db_config
['type']
389 temp_dict
['of_user'] = db_config
.get('user')
390 temp_dict
['of_password'] = db_config
.get('password')
392 temp_dict
['of_debug'] = self
.config
['log_level_of']
394 if temp_dict
['of_controller'] == 'opendaylight':
397 module
= temp_dict
['of_controller']
399 if module
not in ovim
.of_module
:
401 pkg
= __import__("osm_openvim." + module
)
402 of_conn_module
= getattr(pkg
, module
)
403 ovim
.of_module
[module
] = of_conn_module
404 self
.logger
.debug("Module load from {}".format("osm_openvim." + module
))
405 except Exception as e
:
406 self
.logger
.error("Cannot open openflow controller module of type '%s'", module
)
407 raise ovimException("Cannot open openflow controller of type module '{}'"
408 "Revise it is installed".format(module
),
409 HTTP_Internal_Server_Error
)
411 of_conn_module
= ovim
.of_module
[module
]
412 return of_conn_module
.OF_conn(temp_dict
)
413 except Exception as e
:
414 self
.logger
.error("Cannot open the Openflow controller '%s': %s", type(e
).__name
__, str(e
))
415 raise ovimException("Cannot open the Openflow controller '{}': '{}'".format(type(e
).__name
__, str(e
)),
416 HTTP_Internal_Server_Error
)
418 def _create_ofc_thread(self
, of_conn
, ofc_uuid
="Default"):
420 Create and launch a of thread
423 # create openflow thread
425 #if 'of_controller_nets_with_same_vlan' in self.config:
426 # ofc_net_same_vlan = self.config['of_controller_nets_with_same_vlan']
428 # ofc_net_same_vlan = False
429 ofc_net_same_vlan
= False
431 thread
= oft
.openflow_thread(ofc_uuid
, of_conn
, of_test
=self
.of_test_mode
, db
=self
.config
["db"],
432 db_lock
=self
.config
["db_lock"],
433 pmp_with_same_vlan
=ofc_net_same_vlan
,
434 logger_name
=self
.logger_name
+ ".ofc." + ofc_uuid
,
435 debug
=self
.config
.get('log_level_of'))
436 #r, c = thread.OF_connector.obtain_port_correspondence()
438 # raise ovimException("Cannot get openflow information %s", c)
442 def stop_service(self
):
443 threads
= self
.config
.get('host_threads', {})
444 if 'of_thread' in self
.config
:
445 threads
['of'] = (self
.config
['of_thread'])
446 if 'ofcs_thread' in self
.config
:
447 ofcs_thread
= self
.config
['ofcs_thread']
448 for ofc
in ofcs_thread
:
449 threads
[ofc
] = ofcs_thread
[ofc
]
451 if 'dhcp_thread' in self
.config
:
452 threads
['dhcp'] = (self
.config
['dhcp_thread'])
454 for thread_id
, thread
in threads
.items():
455 if thread_id
== 'openvim_controller':
457 thread
.insert_task("exit")
458 for thread_id
, thread
in threads
.items():
459 if thread_id
== 'openvim_controller':
463 def get_networks(self
, columns
=None, db_filter
={}, limit
=None):
465 Retreive networks available
466 :param columns: List with select query parameters
467 :param db_filter: List with where query parameters
468 :param limit: Query limit result
471 result
, content
= self
.db
.get_table(SELECT
=columns
, FROM
='nets', WHERE
=db_filter
, LIMIT
=limit
)
474 raise ovimException(str(content
), -result
)
476 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
480 def show_network(self
, network_id
, db_filter
={}):
482 Get network from DB by id
483 :param network_id: net Id
484 :param db_filter: List with where query parameters
489 raise ovimException("Not network id was not found")
490 db_filter
['uuid'] = network_id
492 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
=db_filter
, LIMIT
=100)
495 raise ovimException(str(content
), -result
)
497 raise ovimException("show_network network '%s' not found" % network_id
, -result
)
499 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
501 result
, ports
= self
.db
.get_table(FROM
='ports', SELECT
=('uuid as port_id',),
502 WHERE
={'net_id': network_id
}, LIMIT
=100)
504 content
[0]['ports'] = ports
506 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
509 def new_network(self
, network
):
514 tenant_id
= network
.get('tenant_id')
517 result
, _
= self
.db
.get_table(FROM
='tenants', SELECT
=('uuid',), WHERE
={'uuid': tenant_id
, "enabled": True})
519 raise ovimException("set_network error, no tenant founded", -result
)
523 net_provider
= network
.get('provider')
524 net_type
= network
.get('type')
525 net_vlan
= network
.get("vlan")
526 net_bind_net
= network
.get("bind_net")
527 net_bind_type
= network
.get("bind_type")
528 net_region
= network
.get("region")
529 name
= network
["name"]
531 # check if network name ends with :<vlan_tag> and network exist in order to make and automated bindning
532 vlan_index
= name
.rfind(":")
533 if not net_bind_net
and not net_bind_type
and vlan_index
> 1:
535 vlan_tag
= int(name
[vlan_index
+ 1:])
536 if not vlan_tag
and vlan_tag
< 4096:
537 net_bind_net
= name
[:vlan_index
]
538 net_bind_type
= "vlan:" + name
[vlan_index
+ 1:]
543 # look for a valid net
544 if self
._check
_valid
_uuid
(net_bind_net
):
545 net_bind_key
= "uuid"
547 net_bind_key
= "name"
548 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
={net_bind_key
: net_bind_net
})
550 raise ovimException(' getting nets from db ' + content
, HTTP_Internal_Server_Error
)
552 raise ovimException(" bind_net %s '%s'not found" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
554 raise ovimException(" more than one bind_net %s '%s' found, use uuid" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
555 network
["bind_net"] = content
[0]["uuid"]
558 if net_bind_type
[0:5] != "vlan:":
559 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>'", HTTP_Bad_Request
)
560 if int(net_bind_type
[5:]) > 4095 or int(net_bind_type
[5:]) <= 0:
561 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>' with a tag between 1 and 4095",
563 network
["bind_type"] = net_bind_type
566 if net_provider
[:9] == "openflow:":
568 if net_type
!= "ptp" and net_type
!= "data":
569 raise ovimException(" only 'ptp' or 'data' net types can be bound to 'openflow'",
575 if net_type
!= "bridge_man" and net_type
!= "bridge_data":
576 raise ovimException("Only 'bridge_man' or 'bridge_data' net types can be bound "
577 "to 'bridge', 'macvtap' or 'default", HTTP_Bad_Request
)
579 net_type
= 'bridge_man'
582 net_type
= 'bridge_man'
585 if net_provider
[:7] == 'bridge:':
586 # check it is one of the pre-provisioned bridges
587 bridge_net_name
= net_provider
[7:]
588 for brnet
in self
.config
['bridge_nets']:
589 if brnet
[0] == bridge_net_name
: # free
591 raise ovimException("invalid 'provider:physical', "
592 "bridge '%s' is already used" % bridge_net_name
, HTTP_Conflict
)
596 # if bridge_net==None:
597 # bottle.abort(HTTP_Bad_Request, "invalid 'provider:physical', bridge '%s' is not one of the
598 # provisioned 'bridge_ifaces' in the configuration file" % bridge_net_name)
601 elif self
.config
['network_type'] == 'bridge' and (net_type
== 'bridge_data' or net_type
== 'bridge_man'):
602 # look for a free precreated nets
603 for brnet
in self
.config
['bridge_nets']:
604 if not brnet
[3]: # free
606 if net_type
== 'bridge_man': # look for the smaller speed
607 if brnet
[2] < bridge_net
[2]:
609 else: # look for the larger speed
610 if brnet
[2] > bridge_net
[2]:
616 raise ovimException("Max limits of bridge networks reached. Future versions of VIM "
617 "will overcome this limit", HTTP_Bad_Request
)
619 self
.logger
.debug("using net " + bridge_net
)
620 net_provider
= "bridge:" + bridge_net
[0]
621 net_vlan
= bridge_net
[1]
622 elif net_type
== 'bridge_data' or net_type
== 'bridge_man' and self
.config
['network_type'] == 'ovs':
625 if net_type
== "data" or net_type
== "ptp":
626 net_region
= "__DATA__"
627 elif net_provider
== "OVS":
628 net_region
= "__OVS__"
629 if not net_vlan
and (net_type
== "data" or net_type
== "ptp" or net_provider
== "OVS"):
630 net_vlan
= self
.db
.get_free_net_vlan(net_region
)
632 raise ovimException("Error getting an available vlan", HTTP_Internal_Server_Error
)
633 if net_provider
== 'OVS':
634 net_provider
= 'OVS' + ":" + str(net_vlan
)
636 network
['provider'] = net_provider
637 network
['type'] = net_type
638 network
['vlan'] = net_vlan
639 network
['region'] = net_region
640 dhcp_integrity
= True
641 if 'enable_dhcp' in network
and network
['enable_dhcp']:
642 dhcp_integrity
= self
._check
_dhcp
_data
_integrity
(network
)
644 result
, content
= self
.db
.new_row('nets', network
, True, True)
646 if result
>= 0 and dhcp_integrity
:
648 bridge_net
[3] = content
649 if self
.config
.get("dhcp_server") and self
.config
['network_type'] == 'bridge':
650 if network
["name"] in self
.config
["dhcp_server"].get("nets", ()):
651 self
.config
["dhcp_nets"].append(content
)
652 self
.logger
.debug("dhcp_server: add new net", content
)
653 elif bridge_net
and bridge_net
[0] in self
.config
["dhcp_server"].get("bridge_ifaces", ()):
654 self
.config
["dhcp_nets"].append(content
)
655 self
.logger
.debug("dhcp_server: add new net", content
, content
)
658 raise ovimException("Error posting network", HTTP_Internal_Server_Error
)
659 # TODO kei change update->edit
661 def edit_network(self
, network_id
, network
):
663 Update entwork data byt id
666 # Look for the previous data
667 where_
= {'uuid': network_id
}
668 result
, network_old
= self
.db
.get_table(FROM
='nets', WHERE
=where_
)
670 raise ovimException("Error updating network %s" % network_old
, HTTP_Internal_Server_Error
)
672 raise ovimException('network %s not found' % network_id
, HTTP_Not_Found
)
674 nbports
, content
= self
.db
.get_table(FROM
='ports', SELECT
=('uuid as port_id',),
675 WHERE
={'net_id': network_id
}, LIMIT
=100)
677 raise ovimException("http_put_network_id error %d %s" % (result
, network_old
), HTTP_Internal_Server_Error
)
679 if 'type' in network
and network
['type'] != network_old
[0]['type']:
680 raise ovimException("Can not change type of network while having ports attached",
681 HTTP_Method_Not_Allowed
)
682 if 'vlan' in network
and network
['vlan'] != network_old
[0]['vlan']:
683 raise ovimException("Can not change vlan of network while having ports attached",
684 HTTP_Method_Not_Allowed
)
687 net_provider
= network
.get('provider', network_old
[0]['provider'])
688 net_type
= network
.get('type', network_old
[0]['type'])
689 net_bind_net
= network
.get("bind_net")
690 net_bind_type
= network
.get("bind_type")
692 # look for a valid net
693 if self
._check
_valid
_uuid
(net_bind_net
):
694 net_bind_key
= "uuid"
696 net_bind_key
= "name"
697 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
={net_bind_key
: net_bind_net
})
699 raise ovimException('Getting nets from db ' + content
, HTTP_Internal_Server_Error
)
701 raise ovimException("bind_net %s '%s'not found" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
703 raise ovimException("More than one bind_net %s '%s' found, use uuid" % (net_bind_key
, net_bind_net
),
705 network
["bind_net"] = content
[0]["uuid"]
707 if net_bind_type
[0:5] != "vlan:":
708 raise ovimException("Bad format for 'bind_type', must be 'vlan:<tag>'", HTTP_Bad_Request
)
709 if int(net_bind_type
[5:]) > 4095 or int(net_bind_type
[5:]) <= 0:
710 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>' with a tag between 1 and 4095",
713 if net_provider
[:9] == "openflow:":
714 if net_type
!= "ptp" and net_type
!= "data":
715 raise ovimException("Only 'ptp' or 'data' net types can be bound to 'openflow'", HTTP_Bad_Request
)
717 if net_type
!= "bridge_man" and net_type
!= "bridge_data":
718 raise ovimException("Only 'bridge_man' or 'bridge_data' net types can be bound to "
719 "'bridge', 'macvtap' or 'default", HTTP_Bad_Request
)
721 # insert in data base
722 result
, content
= self
.db
.update_rows('nets', network
, WHERE
={'uuid': network_id
}, log
=True)
724 # if result > 0 and nbports>0 and 'admin_state_up' in network
725 # and network['admin_state_up'] != network_old[0]['admin_state_up']:
730 self
.net_update_ofc_thread(network_id
)
731 except ovimException
as e
:
732 raise ovimException("Error while launching openflow rules in network '{}' {}"
733 .format(network_id
, str(e
)), HTTP_Internal_Server_Error
)
734 except Exception as e
:
735 raise ovimException("Error while launching openflow rules in network '{}' {}"
736 .format(network_id
, str(e
)), HTTP_Internal_Server_Error
)
738 if self
.config
.get("dhcp_server"):
739 if network_id
in self
.config
["dhcp_nets"]:
740 self
.config
["dhcp_nets"].remove(network_id
)
741 if network
.get("name", network_old
[0]["name"]) in self
.config
["dhcp_server"].get("nets", ()):
742 self
.config
["dhcp_nets"].append(network_id
)
744 net_bind
= network
.get("bind_type", network_old
[0]["bind_type"])
745 if net_bind
and net_bind
and net_bind
[:7] == "bridge:" and net_bind
[7:] in self
.config
["dhcp_server"].get(
746 "bridge_ifaces", ()):
747 self
.config
["dhcp_nets"].append(network_id
)
750 raise ovimException(content
, -result
)
752 def delete_network(self
, network_id
):
754 Delete network by network id
755 :param network_id: network id
759 # delete from the data base
760 result
, content
= self
.db
.delete_row('nets', network_id
)
763 raise ovimException("Network %s not found " % network_id
, HTTP_Not_Found
)
765 for brnet
in self
.config
['bridge_nets']:
766 if brnet
[3] == network_id
:
769 if self
.config
.get("dhcp_server") and network_id
in self
.config
["dhcp_nets"]:
770 self
.config
["dhcp_nets"].remove(network_id
)
773 raise ovimException("Error deleting network '{}': {}".format(network_id
, content
), -result
)
775 def get_openflow_rules(self
, network_id
=None):
777 Get openflow id from DB
778 :param network_id: Network id, if none all networks will be retrieved
779 :return: Return a list with Openflow rules per net
785 where_
= {"net_id": network_id
}
786 result
, content
= self
.db
.get_table(
787 SELECT
=("name", "net_id", "ofc_id", "priority", "vlan_id", "ingress_port", "src_mac", "dst_mac", "actions"),
788 WHERE
=where_
, FROM
='of_flows')
791 raise ovimException(str(content
), -result
)
794 def edit_openflow_rules(self
, network_id
=None):
797 To make actions over the net. The action is to reinstall the openflow rules
798 network_id can be 'all'
799 :param network_id: Network id, if none all networks will be retrieved
800 :return : Number of nets updated
807 where_
= {"uuid": network_id
}
808 result
, content
= self
.db
.get_table(SELECT
=("uuid", "type"), WHERE
=where_
, FROM
='nets')
811 raise ovimException(str(content
), -result
)
814 if net
["type"] != "ptp" and net
["type"] != "data":
819 self
.net_update_ofc_thread(net
['uuid'])
820 except ovimException
as e
:
821 raise ovimException("Error updating network'{}' {}".format(net
['uuid'], str(e
)),
822 HTTP_Internal_Server_Error
)
823 except Exception as e
:
824 raise ovimException("Error updating network '{}' {}".format(net
['uuid'], str(e
)),
825 HTTP_Internal_Server_Error
)
829 def delete_openflow_rules(self
, ofc_id
=None):
831 To make actions over the net. The action is to delete ALL openflow rules
832 :return: return operation result
836 if 'Default' in self
.config
['ofcs_thread']:
837 r
, c
= self
.config
['ofcs_thread']['Default'].insert_task("clear-all")
839 raise ovimException("Default Openflow controller not not running", HTTP_Not_Found
)
841 elif ofc_id
in self
.config
['ofcs_thread']:
842 r
, c
= self
.config
['ofcs_thread'][ofc_id
].insert_task("clear-all")
846 raise ovimException(str(c
), -r
)
848 raise ovimException("Openflow controller not found with ofc_id={}".format(ofc_id
), HTTP_Not_Found
)
851 def get_openflow_ports(self
, ofc_id
=None):
853 Obtain switch ports names of openflow controller
854 :return: Return flow ports in DB
857 if 'Default' in self
.config
['ofcs_thread']:
858 conn
= self
.config
['ofcs_thread']['Default'].OF_connector
860 raise ovimException("Default Openflow controller not not running", HTTP_Not_Found
)
862 elif ofc_id
in self
.config
['ofcs_thread']:
863 conn
= self
.config
['ofcs_thread'][ofc_id
].OF_connector
865 raise ovimException("Openflow controller not found with ofc_id={}".format(ofc_id
), HTTP_Not_Found
)
868 def get_ports(self
, columns
=None, filter={}, limit
=None):
869 # result, content = my.db.get_ports(where_)
870 result
, content
= self
.db
.get_table(SELECT
=columns
, WHERE
=filter, FROM
='ports', LIMIT
=limit
)
872 self
.logger
.error("http_get_ports Error %d %s", result
, content
)
873 raise ovimException(str(content
), -result
)
875 convert_boolean(content
, ('admin_state_up',))
878 def new_port(self
, port_data
):
879 port_data
['type'] = 'external'
880 if port_data
.get('net_id'):
881 # check that new net has the correct type
882 result
, new_net
= self
.db
.check_target_net(port_data
['net_id'], None, 'external')
884 raise ovimException(str(new_net
), -result
)
885 # insert in data base
886 result
, uuid
= self
.db
.new_row('ports', port_data
, True, True)
888 if 'net_id' in port_data
:
890 self
.net_update_ofc_thread(port_data
['net_id'])
891 except ovimException
as e
:
892 raise ovimException("Cannot insert a task for updating network '{}' {}"
893 .format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
894 except Exception as e
:
895 raise ovimException("Cannot insert a task for updating network '{}' {}"
896 .format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
900 raise ovimException(str(uuid
), -result
)
902 def new_external_port(self
, port_data
):
904 Create new external port and check port mapping correspondence
905 :param port_data: port_data = {
906 'region': 'datacenter region',
907 'compute_node': 'compute node id',
908 'pci': 'pci port address',
911 'tenant_id': 'tenant id',
914 'ip_address': 'ip address - optional'}
918 port_data
['type'] = 'external'
920 if port_data
.get('net_id'):
921 # check that new net has the correct type
922 result
, new_net
= self
.db
.check_target_net(port_data
['net_id'], None, 'external')
924 raise ovimException(str(new_net
), -result
)
925 # insert in data base
928 if port_data
.get('region'):
929 db_filter
['region'] = port_data
['region']
930 if port_data
.get('pci'):
931 db_filter
['pci'] = port_data
['pci']
932 if port_data
.get('compute_node'):
933 db_filter
['compute_node'] = port_data
['compute_node']
935 columns
= ['ofc_id', 'switch_dpid', 'switch_port', 'switch_mac', 'pci']
936 port_mapping_data
= self
.get_of_port_mappings(columns
, db_filter
)
938 if not len(port_mapping_data
):
939 raise ovimException("No port mapping founded for '{}'".format(str(db_filter
)),
941 elif len(port_mapping_data
) > 1:
942 raise ovimException("Wrong port data was given, please check pci, region & compute id data",
945 port_data
['ofc_id'] = port_mapping_data
[0]['ofc_id']
946 port_data
['switch_dpid'] = port_mapping_data
[0]['switch_dpid']
947 port_data
['switch_port'] = port_mapping_data
[0]['switch_port']
948 port_data
['switch_mac'] = port_mapping_data
[0]['switch_mac']
950 # remove from compute_node, region and pci of_port_data to adapt to 'ports' structure
951 if 'region' in port_data
:
952 del port_data
['region']
953 if 'pci' in port_data
:
955 if 'compute_node' in port_data
:
956 del port_data
['compute_node']
958 result
, uuid
= self
.db
.new_row('ports', port_data
, True, True)
961 self
.net_update_ofc_thread(port_data
['net_id'], port_data
['ofc_id'])
962 except ovimException
as e
:
963 raise ovimException("Cannot insert a task for updating network '{}' {}".
964 format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
965 except Exception as e
:
966 raise ovimException("Cannot insert a task for updating network '{}' {}"
967 .format(port_data
['net_id'], e
), HTTP_Internal_Server_Error
)
970 raise ovimException(str(uuid
), -result
)
972 def net_update_ofc_thread(self
, net_id
, ofc_id
=None, switch_dpid
=None):
974 Insert a update net task by net id or ofc_id for each ofc thread
975 :param net_id: network id
976 :param ofc_id: openflow controller id
977 :param switch_dpid: switch dpid
981 raise ovimException("No net_id received", HTTP_Internal_Server_Error
)
984 c
= 'No valid ofc_id or switch_dpid received'
987 ports
= self
.get_ports(filter={"net_id": net_id
})
989 port_ofc_id
= port
.get('ofc_id', None)
991 ofc_id
= port
['ofc_id']
992 switch_dpid
= port
['switch_dpid']
994 #TODO if not ofc_id: look at database table ofcs
997 # If no ofc_id found it, default ofc_id is used.
998 if not ofc_id
and not switch_dpid
:
1001 if ofc_id
and ofc_id
in self
.config
['ofcs_thread']:
1002 r
, c
= self
.config
['ofcs_thread'][ofc_id
].insert_task("update-net", net_id
)
1005 ofcs_dpid_list
= self
.config
['ofcs_thread_dpid']
1006 for ofc_t
in ofcs_dpid_list
:
1007 if switch_dpid
in ofc_t
:
1008 r
, c
= ofc_t
[switch_dpid
].insert_task("update-net", net_id
)
1011 message
= "Cannot insert a task for updating network '{}', {}".format(net_id
, c
)
1012 self
.logger
.error(message
)
1013 raise ovimException(message
, HTTP_Internal_Server_Error
)
1015 def delete_port(self
, port_id
):
1016 # Look for the previous port data
1017 result
, ports
= self
.db
.get_table(WHERE
={'uuid': port_id
, "type": "external"}, FROM
='ports')
1019 raise ovimException("Cannot get port info from database: {}".format(ports
), http_code
=-result
)
1020 # delete from the data base
1021 result
, content
= self
.db
.delete_row('ports', port_id
)
1023 raise ovimException("External port '{}' not found".format(port_id
), http_code
=HTTP_Not_Found
)
1025 raise ovimException("Cannot delete port from database: {}".format(content
), http_code
=-result
)
1027 network
= ports
[0].get('net_id', None)
1032 self
.net_update_ofc_thread(network
, ofc_id
=ports
[0]["ofc_id"], switch_dpid
=ports
[0]["switch_dpid"])
1033 except ovimException
as e
:
1034 raise ovimException("Cannot insert a task for delete network '{}' {}".format(network
, str(e
)),
1035 HTTP_Internal_Server_Error
)
1036 except Exception as e
:
1037 raise ovimException("Cannot insert a task for delete network '{}' {}".format(network
, str(e
)),
1038 HTTP_Internal_Server_Error
)
1042 def edit_port(self
, port_id
, port_data
, admin
=True):
1043 # Look for the previous port data
1044 result
, content
= self
.db
.get_table(FROM
="ports", WHERE
={'uuid': port_id
})
1046 raise ovimException("Cannot get port info from database: {}".format(content
), http_code
=-result
)
1048 raise ovimException("Port '{}' not found".format(port_id
), http_code
=HTTP_Not_Found
)
1053 if 'net_id' in port_data
:
1055 old_net
= port
.get('net_id', None)
1056 new_net
= port_data
['net_id']
1057 if old_net
!= new_net
:
1060 nets
.append(new_net
) # put first the new net, so that new openflow rules are created before removing the old ones
1062 nets
.append(old_net
)
1063 if port
['type'] == 'instance:bridge' or port
['type'] == 'instance:ovs':
1064 raise ovimException("bridge interfaces cannot be attached to a different net", http_code
=HTTP_Forbidden
)
1065 elif port
['type'] == 'external' and not admin
:
1066 raise ovimException("Needed admin privileges",http_code
=HTTP_Unauthorized
)
1068 # check that new net has the correct type
1069 result
, new_net_dict
= self
.db
.check_target_net(new_net
, None, port
['type'])
1071 raise ovimException("Error {}".format(new_net_dict
), http_code
=HTTP_Conflict
)
1072 # change VLAN for SR-IOV ports
1073 if result
>= 0 and port
["type"] == "instance:data" and port
["model"] == "VF": # TODO consider also VFnotShared
1075 port_data
["vlan"] = None
1077 port_data
["vlan"] = new_net_dict
["vlan"]
1078 # get host where this VM is allocated
1079 result
, content
= self
.db
.get_table(FROM
="instances", WHERE
={"uuid": port
["instance_id"]})
1081 host_id
= content
[0]["host_id"]
1083 # insert in data base
1085 result
, content
= self
.db
.update_rows('ports', port_data
, WHERE
={'uuid': port_id
}, log
=False)
1086 port
.update(port_data
)
1088 # Insert task to complete actions
1092 self
.net_update_ofc_thread(net_id
, port
["ofc_id"], switch_dpid
=port
["switch_dpid"])
1093 except ovimException
as e
:
1094 raise ovimException("Error updating network'{}' {}".format(net_id
, str(e
)),
1095 HTTP_Internal_Server_Error
)
1096 except Exception as e
:
1097 raise ovimException("Error updating network '{}' {}".format(net_id
, str(e
)),
1098 HTTP_Internal_Server_Error
)
1101 r
, v
= self
.config
['host_threads'][host_id
].insert_task("edit-iface", port_id
, old_net
, new_net
)
1103 self
.logger
.error("Error updating network '{}' {}".format(r
,v
))
1104 # TODO Do something if fails
1108 raise ovimException("Error {}".format(content
), http_code
=-result
)
1110 def new_of_controller(self
, ofc_data
):
1112 Create a new openflow controller into DB
1113 :param ofc_data: Dict openflow controller data
1114 :return: openflow controller dpid
1117 result
, ofc_uuid
= self
.db
.new_row('ofcs', ofc_data
, True, True)
1119 raise ovimException("New ofc Error %s" % ofc_uuid
, HTTP_Internal_Server_Error
)
1121 ofc_data
['uuid'] = ofc_uuid
1122 of_conn
= self
._load
_of
_module
(ofc_data
)
1123 self
._create
_ofc
_task
(ofc_uuid
, ofc_data
['dpid'], of_conn
)
1127 def edit_of_controller(self
, of_id
, ofc_data
):
1129 Edit an openflow controller entry from DB
1133 raise ovimException("No data received during uptade OF contorller", http_code
=HTTP_Internal_Server_Error
)
1135 old_of_controller
= self
.show_of_controller(of_id
)
1137 if old_of_controller
:
1138 result
, content
= self
.db
.update_rows('ofcs', ofc_data
, WHERE
={'uuid': of_id
}, log
=False)
1142 raise ovimException("Error uptating OF contorller with uuid {}".format(of_id
),
1145 raise ovimException("Error uptating OF contorller with uuid {}".format(of_id
),
1146 http_code
=HTTP_Internal_Server_Error
)
1148 def delete_of_controller(self
, of_id
):
1150 Delete an openflow controller from DB.
1151 :param of_id: openflow controller dpid
1155 ofc
= self
.show_of_controller(of_id
)
1157 result
, content
= self
.db
.delete_row("ofcs", of_id
)
1159 raise ovimException("Cannot delete ofc from database: {}".format(content
), http_code
=-result
)
1161 raise ovimException("ofc {} not found ".format(content
), http_code
=HTTP_Not_Found
)
1163 ofc_thread
= self
.config
['ofcs_thread'][of_id
]
1164 del self
.config
['ofcs_thread'][of_id
]
1165 for ofc_th
in self
.config
['ofcs_thread_dpid']:
1166 if ofc
['dpid'] in ofc_th
:
1167 self
.config
['ofcs_thread_dpid'].remove(ofc_th
)
1169 ofc_thread
.insert_task("exit")
1174 def show_of_controller(self
, uuid
):
1176 Show an openflow controller by dpid from DB.
1177 :param db_filter: List with where query parameters
1181 result
, content
= self
.db
.get_table(FROM
='ofcs', WHERE
={"uuid": uuid
}, LIMIT
=100)
1184 raise ovimException("Openflow controller with uuid '{}' not found".format(uuid
),
1185 http_code
=HTTP_Not_Found
)
1187 raise ovimException("Openflow controller with uuid '{}' error".format(uuid
),
1188 http_code
=HTTP_Internal_Server_Error
)
1191 def get_of_controllers(self
, columns
=None, db_filter
={}, limit
=None):
1193 Show an openflow controllers from DB.
1194 :param columns: List with SELECT query parameters
1195 :param db_filter: List with where query parameters
1196 :param limit: result Limit
1199 result
, content
= self
.db
.get_table(SELECT
=columns
, FROM
='ofcs', WHERE
=db_filter
, LIMIT
=limit
)
1202 raise ovimException(str(content
), -result
)
1206 def get_tenants(self
, columns
=None, db_filter
={}, limit
=None):
1208 Retrieve tenant list from DB
1209 :param columns: List with SELECT query parameters
1210 :param db_filter: List with where query parameters
1211 :param limit: result limit
1214 result
, content
= self
.db
.get_table(FROM
='tenants', SELECT
=columns
, WHERE
=db_filter
, LIMIT
=limit
)
1216 raise ovimException('get_tenatns Error {}'.format(str(content
)), -result
)
1218 convert_boolean(content
, ('enabled',))
1221 def show_tenant_id(self
, tenant_id
):
1223 Get tenant from DB by id
1224 :param tenant_id: tenant id
1227 result
, content
= self
.db
.get_table(FROM
='tenants', SELECT
=('uuid', 'name', 'description', 'enabled'),
1228 WHERE
={"uuid": tenant_id
})
1230 raise ovimException(str(content
), -result
)
1232 raise ovimException("tenant with uuid='{}' not found".format(tenant_id
), HTTP_Not_Found
)
1234 convert_boolean(content
, ('enabled',))
1237 def new_tentant(self
, tenant
):
1239 Create a tenant and store in DB
1240 :param tenant: Dictionary with tenant data
1241 :return: the uuid of created tenant. Raise exception upon error
1244 # insert in data base
1245 result
, tenant_uuid
= self
.db
.new_tenant(tenant
)
1250 raise ovimException(str(tenant_uuid
), -result
)
1252 def delete_tentant(self
, tenant_id
):
1254 Delete a tenant from the database.
1255 :param tenant_id: Tenant id
1256 :return: delete tenant id
1260 r
, tenants_flavors
= self
.db
.get_table(FROM
='tenants_flavors', SELECT
=('flavor_id', 'tenant_id'),
1261 WHERE
={'tenant_id': tenant_id
})
1263 tenants_flavors
= ()
1264 r
, tenants_images
= self
.db
.get_table(FROM
='tenants_images', SELECT
=('image_id', 'tenant_id'),
1265 WHERE
={'tenant_id': tenant_id
})
1269 result
, content
= self
.db
.delete_row('tenants', tenant_id
)
1271 raise ovimException("tenant '%s' not found" % tenant_id
, HTTP_Not_Found
)
1273 for flavor
in tenants_flavors
:
1274 self
.db
.delete_row_by_key("flavors", "uuid", flavor
['flavor_id'])
1275 for image
in tenants_images
:
1276 self
.db
.delete_row_by_key("images", "uuid", image
['image_id'])
1279 raise ovimException("Error deleting tenant '%s' " % tenant_id
, HTTP_Internal_Server_Error
)
1281 def edit_tenant(self
, tenant_id
, tenant_data
):
1283 Update a tenant data identified by tenant id
1284 :param tenant_id: tenant id
1285 :param tenant_data: Dictionary with tenant data
1289 # Look for the previous data
1290 result
, tenant_data_old
= self
.db
.get_table(FROM
='tenants', WHERE
={'uuid': tenant_id
})
1292 raise ovimException("Error updating tenant with uuid='{}': {}".format(tenant_id
, tenant_data_old
),
1293 HTTP_Internal_Server_Error
)
1295 raise ovimException("tenant with uuid='{}' not found".format(tenant_id
), HTTP_Not_Found
)
1297 # insert in data base
1298 result
, content
= self
.db
.update_rows('tenants', tenant_data
, WHERE
={'uuid': tenant_id
}, log
=True)
1302 raise ovimException(str(content
), -result
)
1304 def set_of_port_mapping(self
, of_maps
, ofc_id
=None, switch_dpid
=None, region
=None):
1306 Create new port mapping entry
1307 :param of_maps: List with port mapping information
1308 # maps =[{"ofc_id": <ofc_id>,"region": datacenter region,"compute_node": compute uuid,"pci": pci adress,
1309 "switch_dpid": swith dpid,"switch_port": port name,"switch_mac": mac}]
1310 :param ofc_id: ofc id
1311 :param switch_dpid: switch dpid
1312 :param region: datacenter region id
1318 map['ofc_id'] = ofc_id
1320 map['switch_dpid'] = switch_dpid
1322 map['region'] = region
1324 for of_map
in of_maps
:
1325 result
, uuid
= self
.db
.new_row('of_port_mappings', of_map
, True)
1327 of_map
["uuid"] = uuid
1329 raise ovimException(str(uuid
), -result
)
1332 def clear_of_port_mapping(self
, db_filter
={}):
1334 Clear port mapping filtering using db_filter dict
1335 :param db_filter: Parameter to filter during remove process
1338 result
, content
= self
.db
.delete_row_by_dict(FROM
='of_port_mappings', WHERE
=db_filter
)
1343 raise ovimException("Error deleting of_port_mappings with filter='{}'".format(str(db_filter
)),
1344 HTTP_Internal_Server_Error
)
1346 def get_of_port_mappings(self
, column
=None, db_filter
=None, db_limit
=None):
1348 Retrive port mapping from DB
1353 result
, content
= self
.db
.get_table(SELECT
=column
, WHERE
=db_filter
, FROM
='of_port_mappings', LIMIT
=db_limit
)
1356 self
.logger
.error("get_of_port_mappings Error %d %s", result
, content
)
1357 raise ovimException(str(content
), -result
)
1361 def get_dhcp_controller(self
):
1363 Create an host_thread object for manage openvim controller and not create a thread for itself
1364 :return: dhcp_host openvim controller object
1367 if 'openvim_controller' in self
.config
['host_threads']:
1368 return self
.config
['host_threads']['openvim_controller']
1371 controller_ip
= self
.config
['ovs_controller_ip']
1372 ovs_controller_user
= self
.config
.get('ovs_controller_user')
1374 host_test_mode
= True if self
.config
['mode'] == 'test' or self
.config
['mode'] == "OF only" else False
1375 host_develop_mode
= True if self
.config
['mode'] == 'development' else False
1377 dhcp_host
= ht
.host_thread(name
='openvim_controller', user
=ovs_controller_user
, host
=controller_ip
,
1378 password
=self
.config
.get('ovs_controller_password'),
1379 keyfile
=self
.config
.get('ovs_controller_keyfile'),
1380 db
=self
.config
["db"], db_lock
=self
.config
["db_lock"], test
=host_test_mode
,
1381 image_path
=self
.config
['host_image_path'], version
=self
.config
['version'],
1382 host_id
='openvim_controller', develop_mode
=host_develop_mode
,
1383 develop_bridge_iface
=bridge_ifaces
,
1384 logger_name
=self
.logger_name
+ ".host.controller",
1385 debug
=self
.config
.get('log_level_host'))
1387 self
.config
['host_threads']['openvim_controller'] = dhcp_host
1389 dhcp_host
.check_connectivity()
1390 except Exception as e
:
1395 def launch_dhcp_server(self
, vlan
, first_ip
, last_ip
, cidr
, gateway
):
1397 Launch a dhcpserver base on dnsmasq attached to the net base on vlan id across the the openvim computes
1398 :param vlan: vlan identifier
1399 :param first_ip: First dhcp range ip
1400 :param last_ip: Last dhcp range ip
1401 :param cidr: net cidr
1402 :param gateway: net gateway
1405 ip_tools
= IPNetwork(cidr
)
1406 dhcp_netmask
= str(ip_tools
.netmask
)
1407 ip_range
= [first_ip
, last_ip
]
1409 dhcp_path
= self
.config
['ovs_controller_file_path']
1411 controller_host
= self
.get_dhcp_controller()
1412 controller_host
.create_linux_bridge(vlan
)
1413 controller_host
.create_dhcp_interfaces(vlan
, gateway
, dhcp_netmask
)
1414 controller_host
.launch_dhcp_server(vlan
, ip_range
, dhcp_netmask
, dhcp_path
, gateway
)
1416 if __name__
== "__main__":
1418 parser
= argparse
.ArgumentParser()
1419 parser
.add_argument("-v","--version", help="show ovim library version", action
="store_true")
1420 parser
.add_argument("--database-version", help="show required database version", action
="store_true")
1421 args
= parser
.parse_args()
1423 print ('openvimd version {} {}'.format(ovim
.get_version(), ovim
.get_version_date()))
1424 print ('(c) Copyright Telefonica')
1425 elif args
.database_version
:
1426 print ('required database version: {}'.format(ovim
.get_database_version()))