def _notify_agent(self, network_info): host = None cluster_id = network_info['cluster_id'] if 'host' in network_info: host = network_info['host'] else: agent = self._get_ovsvapp_agent_from_cluster(self.context, cluster_id) LOG.debug("Agent chosen for notification: %s.", agent) if agent and 'host' in agent: host = agent['host'] else: LOG.error(_LE("Failed to find OVSvApp Agent with host " "%(host)s while releasing network allocations " "for %(cluster)s in vCenter %(vcenter)s."), {'host': host, 'vcenter': network_info['vcenter_id'], 'cluster': cluster_id}) return try: LOG.info(_LI("Initiating device_delete RPC for network " "%(network)s to OVSvApp agent on host %(host)s."), {'host': host, 'network': network_info}) self.notifier.device_delete(self.context, network_info, host, cluster_id) except Exception: LOG.exception(_LE("Failed to notify agent to delete port group."))
def _parse_mapping(self, entry): """Parse an entry of cluster_dvs_mapping. :param entry: String value which is an entry in conf file for cluster_dvs_mapping. Could be a simple mapping in the form clusterpath:dvsname or a comma separated one like clusterpath1:dvsname1,clusterpath2:dvsname2 :returns: A list of (cluster, dvs) tuples """ try: cluster_dvs_list = [] LOG.debug("Parsing cluster_dvs_mapping %s.", entry) mappings = entry.split(",") for mapping in mappings: cluster = None vds = None if ":" in mapping: cluster, vds = mapping.split(":", 1) cluster = cluster.strip() vds = vds.strip() if not cluster or not vds: LOG.error(_LE("Invalid value %s for opt " "cluster_dvs_mapping."), mapping) else: cluster_dvs_list.append((cluster, vds)) except Exception: LOG.exception(_LE("Invalid value %s for opt cluster_dvs_mapping."), entry) return cluster_dvs_list
def is_valid_dvswitch(session, cluster_mor, dvs_name): """Validate a DVS. Check if DVS exists for a cluster specified in conf. Also validate if DVS is attached to all hosts in a cluster. """ dvs_mor = get_dvs_mor_by_name(session, dvs_name) if dvs_mor: dvs_config = session._call_method( vim_util, "get_dynamic_property", dvs_mor, "DistributedVirtualSwitch", "config.host") # Get all the host attached to given VDS dvs_host_members = dvs_config[0] dvs_attached_host_ids = [] for dvs_host_member in dvs_host_members: dvs_attached_host_ids.append(dvs_host_member.config.host.value) # Get all the hosts present in the cluster hosts_in_cluster = resource_util.get_host_mors_for_cluster( session, cluster_mor) # Check if the host on which OVSvApp VM is hosted is a part of DVSwitch if hosts_in_cluster: for host in hosts_in_cluster: hostname = resource_util.get_hostname_for_host_mor( session, host) if hostname == cfg.CONF.VMWARE.esx_hostname: if host.value not in dvs_attached_host_ids: LOG.error(_LE("DVS not present on" "host %s"), host.value) return False return hosts_in_cluster else: LOG.error(_LE("DVS not present %s"), dvs_name) return False
def update_device_binding(self, rpc_context, **kwargs): agent_id = kwargs.get('agent_id') device_id = kwargs.get('device') host = kwargs.get('host') updated_ports = set() ports = None ports = self.plugin.get_ports(rpc_context, filters={'device_id': [device_id]}) for port in ports: network = self.plugin.get_network(rpc_context, port['network_id']) port['network_type'] = network['provider:network_type'] if network['provider:network_type'] == common_const.TYPE_VXLAN: retry_count = 3 while retry_count > 0: sleep = False for pport in ports: if pport['status'] != common_const.PORT_STATUS_ACTIVE: sleep = True break if sleep: time.sleep(retry_count * 3) retry_count -= 1 ports = self.plugin.get_ports(rpc_context, filters={'device_id': [device_id]}) else: port['status'] = common_const.PORT_STATUS_ACTIVE break if retry_count == 0: LOG.error(_LE("Failed to update binding for device %s, " "as the device has one of more ports " "in BUILD state."), device_id) return port_id = port['id'] LOG.debug("Port %(port_id)s update_port invoked by agent " "%(agent_id)s for host %(host)s.", {'port_id': port_id, 'agent_id': agent_id, 'host': host}) new_port = {'port': {portbindings.HOST_ID: host}} try: updated_port = self.plugin.update_port(rpc_context, port_id, new_port) updated_ports.add(updated_port['id']) if port['network_type'] == common_const.TYPE_VXLAN: time.sleep(1) new_status = (common_const.PORT_STATUS_BUILD if port['admin_state_up'] else common_const.PORT_STATUS_DOWN) if port['status'] != new_status: self.plugin.update_port_status(rpc_context, port['id'], new_status, host) time.sleep(1) kwargs['device'] = port_id self.update_device_up(rpc_context, **kwargs) except Exception: LOG.exception(_LE("Failed to update binding for port " "%s."), port_id) return updated_ports
def initialize_driver(self): self.stop() self.driver = None self.vcenter_ip = cfg.CONF.VMWARE.vcenter_ip self.vcenter_username = cfg.CONF.VMWARE.vcenter_username self.vcenter_password = cfg.CONF.VMWARE.vcenter_password self.vcenter_api_retry_count = cfg.CONF.VMWARE.vcenter_api_retry_count self.wsdl_location = cfg.CONF.VMWARE.wsdl_location self.https_port = cfg.CONF.VMWARE.https_port self.ca_path = None self.connection_timeout = cfg.CONF.VMWARE.connection_timeout if cfg.CONF.VMWARE.cert_check: if not cfg.CONF.VMWARE.cert_path: LOG.error(_LE("SSL certificate path is not defined to " "establish secure vCenter connection. " "Aborting agent!")) raise SystemExit(1) elif not os.path.isfile(cfg.CONF.VMWARE.cert_path): LOG.error(_LE("SSL certificate does not exist at " "the specified path %s. Aborting agent!"), cfg.CONF.VMWARE.cert_path) raise SystemExit(1) else: self.ca_path = cfg.CONF.VMWARE.cert_path if (self.vcenter_ip and self.vcenter_username and self.vcenter_password and self.wsdl_location): vim_session.ConnectionHandler.set_vc_details( self.vcenter_ip, self.vcenter_username, self.vcenter_password, self.vcenter_api_retry_count, self.wsdl_location, self.ca_path, self.connection_timeout, self.https_port) vim_session.ConnectionHandler.start() if self.connection_thread: self.connection_thread.kill() self.connection_thread = eventlet.spawn( vim_session.ConnectionHandler.try_connection) try: self.connection_thread.wait() except greenlet.GreenletExit: LOG.warning(_LW("Thread waiting on vCenter connection " "exited.")) return else: LOG.error(_LE("Must specify vcenter_ip, vcenter_username, " "vcenter_password and wsdl_location.")) return self.driver = dvs_driver.DvsNetworkDriver() self.driver.set_callback(self.netcallback) for mapping in cfg.CONF.VMWARE.cluster_dvs_mapping: cluster_dvs_list = self._parse_mapping(mapping) for cluster, vds in cluster_dvs_list: self._add_cluster(cluster, vds)
def try_connection(cls): while not cls.stopped: try: return cls.get_connection(create=True) except Exception as e: LOG.error(_LE("Connection to vCenter %(host_ip)s failed -" "%(exception)s"), {"host_ip": cls.host_ip, "exception": e}) LOG.error(_LE("Will retry after 60 secs")) time.sleep(60) LOG.error(_LE("Retrying VMWare Connection after 60 secs")) continue
def monitor_events(self): try: LOG.info(_LI("Starting monitoring for vCenter updates")) version = "" self.state = constants.DRIVER_RUNNING while self.state in (constants.DRIVER_RUNNING): try: LOG.debug("Waiting for vCenter updates...") try: updateSet = self.session._call_method( vim_util, "wait_for_updates_ex", version) if self.state != constants.DRIVER_RUNNING: LOG.error(_LE("Driver is not in running state.")) break except error_util.SocketTimeoutException: # Ignore timeout. LOG.warning(_LW("Ignoring socket timeouts while " "monitoring for vCenter updates.")) continue if updateSet: version = updateSet.version events = self._process_update_set(updateSet) LOG.debug("Sending events : %s.", events) self.dispatch_events(events) except exceptions.VimFaultException as e: # InvalidCollectorVersionFault happens # on session re-connect. # Re-initialize WaitForUpdatesEx. if "InvalidCollectorVersion" in e.fault_list: LOG.debug("InvalidCollectorVersion - " "Re-initializing vCenter updates " "monitoring.") version = "" for cluster_mor in self.clusters_by_id.values(): pfo = self._register_cluster_for_updates( cluster_mor) clu_id = cluster_mor.value self.cluster_id_to_filter[clu_id] = pfo continue LOG.exception(_LE("VimFaultException while processing " "update set %s."), e) except Exception: LOG.exception(_LE("Exception while processing update" " set.")) time.sleep(0) LOG.info(_LI("Stopped monitoring for vCenter updates.")) except Exception: LOG.exception(_LE("Monitoring for vCenter updates failed."))
def _remove_all_flows(self, sec_br, port_id, del_provider_rules=False): """Remove all flows for a port.""" LOG.debug("OVSF Removing flows start for port: %s.", port_id) try: sec_br.delete_flows(cookie="%s/-1" % self.get_cookie(port_id)) if del_provider_rules: sec_br.delete_flows(cookie="%s/-1" % self.get_cookie('pr' + port_id)) port = self.filtered_ports.get(port_id) vlan = self._get_port_vlan(port_id) if 'mac_address' not in port or not vlan: LOG.debug("Invalid mac address or vlan for port " "%s. Returning from _remove_all_flows.", port_id) return sec_br.delete_flows(table=ovsvapp_const.SG_LEARN_TABLE_ID, dl_src=port['mac_address'], vlan_tci="0x%04x/0x0fff" % vlan) sec_br.delete_flows(table=ovsvapp_const.SG_LEARN_TABLE_ID, dl_dst=port['mac_address'], vlan_tci="0x%04x/0x0fff" % vlan) sec_br.delete_flows(table=ovsvapp_const.SG_DEFAULT_TABLE_ID, dl_src=port['mac_address'], vlan_tci="0x%04x/0x0fff" % vlan) if del_provider_rules: sec_br.delete_flows(table=ovsvapp_const.SG_DEFAULT_TABLE_ID, dl_dst=port['mac_address'], vlan_tci="0x%04x/0x0fff" % vlan) sec_br.delete_flows(table=ovsvapp_const.SG_EGRESS_TABLE_ID, dl_src=port['mac_address'], vlan_tci="0x%04x/0x0fff" % vlan) except Exception: LOG.exception(_LE("Unable to remove flows %s."), port['id'])
def update_ovsvapp_mitigated_cluster(self, context, id, ovsvapp_mitigated_cluster): _admin_check(context, 'UPDATE') res_dict = ovsvapp_mitigated_cluster['ovsvapp_mitigated_cluster'] vcenter_id = res_dict['vcenter_id'] cluster_id = res_dict['cluster_id'] update_flags = dict() if 'being_mitigated' in res_dict: update_flags['being_mitigated'] = res_dict['being_mitigated'] if 'threshold_reached' in res_dict: update_flags['threshold_reached'] = res_dict['threshold_reached'] LOG.error(_LE("Updating the mitigation properties with " "vCenter id %s."), vcenter_id) with context.session.begin(subtransactions=True): try: query = context.session.query(models.OVSvAppClusters) cluster_row = (query.filter( models.OVSvAppClusters.vcenter_id == vcenter_id, models.OVSvAppClusters.cluster_id == cluster_id ).with_lockmode('update').one()) cluster_row.update(update_flags) except sa_exc.NoResultFound: _msg = ("No entry found for specified vCenter %(vcenter_id)s" " cluster %(cluster_id)s") % {'vcenter_id': vcenter_id, 'cluster_id': cluster_id} raise exc.InvalidInput(error_message=_msg) return res_dict
def update_port_filter(self, port): """Method to update OVS rules for an existing VM port.""" LOG.debug("OVSF Updating port: %s filter.", port['id']) if port['id'] not in self.filtered_ports: LOG.warning(_LW("Attempted to update port filter which is not " "filtered %s."), port['id']) return port_cookie = self.get_cookie(port['id']) port_provider_cookie = self.get_cookie('pr' + port['id']) try: with self.sg_br.deferred(full_ordered=True, order=( 'del', 'mod', 'add')) as deferred_br: if port['id'] not in self.provider_port_cache: self._remove_all_flows(deferred_br, port['id'], True) self._add_flows(deferred_br, port, port_provider_cookie, True) self.provider_port_cache.add(port['id']) # else: # self._remove_all_flows(deferred_br, port['id']) self._setup_aap_flows(deferred_br, port) self._add_flows(deferred_br, port, port_cookie) if 'security_group_rules_deleted' in port: self._remove_flows(deferred_br, port, port_cookie) self.filtered_ports[port['id']] = self._get_compact_port(port) except Exception: LOG.exception(_LE("Unable to update flows for %s."), port['id'])
def remove_stale_port_flows(self, port_id, mac_address, vlan): """Remove all flows for a port.""" LOG.debug("OVSF Removing flows for stale port: %s.", port_id) with self.sg_br.deferred() as deferred_sec_br: try: deferred_sec_br.delete_flows(cookie="%s/-1" % self.get_cookie(port_id)) deferred_sec_br.delete_flows(cookie="%s/-1" % self.get_cookie('pr' + port_id)) deferred_sec_br.delete_flows( table=ovsvapp_const.SG_LEARN_TABLE_ID, dl_src=mac_address, dl_vlan=vlan) deferred_sec_br.delete_flows( table=ovsvapp_const.SG_LEARN_TABLE_ID, dl_dst=mac_address, dl_vlan=vlan) deferred_sec_br.delete_flows( table=ovsvapp_const.SG_LEARN_TABLE_ID, dl_src=mac_address, dl_vlan=vlan) deferred_sec_br.delete_flows( table=ovsvapp_const.SG_LEARN_TABLE_ID, dl_dst=mac_address, dl_vlan=vlan) deferred_sec_br.delete_flows( table=ovsvapp_const.SG_LEARN_TABLE_ID, dl_src=mac_address, dl_vlan=vlan) except Exception: LOG.exception(_LE("OVSF unable to remove flows for port: " "%s."), port_id)
def create_network_map_from_config(config, pg_cache=False): """Creates physical network to dvs map from config""" connection = None while not connection: try: connection = api.VMwareAPISession( host=config.vsphere_hostname, port=config.host_port, server_username=config.vsphere_login, server_password=config.vsphere_password, api_retry_count=config.api_retry_count, task_poll_interval=config.task_poll_interval, scheme='https', create_session=True, cacert=config.ca_file, insecure=config.insecure, pool_size=config.connections_pool_size) except ConnectionError: LOG.error(_LE("No connection to vSphere. Retry in 10 sec...")) sleep(10) network_map = {} controller_class = DVSControllerWithCache if pg_cache else DVSController for pair in config.network_maps: network, dvs = pair.split(':') network_map[network] = controller_class(dvs, config.cluster_name, connection) return network_map
def _setup_aap_flows(self, sec_br, port): """Method to help setup rules for allowed address pairs.""" vlan = self._get_port_vlan(port['id']) if not vlan: LOG.error(_LE("Missing VLAN information for " "port: %s."), port['id']) return if isinstance(port.get('allowed_address_pairs'), list): for addr_pair in port['allowed_address_pairs']: if netaddr.IPNetwork(addr_pair["ip_address"]).version == 4: ap_proto = "ip" else: ap_proto = "ipv6" sec_br.add_flow(priority=ovsvapp_const.SG_RULES_PRI, table=ovsvapp_const.SG_DEFAULT_TABLE_ID, cookie=self.get_cookie(port['id']), dl_dst=port["mac_address"], in_port=self.patch_ofport, dl_src=addr_pair["mac_address"], dl_vlan=vlan, proto=ap_proto, nw_src=addr_pair["ip_address"], actions="resubmit(,%s),output:%s" % (ovsvapp_const.SG_IP_TABLE_ID, self.phy_ofport))
def clean_port_filters(self, ports, remove_port=False): """Method to remove OVS rules for an existing VM port.""" LOG.debug("OVSF Cleaning filters for %s ports.", len(ports)) if not ports: return with self.sg_br.deferred() as deferred_sec_br: for port_id in ports: try: if not self.filtered_ports.get(port_id): LOG.debug("Attempted to remove port filter " "which is not in filtered %s.", port_id) continue if not remove_port: self._remove_all_flows(deferred_sec_br, port_id) else: self._remove_all_flows(deferred_sec_br, port_id, True) if self.provider_port_cache.__contains__(port_id): self.provider_port_cache.remove(port_id) else: LOG.info(_LI("KeyError:Remove requested for " "port_id not present: %s"), self.provider_port_cache) self.filtered_ports.pop(port_id, None) except Exception: LOG.exception(_LE("Unable to delete flows for" " %s."), port_id)
def delete_network_postcommit(self, context): network = context.current segments = context.network_segments vxlan_segments = [] if segments: for segment in segments: if segment[api.NETWORK_TYPE] in self.supported_network_types: vxlan_segments.append(segment) if not vxlan_segments: return try: stale_entries = ovsvapp_db.get_stale_local_vlans_for_network( network['id']) if stale_entries: for (vcenter, cluster, lvid) in stale_entries: network_info = {'vcenter_id': vcenter, 'cluster_id': cluster, 'lvid': lvid, 'network_id': network['id']} if len(vxlan_segments) == 1: seg_id = vxlan_segments[0][api.SEGMENTATION_ID] net_type = vxlan_segments[0][api.NETWORK_TYPE] network_info.update({'segmentation_id': seg_id, 'network_type': net_type}) LOG.debug("Spawning thread for releasing network " "VNI allocations for %s.", network_info) self.threadpool.spawn_n(self._notify_agent, network_info) LOG.info(_LI("Spawned a thread for releasing network " "vni allocations for network: %s."), network_info) except Exception: LOG.exception(_LE("Failed checking stale local vlan allocations."))
def release_local_vlan(net_info): session = db_api.get_session() with session.begin(subtransactions=True): res_keys = ['vcenter_id', 'cluster_id', 'network_id'] res = dict((k, net_info[k]) for k in res_keys) try: query = session.query(models.ClusterVNIAllocations) allocation = (query.filter( models.ClusterVNIAllocations.vcenter_id == res['vcenter_id'], models.ClusterVNIAllocations.cluster_id == res['cluster_id'], models.ClusterVNIAllocations.network_id == res['network_id'] ).with_lockmode('update').one()) if allocation.network_port_count == 0: allocation.update({'network_id': None, 'allocated': False, 'network_port_count': 0}) LOG.info(_LI("Released lvid for network: %s."), res) else: LOG.info(_LI("Unable to release local vlan for network_id %s " "because ports are available on network."), res['network_id']) except sa_exc.NoResultFound: # Nothing to do, may be another controller cleared the record # We will just log and return. LOG.error(_LE("Network %(network)s is already de-allocated for " "cluster %(cluster)s."), {'network': net_info['network_id'], 'cluster': net_info['cluster_id']})
def update_lvid_assignment(self, rpc_context, **kwargs): net_info = kwargs.get('net_info') if net_info: try: ovsvapp_db.release_local_vlan(net_info) except Exception: LOG.exception(_LE("Failed to release the local vlan")) return
def _add_cluster(self, cluster, vds): try: self.driver.add_cluster(cluster, vds) except Exception: LOG.exception(_LE("Adding cluster %(cluster)s:%(vds)s failed."), {'cluster': cluster, 'vds': vds}) else: self.cluster_switch_mapping[cluster] = vds
def add_cluster(self, cluster_path, switch_name): LOG.info(_LI("Adding cluster_switch_mapping %(path)s:%(switch)s."), {'path': cluster_path, 'switch': switch_name}) if (cluster_path in cache.VCCache.get_cluster_switch_mapping() and cache.VCCache.get_switch_for_cluster_path( cluster_path) == switch_name): LOG.info(_LI("cluster_switch_mapping %(cp)s:%(sw)s already " "present."), {'cp': cluster_path, 'sw': switch_name}) return valid, cluster_mor = self.validate_cluster_switch_mapping(cluster_path, switch_name) if not valid: if cluster_path in cache.VCCache.get_cluster_switch_mapping(): LOG.info(_LI("Removing invalid cluster_switch_mapping: " "%(cp)s:%(sw)s."), {'cp': cluster_path, 'sw': switch_name}) self.remove_cluster(cluster_path, switch_name) return if cluster_path in cache.VCCache.get_cluster_switch_mapping(): cluster_id = self._find_cluster_id_for_path(cluster_path) if cluster_id == cluster_mor.value: LOG.info(_LI("Updating switch name for cluster: " "%(cp)s to %(sw)s."), {'cp': cluster_path, 'sw': switch_name}) cache.VCCache.add_switch_for_cluster_path(cluster_path, switch_name) self.delete_stale_portgroups(switch_name) return else: # Now this path points to a different cluster. LOG.info(_LI("Removing cluster %(cid)s as now path %(cp)s " "points to a different cluster."), {'cid': cluster_id, 'cp': cluster_path}) old_clu_mor = self.clusters_by_id[cluster_id] if cluster_id in self.cluster_id_to_filter: self._unregister_cluster_for_updates(old_clu_mor) del self.cluster_id_to_filter[cluster_id] cache.VCCache.remove_cluster_id(cluster_id) if cluster_id in self.clusters_by_id: del self.clusters_by_id[cluster_id] LOG.info(_LI("Registering cluster for mapping %(cp)s:%(sw)s."), {'cp': cluster_path, 'sw': switch_name}) property_filter_obj = self._register_cluster_for_updates(cluster_mor) # Cache the cluster. cache.VCCache.add_path_for_cluster_id(cluster_mor.value, cluster_path) self.clusters_by_id[cluster_mor.value] = cluster_mor self.cluster_id_to_filter[cluster_mor.value] = property_filter_obj cache.VCCache.add_switch_for_cluster_path(cluster_path, switch_name) try: self.delete_stale_portgroups(switch_name) except Exception: LOG.error(_LE("Exception wile deleting stale port groups: %s"), switch_name) if self.state != constants.DRIVER_RUNNING and self.is_connected(): self.state = constants.DRIVER_READY
def _report_state(self): try: agent_status = self.state_rpc.report_state(self.context, self.agent_state, True) if agent_status == n_const.AGENT_REVIVED: LOG.info(_LI('Agent has just revived. Do a full sync.')) self.agent_state.pop('start_flag', None) except Exception: LOG.exception(_LE("Failed reporting state!"))
def set_vm_poweroff(session, vm_mor): """Power off the VM.""" try: task_ref = session._call_method( session._get_vim(), "PowerOffVM_Task", vm_mor) session.wait_for_task(task_ref) except Exception as e: LOG.exception(_LE("%s"), e) raise Exception(e)
def _try_to_obtain_local_vlan(session, port_info, assign): lvid = None res_keys = ['vcenter_id', 'cluster_id', 'network_id'] res = dict((k, port_info[k]) for k in res_keys) try: allocation = (session.query(models.ClusterVNIAllocations).filter( models.ClusterVNIAllocations.vcenter_id == res['vcenter_id'], models.ClusterVNIAllocations.cluster_id == res['cluster_id'], models.ClusterVNIAllocations.network_id == res['network_id'] ).one()) lvid = allocation.lvid if assign: count = allocation.network_port_count + 1 allocation.update({'network_port_count': count}) LOG.debug("Incremented the allocated port count for network " "%s.", res) except sa_exc.NoResultFound: if not assign: raise Exception() try: allocation = session.query(models.ClusterVNIAllocations).filter( models.ClusterVNIAllocations.vcenter_id == res['vcenter_id'], models.ClusterVNIAllocations.cluster_id == res['cluster_id'], models.ClusterVNIAllocations.allocated == 0 ).first() if allocation: lvid = allocation.lvid allocation.update({'network_id': res['network_id'], 'allocated': True, 'network_port_count': 1}) LOG.info(_LI("Assigned local vlan %(lvid)s for the network " "%(network)s on the cluster %(cluster)s."), {'network': port_info['network_id'], 'cluster': port_info['cluster_id'], 'lvid': lvid}) else: LOG.error(_LE("All available VLANs are used up in the cluster " "%(cluster)s of vCenter %(vcenter)s."), {'cluster': res['cluster_id'], 'vcenter': res['vcenter_id']}) except Exception as e: LOG.exception(_LE("Unable to obtain local vlan id %s."), e) return lvid
def get_local_vlan(port_info, assign=True): lvid = None session = db_api.get_session() res_keys = ['vcenter_id', 'cluster_id', 'network_id'] res = dict((k, port_info[k]) for k in res_keys) with session.begin(subtransactions=True): try: if not assign: lvid = _try_to_obtain_local_vlan(session, port_info, assign) return lvid query = session.query(models.ClusterVNIAllocations) # Lock all the rows in the table corresponding to the vCenter # and cluster. cluster_rows = query.filter( (models.ClusterVNIAllocations.vcenter_id == res['vcenter_id']), (models.ClusterVNIAllocations.cluster_id == res['cluster_id']) ).with_lockmode('update').all() if cluster_rows: lvid = _try_to_obtain_local_vlan(session, port_info, assign) return lvid else: LOG.info(_LI("Local VLAN rows not provisioned for the " "cluster %(cluster)s of vCenter %(vcenter)s. " "Going to provision."), {'cluster': res['cluster_id'], 'vcenter': res['vcenter_id']}) except Exception: LOG.exception(_LE("Error retrieving a local vlan for network " "%(network)s for %(port)s."), {'network': port_info['network_id'], 'port': port_info['port_id']}) return status = _initialize_lvids_for_cluster(res) if status: with session.begin(subtransactions=True): lvid = _try_to_obtain_local_vlan(session, port_info, assign) else: LOG.error(_LE("Local VLAN rows not provisioned for the " "cluster %(cluster)s of vCenter %(vcenter)s."), {'cluster': res['cluster_id'], 'vcenter': res['vcenter_id']}) return lvid
def _check_plugin_ext_support(self, extension): """Helper Method. To check if plugin supports Agent Management Extension. """ try: if self.plugin: return extension in self.plugin.supported_extension_aliases except Exception: LOG.exception(_LE("%s extension is not supported."), extension) return False
def _get_port_db(self, session, port_id, agent_id): try: port_db = (session.query(models_v2.Port). enable_eagerloads(False). filter(models_v2.Port.id.startswith(port_id)). one()) return port_db except sa_exc.NoResultFound: LOG.warning(_LW("Port %(port_id)s requested by agent " "%(agent_id)s not found in database."), {'port_id': port_id, 'agent_id': agent_id}) return None except sa_exc.MultipleResultsFound: LOG.error(_LE("Multiple ports have port_id starting with %s."), port_id) return None except Exception: LOG.exception(_LE("Failed to get details for port %s "), port_id) return None
def validate_cluster_switch_mapping(self, cluster_path, switch): """Validate the cluster_switch_mapping.""" if not cluster_path or not switch: return False, None cluster_mor = resource_util.get_cluster_mor_by_path(self.session, cluster_path) if not cluster_mor: LOG.error(_LE("Invalid cluster: %s."), cluster_path) return False, None else: if not self.is_valid_switch(cluster_mor, switch): LOG.error(_LE("Invalid Switch: %(switch)s for cluster: " "%(path)s."), {'switch': switch, 'path': cluster_path}) return False, None else: LOG.info(_LI("Cluster: %(path)s and switch: %(sw)s are " "validated."), {'path': cluster_path, 'sw': switch}) return True, cluster_mor
def set_host_into_maintenance_mode(session, host_mor): """Put ESX host into maintenance mode.""" try: task_ref = session._call_method( session._get_vim(), "EnterMaintenanceMode_Task", host_mor, timeout=0, evacuatePoweredOffVms=False) session.wait_for_task(task_ref) except Exception as e: LOG.exception(_LE("%s"), e) raise Exception(e)
def main(): signal.signal(signal.SIGTERM, stop) signal.signal(signal.SIGINT, stop) common_config.setup_logging() FORMAT = "%(asctime)-15s %(message)s" logging.basicConfig(format=FORMAT, filename=LOG_FILE_PATH, level=logging.DEBUG) try: LOG.info(_LI("Starting ovsvapp-agent-monitor.")) start_monitor() except Exception as e: LOG.exception(_LE("Failed to start ovsvapp-agent-monitor " "%(err)s."), {"err": e})
def release_cluster_lock(vcenter_id, cluster_id): session = db_api.get_session() with session.begin(subtransactions=True): try: query = session.query(models.OVSvAppClusters) cluster_row = (query.filter( models.OVSvAppClusters.vcenter_id == vcenter_id, models.OVSvAppClusters.cluster_id == cluster_id ).with_lockmode('update').one()) cluster_row.update({'being_mitigated': False, 'threshold_reached': False}) except sa_exc.NoResultFound: LOG.error(_LE("Cannot update the row for cluster %s."), cluster_id)
def set_host_into_shutdown_mode(session, host_mor): """Shutdown the ESX host.""" try: enabled = _check_shutdown_enabled(session, host_mor) if enabled: task_ref = session._call_method( session._get_vim(), "ShutdownHost_Task", host_mor, force=True) session.wait_for_task(task_ref) except Exception as e: LOG.exception(_LE("%s"), e) raise Exception(e)
def main(): # cfg.CONF.register_opts(ip_lib.OPTS) common_config.init(sys.argv[1:]) common_config.setup_logging() utils.log_opt_values(LOG) try: agent_config = create_agent_config_map(cfg.CONF) except ValueError as e: LOG.error(_LE('%s Agent terminated!'), e) sys.exit(1) try: agent = DVSAgent(**agent_config) except RuntimeError as e: LOG.error(_LE("%s Agent terminated!"), e) sys.exit(1) signal.signal(signal.SIGTERM, agent._handle_sigterm) # Start everything. LOG.info(_LI("Agent initialized successfully, now running... ")) agent.daemon_loop()
def set_host_into_shutdown_mode(session, host_mor): """Shutdown the ESX host.""" try: enabled = _check_shutdown_enabled(session, host_mor) if enabled: task_ref = session._call_method(session._get_vim(), "ShutdownHost_Task", host_mor, force=True) session.wait_for_task(task_ref) except Exception as e: LOG.exception(_LE("%s"), e) raise Exception(e)
def _delete_port_postcommit(self, port, segment): if (segment and segment[api.NETWORK_TYPE] in self.supported_network_types): LOG.debug( "OVSvApp Mech driver - delete_port_postcommit for " "port: %s with network_type as %s.", port['id'], segment[api.NETWORK_TYPE]) vni = segment[api.SEGMENTATION_ID] network_type = segment[api.NETWORK_TYPE] host = port[portbindings.HOST_ID] agent = None vcenter = None cluster = None net_info = None agents = self.plugin.get_agents( self.context, filters={ 'agent_type': [ovsvapp_const.AGENT_TYPE_OVSVAPP], 'host': [host] }) if agents: agent = agents[0] vcenter = agent['configurations']['vcenter_id'] cluster = agent['configurations']['cluster_id'] net_info = { 'vcenter_id': vcenter, 'cluster_id': cluster, 'network_id': port['network_id'], 'segmentation_id': vni, 'network_type': network_type, 'host': host } else: LOG.debug("Not a valid ESX port: %s.", port['id']) return try: lvid = ovsvapp_db.check_to_reclaim_local_vlan(net_info) if lvid >= 1: net_info.update({'lvid': lvid}) LOG.debug( "Spawning thread for releasing network " "VNI allocations for %s.", net_info) self.threadpool.spawn_n(self._notify_agent, net_info) LOG.info( _LI("Spawned a thread for releasing network " "vni allocations for network: %s."), net_info) except Exception: LOG.exception( _LE("Failed to check for reclaiming " "local vlan."))
def get_host_mors_for_cluster(session, cluster_mor): """Return host mors from cluster mor.""" try: host_mors = None host_ret = session._call_method(vim_util, "get_dynamic_property", cluster_mor, "ClusterComputeResource", "host") if hasattr(host_ret, "ManagedObjectReference"): host_mors = host_ret.ManagedObjectReference return host_mors except Exception as e: LOG.exception(_LE("Error retrieving cluster information")) raise Exception(e)
def update_devices_up(self, rpc_context, **kwargs): devices_up = [] failed_devices_up = [] devices = kwargs.get('devices') for device in devices: try: self.update_device_up(rpc_context, device=device, **kwargs) LOG.debug("Finished update_device_up for %s port.", device) devices_up.append(device) except Exception: failed_devices_up.append(device) LOG.exception(_LE("Failed to update device %s up."), device) return {'devices_up': devices_up, 'failed_devices_up': failed_devices_up}
def run(): signal.signal(signal.SIGTERM, signal_handler) signal.signal(signal.SIGINT, signal_handler) try: global agent_obj ovsvapp_config.register_options() LOG.info(_LI("Loading agent: %s."), cfg.CONF.OVSVAPP.agent_driver) agent_obj = utils.load_object(cfg.CONF.OVSVAPP.agent_driver, agent.Agent) agent_obj.start() except Exception as e: LOG.exception(_LE("Error in OVSvApp agent service.")) if agent_obj: agent_obj.stop() sys.exit(_("ERROR: %s.") % e)
def is_valid_dvswitch(session, cluster_mor, dvs_name): """Validate a DVS. Check if DVS exists for a cluster specified in conf. Also validate if DVS is attached to all hosts in a cluster. """ dvs_mor = get_dvs_mor_by_name(session, dvs_name) if dvs_mor: dvs_config = session._call_method(vim_util, "get_dynamic_property", dvs_mor, "DistributedVirtualSwitch", "config.host") # Get all the host attached to given VDS dvs_host_members = dvs_config[0] dvs_attached_host_ids = [] for dvs_host_member in dvs_host_members: dvs_attached_host_ids.append(dvs_host_member.config.host.value) # Get all the hosts present in the cluster hosts_in_cluster = resource_util.get_host_mors_for_cluster( session, cluster_mor) # Check if the host on which OVSvApp VM is hosted is a part of DVSwitch if hosts_in_cluster: for host in hosts_in_cluster: hostname = resource_util.get_hostname_for_host_mor( session, host) if hostname == cfg.CONF.VMWARE.esx_hostname: if host.value not in dvs_attached_host_ids: LOG.error( _LE("DVS not present on" "host %s") % host.value) return False return hosts_in_cluster else: LOG.error(_LE("DVS not present %s") % dvs_name) return False
def main(): signal.signal(signal.SIGTERM, stop) signal.signal(signal.SIGINT, stop) common_config.setup_logging() FORMAT = '%(asctime)-15s %(message)s' logging.basicConfig(format=FORMAT, filename=LOG_FILE_PATH, level=logging.DEBUG) try: LOG.info(_LI("Starting ovsvapp-agent-monitor.")) start_monitor() except Exception as e: LOG.exception(_LE("Failed to start ovsvapp-agent-monitor " "%(err)s."), {'err': e})
def initialize_thread(self, notifier): """Initialization of agent monitor thread.""" try: self.notifier = notifier monitor_interval = DEFAULT_MONITOR_INTERVAL api_worker_count = cfg.CONF.api_workers if api_worker_count and api_worker_count > 4: monitor_interval = 4 * api_worker_count monitor_thread = loopingcall.FixedIntervalLoopingCall( self.monitor_agent_state) monitor_thread.start(interval=monitor_interval) LOG.debug("Successfully initialized agent monitor " "thread with loop interval: %s.", monitor_interval) except Exception: LOG.exception(_LE("Cannot initialize agent monitor thread.."))
def set_cluster_threshold(vcenter_id, cluster_id): session = db_api.get_session() with session.begin(subtransactions=True): try: query = session.query(models.OVSvAppClusters) cluster_row = (query.filter( models.OVSvAppClusters.vcenter_id == vcenter_id, models.OVSvAppClusters.cluster_id == cluster_id ).with_lockmode('update').one()) LOG.info(_LI("Cluster row found for %s."), cluster_row) if not cluster_row.threshold_reached: cluster_row.update({'being_mitigated': False, 'threshold_reached': True}) except sa_exc.NoResultFound: LOG.error(_LE("Cluster row not found for %s."), cluster_id)
def release_cluster_lock(vcenter_id, cluster_id): session = db_api.get_session() with session.begin(subtransactions=True): try: query = session.query(models.OVSvAppClusters) cluster_row = (query.filter( models.OVSvAppClusters.vcenter_id == vcenter_id, models.OVSvAppClusters.cluster_id == cluster_id).with_lockmode( 'update').one()) cluster_row.update({ 'being_mitigated': False, 'threshold_reached': False }) except sa_exc.NoResultFound: LOG.error(_LE("Cannot update the row for cluster %s."), cluster_id)
def update_devices_down(self, rpc_context, **kwargs): devices_down = [] failed_devices_down = [] devices = kwargs.get('devices') for device in devices: try: dev = self.update_device_down(rpc_context, device=device, **kwargs) LOG.debug("Finished update_device_down for %s port.", dev['device']) devices_down.append(device) except Exception: failed_devices_down.append(device) LOG.exception(_LE("Failed to update device %s down."), device) return {'devices_down': devices_down, 'failed_devices_down': failed_devices_down}
def _get_port_db(self, session, port_id, agent_id): try: port_db = (session.query(models_v2.Port). enable_eagerloads(False). filter(models_v2.Port.id.startswith(port_id)). one()) return port_db except sa_exc.NoResultFound: LOG.warning(_LW("Port %(port_id)s requested by agent " "%(agent_id)s not found in database."), {'port_id': port_id, 'agent_id': agent_id}) return None except exc.MultipleResultsFound: LOG.error(_LE("Multiple ports have port_id starting with %s."), port_id) return None
def update_cluster_lock(self, rpc_context, **kwargs): vcenter_id = kwargs['vcenter_id'] cluster_id = kwargs['cluster_id'] success = kwargs['success'] if cluster_id and vcenter_id: try: if success: LOG.info(_LI("Releasing the cluster row for " "cluster %(id)s in vCenter %(vc)s."), {'id': cluster_id, 'vc': vcenter_id}) ovsvapp_db.release_cluster_lock(vcenter_id, cluster_id) else: ovsvapp_db.set_cluster_threshold(vcenter_id, cluster_id) except Exception: LOG.exception(_LE("Failed to release/set the cluster lock.")) return
def create_port(self, network, net_id, port, virtual_nic): device_id = port.vm_id cluster_mor, cluster_path, switch = self._find_cluster_switch_for_vm( device_id) host_mors = self.is_valid_switch(cluster_mor, switch) if not host_mors: LOG.error(_LE("Invalid Switch: %(sw)s for cluster: %(cp)s."), {'sw': switch, 'cp': cluster_path}) raise error.VcenterConfigurationError("Invalid Switch: %s for " "cluster: %s." % (switch, cluster_path)) hosts = [] for host_mor in host_mors: hosts.append(model.Host(key=host_mor.value)) vswitch = model.VirtualSwitch(switch, hosts=hosts) self.create_network(network, net_id, vswitch)
def delete_stale_portgroups(self, switch): LOG.info(_LI("Deleting unused portgroups on %s."), switch) port_group_names = self.get_unused_portgroups(switch) uuid_regex_vlan = ("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}" "-[0-9a-f]{4}-[0-9a-f]{12}") uuid_regex_vxlan = ("[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}" "-[0-9a-f]{4}-[0-9a-f]{12}-domain-c[0-9]*") for port_group in port_group_names: if (re.match(uuid_regex_vlan, port_group, re.IGNORECASE) or re.match(uuid_regex_vxlan, port_group, re.IGNORECASE)): try: self.delete_portgroup(switch, port_group) except Exception as e: LOG.exception(_LE("Failed to delete portgroup %(pg)s from " "dvs %(dvs)s. Cause : %(err)s"), {'pg': port_group, 'dvs': switch, 'err': e})
def _check_datapath_health(self, monitoring_ip): if monitoring_ip: url = 'http://%s:8080/status.json' % monitoring_ip try: response = requests.get(url, timeout=5) if response: LOG.debug("HTTP response from OVSvApp agent@ %(ip)s is " "%(res)s", {'res': response, 'ip': monitoring_ip}) status = response.json() LOG.info(_LI("ovs status is %(st)s from agent@ %(ip)s"), {'st': status, 'ip': monitoring_ip}) return (status.get('ovs') == "OK") except Exception: LOG.exception(_LE("Failed to get OVS status. Will continue " "with mitigation.")) return False
def prepare_port_filter(self, port): """Method to add OVS rules for a newly created VM port.""" LOG.debug("OVSF Preparing port %s filter.", port['id']) port_cookie = self.get_cookie(port['id']) port_provider_cookie = self.get_cookie('pr' + port['id']) try: with self.sg_br.deferred(full_ordered=True, order=( 'del', 'mod', 'add')) as deferred_br: self._setup_aap_flows(deferred_br, port) if port['id'] not in self.provider_port_cache: # Using provider string as cookie for normal rules. self._add_flows(deferred_br, port, port_provider_cookie, True) self.provider_port_cache.add(port['id']) # Using port id as cookie for normal rules. self._add_flows(deferred_br, port, port_cookie) self.filtered_ports[port['id']] = self._get_compact_port(port) except Exception: LOG.exception(_LE("Unable to add flows for %s."), port['id'])
def reset_cluster_threshold(vcenter_id, cluster_id): session = db_api.get_session() with session.begin(subtransactions=True): try: query = session.query(models.OVSvAppClusters) cluster_row = (query.filter( models.OVSvAppClusters.vcenter_id == vcenter_id, models.OVSvAppClusters.cluster_id == cluster_id ).with_lockmode('update').one()) if cluster_row.threshold_reached: cluster_row.update({'being_mitigated': False, 'threshold_reached': False}) except sa_exc.NoResultFound: # First agent in this cluster LOG.error(_LE("Cluster row not found for %s."), cluster_id) cluster_row = {'vcenter_id': vcenter_id, 'cluster_id': cluster_id} session.execute(models.OVSvAppClusters.__table__.insert(), cluster_row)
def create_port_group(session, dvs_name, pg_name, vlan_id): """Creates a Portgroup on DVS with a vlan id.""" port_group_mor = get_portgroup_mor_by_name(session, dvs_name, pg_name) if port_group_mor: port_group_config = session._call_method( vim_util, "get_dynamic_property", port_group_mor, "DistributedVirtualPortgroup", "config") if vlan_id == port_group_config.defaultPortConfig.vlan.vlanId: LOG.debug("Portgroup %(pg)s with vlan id %(vid)s already exists", {'pg': pg_name, 'vid': vlan_id}) return else: LOG.info(_LI("Portgroup %(pg)s already exists " "but with vlan id %(vid)s"), {'pg': pg_name, 'vid': port_group_config.defaultPortConfig.vlan.vlanId}) raise error_util.RunTimeError("Inconsistent vlan id for portgroup" " %s", pg_name) else: client_factory = session._get_vim().client.factory add_prt_grp_spec = _get_add_vswitch_port_group_spec( client_factory, pg_name, vlan_id) blocked = client_factory.create('ns0:BoolPolicy') blocked.value = False blocked.inherited = False add_prt_grp_spec.defaultPortConfig.blocked = blocked dvs_mor = get_dvs_mor_by_name(session, dvs_name) try: task_ref = session._call_method( session._get_vim(), "AddDVPortgroup_Task", dvs_mor, spec=add_prt_grp_spec) session.wait_for_task(task_ref) LOG.info(_LI("Successfully created portgroup " "%(pg)s with vlan id %(vid)s"), {'pg': pg_name, 'vid': vlan_id}) except Exception as e: LOG.exception(_LE("Failed to create portgroup %(pg)s with " "vlan id %(vid)s on vCenter. Cause : %(err)s"), {'pg': pg_name, 'vid': vlan_id, 'err': e}) raise error_util.RunTimeError("Failed to create portgroup %s " "with vlan id %s on vCenter.Cause" " : %s" % (pg_name, vlan_id, e))
def create_network_map_from_config(config, pg_cache=False): """Creates physical network to dvs map from config""" connection = None while not connection: try: connection = api.VMwareAPISession( config.vsphere_hostname, config.vsphere_login, config.vsphere_password, config.api_retry_count, config.task_poll_interval, pool_size=config.connections_pool_size) except ConnectionError: LOG.error(_LE("No connection to vSphere. Retry in 10 sec...")) sleep(10) network_map = {} controller_class = DVSControllerWithCache if pg_cache else DVSController for pair in config.network_maps: network, dvs = pair.split(':') network_map[network] = controller_class(dvs, connection) return network_map
def clean_port_filters(self, ports, remove_port=False): """Method to remove OVS rules for an existing VM port.""" LOG.debug("OVSF Cleaning filters for %s ports.", len(ports)) if not ports: return with self.sg_br.deferred() as deferred_sec_br: for port_id in ports: try: if not self.filtered_ports.get(port_id): LOG.debug("Attempted to remove port filter " "which is not in filtered %s.", port_id) continue if not remove_port: self._remove_flows(deferred_sec_br, port_id) else: self._remove_flows(deferred_sec_br, port_id, True) self.provider_port_cache.remove(port_id) self.filtered_ports.pop(port_id, None) except Exception: LOG.exception(_LE("Unable to delete flows for" " %s."), port_id)
def delete_port_group(session, dvs_name, pg_name): """Deletes a port group from DVS.""" port_group_mor = get_portgroup_mor_by_name(session, dvs_name, pg_name) if port_group_mor: try: destroy_task = session._call_method(session._get_vim(), "Destroy_Task", port_group_mor) session.wait_for_task(destroy_task) LOG.info(_LI("Successfully deleted portgroup %(pg)s from " "dvs %(dvs)s"), {'pg': pg_name, 'dvs': dvs_name}) except Exception as e: LOG.exception(_LE("Failed to delete portgroup %(pg)s from " "dvs %(dvs)s .Cause : %(err)s"), {'pg': pg_name, 'dvs': dvs_name, 'err': e}) raise error_util.RunTimeError("Failed to delete portgroup %s " "on dvs %s on vCenter.Cause" " : %s" % (pg_name, dvs_name, e)) else: LOG.info(_LI("portgroup %(pg)s not present on dvs %(dvs)s"), {'pg': pg_name, 'dvs': dvs_name})
def process_ovsvapp_agent(self, agent): """Inform the OVSvApp agent. To set the other host into maintenance or shutdown mode. """ try: LOG.info( _LI("Processing the OVSvApp agent to set the other host " "into maintenance or shutdown mode %s."), agent) device_data = {} agent_config = agent['configurations'] source_host = agent_config.get('esx_host_name') chosen_agent = self._get_eligible_ovsvapp_agent( agent_config['cluster_id'], agent_config['vcenter_id']) if chosen_agent and (chosen_agent['id'] in self.active_agents): cluster_id = chosen_agent['configurations'].get('cluster_id') device_data['assigned_agent_host'] = chosen_agent['host'] device_data['esx_host_name'] = source_host device_data['ovsvapp_agent'] = '-'.join( ['ovsvapp', source_host.replace('.', '-')]) LOG.info( _LI("Invoking device_update RPC with" "target host %s."), chosen_agent['host']) self.notifier.device_update(self.context, device_data, cluster_id) else: ovsvapp_db.set_cluster_threshold(agent_config['vcenter_id'], agent_config['cluster_id']) LOG.info( _LI("No eligible OVSvApp agents found for " "processing. Reverting DB status for the agent.")) self.update_agent_state(agent['id'], True) except Exception: agent_config = agent['configurations'] ovsvapp_db.set_cluster_threshold(agent_config['vcenter_id'], agent_config['cluster_id']) LOG.exception( _LE("Unable to inform the OVSvApp agent for " "Host - maintenance or shutdown operation."))
def update_ports_binding(self, rpc_context, **kwargs): agent_id = kwargs.get('agent_id') ports = kwargs.get('ports') host = kwargs.get('host') updated_ports = set() for port_id in ports: # Update not required if the host hasn't changed. if self.plugin.port_bound_to_host(rpc_context, port_id, host): updated_ports.add(port_id) continue LOG.debug("Port %(port_id)s update_port invoked by agent " "%(agent_id)s for host %(host)s.", {'port_id': port_id, 'agent_id': agent_id, 'host': host}) port = {'port': {portbindings.HOST_ID: host}} try: updated_port = self.plugin.update_port(rpc_context, port_id, port) updated_ports.add(updated_port['id']) except Exception: LOG.exception(_LE("Failed to update binding for port %s "), port_id) return updated_ports
def _has_remote_rules(self, sgroups, port_id, sg_rules): try: for group in sgroups: for rule in sg_rules: if OVSVAPP_ID in rule['id']: remote_g = rule.get('remote_group_id') if remote_g is not None and remote_g != group: return True for group in sgroups: remote_rules = self.sgid_remote_rules_dict.get(group) # case when incoming dict has no remote rules but cache does(i.e rules removed) if remote_rules is not None and \ len(remote_rules) > 0: for rule in remote_rules: remote_g = rule.get('remote_group_id') if remote_g is not None and remote_g != group: return True except Exception as e: LOG.error(_LE("Exception in _has_remote_rules: %s"), e) # In case of exceptions better to clear and reapply rules to the # security bridge so return True. return True return False
def delete_network_postcommit(self, context): network = context.current segments = context.network_segments vxlan_segments = [] if segments: for segment in segments: if segment[api.NETWORK_TYPE] in self.supported_network_types: vxlan_segments.append(segment) if not vxlan_segments: return try: stale_entries = ovsvapp_db.get_stale_local_vlans_for_network( network['id']) if stale_entries: for (vcenter, cluster, lvid) in stale_entries: network_info = { 'vcenter_id': vcenter, 'cluster_id': cluster, 'lvid': lvid, 'network_id': network['id'] } if len(vxlan_segments) == 1: seg_id = vxlan_segments[0][api.SEGMENTATION_ID] net_type = vxlan_segments[0][api.NETWORK_TYPE] network_info.update({ 'segmentation_id': seg_id, 'network_type': net_type }) LOG.debug( "Spawning thread for releasing network " "VNI allocations for %s.", network_info) self.threadpool.spawn_n(self._notify_agent, network_info) LOG.info( _LI("Spawned a thread for releasing network " "vni allocations for network: %s."), network_info) except Exception: LOG.exception(_LE("Failed checking stale local vlan allocations."))
def _initialize_lvids_for_cluster(port_info): vcenter = port_info['vcenter_id'] cluster = port_info['cluster_id'] session = db_api.get_session() with session.begin(subtransactions=True): try: (session.query(models.ClusterVNIAllocations). with_lockmode('update')).all() query = session.query(models.ClusterVNIAllocations) existing_allocations = query.filter( models.ClusterVNIAllocations.vcenter_id == vcenter, models.ClusterVNIAllocations.cluster_id == cluster ).all() if not existing_allocations: _generate_vcenter_cluster_allocations( session, vcenter, cluster) return True except Exception: LOG.exception(_LE("Exception while initializing VNI " "allocations for clusters %(cluster)s of " "vCenter %(vcenter)s."), {'cluster': cluster, 'vcenter': vcenter}) return False
def update_port_filter(self, port): """Method to update OVS rules for an existing VM port.""" LOG.debug("OVSF Updating port: %s filter.", port['id']) if port['id'] not in self.filtered_ports: LOG.warning(_LW("Attempted to update port filter which is not " "filtered %s."), port['id']) return port_cookie = self.get_cookie(port['id']) port_provider_cookie = self.get_cookie('pr' + port['id']) try: with self.sg_br.deferred(full_ordered=True, order=( 'del', 'mod', 'add')) as deferred_br: if port['id'] not in self.provider_port_cache: self._remove_flows(deferred_br, port['id'], True) self._add_flows(deferred_br, port, port_provider_cookie, True) self.provider_port_cache.add(port['id']) else: self._remove_flows(deferred_br, port['id']) self._setup_aap_flows(deferred_br, port) self._add_flows(deferred_br, port, port_cookie) self.filtered_ports[port['id']] = self._get_compact_port(port) except Exception: LOG.exception(_LE("Unable to update flows for %s."), port['id'])
def start_monitor(): '''Method to start monitoring the required processes.''' try: current_dir = os.path.dirname(os.path.realpath(__file__)) ovs_monitor_path = str(current_dir) + '/ovsvapp-agent-monitor.sh' os.chmod(ovs_monitor_path, 0o755) LOG.info(_LI("Loading OVS_MONITOR: %s"), ovs_monitor_path) while True: subprocess.call(ovs_monitor_path) f = open(LOG_FILE_PATH) for line in f: pass status = line sf = open(JSON_FILE_PATH, 'w') if 'broken' in status or 'pending' in status: sf.write('{"ovs": "BAD"}') else: sf.write('{"ovs": "OK"}') sf.close() f.close() time.sleep(2) except Exception as e: LOG.exception(_LE("Error in start_monitor method %(err)s."), {'err': e})