def _sync_base(self): ctx = context.get_admin_context() # Sync Networks for network in self.core_plugin.get_networks(ctx): mech_context = driver_context.NetworkContext(self.core_plugin, ctx, network) try: self.driver.create_network_postcommit(mech_context) except Exception: LOG.warn(_LW("Create network postcommit failed for " "network %s"), network['id']) # Sync Subnets for subnet in self.core_plugin.get_subnets(ctx): mech_context = driver_context.SubnetContext(self.core_plugin, ctx, subnet) try: self.driver.create_subnet_postcommit(mech_context) except Exception: LOG.warn(_LW("Create subnet postcommit failed for" " subnet %s"), subnet['id']) # Sync Ports (compute/gateway/dhcp) for port in self.core_plugin.get_ports(ctx): _, binding = l2_db.get_locked_port_and_binding(ctx.session, port['id']) network = self.core_plugin.get_network(ctx, port['network_id']) mech_context = driver_context.PortContext(self.core_plugin, ctx, port, network, binding) try: self.driver.create_port_postcommit(mech_context) except Exception: LOG.warn(_LW("Create port postcommit failed for" " port %s"), port['id'])
def _router_removed(self, router_id, deconfigure=True): """Operations when a router is removed. Get the RouterInfo object corresponding to the router in the service helpers's router_info dict. If deconfigure is set to True, remove this router's configuration from the hosting device. :param router_id: id of the router :param deconfigure: if True, the router's configuration is deleted from the hosting device. :return: None """ ri = self.router_info.get(router_id) if ri is None: LOG.warning(_LW("Info for router %s was not found. " "Skipping router removal"), router_id) return ri.router['gw_port'] = None ri.router[l3_constants.INTERFACE_KEY] = [] ri.router[l3_constants.FLOATINGIP_KEY] = [] try: if deconfigure: self._process_router(ri) driver = self._drivermgr.get_driver(router_id) driver.router_removed(ri, deconfigure) self._drivermgr.remove_driver(router_id) del self.router_info[router_id] self.removed_routers.discard(router_id) except cfg_exceptions.DriverException: LOG.warning(_LW("Router remove for router_id: %s was incomplete. " "Adding the router to removed_routers list"), router_id) self.removed_routers.add(router_id) # remove this router from updated_routers if it is there. It might # end up there too if exception was thrown earlier inside # `_process_router()` self.updated_routers.discard(router_id)
def call_driver(self, action, network, **action_kwargs): """Invoke an action on a DHCP driver instance.""" LOG.debug('Calling driver for network: %(net)s action: %(action)s', {'net': network.id, 'action': action}) try: # the Driver expects something that is duck typed similar to # the base models. driver = self.dhcp_driver_cls(self.conf, network, self.root_helper, self.dhcp_version, self.plugin_rpc) getattr(driver, action)(**action_kwargs) return True except exceptions.Conflict: # No need to resync here, the agent will receive the event related # to a status update for the network LOG.warning(_LW('Unable to %(action)s dhcp for %(net_id)s: there ' 'is a conflict with its current state; please ' 'check that the network and/or its subnet(s) ' 'still exist.'), {'net_id': network.id, 'action': action}) except Exception as e: self.schedule_resync(e, network.id) if (isinstance(e, messaging.RemoteError) and e.exc_type == 'NetworkNotFound' or isinstance(e, exceptions.NetworkNotFound)): LOG.warning(_LW("Network %s has been deleted."), network.id) else: LOG.exception(_LE('Unable to %(action)s dhcp for %(net_id)s.') % {'net_id': network.id, 'action': action})
def get_candidates(self, plugin, context, sync_router): """Return L3 agents where a router could be scheduled.""" with context.session.begin(subtransactions=True): # allow one router is hosted by just # one enabled l3 agent hosting since active is just a # timing problem. Non-active l3 agent can return to # active any time l3_agents = plugin.get_l3_agents_hosting_routers( context, [sync_router['id']], admin_state_up=True) if l3_agents and not sync_router.get('distributed', False): LOG.debug('Router %(router_id)s has already been hosted' ' by L3 agent %(agent_id)s', {'router_id': sync_router['id'], 'agent_id': l3_agents[0]['id']}) return active_l3_agents = plugin.get_l3_agents(context, active=True) if not active_l3_agents: LOG.warn(_LW('No active L3 agents')) return new_l3agents = plugin.get_l3_agent_candidates(context, sync_router, active_l3_agents) old_l3agentset = set(l3_agents) if sync_router.get('distributed', False): new_l3agentset = set(new_l3agents) candidates = list(new_l3agentset - old_l3agentset) else: candidates = new_l3agents if not candidates: LOG.warn(_LW('No L3 agents can host the router %s'), sync_router['id']) return candidates
def _load_all_extensions_from_path(self, path): # Sorting the extension list makes the order in which they # are loaded predictable across a cluster of load-balanced # Neutron Servers for f in sorted(os.listdir(path)): try: LOG.debug('Loading extension file: %s', f) mod_name, file_ext = os.path.splitext(os.path.split(f)[-1]) ext_path = os.path.join(path, f) if file_ext.lower() == '.py' and not mod_name.startswith('_'): mod = imp.load_source(mod_name, ext_path) ext_name = mod_name[0].upper() + mod_name[1:] new_ext_class = getattr(mod, ext_name, None) if not new_ext_class: LOG.warn(_LW('Did not find expected name ' '"%(ext_name)s" in %(file)s'), {'ext_name': ext_name, 'file': ext_path}) continue new_ext = new_ext_class() self.add_extension(new_ext) except Exception as exception: LOG.warn(_LW("Extension file %(f)s wasn't loaded due to " "%(exception)s"), {'f': f, 'exception': exception})
def _get_port_infos(self, context, port, agent_host): if not agent_host: return session = db_api.get_session() agent = self.get_agent_by_host(session, agent_host) if not agent: return agent_ip = self.get_agent_ip(agent) if not agent_ip: LOG.warning(_LW("Unable to retrieve the agent ip, check the agent " "configuration.")) return segment = context.bound_segment if not segment: LOG.warning(_LW("Port %(port)s updated by agent %(agent)s " "isn't bound to any segment"), {'port': port['id'], 'agent': agent}) return network_types = self.get_agent_l2pop_network_types(agent) if network_types is None: network_types = self.get_agent_tunnel_types(agent) if segment['network_type'] not in network_types: return fdb_entries = self._get_port_fdb_entries(port) return agent, agent_host, agent_ip, segment, fdb_entries
def reschedule_routers_from_down_agents(self): """Reschedule routers from down l3 agents if admin state is up.""" # give agents extra time to handle transient failures agent_dead_limit = cfg.CONF.agent_down_time * 2 # check for an abrupt clock change since last check. if a change is # detected, sleep for a while to let the agents check in. tdelta = timeutils.utcnow() - getattr(self, '_clock_jump_canary', timeutils.utcnow()) if timeutils.total_seconds(tdelta) > cfg.CONF.agent_down_time: LOG.warn(_LW("Time since last L3 agent reschedule check has " "exceeded the interval between checks. Waiting " "before check to allow agents to send a heartbeat " "in case there was a clock adjustment.")) time.sleep(agent_dead_limit) self._clock_jump_canary = timeutils.utcnow() context = n_ctx.get_admin_context() cutoff = timeutils.utcnow() - datetime.timedelta( seconds=agent_dead_limit) down_bindings = ( context.session.query(RouterL3AgentBinding). join(agents_db.Agent). filter(agents_db.Agent.heartbeat_timestamp < cutoff, agents_db.Agent.admin_state_up)) for binding in down_bindings: LOG.warn(_LW("Rescheduling router %(router)s from agent %(agent)s " "because the agent did not report to the server in " "the last %(dead_time)s seconds."), {'router': binding.router_id, 'agent': binding.l3_agent_id, 'dead_time': agent_dead_limit}) self.reschedule_router(context, binding.router_id)
def reschedule_routers_from_down_agents(self): """Reschedule routers from down l3 agents if admin state is up.""" # give agents extra time to handle transient failures agent_dead_limit = cfg.CONF.agent_down_time * 2 # check for an abrupt clock change since last check. if a change is # detected, sleep for a while to let the agents check in. tdelta = timeutils.utcnow() - getattr(self, "_clock_jump_canary", timeutils.utcnow()) if timeutils.total_seconds(tdelta) > cfg.CONF.agent_down_time: LOG.warn( _LW( "Time since last L3 agent reschedule check has " "exceeded the interval between checks. Waiting " "before check to allow agents to send a heartbeat " "in case there was a clock adjustment." ) ) time.sleep(agent_dead_limit) self._clock_jump_canary = timeutils.utcnow() context = n_ctx.get_admin_context() cutoff = timeutils.utcnow() - datetime.timedelta(seconds=agent_dead_limit) down_bindings = ( context.session.query(RouterL3AgentBinding) .join(agents_db.Agent) .filter(agents_db.Agent.heartbeat_timestamp < cutoff, agents_db.Agent.admin_state_up) .outerjoin( l3_attrs_db.RouterExtraAttributes, l3_attrs_db.RouterExtraAttributes.router_id == RouterL3AgentBinding.router_id, ) .filter( sa.or_( l3_attrs_db.RouterExtraAttributes.ha == sql.false(), l3_attrs_db.RouterExtraAttributes.ha == sql.null(), ) ) ) try: for binding in down_bindings: LOG.warn( _LW( "Rescheduling router %(router)s from agent %(agent)s " "because the agent did not report to the server in " "the last %(dead_time)s seconds." ), {"router": binding.router_id, "agent": binding.l3_agent_id, "dead_time": agent_dead_limit}, ) try: self.reschedule_router(context, binding.router_id) except (l3agentscheduler.RouterReschedulingFailed, n_rpc.RemoteError): # Catch individual router rescheduling errors here # so one broken one doesn't stop the iteration. LOG.exception(_LE("Failed to reschedule router %s"), binding.router_id) except db_exc.DBError: # Catch DB errors here so a transient DB connectivity issue # doesn't stop the loopingcall. LOG.exception(_LE("Exception encountered during router " "rescheduling."))
def get_device_details(self, rpc_context, **kwargs): """Agent requests device details.""" agent_id = kwargs.get('agent_id') device = kwargs.get('device') host = kwargs.get('host') LOG.debug("Device %(device)s details requested by agent " "%(agent_id)s with host %(host)s", {'device': device, 'agent_id': agent_id, 'host': host}) plugin = manager.NeutronManager.get_plugin() port_id = plugin._device_to_port_id(device) port_context = plugin.get_bound_port_context(rpc_context, port_id, host) if not port_context: LOG.warning(_LW("Device %(device)s requested by agent " "%(agent_id)s not found in database"), {'device': device, 'agent_id': agent_id}) return {'device': device} segment = port_context.bound_segment port = port_context.current if not segment: LOG.warning(_LW("Device %(device)s requested by agent " "%(agent_id)s on network %(network_id)s not " "bound, vif_type: %(vif_type)s"), {'device': device, 'agent_id': agent_id, 'network_id': port['network_id'], 'vif_type': port[portbindings.VIF_TYPE]}) return {'device': device} new_status = (q_const.PORT_STATUS_BUILD if port['admin_state_up'] else q_const.PORT_STATUS_DOWN) if port['status'] != new_status: plugin.update_port_status(rpc_context, port_id, new_status, host) entry = {'device': device, 'network_id': port['network_id'], 'port_id': port_id, 'mac_address': port['mac_address'], 'admin_state_up': port['admin_state_up'], 'network_type': segment[api.NETWORK_TYPE], 'segmentation_id': segment[api.SEGMENTATION_ID], 'physical_network': segment[api.PHYSICAL_NETWORK], 'fixed_ips': port['fixed_ips'], 'device_owner': port['device_owner'], 'profile': port[portbindings.PROFILE]} LOG.debug("Returning: %s", entry) return entry
def call(self, action, resource, data, headers, binary=False): resp = self._call(action, resource, data, headers, binary) if resp[RESP_STATUS] == -1: LOG.warning(_LW('vDirect server is not responding (%s).'), self.server) return self._recover(action, resource, data, headers, binary) elif resp[RESP_STATUS] in (301, 307): LOG.warning(_LW('vDirect server is not active (%s).'), self.server) return self._recover(action, resource, data, headers, binary) else: return resp
def clear_lock(self): LOG.debug("Clearing hash record lock of id %s" % self.random_lock_id) with self.session.begin(subtransactions=True): res = (self.session.query(ConsistencyHash). filter_by(hash_id=self.hash_id).first()) if not res: LOG.warning(_LW("Hash record already gone, no lock to clear.")) return if not res.hash.startswith(self.lock_marker): # if these are frequent the server is too slow LOG.warning(_LW("Another server already removed the lock. %s"), res.hash) return res.hash = res.hash.replace(self.lock_marker, '')
def __init__(self, host, conf=None): super(L3NATAgent, self).__init__() if conf: self.conf = conf else: self.conf = cfg.CONF self.router_info = {} self.virtual_ip = '' self.virtual_mac = '' self.context = context.get_admin_context_without_session() self.plugin_rpc = L3PluginApi(topics.L3PLUGIN, host) self.dvr_base_mac = self.plugin_rpc.get_dvr_base_mac(self.context) self._setup_dataenigine_rpc() self.dataengine_rpc.delete_all_flows() self.fullsync = True # Get the list of service plugins from Neutron Server # This is the first place where we contact neutron-server on startup # so retry in case its not ready to respond. retry_count = 5 while True: retry_count = retry_count - 1 try: self.neutron_service_plugins = ( self.plugin_rpc.get_service_plugin_list(self.context)) except n_rpc.RemoteError as e: with excutils.save_and_reraise_exception() as ctx: ctx.reraise = False LOG.warning(_LW('l3-agent cannot check service plugins ' 'enabled at the neutron server when ' 'startup due to RPC error. It happens ' 'when the server does not support this ' 'RPC API. If the error is ' 'UnsupportedVersion you can ignore this ' 'warning. Detail message: %s'), e) self.neutron_service_plugins = None except messaging.MessagingTimeout as e: with excutils.save_and_reraise_exception() as ctx: if retry_count > 0: ctx.reraise = False LOG.warning(_LW('l3-agent cannot check service ' 'plugins enabled on the neutron ' 'server. Retrying. ' 'Detail message: %s'), e) continue break self._queue = RouterProcessingQueue()
def _create_backend_port(self, context, db_pool): try: subnet = self.plugin._core_plugin.get_subnet(context, db_pool["subnet_id"]) except n_exc.SubnetNotFound: LOG.warning(_LW("Subnet assigned to pool %s doesn't exist, " "backend port can't be created"), db_pool['id']) return fixed_ip = {'subnet_id': subnet['id'], 'fixed_ips': attributes.ATTR_NOT_SPECIFIED} port_data = { 'tenant_id': db_pool['tenant_id'], 'name': 'pool-' + db_pool['id'], 'network_id': subnet['network_id'], 'mac_address': attributes.ATTR_NOT_SPECIFIED, 'admin_state_up': False, 'device_id': '', 'device_owner': '', 'fixed_ips': [fixed_ip] } port = self.plugin._core_plugin.create_port(context, {'port': port_data}) return edb.add_pool_port(context, db_pool['id'], port['id'])
def _set_rules(data): default_rule = 'default' LOG.debug(_("Loading policies from file: %s"), _POLICY_PATH) # Ensure backward compatibility with folsom/grizzly convention # for extension rules policies = policy.Rules.load_json(data, default_rule) for pol in policies.keys(): if any([pol.startswith(depr_pol) for depr_pol in DEPRECATED_POLICY_MAP.keys()]): LOG.warn(_LW("Found deprecated policy rule:%s. Please consider " "upgrading your policy configuration file"), pol) pol_name, action = pol.rsplit(':', 1) try: new_actions = DEPRECATED_ACTION_MAP[action] new_policies = DEPRECATED_POLICY_MAP[pol_name] # bind new actions and policies together for actual_policy in ['_'.join(item) for item in itertools.product(new_actions, new_policies)]: if actual_policy not in policies: # New policy, same rule LOG.info(_LI("Inserting policy:%(new_policy)s in " "place of deprecated " "policy:%(old_policy)s"), {'new_policy': actual_policy, 'old_policy': pol}) policies[actual_policy] = policies[pol] # Remove old-style policy del policies[pol] except KeyError: LOG.error(_LE("Backward compatibility unavailable for " "deprecated policy %s. The policy will " "not be enforced"), pol) policy.set_rules(policies)
def _mysql_check_effective_sql_mode(engine): """Logs a message based on the effective SQL mode for MySQL connections.""" realmode = _mysql_get_effective_sql_mode(engine) if realmode is None: LOG.warning(_LW('Unable to detect effective SQL mode')) return LOG.debug('MySQL server mode set to %s', realmode) # 'TRADITIONAL' mode enables several other modes, so # we need a substring match here if not ('TRADITIONAL' in realmode.upper() or 'STRICT_ALL_TABLES' in realmode.upper()): LOG.warning(_LW("MySQL SQL mode is '%s', " "consider enabling TRADITIONAL or STRICT_ALL_TABLES"), realmode)
def release_segment(self, session, segment): physical_network = segment[api.PHYSICAL_NETWORK] vlan_id = segment[api.SEGMENTATION_ID] ranges = self.network_vlan_ranges.get(physical_network, []) inside = any(lo <= vlan_id <= hi for lo, hi in ranges) with session.begin(subtransactions=True): query = (session.query(VlanAllocation). filter_by(physical_network=physical_network, vlan_id=vlan_id)) if inside: count = query.update({"allocated": False}) if count: LOG.debug("Releasing vlan %(vlan_id)s on physical " "network %(physical_network)s to pool", {'vlan_id': vlan_id, 'physical_network': physical_network}) else: count = query.delete() if count: LOG.debug("Releasing vlan %(vlan_id)s on physical " "network %(physical_network)s outside pool", {'vlan_id': vlan_id, 'physical_network': physical_network}) if not count: LOG.warning(_LW("No vlan_id %(vlan_id)s found on physical " "network %(physical_network)s"), {'vlan_id': vlan_id, 'physical_network': physical_network})
def remove_rule(self, chain, rule, wrap=True, top=False, comment=None): """Remove a rule from a chain. Note: The rule must be exactly identical to the one that was added. You cannot switch arguments around like you can with the iptables CLI tool. """ chain = get_chain_name(chain, wrap) try: if '$' in rule: rule = ' '.join( self._wrap_target_chain(e, wrap) for e in rule.split(' ')) self.rules.remove(IptablesRule(chain, rule, wrap, top, self.wrap_name, comment=comment)) if not wrap: self.remove_rules.append(IptablesRule(chain, rule, wrap, top, self.wrap_name, comment=comment)) except ValueError: LOG.warn(_LW('Tried to remove rule that was not there:' ' %(chain)r %(rule)r %(wrap)r %(top)r'), {'chain': chain, 'rule': rule, 'top': top, 'wrap': wrap})
def bind_port(self, context): LOG.debug("Attempting to bind port %(port)s on " "network %(network)s", {'port': context.current['id'], 'network': context.network.current['id']}) vnic_type = context.current.get(portbindings.VNIC_TYPE, portbindings.VNIC_NORMAL) if vnic_type not in self.supported_vnic_types: LOG.debug("Refusing to bind due to unsupported vnic_type: %s", vnic_type) return if not self._check_supported_pci_vendor_device(context): LOG.debug("Refusing to bind due to unsupported pci_vendor device") return if self.agent_required: for agent in context.host_agents(self.agent_type): LOG.debug("Checking agent: %s", agent) if agent['alive']: if self.try_to_bind(context, agent): return else: LOG.warning(_LW("Attempting to bind with dead agent: %s"), agent) else: self.try_to_bind(context)
def _create_tunnel_port_name(self, tunnel_type, ip_address): try: ip_hex = '%08x' % netaddr.IPAddress(ip_address, version=4) return '%s-%s' % (tunnel_type, ip_hex) except Exception: LOG.warn(_LW("Unable to create tunnel port. " "Invalid remote IP: %s"), ip_address)
def get_traffic_counters(self, chain, wrap=True, zero=False): """Return the sum of the traffic counters of all rules of a chain.""" cmd_tables = self._get_traffic_counters_cmd_tables(chain, wrap) if not cmd_tables: LOG.warn(_LW('Attempted to get traffic counters of chain %s which ' 'does not exist'), chain) return name = get_chain_name(chain, wrap) acc = {'pkts': 0, 'bytes': 0} for cmd, table in cmd_tables: args = [cmd, '-t', table, '-L', name, '-n', '-v', '-x'] if zero: args.append('-Z') if self.namespace: args = ['ip', 'netns', 'exec', self.namespace] + args current_table = (self.execute(args, root_helper=self.root_helper)) current_lines = current_table.split('\n') for line in current_lines[2:]: if not line: break data = line.split() if (len(data) < 2 or not data[0].isdigit() or not data[1].isdigit()): break acc['pkts'] += int(data[0]) acc['bytes'] += int(data[1]) return acc
def _delete_load_balancer(driver, context, vip): try: driver._heleos_api.delete_dva(context.tenant_id, vip['id']) except h_exc.DvaNotFound: LOG.warning(_LW('The load balancer %s had no physical representation, ' 'likely already deleted'), vip['id']) return econ.DELETED
def _ping_listener(engine, dbapi_conn, connection_rec, connection_proxy): """Ensures that MySQL and DB2 connections are alive. Borrowed from: http://groups.google.com/group/sqlalchemy/msg/a4ce563d802c929f """ cursor = dbapi_conn.cursor() try: ping_sql = 'select 1' if engine.name == 'ibm_db_sa': # DB2 requires a table expression ping_sql = 'select 1 from (values (1)) AS t1' cursor.execute(ping_sql) except Exception as ex: if engine.dialect.is_disconnect(ex, dbapi_conn, cursor): msg = _LW('Database server has gone away: %s') % ex LOG.warning(msg) # if the database server has gone away, all connections in the pool # have become invalid and we can safely close all of them here, # rather than waste time on checking of every single connection engine.dispose() # this will be handled by SQLAlchemy and will force it to create # a new connection and retry the original action raise sqla_exc.DisconnectionError(msg) else: raise
def _port_action(self, plugin, context, port, action): """Perform port operations taking care of concurrency issues.""" try: if action == 'create_port': return plugin.create_port(context, port) elif action == 'update_port': return plugin.update_port(context, port['id'], port) else: msg = _('Unrecognized action') raise n_exc.Invalid(message=msg) except (db_exc.DBError, n_exc.NetworkNotFound, n_exc.SubnetNotFound, n_exc.IpAddressGenerationFailure) as e: with excutils.save_and_reraise_exception(reraise=False) as ctxt: if isinstance(e, n_exc.IpAddressGenerationFailure): # Check if the subnet still exists and if it does not, # this is the reason why the ip address generation failed. # In any other unlikely event re-raise try: subnet_id = port['port']['fixed_ips'][0]['subnet_id'] plugin.get_subnet(context, subnet_id) except n_exc.SubnetNotFound: pass else: ctxt.reraise = True net_id = port['port']['network_id'] LOG.warn(_LW("Action %(action)s for network %(net_id)s " "could not complete successfully: %(reason)s"), {"action": action, "net_id": net_id, 'reason': e})
def _agent_registration(self): """Register this agent with the server. This method registers the cfg agent with the neutron server so hosting devices can be assigned to it. In case the server is not ready to accept registration (it sends a False) then we retry registration for `MAX_REGISTRATION_ATTEMPTS` with a delay of `REGISTRATION_RETRY_DELAY`. If there is no server response or a failure to register after the required number of attempts, the agent stops itself. """ for attempts in xrange(MAX_REGISTRATION_ATTEMPTS): context = n_context.get_admin_context_without_session() self.send_agent_report(self.agent_state, context) res = self.devmgr_rpc.register_for_duty(context) if res is True: LOG.info(_LI("[Agent registration] Agent successfully " "registered")) return elif res is False: LOG.warning(_LW("[Agent registration] Neutron server said " "that device manager was not ready. Retrying " "in %0.2f seconds "), REGISTRATION_RETRY_DELAY) time.sleep(REGISTRATION_RETRY_DELAY) elif res is None: LOG.error(_LE("[Agent registration] Neutron server said that " "no device manager was found. Cannot continue. " "Exiting!")) raise SystemExit("Cfg Agent exiting") LOG.error(_LE("[Agent registration] %d unsuccessful registration " "attempts. Exiting!"), MAX_REGISTRATION_ATTEMPTS) raise SystemExit("Cfg Agent exiting")
def _wait_child(self): try: # Don't block if no child processes have exited pid, status = os.waitpid(0, os.WNOHANG) if not pid: return None except OSError as exc: if exc.errno not in (errno.EINTR, errno.ECHILD): raise return None if os.WIFSIGNALED(status): sig = os.WTERMSIG(status) LOG.info(_LI('Child %(pid)d killed by signal %(sig)d'), dict(pid=pid, sig=sig)) else: code = os.WEXITSTATUS(status) LOG.info(_LI('Child %(pid)s exited with status %(code)d'), dict(pid=pid, code=code)) if pid not in self.children: LOG.warning(_LW('pid %d not in child list'), pid) return None wrap = self.children.pop(pid) wrap.children.remove(pid) return wrap
def _get_enabled_agents(self, context, network, agents, method, payload): """Get the list of agents whose admin_state is UP.""" network_id = network['id'] enabled_agents = [x for x in agents if x.admin_state_up] active_agents = [x for x in agents if x.is_active] len_enabled_agents = len(enabled_agents) len_active_agents = len(active_agents) if len_active_agents < len_enabled_agents: LOG.warn(_LW("Only %(active)d of %(total)d DHCP agents associated " "with network '%(net_id)s' are marked as active, so " "notifications may be sent to inactive agents."), {'active': len_active_agents, 'total': len_enabled_agents, 'net_id': network_id}) if not enabled_agents: num_ports = self.plugin.get_ports_count( context, {'network_id': [network_id]}) notification_required = ( num_ports > 0 and len(network['subnets']) >= 1) if notification_required: LOG.error(_LE("Will not send event %(method)s for network " "%(net_id)s: no agent available. Payload: " "%(payload)s"), {'method': method, 'net_id': network_id, 'payload': payload}) return enabled_agents
def get_traffic_counters(self, chain, wrap=True, zero=False): """Return the sum of the traffic counters of all rules of a chain.""" cmd_tables = self._get_traffic_counters_cmd_tables(chain, wrap) if not cmd_tables: LOG.warn(_LW("Attempted to get traffic counters of chain %s which " "does not exist"), chain) return name = get_chain_name(chain, wrap) acc = {"pkts": 0, "bytes": 0} for cmd, table in cmd_tables: args = [cmd, "-t", table, "-L", name, "-n", "-v", "-x"] if zero: args.append("-Z") if self.namespace: args = ["ip", "netns", "exec", self.namespace] + args current_table = self.execute(args, root_helper=self.root_helper) current_lines = current_table.split("\n") for line in current_lines[2:]: if not line: break data = line.split() if len(data) < 2 or not data[0].isdigit() or not data[1].isdigit(): break acc["pkts"] += int(data[0]) acc["bytes"] += int(data[1]) return acc
def get_configuration_dict(self, agent_db): try: conf = jsonutils.loads(agent_db.configurations) except Exception: msg = _LW("Configuration for agent %(agent_type)s on host %(host)s" " is invalid.") LOG.warn(msg, {"agent_type": agent_db.agent_type, "host": agent_db.host}) conf = {} return conf
def _get_fip_data(self, fip_id): fip = None try: fip_db = nuagedb.get_fip_with_lock(self.context.session, fip_id) fip = self._make_floatingip_dict(fip_db) except db_exc.NoResultFound: LOG.warning(_LW("Floating ip %s not found in neutron for sync"), fip_id) return fip
def _get_port_data(self, port_id): port = None try: port_db = nuagedb.get_port_with_lock(self.context.session, port_id) port = self._make_port_dict(port_db) except db_exc.NoResultFound: LOG.warning(_LW("VM port %s not found in neutron for sync"), port_id) return port
def _get_ipalloc_for_fip(self, fip): ipalloc = None try: ipalloc = nuagedb.get_ipalloc_for_fip(self.context.session, fip['floating_network_id'], fip['floating_ip_address'], lock=True) except db_exc.NoResultFound: LOG.warning(_LW("IP allocation for floating ip %s not found in " "neutron for sync"), fip['id']) return ipalloc
def bind_port(self, context): """Binds port to current network segment. Binds port only if the vnic_type is direct or macvtap and the port is from a supported vendor. While binding port set it in ACTIVE state and provide the Port Profile or Vlan Id as part vif_details. """ vnic_type = context.current.get(portbindings.VNIC_TYPE, portbindings.VNIC_NORMAL) LOG.debug( "Attempting to bind port %(port)s with vnic_type " "%(vnic_type)s on network %(network)s", { 'port': context.current['id'], 'vnic_type': vnic_type, 'network': context.network.current['id'] }) profile = context.current.get(portbindings.PROFILE, {}) if not self.driver.check_vnic_type_and_vendor_info(vnic_type, profile): return for segment in context.network.network_segments: if self.check_segment(segment): vlan_id = segment[api.SEGMENTATION_ID] if not vlan_id: LOG.warn(_LW("Bind port: vlan_id is None.")) return LOG.debug("Port binding to Vlan_id: %s", str(vlan_id)) # Check if this is a Cisco VM-FEX port or Intel SR_IOV port if self.driver.is_vmfex_port(profile): profile_name = self.make_profile_name(vlan_id) self.vif_details[ const.VIF_DETAILS_PROFILEID] = profile_name else: self.vif_details[portbindings.VIF_DETAILS_VLAN] = str( vlan_id) context.set_binding(segment[api.ID], self.vif_type, self.vif_details, constants.PORT_STATUS_ACTIVE) return LOG.error( _LE("UCS Mech Driver: Failed binding port ID %(id)s " "on any segment of network %(network)s"), { 'id': context.current['id'], 'network': context.network.current['id'] })
def _plugins_support(self, extension): alias = extension.get_alias() supports_extension = any( (hasattr(plugin, "supported_extension_aliases") and alias in plugin.supported_extension_aliases) for plugin in self.plugins.values()) if not supports_extension: LOG.warn( _LW("Extension %s not supported by any of loaded " "plugins"), alias) return supports_extension
def _get_sec_grp_rule_data(self, secgrprule_id): secgrprule = None try: secrule_db = nuagedb.get_secgrprule_with_lock( self.context.session, secgrprule_id) secgrprule = self._make_security_group_rule_dict(secrule_db) except db_exc.NoResultFound: LOG.warning( _LW("Security group rule %s not found in neutron for " "sync"), secgrprule_id) return secgrprule
def release_segment(self, session, segment): physical_network = segment[api.PHYSICAL_NETWORK] with session.begin(subtransactions=True): count = (session.query(FlatAllocation).filter_by( physical_network=physical_network).delete()) if count: LOG.debug("Releasing flat network on physical network %s", physical_network) else: LOG.warning(_LW("No flat network found on physical network %s"), physical_network)
def _initialize_service_helpers(self, host): svc_helper_class = self.conf.cfg_agent.routing_svc_helper_class try: self.routing_service_helper = importutils.import_object( svc_helper_class, host, self.conf, self) except ImportError as e: LOG.warning(_LW("Error in loading routing service helper. Class " "specified is %(class)s. Reason:%(reason)s"), {'class': self.conf.cfg_agent.routing_svc_helper_class, 'reason': e}) self.routing_service_helper = None
def _check_enhanced_rpc_is_supported_by_server(self): try: self.plugin_rpc.security_group_info_for_devices( self.context, devices=[]) except messaging.UnsupportedVersion: LOG.warning(_LW('security_group_info_for_devices rpc call not ' 'supported by the server, falling back to old ' 'security_group_rules_for_devices which scales ' 'worse.')) return False return True
def restart(self): if self.process.active: self._output_config_file() self.process.reload_cfg() else: LOG.warn( _LW('A previous instance of keepalived seems to be dead, ' 'unable to restart it, a new instance will be ' 'spawned')) self.process.disable() self.spawn()
def add_endpoint(self, ip): LOG.debug("add_gre_endpoint() called for ip %s", ip) session = db_api.get_session() try: gre_endpoint = GreEndpoints(ip_address=ip) gre_endpoint.save(session) except db_exc.DBDuplicateEntry: gre_endpoint = (session.query(GreEndpoints).filter_by( ip_address=ip).one()) LOG.warning(_LW("Gre endpoint with ip %s already exists"), ip) return gre_endpoint
def get_vif_port_by_id(self, port_id): args = ['--format=json', '--', '--columns=external_ids,name,ofport', 'find', 'Interface', 'external_ids:iface-id="%s"' % port_id] result = self.run_vsctl(args) if not result: return json_result = jsonutils.loads(result) try: # Retrieve the indexes of the columns we're looking for headings = json_result['headings'] ext_ids_idx = headings.index('external_ids') name_idx = headings.index('name') ofport_idx = headings.index('ofport') # If data attribute is missing or empty the line below will raise # an exeception which will be captured in this block. # We won't deal with the possibility of ovs-vsctl return multiple # rows since the interface identifier is unique for data in json_result['data']: port_name = data[name_idx] switch = get_bridge_for_iface(self.root_helper, port_name) if switch != self.br_name: continue ofport = data[ofport_idx] # ofport must be integer otherwise return None if not isinstance(ofport, int) or ofport == -1: LOG.warn(_LW("ofport: %(ofport)s for VIF: %(vif)s is not a" " positive integer"), {'ofport': ofport, 'vif': port_id}) return # Find VIF's mac address in external ids ext_id_dict = dict((item[0], item[1]) for item in data[ext_ids_idx][1]) vif_mac = ext_id_dict['attached-mac'] return VifPort(port_name, ofport, port_id, vif_mac, self) LOG.info(_LI("Port %(port_id)s not present in bridge %(br_name)s"), {'port_id': port_id, 'br_name': self.br_name}) except Exception as error: LOG.warn(_LW("Unable to parse interface details. Exception: %s"), error) return
def update_nexusport_binding(port_id, new_vlan_id): """Updates nexusport binding.""" if not new_vlan_id: LOG.warning(_LW("update_nexusport_binding called with no vlan")) return LOG.debug("update_nexusport_binding called") session = db.get_session() binding = _lookup_one_nexus_binding(session=session, port_id=port_id) binding.vlan_id = new_vlan_id session.merge(binding) session.flush() return binding
def _delete_pip_nports(success): if success: for port in ports: try: self.plugin._core_plugin.delete_port( context, port['id']) LOG.debug('pip nport id: %s', port['id']) except Exception as exception: # stop exception propagation, nport may have # been deleted by other means LOG.warning(_LW('pip nport delete failed: %r'), exception)
def _proxy_request(self, instance_id, tenant_id, req): headers = { 'X-Forwarded-For': req.headers.get('X-Forwarded-For'), 'X-Instance-ID': instance_id, 'X-Tenant-ID': tenant_id, 'X-Instance-ID-Signature': self._sign_instance_id(instance_id) } nova_ip_port = '%s:%s' % (self.conf.nova_metadata_ip, self.conf.nova_metadata_port) url = urlparse.urlunsplit(( self.conf.nova_metadata_protocol, nova_ip_port, req.path_info, req.query_string, '')) h = httplib2.Http( ca_certs=self.conf.auth_ca_cert, disable_ssl_certificate_validation=self.conf.nova_metadata_insecure ) if self.conf.nova_client_cert and self.conf.nova_client_priv_key: h.add_certificate(self.conf.nova_client_priv_key, self.conf.nova_client_cert, nova_ip_port) resp, content = h.request(url, method=req.method, headers=headers, body=req.body) if resp.status == 200: LOG.debug(str(resp)) req.response.content_type = resp['content-type'] req.response.body = content return req.response elif resp.status == 403: LOG.warn(_LW( 'The remote metadata server responded with Forbidden. This ' 'response usually occurs when shared secrets do not match.' )) return webob.exc.HTTPForbidden() elif resp.status == 400: return webob.exc.HTTPBadRequest() elif resp.status == 404: return webob.exc.HTTPNotFound() elif resp.status == 409: return webob.exc.HTTPConflict() elif resp.status == 500: msg = _( 'Remote metadata server experienced an internal server error.' ) LOG.warn(msg) return webob.exc.HTTPInternalServerError(explanation=unicode(msg)) else: raise Exception(_('Unexpected response code: %s') % resp.status)
def add_endpoint(self, ip, udp_port=VXLAN_UDP_PORT): LOG.debug("add_vxlan_endpoint() called for ip %s", ip) session = db_api.get_session() try: vxlan_endpoint = VxlanEndpoints(ip_address=ip, udp_port=udp_port) vxlan_endpoint.save(session) except db_exc.DBDuplicateEntry: vxlan_endpoint = (session.query(VxlanEndpoints). filter_by(ip_address=ip).one()) LOG.warning(_LW("Vxlan endpoint with ip %s already exists"), ip) return vxlan_endpoint
def _sync_router(self): ctx = context.get_admin_context() # Sync Router Interfaces filters = {'device_owner': [n_constants.DEVICE_OWNER_ROUTER_INTF]} for interface in self.core_plugin.get_ports(ctx, filters=filters): try: self.driver.add_router_interface_postcommit( ctx, interface['device_id'], {'port_id': interface['id']}) except Exception: LOG.warn(_LW("Add interface postcommit failed for " "port %s"), interface['id'])
def update_port_postcommit(self, context): """Creates a port profile on UCS Manager. Creates a Port Profile for this VLAN if it does not already exist. """ LOG.debug("Inside update_port_postcommit") vlan_id = self._get_vlanid(context) if not vlan_id: LOG.warn(_LW("update_port_postcommit: vlan_id is None.")) return # Check if UCS Manager needs to create a Port Profile. # 1. Make sure this is a vm_fex_port.(Port profiles are created # only for VM-FEX ports.) # 2. Make sure update_port_precommit added an entry in the DB # for this port profile # 3. Make sure that the Port Profile hasn't already been created. profile = context.current.get(portbindings.PROFILE, {}) vnic_type = context.current.get(portbindings.VNIC_TYPE, portbindings.VNIC_NORMAL) if (self.driver.check_vnic_type_and_vendor_info(vnic_type, profile) and self.driver.is_vmfex_port(profile)): LOG.debug( "update_port_postcommit: VM-FEX port updated for " "vlan_id %d", vlan_id) profile_name = self.ucsm_db.get_port_profile_for_vlan(vlan_id) if self.ucsm_db.is_port_profile_created(vlan_id): LOG.debug( "update_port_postcommit: Port Profile %s for " "vlan_id %d already exists. Nothing to do.", profile_name, vlan_id) return # Ask the UCS Manager driver to create the above Port Profile. # Connection to the UCS Manager is managed from within the driver. if self.driver.create_portprofile(profile_name, vlan_id, vnic_type): # Port profile created on UCS, record that in the DB. self.ucsm_db.set_port_profile_created(vlan_id, profile_name) return else: # Enable vlan-id for this regular Neutron virtual port. host_id = context.current.get(portbindings.HOST_ID) LOG.debug("update_port_postcommit: Host_id is %s", host_id) self.driver.update_serviceprofile(host_id, vlan_id)
def schedule_snat_router(self, context, router_id, sync_router): """Schedule the snat router on l3 service agent.""" active_l3_agents = self.get_l3_agents(context, active=True) if not active_l3_agents: LOG.warn(_LW('No active L3 agents found for SNAT')) return snat_candidates = self.get_snat_candidates(sync_router, active_l3_agents) if snat_candidates: chosen_agent = self.bind_snat_servicenode( context, router_id, snat_candidates) self.bind_dvr_router_servicenode( context, router_id, chosen_agent)
def get_vif_port_set(self): port_names = self.get_port_name_list() edge_ports = set() args = [ '--format=json', '--', '--columns=name,external_ids,ofport', 'list', 'Interface' ] result = self.run_vsctl(args, check_error=True) if not result: return edge_ports for row in jsonutils.loads(result)['data']: name = row[0] if name not in port_names: continue external_ids = dict(row[1][1]) # Do not consider VIFs which aren't yet ready # This can happen when ofport values are either [] or ["set", []] # We will therefore consider only integer values for ofport ofport = row[2] try: int_ofport = int(ofport) except (ValueError, TypeError): LOG.warn(_LW("Found not yet ready openvswitch port: %s"), row) else: if int_ofport > 0: if ("iface-id" in external_ids and "attached-mac" in external_ids): edge_ports.add(external_ids['iface-id']) elif ("xs-vif-uuid" in external_ids and "attached-mac" in external_ids): # if this is a xenserver and iface-id is not # automatically synced to OVS from XAPI, we grab it # from XAPI directly iface_id = self.get_xapi_iface_id( external_ids["xs-vif-uuid"]) edge_ports.add(iface_id) else: LOG.warn(_LW("Found failed openvswitch port: %s"), row) return edge_ports
def _get_route_data(self, rt): route = None try: route = nuagedb.get_route_with_lock(self.context.session, rt['destination'], rt['nexthop']) except db_exc.NoResultFound: LOG.warning(_LW("Route with destination %(dest)s and nexthop " "%(hop)s not found in neutron for sync"), {'dest': rt['destination'], 'hop': rt['nexthop']}) return route
def get_stats(self, pool_id): socket_path = self._get_state_file_path(pool_id, 'sock', False) TYPE_BACKEND_REQUEST = 2 TYPE_SERVER_REQUEST = 4 if os.path.exists(socket_path): parsed_stats = self._get_stats_from_socket( socket_path, entity_type=TYPE_BACKEND_REQUEST | TYPE_SERVER_REQUEST) pool_stats = self._get_backend_stats(parsed_stats) pool_stats['members'] = self._get_servers_stats(parsed_stats) return pool_stats else: LOG.warn(_LW('Stats socket not found for pool %s'), pool_id) return {}
def record_port_status_changed(self, port, current_port_status, previous_port_status, initiator): """Determine if nova needs to be notified due to port status change. """ # clear out previous _notify_event port._notify_event = None # If there is no device_id set there is nothing we can do here. if not port.device_id: LOG.debug("device_id is not set on port yet.") return if not port.id: LOG.warning(_LW("Port ID not set! Nova will not be notified of " "port status change.")) return # We only want to notify about nova ports. if not self._is_compute_port(port): return # We notify nova when a vif is unplugged which only occurs when # the status goes from ACTIVE to DOWN. if (previous_port_status == constants.PORT_STATUS_ACTIVE and current_port_status == constants.PORT_STATUS_DOWN): event_name = VIF_UNPLUGGED # We only notify nova when a vif is plugged which only occurs # when the status goes from: # NO_VALUE/DOWN/BUILD -> ACTIVE/ERROR. elif (previous_port_status in [sql_attr.NO_VALUE, constants.PORT_STATUS_DOWN, constants.PORT_STATUS_BUILD] and current_port_status in [constants.PORT_STATUS_ACTIVE, constants.PORT_STATUS_ERROR]): event_name = VIF_PLUGGED # All the remaining state transitions are of no interest to nova else: LOG.debug("Ignoring state change previous_port_status: " "%(pre_status)s current_port_status: %(cur_status)s" " port_id %(id)s", {'pre_status': previous_port_status, 'cur_status': current_port_status, 'id': port.id}) return port._notify_event = ( {'server_uuid': port.device_id, 'name': event_name, 'status': NEUTRON_NOVA_EVENT_STATUS_MAP.get(current_port_status), 'tag': port.id})
def _report_state(self): try: self.state_rpc.report_state(self.context, self.agent_state, self.use_call) self.agent_state.pop('start_flag', None) self.use_call = False except AttributeError: # This means the server does not support report_state LOG.warn(_LW("Neutron server does not support state report." " State report for this agent will be disabled.")) self.heartbeat.stop() return except Exception: LOG.exception(_LE("Failed reporting state!"))
def delete_ipsec_site_connection(self, context, conn_id): """Delete the site-to-site IPSec connection. This will be best effort and will continue, if there are any failures. """ LOG.debug('Deleting IPSec connection %s', conn_id) if not self.steps: LOG.warning(_LW('Unable to find connection %s'), conn_id) else: self.do_rollback() LOG.info(_LI("SUCCESS: Deleted IPSec site-to-site connection %s"), conn_id)
def check_cli_commands(self): """Checks whether the CLI commands are vaild. This method tries to execute the commands on EOS and if it succeedes the command is stored. """ cmd = ['show openstack config region %s timestamp' % self.region] try: self._run_eos_cmds(cmd) self.cli_commands['timestamp'] = cmd except arista_exc.AristaRpcError: self.cli_commands['timestamp'] = [] LOG.warn(_LW("'timestamp' command '%s' is not available on EOS"), cmd)
def update_router_state(self, context, router_id, state, host): with context.session.begin(subtransactions=True): bindings = self.get_ha_router_port_bindings( context, [router_id], host) if bindings: if len(bindings) > 1: LOG.warn( _LW("The router %(router_id)s is bound multiple " "times on the agent %(host)s"), { 'router_id': router_id, 'host': host }) bindings[0].update({'state': state})
def _get_pagination_max_limit(): max_limit = -1 if (cfg.CONF.pagination_max_limit.lower() != constants.PAGINATION_INFINITE): try: max_limit = int(cfg.CONF.pagination_max_limit) if max_limit == 0: raise ValueError() except ValueError: LOG.warn( _LW("Invalid value for pagination_max_limit: %s. It " "should be an integer greater to 0"), cfg.CONF.pagination_max_limit) return max_limit
def call_driver(self, action, network, **action_kwargs): """Invoke an action on a DHCP driver instance.""" LOG.debug('Calling driver for network: %(net)s action: %(action)s', { 'net': network.id, 'action': action }) try: # the Driver expects something that is duck typed similar to # the base models. driver = self.dhcp_driver_cls(self.conf, network, self.root_helper, self.dhcp_version, self.plugin_rpc) getattr(driver, action)(**action_kwargs) return True except exceptions.Conflict: # No need to resync here, the agent will receive the event related # to a status update for the network LOG.warning( _LW('Unable to %(action)s dhcp for %(net_id)s: there ' 'is a conflict with its current state; please ' 'check that the network and/or its subnet(s) ' 'still exist.'), { 'net_id': network.id, 'action': action }) except Exception as e: self.schedule_resync(e, network.id) if (isinstance(e, messaging.RemoteError) and e.exc_type == 'NetworkNotFound' or isinstance(e, exceptions.NetworkNotFound)): LOG.warning(_LW("Network %s has been deleted."), network.id) else: LOG.exception( _LE('Unable to %(action)s dhcp for %(net_id)s.') % { 'net_id': network.id, 'action': action })
def send_events(self): if not self.pending_events: return batched_events = self.pending_events self.pending_events = [] LOG.debug("Sending events: %s", batched_events) try: response = self.nclient.server_external_events.create( batched_events) except nova_exceptions.NotFound: LOG.warning(_LW("Nova returned NotFound for event: %s"), batched_events) except Exception: LOG.exception(_LE("Failed to notify nova on events: %s"), batched_events) else: if not isinstance(response, list): LOG.error(_LE("Error response returned from nova: %s"), response) return response_error = False for event in response: try: code = event['code'] except KeyError: response_error = True continue if code != 200: LOG.warning(_LW("Nova event: %s returned with failed " "status"), event) else: LOG.info(_LI("Nova event response: %s"), event) if response_error: LOG.error(_LE("Error response returned from nova: %s"), response)
def schedule(self, plugin, context, network): """Schedule the network to active DHCP agent(s). A list of scheduled agents is returned. """ agents_per_network = cfg.CONF.dhcp_agents_per_network #TODO(gongysh) don't schedule the networks with only # subnets whose enable_dhcp is false with context.session.begin(subtransactions=True): dhcp_agents = plugin.get_dhcp_agents_hosting_networks( context, [network['id']], active=True) if len(dhcp_agents) >= agents_per_network: LOG.debug('Network %s is hosted already', network['id']) return n_agents = agents_per_network - len(dhcp_agents) enabled_dhcp_agents = plugin.get_agents_db( context, filters={ 'agent_type': [constants.AGENT_TYPE_DHCP], 'admin_state_up': [True]}) if not enabled_dhcp_agents: LOG.warn(_LW('No more DHCP agents')) return active_dhcp_agents = [ agent for agent in set(enabled_dhcp_agents) if not agents_db.AgentDbMixin.is_agent_down( agent['heartbeat_timestamp']) and agent not in dhcp_agents ] if not active_dhcp_agents: LOG.warn(_LW('No more DHCP agents')) return n_agents = min(len(active_dhcp_agents), n_agents) chosen_agents = random.sample(active_dhcp_agents, n_agents) self._schedule_bind_network(context, chosen_agents, network['id']) return chosen_agents
def treat_devices_added_or_updated(self, devices): resync = False all_ports = dict((p.normalized_port_name(), p) for p in self._get_ports(self.int_br) if p.is_neutron_port()) for device in devices: LOG.debug("Processing port %s", device) if device not in all_ports: # The port has disappeared and should not be processed # There is no need to put the port DOWN in the plugin as # it never went up in the first place LOG.info(_LI("Port %s was not found on the integration bridge " "and will therefore not be processed"), device) continue port = all_ports[device] try: details = self.plugin_rpc.get_device_details(self.context, device, self.agent_id) except Exception as e: LOG.debug("Unable to get port details for %(device)s: %(e)s", {'device': device, 'e': e}) resync = True continue if 'port_id' in details: LOG.info(_LI("Port %(device)s updated. Details: %(details)s"), {'device': device, 'details': details}) port.vif_mac = details.get('mac_address') self.treat_vif_port(port, details['port_id'], details['network_id'], details['network_type'], details['physical_network'], details['segmentation_id'], details['admin_state_up']) # update plugin about port status if details.get('admin_state_up'): LOG.debug("Setting status for %s to UP", device) self.plugin_rpc.update_device_up( self.context, device, self.agent_id, cfg.CONF.host) else: LOG.debug("Setting status for %s to DOWN", device) self.plugin_rpc.update_device_down( self.context, device, self.agent_id, cfg.CONF.host) LOG.info(_LI("Configuration for device %s completed."), device) else: LOG.warn(_LW("Device %s not defined on plugin"), device) if (port and port.ofport != -1): self.port_dead(port) return resync