def _delete_port_group(self, pg_ref, name, ignore_in_use=False): while True: try: pg_delete_task = pg_ref.Destroy_Task() wait_for_task(pg_delete_task, si=self.connection) LOG.info(_LI('Network %(name)s deleted.') % {'name': name}) self._port_groups_by_name.pop(name, None) return True except vim.fault.ResourceInUse as e: if ignore_in_use: LOG.info( _LW("Could not delete port-group %(name)s. Reason: %(message)s" ) % { 'name': name, 'message': e.message }) return False else: raise exceptions.wrap_wmvare_vim_exception(e) except vim.fault.VimFault as e: if dvs_const.DELETED_TEXT in e.message: return True else: raise exceptions.wrap_wmvare_vim_exception(e) return False
def update_network(self, network, original=None): original_name = self._get_net_name(self.dvs_name, original) if original else None current_name = self._get_net_name(self.dvs_name, network) blocked = not network['admin_state_up'] try: pg_ref = self._get_pg_by_name(original_name or current_name) pg_config_info = self._get_config_by_ref(pg_ref) if (pg_config_info.defaultPortConfig.blocked.value != blocked or (original_name and original_name != current_name)): # we upgrade only defaultPortConfig, because it is inherited # by all ports in PortGroup, unless they are explicitly # overwritten on specific port. pg_spec = self._build_pg_update_spec( pg_config_info.configVersion, blocked=blocked) pg_spec.name = current_name pg_update_task = pg_ref.ReconfigureDVPortgroup_Task( spec=pg_spec) wait_for_task(pg_update_task, si=self.connection) LOG.info(_LI('Network %(name)s updated'), {'name': current_name}) except vim.fault.VimFault as e: raise exceptions.wrap_wmvare_vim_exception(e)
def _increase_ports_on_portgroup(self, port_group): pg_info = self._get_config_by_ref(port_group) # TODO(ekosareva): need to have max size of ports number ports_number = max(INIT_PG_PORTS_COUNT, pg_info.numPorts * 2) pg_spec = self._build_pg_update_spec(pg_info.configVersion, ports_number=ports_number) pg_update_task = port_group.ReconfigureDVPortgroup_Task(spec=pg_spec) wait_for_task(pg_update_task, si=self.connection)
def update_mtu(self, max_mtu): if max_mtu == self._max_mtu: return try: pg_config_info = self._build_dvswitch_update_spec() pg_config_info.maxMtu = max_mtu pg_config_info.configVersion = self._config_version pg_update_task = self._dvs.ReconfigureDvs_Task(spec=pg_config_info) wait_for_task(pg_update_task, si=self.connection) self.max_mtu = max_mtu except vim.fault.VimFault as e: raise exceptions.wrap_wmvare_vim_exception(e)
def release_port(self, port): try: port_info = self.get_port_info(port) update_spec = builder.port_config_spec( port_info.config.configVersion, name='') update_spec.key = port_info.key # setting = builder.port_setting() # setting.filterPolicy = builder.filter_policy([]) # update_spec.setting = setting update_spec.operation = 'remove' update_task = self.submit_update_ports([update_spec]) wait_for_task(update_task, si=self.connection) self.remove_block(port_info.key) except exceptions.PortNotFound: LOG.debug("Port %s was not found. Nothing to delete." % port['id']) except exceptions.ResourceInUse: LOG.debug("Port %s in use. Nothing to delete." % port['id']) except vim.fault.VimFault as e: raise exceptions.wrap_wmvare_vim_exception(e)
def update_ports(self, update_specs): if not update_specs: return LOG.debug("Update Ports: {}".format( sorted([spec.name for spec in update_specs]))) update_task = self.submit_update_ports(update_specs) try: return wait_for_task( update_task, si=self.connection ) # -> May raise DvsOperationBulkFault, when host is down except vim.fault.NotFound: return
def book_port(self, network, port_name, segment, net_name=None): try: if not net_name: net_name = self._get_net_name(self.dvs_name, network) pg = self._get_or_create_pg(net_name, network, segment) for iter in range(0, 4): try: port_info = self._lookup_unbound_port_or_increase_pg(pg) port_settings = builder.port_setting() port_settings.blocked = builder.blocked(False) update_spec = builder.port_config_spec( port_info.config.configVersion, port_settings, name=port_name) update_spec.key = port_info.key update_task = self.submit_update_ports([update_spec]) wait_for_task(update_task, si=self.connection) return port_info.key except vim.fault.VimFault as e: sleep(0.1) raise exceptions.wrap_wmvare_vim_exception(e) except vim.fault.VimFault as e: raise exceptions.wrap_wmvare_vim_exception(e)
def create_network(self, network, segment): name = self._get_net_name(self.dvs_name, network) blocked = not network['admin_state_up'] try: pg_spec = self._build_pg_create_spec(name, segment['segmentation_id'], blocked) pg_create_task = self._dvs.CreateDVPortgroup_Task(spec=pg_spec) result = wait_for_task(pg_create_task, si=self.connection) except vim.fault.VimFault as e: raise exceptions.wrap_wmvare_vim_exception(e) else: pg = result.result self._port_groups_by_name[name] = pg LOG.info(_LI('Network %(name)s created \n%(pg_ref)s'), { 'name': name, 'pg_ref': pg }) return pg
def update_dvportgroup(self, pg, port_config=None, name=None, retries=3): for ntry in six.moves.xrange(retries): pg_ref = pg.ref if not pg.name: LOG.debug("Missing name for %s", pg_ref.value) if pg.async_fetch: LOG.warning("Blocking on port-group %s", pg.name) pg.async_fetch.wait() default_port_config = pg.default_port_config if (name == pg.name or not name) \ and (default_port_config or not port_config) \ and not _config_differs(default_port_config, port_config): LOG.debug("Skipping update: No changes to known config on %s", pg.name) return try: pg_spec = builder.pg_config(port_config) pg_spec.configVersion = str(pg.config_version) if name and name != pg.name: pg_spec.name = name now = timeutils.utcnow() if not CONF.AGENT.dry_run: pg_update_task = pg_ref.ReconfigureDVPortgroup_Task( spec=pg_spec) else: LOG.debug(pg_spec) pg.config_version = str(int(pg.config_version) + 1) pg.default_port_config = port_config if not CONF.AGENT.dry_run: wait_for_task(pg_update_task, si=self.connection) delta = timeutils.utcnow() - now stats.timing('networking_dvs.dvportgroup.updated', delta) LOG.debug("Updating portgroup {} took {} seconds.".format( pg_ref.value, delta.seconds)) return except vim.fault.DvsOperationBulkFault as e: self.rectify_for_fault(e) except vim.fault.VimFault as e: if dvs_const.CONCURRENT_MODIFICATION_TEXT in str(e) \ and ntry != retries - 1: LOG.debug("Concurrent modification detected, will retry.") ## TODO A proper read-out of the current config props = util.get_object_properties_dict( self.connection, pg_ref, ["config.configVersion", "config.defaultPortConfig"]) pg.config_version = props["config.configVersion"] pg.default_port_config = props["config.defaultPortConfig"] continue raise exceptions.wrap_wmvare_vim_exception(e)
def create_dvportgroup(self, sg_set, port_config, update=True): """ Creates an automatically-named dvportgroup on the dvswitch with the specified sg rules and marks it as such through the description Returns a dictionary with "key" and "ref" keys. Note, that while a portgroup's key and managed object id have the same string format and appear identical under normal use it is possible to have them diverge by the use of the backup and restore feature of the dvs for example. As such, one should not rely on any equivalence between them. """ # There is a create_network method a few lines above # which seems to be part of a non-used call path # starting from the dvs_agent_rpc_api. TODO - remove it dvpg_name = dvportgroup_name(self.uuid, sg_set) portgroups = self._get_portgroups() if dvpg_name in portgroups: existing = portgroups[dvpg_name] if update: self.update_dvportgroup(existing, port_config) return existing if CONF.AGENT.dry_run: return try: pg_spec = builder.pg_config(port_config) pg_spec.name = dvpg_name pg_spec.numPorts = 0 pg_spec.type = 'earlyBinding' pg_spec.description = sg_set now = timeutils.utcnow() pg_create_task = self._dvs.CreateDVPortgroup_Task(spec=pg_spec) result = wait_for_task(pg_create_task, si=self.connection) pg_ref = result.result props = util.get_object_properties_dict(self.connection, pg_ref, ["key"]) delta = timeutils.utcnow() - now stats.timing('networking_dvs.dvportgroup.created', delta) LOG.debug("Creating portgroup {} took {} seconds.".format( pg_ref.value, delta.seconds)) pg = PortGroup(key=props["key"], ref=pg_ref, name=dvpg_name, config_version=0, description=sg_set, default_port_config=port_config) self._port_groups_by_name[dvpg_name] = pg return pg except vim.fault.DuplicateName as dn: LOG.info( "Untagged portgroup with matching name {} found, will update and use." .format(dvpg_name)) if dvpg_name not in portgroups: portgroups = self._get_portgroups(refresh=True) if dvpg_name not in portgroups: LOG.error( "Portgroup with matching name {} not found while expected." .format(dvpg_name)) return existing = portgroups[dvpg_name] if update: self.update_dvportgroup(existing, port_config) return existing except vim.fault.VimFault as e: raise exceptions.wrap_wmvare_vim_exception(e)