1 # -*- coding: utf-8 -*-
4 # Copyright 2015 Telefónica Investigación y Desarrollo, S.A.U.
5 # This file is part of openvim
8 # Licensed under the Apache License, Version 2.0 (the "License"); you may
9 # not use this file except in compliance with the License. You may obtain
10 # a copy of the License at
12 # http://www.apache.org/licenses/LICENSE-2.0
14 # Unless required by applicable law or agreed to in writing, software
15 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17 # License for the specific language governing permissions and limitations
20 # For those usages not covered by the Apache License, Version 2.0 please
21 # contact with: nfvlabs@tid.es
25 This is the thread for the http server North API.
26 Two thread will be launched, with normal and administrative permissions.
29 __author__
= "Alfonso Tierno, Leonardo Mirabal"
30 __date__
= "$06-Feb-2017 12:07:15$"
37 import host_thread
as ht
38 import dhcp_thread
as dt
39 import openflow_thread
as oft
40 from netaddr
import IPNetwork
41 from jsonschema
import validate
as js_v
, exceptions
as js_e
43 HTTP_Bad_Request
= 400
44 HTTP_Unauthorized
= 401
47 HTTP_Method_Not_Allowed
= 405
48 HTTP_Not_Acceptable
= 406
49 HTTP_Request_Timeout
= 408
51 HTTP_Service_Unavailable
= 503
52 HTTP_Internal_Server_Error
= 500
55 def convert_boolean(data
, items
):
56 '''Check recursively the content of data, and if there is an key contained in items, convert value from string to boolean
57 It assumes that bandwidth is well formed
59 'data': dictionary bottle.FormsDict variable to be checked. None or empty is consideted valid
60 'items': tuple of keys to convert
64 if type(data
) is dict:
66 if type(data
[k
]) is dict or type(data
[k
]) is tuple or type(data
[k
]) is list:
67 convert_boolean(data
[k
], items
)
69 if type(data
[k
]) is str:
70 if data
[k
] == "false":
72 elif data
[k
] == "true":
74 if type(data
) is tuple or type(data
) is list:
76 if type(k
) is dict or type(k
) is tuple or type(k
) is list:
77 convert_boolean(k
, items
)
81 class ovimException(Exception):
82 def __init__(self
, message
, http_code
=HTTP_Bad_Request
):
83 self
.http_code
= http_code
84 Exception.__init
__(self
, message
)
88 running_info
= {} #TODO OVIM move the info of running threads from config_dic to this static variable
89 def __init__(self
, configuration
):
90 self
.config
= configuration
91 self
.logger
= logging
.getLogger(configuration
["logger_name"])
93 self
.db
= self
._create
_database
_connection
()
96 def _create_database_connection(self
):
97 db
= vim_db
.vim_db((self
.config
["network_vlan_range_start"], self
.config
["network_vlan_range_end"]),
98 self
.config
['log_level_db']);
99 if db
.connect(self
.config
['db_host'], self
.config
['db_user'], self
.config
['db_passwd'],
100 self
.config
['db_name']) == -1:
101 # self.logger.error("Cannot connect to database %s at %s@%s", self.config['db_name'], self.config['db_user'],
102 # self.config['db_host'])
103 raise ovimException("Cannot connect to database {} at {}@{}".format(self
.config
['db_name'],
104 self
.config
['db_user'],
105 self
.config
['db_host']) )
109 def start_service(self
):
110 #if self.running_info:
111 # return #TODO service can be checked and rebuild broken threads
112 r
= self
.db
.get_db_version()
114 raise ovimException("DATABASE is not a VIM one or it is a '0.0' version. Try to upgrade to version '{}' with "\
115 "'./database_utils/migrate_vim_db.sh'".format(self
.config
["database_version"]) )
116 elif r
[1]!=self
.config
["database_version"]:
117 raise ovimException("DATABASE wrong version '{}'. Try to upgrade/downgrade to version '{}' with "\
118 "'./database_utils/migrate_vim_db.sh'".format(r
[1], self
.config
["database_version"]) )
120 # create database connection for openflow threads
121 db_of
= self
._create
_database
_connection
()
122 self
.config
["db"] = db_of
123 db_lock
= threading
.Lock()
124 self
.config
["db_lock"] = db_lock
126 # precreate interfaces; [bridge:<host_bridge_name>, VLAN used at Host, uuid of network camping in this bridge, speed in Gbit/s
127 self
.config
['dhcp_nets'] = []
128 self
.config
['bridge_nets'] = []
129 for bridge
, vlan_speed
in self
.config
["bridge_ifaces"].items():
130 # skip 'development_bridge'
131 if self
.config
['mode'] == 'development' and self
.config
['development_bridge'] == bridge
:
133 self
.config
['bridge_nets'].append([bridge
, vlan_speed
[0], vlan_speed
[1], None])
135 # check if this bridge is already used (present at database) for a network)
136 used_bridge_nets
= []
137 for brnet
in self
.config
['bridge_nets']:
138 r
, nets
= db_of
.get_table(SELECT
=('uuid',), FROM
='nets', WHERE
={'provider': "bridge:" + brnet
[0]})
140 brnet
[3] = nets
[0]['uuid']
141 used_bridge_nets
.append(brnet
[0])
142 if self
.config
.get("dhcp_server"):
143 if brnet
[0] in self
.config
["dhcp_server"]["bridge_ifaces"]:
144 self
.config
['dhcp_nets'].append(nets
[0]['uuid'])
145 if len(used_bridge_nets
) > 0:
146 self
.logger
.info("found used bridge nets: " + ",".join(used_bridge_nets
))
147 # get nets used by dhcp
148 if self
.config
.get("dhcp_server"):
149 for net
in self
.config
["dhcp_server"].get("nets", ()):
150 r
, nets
= db_of
.get_table(SELECT
=('uuid',), FROM
='nets', WHERE
={'name': net
})
152 self
.config
['dhcp_nets'].append(nets
[0]['uuid'])
154 # get host list from data base before starting threads
155 r
, hosts
= db_of
.get_table(SELECT
=('name', 'ip_name', 'user', 'uuid'), FROM
='hosts', WHERE
={'status': 'ok'})
157 raise ovimException("Cannot get hosts from database {}".format(hosts
))
158 # create connector to the openflow controller
159 of_test_mode
= False if self
.config
['mode'] == 'normal' or self
.config
['mode'] == "OF only" else True
162 OF_conn
= oft
.of_test_connector({"of_debug": self
.config
['log_level_of']})
164 # load other parameters starting by of_ from config dict in a temporal dict
165 temp_dict
= {"of_ip": self
.config
['of_controller_ip'],
166 "of_port": self
.config
['of_controller_port'],
167 "of_dpid": self
.config
['of_controller_dpid'],
168 "of_debug": self
.config
['log_level_of']
170 for k
, v
in self
.config
.iteritems():
171 if type(k
) is str and k
[0:3] == "of_" and k
[0:13] != "of_controller":
173 if self
.config
['of_controller'] == 'opendaylight':
175 elif "of_controller_module" in self
.config
:
176 module
= self
.config
["of_controller_module"]
178 module
= self
.config
['of_controller']
181 module_info
= imp
.find_module(module
)
183 OF_conn
= imp
.load_module("OF_conn", *module_info
)
185 OF_conn
= OF_conn
.OF_conn(temp_dict
)
186 except Exception as e
:
187 self
.logger
.error("Cannot open the Openflow controller '%s': %s", type(e
).__name
__, str(e
))
188 if module_info
and module_info
[0]:
189 file.close(module_info
[0])
191 except (IOError, ImportError) as e
:
192 if module_info
and module_info
[0]:
193 file.close(module_info
[0])
195 "Cannot open openflow controller module '%s'; %s: %s; revise 'of_controller' field of configuration file.",
196 module
, type(e
).__name
__, str(e
))
197 raise ovimException("Cannot open openflow controller module '{}'; {}: {}; revise 'of_controller' field of configuration file.".fromat(
198 module
, type(e
).__name
__, str(e
)))
201 # create openflow thread
202 thread
= oft
.openflow_thread(OF_conn
, of_test
=of_test_mode
, db
=db_of
, db_lock
=db_lock
,
203 pmp_with_same_vlan
=self
.config
['of_controller_nets_with_same_vlan'],
204 debug
=self
.config
['log_level_of'])
205 r
, c
= thread
.OF_connector
.obtain_port_correspondence()
207 raise ovimException("Cannot get openflow information %s", c
)
209 self
.config
['of_thread'] = thread
211 # create dhcp_server thread
212 host_test_mode
= True if self
.config
['mode'] == 'test' or self
.config
['mode'] == "OF only" else False
213 dhcp_params
= self
.config
.get("dhcp_server")
215 thread
= dt
.dhcp_thread(dhcp_params
=dhcp_params
, test
=host_test_mode
, dhcp_nets
=self
.config
["dhcp_nets"],
216 db
=db_of
, db_lock
=db_lock
, debug
=self
.config
['log_level_of'])
218 self
.config
['dhcp_thread'] = thread
220 # Create one thread for each host
221 host_test_mode
= True if self
.config
['mode'] == 'test' or self
.config
['mode'] == "OF only" else False
222 host_develop_mode
= True if self
.config
['mode'] == 'development' else False
223 host_develop_bridge_iface
= self
.config
.get('development_bridge', None)
224 self
.config
['host_threads'] = {}
226 host
['image_path'] = '/opt/VNF/images/openvim'
227 thread
= ht
.host_thread(name
=host
['name'], user
=host
['user'], host
=host
['ip_name'], db
=db_of
, db_lock
=db_lock
,
228 test
=host_test_mode
, image_path
=self
.config
['image_path'], version
=self
.config
['version'],
229 host_id
=host
['uuid'], develop_mode
=host_develop_mode
,
230 develop_bridge_iface
=host_develop_bridge_iface
)
232 self
.config
['host_threads'][host
['uuid']] = thread
234 # create ovs dhcp thread
235 result
, content
= self
.db
.get_table(FROM
='nets')
237 self
.logger
.error("http_get_ports Error %d %s", result
, content
)
238 raise ovimException(str(content
), -result
)
241 net_type
= net
['type']
242 if net_type
== 'bridge_data' or net_type
== 'bridge_man' \
243 and net
["provider"][:4] =="OVS:" and net
["enable_dhcp"] == "true":
244 self
.launch_dhcp_server(net
['vlan'],
245 net
['dhcp_first_ip'],
250 def stop_service(self
):
251 threads
= self
.config
.get('host_threads', {})
252 if 'of_thread' in self
.config
:
253 threads
['of'] = (self
.config
['of_thread'])
254 if 'dhcp_thread' in self
.config
:
255 threads
['dhcp'] = (self
.config
['dhcp_thread'])
257 for thread
in threads
.values():
258 thread
.insert_task("exit")
259 for thread
in threads
.values():
262 def get_networks(self
, select_
=None, where_
=None, limit_
=100):
264 Retreive networks available
265 :param select_: List with select query parameters
266 :param where_: List with where query parameters
267 :param limit_: Query limit result
270 result
, content
= self
.db
.get_table(SELECT
=select_
, FROM
='nets', WHERE
=where_
, LIMIT
=limit_
)
273 raise ovimException(str(content
), -result
)
275 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
279 def get_network_by_id(self
, where_
, limit_
=100):
287 if 'uuid' not in where_
:
288 raise ovimException("Not network id was not found" )
289 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
=where_
, LIMIT
=limit_
)
291 network_id
= where_
['uuid']
294 raise ovimException(str(content
), -result
)
296 raise ovimException("http_get_networks_id network '%s' not found" % network_id
, -result
)
298 convert_boolean(content
, ('shared', 'admin_state_up', 'enable_dhcp'))
300 result
, ports
= self
.db
.get_table(FROM
='ports', SELECT
=('uuid as port_id',),
301 WHERE
={'net_id': network_id
}, LIMIT
=100)
303 content
[0]['ports'] = ports
306 def set_network(self
, network
):
311 tenant_id
= network
.get('tenant_id')
314 result
, _
= self
.db
.get_table(FROM
='tenants', SELECT
=('uuid',), WHERE
={'uuid': tenant_id
, "enabled": True})
316 raise ovimException("set_network error, no tenant founded", -result
)
320 net_provider
= network
.get('provider')
321 net_type
= network
.get('type')
322 net_enable_dhcp
= network
.get('enable_dhcp')
324 net_cidr
= network
.get('cidr')
326 net_vlan
= network
.get("vlan")
327 net_bind_net
= network
.get("bind_net")
328 net_bind_type
= network
.get("bind_type")
329 name
= network
["name"]
331 # check if network name ends with :<vlan_tag> and network exist in order to make and automated bindning
332 vlan_index
= name
.rfind(":")
333 if not net_bind_net
and not net_bind_type
and vlan_index
> 1:
335 vlan_tag
= int(name
[vlan_index
+ 1:])
336 if not vlan_tag
and vlan_tag
< 4096:
337 net_bind_net
= name
[:vlan_index
]
338 net_bind_type
= "vlan:" + name
[vlan_index
+ 1:]
343 # look for a valid net
344 if self
._check
_valid
_uuid
(net_bind_net
):
345 net_bind_key
= "uuid"
347 net_bind_key
= "name"
348 result
, content
= self
.db
.get_table(FROM
='nets', WHERE
={net_bind_key
: net_bind_net
})
350 raise ovimException(' getting nets from db ' + content
, HTTP_Internal_Server_Error
)
352 raise ovimException(" bind_net %s '%s'not found" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
354 raise ovimException(" more than one bind_net %s '%s' found, use uuid" % (net_bind_key
, net_bind_net
), HTTP_Bad_Request
)
355 network
["bind_net"] = content
[0]["uuid"]
358 if net_bind_type
[0:5] != "vlan:":
359 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>'", HTTP_Bad_Request
)
360 if int(net_bind_type
[5:]) > 4095 or int(net_bind_type
[5:]) <= 0:
361 raise ovimException("bad format for 'bind_type', must be 'vlan:<tag>' with a tag between 1 and 4095",
363 network
["bind_type"] = net_bind_type
366 if net_provider
[:9] == "openflow:":
368 if net_type
!= "ptp" and net_type
!= "data":
369 raise ovimException(" only 'ptp' or 'data' net types can be bound to 'openflow'",
375 if net_type
!= "bridge_man" and net_type
!= "bridge_data":
376 raise ovimException("Only 'bridge_man' or 'bridge_data' net types can be bound "
377 "to 'bridge', 'macvtap' or 'default", HTTP_Bad_Request
)
379 net_type
= 'bridge_man'
382 net_type
= 'bridge_man'
385 if net_provider
[:7] == 'bridge:':
386 # check it is one of the pre-provisioned bridges
387 bridge_net_name
= net_provider
[7:]
388 for brnet
in self
.config
['bridge_nets']:
389 if brnet
[0] == bridge_net_name
: # free
391 raise ovimException("invalid 'provider:physical', "
392 "bridge '%s' is already used" % bridge_net_name
, HTTP_Conflict
)
396 # if bridge_net==None:
397 # bottle.abort(HTTP_Bad_Request, "invalid 'provider:physical', bridge '%s' is not one of the provisioned 'bridge_ifaces' in the configuration file" % bridge_net_name)
399 elif self
.config
['network_type'] == 'bridge' and (net_type
== 'bridge_data' or net_type
== 'bridge_man'):
400 # look for a free precreated nets
401 for brnet
in self
.config
['bridge_nets']:
402 if not brnet
[3]: # free
404 if net_type
== 'bridge_man': # look for the smaller speed
405 if brnet
[2] < bridge_net
[2]:
407 else: # look for the larger speed
408 if brnet
[2] > bridge_net
[2]:
414 raise ovimException("Max limits of bridge networks reached. Future versions of VIM "
415 "will overcome this limit", HTTP_Bad_Request
)
417 print "using net", bridge_net
418 net_provider
= "bridge:" + bridge_net
[0]
419 net_vlan
= bridge_net
[1]
420 elif net_type
== 'bridge_data' or net_type
== 'bridge_man' and self
.config
['network_type'] == 'ovs':
422 if not net_vlan
and (net_type
== "data" or net_type
== "ptp" or net_provider
== "OVS"):
423 net_vlan
= self
.db
.get_free_net_vlan()
425 raise ovimException("Error getting an available vlan", HTTP_Internal_Server_Error
)
426 if net_provider
== 'OVS':
427 net_provider
= 'OVS' + ":" + str(net_vlan
)
429 network
['provider'] = net_provider
430 network
['type'] = net_type
431 network
['vlan'] = net_vlan
432 dhcp_integrity
= True
433 if 'enable_dhcp' in network
and network
['enable_dhcp']:
434 dhcp_integrity
= self
._check
_dhcp
_data
_integrity
(network
)
436 result
, content
= self
.db
.new_row('nets', network
, True, True)
438 if result
>= 0 and dhcp_integrity
:
440 bridge_net
[3] = content
441 if self
.config
.get("dhcp_server") and self
.config
['network_type'] == 'bridge':
442 if network
["name"] in self
.config
["dhcp_server"].get("nets", ()):
443 self
.config
["dhcp_nets"].append(content
)
444 print "dhcp_server: add new net", content
445 elif not bridge_net
and bridge_net
[0] in self
.config
["dhcp_server"].get("bridge_ifaces", ()):
446 self
.config
["dhcp_nets"].append(content
)
447 print "dhcp_server: add new net", content
450 print "http_post_networks error %d %s" % (result
, content
)
451 raise ovimException("Error posting network", HTTP_Internal_Server_Error
)
454 def _check_dhcp_data_integrity(network
):
456 Check if all dhcp parameter for anet are valid, if not will be calculated from cidr value
457 :param network: list with user nets paramters
462 if "cidr" in network
:
463 cidr
= network
["cidr"]
464 ip_tools
= IPNetwork(cidr
)
465 cidr_len
= ip_tools
.prefixlen
469 ips
= IPNetwork(cidr
)
470 if "dhcp_first_ip" not in network
:
471 network
["dhcp_first_ip"] = str(ips
[2])
472 if "dhcp_last_ip" not in network
:
473 network
["dhcp_last_ip"] = str(ips
[-2])
474 if "gateway_ip" not in network
:
475 network
["gateway_ip"] = str(ips
[1])
482 def _check_valid_uuid( uuid
):
483 id_schema
= {"type": "string", "pattern": "^[a-fA-F0-9]{8}(-[a-fA-F0-9]{4}){3}-[a-fA-F0-9]{12}$"}
485 js_v(uuid
, id_schema
)
487 except js_e
.ValidationError
:
490 def get_openflow_rules(self
, network_id
=None):
492 Get openflow id from DB
493 :param network_id: Network id, if none all networks will be retrieved
494 :return: Return a list with Openflow rules per net
500 where_
= {"net_id": network_id
}
502 result
, content
= self
.db
.get_table(
503 SELECT
=("name", "net_id", "priority", "vlan_id", "ingress_port", "src_mac", "dst_mac", "actions"),
504 WHERE
=where_
, FROM
='of_flows')
507 raise ovimException(str(content
), -result
)
510 def update_openflow_rules(self
, network_id
=None):
513 To make actions over the net. The action is to reinstall the openflow rules
514 network_id can be 'all'
515 :param network_id: Network id, if none all networks will be retrieved
516 :return : Number of nets updated
523 where_
= {"uuid": network_id
}
524 result
, content
= self
.db
.get_table(SELECT
=("uuid", "type"), WHERE
=where_
, FROM
='nets')
527 raise ovimException(str(content
), -result
)
530 if net
["type"] != "ptp" and net
["type"] != "data":
533 r
, c
= self
.config
['of_thread'].insert_task("update-net", net
['uuid'])
535 raise ovimException(str(c
), -r
)
538 def clear_openflow_rules(self
):
540 To make actions over the net. The action is to delete ALL openflow rules
541 :return: return operation result
544 r
, c
= self
.config
['of_thread'].insert_task("clear-all")
546 raise ovimException(str(c
), -r
)
549 def get_openflow_ports(self
):
551 Obtain switch ports names of openflow controller
552 :return: Return flow ports in DB
554 data
= {'ports': self
.config
['of_thread'].OF_connector
.pp2ofi
}
557 def get_ports(self
, columns
=None, filter={}, limit
=None):
558 # result, content = my.db.get_ports(where_)
559 result
, content
= self
.db
.get_table(SELECT
=columns
, WHERE
=filter, FROM
='ports', LIMIT
=limit
)
561 self
.logger
.error("http_get_ports Error %d %s", result
, content
)
562 raise ovimException(str(content
), -result
)
564 convert_boolean(content
, ('admin_state_up',))
567 def new_port(self
, port_data
):
568 port_data
['type'] = 'external'
569 if port_data
.get('net_id'):
570 # check that new net has the correct type
571 result
, new_net
= self
.db
.check_target_net(port_data
['net_id'], None, 'external')
573 raise ovimException(str(new_net
), -result
)
574 # insert in data base
575 result
, uuid
= self
.db
.new_row('ports', port_data
, True, True)
577 if 'net_id' in port_data
:
578 r
, c
= self
.config
['of_thread'].insert_task("update-net", port_data
['net_id'])
580 self
.logger
.error("Cannot insert a task for updating network '$s' %s", port_data
['net_id'], c
)
581 #TODO put network in error status
584 raise ovimException(str(uuid
), -result
)
586 def delete_port(self
, port_id
):
587 # Look for the previous port data
588 result
, ports
= self
.db
.get_table(WHERE
={'uuid': port_id
, "type": "external"}, FROM
='ports')
590 raise ovimException("Cannot get port info from database: {}".format(ports
), http_code
=-result
)
591 # delete from the data base
592 result
, content
= self
.db
.delete_row('ports', port_id
)
594 raise ovimException("External port '{}' not found".format(port_id
), http_code
=HTTP_Not_Found
)
596 raise ovimException("Cannot delete port from database: {}".format(content
), http_code
=-result
)
598 network
= ports
[0].get('net_id', None)
601 r
, c
= self
.config
['of_thread'].insert_task("update-net", network
)
603 self
.logger
.error("Cannot insert a task for updating network '$s' %s", network
, c
)
607 def edit_port(self
, port_id
, port_data
, admin
=True):
608 # Look for the previous port data
609 result
, content
= self
.db
.get_table(FROM
="ports", WHERE
={'uuid': port_id
})
611 raise ovimException("Cannot get port info from database: {}".format(content
), http_code
=-result
)
613 raise ovimException("Port '{}' not found".format(port_id
), http_code
=HTTP_Not_Found
)
618 if 'net_id' in port_data
:
620 old_net
= port
.get('net_id', None)
621 new_net
= port_data
['net_id']
622 if old_net
!= new_net
:
625 nets
.append(new_net
) # put first the new net, so that new openflow rules are created before removing the old ones
628 if port
['type'] == 'instance:bridge' or port
['type'] == 'instance:ovs':
629 raise ovimException("bridge interfaces cannot be attached to a different net", http_code
=HTTP_Forbidden
)
630 elif port
['type'] == 'external' and not admin
:
631 raise ovimException("Needed admin privileges",http_code
=HTTP_Unauthorized
)
633 # check that new net has the correct type
634 result
, new_net_dict
= self
.db
.check_target_net(new_net
, None, port
['type'])
636 raise ovimException("Error {}".format(new_net_dict
), http_code
=HTTP_Conflict
)
637 # change VLAN for SR-IOV ports
638 if result
>= 0 and port
["type"] == "instance:data" and port
["model"] == "VF": # TODO consider also VFnotShared
640 port_data
["vlan"] = None
642 port_data
["vlan"] = new_net_dict
["vlan"]
643 # get host where this VM is allocated
644 result
, content
= self
.db
.get_table(FROM
="instances", WHERE
={"uuid": port
["instance_id"]})
646 host_id
= content
[0]["host_id"]
648 # insert in data base
650 result
, content
= self
.db
.update_rows('ports', port_data
, WHERE
={'uuid': port_id
}, log
=False)
652 # Insert task to complete actions
655 r
, v
= self
.config
['of_thread'].insert_task("update-net", net_id
)
657 self
.logger
.error("Error updating network '{}' {}".format(r
,v
))
658 # TODO Do something if fails
660 r
, v
= self
.config
['host_threads'][host_id
].insert_task("edit-iface", port_id
, old_net
, new_net
)
662 self
.logger
.error("Error updating network '{}' {}".format(r
,v
))
663 # TODO Do something if fails
667 raise ovimException("Error {}".format(content
), http_code
=-result
)
669 def get_dhcp_controller(self
):
671 Create an host_thread object for manage openvim controller and not create a thread for itself
672 :return: dhcp_host openvim controller object
675 if 'openvim_controller' in self
.config
['host_threads']:
676 return self
.config
['host_threads']['openvim_controller']
679 controller_ip
= self
.config
['ovs_controller_ip']
680 ovs_controller_user
= self
.config
['ovs_controller_user']
682 host_test_mode
= True if self
.config
['mode'] == 'test' or self
.config
['mode'] == "OF only" else False
683 host_develop_mode
= True if self
.config
['mode'] == 'development' else False
685 dhcp_host
= ht
.host_thread(name
='openvim_controller', user
=ovs_controller_user
, host
=controller_ip
,
686 db
=self
.config
['db'],
687 db_lock
=self
.config
['db_lock'], test
=host_test_mode
,
688 image_path
=self
.config
['image_path'], version
=self
.config
['version'],
689 host_id
='openvim_controller', develop_mode
=host_develop_mode
,
690 develop_bridge_iface
=bridge_ifaces
)
692 self
.config
['host_threads']['openvim_controller'] = dhcp_host
693 if not host_test_mode
:
694 dhcp_host
.ssh_connect()
697 def launch_dhcp_server(self
, vlan
, first_ip
, last_ip
, cidr
, gateway
):
699 Launch a dhcpserver base on dnsmasq attached to the net base on vlan id across the the openvim computes
700 :param vlan: vlan identifier
701 :param first_ip: First dhcp range ip
702 :param last_ip: Last dhcp range ip
703 :param cidr: net cidr
706 ip_tools
= IPNetwork(cidr
)
707 dhcp_netmask
= str(ip_tools
.netmask
)
708 ip_range
= [first_ip
, last_ip
]
710 dhcp_path
= self
.config
['ovs_controller_file_path']
712 controller_host
= self
.get_dhcp_controller()
713 controller_host
.create_linux_bridge(vlan
)
714 controller_host
.create_dhcp_interfaces(vlan
, first_ip
, dhcp_netmask
)
715 controller_host
.launch_dhcp_server(vlan
, ip_range
, dhcp_netmask
, dhcp_path
, gateway
)