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, 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 subnet_settings: the subnet settings of the object to retrieve
215 :param subnet_name: the name of the subnet to retrieve
216 :return: a SNAPS-OO Subnet domain object or None
220 sub_filter['name'] = subnet_settings.name
221 sub_filter['cidr'] = subnet_settings.cidr
222 if subnet_settings.gateway_ip:
223 sub_filter['gateway_ip'] = subnet_settings.gateway_ip
225 if subnet_settings.enable_dhcp is not None:
226 sub_filter['enable_dhcp'] = subnet_settings.enable_dhcp
228 if subnet_settings.destination:
229 sub_filter['destination'] = subnet_settings.destination
231 if subnet_settings.nexthop:
232 sub_filter['nexthop'] = subnet_settings.nexthop
234 if subnet_settings.ipv6_ra_mode:
235 sub_filter['ipv6_ra_mode'] = subnet_settings.ipv6_ra_mode
237 if subnet_settings.ipv6_address_mode:
238 sub_filter['ipv6_address_mode'] = subnet_settings.ipv6_address_mode
240 sub_filter['name'] = subnet_name
244 subnets = neutron.list_subnets(**sub_filter)
245 for subnet in subnets['subnets']:
246 return Subnet(**subnet)
249 def get_subnet_by_id(neutron, subnet_id):
251 Returns a SNAPS-OO Subnet domain object for a given ID
252 :param neutron: the OpenStack neutron client
253 :param subnet_id: the subnet ID
254 :return: a Subnet object
256 os_subnet = neutron.show_subnet(subnet_id)
257 if os_subnet and 'subnet' in os_subnet:
258 return Subnet(**os_subnet['subnet'])
261 def get_subnets_by_network(neutron, network):
263 Returns a list of SNAPS-OO Subnet domain objects
264 :param neutron: the OpenStack neutron client
265 :param network: the SNAPS-OO Network domain object
266 :return: a list of Subnet objects
268 return get_subnets_by_network_id(neutron, network.id)
271 def get_subnets_by_network_id(neutron, network_id):
273 Returns a list of SNAPS-OO Subnet domain objects
274 :param neutron: the OpenStack neutron client
275 :param network_id: the subnet's ID
276 :return: a list of Subnet objects
280 os_subnets = neutron.list_subnets(network_id=network_id)
282 for os_subnet in os_subnets['subnets']:
283 out.append(Subnet(**os_subnet))
288 def create_router(neutron, os_creds, router_settings):
290 Creates a router for OpenStack
291 :param neutron: the client
292 :param os_creds: the OpenStack credentials
293 :param router_settings: A dictionary containing the router configuration
294 and is responsible for creating the subnet request
296 :return: a SNAPS-OO Router domain object
299 json_body = router_settings.dict_for_neutron(neutron, os_creds)
300 logger.info('Creating router with name - ' + router_settings.name)
301 os_router = neutron.create_router(json_body)
302 return __map_router(neutron, os_router['router'])
304 logger.error("Failed to create router.")
305 raise NeutronException('Failed to create router')
308 def delete_router(neutron, router):
310 Deletes a router for OpenStack
311 :param neutron: the client
312 :param router: a SNAPS-OO Router domain object
314 if neutron and router:
315 logger.info('Deleting router with name - ' + router.name)
316 neutron.delete_router(router=router.id)
319 def get_router_by_id(neutron, router_id):
321 Returns a router with a given ID, else None if not found
322 :param neutron: the client
323 :param router_id: the Router ID
324 :return: a SNAPS-OO Router domain object
326 router = neutron.show_router(router_id)
328 return __map_router(neutron, router['router'])
331 def get_router(neutron, keystone, router_settings=None, router_name=None,
334 Returns the first router object (dictionary) found the given the settings
335 values if not None, else finds the first with the value of the router_name
337 :param neutron: the Neutron client
338 :param keystone: the Keystone client
339 :param router_settings: the RouterConfig object
340 :param router_name: the name of the network to retrieve
341 :param project_name: the name of the router's project
342 :return: a SNAPS-OO Router domain object
344 router_filter = dict()
346 router_filter['name'] = router_settings.name
347 if router_settings.admin_state_up is not None:
348 router_filter['admin_state_up'] = router_settings.admin_state_up
350 router_filter['name'] = router_name
354 os_routers = neutron.list_routers(**router_filter)
355 for os_router in os_routers['routers']:
357 project = keystone_utils.get_project_by_id(
358 keystone, os_router['project_id'])
359 if project and project.name == project_name:
360 return __map_router(neutron, os_router)
363 def __map_router(neutron, os_router):
365 Takes an OpenStack router instance and maps it to a SNAPS Router domain
367 :param neutron: the neutron client
368 :param os_router: the OpenStack Router object
371 device_ports = neutron.list_ports(
372 **{'device_id': os_router['id']})['ports']
373 port_subnets = list()
375 # Order by create date
376 sorted_ports = sorted(
377 device_ports, key=lambda dev_port: dev_port['created_at'])
379 for port in sorted_ports:
381 for fixed_ip in port['fixed_ips']:
382 subnet = get_subnet_by_id(neutron, fixed_ip['subnet_id'])
383 if subnet and subnet.network_id == port['network_id']:
384 subnets.append(subnet)
385 port_subnets.append((Port(**port), subnets))
387 os_router['port_subnets'] = port_subnets
388 return Router(**os_router)
391 def add_interface_router(neutron, router, subnet=None, port=None):
393 Adds an interface router for OpenStack for either a subnet or port.
394 Exception will be raised if requesting for both.
395 :param neutron: the client
396 :param router: the router object
397 :param subnet: the subnet object
398 :param port: the port object
399 :return: the interface router object
402 raise NeutronException(
403 'Cannot add interface to the router. Both subnet and '
404 'port were sent in. Either or please.')
406 if neutron and router and (router or subnet):
407 logger.info('Adding interface to router with name ' + router.name)
408 os_intf_router = neutron.add_interface_router(
409 router=router.id, body=__create_port_json_body(subnet, port))
410 return InterfaceRouter(**os_intf_router)
412 raise NeutronException(
413 'Unable to create interface router as neutron client,'
414 ' router or subnet were not created')
417 def remove_interface_router(neutron, router, subnet=None, port=None):
419 Removes an interface router for OpenStack
420 :param neutron: the client
421 :param router: the SNAPS-OO Router domain object
422 :param subnet: the subnet object (either subnet or port, not both)
423 :param port: the port object
427 logger.info('Removing router interface from router named ' +
429 neutron.remove_interface_router(
431 body=__create_port_json_body(subnet, port))
432 except NotFound as e:
433 logger.warning('Could not remove router interface. NotFound - %s',
437 logger.warning('Could not remove router interface, No router object')
440 def __create_port_json_body(subnet=None, port=None):
442 Returns the dictionary required for creating and deleting router
443 interfaces. Will only work on a subnet or port object. Will throw and
444 exception if parameters contain both or neither
445 :param subnet: the subnet object
446 :param port: the port object
450 raise NeutronException(
451 'Cannot create JSON body with both subnet and port')
452 if not subnet and not port:
453 raise NeutronException(
454 'Cannot create JSON body without subnet or port')
457 return {"subnet_id": subnet.id}
459 return {"port_id": port.id}
462 def create_port(neutron, os_creds, port_settings):
464 Creates a port for OpenStack
465 :param neutron: the client
466 :param os_creds: the OpenStack credentials
467 :param port_settings: the settings object for port configuration
468 :return: the SNAPS-OO Port domain object
470 json_body = port_settings.dict_for_neutron(neutron, os_creds)
471 logger.info('Creating port for network with name - %s',
472 port_settings.network_name)
473 os_port = neutron.create_port(body=json_body)['port']
474 return Port(**os_port)
477 def delete_port(neutron, port):
479 Removes an OpenStack port
480 :param neutron: the client
481 :param port: the SNAPS-OO Port domain object
483 logger.info('Deleting port with name ' + port.name)
484 neutron.delete_port(port.id)
487 def get_port(neutron, keystone, port_settings=None, port_name=None,
490 Returns the first port object (dictionary) found for the given query
491 :param neutron: the Neutron client
492 :param keystone: the Keystone client
493 :param port_settings: the PortConfig object used for generating the query
494 :param port_name: if port_settings is None, this name is the value to place
496 :param project_name: the associated project name
497 :return: a SNAPS-OO Port domain object
502 if port_settings.name and len(port_settings.name) > 0:
503 port_filter['name'] = port_settings.name
504 if port_settings.admin_state_up:
505 port_filter['admin_state_up'] = port_settings.admin_state_up
506 if port_settings.device_id:
507 port_filter['device_id'] = port_settings.device_id
508 if port_settings.mac_address:
509 port_filter['mac_address'] = port_settings.mac_address
510 if port_settings.project_name:
511 project_name = port_settings.project_name
512 if port_settings.network_name:
513 network = get_network(
514 neutron, keystone, network_name=port_settings.network_name,
515 project_name=project_name)
517 port_filter['network_id'] = network.id
519 port_filter['name'] = port_name
521 ports = neutron.list_ports(**port_filter)
522 for port in ports['ports']:
524 project = keystone_utils.get_project_by_id(
525 keystone, port['project_id'])
526 if project and project.name == project_name:
533 def get_port_by_id(neutron, port_id):
535 Returns a SNAPS-OO Port domain object for the given ID or none if not found
536 :param neutron: the client
537 :param port_id: the to query
538 :return: a SNAPS-OO Port domain object or None
540 port = neutron.show_port(port_id)
542 return Port(**port['port'])
546 def get_ports(neutron, network, ips=None):
548 Returns a list of SNAPS-OO Port objects for all OpenStack Port objects that
549 are associated with the 'network' parameter
550 :param neutron: the client
551 :param network: SNAPS-OO Network domain object
552 :param ips: the IPs to lookup if not None
553 :return: a SNAPS-OO Port domain object or None if not found
556 ports = neutron.list_ports(**{'network_id': network.id})
557 for port in ports['ports']:
559 for fixed_ips in port['fixed_ips']:
560 if ('ip_address' in fixed_ips and
561 fixed_ips['ip_address'] in ips) or ips is None:
562 out.append(Port(**port))
565 out.append(Port(**port))
570 def create_security_group(neutron, keystone, sec_grp_settings):
572 Creates a security group object in OpenStack
573 :param neutron: the Neutron client
574 :param keystone: the Keystone client
575 :param sec_grp_settings: the security group settings
576 :return: a SNAPS-OO SecurityGroup domain object
578 logger.info('Creating security group with name - %s',
579 sec_grp_settings.name)
580 os_group = neutron.create_security_group(
581 sec_grp_settings.dict_for_neutron(keystone))
582 return __map_os_security_group(neutron, os_group['security_group'])
585 def delete_security_group(neutron, sec_grp):
587 Deletes a security group object from OpenStack
588 :param neutron: the client
589 :param sec_grp: the SNAPS SecurityGroup object to delete
591 logger.info('Deleting security group with name - %s', sec_grp.name)
592 neutron.delete_security_group(sec_grp.id)
595 def get_security_group(neutron, keystone, sec_grp_settings=None,
596 sec_grp_name=None, project_name=None):
598 Returns the first security group for a given query. The query gets built
599 from the sec_grp_settings parameter if not None, else only the name of
600 the security group will be used, else if the query parameters are None then
601 None will be returned
602 :param neutron: the neutron client
603 :param keystone: the keystone client
604 :param sec_grp_settings: an instance of SecurityGroupConfig object
605 :param sec_grp_name: the name of security group object to retrieve
606 :param project_name: the name of the project/tentant object that owns the
607 secuity group to retrieve
608 :return: a SNAPS-OO SecurityGroup domain object or None if not found
611 sec_grp_filter = dict()
614 sec_grp_filter['name'] = sec_grp_settings.name
616 if sec_grp_settings.description:
617 sec_grp_filter['description'] = sec_grp_settings.description
618 if sec_grp_settings.project_name:
619 project_name = sec_grp_settings.project_name
621 sec_grp_filter['name'] = sec_grp_name
625 groups = neutron.list_security_groups(**sec_grp_filter)
627 for group in groups['security_groups']:
629 project = keystone_utils.get_project_by_id(
630 keystone, group['tenant_id'])
631 if project and project_name == project.name:
636 return __map_os_security_group(neutron, group)
639 def __map_os_security_group(neutron, os_sec_grp):
641 Creates a SecurityGroup SNAPS domain object from an OpenStack Security
643 :param neutron: the neutron client for performing rule lookups
644 :param os_sec_grp: the OpenStack Security Group dict object
645 :return: a SecurityGroup object
647 os_sec_grp['rules'] = get_rules_by_security_group_id(
648 neutron, os_sec_grp['id'])
649 return SecurityGroup(**os_sec_grp)
652 def get_security_group_by_id(neutron, sec_grp_id):
654 Returns the first security group object of the given name else None
655 :param neutron: the client
656 :param sec_grp_id: the id of the security group to retrieve
657 :return: a SNAPS-OO SecurityGroup domain object or None if not found
659 logger.info('Retrieving security group with ID - ' + sec_grp_id)
661 groups = neutron.list_security_groups(**{'id': sec_grp_id})
662 for group in groups['security_groups']:
663 if group['id'] == sec_grp_id:
664 return __map_os_security_group(neutron, group)
668 def create_security_group_rule(neutron, keystone, sec_grp_rule_settings,
671 Creates a security group rule in OpenStack
672 :param neutron: the neutron client
673 :param keystone: the keystone client
674 :param sec_grp_rule_settings: the security group rule settings
675 :param proj_name: the default project name
676 :return: a SNAPS-OO SecurityGroupRule domain object
678 logger.info('Creating security group to security group - %s',
679 sec_grp_rule_settings.sec_grp_name)
680 os_rule = neutron.create_security_group_rule(
681 sec_grp_rule_settings.dict_for_neutron(neutron, keystone, proj_name))
682 return SecurityGroupRule(**os_rule['security_group_rule'])
685 def delete_security_group_rule(neutron, sec_grp_rule):
687 Deletes a security group rule object from OpenStack
688 :param neutron: the client
689 :param sec_grp_rule: the SNAPS SecurityGroupRule object to delete
691 logger.info('Deleting security group rule with ID - %s',
693 neutron.delete_security_group_rule(sec_grp_rule.id)
696 def get_rules_by_security_group(neutron, sec_grp):
698 Retrieves all of the rules for a given security group
699 :param neutron: the client
700 :param sec_grp: a list of SNAPS SecurityGroupRule domain objects
702 return get_rules_by_security_group_id(neutron, sec_grp.id)
705 def get_rules_by_security_group_id(neutron, sec_grp_id):
707 Retrieves all of the rules for a given security group by it's ID
708 :param neutron: the client
709 :param sec_grp_id: the ID of the associated security group
711 logger.info('Retrieving security group rules associate with the '
712 'security group with ID - %s', sec_grp_id)
714 rules = neutron.list_security_group_rules(
715 **{'security_group_id': sec_grp_id})
716 for rule in rules['security_group_rules']:
717 if rule['security_group_id'] == sec_grp_id:
718 out.append(SecurityGroupRule(**rule))
722 def get_rule_by_id(neutron, sec_grp, rule_id):
724 Returns a SecurityGroupRule object from OpenStack
725 :param neutron: the client
726 :param sec_grp: the SNAPS SecurityGroup domain object
727 :param rule_id: the rule's ID
728 :param sec_grp: a SNAPS SecurityGroupRule domain object
730 rules = neutron.list_security_group_rules(
731 **{'security_group_id': sec_grp.id})
732 for rule in rules['security_group_rules']:
733 if rule['id'] == rule_id:
734 return SecurityGroupRule(**rule)
738 def get_external_networks(neutron):
740 Returns a list of external OpenStack network object/dict for all external
742 :param neutron: the client
743 :return: a list of external networks of Type SNAPS-OO domain class Network
746 for network in neutron.list_networks(
747 **{'router:external': True})['networks']:
748 out.append(__map_network(neutron, network))
752 def get_port_floating_ips(neutron, ports):
754 Returns all of the floating IPs associated with the ports returned in a
755 list of tuples where the port object is in the first position and the
756 floating IP object is in the second
757 :param neutron: the Neutron client
758 :param ports: a list of tuple 2 where index 0 is the port name and index 1
759 is the SNAPS-OO Port object
760 :return: a list of tuple 2 (port_id, SNAPS FloatingIp) objects when ports
761 is not None else a list of FloatingIp objects
764 fips = neutron.list_floatingips()
765 for fip in fips['floatingips']:
766 for port_name, port in ports:
767 if port and port.id == fip['port_id']:
768 out.append((port.id, FloatingIp(**fip)))
773 def get_floating_ips(neutron):
775 Returns a list of all of the floating IPs
776 :param neutron: the Neutron client
779 fips = neutron.list_floatingips()
780 for fip in fips['floatingips']:
781 out.append(FloatingIp(**fip))
785 def create_floating_ip(neutron, keystone, ext_net_name, port_id=None):
787 Returns the floating IP object that was created with this call
788 :param neutron: the Neutron client
789 :param keystone: the Keystone client
790 :param ext_net_name: the name of the external network on which to apply the
792 :param port_id: the ID of the port to which the floating IP will be
794 :return: the SNAPS FloatingIp object
796 logger.info('Creating floating ip to external network - ' + ext_net_name)
797 ext_net = get_network(neutron, keystone, network_name=ext_net_name)
799 body = {'floatingip': {'floating_network_id': ext_net.id}}
801 body['floatingip']['port_id'] = port_id
803 fip = neutron.create_floatingip(body=body)
805 return FloatingIp(id=fip['floatingip']['id'],
806 ip=fip['floatingip']['floating_ip_address'])
808 raise NeutronException(
809 'Cannot create floating IP, external network not found')
812 def get_floating_ip(neutron, floating_ip):
814 Returns a floating IP object that should be identical to the floating_ip
816 :param neutron: the Neutron client
817 :param floating_ip: the SNAPS FloatingIp object
818 :return: hopefully the same floating IP object input
820 logger.debug('Attempting to retrieve existing floating ip with IP - %s',
822 os_fip = __get_os_floating_ip(neutron, floating_ip)
824 return FloatingIp(id=os_fip['id'], ip=os_fip['floating_ip_address'])
827 def __get_os_floating_ip(neutron, floating_ip):
829 Returns an OpenStack floating IP object
831 :param neutron: the Neutron client
832 :param floating_ip: the SNAPS FloatingIp object
833 :return: hopefully the same floating IP object input
835 logger.debug('Attempting to retrieve existing floating ip with IP - %s',
837 fips = neutron.list_floatingips(ip=floating_ip.id)
839 for fip in fips['floatingips']:
840 if fip['id'] == floating_ip.id:
844 def delete_floating_ip(neutron, floating_ip):
846 Responsible for deleting a floating IP
847 :param neutron: the Neutron client
848 :param floating_ip: the SNAPS FloatingIp object
851 logger.debug('Attempting to delete existing floating ip with IP - %s',
853 return neutron.delete_floatingip(floating_ip.id)
856 def get_network_quotas(neutron, project_id):
858 Returns a list of NetworkQuotas objects
859 :param neutron: the neutron client
860 :param project_id: the project's ID of the quotas to lookup
861 :return: an object of type NetworkQuotas or None if not found
863 quota = neutron.show_quota(project_id)
865 return NetworkQuotas(**quota['quota'])
868 def update_quotas(neutron, project_id, network_quotas):
870 Updates the networking quotas for a given project
871 :param neutron: the Neutron client
872 :param project_id: the project's ID that requires quota updates
873 :param network_quotas: an object of type NetworkQuotas containing the
878 update_body['security_group'] = network_quotas.security_group
879 update_body['security_group_rule'] = network_quotas.security_group_rule
880 update_body['floatingip'] = network_quotas.floatingip
881 update_body['network'] = network_quotas.network
882 update_body['port'] = network_quotas.port
883 update_body['router'] = network_quotas.router
884 update_body['subnet'] = network_quotas.subnet
886 return neutron.update_quota(project_id, {'quota': update_body})
889 class NeutronException(Exception):
891 Exception when calls to the Keystone client cannot be served properly