1 # Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
2 # and others. All rights reserved.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 from neutronclient.common.exceptions import NotFound
18 from neutronclient.neutron.client import Client
20 from snaps.domain.network import (
21 Port, SecurityGroup, SecurityGroupRule, Router, InterfaceRouter, Subnet,
23 from snaps.domain.project import NetworkQuotas
24 from snaps.domain.vm_inst import FloatingIp
25 from snaps.openstack.utils import keystone_utils
27 __author__ = 'spisarski'
29 logger = logging.getLogger('neutron_utils')
32 Utilities for basic neutron API calls
36 def neutron_client(os_creds, session=None):
38 Instantiates and returns a client for communications with OpenStack's
40 :param os_creds: the credentials for connecting to the OpenStack remote API
41 :param session: the keystone session object (optional)
42 :return: the client object
45 session = keystone_utils.keystone_session(os_creds)
46 return Client(api_version=os_creds.network_api_version,
48 region_name=os_creds.region_name)
51 def create_network(neutron, os_creds, network_settings):
53 Creates a network for OpenStack
54 :param neutron: the client
55 :param os_creds: the OpenStack credentials
56 :param network_settings: A dictionary containing the network configuration
57 and is responsible for creating the network
59 :return: a SNAPS-OO Network domain object if found else None
61 logger.info('Creating network with name ' + network_settings.name)
62 json_body = network_settings.dict_for_neutron(os_creds)
63 os_network = neutron.create_network(body=json_body)
66 network = get_network_by_id(neutron, os_network['network']['id'])
69 for subnet_settings in network_settings.subnet_settings:
72 create_subnet(neutron, subnet_settings, os_creds, network))
75 'Unexpected error creating subnet [%s] for network [%s]',
76 subnet_settings.name, network.name)
78 for subnet in subnets:
79 delete_subnet(neutron, subnet)
81 delete_network(neutron, network)
85 return get_network_by_id(neutron, network.id)
88 def delete_network(neutron, network):
90 Deletes a network for OpenStack
91 :param neutron: the client
92 :param network: a SNAPS-OO Network domain object
94 if neutron and network:
96 for subnet in network.subnets:
97 logger.info('Deleting subnet with name ' + subnet.name)
99 delete_subnet(neutron, subnet)
103 logger.info('Deleting network with name ' + network.name)
104 neutron.delete_network(network.id)
107 def get_network(neutron, keystone, network_settings=None, network_name=None,
110 Returns Network SNAPS-OO domain object the first network found with
111 either the given attributes from the network_settings object if not None,
112 else the query will use just the name from the network_name parameter.
113 When the project_name is included, that will be added to the query filter.
114 :param neutron: the Neutron client
115 :param keystone: the Keystone client
116 :param network_settings: the NetworkConfig object used to create filter
117 :param network_name: the name of the network to retrieve
118 :param project_name: the name of the network's project
119 :return: a SNAPS-OO Network domain object
123 net_filter['name'] = network_settings.name
125 net_filter['name'] = network_name
127 networks = neutron.list_networks(**net_filter)
128 for network, netInsts in networks.items():
129 for inst in netInsts:
131 project = keystone_utils.get_project_by_id(
132 keystone, inst['project_id'])
133 if project and project.name == project_name:
134 return __map_network(neutron, inst)
136 return __map_network(neutron, inst)
139 def __get_os_network_by_id(neutron, network_id):
141 Returns the OpenStack network object (dictionary) with the given ID else
143 :param neutron: the client
144 :param network_id: the id of the network to retrieve
145 :return: a SNAPS-OO Network domain object
147 networks = neutron.list_networks(**{'id': network_id})
148 for network in networks['networks']:
149 if network['id'] == network_id:
153 def get_network_by_id(neutron, network_id):
155 Returns the SNAPS Network domain object for the given ID else None
156 :param neutron: the client
157 :param network_id: the id of the network to retrieve
158 :return: a SNAPS-OO Network domain object
160 os_network = __get_os_network_by_id(neutron, network_id)
162 return __map_network(neutron, os_network)
165 def __map_network(neutron, os_network):
167 Returns the network object (dictionary) with the given ID else None
168 :param neutron: the client
169 :param os_network: the OpenStack Network dict
170 :return: a SNAPS-OO Network domain object
172 subnets = get_subnets_by_network_id(neutron, os_network['id'])
173 os_network['subnets'] = subnets
174 return Network(**os_network)
177 def create_subnet(neutron, subnet_settings, os_creds, network):
179 Creates a network subnet for OpenStack
180 :param neutron: the client
181 :param subnet_settings: A dictionary containing the subnet configuration
182 and is responsible for creating the subnet request
184 :param os_creds: the OpenStack credentials
185 :param network: the network object
186 :return: a SNAPS-OO Subnet domain object
188 if neutron and network and subnet_settings:
189 json_body = {'subnets': [subnet_settings.dict_for_neutron(
190 os_creds, network=network)]}
191 logger.info('Creating subnet with name ' + subnet_settings.name)
192 subnets = neutron.create_subnet(body=json_body)
193 return Subnet(**subnets['subnets'][0])
195 raise NeutronException('Failed to create subnet')
198 def delete_subnet(neutron, subnet):
200 Deletes a network subnet for OpenStack
201 :param neutron: the client
202 :param subnet: a SNAPS-OO Subnet domain object
204 if neutron and subnet:
205 logger.info('Deleting subnet with name ' + subnet.name)
206 neutron.delete_subnet(subnet.id)
209 def get_subnet(neutron, network, subnet_settings=None, subnet_name=None):
211 Returns the first subnet object that fits the query else None including
212 if subnet_settings or subnet_name parameters are None.
213 :param neutron: the client
214 :param network: the associated SNAPS-OO Network domain object
215 :param subnet_settings: the subnet settings of the object to retrieve
216 :param subnet_name: the name of the subnet to retrieve
217 :return: a SNAPS-OO Subnet domain object or None
219 sub_filter = {'network_id': network.id}
221 sub_filter['name'] = subnet_settings.name
222 sub_filter['cidr'] = subnet_settings.cidr
223 if subnet_settings.gateway_ip:
224 sub_filter['gateway_ip'] = subnet_settings.gateway_ip
226 if subnet_settings.enable_dhcp is not None:
227 sub_filter['enable_dhcp'] = subnet_settings.enable_dhcp
229 if subnet_settings.destination:
230 sub_filter['destination'] = subnet_settings.destination
232 if subnet_settings.nexthop:
233 sub_filter['nexthop'] = subnet_settings.nexthop
235 if subnet_settings.ipv6_ra_mode:
236 sub_filter['ipv6_ra_mode'] = subnet_settings.ipv6_ra_mode
238 if subnet_settings.ipv6_address_mode:
239 sub_filter['ipv6_address_mode'] = subnet_settings.ipv6_address_mode
241 sub_filter['name'] = subnet_name
245 subnets = neutron.list_subnets(**sub_filter)
246 for subnet in subnets['subnets']:
247 return Subnet(**subnet)
250 def get_subnet_by_name(neutron, keystone, subnet_name, project_name=None):
252 Returns the first subnet object that fits the query else None including
253 if subnet_settings or subnet_name parameters are None.
254 :param neutron: the Neutron client
255 :param keystone: the Keystone client
256 :param subnet_name: the name of the subnet to retrieve
257 :param project_name: the name of the associated project to the subnet to
259 :return: a SNAPS-OO Subnet domain object or None
263 project = keystone_utils.get_project(
264 keystone, project_name=project_name)
266 sub_filter = {'name': subnet_name, 'project_id': project.id}
267 subnets = neutron.list_subnets(**sub_filter)
268 for subnet in subnets['subnets']:
269 return Subnet(**subnet)
271 sub_filter = {'name': subnet_name}
272 subnets = neutron.list_subnets(**sub_filter)
273 for subnet in subnets['subnets']:
274 return Subnet(**subnet)
277 def get_subnet_by_id(neutron, subnet_id):
279 Returns a SNAPS-OO Subnet domain object for a given ID
280 :param neutron: the OpenStack neutron client
281 :param subnet_id: the subnet ID
282 :return: a Subnet object
284 os_subnet = neutron.show_subnet(subnet_id)
285 if os_subnet and 'subnet' in os_subnet:
286 return Subnet(**os_subnet['subnet'])
289 def get_subnets_by_network(neutron, network):
291 Returns a list of SNAPS-OO Subnet domain objects
292 :param neutron: the OpenStack neutron client
293 :param network: the SNAPS-OO Network domain object
294 :return: a list of Subnet objects
296 return get_subnets_by_network_id(neutron, network.id)
299 def get_subnets_by_network_id(neutron, network_id):
301 Returns a list of SNAPS-OO Subnet domain objects
302 :param neutron: the OpenStack neutron client
303 :param network_id: the subnet's ID
304 :return: a list of Subnet objects
308 os_subnets = neutron.list_subnets(network_id=network_id)
310 for os_subnet in os_subnets['subnets']:
311 out.append(Subnet(**os_subnet))
316 def create_router(neutron, os_creds, router_settings):
318 Creates a router for OpenStack
319 :param neutron: the client
320 :param os_creds: the OpenStack credentials
321 :param router_settings: A dictionary containing the router configuration
322 and is responsible for creating the subnet request
324 :return: a SNAPS-OO Router domain object
327 json_body = router_settings.dict_for_neutron(neutron, os_creds)
328 logger.info('Creating router with name - ' + router_settings.name)
329 os_router = neutron.create_router(json_body)
330 return __map_router(neutron, os_router['router'])
332 logger.error("Failed to create router.")
333 raise NeutronException('Failed to create router')
336 def delete_router(neutron, router):
338 Deletes a router for OpenStack
339 :param neutron: the client
340 :param router: a SNAPS-OO Router domain object
342 if neutron and router:
343 logger.info('Deleting router with name - ' + router.name)
344 neutron.delete_router(router=router.id)
347 def get_router_by_id(neutron, router_id):
349 Returns a router with a given ID, else None if not found
350 :param neutron: the client
351 :param router_id: the Router ID
352 :return: a SNAPS-OO Router domain object
354 router = neutron.show_router(router_id)
356 return __map_router(neutron, router['router'])
359 def get_router(neutron, keystone, router_settings=None, router_name=None,
362 Returns the first router object (dictionary) found the given the settings
363 values if not None, else finds the first with the value of the router_name
365 :param neutron: the Neutron client
366 :param keystone: the Keystone client
367 :param router_settings: the RouterConfig object
368 :param router_name: the name of the network to retrieve
369 :param project_name: the name of the router's project
370 :return: a SNAPS-OO Router domain object
372 router_filter = dict()
374 router_filter['name'] = router_settings.name
375 if router_settings.admin_state_up is not None:
376 router_filter['admin_state_up'] = router_settings.admin_state_up
378 router_filter['name'] = router_name
382 os_routers = neutron.list_routers(**router_filter)
383 for os_router in os_routers['routers']:
385 project = keystone_utils.get_project_by_id(
386 keystone, os_router['project_id'])
387 if project and project.name == project_name:
388 return __map_router(neutron, os_router)
391 def __map_router(neutron, os_router):
393 Takes an OpenStack router instance and maps it to a SNAPS Router domain
395 :param neutron: the neutron client
396 :param os_router: the OpenStack Router object
399 device_ports = neutron.list_ports(
400 **{'device_id': os_router['id']})['ports']
401 port_subnets = list()
403 # Order by create date
404 sorted_ports = sorted(
405 device_ports, key=lambda dev_port: dev_port['created_at'])
407 for port in sorted_ports:
409 for fixed_ip in port['fixed_ips']:
410 subnet = get_subnet_by_id(neutron, fixed_ip['subnet_id'])
411 if subnet and subnet.network_id == port['network_id']:
412 subnets.append(subnet)
413 port_subnets.append((Port(**port), subnets))
415 os_router['port_subnets'] = port_subnets
416 return Router(**os_router)
419 def add_interface_router(neutron, router, subnet=None, port=None):
421 Adds an interface router for OpenStack for either a subnet or port.
422 Exception will be raised if requesting for both.
423 :param neutron: the client
424 :param router: the router object
425 :param subnet: the subnet object
426 :param port: the port object
427 :return: the interface router object
430 raise NeutronException(
431 'Cannot add interface to the router. Both subnet and '
432 'port were sent in. Either or please.')
434 if neutron and router and (router or subnet):
435 logger.info('Adding interface to router with name ' + router.name)
436 os_intf_router = neutron.add_interface_router(
437 router=router.id, body=__create_port_json_body(subnet, port))
438 return InterfaceRouter(**os_intf_router)
440 raise NeutronException(
441 'Unable to create interface router as neutron client,'
442 ' router or subnet were not created')
445 def remove_interface_router(neutron, router, subnet=None, port=None):
447 Removes an interface router for OpenStack
448 :param neutron: the client
449 :param router: the SNAPS-OO Router domain object
450 :param subnet: the subnet object (either subnet or port, not both)
451 :param port: the port object
455 logger.info('Removing router interface from router named ' +
457 neutron.remove_interface_router(
459 body=__create_port_json_body(subnet, port))
460 except NotFound as e:
461 logger.warning('Could not remove router interface. NotFound - %s',
465 logger.warning('Could not remove router interface, No router object')
468 def __create_port_json_body(subnet=None, port=None):
470 Returns the dictionary required for creating and deleting router
471 interfaces. Will only work on a subnet or port object. Will throw and
472 exception if parameters contain both or neither
473 :param subnet: the subnet object
474 :param port: the port object
478 raise NeutronException(
479 'Cannot create JSON body with both subnet and port')
480 if not subnet and not port:
481 raise NeutronException(
482 'Cannot create JSON body without subnet or port')
485 return {"subnet_id": subnet.id}
487 return {"port_id": port.id}
490 def create_port(neutron, os_creds, port_settings):
492 Creates a port for OpenStack
493 :param neutron: the client
494 :param os_creds: the OpenStack credentials
495 :param port_settings: the settings object for port configuration
496 :return: the SNAPS-OO Port domain object
498 json_body = port_settings.dict_for_neutron(neutron, os_creds)
499 logger.info('Creating port for network with name - %s',
500 port_settings.network_name)
501 os_port = neutron.create_port(body=json_body)['port']
502 return Port(**os_port)
505 def delete_port(neutron, port):
507 Removes an OpenStack port
508 :param neutron: the client
509 :param port: the SNAPS-OO Port domain object
511 logger.info('Deleting port with name ' + port.name)
512 neutron.delete_port(port.id)
515 def get_port(neutron, keystone, port_settings=None, port_name=None,
518 Returns the first port object (dictionary) found for the given query
519 :param neutron: the Neutron client
520 :param keystone: the Keystone client
521 :param port_settings: the PortConfig object used for generating the query
522 :param port_name: if port_settings is None, this name is the value to place
524 :param project_name: the associated project name
525 :return: a SNAPS-OO Port domain object
530 if port_settings.name and len(port_settings.name) > 0:
531 port_filter['name'] = port_settings.name
532 if port_settings.admin_state_up:
533 port_filter['admin_state_up'] = port_settings.admin_state_up
534 if port_settings.device_id:
535 port_filter['device_id'] = port_settings.device_id
536 if port_settings.mac_address:
537 port_filter['mac_address'] = port_settings.mac_address
538 if port_settings.project_name:
539 project_name = port_settings.project_name
540 if port_settings.network_name:
541 network = get_network(
542 neutron, keystone, network_name=port_settings.network_name,
543 project_name=project_name)
545 port_filter['network_id'] = network.id
547 port_filter['name'] = port_name
549 ports = neutron.list_ports(**port_filter)
550 for port in ports['ports']:
552 project = keystone_utils.get_project_by_id(
553 keystone, port['project_id'])
554 if project and project.name == project_name:
561 def get_port_by_id(neutron, port_id):
563 Returns a SNAPS-OO Port domain object for the given ID or none if not found
564 :param neutron: the client
565 :param port_id: the to query
566 :return: a SNAPS-OO Port domain object or None
568 port = neutron.show_port(port_id)
570 return Port(**port['port'])
574 def get_ports(neutron, network, ips=None):
576 Returns a list of SNAPS-OO Port objects for all OpenStack Port objects that
577 are associated with the 'network' parameter
578 :param neutron: the client
579 :param network: SNAPS-OO Network domain object
580 :param ips: the IPs to lookup if not None
581 :return: a SNAPS-OO Port domain object or None if not found
584 ports = neutron.list_ports(**{'network_id': network.id})
585 for port in ports['ports']:
587 for fixed_ips in port['fixed_ips']:
588 if ('ip_address' in fixed_ips and
589 fixed_ips['ip_address'] in ips) or ips is None:
590 out.append(Port(**port))
593 out.append(Port(**port))
598 def create_security_group(neutron, keystone, sec_grp_settings):
600 Creates a security group object in OpenStack
601 :param neutron: the Neutron client
602 :param keystone: the Keystone client
603 :param sec_grp_settings: the security group settings
604 :return: a SNAPS-OO SecurityGroup domain object
606 logger.info('Creating security group with name - %s',
607 sec_grp_settings.name)
608 os_group = neutron.create_security_group(
609 sec_grp_settings.dict_for_neutron(keystone))
610 return __map_os_security_group(neutron, os_group['security_group'])
613 def delete_security_group(neutron, sec_grp):
615 Deletes a security group object from OpenStack
616 :param neutron: the client
617 :param sec_grp: the SNAPS SecurityGroup object to delete
619 logger.info('Deleting security group with name - %s', sec_grp.name)
620 neutron.delete_security_group(sec_grp.id)
623 def get_security_group(neutron, keystone, sec_grp_settings=None,
624 sec_grp_name=None, project_name=None):
626 Returns the first security group for a given query. The query gets built
627 from the sec_grp_settings parameter if not None, else only the name of
628 the security group will be used, else if the query parameters are None then
629 None will be returned
630 :param neutron: the neutron client
631 :param keystone: the keystone client
632 :param sec_grp_settings: an instance of SecurityGroupConfig object
633 :param sec_grp_name: the name of security group object to retrieve
634 :param project_name: the name of the project/tentant object that owns the
635 secuity group to retrieve
636 :return: a SNAPS-OO SecurityGroup domain object or None if not found
639 sec_grp_filter = dict()
642 sec_grp_filter['name'] = sec_grp_settings.name
644 if sec_grp_settings.description:
645 sec_grp_filter['description'] = sec_grp_settings.description
646 if sec_grp_settings.project_name:
647 project_name = sec_grp_settings.project_name
649 sec_grp_filter['name'] = sec_grp_name
653 groups = neutron.list_security_groups(**sec_grp_filter)
654 for group in groups['security_groups']:
656 project = keystone_utils.get_project_by_id(
657 keystone, group['tenant_id'])
658 if project and project_name == project.name:
659 return __map_os_security_group(neutron, group)
661 return __map_os_security_group(neutron, group)
664 def __map_os_security_group(neutron, os_sec_grp):
666 Creates a SecurityGroup SNAPS domain object from an OpenStack Security
668 :param neutron: the neutron client for performing rule lookups
669 :param os_sec_grp: the OpenStack Security Group dict object
670 :return: a SecurityGroup object
672 os_sec_grp['rules'] = get_rules_by_security_group_id(
673 neutron, os_sec_grp['id'])
674 return SecurityGroup(**os_sec_grp)
677 def get_security_group_by_id(neutron, sec_grp_id):
679 Returns the first security group object of the given name else None
680 :param neutron: the client
681 :param sec_grp_id: the id of the security group to retrieve
682 :return: a SNAPS-OO SecurityGroup domain object or None if not found
684 logger.info('Retrieving security group with ID - ' + sec_grp_id)
686 groups = neutron.list_security_groups(**{'id': sec_grp_id})
687 for group in groups['security_groups']:
688 if group['id'] == sec_grp_id:
689 return __map_os_security_group(neutron, group)
693 def create_security_group_rule(neutron, keystone, sec_grp_rule_settings,
696 Creates a security group rule in OpenStack
697 :param neutron: the neutron client
698 :param keystone: the keystone client
699 :param sec_grp_rule_settings: the security group rule settings
700 :param proj_name: the default project name
701 :return: a SNAPS-OO SecurityGroupRule domain object
703 logger.info('Creating security group to security group - %s',
704 sec_grp_rule_settings.sec_grp_name)
705 os_rule = neutron.create_security_group_rule(
706 sec_grp_rule_settings.dict_for_neutron(neutron, keystone, proj_name))
707 return SecurityGroupRule(**os_rule['security_group_rule'])
710 def delete_security_group_rule(neutron, sec_grp_rule):
712 Deletes a security group rule object from OpenStack
713 :param neutron: the client
714 :param sec_grp_rule: the SNAPS SecurityGroupRule object to delete
716 logger.info('Deleting security group rule with ID - %s',
718 neutron.delete_security_group_rule(sec_grp_rule.id)
721 def get_rules_by_security_group(neutron, sec_grp):
723 Retrieves all of the rules for a given security group
724 :param neutron: the client
725 :param sec_grp: a list of SNAPS SecurityGroupRule domain objects
727 return get_rules_by_security_group_id(neutron, sec_grp.id)
730 def get_rules_by_security_group_id(neutron, sec_grp_id):
732 Retrieves all of the rules for a given security group by it's ID
733 :param neutron: the client
734 :param sec_grp_id: the ID of the associated security group
736 logger.info('Retrieving security group rules associate with the '
737 'security group with ID - %s', sec_grp_id)
739 rules = neutron.list_security_group_rules(
740 **{'security_group_id': sec_grp_id})
741 for rule in rules['security_group_rules']:
742 if rule['security_group_id'] == sec_grp_id:
743 out.append(SecurityGroupRule(**rule))
747 def get_rule_by_id(neutron, sec_grp, rule_id):
749 Returns a SecurityGroupRule object from OpenStack
750 :param neutron: the client
751 :param sec_grp: the SNAPS SecurityGroup domain object
752 :param rule_id: the rule's ID
753 :param sec_grp: a SNAPS SecurityGroupRule domain object
755 rules = neutron.list_security_group_rules(
756 **{'security_group_id': sec_grp.id})
757 for rule in rules['security_group_rules']:
758 if rule['id'] == rule_id:
759 return SecurityGroupRule(**rule)
763 def get_external_networks(neutron):
765 Returns a list of external OpenStack network object/dict for all external
767 :param neutron: the client
768 :return: a list of external networks of Type SNAPS-OO domain class Network
771 for network in neutron.list_networks(
772 **{'router:external': True})['networks']:
773 out.append(__map_network(neutron, network))
777 def get_port_floating_ips(neutron, ports):
779 Returns all of the floating IPs associated with the ports returned in a
780 list of tuples where the port object is in the first position and the
781 floating IP object is in the second
782 :param neutron: the Neutron client
783 :param ports: a list of tuple 2 where index 0 is the port name and index 1
784 is the SNAPS-OO Port object
785 :return: a list of tuple 2 (port_id, SNAPS FloatingIp) objects when ports
786 is not None else a list of FloatingIp objects
789 fips = neutron.list_floatingips()
790 for fip in fips['floatingips']:
791 for port_name, port in ports:
792 if port and port.id == fip['port_id']:
793 out.append((port.id, FloatingIp(**fip)))
798 def get_floating_ips(neutron):
800 Returns a list of all of the floating IPs
801 :param neutron: the Neutron client
804 fips = neutron.list_floatingips()
805 for fip in fips['floatingips']:
806 out.append(FloatingIp(**fip))
810 def create_floating_ip(neutron, keystone, ext_net_name, port_id=None):
812 Returns the floating IP object that was created with this call
813 :param neutron: the Neutron client
814 :param keystone: the Keystone client
815 :param ext_net_name: the name of the external network on which to apply the
817 :param port_id: the ID of the port to which the floating IP will be
819 :return: the SNAPS FloatingIp object
821 logger.info('Creating floating ip to external network - ' + ext_net_name)
822 ext_net = get_network(neutron, keystone, network_name=ext_net_name)
824 body = {'floatingip': {'floating_network_id': ext_net.id}}
826 body['floatingip']['port_id'] = port_id
828 fip = neutron.create_floatingip(body=body)
830 return FloatingIp(id=fip['floatingip']['id'],
831 ip=fip['floatingip']['floating_ip_address'])
833 raise NeutronException(
834 'Cannot create floating IP, external network not found')
837 def get_floating_ip(neutron, floating_ip):
839 Returns a floating IP object that should be identical to the floating_ip
841 :param neutron: the Neutron client
842 :param floating_ip: the SNAPS FloatingIp object
843 :return: hopefully the same floating IP object input
845 logger.debug('Attempting to retrieve existing floating ip with IP - %s',
847 os_fip = __get_os_floating_ip(neutron, floating_ip)
849 return FloatingIp(id=os_fip['id'], ip=os_fip['floating_ip_address'])
852 def __get_os_floating_ip(neutron, floating_ip):
854 Returns an OpenStack floating IP object
856 :param neutron: the Neutron client
857 :param floating_ip: the SNAPS FloatingIp object
858 :return: hopefully the same floating IP object input
860 logger.debug('Attempting to retrieve existing floating ip with IP - %s',
862 fips = neutron.list_floatingips(ip=floating_ip.id)
864 for fip in fips['floatingips']:
865 if fip['id'] == floating_ip.id:
869 def delete_floating_ip(neutron, floating_ip):
871 Responsible for deleting a floating IP
872 :param neutron: the Neutron client
873 :param floating_ip: the SNAPS FloatingIp object
876 logger.debug('Attempting to delete existing floating ip with IP - %s',
878 return neutron.delete_floatingip(floating_ip.id)
881 def get_network_quotas(neutron, project_id):
883 Returns a list of NetworkQuotas objects
884 :param neutron: the neutron client
885 :param project_id: the project's ID of the quotas to lookup
886 :return: an object of type NetworkQuotas or None if not found
888 quota = neutron.show_quota(project_id)
890 return NetworkQuotas(**quota['quota'])
893 def update_quotas(neutron, project_id, network_quotas):
895 Updates the networking quotas for a given project
896 :param neutron: the Neutron client
897 :param project_id: the project's ID that requires quota updates
898 :param network_quotas: an object of type NetworkQuotas containing the
903 update_body['security_group'] = network_quotas.security_group
904 update_body['security_group_rule'] = network_quotas.security_group_rule
905 update_body['floatingip'] = network_quotas.floatingip
906 update_body['network'] = network_quotas.network
907 update_body['port'] = network_quotas.port
908 update_body['router'] = network_quotas.router
909 update_body['subnet'] = network_quotas.subnet
911 return neutron.update_quota(project_id, {'quota': update_body})
914 class NeutronException(Exception):
916 Exception when calls to the Keystone client cannot be served properly