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."))
Example #2
0
    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
Example #3
0
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
Example #5
0
 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
Example #7
0
 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)
Example #12
0
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."))
Example #16
0
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']})
Example #17
0
 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
Example #18
0
 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
Example #19
0
 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!"))
Example #21
0
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)
Example #22
0
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
Example #23
0
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
Example #25
0
 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
Example #26
0
 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
Example #27
0
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)
Example #28
0
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})
Example #29
0
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)
Example #30
0
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)
Example #31
0
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}
Example #36
0
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)
Example #37
0
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
Example #38
0
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.."))
Example #40
0
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)
Example #41
0
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
Example #45
0
 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)
Example #46
0
 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'])
Example #49
0
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)
Example #50
0
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))
Example #51
0
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)
Example #53
0
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."))
Example #58
0
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'])
Example #60
0
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})