This is an automated email from the ASF dual-hosted git repository. pearl11594 pushed a commit to branch nsx-integration in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit bedfe44482f06e9a0a53df3e690ae9b019884ab6 Author: Pearl Dsilva <[email protected]> AuthorDate: Mon Aug 28 15:27:32 2023 -0400 Add support to create and delete nsx tier-1 gateway --- .../com/cloud/network/element/NsxProviderVO.java | 14 ++- .../resources/META-INF/db/schema-41810to41900.sql | 1 + .../agent/api/DeleteNsxTier1GatewayCommand.java | 8 ++ .../api/response/NsxControllerResponse.java | 6 +- .../apache/cloudstack/resource/NsxResource.java | 73 ++++++++++++-- .../cloudstack/service/NsxControllerUtils.java | 4 +- .../org/apache/cloudstack/service/NsxElement.java | 105 +++++++++++++++++++-- .../cloudstack/service/NsxProviderServiceImpl.java | 22 +++-- .../apache/cloudstack/service/NsxServiceImpl.java | 8 ++ ui/src/views/infra/network/ServiceProvidersTab.vue | 28 ++++++ 10 files changed, 237 insertions(+), 32 deletions(-) diff --git a/engine/schema/src/main/java/com/cloud/network/element/NsxProviderVO.java b/engine/schema/src/main/java/com/cloud/network/element/NsxProviderVO.java index 96eaa0ad3f6..f86b3401cdd 100644 --- a/engine/schema/src/main/java/com/cloud/network/element/NsxProviderVO.java +++ b/engine/schema/src/main/java/com/cloud/network/element/NsxProviderVO.java @@ -39,6 +39,9 @@ public class NsxProviderVO implements NsxProvider { @Column(name = "zone_id") private long zoneId; + @Column(name = "host_id") + private long hostId; + @Column(name = "uuid") private String uuid; @@ -68,8 +71,9 @@ public class NsxProviderVO implements NsxProvider { this.uuid = UUID.randomUUID().toString(); } - public NsxProviderVO( long zoneId,String providerName, String hostname, String username, String password, String tier0Gateway, String edgeCluster) { + public NsxProviderVO( long zoneId, long hostId, String providerName, String hostname, String username, String password, String tier0Gateway, String edgeCluster) { this.zoneId = zoneId; + this.hostId = hostId; this.uuid = UUID.randomUUID().toString(); this.providerName = providerName; this.hostname = hostname; @@ -97,6 +101,14 @@ public class NsxProviderVO implements NsxProvider { this.zoneId = zoneId; } + public long getHostId() { + return hostId; + } + + public void setHostId(long hostId) { + this.hostId = hostId; + } + @Override public String getUuid() { return uuid; diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41810to41900.sql b/engine/schema/src/main/resources/META-INF/db/schema-41810to41900.sql index db744dca0d8..ce63fe81345 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41810to41900.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41810to41900.sql @@ -185,6 +185,7 @@ CREATE TABLE `cloud`.`nsx_providers` ( `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', `uuid` varchar(40), `zone_id` bigint unsigned NOT NULL COMMENT 'Zone ID', + `host_id` bigint unsigned NOT NULL COMMENT 'Host ID', `provider_name` varchar(40), `hostname` varchar(255) NOT NULL, `port` varchar(255), diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxTier1GatewayCommand.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxTier1GatewayCommand.java new file mode 100644 index 00000000000..7660cd79a44 --- /dev/null +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/agent/api/DeleteNsxTier1GatewayCommand.java @@ -0,0 +1,8 @@ +package org.apache.cloudstack.agent.api; + +public class DeleteNsxTier1GatewayCommand extends CreateNsxTier1GatewayCommand { + + public DeleteNsxTier1GatewayCommand(String zoneName, Long zoneId, String accountName, Long accountId, String vpcName) { + super(zoneName, zoneId, accountName, accountId, vpcName); + } +} diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/api/response/NsxControllerResponse.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/api/response/NsxControllerResponse.java index 8b574c3d970..811b7f1d250 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/api/response/NsxControllerResponse.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/api/response/NsxControllerResponse.java @@ -34,7 +34,7 @@ public class NsxControllerResponse extends BaseResponse { @SerializedName(ApiConstants.ZONE_ID) @Param(description = "Zone ID to which the NSX controller is associated with") - private long zoneId; + private String zoneId; @SerializedName(ApiConstants.ZONE_NAME) @Param(description = "Zone name to which the NSX controller is associated with") @@ -76,11 +76,11 @@ public class NsxControllerResponse extends BaseResponse { this.name = name; } - public long getZoneId() { + public String getZoneId() { return zoneId; } - public void setZoneId(long zoneId) { + public void setZoneId(String zoneId) { this.zoneId = zoneId; } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java index 02c1e86b8a8..44cdb211902 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/resource/NsxResource.java @@ -27,25 +27,32 @@ import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.ReadyAnswer; import com.cloud.agent.api.Answer; import com.cloud.agent.api.PingCommand; +import com.cloud.exception.InvalidParameterValueException; import com.cloud.host.Host; import com.cloud.resource.ServerResource; import com.cloud.utils.exception.CloudRuntimeException; import com.vmware.nsx_policy.infra.Tier1s; +import com.vmware.nsx_policy.infra.tier_0s.LocaleServices; import com.vmware.nsx_policy.model.ApiError; +import com.vmware.nsx_policy.model.ChildLocaleServices; +import com.vmware.nsx_policy.model.LocaleServicesListResult; import com.vmware.nsx_policy.model.Tier1; +import com.vmware.vapi.bindings.Service; import com.vmware.vapi.std.errors.Error; import org.apache.cloudstack.NsxAnswer; import org.apache.cloudstack.StartupNsxCommand; import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand; +import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand; import org.apache.cloudstack.service.NsxApi; import org.apache.log4j.Logger; import javax.naming.ConfigurationException; +import java.util.List; import java.util.Map; public class NsxResource implements ServerResource { - private static final Logger s_logger = Logger.getLogger(NsxResource.class); + private static final Logger LOGGER = Logger.getLogger(NsxResource.class); private static final String TIER_0_GATEWAY_PATH_PREFIX = "/infra/tier-0s/"; private static final String TIER_1_RESOURCE_TYPE = "Tier1"; // private static final String ROUTING = "ROUTING"; @@ -88,7 +95,9 @@ public class NsxResource implements ServerResource { public Answer executeRequest(Command cmd) { if (cmd instanceof ReadyCommand) { return executeRequest((ReadyCommand) cmd); - } if (cmd instanceof CreateNsxTier1GatewayCommand) { + } else if (cmd instanceof DeleteNsxTier1GatewayCommand) { + return executeRequest((DeleteNsxTier1GatewayCommand) cmd); + } else if (cmd instanceof CreateNsxTier1GatewayCommand) { return executeRequest((CreateNsxTier1GatewayCommand) cmd); } else { return Answer.createUnsupportedCommandAnswer(cmd); @@ -176,6 +185,11 @@ public class NsxResource implements ServerResource { throw new ConfigurationException("Unable to find zone"); } + tier0Gateway = (String) params.get("tier0Gateway"); + if (tier0Gateway == null) { + throw new ConfigurationException("Missing NSX tier0 gateway"); + } + edgeCluster = (String) params.get("edgeCluster"); if (edgeCluster == null) { throw new ConfigurationException("Missing NSX edgeCluster"); @@ -190,18 +204,35 @@ public class NsxResource implements ServerResource { return new ReadyAnswer(cmd); } + private Service getService(Class serviceClass) { + return nsxApi.getApiClient().createStub(serviceClass); + } + private Answer executeRequest(CreateNsxTier1GatewayCommand cmd) { - String tier0GatewayPath = TIER_0_GATEWAY_PATH_PREFIX + tier0Gateway; String name = getVpcName(cmd); - Tier1s tier1service = nsxApi.getApiClient().createStub(Tier1s.class); - Tier1 tier1 = new Tier1.Builder() + Tier1 tier1 = getTier1Gateway(name); + if (tier1 != null) { + throw new InvalidParameterValueException(String.format("VPC network with name %s exists in NSX zone: %s and account %s", name, cmd.getZoneName(), cmd.getAccountName())); + } + List<com.vmware.nsx_policy.model.LocaleServices> localeServices = getTier0LocalServices(tier0Gateway); + String tier0GatewayPath = TIER_0_GATEWAY_PATH_PREFIX + tier0Gateway; + + Tier1s tier1service = (Tier1s) getService(Tier1s.class); + tier1 = new Tier1.Builder() .setTier0Path(tier0GatewayPath) .setResourceType(TIER_1_RESOURCE_TYPE) .setPoolAllocation(ROUTING.name()) .setHaMode(ACTIVE_STANDBY.name()) .setId(name) .setDisplayName(name) - .build(); + .setChildren( + List.of(new ChildLocaleServices.Builder("ChildLocaleServices") + .setLocaleServices( + new com.vmware.nsx_policy.model.LocaleServices.Builder() + .setEdgeClusterPath(localeServices.get(0).getEdgeClusterPath()) + .setResourceType("LocaleServices") + .build() + ).build())).build(); try { tier1service.patch(name, tier1); } catch (Error error) { @@ -211,6 +242,36 @@ public class NsxResource implements ServerResource { return new NsxAnswer(cmd, true, ""); } + private Answer executeRequest(DeleteNsxTier1GatewayCommand cmd) { + try { + Tier1s tier1service = (Tier1s) getService(Tier1s.class); + tier1service.delete(cmd.getVpcName()); + } catch (Exception e) { + return new Answer(cmd, new CloudRuntimeException(e.getMessage())); + } + return new Answer(cmd, true, null); + } + + private List<com.vmware.nsx_policy.model.LocaleServices> getTier0LocalServices(String tier0Gateway) { + try { + LocaleServices tier0LocaleServices = (LocaleServices) getService(LocaleServices.class); + LocaleServicesListResult result =tier0LocaleServices.list(tier0Gateway, null, false, null, null, null, null); + return result.getResults(); + } catch (Exception e) { + throw new CloudRuntimeException(String.format("Failed to fetch locale services for tier gateway %s due to %s", tier0Gateway, e.getMessage())); + } + } + + private Tier1 getTier1Gateway(String tier1GatewayId) { + try { + Tier1s tier1service = (Tier1s) getService(Tier1s.class); + return tier1service.get(tier1GatewayId); + } catch (Exception e) { + LOGGER.debug(String.format("NSX Tier-1 gateway with name: %s not found", tier1GatewayId)); + } + return null; + } + private String getVpcName(CreateNsxTier1GatewayCommand cmd) { return cmd.getZoneName() + "-" + cmd.getAccountName() + "-" + cmd.getVpcName(); } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxControllerUtils.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxControllerUtils.java index 24261d0f9e3..944d33e3c42 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxControllerUtils.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxControllerUtils.java @@ -19,7 +19,6 @@ package org.apache.cloudstack.service; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.exception.InvalidParameterValueException; -import com.cloud.hypervisor.Hypervisor; import com.cloud.network.dao.NsxProviderDao; import com.cloud.network.element.NsxProviderVO; import org.apache.cloudstack.NsxAnswer; @@ -46,7 +45,8 @@ public class NsxControllerUtils { throw new InvalidParameterValueException("Failed to find an NSX controller"); } - Answer answer = agentMgr.sendTo(zoneId, Hypervisor.HypervisorType.VMware, cmd); + //Answer answer = agentMgr.sendTo(zoneId, Hypervisor.HypervisorType.VMware, cmd); + Answer answer = agentMgr.easySend(nsxProviderVO.getHostId(), cmd); if (answer == null || !answer.getResult()) { s_logger.error("NSX API Command failed"); diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java index 13942ae7618..e462d40f1eb 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxElement.java @@ -16,15 +16,24 @@ // under the License. package org.apache.cloudstack.service; +import com.cloud.agent.AgentManager; +import com.cloud.agent.Listener; import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.agent.api.AgentControlAnswer; +import com.cloud.agent.api.AgentControlCommand; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.deploy.DeployDestination; -import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ConnectionException; +import com.cloud.host.Host; import com.cloud.host.HostVO; +import com.cloud.host.Status; import com.cloud.network.Network; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.element.DhcpServiceProvider; @@ -35,6 +44,7 @@ import com.cloud.network.vpc.PrivateGateway; import com.cloud.network.vpc.StaticRouteProfile; import com.cloud.network.vpc.Vpc; import com.cloud.offering.NetworkOffering; +import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; @@ -44,7 +54,7 @@ import com.cloud.utils.component.AdapterBase; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; import com.cloud.vm.VirtualMachineProfile; -import org.apache.cloudstack.network.router.deployment.RouterDeploymentDefinitionBuilder; +import org.apache.cloudstack.StartupNsxCommand; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -58,16 +68,19 @@ import java.util.Objects; @Component public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsServiceProvider, VpcProvider, - ResourceStateAdapter { + ResourceStateAdapter, Listener { - @Inject - RouterDeploymentDefinitionBuilder routerDeploymentDefinitionBuilder; @Inject AccountManager accountMgr; @Inject NsxServiceImpl nsxService; @Inject DataCenterDao dataCenterDao; + @Inject + AgentManager agentManager; + @Inject + ResourceManager resourceManager; + private static final Logger LOGGER = Logger.getLogger(NsxElement.class); private final Map<Network.Service, Map<Network.Capability, String>> capabilities = initCapabilities(); @@ -160,7 +173,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS @Override public boolean isReady(PhysicalNetworkServiceProvider provider) { - return false; + return true; } @Override @@ -180,6 +193,8 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS @Override public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { + agentManager.registerForHostEvents(this, true, true, true); + resourceManager.registerResourceStateAdapter(this.getClass().getSimpleName(), this); return false; } @@ -200,7 +215,11 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS @Override public HostVO createHostVOForDirectConnectAgent(HostVO host, StartupCommand[] startup, ServerResource resource, Map<String, String> details, List<String> hostTags) { - return null; + if (!(startup[0] instanceof StartupNsxCommand)) { + return null; + } + host.setType(Host.Type.L2Networking); + return host; } @Override @@ -225,8 +244,19 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS } @Override - public boolean shutdownVpc(Vpc vpc, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { - return false; + public boolean shutdownVpc(Vpc vpc, ReservationContext context) throws ConcurrentOperationException { + DataCenterVO zone = dataCenterDao.findById(vpc.getZoneId()); + if (Network.Provider.Nsx.getName().equalsIgnoreCase(zone.getDhcpProvider())) { + if (Objects.isNull(zone)) { + throw new InvalidParameterValueException(String.format("Failed to find zone with id %s", vpc.getZoneId())); + } + Account account = accountMgr.getAccount(vpc.getAccountId()); + if (Objects.isNull(account)) { + throw new InvalidParameterValueException(String.format("Failed to find account with id %s", vpc.getAccountId())); + } + return nsxService.deleteVpcNetwork(vpc.getZoneId(), zone.getName(), account.getAccountId(), account.getName(), vpc.getName()); + } + return true; } @Override @@ -248,4 +278,59 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS public boolean applyACLItemsToPrivateGw(PrivateGateway gateway, List<? extends NetworkACLItem> rules) throws ResourceUnavailableException { return false; } + + @Override + public boolean processAnswers(long agentId, long seq, Answer[] answers) { + return false; + } + + @Override + public boolean processCommands(long agentId, long seq, Command[] commands) { + return false; + } + + @Override + public AgentControlAnswer processControlCommand(long agentId, AgentControlCommand cmd) { + return null; + } + + @Override + public void processHostAdded(long hostId) { + + } + + @Override + public void processConnect(Host host, StartupCommand cmd, boolean forRebalance) throws ConnectionException { + + } + + @Override + public boolean processDisconnect(long agentId, Status state) { + return false; + } + + @Override + public void processHostAboutToBeRemoved(long hostId) { + + } + + @Override + public void processHostRemoved(long hostId, long clusterId) { + + } + + @Override + public boolean isRecurring() { + return false; + } + + @Override + public int getTimeout() { + return 0; + } + + @Override + public boolean processTimeout(long agentId, long seq) { + return false; + } } diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxProviderServiceImpl.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxProviderServiceImpl.java index 9aac12fda8c..cfd1566f604 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxProviderServiceImpl.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxProviderServiceImpl.java @@ -20,6 +20,8 @@ import com.amazonaws.util.CollectionUtils; import com.cloud.dc.DataCenterVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.exception.InvalidParameterValueException; +import com.cloud.host.DetailVO; +import com.cloud.host.Host; import com.cloud.host.dao.HostDetailsDao; import com.cloud.network.Network; import com.cloud.network.Networks; @@ -97,22 +99,22 @@ public class NsxProviderServiceImpl implements NsxProviderService { NsxResource nsxResource = new NsxResource(); try { nsxResource.configure(hostname, hostdetails); - //final Host host = resourceManager.addHost(zoneId, nsxResource, nsxResource.getType(), params); - //if (host != null) { + final Host host = resourceManager.addHost(zoneId, nsxResource, nsxResource.getType(), params); + if (host != null) { nsxProvider = Transaction.execute((TransactionCallback<NsxProviderVO>) status -> { - NsxProviderVO nsxProviderVO = new NsxProviderVO(zoneId, name, hostname, + NsxProviderVO nsxProviderVO = new NsxProviderVO(zoneId, host.getId(), name, hostname, username, password, tier0Gateway, edgeCluster); nsxProviderDao.persist(nsxProviderVO); -// DetailVO detail = new DetailVO(host.getId(), "nsxcontrollerid", -// String.valueOf(nsxProviderVO.getId())); -// hostDetailsDao.persist(detail); + DetailVO detail = new DetailVO(host.getId(), "nsxcontrollerid", + String.valueOf(nsxProviderVO.getId())); + hostDetailsDao.persist(detail); return nsxProviderVO; }); -// } else { -// throw new CloudRuntimeException("Failed to add NSX controller due to internal error."); -// } + } else { + throw new CloudRuntimeException("Failed to add NSX controller due to internal error."); + } } catch (ConfigurationException e) { throw new CloudRuntimeException(e.getMessage()); } @@ -130,7 +132,7 @@ public class NsxProviderServiceImpl implements NsxProviderService { response.setUuid(nsxProvider.getUuid()); response.setHostname(nsxProvider.getHostname()); response.setPort(nsxProvider.getPort()); - response.setZoneId(nsxProvider.getZoneId()); + response.setZoneId(zone.getUuid()); response.setZoneName(zone.getName()); response.setTier0Gateway(nsxProvider.getTier0Gateway()); response.setTier0Gateway(nsxProvider.getEdgeCluster()); diff --git a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java index 95e4dbbe917..bbad6ab5389 100644 --- a/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java +++ b/plugins/network-elements/nsx/src/main/java/org/apache/cloudstack/service/NsxServiceImpl.java @@ -18,6 +18,7 @@ package org.apache.cloudstack.service; import org.apache.cloudstack.NsxAnswer; import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand; +import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand; import javax.inject.Inject; @@ -30,4 +31,11 @@ public class NsxServiceImpl implements NsxService { NsxAnswer result = nsxControllerUtils.sendNsxCommand(createNsxTier1GatewayCommand, zoneId); return result.getResult(); } + + public boolean deleteVpcNetwork(Long zoneId, String zoneName, Long accountId, String accountName, String vpcName) { + DeleteNsxTier1GatewayCommand deleteNsxTier1GatewayCommand = + new DeleteNsxTier1GatewayCommand(zoneName, zoneId, accountName, accountId, vpcName); + NsxAnswer result = nsxControllerUtils.sendNsxCommand(deleteNsxTier1GatewayCommand, zoneId); + return result.getResult(); + } } diff --git a/ui/src/views/infra/network/ServiceProvidersTab.vue b/ui/src/views/infra/network/ServiceProvidersTab.vue index e61acf7b70a..c8e79dc9b56 100644 --- a/ui/src/views/infra/network/ServiceProvidersTab.vue +++ b/ui/src/views/infra/network/ServiceProvidersTab.vue @@ -1060,6 +1060,34 @@ export default { { title: 'Nsx', details: ['name', 'state', 'id', 'physicalnetworkid', 'servicelist'], + actions: [ + { + api: 'updateNetworkServiceProvider', + icon: 'stop-outlined', + listView: true, + label: 'label.disable.provider', + confirm: 'message.confirm.disable.provider', + // show: (record) => { return record && record.id && record.state === 'Enabled' }, + mapping: { + state: { + value: (record) => { return 'Disabled' } + } + } + }, + { + api: 'updateNetworkServiceProvider', + icon: 'play-circle-outlined', + listView: true, + label: 'label.enable.provider', + confirm: 'message.confirm.enable.provider', + // show: (record) => { return record && record.id && record.state === 'Disabled' }, + mapping: { + state: { + value: (record) => { return 'Enabled' } + } + } + } + ], lists: [ { title: 'label.nsx.controller',
