mirror of https://github.com/apache/cloudstack.git
add create/delete segment and UI integration
This commit is contained in:
parent
2cccd53944
commit
37d634406d
|
|
@ -430,6 +430,8 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
|
|||
|
||||
long getDataCenterId();
|
||||
|
||||
long getAccountId();
|
||||
|
||||
long getNetworkOfferingId();
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -369,6 +369,10 @@ public class NetworkVO implements Network {
|
|||
return mode;
|
||||
}
|
||||
|
||||
public void setAccountId(long accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getAccountId() {
|
||||
return accountId;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
package org.apache.cloudstack.agent.api;
|
||||
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
|
||||
public class CreateNsxSegmentCommand extends CreateNsxTier1GatewayCommand {
|
||||
private NetworkVO tierNetwork;
|
||||
public CreateNsxSegmentCommand(String zoneName, Long zoneId, String accountName, Long accountId, String vpcName, NetworkVO tierNetwork) {
|
||||
super(zoneName, zoneId, accountName, accountId, vpcName);
|
||||
this.tierNetwork = tierNetwork;
|
||||
}
|
||||
|
||||
public NetworkVO getTierNetwork() {
|
||||
return tierNetwork;
|
||||
}
|
||||
|
||||
public void setTierNetwork(NetworkVO tierNetwork) {
|
||||
this.tierNetwork = tierNetwork;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package org.apache.cloudstack.agent.api;
|
||||
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
|
||||
public class DeleteNsxSegmentCommand extends CreateNsxSegmentCommand {
|
||||
public DeleteNsxSegmentCommand(String accountName, NetworkVO network) {
|
||||
super(null, network.getDataCenterId(), accountName, network.getAccountId(), null, network);
|
||||
}
|
||||
}
|
||||
|
|
@ -16,47 +16,60 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.resource;
|
||||
|
||||
import static org.apache.cloudstack.utils.NsxApiClientUtils.PoolAllocation.ROUTING;
|
||||
import static org.apache.cloudstack.utils.NsxApiClientUtils.HAMode.ACTIVE_STANDBY;
|
||||
import static org.apache.cloudstack.utils.NsxApiClientUtils.createApiClient;
|
||||
|
||||
import com.cloud.agent.IAgentControl;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.ReadyCommand;
|
||||
import com.cloud.agent.api.ReadyAnswer;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.PingCommand;
|
||||
import com.cloud.agent.api.ReadyAnswer;
|
||||
import com.cloud.agent.api.ReadyCommand;
|
||||
import com.cloud.agent.api.StartupCommand;
|
||||
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.EdgeClusters;
|
||||
import com.vmware.nsx.model.EdgeCluster;
|
||||
import com.vmware.nsx_policy.infra.Segments;
|
||||
import com.vmware.nsx_policy.infra.Tier1s;
|
||||
import com.vmware.nsx_policy.infra.segments.ServiceSegments;
|
||||
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.Segment;
|
||||
import com.vmware.nsx_policy.model.SegmentSubnet;
|
||||
import com.vmware.nsx_policy.model.ServiceSegmentListResult;
|
||||
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.CreateNsxSegmentCommand;
|
||||
import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNsxSegmentCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand;
|
||||
import org.apache.cloudstack.service.NsxApi;
|
||||
import org.apache.cloudstack.utils.NsxApiClientUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static java.util.Objects.isNull;
|
||||
import static org.apache.cloudstack.utils.NsxApiClientUtils.HAMode.ACTIVE_STANDBY;
|
||||
import static org.apache.cloudstack.utils.NsxApiClientUtils.FailoverMode.PREEMPTIVE;
|
||||
import static org.apache.cloudstack.utils.NsxApiClientUtils.PoolAllocation.ROUTING;
|
||||
import static org.apache.cloudstack.utils.NsxApiClientUtils.createApiClient;
|
||||
|
||||
public class NsxResource implements ServerResource {
|
||||
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_GATEWAY_PATH_PREFIX = "/infra/tier-1s/";
|
||||
private static final String TIER_1_RESOURCE_TYPE = "Tier1";
|
||||
// private static final String ROUTING = "ROUTING";
|
||||
private static final String SEGMENT_RESOURCE_TYPE = "Segment";
|
||||
|
||||
private String name;
|
||||
protected String hostname;
|
||||
protected String username;
|
||||
|
|
@ -98,7 +111,11 @@ public class NsxResource implements ServerResource {
|
|||
return executeRequest((ReadyCommand) cmd);
|
||||
} else if (cmd instanceof DeleteNsxTier1GatewayCommand) {
|
||||
return executeRequest((DeleteNsxTier1GatewayCommand) cmd);
|
||||
} else if (cmd instanceof CreateNsxTier1GatewayCommand) {
|
||||
} else if (cmd instanceof DeleteNsxSegmentCommand) {
|
||||
return executeRequest((DeleteNsxSegmentCommand) cmd);
|
||||
} else if (cmd instanceof CreateNsxSegmentCommand) {
|
||||
return executeRequest((CreateNsxSegmentCommand) cmd);
|
||||
} else if (cmd instanceof CreateNsxTier1GatewayCommand) {
|
||||
return executeRequest((CreateNsxTier1GatewayCommand) cmd);
|
||||
} else {
|
||||
return Answer.createUnsupportedCommandAnswer(cmd);
|
||||
|
|
@ -206,15 +223,13 @@ public class NsxResource implements ServerResource {
|
|||
}
|
||||
|
||||
private Function<Class, Service> nsxService = svcClass -> { return nsxApi.getApiClient().createStub(svcClass); };
|
||||
private Service getService(Class svcClass) {
|
||||
return nsxApi.getApiClient().createStub(svcClass);
|
||||
}
|
||||
private Answer executeRequest(CreateNsxTier1GatewayCommand cmd) {
|
||||
String name = getTier1GatewayName(cmd);
|
||||
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;
|
||||
|
||||
|
|
@ -224,6 +239,7 @@ public class NsxResource implements ServerResource {
|
|||
.setResourceType(TIER_1_RESOURCE_TYPE)
|
||||
.setPoolAllocation(ROUTING.name())
|
||||
.setHaMode(ACTIVE_STANDBY.name())
|
||||
.setFailoverMode(PREEMPTIVE.name())
|
||||
.setId(name)
|
||||
.setDisplayName(name)
|
||||
.setChildren(
|
||||
|
|
@ -231,7 +247,7 @@ public class NsxResource implements ServerResource {
|
|||
.setLocaleServices(
|
||||
new com.vmware.nsx_policy.model.LocaleServices.Builder()
|
||||
.setEdgeClusterPath(localeServices.get(0).getEdgeClusterPath())
|
||||
.setId(localeServices.get(0).getId())
|
||||
.setParentPath(TIER_1_GATEWAY_PATH_PREFIX + getTier1GatewayName(cmd))
|
||||
.setResourceType("LocaleServices")
|
||||
.build()
|
||||
).build())).build();
|
||||
|
|
@ -254,16 +270,69 @@ public class NsxResource implements ServerResource {
|
|||
return new NsxAnswer(cmd, true, null);
|
||||
}
|
||||
|
||||
private Answer executeRequest(CreateNsxSegmentCommand cmd) {
|
||||
try {
|
||||
String segmentName = getSegmentName(cmd);
|
||||
Segments segmentService = (Segments) nsxService.apply(Segments.class);
|
||||
SegmentSubnet subnet = new SegmentSubnet.Builder()
|
||||
.setGatewayAddress(cmd.getTierNetwork().getGateway() + "/" + cmd.getTierNetwork().getCidr().split("/")[1]).build();
|
||||
Segment segment = new Segment.Builder()
|
||||
.setResourceType(SEGMENT_RESOURCE_TYPE)
|
||||
.setId(segmentName)
|
||||
.setDisplayName(segmentName)
|
||||
.setConnectivityPath(isNull(cmd.getVpcName()) ? TIER_0_GATEWAY_PATH_PREFIX + tier0Gateway
|
||||
: TIER_1_GATEWAY_PATH_PREFIX + getTier1GatewayName(cmd))
|
||||
.setAdminState(NsxApiClientUtils.AdminState.UP.name())
|
||||
.setSubnets(List.of(subnet))
|
||||
.build();
|
||||
segmentService.patch(segmentName, segment);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(String.format("Failed to create network: %s", cmd.getTierNetwork().getName()));
|
||||
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
|
||||
}
|
||||
return new NsxAnswer(cmd, true, null);
|
||||
}
|
||||
|
||||
private NsxAnswer executeRequest(DeleteNsxSegmentCommand cmd) {
|
||||
try {
|
||||
String segmentName = getSegmentName(cmd);
|
||||
Segments segmentService = (Segments) nsxService.apply(Segments.class);
|
||||
segmentService.delete(segmentName);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error(String.format("Failed to delete NSX segment: %s", getSegmentName(cmd)) );
|
||||
return new NsxAnswer(cmd, new CloudRuntimeException(e.getMessage()));
|
||||
}
|
||||
return new NsxAnswer(cmd, true, null);
|
||||
}
|
||||
|
||||
private List<com.vmware.nsx_policy.model.LocaleServices> getTier0LocalServices(String tier0Gateway) {
|
||||
try {
|
||||
LocaleServices tier0LocaleServices = (LocaleServices) nsxService.apply(LocaleServices.class);
|
||||
LocaleServicesListResult result =tier0LocaleServices.list(tier0Gateway, null, false, null, null, null, null);
|
||||
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 EdgeCluster getEdgeClusterDetails(String edgeClusterName) {
|
||||
try {
|
||||
EdgeClusters edgeClusterService = (EdgeClusters) nsxService.apply(EdgeClusters.class);
|
||||
return edgeClusterService.get(edgeClusterName);
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException(String.format("Failed to fetch details of edge cluster: %s, due to: %s", edgeClusterName, e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
private ServiceSegmentListResult listServiceSegments() {
|
||||
try {
|
||||
ServiceSegments serviceSegmentSvc = (ServiceSegments) nsxService.apply(ServiceSegments.class);
|
||||
return serviceSegmentSvc.list(null, null, null, true, null);
|
||||
} catch (Exception e) {
|
||||
throw new CloudRuntimeException(String.format("Failed to fetch service segment list due to %s", e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
private Tier1 getTier1Gateway(String tier1GatewayId) {
|
||||
try {
|
||||
Tier1s tier1service = (Tier1s) nsxService.apply(Tier1s.class);
|
||||
|
|
@ -278,6 +347,10 @@ public class NsxResource implements ServerResource {
|
|||
return cmd.getZoneName() + "-" + cmd.getAccountName() + "-" + cmd.getVpcName();
|
||||
}
|
||||
|
||||
private String getSegmentName(CreateNsxSegmentCommand cmd) {
|
||||
return cmd.getAccountName() + "-" + cmd.getTierNetwork().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -36,8 +36,11 @@ import com.cloud.host.Host;
|
|||
import com.cloud.host.HostVO;
|
||||
import com.cloud.host.Status;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.Networks;
|
||||
import com.cloud.network.PhysicalNetworkServiceProvider;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.network.dao.PhysicalNetworkDao;
|
||||
import com.cloud.network.dao.PhysicalNetworkVO;
|
||||
import com.cloud.network.element.DhcpServiceProvider;
|
||||
|
|
@ -84,11 +87,15 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS
|
|||
@Inject
|
||||
DataCenterDao dataCenterDao;
|
||||
@Inject
|
||||
NetworkDao networkDao;
|
||||
@Inject
|
||||
AgentManager agentManager;
|
||||
@Inject
|
||||
ResourceManager resourceManager;
|
||||
@Inject
|
||||
PhysicalNetworkDao physicalNetworkDao;
|
||||
@Inject
|
||||
NetworkModel networkModel;
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(NsxElement.class);
|
||||
|
||||
|
|
@ -97,12 +104,21 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS
|
|||
|
||||
private static Map<Network.Service, Map<Network.Capability, String>> initCapabilities() {
|
||||
Map<Network.Service, Map<Network.Capability, String>> capabilities = new HashMap<>();
|
||||
|
||||
Map<Network.Capability, String> dhcpCapabilities = Map.of(Network.Capability.DhcpAccrossMultipleSubnets, "true");
|
||||
capabilities.put(Network.Service.Dhcp, dhcpCapabilities);
|
||||
|
||||
Map<Network.Capability, String> dnsCapabilities = new HashMap<>();
|
||||
dnsCapabilities.put(Network.Capability.AllowDnsSuffixModification, "true");
|
||||
capabilities.put(Network.Service.Dns, dnsCapabilities);
|
||||
capabilities.put(Network.Service.Connectivity, null);
|
||||
|
||||
// capabilities.put(Network.Service.Connectivity, null);
|
||||
capabilities.put(Network.Service.StaticNat, null);
|
||||
|
||||
Map<Network.Capability, String> sourceNatCapabilities = new HashMap<>();
|
||||
sourceNatCapabilities.put(Network.Capability.RedundantRouter, "true");
|
||||
sourceNatCapabilities.put(Network.Capability.SupportedSourceNatTypes, "peraccount");
|
||||
capabilities.put(Network.Service.SourceNat, sourceNatCapabilities);
|
||||
return capabilities;
|
||||
}
|
||||
@Override
|
||||
|
|
@ -172,12 +188,14 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS
|
|||
|
||||
@Override
|
||||
public boolean shutdown(Network network, ReservationContext context, boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||
return false;
|
||||
return canHandle(network, Network.Service.Connectivity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||
return false;
|
||||
Account account = accountMgr.getAccount(network.getAccountId());
|
||||
NetworkVO networkVO = networkDao.findById(network.getId());
|
||||
return nsxService.deleteNetwork(account.getAccountName(), networkVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -192,7 +210,7 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS
|
|||
|
||||
@Override
|
||||
public boolean canEnableIndividualServices() {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -357,5 +375,17 @@ public class NsxElement extends AdapterBase implements DhcpServiceProvider, DnsS
|
|||
return false;
|
||||
}
|
||||
|
||||
protected boolean canHandle(Network network, Network.Service service) {
|
||||
LOGGER.debug("Checking if Nsx Element can handle service " + service.getName() + " on network "
|
||||
+ network.getDisplayText());
|
||||
|
||||
if (!networkModel.isProviderForNetwork(getProvider(), network.getId())) {
|
||||
LOGGER.debug("Nsx Element is not a provider for network " + network.getDisplayText());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private final Function<Long, DataCenterVO> zoneFunction = zoneId -> { return dataCenterDao.findById(zoneId); };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,24 +16,36 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.service;
|
||||
|
||||
import static java.util.Objects.isNull;
|
||||
import static java.util.Objects.nonNull;
|
||||
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkMigrationResponder;
|
||||
import com.cloud.network.NetworkProfile;
|
||||
import com.cloud.network.Networks;
|
||||
import com.cloud.network.PhysicalNetwork;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.network.dao.PhysicalNetworkVO;
|
||||
import com.cloud.network.guru.GuestNetworkGuru;
|
||||
import com.cloud.network.vpc.VpcVO;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.ReservationContext;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import org.apache.cloudstack.NsxAnswer;
|
||||
import org.apache.cloudstack.agent.api.CreateNsxSegmentCommand;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
|
@ -43,6 +55,12 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr
|
|||
|
||||
@Inject
|
||||
NetworkOfferingServiceMapDao networkOfferingServiceMapDao;
|
||||
@Inject
|
||||
NsxControllerUtils nsxControllerUtils;
|
||||
@Inject
|
||||
DataCenterDao zoneDao;
|
||||
@Inject
|
||||
AccountDao accountDao;
|
||||
|
||||
private static final Networks.TrafficType[] TrafficTypes = {Networks.TrafficType.Guest};
|
||||
|
||||
|
|
@ -56,12 +74,39 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr
|
|||
PhysicalNetwork physicalNetwork) {
|
||||
return networkType == DataCenter.NetworkType.Advanced && isMyTrafficType(offering.getTrafficType())
|
||||
&& isMyIsolationMethod(physicalNetwork) && networkOfferingServiceMapDao.isProviderForNetworkOffering(
|
||||
offering.getId(), Network.Provider.Tungsten);
|
||||
offering.getId(), Network.Provider.Nsx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
|
||||
return null;
|
||||
PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
|
||||
DataCenter dc = _dcDao.findById(plan.getDataCenterId());
|
||||
|
||||
if (!canHandle(offering, dc.getNetworkType(), physnet)) {
|
||||
LOGGER.debug("Refusing to design this network");
|
||||
return null;
|
||||
}
|
||||
|
||||
NetworkVO network = (NetworkVO) super.design(offering, plan, userSpecified, owner);
|
||||
|
||||
if (network == null) {
|
||||
return null;
|
||||
}
|
||||
if (userSpecified != null) {
|
||||
if ((userSpecified.getIp6Cidr() == null && userSpecified.getIp6Gateway() != null) || (
|
||||
userSpecified.getIp6Cidr() != null && userSpecified.getIp6Gateway() == null)) {
|
||||
throw new InvalidParameterValueException("cidrv6 and gatewayv6 must be specified together.");
|
||||
}
|
||||
|
||||
if (userSpecified.getIp6Cidr() != null) {
|
||||
network.setIp6Cidr(userSpecified.getIp6Cidr());
|
||||
network.setIp6Gateway(userSpecified.getIp6Gateway());
|
||||
}
|
||||
}
|
||||
|
||||
network.setBroadcastDomainType(Networks.BroadcastDomainType.NSX);
|
||||
network.setState(Network.State.Allocated);
|
||||
return network;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -73,7 +118,38 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr
|
|||
@Override
|
||||
public Network implement(Network network, NetworkOffering offering, DeployDestination dest,
|
||||
ReservationContext context) {
|
||||
return null;
|
||||
NetworkVO implemented = new NetworkVO(network.getTrafficType(), network.getMode(),
|
||||
network.getBroadcastDomainType(), network.getNetworkOfferingId(), Network.State.Implemented,
|
||||
network.getDataCenterId(), network.getPhysicalNetworkId(), offering.isRedundantRouter());
|
||||
implemented.setAccountId(network.getAccountId());
|
||||
|
||||
if (network.getGateway() != null) {
|
||||
implemented.setGateway(network.getGateway());
|
||||
}
|
||||
|
||||
if (network.getCidr() != null) {
|
||||
implemented.setCidr(network.getCidr());
|
||||
}
|
||||
|
||||
if (network.getVpcId() != null) {
|
||||
implemented.setVpcId(network.getVpcId());
|
||||
}
|
||||
|
||||
if (network.getName() != null) {
|
||||
implemented.setName(network.getName());
|
||||
}
|
||||
implemented.setBroadcastUri(Networks.BroadcastDomainType.NSX.toUri("nsx"));
|
||||
try {
|
||||
long zoneId = network.getDataCenterId();
|
||||
DataCenter zone = zoneDao.findById(zoneId);
|
||||
if (isNull(zone)) {
|
||||
throw new CloudRuntimeException(String.format("Failed to find zone with id: %s", zoneId));
|
||||
}
|
||||
createNsxSegment(implemented, zone);
|
||||
} catch (Exception ex) {
|
||||
throw new CloudRuntimeException("unable to create NSX network " + network.getUuid() + "due to: " + ex.getMessage());
|
||||
}
|
||||
return implemented;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -112,4 +188,25 @@ public class NsxGuestNetworkGuru extends GuestNetworkGuru implements NetworkMigr
|
|||
public void commitMigration(NicProfile nic, Network network, VirtualMachineProfile vm, ReservationContext src, ReservationContext dst) {
|
||||
|
||||
}
|
||||
|
||||
private void createNsxSegment(NetworkVO networkVO, DataCenter zone) {
|
||||
String vpcName = null;
|
||||
if (nonNull(networkVO.getVpcId())) {
|
||||
VpcVO vpc = _vpcDao.findById(networkVO.getVpcId());
|
||||
if (isNull(vpc)) {
|
||||
throw new CloudRuntimeException(String.format("Failed to find VPC network with id: %s", networkVO.getVpcId()));
|
||||
}
|
||||
vpcName = vpc.getName();
|
||||
}
|
||||
Account account = accountDao.findById(networkVO.getAccountId());
|
||||
if (isNull(account)) {
|
||||
throw new CloudRuntimeException(String.format("Unable to find account with id: %s", networkVO.getAccountId()));
|
||||
}
|
||||
CreateNsxSegmentCommand command = new CreateNsxSegmentCommand(zone.getName(), zone.getId(),
|
||||
account.getAccountName(), networkVO.getAccountId(), vpcName, networkVO);
|
||||
NsxAnswer answer = nsxControllerUtils.sendNsxCommand(command, zone.getId());
|
||||
if (!answer.getResult()) {
|
||||
throw new CloudRuntimeException("can not create NSX network");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,8 +16,10 @@
|
|||
// under the License.
|
||||
package org.apache.cloudstack.service;
|
||||
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import org.apache.cloudstack.NsxAnswer;
|
||||
import org.apache.cloudstack.agent.api.CreateNsxTier1GatewayCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNsxSegmentCommand;
|
||||
import org.apache.cloudstack.agent.api.DeleteNsxTier1GatewayCommand;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
|
@ -38,4 +40,10 @@ public class NsxServiceImpl implements NsxService {
|
|||
NsxAnswer result = nsxControllerUtils.sendNsxCommand(deleteNsxTier1GatewayCommand, zoneId);
|
||||
return result.getResult();
|
||||
}
|
||||
|
||||
public boolean deleteNetwork(String accountName, NetworkVO network) {
|
||||
DeleteNsxSegmentCommand deleteNsxSegmentCommand = new DeleteNsxSegmentCommand(accountName, network);
|
||||
NsxAnswer result = nsxControllerUtils.sendNsxCommand(deleteNsxSegmentCommand, network.getDataCenterId());
|
||||
return result.getResult();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,10 +40,25 @@ public class NsxApiClientUtils {
|
|||
LB_XLARGE
|
||||
}
|
||||
|
||||
public enum TYPE {
|
||||
ROUTED,
|
||||
NATTED
|
||||
}
|
||||
|
||||
public enum HAMode {
|
||||
ACTIVE_STANDBY,
|
||||
ACTIVE_ACTIVE
|
||||
}
|
||||
|
||||
public enum FailoverMode {
|
||||
PREEMPTIVE,
|
||||
NON_PREEMPTIVE
|
||||
}
|
||||
|
||||
public enum AdminState {
|
||||
UP,
|
||||
DOWN
|
||||
}
|
||||
public static ApiClient createApiClient(String hostname, String port, String username, char[] password) {
|
||||
String controllerUrl = String.format("https://%s:%s", hostname, port);
|
||||
HttpConfiguration.SslConfiguration.Builder sslConfigBuilder = new HttpConfiguration.SslConfiguration.Builder();
|
||||
|
|
|
|||
|
|
@ -1375,6 +1375,14 @@
|
|||
"label.not.found": "Not found",
|
||||
"label.not.suitable": "Not suitable",
|
||||
"label.notifications": "Notifications",
|
||||
"label.nsx.provider": "NSX Provider",
|
||||
"label.nsx.provider.name": "NSX provider name",
|
||||
"label.nsx.provider.hostname": "NSX provider hostname",
|
||||
"label.nsx.provider.port": "NSX provider port",
|
||||
"label.nsx.provider.username": "NSX provider username",
|
||||
"label.nsx.provider.password": "NSX provider password",
|
||||
"label.nsx.provider.edgecluster": "NSX provider edge cluster",
|
||||
"label.nsx.provider.tier0gateway": "NSX provider tier-0 gateway",
|
||||
"label.num.cpu.cores": "# of CPU cores",
|
||||
"label.number": "#Rule",
|
||||
"label.numretries": "Number of retries",
|
||||
|
|
@ -2752,6 +2760,7 @@
|
|||
"message.host.dedication.released": "Host dedication released.",
|
||||
"message.info.cloudian.console": "Cloudian Management Console should open in another window.",
|
||||
"message.installwizard.cloudstack.helptext.website": " * Project website:\t ",
|
||||
"message.infra.setup.nsx.description": "This zone must contain an NSX provider because the isolation method is NSX",
|
||||
"message.infra.setup.tungsten.description": "This zone must contain a Tungsten-Fabric provider because the isolation method is TF",
|
||||
"message.installwizard.cloudstack.helptext.document": " * Documentation:\t ",
|
||||
"message.installwizard.cloudstack.helptext.header": "\nYou can find more information about Apache CloudStack™ on the pages listed below.\n",
|
||||
|
|
|
|||
|
|
@ -480,6 +480,11 @@ export default {
|
|||
this.stepData.isTungstenZone = true
|
||||
this.stepData.tungstenPhysicalNetworkId = physicalNetworkReturned.id
|
||||
}
|
||||
if (physicalNetwork.isolationMethod === 'NSX' &&
|
||||
physicalNetwork.traffics.findIndex(traffic => traffic.type === 'public' || traffic.type === 'guest') > -1) {
|
||||
this.stepData.isNsxZone = true
|
||||
this.stepData.tungstenPhysicalNetworkId = physicalNetworkReturned.id
|
||||
}
|
||||
} else {
|
||||
this.stepData.physicalNetworkReturned = this.stepData.physicalNetworkItem['createPhysicalNetwork' + index]
|
||||
}
|
||||
|
|
@ -965,6 +970,8 @@ export default {
|
|||
|
||||
if (this.stepData.isTungstenZone) {
|
||||
await this.stepCreateTungstenFabricPublicNetwork()
|
||||
} else if (this.stepData.isNsxZone) {
|
||||
await this.stepAddNsxController()
|
||||
} else {
|
||||
await this.stepConfigureStorageTraffic()
|
||||
}
|
||||
|
|
@ -1035,6 +1042,28 @@ export default {
|
|||
this.setStepStatus(STATUS_FAILED)
|
||||
}
|
||||
},
|
||||
async stepAddNsxController () {
|
||||
try {
|
||||
if (!this.stepData.stepMove.includes('addNsxController')) {
|
||||
const providerParams = {}
|
||||
providerParams.name = this.prefillContent?.name || ''
|
||||
providerParams.nsxproviderhostname = this.prefillContent?.nsxHostname || ''
|
||||
providerParams.nsxproviderport = this.prefillContent?.nsxPort || ''
|
||||
providerParams.username = this.prefillContent?.username || ''
|
||||
providerParams.password = this.prefillContent?.password || ''
|
||||
providerParams.zoneid = this.stepData.zoneReturned.id
|
||||
providerParams.tier0gateway = this.prefillContent?.tier0Gateway || ''
|
||||
providerParams.edgecluster = this.prefillContent?.edgeCluster || ''
|
||||
|
||||
await this.addNsxController(providerParams)
|
||||
this.stepData.stepMove.push('addNsxController')
|
||||
}
|
||||
} catch (e) {
|
||||
this.messageError = e
|
||||
this.processStatus = STATUS_FAILED
|
||||
this.setStepStatus(STATUS_FAILED)
|
||||
}
|
||||
},
|
||||
async stepConfigureStorageTraffic () {
|
||||
let targetNetwork = false
|
||||
this.prefillContent.physicalNetworks.forEach(physicalNetwork => {
|
||||
|
|
@ -2177,6 +2206,16 @@ export default {
|
|||
})
|
||||
})
|
||||
},
|
||||
addNsxController (args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
api('addNsxController', {}, 'POST', args).then(json => {
|
||||
resolve()
|
||||
}).catch(error => {
|
||||
const message = error.response.headers['x-description']
|
||||
reject(message)
|
||||
})
|
||||
})
|
||||
},
|
||||
configTungstenFabricService (args) {
|
||||
return new Promise((resolve, reject) => {
|
||||
api('configTungstenFabricService', {}, 'POST', args).then(json => {
|
||||
|
|
|
|||
|
|
@ -74,6 +74,18 @@
|
|||
:isFixError="isFixError"
|
||||
/>
|
||||
|
||||
<static-inputs-form
|
||||
v-if="steps && steps[currentStep].formKey === 'nsx'"
|
||||
@nextPressed="nextPressed"
|
||||
@backPressed="handleBack"
|
||||
@fieldsChanged="fieldsChanged"
|
||||
@submitLaunchZone="submitLaunchZone"
|
||||
:fields="nsxFields"
|
||||
:prefillContent="prefillContent"
|
||||
:description="nsxSetupDescription"
|
||||
:isFixError="isFixError"
|
||||
/>
|
||||
|
||||
<static-inputs-form
|
||||
v-if="steps && steps[currentStep].formKey === 'pod'"
|
||||
@nextPressed="nextPressed"
|
||||
|
|
@ -189,6 +201,16 @@ export default {
|
|||
}
|
||||
return isTungsten
|
||||
},
|
||||
isNsxZone () {
|
||||
let isNsx = false
|
||||
if (!this.prefillContent.physicalNetworks) {
|
||||
isNsx = false
|
||||
} else {
|
||||
const nsxIdx = this.prefillContent.physicalNetworks.findIndex(network => network.isolationMethod === 'NSX')
|
||||
isNsx = nsxIdx > -1
|
||||
}
|
||||
return isNsx
|
||||
},
|
||||
allSteps () {
|
||||
const steps = []
|
||||
steps.push({
|
||||
|
|
@ -201,6 +223,12 @@ export default {
|
|||
formKey: 'tungsten'
|
||||
})
|
||||
}
|
||||
if (this.isNsxZone) {
|
||||
steps.push({
|
||||
title: 'label.nsx.provider',
|
||||
formKey: 'nsx'
|
||||
})
|
||||
}
|
||||
if (this.havingNetscaler) {
|
||||
steps.push({
|
||||
title: 'label.netScaler',
|
||||
|
|
@ -347,6 +375,53 @@ export default {
|
|||
}
|
||||
]
|
||||
},
|
||||
nsxFields () {
|
||||
const fields = [
|
||||
{
|
||||
title: 'label.nsx.provider.name',
|
||||
key: 'name',
|
||||
placeHolder: 'message.installwizard.tooltip.nsx.provider.name',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
title: 'label.nsx.provider.hostname',
|
||||
key: 'nsxHostname',
|
||||
placeHolder: 'message.installwizard.tooltip.nsx.provider.hostname',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
title: 'label.nsx.provider.port',
|
||||
key: 'nsxPort',
|
||||
placeHolder: 'message.installwizard.tooltip.nsx.provider.port',
|
||||
required: false
|
||||
},
|
||||
{
|
||||
title: 'label.nsx.provider.username',
|
||||
key: 'username',
|
||||
placeHolder: 'message.installwizard.tooltip.nsx.provider.username',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
title: 'label.nsx.provider.password',
|
||||
key: 'password',
|
||||
placeHolder: 'message.installwizard.tooltip.nsx.provider.password',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
title: 'label.nsx.provider.edgecluster',
|
||||
key: 'edgeCluster',
|
||||
placeHolder: 'message.installwizard.tooltip.nsx.provider.edgecluster',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
title: 'label.nsx.provider.tier0gateway',
|
||||
key: 'tier0Gateway',
|
||||
placeHolder: 'message.installwizard.tooltip.nsx.provider.tier0gateway',
|
||||
required: true
|
||||
}
|
||||
]
|
||||
return fields
|
||||
},
|
||||
guestTrafficFields () {
|
||||
const fields = [
|
||||
{
|
||||
|
|
@ -416,6 +491,7 @@ export default {
|
|||
},
|
||||
podSetupDescription: 'message.add.pod.during.zone.creation',
|
||||
tungstenSetupDescription: 'message.infra.setup.tungsten.description',
|
||||
nsxSetupDescription: 'message.infra.setup.nsx.description',
|
||||
netscalerSetupDescription: 'label.please.specify.netscaler.info',
|
||||
storageTrafficDescription: 'label.zonewizard.traffictype.storage',
|
||||
podFields: [
|
||||
|
|
@ -459,6 +535,7 @@ export default {
|
|||
created () {
|
||||
this.physicalNetworks = this.prefillContent.physicalNetworks
|
||||
this.steps = this.filteredSteps()
|
||||
console.log(this.isNsxZone)
|
||||
this.currentStep = this.prefillContent?.networkStep || 0
|
||||
if (this.stepChild && this.stepChild !== '') {
|
||||
this.currentStep = this.steps.findIndex(item => item.formKey === this.stepChild)
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
<a-select-option value="VSP"> VSP </a-select-option>
|
||||
<a-select-option value="VCS"> VCS </a-select-option>
|
||||
<a-select-option value="TF"> TF </a-select-option>
|
||||
<a-select-option value="NSX"> NSX </a-select-option>
|
||||
<a-select-option v-if="hypervisor === 'VMware'" value="NSX"> NSX </a-select-option>
|
||||
|
||||
<template #suffixIcon>
|
||||
<a-tooltip
|
||||
|
|
|
|||
Loading…
Reference in New Issue