def test_update_port_associations_for_ip(self, associate_mock, disassociate_mock, get_associations_mock): self.context.session.add = mock.Mock() self.context.session.delete = mock.Mock() mock_ports = [models.Port(id=str(x), network_id="2", ip_addresses=[]) for x in xrange(4)] mock_address = models.IPAddress(id="1", address=3232235876, address_readable="192.168.1.100", subnet_id="1", network_id="2", version=4, used_by_tenant_id="1") mock_address.ports = mock_ports new_port_list = mock_ports[1:3] new_port_list.append(models.Port(id="4", network_id="2", ip_addresses=[])) get_associations_mock.return_value = mock_ports # NOTE(thomasem): Should be the new address after associating # any new ports in the list. mock_new_address = associate_mock.return_value db_api.update_port_associations_for_ip(self.context, new_port_list, mock_address) associate_mock.assert_called_once_with(self.context, set([new_port_list[2]]), mock_address) disassociate_mock.assert_called_once_with(self.context, set([mock_ports[0], mock_ports[3]]), mock_new_address)
def delete_ip_address(context, id): """Delete an ip address. : param context: neutron api request context : param id: UUID representing the ip address to delete. """ LOG.info("delete_ip_address %s for tenant %s" % (id, context.tenant_id)) with context.session.begin(): ip_address = db_api.ip_address_find( context, id=id, scope=db_api.ONE) if not ip_address or ip_address.deallocated: raise q_exc.IpAddressNotFound(addr_id=id) iptype = ip_address.address_type if iptype == ip_types.FIXED and not CONF.QUARK.ipaddr_allow_fixed_ip: raise n_exc.BadRequest( resource="ip_addresses", msg="Fixed ips cannot be updated using this interface.") if ip_address.has_any_shared_owner(): raise q_exc.PortRequiresDisassociation() db_api.update_port_associations_for_ip(context, [], ip_address) ipam_driver.deallocate_ip_address(context, ip_address)
def delete_ip_address(context, id): """Delete an ip address. : param context: neutron api request context : param id: UUID representing the ip address to delete. """ LOG.info("delete_ip_address %s for tenant %s" % (id, context.tenant_id)) with context.session.begin(): ip_address = db_api.ip_address_find(context, id=id, scope=db_api.ONE) if not ip_address or ip_address.deallocated: raise q_exc.IpAddressNotFound(addr_id=id) iptype = ip_address.address_type if iptype == ip_types.FIXED and not CONF.QUARK.ipaddr_allow_fixed_ip: raise n_exc.BadRequest( resource="ip_addresses", msg="Fixed ips cannot be updated using this interface.") if ip_address.has_any_shared_owner(): raise q_exc.PortRequiresDisassociation() db_api.update_port_associations_for_ip(context, [], ip_address) ipam_driver.deallocate_ip_address(context, ip_address)
def update_ip_address(context, id, ip_address): LOG.info("update_ip_address %s for tenant %s" % (id, context.tenant_id)) ports = [] with context.session.begin(): address = db_api.ip_address_find( context, id=id, tenant_id=context.tenant_id, scope=db_api.ONE) if not address: raise exceptions.NotFound( message="No IP address found with id=%s" % id) reset = ip_address['ip_address'].get('reset_allocation_time', False) if reset and address['deallocated'] == 1: if context.is_admin: LOG.info("IP's deallocated time being manually reset") address['deallocated_at'] = _get_deallocated_override() else: msg = "Modification of reset_allocation_time requires admin" raise webob.exc.HTTPForbidden(detail=msg) port_ids = ip_address['ip_address'].get('port_ids') if port_ids: _raise_if_shared_and_enabled(ip_address, address) ports = db_api.port_find(context, tenant_id=context.tenant_id, id=port_ids, scope=db_api.ALL) # NOTE(name): could be considered inefficient because we're # converting to a list to check length. Maybe revisit if len(ports) != len(port_ids): raise exceptions.NotFound( message="No ports not found with ids=%s" % port_ids) validate_ports_on_network_and_same_segment(ports, address["network_id"]) validate_port_ip_quotas(context, ports) LOG.info("Updating IP address, %s, to only be used by the" "following ports: %s" % (address.address_readable, [p.id for p in ports])) new_address = db_api.update_port_associations_for_ip(context, ports, address) else: if port_ids is not None: ipam_driver.deallocate_ip_address( context, address) return v._make_ip_dict(address) return v._make_ip_dict(new_address)
def update_ip_address(context, id, ip_address): """Due to NCP-1592 ensure that address_type cannot change after update.""" LOG.info("update_ip_address %s for tenant %s" % (id, context.tenant_id)) ports = [] if 'ip_address' not in ip_address: raise n_exc.BadRequest(resource="ip_addresses", msg="Invalid request body.") with context.session.begin(): address = db_api.ip_address_find(context, id=id, scope=db_api.ONE) if not address: raise q_exc.IpAddressNotFound(addr_id=id) iptype = address.address_type if iptype == ip_types.FIXED and not CONF.QUARK.ipaddr_allow_fixed_ip: raise n_exc.BadRequest( resource="ip_addresses", msg="Fixed ips cannot be updated using this interface.") reset = ip_address['ip_address'].get('reset_allocation_time', False) if reset and address['deallocated'] == 1: if context.is_admin: LOG.info("IP's deallocated time being manually reset") address['deallocated_at'] = _get_deallocated_override() else: msg = "Modification of reset_allocation_time requires admin" raise webob.exc.HTTPForbidden(detail=msg) port_ids = ip_address['ip_address'].get('port_ids', None) if port_ids is not None and not port_ids: raise n_exc.BadRequest( resource="ip_addresses", msg="Cannot be updated with empty port_id list") if iptype == ip_types.SHARED: has_owner = address.has_any_shared_owner() if port_ids: if iptype == ip_types.FIXED and len(port_ids) > 1: raise n_exc.BadRequest( resource="ip_addresses", msg="Fixed ips cannot be updated with more than one port.") _raise_if_shared_and_enabled(ip_address, address) ports = db_api.port_find(context, tenant_id=context.tenant_id, id=port_ids, scope=db_api.ALL) # NOTE(name): could be considered inefficient because we're # converting to a list to check length. Maybe revisit if len(ports) != len(port_ids): raise n_exc.PortNotFound(port_id=port_ids) validate_and_fetch_segment(ports, address["network_id"]) validate_port_ip_quotas(context, address.network_id, ports) if iptype == ip_types.SHARED and has_owner: for assoc in address.associations: pid = assoc.port_id if pid not in port_ids and 'none' != assoc.service: raise q_exc.PortRequiresDisassociation() LOG.info("Updating IP address, %s, to only be used by the" "following ports: %s" % (address.address_readable, [p.id for p in ports])) new_address = db_api.update_port_associations_for_ip( context, ports, address) elif iptype == ip_types.SHARED and has_owner: raise q_exc.PortRequiresDisassociation() else: ipam_driver.deallocate_ip_address(context, address) return v._make_ip_dict(address) return v._make_ip_dict(new_address)
def update_ip_address(context, id, ip_address): """Due to NCP-1592 ensure that address_type cannot change after update.""" LOG.info("update_ip_address %s for tenant %s" % (id, context.tenant_id)) ports = [] if 'ip_address' not in ip_address: raise n_exc.BadRequest(resource="ip_addresses", msg="Invalid request body.") with context.session.begin(): address = db_api.ip_address_find(context, id=id, scope=db_api.ONE) if not address: raise q_exc.IpAddressNotFound(addr_id=id) iptype = address.address_type if iptype == ip_types.FIXED and not CONF.QUARK.ipaddr_allow_fixed_ip: raise n_exc.BadRequest( resource="ip_addresses", msg="Fixed ips cannot be updated using this interface.") reset = ip_address['ip_address'].get('reset_allocation_time', False) if reset and address['deallocated'] == 1: if context.is_admin: LOG.info("IP's deallocated time being manually reset") address['deallocated_at'] = _get_deallocated_override() else: msg = "Modification of reset_allocation_time requires admin" raise webob.exc.HTTPForbidden(detail=msg) port_ids = ip_address['ip_address'].get('port_ids', None) if port_ids is not None and not port_ids: raise n_exc.BadRequest( resource="ip_addresses", msg="Cannot be updated with empty port_id list") if iptype == ip_types.SHARED: has_owner = address.has_any_shared_owner() if port_ids: if iptype == ip_types.FIXED and len(port_ids) > 1: raise n_exc.BadRequest( resource="ip_addresses", msg="Fixed ips cannot be updated with more than one port.") _raise_if_shared_and_enabled(ip_address, address) ports = db_api.port_find(context, tenant_id=context.tenant_id, id=port_ids, scope=db_api.ALL) # NOTE(name): could be considered inefficient because we're # converting to a list to check length. Maybe revisit if len(ports) != len(port_ids): raise n_exc.PortNotFound(port_id=port_ids) validate_and_fetch_segment(ports, address["network_id"]) validate_port_ip_quotas(context, address.network_id, ports) if iptype == ip_types.SHARED and has_owner: for assoc in address.associations: pid = assoc.port_id if pid not in port_ids and 'none' != assoc.service: raise q_exc.PortRequiresDisassociation() LOG.info("Updating IP address, %s, to only be used by the" "following ports: %s" % (address.address_readable, [p.id for p in ports])) new_address = db_api.update_port_associations_for_ip(context, ports, address) elif iptype == ip_types.SHARED and has_owner: raise q_exc.PortRequiresDisassociation() else: ipam_driver.deallocate_ip_address(context, address) return v._make_ip_dict(address) return v._make_ip_dict(new_address)