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.15-r531"
46 version_date
= "May 2017"
47 database_version
= 19 #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
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', 'password', 'keyfile'),
248 FROM
='hosts', WHERE
={'status': 'ok'})
250 raise ovimException("Cannot get hosts from database {}".format(hosts
))
252 self
.config
['host_threads'] = {}
254 thread
= ht
.host_thread(name
=host
['name'], user
=host
['user'], host
=host
['ip_name'], db
=self
.config
["db"],
255 password
=host
['password'],
256 keyfile
=host
.get('keyfile', self
.config
["host_ssh_keyfile"]),
257 db_lock
=self
.config
["db_lock"], test
=host_test_mode
,
258 image_path
=self
.config
['host_image_path'],
259 version
=self
.config
['version'], host_id
=host
['uuid'],
260 develop_mode
=host_develop_mode
,
261 develop_bridge_iface
=host_develop_bridge_iface
,
262 logger_name
=self
.logger_name
+ ".host." + host
['name'],
263 debug
=self
.config
.get('log_level_host'))
265 self
.config
['host_threads'][host
['uuid']] = thread
267 # create ovs dhcp thread
268 result
, content
= self
.db
.get_table(FROM
='nets')
270 self
.logger
.error("http_get_ports Error %d %s", result
, content
)
271 raise ovimException(str(content
), -result
)
274 net_type
= net
['type']
275 if (net_type
== 'bridge_data' or net_type
== 'bridge_man') and \
276 net
["provider"][:4] == 'OVS:' and net
["enable_dhcp"] == "true":
278 self
.launch_dhcp_server(net
['vlan'],
279 net
['dhcp_first_ip'],
283 except Exception as e
:
284 self
.logger
.error("Fail at launching dhcp server for net_id='%s' net_name='%s': %s",
285 net
["uuid"], net
["name"], str(e
))
286 self
.db
.update_rows("nets", {"status": "ERROR",
287 "last_error": "Fail at launching dhcp server: " + str(e
)},
288 {"uuid": net
["uuid"]})
290 def _start_of_db_tasks(self
):
292 Start ofc task for existing ofcs in database
297 ofcs
= self
.get_of_controllers()
300 of_conn
= self
._load
_of
_module
(ofc
)
301 # create ofc thread per of controller
302 self
._create
_ofc
_task
(ofc
['uuid'], ofc
['dpid'], of_conn
)
304 def _create_ofc_task(self
, ofc_uuid
, dpid
, of_conn
):
306 Create an ofc thread for handle each sdn controllers
307 :param ofc_uuid: sdn controller uuid
308 :param dpid: sdn controller dpid
309 :param of_conn: OF_conn module
312 if 'ofcs_thread' not in self
.config
and 'ofcs_thread_dpid' not in self
.config
:
314 ofcs_thread_dpid
= []
316 ofcs_threads
= self
.config
['ofcs_thread']
317 ofcs_thread_dpid
= self
.config
['ofcs_thread_dpid']
319 if ofc_uuid
not in ofcs_threads
:
320 ofc_thread
= self
._create
_ofc
_thread
(of_conn
, ofc_uuid
)
321 if ofc_uuid
== "Default":
322 self
.config
['of_thread'] = ofc_thread
324 ofcs_threads
[ofc_uuid
] = ofc_thread
325 self
.config
['ofcs_thread'] = ofcs_threads
327 ofcs_thread_dpid
.append({dpid
: ofc_thread
})
328 self
.config
['ofcs_thread_dpid'] = ofcs_thread_dpid
330 def _start_ofc_default_task(self
):
332 Create default ofc thread
334 if 'of_controller' not in self
.config \
335 and 'of_controller_ip' not in self
.config \
336 and 'of_controller_port' not in self
.config \
337 and 'of_controller_dpid' not in self
.config
:
342 db_config
['ip'] = self
.config
.get('of_controller_ip')
343 db_config
['port'] = self
.config
.get('of_controller_port')
344 db_config
['dpid'] = self
.config
.get('of_controller_dpid')
345 db_config
['type'] = self
.config
.get('of_controller')
346 db_config
['user'] = self
.config
.get('of_user')
347 db_config
['password'] = self
.config
.get('of_password')
349 # create connector to the openflow controller
350 # load other parameters starting by of_ from config dict in a temporal dict
352 of_conn
= self
._load
_of
_module
(db_config
)
353 # create openflow thread
354 self
._create
_ofc
_task
("Default", db_config
['dpid'], of_conn
)
356 def _load_of_module(self
, db_config
):
358 import python module for each SDN controller supported
359 :param db_config: SDN dn information
363 raise ovimException("No module found it", HTTP_Internal_Server_Error
)
368 if self
.of_test_mode
:
369 return openflow_conn
.OfTestConnector({"name": db_config
['type'],
370 "dpid": db_config
['dpid'],
371 "of_debug": self
.config
['log_level_of']})
375 temp_dict
['of_ip'] = db_config
['ip']
376 temp_dict
['of_port'] = db_config
['port']
377 temp_dict
['of_dpid'] = db_config
['dpid']
378 temp_dict
['of_controller'] = db_config
['type']
379 temp_dict
['of_user'] = db_config
.get('user')
380 temp_dict
['of_password'] = db_config
.get('password')
382 temp_dict
['of_debug'] = self
.config
['log_level_of']
384 if temp_dict
['of_controller'] == 'opendaylight':
387 module
= temp_dict
['of_controller']
389 if module
not in ovim
.of_module
:
391 pkg
= __import__("osm_openvim." + module
)
392 of_conn_module
= getattr(pkg
, module
)
393 ovim
.of_module
[module
] = of_conn_module
394 self
.logger
.debug("Module load from {}".format("osm_openvim." + module
))
395 except Exception as e
:
396 self
.logger
.error("Cannot open openflow controller module of type '%s'", module
)
397 raise ovimException("Cannot open openflow controller of type module '{}'"
398 "Revise it is installed".format(module
),
399 HTTP_Internal_Server_Error
)
401 of_conn_module
= ovim
.of_module
[module
]
402 return of_conn_module
.OF_conn(temp_dict
)
403 except Exception as e
:
404 self
.logger
.error("Cannot open the Openflow controller '%s': %s", type(e
).__name
__, str(e
))
405 raise ovimException("Cannot open the Openflow controller '{}': '{}'".format(type(e
).__name
__, str(e
)),
406 HTTP_Internal_Server_Error
)
408 def _create_ofc_thread(self
, of_conn
, ofc_uuid
="Default"):
410 Create and launch a of thread
413 # create openflow thread
415 #if 'of_controller_nets_with_same_vlan' in self.config:
416 # ofc_net_same_vlan = self.config['of_controller_nets_with_same_vlan']
418 # ofc_net_same_vlan = False
419 ofc_net_same_vlan
= False
421 thread
= oft
.openflow_thread(ofc_uuid
, of_conn
, of_test
=self
.of_test_mode
, db
=self
.config
["db"],
422 db_lock
=self
.config
["db_lock"],
423 pmp_with_same_vlan
=ofc_net_same_vlan
,
424 logger_name
=self
.logger_name
+ ".ofc." + ofc_uuid
,
425 debug
=self
.config
.get('log_level_of'))
426 #r, c = thread.OF_connector.obtain_port_correspondence()
428 # raise ovimException("Cannot get openflow information %s", c)
432 def stop_service(self
):
433 threads
= self
.config
.get('host_threads', {})
434 if 'of_thread' in self
.config
:
435 threads
['of'] = (self
.config
['of_thread'])
436 if 'ofcs_thread' in self
.config
:
437 ofcs_thread
= self
.config
['ofcs_thread']
438 for ofc
in ofcs_thread
:
439 threads
[ofc
] = ofcs_thread
[ofc
]
441 if 'dhcp_thread' in self
.config
:
442 threads
['dhcp'] = (self
.config
['dhcp_thread'])
444 for thread_id
, thread
in threads
.items():
445 if thread_id
== 'openvim_controller':
447 thread
.insert_task("exit")
448 for thread_id
, thread
in threads
.items():
449 if thread_id
== 'openvim_controller':
453 def get_networks(self
, columns
=None, db_filter
={}, limit
=None):
455 Retreive networks available
456 :param columns: List with select query parameters
457 :param db_filter: List with where query parameters
458 :param limit: Query limit result
461 result
, content
= self
.db
.get_table(SELECT
=columns
, FROM
='nets', WHERE
=db_filter
, LIMIT
=limit
)
464 raise ovimException(str(content
), -result
)
466 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
470 def show_network(self
, network_id
, db_filter
={}):
472 Get network from DB by id
473 :param network_id: net Id
474 :param db_filter: List with where query parameters
479 raise ovimException("Not network id was not found")
480 db_filter
['uuid'] = network_id
482 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
=db_filter
, LIMIT
=100)
485 raise ovimException(str(content
), -result
)
487 raise ovimException("show_network network '%s' not found" % network_id
, -result
)
489 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
491 result
, ports
= self
.db
.get_table(FROM
='ports', SELECT
=('uuid as port_id',),
492 WHERE
={'net_id': network_id
}, LIMIT
=100)
494 content
[0]['ports'] = ports
496 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
499 def new_network(self
, network
):
504 tenant_id
= network
.get('tenant_id')
507 result
, _
= self
.db
.get_table(FROM
='tenants', SELECT
=('uuid',), WHERE
={'uuid': tenant_id
, "enabled": True})
509 raise ovimException("set_network error, no tenant founded", -result
)
513 net_provider
= network
.get('provider')
514 net_type
= network
.get('type')
515 net_vlan
= network
.get("vlan")
516 net_bind_net
= network
.get("bind_net")
517 net_bind_type
= network
.get("bind_type")
518 net_region
= network
.get("region")
519 name
= network
["name"]
521 # check if network name ends with :<vlan_tag> and network exist in order to make and automated bindning
522 vlan_index
= name
.rfind(":")
523 if not net_bind_net
and not net_bind_type
and vlan_index
> 1:
525 vlan_tag
= int(name
[vlan_index
+ 1:])
526 if not vlan_tag
and vlan_tag
< 4096:
527 net_bind_net
= name
[:vlan_index
]
528 net_bind_type
= "vlan:" + name
[vlan_index
+ 1:]
533 # look for a valid net
534 if self
._check
_valid
_uuid
(net_bind_net
):
535 net_bind_key
= "uuid"
537 net_bind_key
= "name"
538 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
={net_bind_key
: net_bind_net
})
540 raise ovimException(' getting nets from db ' + content
, HTTP_Internal_Server_Error
)
542 raise ovimException(" bind_net %s '%s'not found" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
544 raise ovimException(" more than one bind_net %s '%s' found, use uuid" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
545 network
["bind_net"] = content
[0]["uuid"]
548 if net_bind_type
[0:5] != "vlan:":
549 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>'", HTTP_Bad_Request
)
550 if int(net_bind_type
[5:]) > 4095 or int(net_bind_type
[5:]) <= 0:
551 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>' with a tag between 1 and 4095",
553 network
["bind_type"] = net_bind_type
556 if net_provider
[:9] == "openflow:":
558 if net_type
!= "ptp" and net_type
!= "data":
559 raise ovimException(" only 'ptp' or 'data' net types can be bound to 'openflow'",
565 if net_type
!= "bridge_man" and net_type
!= "bridge_data":
566 raise ovimException("Only 'bridge_man' or 'bridge_data' net types can be bound "
567 "to 'bridge', 'macvtap' or 'default", HTTP_Bad_Request
)
569 net_type
= 'bridge_man'
572 net_type
= 'bridge_man'
575 if net_provider
[:7] == 'bridge:':
576 # check it is one of the pre-provisioned bridges
577 bridge_net_name
= net_provider
[7:]
578 for brnet
in self
.config
['bridge_nets']:
579 if brnet
[0] == bridge_net_name
: # free
581 raise ovimException("invalid 'provider:physical', "
582 "bridge '%s' is already used" % bridge_net_name
, HTTP_Conflict
)
586 # if bridge_net==None:
587 # bottle.abort(HTTP_Bad_Request, "invalid 'provider:physical', bridge '%s' is not one of the
588 # provisioned 'bridge_ifaces' in the configuration file" % bridge_net_name)
591 elif self
.config
['network_type'] == 'bridge' and (net_type
== 'bridge_data' or net_type
== 'bridge_man'):
592 # look for a free precreated nets
593 for brnet
in self
.config
['bridge_nets']:
594 if not brnet
[3]: # free
596 if net_type
== 'bridge_man': # look for the smaller speed
597 if brnet
[2] < bridge_net
[2]:
599 else: # look for the larger speed
600 if brnet
[2] > bridge_net
[2]:
606 raise ovimException("Max limits of bridge networks reached. Future versions of VIM "
607 "will overcome this limit", HTTP_Bad_Request
)
609 self
.logger
.debug("using net " + bridge_net
)
610 net_provider
= "bridge:" + bridge_net
[0]
611 net_vlan
= bridge_net
[1]
612 elif net_type
== 'bridge_data' or net_type
== 'bridge_man' and self
.config
['network_type'] == 'ovs':
615 if net_type
== "data" or net_type
== "ptp":
616 net_region
= "__DATA__"
617 elif net_provider
== "OVS":
618 net_region
= "__OVS__"
619 if not net_vlan
and (net_type
== "data" or net_type
== "ptp" or net_provider
== "OVS"):
620 net_vlan
= self
.db
.get_free_net_vlan(net_region
)
622 raise ovimException("Error getting an available vlan", HTTP_Internal_Server_Error
)
623 if net_provider
== 'OVS':
624 net_provider
= 'OVS' + ":" + str(net_vlan
)
626 network
['provider'] = net_provider
627 network
['type'] = net_type
628 network
['vlan'] = net_vlan
629 network
['region'] = net_region
630 dhcp_integrity
= True
631 if 'enable_dhcp' in network
and network
['enable_dhcp']:
632 dhcp_integrity
= self
._check
_dhcp
_data
_integrity
(network
)
634 result
, content
= self
.db
.new_row('nets', network
, True, True)
636 if result
>= 0 and dhcp_integrity
:
638 bridge_net
[3] = content
639 if self
.config
.get("dhcp_server") and self
.config
['network_type'] == 'bridge':
640 if network
["name"] in self
.config
["dhcp_server"].get("nets", ()):
641 self
.config
["dhcp_nets"].append(content
)
642 self
.logger
.debug("dhcp_server: add new net", content
)
643 elif bridge_net
and bridge_net
[0] in self
.config
["dhcp_server"].get("bridge_ifaces", ()):
644 self
.config
["dhcp_nets"].append(content
)
645 self
.logger
.debug("dhcp_server: add new net", content
, content
)
648 raise ovimException("Error posting network", HTTP_Internal_Server_Error
)
649 # TODO kei change update->edit
651 def edit_network(self
, network_id
, network
):
653 Update entwork data byt id
656 # Look for the previous data
657 where_
= {'uuid': network_id
}
658 result
, network_old
= self
.db
.get_table(FROM
='nets', WHERE
=where_
)
660 raise ovimException("Error updating network %s" % network_old
, HTTP_Internal_Server_Error
)
662 raise ovimException('network %s not found' % network_id
, HTTP_Not_Found
)
664 nbports
, content
= self
.db
.get_table(FROM
='ports', SELECT
=('uuid as port_id',),
665 WHERE
={'net_id': network_id
}, LIMIT
=100)
667 raise ovimException("http_put_network_id error %d %s" % (result
, network_old
), HTTP_Internal_Server_Error
)
669 if 'type' in network
and network
['type'] != network_old
[0]['type']:
670 raise ovimException("Can not change type of network while having ports attached",
671 HTTP_Method_Not_Allowed
)
672 if 'vlan' in network
and network
['vlan'] != network_old
[0]['vlan']:
673 raise ovimException("Can not change vlan of network while having ports attached",
674 HTTP_Method_Not_Allowed
)
677 net_provider
= network
.get('provider', network_old
[0]['provider'])
678 net_type
= network
.get('type', network_old
[0]['type'])
679 net_bind_net
= network
.get("bind_net")
680 net_bind_type
= network
.get("bind_type")
682 # look for a valid net
683 if self
._check
_valid
_uuid
(net_bind_net
):
684 net_bind_key
= "uuid"
686 net_bind_key
= "name"
687 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
={net_bind_key
: net_bind_net
})
689 raise ovimException('Getting nets from db ' + content
, HTTP_Internal_Server_Error
)
691 raise ovimException("bind_net %s '%s'not found" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
693 raise ovimException("More than one bind_net %s '%s' found, use uuid" % (net_bind_key
, net_bind_net
),
695 network
["bind_net"] = content
[0]["uuid"]
697 if net_bind_type
[0:5] != "vlan:":
698 raise ovimException("Bad format for 'bind_type', must be 'vlan:<tag>'", HTTP_Bad_Request
)
699 if int(net_bind_type
[5:]) > 4095 or int(net_bind_type
[5:]) <= 0:
700 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>' with a tag between 1 and 4095",
703 if net_provider
[:9] == "openflow:":
704 if net_type
!= "ptp" and net_type
!= "data":
705 raise ovimException("Only 'ptp' or 'data' net types can be bound to 'openflow'", HTTP_Bad_Request
)
707 if net_type
!= "bridge_man" and net_type
!= "bridge_data":
708 raise ovimException("Only 'bridge_man' or 'bridge_data' net types can be bound to "
709 "'bridge', 'macvtap' or 'default", HTTP_Bad_Request
)
711 # insert in data base
712 result
, content
= self
.db
.update_rows('nets', network
, WHERE
={'uuid': network_id
}, log
=True)
714 # if result > 0 and nbports>0 and 'admin_state_up' in network
715 # and network['admin_state_up'] != network_old[0]['admin_state_up']:
720 self
.net_update_ofc_thread(network_id
)
721 except ovimException
as e
:
722 raise ovimException("Error while launching openflow rules in network '{}' {}"
723 .format(network_id
, str(e
)), HTTP_Internal_Server_Error
)
724 except Exception as e
:
725 raise ovimException("Error while launching openflow rules in network '{}' {}"
726 .format(network_id
, str(e
)), HTTP_Internal_Server_Error
)
728 if self
.config
.get("dhcp_server"):
729 if network_id
in self
.config
["dhcp_nets"]:
730 self
.config
["dhcp_nets"].remove(network_id
)
731 if network
.get("name", network_old
[0]["name"]) in self
.config
["dhcp_server"].get("nets", ()):
732 self
.config
["dhcp_nets"].append(network_id
)
734 net_bind
= network
.get("bind_type", network_old
[0]["bind_type"])
735 if net_bind
and net_bind
and net_bind
[:7] == "bridge:" and net_bind
[7:] in self
.config
["dhcp_server"].get(
736 "bridge_ifaces", ()):
737 self
.config
["dhcp_nets"].append(network_id
)
740 raise ovimException(content
, -result
)
742 def delete_network(self
, network_id
):
744 Delete network by network id
745 :param network_id: network id
749 # delete from the data base
750 result
, content
= self
.db
.delete_row('nets', network_id
)
753 raise ovimException("Network %s not found " % network_id
, HTTP_Not_Found
)
755 for brnet
in self
.config
['bridge_nets']:
756 if brnet
[3] == network_id
:
759 if self
.config
.get("dhcp_server") and network_id
in self
.config
["dhcp_nets"]:
760 self
.config
["dhcp_nets"].remove(network_id
)
763 raise ovimException("Error deleting network '{}': {}".format(network_id
, content
), -result
)
765 def get_openflow_rules(self
, network_id
=None):
767 Get openflow id from DB
768 :param network_id: Network id, if none all networks will be retrieved
769 :return: Return a list with Openflow rules per net
775 where_
= {"net_id": network_id
}
776 result
, content
= self
.db
.get_table(
777 SELECT
=("name", "net_id", "ofc_id", "priority", "vlan_id", "ingress_port", "src_mac", "dst_mac", "actions"),
778 WHERE
=where_
, FROM
='of_flows')
781 raise ovimException(str(content
), -result
)
784 def edit_openflow_rules(self
, network_id
=None):
787 To make actions over the net. The action is to reinstall the openflow rules
788 network_id can be 'all'
789 :param network_id: Network id, if none all networks will be retrieved
790 :return : Number of nets updated
797 where_
= {"uuid": network_id
}
798 result
, content
= self
.db
.get_table(SELECT
=("uuid", "type"), WHERE
=where_
, FROM
='nets')
801 raise ovimException(str(content
), -result
)
804 if net
["type"] != "ptp" and net
["type"] != "data":
809 self
.net_update_ofc_thread(net
['uuid'])
810 except ovimException
as e
:
811 raise ovimException("Error updating network'{}' {}".format(net
['uuid'], str(e
)),
812 HTTP_Internal_Server_Error
)
813 except Exception as e
:
814 raise ovimException("Error updating network '{}' {}".format(net
['uuid'], str(e
)),
815 HTTP_Internal_Server_Error
)
819 def delete_openflow_rules(self
, ofc_id
=None):
821 To make actions over the net. The action is to delete ALL openflow rules
822 :return: return operation result
826 if 'Default' in self
.config
['ofcs_thread']:
827 r
, c
= self
.config
['ofcs_thread']['Default'].insert_task("clear-all")
829 raise ovimException("Default Openflow controller not not running", HTTP_Not_Found
)
831 elif ofc_id
in self
.config
['ofcs_thread']:
832 r
, c
= self
.config
['ofcs_thread'][ofc_id
].insert_task("clear-all")
836 raise ovimException(str(c
), -r
)
838 raise ovimException("Openflow controller not found with ofc_id={}".format(ofc_id
), HTTP_Not_Found
)
841 def get_openflow_ports(self
, ofc_id
=None):
843 Obtain switch ports names of openflow controller
844 :return: Return flow ports in DB
847 if 'Default' in self
.config
['ofcs_thread']:
848 conn
= self
.config
['ofcs_thread']['Default'].OF_connector
850 raise ovimException("Default Openflow controller not not running", HTTP_Not_Found
)
852 elif ofc_id
in self
.config
['ofcs_thread']:
853 conn
= self
.config
['ofcs_thread'][ofc_id
].OF_connector
855 raise ovimException("Openflow controller not found with ofc_id={}".format(ofc_id
), HTTP_Not_Found
)
858 def get_ports(self
, columns
=None, filter={}, limit
=None):
859 # result, content = my.db.get_ports(where_)
860 result
, content
= self
.db
.get_table(SELECT
=columns
, WHERE
=filter, FROM
='ports', LIMIT
=limit
)
862 self
.logger
.error("http_get_ports Error %d %s", result
, content
)
863 raise ovimException(str(content
), -result
)
865 convert_boolean(content
, ('admin_state_up',))
868 def new_port(self
, port_data
):
869 port_data
['type'] = 'external'
870 if port_data
.get('net_id'):
871 # check that new net has the correct type
872 result
, new_net
= self
.db
.check_target_net(port_data
['net_id'], None, 'external')
874 raise ovimException(str(new_net
), -result
)
875 # insert in data base
876 result
, uuid
= self
.db
.new_row('ports', port_data
, True, True)
878 if 'net_id' in port_data
:
880 self
.net_update_ofc_thread(port_data
['net_id'])
881 except ovimException
as e
:
882 raise ovimException("Cannot insert a task for updating network '{}' {}"
883 .format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
884 except Exception as e
:
885 raise ovimException("Cannot insert a task for updating network '{}' {}"
886 .format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
890 raise ovimException(str(uuid
), -result
)
892 def new_external_port(self
, port_data
):
894 Create new external port and check port mapping correspondence
895 :param port_data: port_data = {
896 'region': 'datacenter region',
897 'compute_node': 'compute node id',
898 'pci': 'pci port address',
901 'tenant_id': 'tenant id',
904 'ip_address': 'ip address - optional'}
908 port_data
['type'] = 'external'
910 if port_data
.get('net_id'):
911 # check that new net has the correct type
912 result
, new_net
= self
.db
.check_target_net(port_data
['net_id'], None, 'external')
914 raise ovimException(str(new_net
), -result
)
915 # insert in data base
918 if port_data
.get('region'):
919 db_filter
['region'] = port_data
['region']
920 if port_data
.get('pci'):
921 db_filter
['pci'] = port_data
['pci']
922 if port_data
.get('compute_node'):
923 db_filter
['compute_node'] = port_data
['compute_node']
925 columns
= ['ofc_id', 'switch_dpid', 'switch_port', 'switch_mac', 'pci']
926 port_mapping_data
= self
.get_of_port_mappings(columns
, db_filter
)
928 if not len(port_mapping_data
):
929 raise ovimException("No port mapping founded for '{}'".format(str(db_filter
)),
931 elif len(port_mapping_data
) > 1:
932 raise ovimException("Wrong port data was given, please check pci, region & compute id data",
935 port_data
['ofc_id'] = port_mapping_data
[0]['ofc_id']
936 port_data
['switch_dpid'] = port_mapping_data
[0]['switch_dpid']
937 port_data
['switch_port'] = port_mapping_data
[0]['switch_port']
938 port_data
['switch_mac'] = port_mapping_data
[0]['switch_mac']
940 # remove from compute_node, region and pci of_port_data to adapt to 'ports' structure
941 if 'region' in port_data
:
942 del port_data
['region']
943 if 'pci' in port_data
:
945 if 'compute_node' in port_data
:
946 del port_data
['compute_node']
948 result
, uuid
= self
.db
.new_row('ports', port_data
, True, True)
951 self
.net_update_ofc_thread(port_data
['net_id'], port_data
['ofc_id'])
952 except ovimException
as e
:
953 raise ovimException("Cannot insert a task for updating network '{}' {}".
954 format(port_data
['net_id'], str(e
)), HTTP_Internal_Server_Error
)
955 except Exception as e
:
956 raise ovimException("Cannot insert a task for updating network '{}' {}"
957 .format(port_data
['net_id'], e
), HTTP_Internal_Server_Error
)
960 raise ovimException(str(uuid
), -result
)
962 def net_update_ofc_thread(self
, net_id
, ofc_id
=None, switch_dpid
=None):
964 Insert a update net task by net id or ofc_id for each ofc thread
965 :param net_id: network id
966 :param ofc_id: openflow controller id
967 :param switch_dpid: switch dpid
971 raise ovimException("No net_id received", HTTP_Internal_Server_Error
)
974 c
= 'No valid ofc_id or switch_dpid received'
977 ports
= self
.get_ports(filter={"net_id": net_id
})
979 port_ofc_id
= port
.get('ofc_id', None)
981 ofc_id
= port
['ofc_id']
982 switch_dpid
= port
['switch_dpid']
984 #TODO if not ofc_id: look at database table ofcs
987 # If no ofc_id found it, default ofc_id is used.
988 if not ofc_id
and not switch_dpid
:
991 if ofc_id
and ofc_id
in self
.config
['ofcs_thread']:
992 r
, c
= self
.config
['ofcs_thread'][ofc_id
].insert_task("update-net", net_id
)
995 ofcs_dpid_list
= self
.config
['ofcs_thread_dpid']
996 for ofc_t
in ofcs_dpid_list
:
997 if switch_dpid
in ofc_t
:
998 r
, c
= ofc_t
[switch_dpid
].insert_task("update-net", net_id
)
1001 message
= "Cannot insert a task for updating network '{}', {}".format(net_id
, c
)
1002 self
.logger
.error(message
)
1003 raise ovimException(message
, HTTP_Internal_Server_Error
)
1005 def delete_port(self
, port_id
):
1006 # Look for the previous port data
1007 result
, ports
= self
.db
.get_table(WHERE
={'uuid': port_id
, "type": "external"}, FROM
='ports')
1009 raise ovimException("Cannot get port info from database: {}".format(ports
), http_code
=-result
)
1010 # delete from the data base
1011 result
, content
= self
.db
.delete_row('ports', port_id
)
1013 raise ovimException("External port '{}' not found".format(port_id
), http_code
=HTTP_Not_Found
)
1015 raise ovimException("Cannot delete port from database: {}".format(content
), http_code
=-result
)
1017 network
= ports
[0].get('net_id', None)
1022 self
.net_update_ofc_thread(network
, ofc_id
=ports
[0]["ofc_id"], switch_dpid
=ports
[0]["switch_dpid"])
1023 except ovimException
as e
:
1024 raise ovimException("Cannot insert a task for delete network '{}' {}".format(network
, str(e
)),
1025 HTTP_Internal_Server_Error
)
1026 except Exception as e
:
1027 raise ovimException("Cannot insert a task for delete network '{}' {}".format(network
, str(e
)),
1028 HTTP_Internal_Server_Error
)
1032 def edit_port(self
, port_id
, port_data
, admin
=True):
1033 # Look for the previous port data
1034 result
, content
= self
.db
.get_table(FROM
="ports", WHERE
={'uuid': port_id
})
1036 raise ovimException("Cannot get port info from database: {}".format(content
), http_code
=-result
)
1038 raise ovimException("Port '{}' not found".format(port_id
), http_code
=HTTP_Not_Found
)
1043 if 'net_id' in port_data
:
1045 old_net
= port
.get('net_id', None)
1046 new_net
= port_data
['net_id']
1047 if old_net
!= new_net
:
1050 nets
.append(new_net
) # put first the new net, so that new openflow rules are created before removing the old ones
1052 nets
.append(old_net
)
1053 if port
['type'] == 'instance:bridge' or port
['type'] == 'instance:ovs':
1054 raise ovimException("bridge interfaces cannot be attached to a different net", http_code
=HTTP_Forbidden
)
1055 elif port
['type'] == 'external' and not admin
:
1056 raise ovimException("Needed admin privileges",http_code
=HTTP_Unauthorized
)
1058 # check that new net has the correct type
1059 result
, new_net_dict
= self
.db
.check_target_net(new_net
, None, port
['type'])
1061 raise ovimException("Error {}".format(new_net_dict
), http_code
=HTTP_Conflict
)
1062 # change VLAN for SR-IOV ports
1063 if result
>= 0 and port
["type"] == "instance:data" and port
["model"] == "VF": # TODO consider also VFnotShared
1065 port_data
["vlan"] = None
1067 port_data
["vlan"] = new_net_dict
["vlan"]
1068 # get host where this VM is allocated
1069 result
, content
= self
.db
.get_table(FROM
="instances", WHERE
={"uuid": port
["instance_id"]})
1071 host_id
= content
[0]["host_id"]
1073 # insert in data base
1075 result
, content
= self
.db
.update_rows('ports', port_data
, WHERE
={'uuid': port_id
}, log
=False)
1076 port
.update(port_data
)
1078 # Insert task to complete actions
1082 self
.net_update_ofc_thread(net_id
, port
["ofc_id"], switch_dpid
=port
["switch_dpid"])
1083 except ovimException
as e
:
1084 raise ovimException("Error updating network'{}' {}".format(net_id
, str(e
)),
1085 HTTP_Internal_Server_Error
)
1086 except Exception as e
:
1087 raise ovimException("Error updating network '{}' {}".format(net_id
, str(e
)),
1088 HTTP_Internal_Server_Error
)
1091 r
, v
= self
.config
['host_threads'][host_id
].insert_task("edit-iface", port_id
, old_net
, new_net
)
1093 self
.logger
.error("Error updating network '{}' {}".format(r
,v
))
1094 # TODO Do something if fails
1098 raise ovimException("Error {}".format(content
), http_code
=-result
)
1100 def new_of_controller(self
, ofc_data
):
1102 Create a new openflow controller into DB
1103 :param ofc_data: Dict openflow controller data
1104 :return: openflow controller dpid
1107 result
, ofc_uuid
= self
.db
.new_row('ofcs', ofc_data
, True, True)
1109 raise ovimException("New ofc Error %s" % ofc_uuid
, HTTP_Internal_Server_Error
)
1111 ofc_data
['uuid'] = ofc_uuid
1112 of_conn
= self
._load
_of
_module
(ofc_data
)
1113 self
._create
_ofc
_task
(ofc_uuid
, ofc_data
['dpid'], of_conn
)
1117 def edit_of_controller(self
, of_id
, ofc_data
):
1119 Edit an openflow controller entry from DB
1123 raise ovimException("No data received during uptade OF contorller", http_code
=HTTP_Internal_Server_Error
)
1125 old_of_controller
= self
.show_of_controller(of_id
)
1127 if old_of_controller
:
1128 result
, content
= self
.db
.update_rows('ofcs', ofc_data
, WHERE
={'uuid': of_id
}, log
=False)
1132 raise ovimException("Error uptating OF contorller with uuid {}".format(of_id
),
1135 raise ovimException("Error uptating OF contorller with uuid {}".format(of_id
),
1136 http_code
=HTTP_Internal_Server_Error
)
1138 def delete_of_controller(self
, of_id
):
1140 Delete an openflow controller from DB.
1141 :param of_id: openflow controller dpid
1145 ofc
= self
.show_of_controller(of_id
)
1147 result
, content
= self
.db
.delete_row("ofcs", of_id
)
1149 raise ovimException("Cannot delete ofc from database: {}".format(content
), http_code
=-result
)
1151 raise ovimException("ofc {} not found ".format(content
), http_code
=HTTP_Not_Found
)
1153 ofc_thread
= self
.config
['ofcs_thread'][of_id
]
1154 del self
.config
['ofcs_thread'][of_id
]
1155 for ofc_th
in self
.config
['ofcs_thread_dpid']:
1156 if ofc
['dpid'] in ofc_th
:
1157 self
.config
['ofcs_thread_dpid'].remove(ofc_th
)
1159 ofc_thread
.insert_task("exit")
1164 def show_of_controller(self
, uuid
):
1166 Show an openflow controller by dpid from DB.
1167 :param db_filter: List with where query parameters
1171 result
, content
= self
.db
.get_table(FROM
='ofcs', WHERE
={"uuid": uuid
}, LIMIT
=100)
1174 raise ovimException("Openflow controller with uuid '{}' not found".format(uuid
),
1175 http_code
=HTTP_Not_Found
)
1177 raise ovimException("Openflow controller with uuid '{}' error".format(uuid
),
1178 http_code
=HTTP_Internal_Server_Error
)
1181 def get_of_controllers(self
, columns
=None, db_filter
={}, limit
=None):
1183 Show an openflow controllers from DB.
1184 :param columns: List with SELECT query parameters
1185 :param db_filter: List with where query parameters
1186 :param limit: result Limit
1189 result
, content
= self
.db
.get_table(SELECT
=columns
, FROM
='ofcs', WHERE
=db_filter
, LIMIT
=limit
)
1192 raise ovimException(str(content
), -result
)
1196 def get_tenants(self
, columns
=None, db_filter
={}, limit
=None):
1198 Retrieve tenant list from DB
1199 :param columns: List with SELECT query parameters
1200 :param db_filter: List with where query parameters
1201 :param limit: result limit
1204 result
, content
= self
.db
.get_table(FROM
='tenants', SELECT
=columns
, WHERE
=db_filter
, LIMIT
=limit
)
1206 raise ovimException('get_tenatns Error {}'.format(str(content
)), -result
)
1208 convert_boolean(content
, ('enabled',))
1211 def show_tenant_id(self
, tenant_id
):
1213 Get tenant from DB by id
1214 :param tenant_id: tenant id
1217 result
, content
= self
.db
.get_table(FROM
='tenants', SELECT
=('uuid', 'name', 'description', 'enabled'),
1218 WHERE
={"uuid": tenant_id
})
1220 raise ovimException(str(content
), -result
)
1222 raise ovimException("tenant with uuid='{}' not found".format(tenant_id
), HTTP_Not_Found
)
1224 convert_boolean(content
, ('enabled',))
1227 def new_tentant(self
, tenant
):
1229 Create a tenant and store in DB
1230 :param tenant: Dictionary with tenant data
1231 :return: the uuid of created tenant. Raise exception upon error
1234 # insert in data base
1235 result
, tenant_uuid
= self
.db
.new_tenant(tenant
)
1240 raise ovimException(str(tenant_uuid
), -result
)
1242 def delete_tentant(self
, tenant_id
):
1244 Delete a tenant from the database.
1245 :param tenant_id: Tenant id
1246 :return: delete tenant id
1250 r
, tenants_flavors
= self
.db
.get_table(FROM
='tenants_flavors', SELECT
=('flavor_id', 'tenant_id'),
1251 WHERE
={'tenant_id': tenant_id
})
1253 tenants_flavors
= ()
1254 r
, tenants_images
= self
.db
.get_table(FROM
='tenants_images', SELECT
=('image_id', 'tenant_id'),
1255 WHERE
={'tenant_id': tenant_id
})
1259 result
, content
= self
.db
.delete_row('tenants', tenant_id
)
1261 raise ovimException("tenant '%s' not found" % tenant_id
, HTTP_Not_Found
)
1263 for flavor
in tenants_flavors
:
1264 self
.db
.delete_row_by_key("flavors", "uuid", flavor
['flavor_id'])
1265 for image
in tenants_images
:
1266 self
.db
.delete_row_by_key("images", "uuid", image
['image_id'])
1269 raise ovimException("Error deleting tenant '%s' " % tenant_id
, HTTP_Internal_Server_Error
)
1271 def edit_tenant(self
, tenant_id
, tenant_data
):
1273 Update a tenant data identified by tenant id
1274 :param tenant_id: tenant id
1275 :param tenant_data: Dictionary with tenant data
1279 # Look for the previous data
1280 result
, tenant_data_old
= self
.db
.get_table(FROM
='tenants', WHERE
={'uuid': tenant_id
})
1282 raise ovimException("Error updating tenant with uuid='{}': {}".format(tenant_id
, tenant_data_old
),
1283 HTTP_Internal_Server_Error
)
1285 raise ovimException("tenant with uuid='{}' not found".format(tenant_id
), HTTP_Not_Found
)
1287 # insert in data base
1288 result
, content
= self
.db
.update_rows('tenants', tenant_data
, WHERE
={'uuid': tenant_id
}, log
=True)
1292 raise ovimException(str(content
), -result
)
1294 def set_of_port_mapping(self
, of_maps
, ofc_id
=None, switch_dpid
=None, region
=None):
1296 Create new port mapping entry
1297 :param of_maps: List with port mapping information
1298 # maps =[{"ofc_id": <ofc_id>,"region": datacenter region,"compute_node": compute uuid,"pci": pci adress,
1299 "switch_dpid": swith dpid,"switch_port": port name,"switch_mac": mac}]
1300 :param ofc_id: ofc id
1301 :param switch_dpid: switch dpid
1302 :param region: datacenter region id
1308 map['ofc_id'] = ofc_id
1310 map['switch_dpid'] = switch_dpid
1312 map['region'] = region
1314 for of_map
in of_maps
:
1315 result
, uuid
= self
.db
.new_row('of_port_mappings', of_map
, True)
1317 of_map
["uuid"] = uuid
1319 raise ovimException(str(uuid
), -result
)
1322 def clear_of_port_mapping(self
, db_filter
={}):
1324 Clear port mapping filtering using db_filter dict
1325 :param db_filter: Parameter to filter during remove process
1328 result
, content
= self
.db
.delete_row_by_dict(FROM
='of_port_mappings', WHERE
=db_filter
)
1333 raise ovimException("Error deleting of_port_mappings with filter='{}'".format(str(db_filter
)),
1334 HTTP_Internal_Server_Error
)
1336 def get_of_port_mappings(self
, column
=None, db_filter
=None, db_limit
=None):
1338 Retrive port mapping from DB
1343 result
, content
= self
.db
.get_table(SELECT
=column
, WHERE
=db_filter
, FROM
='of_port_mappings', LIMIT
=db_limit
)
1346 self
.logger
.error("get_of_port_mappings Error %d %s", result
, content
)
1347 raise ovimException(str(content
), -result
)
1351 def get_dhcp_controller(self
):
1353 Create an host_thread object for manage openvim controller and not create a thread for itself
1354 :return: dhcp_host openvim controller object
1357 if 'openvim_controller' in self
.config
['host_threads']:
1358 return self
.config
['host_threads']['openvim_controller']
1361 controller_ip
= self
.config
['ovs_controller_ip']
1362 ovs_controller_user
= self
.config
.get('ovs_controller_user')
1364 host_test_mode
= True if self
.config
['mode'] == 'test' or self
.config
['mode'] == "OF only" else False
1365 host_develop_mode
= True if self
.config
['mode'] == 'development' else False
1367 dhcp_host
= ht
.host_thread(name
='openvim_controller', user
=ovs_controller_user
, host
=controller_ip
,
1368 password
=self
.config
.get('ovs_controller_password'),
1369 keyfile
=self
.config
.get('ovs_controller_keyfile'),
1370 db
=self
.config
["db"], db_lock
=self
.config
["db_lock"], test
=host_test_mode
,
1371 image_path
=self
.config
['host_image_path'], version
=self
.config
['version'],
1372 host_id
='openvim_controller', develop_mode
=host_develop_mode
,
1373 develop_bridge_iface
=bridge_ifaces
,
1374 logger_name
=self
.logger_name
+ ".host.controller",
1375 debug
=self
.config
.get('log_level_host'))
1377 self
.config
['host_threads']['openvim_controller'] = dhcp_host
1378 if not host_test_mode
:
1379 dhcp_host
.ssh_connect()
1382 def launch_dhcp_server(self
, vlan
, first_ip
, last_ip
, cidr
, gateway
):
1384 Launch a dhcpserver base on dnsmasq attached to the net base on vlan id across the the openvim computes
1385 :param vlan: vlan identifier
1386 :param first_ip: First dhcp range ip
1387 :param last_ip: Last dhcp range ip
1388 :param cidr: net cidr
1389 :param gateway: net gateway
1392 ip_tools
= IPNetwork(cidr
)
1393 dhcp_netmask
= str(ip_tools
.netmask
)
1394 ip_range
= [first_ip
, last_ip
]
1396 dhcp_path
= self
.config
['ovs_controller_file_path']
1398 controller_host
= self
.get_dhcp_controller()
1399 controller_host
.create_linux_bridge(vlan
)
1400 controller_host
.create_dhcp_interfaces(vlan
, gateway
, dhcp_netmask
)
1401 controller_host
.launch_dhcp_server(vlan
, ip_range
, dhcp_netmask
, dhcp_path
, gateway
)
1403 if __name__
== "__main__":
1405 parser
= argparse
.ArgumentParser()
1406 parser
.add_argument("-v","--version", help="show ovim library version", action
="store_true")
1407 parser
.add_argument("--database-version", help="show required database version", action
="store_true")
1408 args
= parser
.parse_args()
1410 print ('openvimd version {} {}'.format(ovim
.get_version(), ovim
.get_version_date()))
1411 print ('(c) Copyright Telefonica')
1412 elif args
.database_version
:
1413 print ('required database version: {}'.format(ovim
.get_database_version()))