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 if 'project_id' in inst.keys():
132 project = keystone_utils.get_project_by_id(
133 keystone, inst['project_id'])
135 project = keystone_utils.get_project_by_id(
136 keystone, inst['tenant_id'])
137 if project and project.name == project_name:
138 return __map_network(neutron, inst)
140 return __map_network(neutron, inst)
143 def __get_os_network_by_id(neutron, network_id):
145 Returns the OpenStack network object (dictionary) with the given ID else
147 :param neutron: the client
148 :param network_id: the id of the network to retrieve
149 :return: a SNAPS-OO Network domain object
151 networks = neutron.list_networks(**{'id': network_id})
152 for network in networks['networks']:
153 if network['id'] == network_id:
157 def get_network_by_id(neutron, network_id):
159 Returns the SNAPS Network domain object for the given ID else None
160 :param neutron: the client
161 :param network_id: the id of the network to retrieve
162 :return: a SNAPS-OO Network domain object
164 os_network = __get_os_network_by_id(neutron, network_id)
166 return __map_network(neutron, os_network)
169 def __map_network(neutron, os_network):
171 Returns the network object (dictionary) with the given ID else None
172 :param neutron: the client
173 :param os_network: the OpenStack Network dict
174 :return: a SNAPS-OO Network domain object
176 subnets = get_subnets_by_network_id(neutron, os_network['id'])
177 os_network['subnets'] = subnets
178 return Network(**os_network)
181 def create_subnet(neutron, subnet_settings, os_creds, network):
183 Creates a network subnet for OpenStack
184 :param neutron: the client
185 :param subnet_settings: A dictionary containing the subnet configuration
186 and is responsible for creating the subnet request
188 :param os_creds: the OpenStack credentials
189 :param network: the network object
190 :return: a SNAPS-OO Subnet domain object
192 if neutron and network and subnet_settings:
193 json_body = {'subnets': [subnet_settings.dict_for_neutron(
194 os_creds, network=network)]}
195 logger.info('Creating subnet with name ' + subnet_settings.name)
196 subnets = neutron.create_subnet(body=json_body)
197 return Subnet(**subnets['subnets'][0])
199 raise NeutronException('Failed to create subnet')
202 def delete_subnet(neutron, subnet):
204 Deletes a network subnet for OpenStack
205 :param neutron: the client
206 :param subnet: a SNAPS-OO Subnet domain object
208 if neutron and subnet:
209 logger.info('Deleting subnet with name ' + subnet.name)
210 neutron.delete_subnet(subnet.id)
213 def get_subnet(neutron, subnet_settings=None, subnet_name=None):
215 Returns the first subnet object that fits the query else None including
216 if subnet_settings or subnet_name parameters are None.
217 :param neutron: the client
218 :param subnet_settings: the subnet settings of the object to retrieve
219 :param subnet_name: the name of the subnet to retrieve
220 :return: a SNAPS-OO Subnet domain object or None
224 sub_filter['name'] = subnet_settings.name
225 sub_filter['cidr'] = subnet_settings.cidr
226 if subnet_settings.gateway_ip:
227 sub_filter['gateway_ip'] = subnet_settings.gateway_ip
229 if subnet_settings.enable_dhcp is not None:
230 sub_filter['enable_dhcp'] = subnet_settings.enable_dhcp
232 if subnet_settings.destination:
233 sub_filter['destination'] = subnet_settings.destination
235 if subnet_settings.nexthop:
236 sub_filter['nexthop'] = subnet_settings.nexthop
238 if subnet_settings.ipv6_ra_mode:
239 sub_filter['ipv6_ra_mode'] = subnet_settings.ipv6_ra_mode
241 if subnet_settings.ipv6_address_mode:
242 sub_filter['ipv6_address_mode'] = subnet_settings.ipv6_address_mode
244 sub_filter['name'] = subnet_name
248 subnets = neutron.list_subnets(**sub_filter)
249 for subnet in subnets['subnets']:
250 return Subnet(**subnet)
253 def get_subnet_by_id(neutron, subnet_id):
255 Returns a SNAPS-OO Subnet domain object for a given ID
256 :param neutron: the OpenStack neutron client
257 :param subnet_id: the subnet ID
258 :return: a Subnet object
260 os_subnet = neutron.show_subnet(subnet_id)
261 if os_subnet and 'subnet' in os_subnet:
262 return Subnet(**os_subnet['subnet'])
265 def get_subnets_by_network(neutron, network):
267 Returns a list of SNAPS-OO Subnet domain objects
268 :param neutron: the OpenStack neutron client
269 :param network: the SNAPS-OO Network domain object
270 :return: a list of Subnet objects
272 return get_subnets_by_network_id(neutron, network.id)
275 def get_subnets_by_network_id(neutron, network_id):
277 Returns a list of SNAPS-OO Subnet domain objects
278 :param neutron: the OpenStack neutron client
279 :param network_id: the subnet's ID
280 :return: a list of Subnet objects
284 os_subnets = neutron.list_subnets(network_id=network_id)
286 for os_subnet in os_subnets['subnets']:
287 out.append(Subnet(**os_subnet))
292 def create_router(neutron, os_creds, router_settings):
294 Creates a router for OpenStack
295 :param neutron: the client
296 :param os_creds: the OpenStack credentials
297 :param router_settings: A dictionary containing the router configuration
298 and is responsible for creating the subnet request
300 :return: a SNAPS-OO Router domain object
303 json_body = router_settings.dict_for_neutron(neutron, os_creds)
304 logger.info('Creating router with name - ' + router_settings.name)
305 os_router = neutron.create_router(json_body)
306 return __map_router(neutron, os_router['router'])
308 logger.error("Failed to create router.")
309 raise NeutronException('Failed to create router')
312 def delete_router(neutron, router):
314 Deletes a router for OpenStack
315 :param neutron: the client
316 :param router: a SNAPS-OO Router domain object
318 if neutron and router:
319 logger.info('Deleting router with name - ' + router.name)
320 neutron.delete_router(router=router.id)
323 def get_router_by_id(neutron, router_id):
325 Returns a router with a given ID, else None if not found
326 :param neutron: the client
327 :param router_id: the Router ID
328 :return: a SNAPS-OO Router domain object
330 router = neutron.show_router(router_id)
332 return __map_router(neutron, router['router'])
335 def get_router(neutron, keystone, router_settings=None, router_name=None,
338 Returns the first router object (dictionary) found the given the settings
339 values if not None, else finds the first with the value of the router_name
341 :param neutron: the Neutron client
342 :param keystone: the Keystone client
343 :param router_settings: the RouterConfig object
344 :param router_name: the name of the network to retrieve
345 :param project_name: the name of the router's project
346 :return: a SNAPS-OO Router domain object
348 router_filter = dict()
350 router_filter['name'] = router_settings.name
351 if router_settings.admin_state_up is not None:
352 router_filter['admin_state_up'] = router_settings.admin_state_up
354 router_filter['name'] = router_name
358 os_routers = neutron.list_routers(**router_filter)
359 for os_router in os_routers['routers']:
361 if 'project_id' in os_router.keys():
362 project = keystone_utils.get_project_by_id(
363 keystone, os_router['project_id'])
365 project = keystone_utils.get_project_by_id(
366 keystone, os_router['tenant_id'])
367 if project and project.name == project_name:
368 return __map_router(neutron, os_router)
371 def __map_router(neutron, os_router):
373 Takes an OpenStack router instance and maps it to a SNAPS Router domain
375 :param neutron: the neutron client
376 :param os_router: the OpenStack Router object
379 device_ports = neutron.list_ports(
380 **{'device_id': os_router['id']})['ports']
381 port_subnets = list()
383 # Order by create date
384 sorted_ports = sorted(
385 device_ports, key=lambda dev_port: dev_port['created_at'])
387 for port in sorted_ports:
389 for fixed_ip in port['fixed_ips']:
390 subnet = get_subnet_by_id(neutron, fixed_ip['subnet_id'])
391 if subnet and subnet.network_id == port['network_id']:
392 subnets.append(subnet)
393 port_subnets.append((Port(**port), subnets))
395 os_router['port_subnets'] = port_subnets
396 return Router(**os_router)
399 def add_interface_router(neutron, router, subnet=None, port=None):
401 Adds an interface router for OpenStack for either a subnet or port.
402 Exception will be raised if requesting for both.
403 :param neutron: the client
404 :param router: the router object
405 :param subnet: the subnet object
406 :param port: the port object
407 :return: the interface router object
410 raise NeutronException(
411 'Cannot add interface to the router. Both subnet and '
412 'port were sent in. Either or please.')
414 if neutron and router and (router or subnet):
415 logger.info('Adding interface to router with name ' + router.name)
416 os_intf_router = neutron.add_interface_router(
417 router=router.id, body=__create_port_json_body(subnet, port))
418 return InterfaceRouter(**os_intf_router)
420 raise NeutronException(
421 'Unable to create interface router as neutron client,'
422 ' router or subnet were not created')
425 def remove_interface_router(neutron, router, subnet=None, port=None):
427 Removes an interface router for OpenStack
428 :param neutron: the client
429 :param router: the SNAPS-OO Router domain object
430 :param subnet: the subnet object (either subnet or port, not both)
431 :param port: the port object
435 logger.info('Removing router interface from router named ' +
437 neutron.remove_interface_router(
439 body=__create_port_json_body(subnet, port))
440 except NotFound as e:
441 logger.warning('Could not remove router interface. NotFound - %s',
445 logger.warning('Could not remove router interface, No router object')
448 def __create_port_json_body(subnet=None, port=None):
450 Returns the dictionary required for creating and deleting router
451 interfaces. Will only work on a subnet or port object. Will throw and
452 exception if parameters contain both or neither
453 :param subnet: the subnet object
454 :param port: the port object
458 raise NeutronException(
459 'Cannot create JSON body with both subnet and port')
460 if not subnet and not port:
461 raise NeutronException(
462 'Cannot create JSON body without subnet or port')
465 return {"subnet_id": subnet.id}
467 return {"port_id": port.id}
470 def create_port(neutron, os_creds, port_settings):
472 Creates a port for OpenStack
473 :param neutron: the client
474 :param os_creds: the OpenStack credentials
475 :param port_settings: the settings object for port configuration
476 :return: the SNAPS-OO Port domain object
478 json_body = port_settings.dict_for_neutron(neutron, os_creds)
479 logger.info('Creating port for network with name - %s',
480 port_settings.network_name)
481 os_port = neutron.create_port(body=json_body)['port']
482 return Port(**os_port)
485 def delete_port(neutron, port):
487 Removes an OpenStack port
488 :param neutron: the client
489 :param port: the SNAPS-OO Port domain object
491 logger.info('Deleting port with name ' + port.name)
492 neutron.delete_port(port.id)
495 def get_port(neutron, keystone, port_settings=None, port_name=None,
498 Returns the first port object (dictionary) found for the given query
499 :param neutron: the Neutron client
500 :param keystone: the Keystone client
501 :param port_settings: the PortConfig object used for generating the query
502 :param port_name: if port_settings is None, this name is the value to place
504 :param project_name: the associated project name
505 :return: a SNAPS-OO Port domain object
510 if port_settings.name and len(port_settings.name) > 0:
511 port_filter['name'] = port_settings.name
512 if port_settings.admin_state_up:
513 port_filter['admin_state_up'] = port_settings.admin_state_up
514 if port_settings.device_id:
515 port_filter['device_id'] = port_settings.device_id
516 if port_settings.mac_address:
517 port_filter['mac_address'] = port_settings.mac_address
518 if port_settings.project_name:
519 project_name = port_settings.project_name
520 if port_settings.network_name:
521 network = get_network(
522 neutron, keystone, network_name=port_settings.network_name,
523 project_name=project_name)
525 port_filter['network_id'] = network.id
527 port_filter['name'] = port_name
529 ports = neutron.list_ports(**port_filter)
530 for port in ports['ports']:
532 if 'project_id' in port.keys():
533 project = keystone_utils.get_project_by_id(
534 keystone, port['project_id'])
536 project = keystone_utils.get_project_by_id(
537 keystone, port['tenant_id'])
538 if project and project.name == project_name:
545 def get_port_by_id(neutron, port_id):
547 Returns a SNAPS-OO Port domain object for the given ID or none if not found
548 :param neutron: the client
549 :param port_id: the to query
550 :return: a SNAPS-OO Port domain object or None
552 port = neutron.show_port(port_id)
554 return Port(**port['port'])
558 def get_ports(neutron, network, ips=None):
560 Returns a list of SNAPS-OO Port objects for all OpenStack Port objects that
561 are associated with the 'network' parameter
562 :param neutron: the client
563 :param network: SNAPS-OO Network domain object
564 :param ips: the IPs to lookup if not None
565 :return: a SNAPS-OO Port domain object or None if not found
568 ports = neutron.list_ports(**{'network_id': network.id})
569 for port in ports['ports']:
571 for fixed_ips in port['fixed_ips']:
572 if ('ip_address' in fixed_ips and
573 fixed_ips['ip_address'] in ips) or ips is None:
574 out.append(Port(**port))
577 out.append(Port(**port))
582 def create_security_group(neutron, keystone, sec_grp_settings):
584 Creates a security group object in OpenStack
585 :param neutron: the Neutron client
586 :param keystone: the Keystone client
587 :param sec_grp_settings: the security group settings
588 :return: a SNAPS-OO SecurityGroup domain object
590 logger.info('Creating security group with name - %s',
591 sec_grp_settings.name)
592 os_group = neutron.create_security_group(
593 sec_grp_settings.dict_for_neutron(keystone))
594 return __map_os_security_group(neutron, os_group['security_group'])
597 def delete_security_group(neutron, sec_grp):
599 Deletes a security group object from OpenStack
600 :param neutron: the client
601 :param sec_grp: the SNAPS SecurityGroup object to delete
603 logger.info('Deleting security group with name - %s', sec_grp.name)
604 neutron.delete_security_group(sec_grp.id)
607 def get_security_group(neutron, keystone, sec_grp_settings=None,
608 sec_grp_name=None, project_name=None):
610 Returns the first security group for a given query. The query gets built
611 from the sec_grp_settings parameter if not None, else only the name of
612 the security group will be used, else if the query parameters are None then
613 None will be returned
614 :param neutron: the neutron client
615 :param keystone: the keystone client
616 :param sec_grp_settings: an instance of SecurityGroupConfig object
617 :param sec_grp_name: the name of security group object to retrieve
618 :param project_name: the name of the project/tentant object that owns the
619 secuity group to retrieve
620 :return: a SNAPS-OO SecurityGroup domain object or None if not found
623 sec_grp_filter = dict()
626 sec_grp_filter['name'] = sec_grp_settings.name
628 if sec_grp_settings.description:
629 sec_grp_filter['description'] = sec_grp_settings.description
630 if sec_grp_settings.project_name:
631 project_name = sec_grp_settings.project_name
633 sec_grp_filter['name'] = sec_grp_name
637 groups = neutron.list_security_groups(**sec_grp_filter)
639 for group in groups['security_groups']:
641 if 'project_id' in group.keys():
642 project = keystone_utils.get_project_by_id(
643 keystone, group['project_id'])
645 project = keystone_utils.get_project_by_id(
646 keystone, group['tenant_id'])
647 if project and project_name == project.name:
652 return __map_os_security_group(neutron, group)
655 def __map_os_security_group(neutron, os_sec_grp):
657 Creates a SecurityGroup SNAPS domain object from an OpenStack Security
659 :param neutron: the neutron client for performing rule lookups
660 :param os_sec_grp: the OpenStack Security Group dict object
661 :return: a SecurityGroup object
663 os_sec_grp['rules'] = get_rules_by_security_group_id(
664 neutron, os_sec_grp['id'])
665 return SecurityGroup(**os_sec_grp)
668 def get_security_group_by_id(neutron, sec_grp_id):
670 Returns the first security group object of the given name else None
671 :param neutron: the client
672 :param sec_grp_id: the id of the security group to retrieve
673 :return: a SNAPS-OO SecurityGroup domain object or None if not found
675 logger.info('Retrieving security group with ID - ' + sec_grp_id)
677 groups = neutron.list_security_groups(**{'id': sec_grp_id})
678 for group in groups['security_groups']:
679 if group['id'] == sec_grp_id:
680 return __map_os_security_group(neutron, group)
684 def list_security_groups(neutron):
687 Lists the available security groups
688 :param neutron: the neutron client
690 logger.info('Listing the available security groups')
692 response = neutron.list_security_groups()
693 for sg in response['security_groups']:
694 sec_groups.append(__map_os_security_group(neutron, sg))
699 def create_security_group_rule(neutron, keystone, sec_grp_rule_settings,
702 Creates a security group rule in OpenStack
703 :param neutron: the neutron client
704 :param keystone: the keystone client
705 :param sec_grp_rule_settings: the security group rule settings
706 :param proj_name: the default project name
707 :return: a SNAPS-OO SecurityGroupRule domain object
709 logger.info('Creating security group to security group - %s',
710 sec_grp_rule_settings.sec_grp_name)
711 os_rule = neutron.create_security_group_rule(
712 sec_grp_rule_settings.dict_for_neutron(neutron, keystone, proj_name))
713 return SecurityGroupRule(**os_rule['security_group_rule'])
716 def delete_security_group_rule(neutron, sec_grp_rule):
718 Deletes a security group rule object from OpenStack
719 :param neutron: the client
720 :param sec_grp_rule: the SNAPS SecurityGroupRule object to delete
722 logger.info('Deleting security group rule with ID - %s',
724 neutron.delete_security_group_rule(sec_grp_rule.id)
727 def get_rules_by_security_group(neutron, sec_grp):
729 Retrieves all of the rules for a given security group
730 :param neutron: the client
731 :param sec_grp: a list of SNAPS SecurityGroupRule domain objects
733 return get_rules_by_security_group_id(neutron, sec_grp.id)
736 def get_rules_by_security_group_id(neutron, sec_grp_id):
738 Retrieves all of the rules for a given security group by it's ID
739 :param neutron: the client
740 :param sec_grp_id: the ID of the associated security group
742 logger.info('Retrieving security group rules associate with the '
743 'security group with ID - %s', sec_grp_id)
745 rules = neutron.list_security_group_rules(
746 **{'security_group_id': sec_grp_id})
747 for rule in rules['security_group_rules']:
748 if rule['security_group_id'] == sec_grp_id:
749 out.append(SecurityGroupRule(**rule))
753 def get_rule_by_id(neutron, sec_grp, rule_id):
755 Returns a SecurityGroupRule object from OpenStack
756 :param neutron: the client
757 :param sec_grp: the SNAPS SecurityGroup domain object
758 :param rule_id: the rule's ID
759 :param sec_grp: a SNAPS SecurityGroupRule domain object
761 rules = neutron.list_security_group_rules(
762 **{'security_group_id': sec_grp.id})
763 for rule in rules['security_group_rules']:
764 if rule['id'] == rule_id:
765 return SecurityGroupRule(**rule)
769 def get_external_networks(neutron):
771 Returns a list of external OpenStack network object/dict for all external
773 :param neutron: the client
774 :return: a list of external networks of Type SNAPS-OO domain class Network
777 for network in neutron.list_networks(
778 **{'router:external': True})['networks']:
779 out.append(__map_network(neutron, network))
783 def get_port_floating_ips(neutron, ports):
785 Returns all of the floating IPs associated with the ports returned in a
786 list of tuples where the port object is in the first position and the
787 floating IP object is in the second
788 :param neutron: the Neutron client
789 :param ports: a list of tuple 2 where index 0 is the port name and index 1
790 is the SNAPS-OO Port object
791 :return: a list of tuple 2 (port_id, SNAPS FloatingIp) objects when ports
792 is not None else a list of FloatingIp objects
795 fips = neutron.list_floatingips()
796 for fip in fips['floatingips']:
797 for port_name, port in ports:
798 if port and port.id == fip['port_id']:
799 out.append((port.id, FloatingIp(**fip)))
804 def get_floating_ips(neutron):
806 Returns a list of all of the floating IPs
807 :param neutron: the Neutron client
810 fips = neutron.list_floatingips()
811 for fip in fips['floatingips']:
812 out.append(FloatingIp(**fip))
816 def create_floating_ip(neutron, keystone, ext_net_name, port_id=None):
818 Returns the floating IP object that was created with this call
819 :param neutron: the Neutron client
820 :param keystone: the Keystone client
821 :param ext_net_name: the name of the external network on which to apply the
823 :param port_id: the ID of the port to which the floating IP will be
825 :return: the SNAPS FloatingIp object
827 logger.info('Creating floating ip to external network - ' + ext_net_name)
828 ext_net = get_network(neutron, keystone, network_name=ext_net_name)
830 body = {'floatingip': {'floating_network_id': ext_net.id}}
832 body['floatingip']['port_id'] = port_id
834 fip = neutron.create_floatingip(body=body)
836 return FloatingIp(id=fip['floatingip']['id'],
837 ip=fip['floatingip']['floating_ip_address'])
839 raise NeutronException(
840 'Cannot create floating IP, external network not found')
843 def get_floating_ip(neutron, floating_ip):
845 Returns a floating IP object that should be identical to the floating_ip
847 :param neutron: the Neutron client
848 :param floating_ip: the SNAPS FloatingIp object
849 :return: hopefully the same floating IP object input
851 logger.debug('Attempting to retrieve existing floating ip with IP - %s',
853 os_fip = __get_os_floating_ip(neutron, floating_ip)
855 return FloatingIp(id=os_fip['id'], ip=os_fip['floating_ip_address'])
858 def __get_os_floating_ip(neutron, floating_ip):
860 Returns an OpenStack floating IP object
862 :param neutron: the Neutron client
863 :param floating_ip: the SNAPS FloatingIp object
864 :return: hopefully the same floating IP object input
866 logger.debug('Attempting to retrieve existing floating ip with IP - %s',
868 fips = neutron.list_floatingips(ip=floating_ip.id)
870 for fip in fips['floatingips']:
871 if fip['id'] == floating_ip.id:
875 def delete_floating_ip(neutron, floating_ip):
877 Responsible for deleting a floating IP
878 :param neutron: the Neutron client
879 :param floating_ip: the SNAPS FloatingIp object
882 logger.debug('Attempting to delete existing floating ip with IP - %s',
884 return neutron.delete_floatingip(floating_ip.id)
887 def get_network_quotas(neutron, project_id):
889 Returns a list of NetworkQuotas objects
890 :param neutron: the neutron client
891 :param project_id: the project's ID of the quotas to lookup
892 :return: an object of type NetworkQuotas or None if not found
894 quota = neutron.show_quota(project_id)
896 return NetworkQuotas(**quota['quota'])
899 def update_quotas(neutron, project_id, network_quotas):
901 Updates the networking quotas for a given project
902 :param neutron: the Neutron client
903 :param project_id: the project's ID that requires quota updates
904 :param network_quotas: an object of type NetworkQuotas containing the
909 update_body['security_group'] = network_quotas.security_group
910 update_body['security_group_rule'] = network_quotas.security_group_rule
911 update_body['floatingip'] = network_quotas.floatingip
912 update_body['network'] = network_quotas.network
913 update_body['port'] = network_quotas.port
914 update_body['router'] = network_quotas.router
915 update_body['subnet'] = network_quotas.subnet
917 return neutron.update_quota(project_id, {'quota': update_body})
920 class NeutronException(Exception):
922 Exception when calls to the Keystone client cannot be served properly