def update_port(self, context, port_id, port): """Update values of a port. :param context: neutron api request context :param id: UUID representing the port to update. :param port: dictionary with keys indicating fields to update. :returns: a mapping sequence with the following signature: { "id": uuid represeting the port. "network_id": uuid of network. "tenant_id": tenant_id "mac_address": mac address to use on this port. "admin_state_up": sets admin state of port. if down, port does not forward packets. "status": dicates whether port is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR") "fixed_ips": list of subnet ID's and IP addresses to be used on this port "device_id": identifies the device (e.g., virtual server) using this port. } :raises: exceptions.StateInvalid :raises: exceptions.PortNotFound :raises: RemoteRestError """ LOG.debug(_("NeutronRestProxyV2: update_port() called")) self._warn_on_state_status(port["port"]) # Validate Args orig_port = super(NeutronRestProxyV2, self).get_port(context, port_id) with context.session.begin(subtransactions=True): # Update DB new_port = super(NeutronRestProxyV2, self).update_port(context, port_id, port) self._update_extra_dhcp_opts_on_port(context, port_id, port, new_port) if portbindings.HOST_ID in port["port"] and "id" in new_port: host_id = port["port"][portbindings.HOST_ID] porttracker_db.put_port_hostid(context, new_port["id"], host_id) new_port = self._extend_port_dict_binding(context, new_port) # update on networl ctrl mapped_port = self._map_state_and_status(new_port) self.servers.rest_update_port(orig_port["tenant_id"], orig_port["network_id"], mapped_port, port_id) if new_port.get("device_id") != orig_port.get("device_id") and orig_port.get("device_id"): try: self.servers.rest_unplug_interface(orig_port["tenant_id"], orig_port["network_id"], orig_port["id"]) device_id = new_port.get("device_id") if device_id: self.rest_plug_interface(new_port["tenant_id"], new_port["network_id"], new_port, device_id) except RemoteRestError: with excutils.save_and_reraise_exception(): port_update = {"port": {"status": "ERROR"}} super(NeutronRestProxyV2, self).update_port(context, new_port["id"], port_update) # return new_port return new_port
def create_port(self, context, port): """Create a port, which is a connection point of a device (e.g., a VM NIC) to attach to a L2 Neutron network. :param context: neutron api request context :param port: dictionary describing the port :returns: { "id": uuid represeting the port. "network_id": uuid of network. "tenant_id": tenant_id "mac_address": mac address to use on this port. "admin_state_up": Sets admin state of port. if down, port does not forward packets. "status": dicates whether port is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR") "fixed_ips": list of subnet ID"s and IP addresses to be used on this port "device_id": identifies the device (e.g., virtual server) using this port. } :raises: exceptions.NetworkNotFound :raises: exceptions.StateInvalid :raises: RemoteRestError """ LOG.debug(_("NeutronRestProxyV2: create_port() called")) # Update DB in new session so exceptions rollback changes with context.session.begin(subtransactions=True): self._ensure_default_security_group_on_port(context, port) sgids = self._get_security_groups_on_port(context, port) # set port status to pending. updated after rest call completes port['port']['status'] = const.PORT_STATUS_BUILD dhcp_opts = port['port'].get(edo_ext.EXTRADHCPOPTS, []) new_port = super(NeutronRestProxyV2, self).create_port(context, port) self._process_port_create_security_group(context, new_port, sgids) if (portbindings.HOST_ID in port['port'] and 'id' in new_port): host_id = port['port'][portbindings.HOST_ID] porttracker_db.put_port_hostid(context, new_port['id'], host_id) new_port[addr_pair.ADDRESS_PAIRS] = ( self._process_create_allowed_address_pairs( context, new_port, port['port'].get(addr_pair.ADDRESS_PAIRS))) self._process_port_create_extra_dhcp_opts(context, new_port, dhcp_opts) new_port = self._extend_port_dict_binding(context, new_port) net = super(NeutronRestProxyV2, self).get_network(context, new_port["network_id"]) if self.add_meta_server_route: if new_port['device_owner'] == const.DEVICE_OWNER_DHCP: destination = METADATA_SERVER_IP + '/32' self._add_host_route(context, destination, new_port) # create on network ctrl mapped_port = self._map_state_and_status(new_port) self.evpool.spawn_n(self.async_port_create, net["tenant_id"], new_port["network_id"], mapped_port) self.notify_security_groups_member_updated(context, new_port) return new_port
def create_port(self, context, port): """Create a port, which is a connection point of a device (e.g., a VM NIC) to attach to a L2 Neutron network. :param context: neutron api request context :param port: dictionary describing the port :returns: { "id": uuid represeting the port. "network_id": uuid of network. "tenant_id": tenant_id "mac_address": mac address to use on this port. "admin_state_up": Sets admin state of port. if down, port does not forward packets. "status": dicates whether port is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR") "fixed_ips": list of subnet ID"s and IP addresses to be used on this port "device_id": identifies the device (e.g., virtual server) using this port. } :raises: exceptions.NetworkNotFound :raises: exceptions.StateInvalid :raises: RemoteRestError """ LOG.debug(_("NeutronRestProxyV2: create_port() called")) # Update DB in new session so exceptions rollback changes with context.session.begin(subtransactions=True): self._ensure_default_security_group_on_port(context, port) sgids = self._get_security_groups_on_port(context, port) # set port status to pending. updated after rest call completes port['port']['status'] = const.PORT_STATUS_BUILD dhcp_opts = port['port'].get(edo_ext.EXTRADHCPOPTS, []) new_port = super(NeutronRestProxyV2, self).create_port(context, port) self._process_port_create_security_group(context, new_port, sgids) if (portbindings.HOST_ID in port['port'] and 'id' in new_port): host_id = port['port'][portbindings.HOST_ID] porttracker_db.put_port_hostid(context, new_port['id'], host_id) self._process_port_create_extra_dhcp_opts(context, new_port, dhcp_opts) new_port = self._extend_port_dict_binding(context, new_port) net = super(NeutronRestProxyV2, self).get_network(context, new_port["network_id"]) if self.add_meta_server_route: if new_port['device_owner'] == 'network:dhcp': destination = METADATA_SERVER_IP + '/32' self._add_host_route(context, destination, new_port) # create on network ctrl mapped_port = self._map_state_and_status(new_port) self.evpool.spawn_n(self.async_port_create, net["tenant_id"], new_port["network_id"], mapped_port) self.notify_security_groups_member_updated(context, new_port) return new_port
def _prepare_port_for_controller(self, context): port = context.current net = context.network.current port["network"] = net port["binding_host"] = context._binding.host actx = ctx.get_admin_context() if portbindings.HOST_ID in port and "id" in port: host_id = port[portbindings.HOST_ID] porttracker_db.put_port_hostid(actx, port["id"], host_id) else: host_id = "" prepped_port = self._extend_port_dict_binding(actx, port) prepped_port = self._map_state_and_status(prepped_port) if portbindings.HOST_ID not in prepped_port or prepped_port[portbindings.HOST_ID] == "": # in ML2, controller doesn't care about ports without # the host_id set return False return prepped_port
def _prepare_port_for_controller(self, context): port = context.current net = context.network.current port['network'] = net port['binding_host'] = context._binding.host actx = ctx.get_admin_context() if (portbindings.HOST_ID in port and 'id' in port): host_id = port[portbindings.HOST_ID] porttracker_db.put_port_hostid(actx, port['id'], host_id) else: host_id = '' prepped_port = self._extend_port_dict_binding(actx, port) prepped_port = self._map_state_and_status(prepped_port) if (portbindings.HOST_ID not in prepped_port or prepped_port[portbindings.HOST_ID] == ''): # in ML2, controller doesn't care about ports without # the host_id set return False return prepped_port
def _prepare_port_for_controller(self, context): port = context.current net = context.network.current port['network'] = net port['binding_host'] = context._binding.host actx = ctx.get_admin_context() if (portbindings.HOST_ID in port and 'id' in port): host_id = port[portbindings.HOST_ID] porttracker_db.put_port_hostid(actx, port['id'], host_id) else: host_id = '' prepped_port = self._extend_port_dict_binding(actx, port) prepped_port = self._map_state_and_status(prepped_port) if (portbindings.HOST_ID not in prepped_port or prepped_port[portbindings.HOST_ID] == ''): LOG.warning(_("Ignoring port notification to controller because " "of missing host ID.")) # in ML2, controller doesn't care about ports without # the host_id set return False return prepped_port
def update_port(self, context, port_id, port): """Update values of a port. :param context: neutron api request context :param id: UUID representing the port to update. :param port: dictionary with keys indicating fields to update. :returns: a mapping sequence with the following signature: { "id": uuid represeting the port. "network_id": uuid of network. "tenant_id": tenant_id "mac_address": mac address to use on this port. "admin_state_up": sets admin state of port. if down, port does not forward packets. "status": dicates whether port is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR") "fixed_ips": list of subnet ID's and IP addresses to be used on this port "device_id": identifies the device (e.g., virtual server) using this port. } :raises: exceptions.StateInvalid :raises: exceptions.PortNotFound :raises: RemoteRestError """ LOG.debug(_("NeutronRestProxyV2: update_port() called")) self._warn_on_state_status(port['port']) # Validate Args orig_port = super(NeutronRestProxyV2, self).get_port(context, port_id) with context.session.begin(subtransactions=True): # Update DB new_port = super(NeutronRestProxyV2, self).update_port(context, port_id, port) ctrl_update_required = False if addr_pair.ADDRESS_PAIRS in port['port']: ctrl_update_required |= ( self.update_address_pairs_on_port(context, port_id, port, orig_port, new_port)) if 'fixed_ips' in port['port']: self._check_fixed_ips_and_address_pairs_no_overlap( context, new_port) self._update_extra_dhcp_opts_on_port(context, port_id, port, new_port) old_host_id = porttracker_db.get_port_hostid(context, orig_port['id']) if (portbindings.HOST_ID in port['port'] and 'id' in new_port): host_id = port['port'][portbindings.HOST_ID] porttracker_db.put_port_hostid(context, new_port['id'], host_id) if old_host_id != host_id: ctrl_update_required = True if (new_port.get("device_id") != orig_port.get("device_id") and orig_port.get("device_id")): ctrl_update_required = True if ctrl_update_required: # tenant_id must come from network in case network is shared net_tenant_id = self._get_port_net_tenantid(context, new_port) new_port = self._extend_port_dict_binding(context, new_port) mapped_port = self._map_state_and_status(new_port) self.servers.rest_update_port(net_tenant_id, new_port["network_id"], mapped_port) agent_update_required = self.update_security_group_on_port( context, port_id, port, orig_port, new_port) agent_update_required |= self.is_security_group_member_updated( context, orig_port, new_port) # return new_port return new_port
def update_port(self, context, port_id, port): """Update values of a port. :param context: neutron api request context :param id: UUID representing the port to update. :param port: dictionary with keys indicating fields to update. :returns: a mapping sequence with the following signature: { "id": uuid represeting the port. "network_id": uuid of network. "tenant_id": tenant_id "mac_address": mac address to use on this port. "admin_state_up": sets admin state of port. if down, port does not forward packets. "status": dicates whether port is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR") "fixed_ips": list of subnet ID's and IP addresses to be used on this port "device_id": identifies the device (e.g., virtual server) using this port. } :raises: exceptions.StateInvalid :raises: exceptions.PortNotFound :raises: RemoteRestError """ LOG.debug(_("NeutronRestProxyV2: update_port() called")) self._warn_on_state_status(port['port']) # Validate Args orig_port = super(NeutronRestProxyV2, self).get_port(context, port_id) with context.session.begin(subtransactions=True): # Update DB new_port = super(NeutronRestProxyV2, self).update_port(context, port_id, port) self._update_extra_dhcp_opts_on_port(context, port_id, port, new_port) ctrl_update_required = False old_host_id = porttracker_db.get_port_hostid( context, orig_port['id']) if (portbindings.HOST_ID in port['port'] and 'id' in new_port): host_id = port['port'][portbindings.HOST_ID] porttracker_db.put_port_hostid(context, new_port['id'], host_id) if old_host_id != host_id: ctrl_update_required = True if (new_port.get("device_id") != orig_port.get("device_id") and orig_port.get("device_id")): ctrl_update_required = True if ctrl_update_required: # tenant_id must come from network in case network is shared net_tenant_id = self._get_port_net_tenantid(context, new_port) new_port = self._extend_port_dict_binding(context, new_port) mapped_port = self._map_state_and_status(new_port) self.servers.rest_update_port(net_tenant_id, new_port["network_id"], mapped_port) agent_update_required = self.update_security_group_on_port( context, port_id, port, orig_port, new_port) agent_update_required |= self.is_security_group_member_updated( context, orig_port, new_port) # return new_port return new_port
def update_port(self, context, port_id, port): """Update values of a port. :param context: neutron api request context :param id: UUID representing the port to update. :param port: dictionary with keys indicating fields to update. :returns: a mapping sequence with the following signature: { "id": uuid represeting the port. "network_id": uuid of network. "tenant_id": tenant_id "mac_address": mac address to use on this port. "admin_state_up": sets admin state of port. if down, port does not forward packets. "status": dicates whether port is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR") "fixed_ips": list of subnet ID's and IP addresses to be used on this port "device_id": identifies the device (e.g., virtual server) using this port. } :raises: exceptions.StateInvalid :raises: exceptions.PortNotFound :raises: RemoteRestError """ LOG.debug(_("NeutronRestProxyV2: update_port() called")) self._warn_on_state_status(port["port"]) # Validate Args orig_port = super(NeutronRestProxyV2, self).get_port(context, port_id) # Update DB new_port = super(NeutronRestProxyV2, self).update_port(context, port_id, port) if portbindings.HOST_ID in port["port"] and "device_id" in port["port"]: porttracker_db.put_port_hostid(context, port["port"]["device_id"], port["port"][portbindings.HOST_ID]) # update on networl ctrl try: resource = PORTS_PATH % (orig_port["tenant_id"], orig_port["network_id"], port_id) mapped_port = self._map_state_and_status(new_port) data = {"port": mapped_port} ret = self.servers.put(resource, data) if not self.servers.action_success(ret): raise RemoteRestError(ret[2]) if new_port.get("device_id") != orig_port.get("device_id"): if orig_port.get("device_id"): self._unplug_interface(context, orig_port["tenant_id"], orig_port["network_id"], orig_port["id"]) device_id = new_port.get("device_id") if device_id: self._plug_interface( context, new_port["tenant_id"], new_port["network_id"], new_port["id"], device_id ) except RemoteRestError as e: LOG.error(_("NeutronRestProxyV2: Unable to create remote port: " "%s"), e.message) # reset port to original state super(NeutronRestProxyV2, self).update_port(context, port_id, orig_port) raise # return new_port return self._extend_port_dict_binding(context, new_port)
def create_port(self, context, port): """Create a port, which is a connection point of a device (e.g., a VM NIC) to attach to a L2 Neutron network. :param context: neutron api request context :param port: dictionary describing the port :returns: { "id": uuid represeting the port. "network_id": uuid of network. "tenant_id": tenant_id "mac_address": mac address to use on this port. "admin_state_up": Sets admin state of port. if down, port does not forward packets. "status": dicates whether port is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR") "fixed_ips": list of subnet ID"s and IP addresses to be used on this port "device_id": identifies the device (e.g., virtual server) using this port. } :raises: exceptions.NetworkNotFound :raises: exceptions.StateInvalid :raises: RemoteRestError """ LOG.debug(_("NeutronRestProxyV2: create_port() called")) # Update DB port["port"]["admin_state_up"] = False if portbindings.HOST_ID in port["port"] and "device_id" in port["port"]: porttracker_db.put_port_hostid(context, port["port"]["device_id"], port["port"][portbindings.HOST_ID]) new_port = super(NeutronRestProxyV2, self).create_port(context, port) net = super(NeutronRestProxyV2, self).get_network(context, new_port["network_id"]) if self.add_meta_server_route: if new_port["device_owner"] == "network:dhcp": destination = METADATA_SERVER_IP + "/32" self._add_host_route(context, destination, new_port) # create on networl ctrl try: resource = PORT_RESOURCE_PATH % (net["tenant_id"], net["id"]) mapped_port = self._map_state_and_status(new_port) data = {"port": mapped_port} ret = self.servers.post(resource, data) if not self.servers.action_success(ret): raise RemoteRestError(ret[2]) # connect device to network, if present device_id = port["port"].get("device_id") if device_id: self._plug_interface(context, net["tenant_id"], net["id"], new_port["id"], device_id) except RemoteRestError as e: LOG.error(_("NeutronRestProxyV2: Unable to create remote port: " "%s"), e.message) super(NeutronRestProxyV2, self).delete_port(context, new_port["id"]) raise # Set port state up and return that port port_update = {"port": {"admin_state_up": True}} new_port = super(NeutronRestProxyV2, self).update_port(context, new_port["id"], port_update) return self._extend_port_dict_binding(context, new_port)
def create_port(self, context, port): """Create a port, which is a connection point of a device (e.g., a VM NIC) to attach to a L2 Neutron network. :param context: neutron api request context :param port: dictionary describing the port :returns: { "id": uuid represeting the port. "network_id": uuid of network. "tenant_id": tenant_id "mac_address": mac address to use on this port. "admin_state_up": Sets admin state of port. if down, port does not forward packets. "status": dicates whether port is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR") "fixed_ips": list of subnet ID"s and IP addresses to be used on this port "device_id": identifies the device (e.g., virtual server) using this port. } :raises: exceptions.NetworkNotFound :raises: exceptions.StateInvalid :raises: RemoteRestError """ LOG.debug(_("NeutronRestProxyV2: create_port() called")) # Update DB in new session so exceptions rollback changes with context.session.begin(subtransactions=True): port["port"]["admin_state_up"] = False dhcp_opts = port["port"].get(edo_ext.EXTRADHCPOPTS, []) new_port = super(NeutronRestProxyV2, self).create_port(context, port) if portbindings.HOST_ID in port["port"] and "id" in new_port: host_id = port["port"][portbindings.HOST_ID] porttracker_db.put_port_hostid(context, new_port["id"], host_id) self._process_port_create_extra_dhcp_opts(context, new_port, dhcp_opts) new_port = self._extend_port_dict_binding(context, new_port) net = super(NeutronRestProxyV2, self).get_network(context, new_port["network_id"]) if self.add_meta_server_route: if new_port["device_owner"] == "network:dhcp": destination = METADATA_SERVER_IP + "/32" self._add_host_route(context, destination, new_port) # create on network ctrl mapped_port = self._map_state_and_status(new_port) self.servers.rest_create_port(net, mapped_port) # connect device to network, if present device_id = port["port"].get("device_id") if device_id: try: self.servers.rest_plug_interface(net["tenant_id"], net["id"], new_port, device_id) except RemoteRestError: with excutils.save_and_reraise_exception(): port_update = {"port": {"status": "ERROR"}} super(NeutronRestProxyV2, self).update_port(context, new_port["id"], port_update) # Set port state up and return that port port_update = {"port": {"admin_state_up": True}} new_port = super(NeutronRestProxyV2, self).update_port(context, new_port["id"], port_update) return self._extend_port_dict_binding(context, new_port)
def create_port(self, context, port): """Create a port, which is a connection point of a device (e.g., a VM NIC) to attach to a L2 Neutron network. :param context: neutron api request context :param port: dictionary describing the port :returns: { "id": uuid represeting the port. "network_id": uuid of network. "tenant_id": tenant_id "mac_address": mac address to use on this port. "admin_state_up": Sets admin state of port. if down, port does not forward packets. "status": dicates whether port is currently operational (limit values to "ACTIVE", "DOWN", "BUILD", and "ERROR") "fixed_ips": list of subnet ID"s and IP addresses to be used on this port "device_id": identifies the device (e.g., virtual server) using this port. } :raises: exceptions.NetworkNotFound :raises: exceptions.StateInvalid :raises: RemoteRestError """ LOG.debug(_("NeutronRestProxyV2: create_port() called")) # Update DB in new session so exceptions rollback changes with context.session.begin(subtransactions=True): self._ensure_default_security_group_on_port(context, port) sgids = self._get_security_groups_on_port(context, port) # non-router port status is set to pending. it is then updated # after the async rest call completes. router ports are synchronous if port["port"]["device_owner"] == l3_db.DEVICE_OWNER_ROUTER_INTF: port["port"]["status"] = const.PORT_STATUS_ACTIVE else: port["port"]["status"] = const.PORT_STATUS_BUILD dhcp_opts = port["port"].get(edo_ext.EXTRADHCPOPTS, []) new_port = super(NeutronRestProxyV2, self).create_port(context, port) self._process_port_create_security_group(context, new_port, sgids) if portbindings.HOST_ID in port["port"] and "id" in new_port: host_id = port["port"][portbindings.HOST_ID] porttracker_db.put_port_hostid(context, new_port["id"], host_id) new_port[addr_pair.ADDRESS_PAIRS] = self._process_create_allowed_address_pairs( context, new_port, port["port"].get(addr_pair.ADDRESS_PAIRS) ) self._process_port_create_extra_dhcp_opts(context, new_port, dhcp_opts) new_port = self._extend_port_dict_binding(context, new_port) net = super(NeutronRestProxyV2, self).get_network(context, new_port["network_id"]) if self.add_meta_server_route: if new_port["device_owner"] == const.DEVICE_OWNER_DHCP: destination = METADATA_SERVER_IP + "/32" self._add_host_route(context, destination, new_port) # create on network ctrl mapped_port = self._map_state_and_status(new_port) # ports have to be created synchronously when creating a router # port since adding router interfaces is a multi-call process if mapped_port["device_owner"] == l3_db.DEVICE_OWNER_ROUTER_INTF: self.servers.rest_create_port(net["tenant_id"], new_port["network_id"], mapped_port) else: self.evpool.spawn_n(self.async_port_create, net["tenant_id"], new_port["network_id"], mapped_port) self.notify_security_groups_member_updated(context, new_port) return new_port