CLOUDSTACK-10189: Adding nuage VSD managed network support to CloudStack (#2360)

Exposing externalId en domainId field in the UI to CS users.

Co-Authored-By: Sigert Goeminne sigert.goeminne@nuagenetworks.net
Co-Authored-By: Raf Smeets raf.smeets@nuagenetworks.net
This commit is contained in:
Sigert Goeminne 2017-12-28 10:25:15 +01:00 committed by Rohit Yadav
parent 2ab5ab1c90
commit 26759d1d13
42 changed files with 1005 additions and 113 deletions

View File

@ -390,4 +390,6 @@ public interface Network extends ControlledEntity, StateObject<Network.State>, I
void setNetworkACLId(Long networkACLId);
boolean isStrechedL2Network();
String getExternalId();
}

View File

@ -57,6 +57,7 @@ public class NetworkProfile implements Network {
private Long networkAclId;
private final String guruName;
private boolean strechedL2Subnet;
private String externalId;
public NetworkProfile(Network network) {
id = network.getId();
@ -91,6 +92,7 @@ public class NetworkProfile implements Network {
guruName = network.getGuruName();
strechedL2Subnet = network.isStrechedL2Network();
isRedundant = network.isRedundant();
externalId = network.getExternalId();
}
public String getDns1() {
@ -300,4 +302,9 @@ public class NetworkProfile implements Network {
return false;
}
@Override
public String getExternalId() {
return externalId;
}
}

View File

@ -654,6 +654,7 @@ public class ApiConstants {
public static final String IAM_ALLOW_DENY = "permission";
public static final String ENTITY_TYPE = "entitytype";
public static final String ENTITY_ID = "entityid";
public static final String EXTERNAL_ID = "externalid";
public static final String ACCESS_TYPE = "accesstype";
public static final String RESOURCE_DETAILS = "resourcedetails";
@ -706,6 +707,7 @@ public class ApiConstants {
public static final String HAS_ANNOTATION = "hasannotation";
public static final String LAST_ANNOTATED = "lastannotated";
public enum HostDetails {
all, capacity, events, stats, min;
}

View File

@ -16,7 +16,6 @@
// under the License.
package org.apache.cloudstack.api.command.user.network;
import com.cloud.utils.net.NetUtils;
import org.apache.log4j.Logger;
import org.apache.cloudstack.acl.RoleType;
@ -44,6 +43,7 @@ import com.cloud.exception.ResourceAllocationException;
import com.cloud.network.Network;
import com.cloud.network.Network.GuestType;
import com.cloud.offering.NetworkOffering;
import com.cloud.utils.net.NetUtils;
@APICommand(name = "createNetwork", description = "Creates a network", responseObject = NetworkResponse.class, responseView = ResponseView.Restricted, entityType = {Network.class},
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
@ -134,6 +134,9 @@ public class CreateNetworkCmd extends BaseCmd {
@Parameter(name = ApiConstants.IP6_CIDR, type = CommandType.STRING, description = "the CIDR of IPv6 network, must be at least /64")
private String ip6Cidr;
@Parameter(name = ApiConstants.EXTERNAL_ID, type = CommandType.STRING, description = "ID of the network in an external system.")
private String externalId;
@Parameter(name = ApiConstants.DISPLAY_NETWORK,
type = CommandType.BOOLEAN,
description = "an optional field, whether to the display the network to the end user or not.", authorized = {RoleType.Admin})
@ -209,6 +212,10 @@ public class CreateNetworkCmd extends BaseCmd {
return displayNetwork;
}
public String getExternalId() {
return externalId;
}
@Override
public boolean isDisplay() {
if(displayNetwork == null)

View File

@ -225,6 +225,10 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes
@Param(description = "If a network is enabled for 'streched l2 subnet' then represents zones on which network currently spans", since = "4.4")
private Set<String> networkSpannedZones;
@SerializedName(ApiConstants.EXTERNAL_ID)
@Param(description = "The external id of the network", since = "4.11")
private String externalId;
public Boolean getDisplayNetwork() {
return displayNetwork;
}
@ -429,4 +433,8 @@ public class NetworkResponse extends BaseResponse implements ControlledEntityRes
public void setNetworkSpannedZones(Set<String> networkSpannedZones) {
this.networkSpannedZones = networkSpannedZones;
}
public void setExternalId(String externalId) {
this.externalId = externalId;
}
}

View File

@ -169,7 +169,7 @@ public interface NetworkOrchestrationService {
Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, boolean bypassVlanOverlapCheck, String networkDomain, Account owner,
Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String ip6Gateway, String ip6Cidr,
Boolean displayNetworkEnabled, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
Boolean displayNetworkEnabled, String isolatedPvlan, String externalId) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;
UserDataServiceProvider getPasswordResetProvider(Network network);

View File

@ -109,7 +109,7 @@ public interface VpcManager {
Network
createVpcGuestNetwork(long ntwkOffId, String name, String displayText, String gateway, String cidr, String vlanId, String networkDomain, Account owner,
Long domainId, PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, long vpcId, Long aclId, Account caller,
Boolean displayNetworkEnabled)
Boolean displayNetworkEnabled, String externalId)
throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException;

View File

@ -38,7 +38,8 @@ import java.util.stream.Collectors;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import com.cloud.vm.NicExtraDhcpOptionVO;
import org.apache.log4j.Logger;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.cloud.entity.api.db.VMNetworkMapVO;
@ -53,7 +54,7 @@ import org.apache.cloudstack.framework.messagebus.MessageBus;
import org.apache.cloudstack.framework.messagebus.PublishScope;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.region.PortableIpDao;
import org.apache.log4j.Logger;
import com.cloud.agent.AgentManager;
import com.cloud.agent.Listener;
@ -204,6 +205,7 @@ import com.cloud.vm.DomainRouterVO;
import com.cloud.utils.net.Dhcp;
import com.cloud.vm.Nic;
import com.cloud.vm.Nic.ReservationStrategy;
import com.cloud.vm.NicExtraDhcpOptionVO;
import com.cloud.vm.NicIpAlias;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
@ -700,7 +702,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
public void doInTransactionWithoutResult(final TransactionStatus status) {
final NetworkVO vo = new NetworkVO(id, network, offering.getId(), guru.getName(), owner.getDomainId(), owner.getId(), relatedFile, name, displayText, predefined
.getNetworkDomain(), offering.getGuestType(), plan.getDataCenterId(), plan.getPhysicalNetworkId(), aclType, offering.getSpecifyIpRanges(),
vpcId, offering.getRedundantRouter());
vpcId, offering.getRedundantRouter(), predefined.getExternalId());
vo.setDisplayNetwork(isDisplayNetworkEnabled == null ? true : isDisplayNetworkEnabled);
vo.setStrechedL2Network(offering.getSupportsStrechedL2());
final NetworkVO networkPersisted = _networksDao.persist(vo, vo.getGuestType() == Network.GuestType.Isolated,
@ -2083,7 +2085,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
public Network createGuestNetwork(final long networkOfferingId, final String name, final String displayText, final String gateway, final String cidr, String vlanId,
boolean bypassVlanOverlapCheck, String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk,
final long zoneId, final ACLType aclType, Boolean subdomainAccess, final Long vpcId, final String ip6Gateway, final String ip6Cidr,
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
final Boolean isDisplayNetworkEnabled, final String isolatedPvlan, String externalId) throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
final NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
// this method supports only guest network creation
@ -2333,14 +2335,17 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra
userNetwork.setIp6Gateway(ip6Gateway);
}
if (externalId != null) {
userNetwork.setExternalId(externalId);
}
if (vlanIdFinal != null) {
if (isolatedPvlan == null) {
URI uri = null;
if (UuidUtils.validateUUID(vlanIdFinal)){
//Logical router's UUID provided as VLAN_ID
userNetwork.setVlanIdAsUUID(vlanIdFinal); //Set transient field
}
else {
} else {
uri = BroadcastDomainType.fromString(vlanIdFinal);
}
userNetwork.setBroadcastUri(uri);

View File

@ -496,3 +496,6 @@ UPDATE `cloud`.`monitoring_services` SET pidfile="/var/run/apache2/apache2.pid"
-- Use 'Other Linux 64-bit' as guest os for the default systemvmtemplate for VMware
-- This fixes a memory allocation issue to systemvms on VMware/ESXi
UPDATE `cloud`.`vm_template` SET guest_os_id=99 WHERE id=8;
-- Network External Ids
ALTER TABLE `cloud`.`networks` ADD `external_id` varchar(255);

View File

@ -172,6 +172,9 @@ public class NetworkVO implements Network {
@Column(name = "streched_l2")
boolean strechedL2Network = false;
@Column(name = "external_id")
String externalId;
@Transient
transient String vlanIdAsUUID;
@ -216,7 +219,7 @@ public class NetworkVO implements Network {
}
public NetworkVO(long id, Network that, long offeringId, String guruName, long domainId, long accountId, long related, String name, String displayText,
String networkDomain, GuestType guestType, long dcId, Long physicalNetworkId, ACLType aclType, boolean specifyIpRanges, Long vpcId, final boolean isRedundant) {
String networkDomain, GuestType guestType, long dcId, Long physicalNetworkId, ACLType aclType, boolean specifyIpRanges, Long vpcId, final boolean isRedundant, String externalId) {
this(id,
that.getTrafficType(),
that.getMode(),
@ -248,6 +251,7 @@ public class NetworkVO implements Network {
uuid = UUID.randomUUID().toString();
ip6Gateway = that.getIp6Gateway();
ip6Cidr = that.getIp6Cidr();
this.externalId = externalId;
}
/**
@ -638,4 +642,12 @@ public class NetworkVO implements Network {
public void setVpcId(Long vpcId) {
this.vpcId = vpcId;
}
public String getExternalId() {
return externalId;
}
public void setExternalId(String externalId) {
this.externalId = externalId;
}
}

View File

@ -35,7 +35,7 @@
</repository>
</repositories>
<properties>
<nuage.vsp.client.version>1.0.6</nuage.vsp.client.version>
<nuage.vsp.client.version>1.0.7</nuage.vsp.client.version>
</properties>
<dependencies>
<dependency>

View File

@ -20,11 +20,15 @@
package com.cloud.agent.api.element;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.commons.lang.builder.HashCodeBuilder;
import com.cloud.agent.api.Command;
import com.cloud.network.manager.NuageVspManager;
import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
public class ShutDownVpcVspCommand extends Command {
@ -32,13 +36,19 @@ public class ShutDownVpcVspCommand extends Command {
private final String _vpcUuid;
private final String _domainTemplateName;
private final List<String> _domainRouterUuids;
private final NetworkRelatedVsdIds _relatedVsdIds;
public ShutDownVpcVspCommand(String domainUuid, String vpcUuid, String domainTemplateName, List<String> domainRouterUuids) {
public ShutDownVpcVspCommand(String domainUuid, String vpcUuid, String domainTemplateName, List<String> domainRouterUuids, Map<String, String> details) {
super();
this._domainUuid = domainUuid;
this._vpcUuid = vpcUuid;
this._domainTemplateName = domainTemplateName;
this._domainRouterUuids = domainRouterUuids;
this._relatedVsdIds = new NetworkRelatedVsdIds.Builder()
.vsdDomainId(details.get(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID))
.vsdZoneId(details.get(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID))
.withVsdManaged(details.get(NuageVspManager.NETWORK_METADATA_VSD_MANAGED) != null && details.get(NuageVspManager.NETWORK_METADATA_VSD_MANAGED).equals("true"))
.build();
}
public String getDomainUuid() {
@ -57,6 +67,10 @@ public class ShutDownVpcVspCommand extends Command {
return _domainRouterUuids;
}
public NetworkRelatedVsdIds getRelatedVsdIds() {
return _relatedVsdIds;
}
@Override
public boolean executeInSequence() {
return false;

View File

@ -33,11 +33,13 @@ public class ImplementNetworkVspCommand extends Command {
private final VspNetwork _network;
private final VspDhcpDomainOption _dhcpOption;
private final boolean _isVsdManaged;
public ImplementNetworkVspCommand(VspNetwork network, VspDhcpDomainOption dhcpOption) {
public ImplementNetworkVspCommand(VspNetwork network, VspDhcpDomainOption dhcpOption, boolean isVsdManaged) {
super();
this._network = network;
this._dhcpOption = dhcpOption;
this._isVsdManaged = isVsdManaged;
}
public VspNetwork getNetwork() {
@ -85,4 +87,8 @@ public class ImplementNetworkVspCommand extends Command {
.append("dhcpOption", _dhcpOption)
.toString();
}
public boolean isVsdManaged() {
return _isVsdManaged;
}
}

View File

@ -20,6 +20,7 @@
package com.cloud.agent.api.manager;
import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
import net.nuage.vsp.acs.client.api.model.VspNetwork;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.guru.ImplementNetworkVspCommand;
@ -30,8 +31,11 @@ import com.cloud.agent.api.guru.ImplementNetworkVspCommand;
public class ImplementNetworkVspAnswer extends Answer {
private NetworkRelatedVsdIds networkRelatedVsdIds;
public ImplementNetworkVspAnswer(ImplementNetworkVspCommand command, NetworkRelatedVsdIds networkRelatedVsdIds) {
private VspNetwork vspNetwork;
public ImplementNetworkVspAnswer(ImplementNetworkVspCommand command, VspNetwork vspNetwork, NetworkRelatedVsdIds networkRelatedVsdIds) {
super(command);
this.vspNetwork = vspNetwork;
this.networkRelatedVsdIds = networkRelatedVsdIds;
}
@ -42,4 +46,8 @@ public class ImplementNetworkVspAnswer extends Answer {
public NetworkRelatedVsdIds getNetworkRelatedVsdIds() {
return networkRelatedVsdIds;
}
public VspNetwork getVspNetwork() {
return vspNetwork;
}
}

View File

@ -507,7 +507,6 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
return true;
}
@Override
public boolean applyStaticNats(Network config, List<? extends StaticNat> rules) throws ResourceUnavailableException {
List<VspStaticNat> vspStaticNatDetails = new ArrayList<VspStaticNat>();
@ -687,6 +686,8 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
preConfiguredDomainTemplateName = _configDao.getValue(NuageVspManager.NuageVspVpcDomainTemplateName.key());
}
Map<String, String> vpcDetails = _vpcDetailsDao.listDetailsKeyPairs(vpc.getId(), false);
cleanUpVpcCaching(vpc.getId());
//related to migration caching
List<? extends ResourceTag> vpcResourceDetails = _resourceTagDao.listByResourceUuid(vpc.getUuid());
@ -698,7 +699,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider
.ifPresent(this::cleanUpVpcCaching);
}
ShutDownVpcVspCommand cmd = new ShutDownVpcVspCommand(vpcDomain.getUuid(), vpc.getUuid(), preConfiguredDomainTemplateName, domainRouterUuids);
ShutDownVpcVspCommand cmd = new ShutDownVpcVspCommand(vpcDomain.getUuid(), vpc.getUuid(), preConfiguredDomainTemplateName, domainRouterUuids, vpcDetails);
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
s_logger.error("ShutDownVpcVspCommand for VPC " + vpc.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));

View File

@ -58,7 +58,9 @@ import com.cloud.agent.api.manager.ImplementNetworkVspAnswer;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.DataCenterDetailVO;
import com.cloud.dc.VlanVO;
import com.cloud.dc.dao.DataCenterDetailsDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.domain.dao.DomainDao;
@ -67,7 +69,6 @@ import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapacityException;
import com.cloud.exception.UnsupportedServiceException;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.network.Network;
import com.cloud.network.Network.GuestType;
import com.cloud.network.Network.State;
@ -76,13 +77,10 @@ import com.cloud.network.Networks;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetwork.IsolationMethod;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.NetworkDetailVO;
import com.cloud.network.dao.NetworkDetailsDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.NuageVspDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.network.manager.NuageVspManager;
import com.cloud.network.vpc.dao.VpcDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
@ -92,6 +90,7 @@ import com.cloud.user.dao.AccountDao;
import com.cloud.util.NuageVspEntityBuilder;
import com.cloud.utils.StringUtils;
import com.cloud.utils.db.DB;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.Ip;
import com.cloud.vm.Nic;
import com.cloud.vm.NicProfile;
@ -102,7 +101,7 @@ import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.dao.VMInstanceDao;
public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
public class NuageVspGuestNetworkGuru extends GuestNetworkGuru implements NetworkGuruAdditionalFunctions {
public static final Logger s_logger = Logger.getLogger(NuageVspGuestNetworkGuru.class);
@Inject
@ -114,12 +113,6 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
@Inject
AccountDao _accountDao;
@Inject
NuageVspDao _nuageVspDao;
@Inject
HostDao _hostDao;
@Inject
VpcDao _vpcDao;
@Inject
VMInstanceDao _vmInstanceDao;
@Inject
AgentManager _agentMgr;
@ -135,6 +128,8 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
VpcDetailsDao _vpcDetailsDao;
@Inject
NetworkOrchestrationService _networkOrchestrationService;
@Inject
DataCenterDetailsDao _dcDetailsDao;
public NuageVspGuestNetworkGuru() {
super();
@ -158,10 +153,90 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
}
networkObject.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp);
if (userSpecified instanceof NetworkVO && userSpecified.getExternalId() != null) {
if (owner.getType() < Account.ACCOUNT_TYPE_ADMIN) {
throw new IllegalArgumentException("vsdManaged networks are only useable by admins.");
}
if (!isUniqueReference(plan.getDataCenterId(), userSpecified.getExternalId())) {
s_logger.debug("Refusing to design network. VsdManaged network object already present in zone.");
return null;
}
}
return networkObject;
}
private boolean isUniqueReference(long dataCenterId, String vsdSubnetId) {
DataCenterDetailVO detail = _dcDetailsDao.findDetail(dataCenterId, vsdSubnetId);
return detail == null;
}
private boolean isVsdManagedVpc(long vpcId) {
//Check if it's a vpc and if the vpc is already vsdManaged OR if it has 0 tiers
Map<String, String> vpcDetails = _vpcDetailsDao.listDetailsKeyPairs(vpcId, false);
return vpcDetails.get(NuageVspManager.NETWORK_METADATA_VSD_MANAGED) != null && vpcDetails.get(NuageVspManager.NETWORK_METADATA_VSD_MANAGED).equals("true");
}
/** In case an externalId is specified, we get called here, and store the id the same way as cached data */
@Override
public void finalizeNetworkDesign(long networkId, String vlanIdAsUUID) {
NetworkVO designedNetwork = _networkDao.findById(networkId);
String externalId = designedNetwork.getExternalId();
boolean isVpc = designedNetwork.getVpcId() != null;
if (isVpc && _networkDao.listByVpc(designedNetwork.getVpcId()).size() > 1) {
boolean isVsdManagedVpc = isVsdManagedVpc(designedNetwork.getVpcId());
if (isVsdManagedVpc && externalId == null) {
throw new CloudRuntimeException("Refusing to design network. Network is vsdManaged but is part of a non vsd managed vpc.");
} else if (!isVsdManagedVpc && externalId != null) {
throw new CloudRuntimeException("Refusing to design network. Network is not vsdManaged but is part of a vsd managed vpc.");
}
}
if (externalId == null) {
return;
}
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(designedNetwork, externalId);
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(designedNetwork.getPhysicalNetworkId());
ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, null, true);
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
s_logger.error("ImplementNetworkVspCommand for network " + vspNetwork.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
if ((null != answer) && (null != answer.getDetails())) {
s_logger.error(answer.getDetails());
}
throw new CloudRuntimeException("ImplementNetworkVspCommand for network " + vspNetwork.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
}
//check if the network does not violate the uuid cidr
ImplementNetworkVspAnswer implementAnswer = (ImplementNetworkVspAnswer) answer;
VspNetwork updatedVspNetwork = implementAnswer.getVspNetwork();
NetworkVO forUpdate = _networkDao.createForUpdate(networkId);
if (isVpc && (!designedNetwork.getCidr().equals(updatedVspNetwork.getCidr()) || !designedNetwork.getGateway().equals(updatedVspNetwork.getGateway()))) {
throw new CloudRuntimeException("Tier network does not match the VsdManaged subnet cidr or gateway.");
} else {
forUpdate.setCidr(updatedVspNetwork.getCidr());
forUpdate.setGateway(updatedVspNetwork.getGateway());
}
saveNetworkAndVpcDetails(vspNetwork, implementAnswer.getNetworkRelatedVsdIds(), designedNetwork.getVpcId());
saveNetworkDetail(networkId, NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID, externalId);
saveNetworkDetail(networkId, NuageVspManager.NETWORK_METADATA_VSD_MANAGED, "true");
forUpdate.setState(State.Allocated);
_networkDao.update(networkId, forUpdate);
}
@Override
public Map<String, ? extends Object> listAdditionalNicParams(String nicUuid) {
return null;
}
@Override
public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapacityException {
long networkId = network.getId();
@ -213,7 +288,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
implemented = new NetworkVO(network.getId(), network, network.getNetworkOfferingId(), network.getGuruName(), network.getDomainId(), network.getAccountId(),
network.getRelated(), network.getName(), network.getDisplayText(), network.getNetworkDomain(), network.getGuestType(), network.getDataCenterId(),
physicalNetworkId, network.getAclType(), network.getSpecifyIpRanges(), network.getVpcId(), offering.getRedundantRouter());
physicalNetworkId, network.getAclType(), network.getSpecifyIpRanges(), network.getVpcId(), offering.getRedundantRouter(), network.getExternalId());
implemented.setUuid(network.getUuid());
implemented.setState(State.Allocated);
if (network.getGateway() != null) {
@ -229,7 +304,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
implemented.setBroadcastUri(Networks.BroadcastDomainType.Vsp.toUri(broadcastUriStr));
implemented.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp);
boolean implementSucceeded = implement(network.getVpcId(), physicalNetworkId, vspNetwork, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering));
boolean implementSucceeded = implement(network.getVpcId(), physicalNetworkId, vspNetwork, implemented, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering));
if (!implementSucceeded) {
return null;
@ -237,11 +312,9 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
if (StringUtils.isNotBlank(vspNetwork.getDomainTemplateName())) {
if (network.getVpcId() != null) {
VpcDetailVO vpcDetail = new VpcDetailVO(network.getVpcId(), NuageVspManager.nuageDomainTemplateDetailName, vspNetwork.getDomainTemplateName(), false);
_vpcDetailsDao.persist(vpcDetail);
saveVpcDetail(network.getVpcId(), NuageVspManager.nuageDomainTemplateDetailName, vspNetwork.getDomainTemplateName());
} else {
NetworkDetailVO networkDetail = new NetworkDetailVO(implemented.getId(), NuageVspManager.nuageDomainTemplateDetailName, vspNetwork.getDomainTemplateName(), false);
_networkDetailsDao.persist(networkDetail);
saveNetworkDetail(implemented.getId(), NuageVspManager.nuageDomainTemplateDetailName, vspNetwork.getDomainTemplateName());
}
}
@ -252,10 +325,19 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
return implemented;
}
private boolean implement(Long vpcId, long physicalNetworkId, VspNetwork vspNetwork, VspDhcpDomainOption vspDhcpDomainOption) {
private boolean implement(Long vpcId, long physicalNetworkId, VspNetwork vspNetwork, NetworkVO implemented, VspDhcpDomainOption vspDhcpDomainOption) {
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(physicalNetworkId);
ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, vspDhcpDomainOption);
ImplementNetworkVspAnswer answer = (ImplementNetworkVspAnswer) _agentMgr.easySend(nuageVspHost.getId(), cmd);
final boolean isVsdManaged = vspNetwork.getNetworkRelatedVsdIds()
.getVsdSubnetId()
.isPresent();
if (isVsdManaged) {
//Implement cmd was already send in design step.
_dcDetailsDao.persist(implemented.getDataCenterId(), vspNetwork.getNetworkRelatedVsdIds().getVsdSubnetId().orElseThrow(() -> new CloudRuntimeException("Managed but no subnetId. How can this happen?")), implemented.getUuid());
return true;
}
ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, vspDhcpDomainOption, false);
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);
if (answer == null || !answer.getResult()) {
s_logger.error("ImplementNetworkVspCommand for network " + vspNetwork.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname"));
if ((null != answer) && (null != answer.getDetails())) {
@ -263,7 +345,9 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
}
return false;
}
saveNetworkAndVpcDetails(vspNetwork, answer.getNetworkRelatedVsdIds(), vpcId);
ImplementNetworkVspAnswer implementAnswer = (ImplementNetworkVspAnswer) answer;
saveNetworkAndVpcDetails(vspNetwork, implementAnswer.getNetworkRelatedVsdIds(), vpcId);
return true;
}
@ -274,23 +358,31 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
long networkId = vspNetwork.getId();
for (Map.Entry<String, String> networkDetail : networkDetails.entrySet()) {
_networkDetailsDao.addDetail(networkId, networkDetail.getKey(), networkDetail.getValue(), false);
saveNetworkDetail(vspNetwork.getId(), networkDetail.getKey(), networkDetail.getValue());
}
if(vspNetwork.isVpc()) {
Map<String, String> vpcDetails = constructVpcDetails(networkRelatedVsdIds);
for (Map.Entry<String, String> vpcDetail : vpcDetails.entrySet()) {
_vpcDetailsDao.addDetail(vpcId, vpcDetail.getKey(), vpcDetail.getValue(), false);
saveVpcDetail(vpcId, vpcDetail.getKey(), vpcDetail.getValue());
}
}
}
}
private void saveVpcDetail(Long vpcId, String key, String value) {
_vpcDetailsDao.addDetail(vpcId, key, value, false);
}
private void saveNetworkDetail(long networkId, String key, String value) {
_networkDetailsDao.addDetail(networkId, key, value, false);
}
private static Map<String, String> constructNetworkDetails(NetworkRelatedVsdIds networkRelatedVsdIds, boolean isVpc) {
Map<String, String> networkDetails = Maps.newHashMap();
if(!isVpc) {
if (!isVpc) {
networkRelatedVsdIds.getVsdDomainId().ifPresent(v -> networkDetails.put(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID, v));
networkRelatedVsdIds.getVsdZoneId().ifPresent(v -> networkDetails.put(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID, v));
}
@ -304,6 +396,9 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
networkRelatedVsdIds.getVsdDomainId().ifPresent(v -> vpcDetails.put(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID, v));
networkRelatedVsdIds.getVsdZoneId().ifPresent(v -> vpcDetails.put(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID, v));
if (networkRelatedVsdIds.isVsdManaged()) {
vpcDetails.put(NuageVspManager.NETWORK_METADATA_VSD_MANAGED, "true");
}
return vpcDetails;
}
@ -355,7 +450,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
if (vm.getType() == VirtualMachine.Type.DomainRouter && vspNetwork.getVirtualRouterIp().equals("null")) {
//In case of upgrade network offering
vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(vm.getVirtualMachine().getDomainId(), network, true);
vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(vm.getVirtualMachine().getDomainId(), network, null, true);
String broadcastUriStr = network.getUuid() + "/" + vspNetwork.getVirtualRouterIp();
NetworkVO updatedNetwork = _networkDao.createForUpdate(network.getId());
updatedNetwork.setBroadcastUri(Networks.BroadcastDomainType.Vsp.toUri(broadcastUriStr));
@ -381,7 +476,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
// Make sure the shared network is present
NetworkOffering offering = _ntwkOfferingDao.findById(network.getNetworkOfferingId());
if (!implement(network.getVpcId(), network.getPhysicalNetworkId(), vspNetwork, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering))) {
if (!implement(network.getVpcId(), network.getPhysicalNetworkId(), vspNetwork, null, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering))) {
s_logger.error("Failed to implement shared network " + network.getUuid() + " under domain " + context.getDomain().getUuid());
throw new InsufficientVirtualNetworkCapacityException("Failed to implement shared network " + network.getUuid() + " under domain " +
context.getDomain().getUuid(), Network.class, network.getId());
@ -643,6 +738,15 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru {
}
VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network);
//Clean up VSD managed subnet caching
if (vspNetwork.getNetworkRelatedVsdIds().isVsdManaged()) {
final long dataCenterId = network.getDataCenterId();
vspNetwork.getNetworkRelatedVsdIds().getVsdSubnetId().ifPresent(subnetId -> {
_dcDetailsDao.removeDetail(dataCenterId, subnetId);
});
}
HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId());
TrashNetworkVspCommand cmd = new TrashNetworkVspCommand(vspNetwork);
Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd);

View File

@ -19,6 +19,11 @@
package com.cloud.network.manager;
import java.util.List;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
import com.cloud.agent.api.manager.EntityExistsCommand;
import com.cloud.api.commands.AddNuageVspDeviceCmd;
import com.cloud.api.commands.AssociateNuageVspDomainTemplateCmd;
@ -35,12 +40,8 @@ import com.cloud.network.Network;
import com.cloud.network.NuageVspDeviceVO;
import com.cloud.utils.component.PluggableService;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.ConfigKey.Scope;
import java.util.List;
public interface NuageVspManager extends PluggableService {
String nuageVspSharedNetworkOfferingWithSGServiceName = "DefaultNuageVspSharedNetworkOfferingWithSGService";
@ -86,6 +87,8 @@ public interface NuageVspManager extends PluggableService {
String NETWORK_METADATA_VSD_SUBNET_ID = "vsdSubnetId";
String NETWORK_METADATA_VSD_MANAGED = "isVsdManaged";
String CMSID_CONFIG_KEY = "nuagevsp.cms.id";
String NUAGE_VSP_ISOLATION = "VSP";

View File

@ -241,6 +241,16 @@ public class NuageVspResource extends ManagerBase implements ServerResource, Vsp
return pingNuageVspCommand;
}
public boolean getStatus() {
try {
login();
return true;
} catch (NuageVspException | ConfigurationException e) {
s_logger.error("Failed to ping to Nuage VSD on " + _name + " as user " +_vspHost.getCmsUserLogin(), e);
return false;
}
}
@Override
public Answer executeRequest(final Command cmd) {
final NuageVspRequestWrapper wrapper = NuageVspRequestWrapper.getInstance();

View File

@ -0,0 +1,43 @@
//
// 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 com.cloud.network.vsp.resource.wrapper;
import javax.naming.ConfigurationException;
import net.nuage.vsp.acs.client.exception.NuageVspException;
import com.cloud.agent.api.CheckHealthCommand;
import com.cloud.network.resource.NuageVspResource;
import com.cloud.resource.ResourceWrapper;
@ResourceWrapper(handles = CheckHealthCommand.class)
public class NuageVspCheckHealthCommandWrapper extends NuageVspCommandWrapper<CheckHealthCommand> {
@Override
public boolean executeNuageVspCommand(CheckHealthCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException {
return nuageVspResource.getStatus();
}
@Override
public StringBuilder fillDetail(StringBuilder stringBuilder, CheckHealthCommand cmd) {
return stringBuilder.append("Check Health");
}
}

View File

@ -45,7 +45,7 @@ public abstract class NuageVspCommandWrapper<T extends Command> extends CommandW
} catch (NuageVspUnsupportedRequestException e) {
s_logger.error("Failure during " + command + " on " + nuageVspResource.getName(), e);
return new UnsupportedAnswer(command, e.getMessage()); //New Exception so there is no stacktrace showed in the UI when changing ACL lists.
} catch (NuageVspException | ConfigurationException e) {
} catch (Exception e) {
s_logger.error("Failure during " + command + " on " + nuageVspResource.getName(), e);
return new Answer(command, e);
}

View File

@ -19,11 +19,9 @@
package com.cloud.network.vsp.resource.wrapper;
import javax.naming.ConfigurationException;
import net.nuage.vsp.acs.client.api.NuageVspGuruClient;
import net.nuage.vsp.acs.client.api.model.NetworkRelatedVsdIds;
import net.nuage.vsp.acs.client.exception.NuageVspException;
import net.nuage.vsp.acs.client.api.model.VspNetwork;
import com.cloud.agent.api.guru.ImplementNetworkVspCommand;
import com.cloud.agent.api.manager.ImplementNetworkVspAnswer;
@ -38,9 +36,14 @@ public final class NuageVspGuruImplementNetworkCommandWrapper extends CommandWra
public ImplementNetworkVspAnswer execute(ImplementNetworkVspCommand command, NuageVspResource serverResource) {
try {
NuageVspGuruClient client = serverResource.getNuageVspGuruClient();
NetworkRelatedVsdIds networkRelatedVsdIds = client.implement(command.getNetwork(), command.getDhcpOption());
return new ImplementNetworkVspAnswer(command, networkRelatedVsdIds);
} catch (ConfigurationException | NuageVspException e) {
if (command.isVsdManaged()) {
VspNetwork vspNetwork = client.addPermissionL3Network(command.getNetwork());
return new ImplementNetworkVspAnswer(command, vspNetwork, vspNetwork.getNetworkRelatedVsdIds());
} else {
NetworkRelatedVsdIds networkRelatedVsdIds = client.implement(command.getNetwork(), command.getDhcpOption());
return new ImplementNetworkVspAnswer(command, command.getNetwork(), networkRelatedVsdIds);
}
} catch (Exception e) {
return new ImplementNetworkVspAnswer(command, e);
}
}

View File

@ -31,7 +31,7 @@ import com.cloud.resource.ResourceWrapper;
public final class NuageVspShutdownVpcCommandWrapper extends NuageVspCommandWrapper<ShutDownVpcVspCommand> {
@Override public boolean executeNuageVspCommand(ShutDownVpcVspCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException {
nuageVspResource.getNuageVspElementClient().shutdownVpc(cmd.getDomainUuid(), cmd.getVpcUuid(), cmd.getDomainTemplateName(), cmd.getDomainRouterUuids());
nuageVspResource.getNuageVspElementClient().shutdownVpc(cmd.getDomainUuid(), cmd.getVpcUuid(), cmd.getDomainTemplateName(), cmd.getDomainRouterUuids(), cmd.getRelatedVsdIds());
return true;
}

View File

@ -43,6 +43,7 @@ import net.nuage.vsp.acs.client.api.model.VspStaticNat;
import net.nuage.vsp.acs.client.api.model.VspVm;
import net.nuage.vsp.acs.client.common.model.Pair;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
@ -50,7 +51,7 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
import com.cloud.dc.Vlan;
import com.cloud.dc.VlanVO;
@ -88,8 +89,6 @@ import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.NicSecondaryIpDao;
import com.cloud.vm.dao.NicSecondaryIpVO;
import com.cloud.vm.dao.VMInstanceDao;
import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao;
import org.apache.commons.collections.MapUtils;
public class NuageVspEntityBuilder {
private static final Logger s_logger = Logger.getLogger(NuageVspEntityBuilder.class);
@ -113,8 +112,6 @@ public class NuageVspEntityBuilder {
@Inject
VlanDetailsDao _vlanDetailsDao;
@Inject
ConfigurationDao _configurationDao;
@Inject
IPAddressDao _ipAddressDao;
@Inject
NetworkDetailsDao _networkDetailsDao;
@ -160,18 +157,30 @@ public class NuageVspEntityBuilder {
}
public VspNetwork buildVspNetwork(Network network) {
return buildVspNetwork(network.getDomainId(), network, false);
}
public VspNetwork buildVspNetwork(long domainId, Network network) {
return buildVspNetwork(domainId, network, false);
return buildVspNetwork(network.getDomainId(), network, null, false);
}
public VspNetwork buildVspNetwork(Network network, boolean recalculateBroadcastUri) {
return buildVspNetwork(network.getDomainId(), network, recalculateBroadcastUri);
return buildVspNetwork(network.getDomainId(), network, null, recalculateBroadcastUri);
}
public VspNetwork buildVspNetwork(Network network, String vsdSubnetId) {
return buildVspNetwork(network.getDomainId(), network, vsdSubnetId, false);
}
public VspNetwork buildVspNetwork(long domainId, Network network) {
return buildVspNetwork(domainId, network, null, false);
}
public VspNetwork buildVspNetwork(long domainId, Network network, boolean recalculateBroadcastUri) {
return buildVspNetwork(domainId, network, null, recalculateBroadcastUri);
}
public VspNetwork buildVspNetwork(long domainId, Network network, String vsdSubnetId) {
return buildVspNetwork(domainId, network, vsdSubnetId, false);
}
public VspNetwork buildVspNetwork(long domainId, Network network, String vsdSubnetId, boolean recalculateBroadcastUri) {
VspNetwork.Builder vspNetworkBuilder = new VspNetwork.Builder()
.id(network.getId())
.uuid(network.getUuid())
@ -183,21 +192,26 @@ public class NuageVspEntityBuilder {
VspDomain vspDomain = buildVspDomain(domain);
vspNetworkBuilder.domain(vspDomain);
AccountVO account = _accountDao.findById(network.getAccountId());
if (account != null) {
vspNetworkBuilder.accountUuid(account.getUuid()).accountName(account.getAccountName());
}
NetworkOfferingVO networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
vspNetworkBuilder.egressDefaultPolicy(networkOffering.getEgressDefaultPolicy()).publicAccess(networkOffering.getSupportsPublicAccess());
vspNetworkBuilder.egressDefaultPolicy(networkOffering.getEgressDefaultPolicy())
.publicAccess(networkOffering.getSupportsPublicAccess());
Map<String, String> networkDetails = _networkDetailsDao.listDetailsKeyPairs(network.getId(), false);
String vsdSubnetId = null;
String vsdZoneId = null;
String vsdDomainId = null;
final NetworkRelatedVsdIds.Builder relatedVsdIdsBuilder = new NetworkRelatedVsdIds.Builder();
if (MapUtils.isNotEmpty(networkDetails)) {
vsdSubnetId = networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID);
relatedVsdIdsBuilder.vsdSubnetId(networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_SUBNET_ID))
.withVsdManaged("true".equals(networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_MANAGED)));
} else if (vsdSubnetId != null) {
relatedVsdIdsBuilder.vsdSubnetId(vsdSubnetId)
.withVsdManaged("true".equals(networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_MANAGED)));
}
if (network.getVpcId() != null) {
@ -207,16 +221,9 @@ public class NuageVspEntityBuilder {
.vpcName(vpc.getName())
.networkType(VspNetwork.NetworkType.Vpc);
Map<String, String> vpcDetails = _vpcDetailsDao.listDetailsKeyPairs(vpcId, false);
if (MapUtils.isNotEmpty(vpcDetails)) {
vsdDomainId = vpcDetails.get(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID);
vsdZoneId = vpcDetails.get(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID);
}
applyDomainAndZoneId(relatedVsdIdsBuilder, vpcDetails);
} else {
if (MapUtils.isNotEmpty(networkDetails)) {
vsdDomainId = networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID);
vsdZoneId = networkDetails.get(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID);
}
applyDomainAndZoneId(relatedVsdIdsBuilder, networkDetails);
if (networkOffering.getGuestType() == Network.GuestType.Shared) {
List<VlanVO> vlans = _vlanDao.listVlansByNetworkIdIncludingRemoved(network.getId());
@ -238,11 +245,7 @@ public class NuageVspEntityBuilder {
}
NetworkRelatedVsdIds networkRelatedVsdIds = new NetworkRelatedVsdIds.Builder()
.vsdDomainId(vsdDomainId)
.vsdSubnetId(vsdSubnetId)
.vsdZoneId(vsdZoneId)
.build();
NetworkRelatedVsdIds networkRelatedVsdIds = relatedVsdIdsBuilder.build();
vspNetworkBuilder.networkRelatedVsdIds(networkRelatedVsdIds);
boolean firewallServiceSupported = _networkModel.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.Firewall);
@ -266,6 +269,14 @@ public class NuageVspEntityBuilder {
return vspNetworkBuilder.build();
}
private void applyDomainAndZoneId(NetworkRelatedVsdIds.Builder relatedVsdIdsBuilder, Map<String, String> details) {
if (MapUtils.isNotEmpty(details)) {
relatedVsdIdsBuilder
.vsdDomainId(details.get(NuageVspManager.NETWORK_METADATA_VSD_DOMAIN_ID))
.vsdZoneId(details.get(NuageVspManager.NETWORK_METADATA_VSD_ZONE_ID));
}
}
public boolean usesVirtualRouter(long networkOfferingId) {
return _networkOfferingServiceMapDao.isProviderForNetworkOffering(networkOfferingId, Network.Provider.VirtualRouter) ||
_networkOfferingServiceMapDao.isProviderForNetworkOffering(networkOfferingId, Network.Provider.VPCVirtualRouter);

View File

@ -146,7 +146,6 @@ public class NuageTest {
return new NetworkRelatedVsdIds.Builder()
.vsdZoneId("vsdZoneId")
.vsdDomainId("vsdDomainId")
.vsdEnterpriseId("vsdEnterpriseId")
.vsdSubnetId("vsdSubnetId")
.build();
}

View File

@ -31,6 +31,7 @@ import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.internal.util.collections.Sets;
import org.mockito.invocation.InvocationOnMock;
import com.google.common.collect.ImmutableMap;
@ -45,6 +46,7 @@ import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.DataCenterDetailsDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.domain.Domain;
@ -110,6 +112,7 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest {
@Mock private IPAddressDao _ipAddressDao;
@Mock private NuageVspManager _nuageVspManager;
@Mock private ConfigurationManager _configurationManager;
@Mock private DataCenterDetailsDao _dcDetailsDao;
@Mock private NetworkDetailsDao _networkDetailsDao;
@Mock private PhysicalNetworkVO physnet;
@ -138,7 +141,7 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest {
when(_hostDao.findById(NETWORK_ID)).thenReturn(host);
when(host.getId()).thenReturn(NETWORK_ID);
when(_agentManager.easySend(eq(NETWORK_ID), any(Command.class))).thenReturn(new Answer(null));
when(_agentManager.easySend(eq(NETWORK_ID), any(ImplementNetworkVspCommand.class))).thenReturn(new ImplementNetworkVspAnswer(null, new NetworkRelatedVsdIds.Builder().build()));
when(_agentManager.easySend(eq(NETWORK_ID), any(ImplementNetworkVspCommand.class))).thenAnswer(this::mockImplement);
when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host);
final NuageVspDeviceVO device = mock(NuageVspDeviceVO.class);
@ -147,6 +150,15 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest {
when(device.getHostId()).thenReturn(NETWORK_ID);
}
Answer mockImplement(InvocationOnMock invocation) {
if (invocation.getArguments()[1] instanceof ImplementNetworkVspCommand) {
ImplementNetworkVspCommand command = (ImplementNetworkVspCommand)(invocation.getArguments()[1]);
return new ImplementNetworkVspAnswer(command, command.getNetwork(), new NetworkRelatedVsdIds.Builder().build());
} else {
return new Answer(null);
}
}
@Test
public void testCanHandle() {
final NetworkOffering offering = mock(NetworkOffering.class);

View File

@ -20,6 +20,7 @@
package com.cloud.network.resource;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -152,12 +153,25 @@ public class NuageVspResourceTest extends NuageTest {
VspNetwork vspNetwork = buildVspNetwork();
VspDhcpDomainOption vspDhcpOptions = buildspDhcpDomainOption();
ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, vspDhcpOptions);
ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, vspDhcpOptions, false);
ImplementNetworkVspAnswer implNtwkAns = (ImplementNetworkVspAnswer)_resource.executeRequest(cmd);
assertTrue(implNtwkAns.getResult());
verify(_mockNuageVspGuruClient).implement(vspNetwork, vspDhcpOptions);
}
@Test
public void testImplementVsdManagedNetworkVspCommand() throws Exception {
_resource.configure("NuageVspResource", _hostDetails);
VspNetwork vspNetwork = buildVspNetwork();
VspDhcpDomainOption vspDhcpOptions = buildspDhcpDomainOption();
when(_mockNuageVspGuruClient.addPermissionL3Network(vspNetwork)).thenReturn(vspNetwork);
ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, vspDhcpOptions, true);
ImplementNetworkVspAnswer implNtwkAns = (ImplementNetworkVspAnswer)_resource.executeRequest(cmd);
assertTrue(implNtwkAns.getResult());
verify(_mockNuageVspGuruClient).addPermissionL3Network(vspNetwork);
}
@Test
public void testReserveVmInterfaceVspCommand() throws Exception {
_resource.configure("NuageVspResource", _hostDetails);
@ -220,7 +234,7 @@ public class NuageVspResourceTest extends NuageTest {
public void testShutDownVpcVspCommand() throws Exception {
_resource.configure("NuageVspResource", _hostDetails);
ShutDownVpcVspCommand cmd = new ShutDownVpcVspCommand("domainUuid", "vpcUuid", "domainTemplateName", Lists.<String>newArrayList());
ShutDownVpcVspCommand cmd = new ShutDownVpcVspCommand("domainUuid", "vpcUuid", "domainTemplateName", Lists.<String>newArrayList(), new HashMap<>());
Answer shutVpcAns = _resource.executeRequest(cmd);
assertTrue(shutVpcAns.getResult());
}

View File

@ -2206,6 +2206,7 @@ public class ApiResponseHelper implements ResponseGenerator {
}
response.setNetworkSpannedZones(networkSpannedZones);
}
response.setExternalId(network.getExternalId());
response.setObjectName("network");
return response;
}

View File

@ -1662,7 +1662,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId()
+ " as a part of createVlanIpRange process");
guestNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName()
+ "-network", null, null, null, false, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null);
+ "-network", null, null, null, false, null, owner, null, physicalNetwork, zoneId, ACLType.Account, null, null, null, null, true, null, null);
if (guestNetwork == null) {
s_logger.warn("Failed to create default Virtual network for the account " + accountId + "in zone " + zoneId);
throw new CloudRuntimeException("Failed to create a Guest Isolated Networks with SourceNAT "

View File

@ -103,6 +103,7 @@ import com.cloud.network.dao.AccountGuestVlanMapVO;
import com.cloud.network.dao.FirewallRulesDao;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.LoadBalancerDao;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkDetailVO;
import com.cloud.network.dao.NetworkDetailsDao;
@ -192,7 +193,6 @@ import com.cloud.vm.dao.NicSecondaryIpDao;
import com.cloud.vm.dao.NicSecondaryIpVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
import com.cloud.network.dao.LoadBalancerDao;
/**
* NetworkServiceImpl implements NetworkService.
@ -1031,6 +1031,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
Boolean displayNetwork = cmd.getDisplayNetwork();
Long aclId = cmd.getAclId();
String isolatedPvlan = cmd.getIsolatedPvlan();
String externalId = cmd.getExternalId();
// Validate network offering
NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
@ -1292,7 +1293,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
Network network = commitNetwork(networkOfferingId, gateway, startIP, endIP, netmask, networkDomain, vlanId, bypassVlanOverlapCheck, name, displayText, caller, physicalNetworkId, zoneId, domainId,
isDomainSpecific, subdomainAccess, vpcId, startIPv6, endIPv6, ip6Gateway, ip6Cidr, displayNetwork, aclId, isolatedPvlan, ntwkOff, pNtwk, aclType, owner, cidr,
createVlan);
createVlan, externalId);
// if the network offering has persistent set to true, implement the network
if (ntwkOff.getIsPersistent()) {
@ -1325,7 +1326,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
final String vlanId, final Boolean bypassVlanOverlapCheck, final String name, final String displayText, final Account caller, final Long physicalNetworkId, final Long zoneId, final Long domainId,
final boolean isDomainSpecific, final Boolean subdomainAccessFinal, final Long vpcId, final String startIPv6, final String endIPv6, final String ip6Gateway,
final String ip6Cidr, final Boolean displayNetwork, final Long aclId, final String isolatedPvlan, final NetworkOfferingVO ntwkOff, final PhysicalNetwork pNtwk,
final ACLType aclType, final Account ownerFinal, final String cidr, final boolean createVlan) throws InsufficientCapacityException, ResourceAllocationException {
final ACLType aclType, final Account ownerFinal, final String cidr, final boolean createVlan, final String externalId) throws InsufficientCapacityException, ResourceAllocationException {
try {
Network network = Transaction.execute(new TransactionCallbackWithException<Network, Exception>() {
@Override
@ -1370,7 +1371,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
}
network = _vpcMgr.createVpcGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, networkDomain, owner, sharedDomainId, pNtwk, zoneId,
aclType, subdomainAccess, vpcId, aclId, caller, displayNetwork);
aclType, subdomainAccess, vpcId, aclId, caller, displayNetwork, externalId);
} else {
if (_configMgr.isOfferingForVpc(ntwkOff)) {
throw new InvalidParameterValueException("Network offering can be used for VPC networks only");
@ -1380,7 +1381,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
}
network = _networkMgr.createGuestNetwork(networkOfferingId, name, displayText, gateway, cidr, vlanId, bypassVlanOverlapCheck, networkDomain, owner, sharedDomainId, pNtwk, zoneId,
aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan);
aclType, subdomainAccess, vpcId, ip6Gateway, ip6Cidr, displayNetwork, isolatedPvlan, externalId);
}
if (_accountMgr.isRootAdmin(caller.getId()) && createVlan && network != null) {
@ -4335,7 +4336,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService {
if (privateNetwork == null) {
//create Guest network
privateNetwork = _networkMgr.createGuestNetwork(ntwkOffFinal.getId(), networkName, displayText, gateway, cidr, uriString, false, null, owner, null, pNtwk,
pNtwk.getDataCenterId(), ACLType.Account, null, vpcId, null, null, true, null);
pNtwk.getDataCenterId(), ACLType.Account, null, vpcId, null, null, true, null, null);
if (privateNetwork != null) {
s_logger.debug("Successfully created guest network " + privateNetwork);
} else {

View File

@ -38,6 +38,9 @@ import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.apache.cloudstack.acl.ControlledEntity.ACLType;
import org.apache.cloudstack.api.command.user.vpc.ListPrivateGatewaysCmd;
import org.apache.cloudstack.api.command.user.vpc.ListStaticRoutesCmd;
@ -45,8 +48,6 @@ import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import com.cloud.configuration.Config;
import com.cloud.configuration.Resource.ResourceType;
@ -2316,7 +2317,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
@Override
public Network createVpcGuestNetwork(final long ntwkOffId, final String name, final String displayText, final String gateway, final String cidr, final String vlanId,
String networkDomain, final Account owner, final Long domainId, final PhysicalNetwork pNtwk, final long zoneId, final ACLType aclType, final Boolean subdomainAccess,
final long vpcId, final Long aclId, final Account caller, final Boolean isDisplayNetworkEnabled) throws ConcurrentOperationException, InsufficientCapacityException,
final long vpcId, final Long aclId, final Account caller, final Boolean isDisplayNetworkEnabled, String externalId) throws ConcurrentOperationException, InsufficientCapacityException,
ResourceAllocationException {
final Vpc vpc = getActiveVpc(vpcId);
@ -2341,7 +2342,7 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
// 2) Create network
final Network guestNetwork = _ntwkMgr.createGuestNetwork(ntwkOffId, name, displayText, gateway, cidr, vlanId, false, networkDomain, owner, domainId, pNtwk, zoneId, aclType,
subdomainAccess, vpcId, null, null, isDisplayNetworkEnabled, null);
subdomainAccess, vpcId, null, null, isDisplayNetworkEnabled, null, externalId);
if (guestNetwork != null) {
guestNetwork.setNetworkACLId(aclId);

View File

@ -3156,7 +3156,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
s_logger.debug("Creating network for account " + owner + " from the network offering id=" + requiredOfferings.get(0).getId() + " as a part of deployVM process");
Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), owner.getAccountName() + "-network", owner.getAccountName() + "-network",
null, null, null, false, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null);
null, null, null, false, null, owner, null, physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null, true, null,
null);
if (newNetwork != null) {
defaultNetwork = _networkDao.findById(newNetwork.getId());
}
@ -5795,8 +5796,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
s_logger.debug("Creating network for account " + newAccount + " from the network offering id=" + requiredOfferings.get(0).getId()
+ " as a part of deployVM process");
Network newNetwork = _networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(), newAccount.getAccountName() + "-network",
newAccount.getAccountName() + "-network", null, null, null, false, null, newAccount, null, physicalNetwork, zone.getId(), ACLType.Account, null, null,
null, null, true, null);
newAccount.getAccountName() + "-network", null, null, null, false, null, newAccount,
null, physicalNetwork, zone.getId(), ACLType.Account, null, null,
null, null, true, null, null);
// if the network offering has persistent set to true, implement the network
if (requiredOfferings.get(0).getIsPersistent()) {
DeployDestination dest = new DeployDestination(zone, null, null, null);

View File

@ -122,8 +122,8 @@ public class CreatePrivateNetworkTest {
ACLType.Account, false, 1L, false);
when(
networkService._networkMgr.createGuestNetwork(eq(ntwkOff.getId()), eq("bla"), eq("fake"), eq("10.1.1.1"), eq("10.1.1.0/24"), anyString(), anyBoolean(), anyString(),
eq(account), anyLong(), eq(physicalNetwork), eq(physicalNetwork.getDataCenterId()), eq(ACLType.Account), anyBoolean(), eq(1L), anyString(), anyString(),
anyBoolean(), anyString())).thenReturn(net);
eq(account), anyLong(), eq(physicalNetwork), eq(physicalNetwork.getDataCenterId()), eq(ACLType.Account), anyBoolean(), eq(1L), anyString(), anyString(),
anyBoolean(), anyString(), anyString())).thenReturn(net);
when(networkService._privateIpDao.findByIpAndSourceNetworkId(net.getId(), "10.1.1.2")).thenReturn(null);
when(networkService._privateIpDao.findByIpAndSourceNetworkIdAndVpcId(eq(1L), anyString(), eq(1L))).thenReturn(null);

View File

@ -638,7 +638,7 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkOrches
@Override
public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, String cidr, String vlanId, boolean bypassVlanOverlapCheck, String networkDomain,
Account owner, Long domainId, PhysicalNetwork physicalNetwork, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId, String gatewayv6,
String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan) throws ConcurrentOperationException, InsufficientCapacityException,
String cidrv6, Boolean displayNetworkEnabled, String isolatedPvlan, String externalId) throws ConcurrentOperationException, InsufficientCapacityException,
ResourceAllocationException {
// TODO Auto-generated method stub
return null;

View File

@ -387,7 +387,7 @@ class nuageTestCase(cloudstackTestCase):
@needscleanup
def create_Network(cls, nw_off, gateway="10.1.1.1",
netmask="255.255.255.0", vpc=None, acl_list=None,
testdata=None, account=None, vlan=None):
testdata=None, account=None, vlan=None, externalid=None):
if not account:
account = cls.account
cls.debug("Creating a network in the account - %s" % account.name)
@ -404,6 +404,7 @@ class nuageTestCase(cloudstackTestCase):
zoneid=cls.zone.id,
gateway=gateway,
vlan=vlan,
externalid=externalid,
vpcid=vpc.id if vpc else cls.vpc.id
if hasattr(cls, "vpc") else None,
aclid=acl_list.id if acl_list else None

View File

@ -0,0 +1,512 @@
# 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.
""" Component tests for VSP Managed Subnets functionality
with Nuage VSP SDN plugin
"""
# Import Local Modules
from nuageTestCase import nuageTestCase
from marvin.lib.base import (Account,
VirtualMachine)
from marvin.cloudstackAPI import updateZone
# Import System Modules
from nose.plugins.attrib import attr
import time
class TestNuageManagedSubnets(nuageTestCase):
"""Test Managed Subnets functionality with Nuage VSP SDN plugin
"""
@classmethod
def setUpClass(cls):
super(TestNuageManagedSubnets, cls).setUpClass()
# create a nuage vpc offering
cls.nuage_vpc_offering = \
cls.create_VpcOffering(cls.test_data["nuagevsp"]["vpc_offering"])
# tier network offerings
cls.nuage_vpc_network_offering = \
cls.create_NetworkOffering(cls.test_data["nuagevsp"]
["vpc_network_offering"])
# create a Nuage isolated network offering with vr
cls.nuage_isolated_network_offering = cls.create_NetworkOffering(
cls.test_data["nuagevsp"]["isolated_network_offering"], True)
# create a Nuage isolated network offering with vr and persistent
cls.nuage_isolated_network_offering_persistent = \
cls.create_NetworkOffering(
cls.test_data["nuagevsp"]
["isolated_network_offering_persistent"],
True)
# create a Nuage isolated network offering without vr
cls.nuage_isolated_network_offering_without_vr = \
cls.create_NetworkOffering(
cls.test_data["nuagevsp"]
["isolated_network_offering_without_vr"],
True)
# create a Nuage isolated network offering without vr but persistent
cls.nuage_isolated_network_offering_without_vr_persistent = \
cls.create_NetworkOffering(
cls.test_data["nuagevsp"]
["isolated_network_offering_without_vr_persistent"],
True)
# create a Nuage shared network offering
cls.nuage_shared_network_offering = cls.create_NetworkOffering(
cls.test_data["nuagevsp"]["shared_nuage_network_offering"],
False)
cls._cleanup = [
cls.nuage_isolated_network_offering,
cls.nuage_isolated_network_offering_persistent,
cls.nuage_isolated_network_offering_without_vr,
cls.nuage_isolated_network_offering_without_vr_persistent,
cls.nuage_vpc_offering,
cls.nuage_vpc_network_offering,
cls.nuage_shared_network_offering
]
return
def setUp(self):
# Create an account
self.account = Account.create(self.api_client,
self.test_data["account"],
admin=True,
domainid=self.domain.id
)
self.cleanup = [self.account]
return
def verify_pingtovmipaddress(self, ssh, pingtovmipaddress):
"""verify ping to ipaddress of the vm and retry 3 times"""
if self.isSimulator:
return
successfull_ping = False
nbr_retries = 0
max_retries = 5
cmd = 'ping -c 2 ' + pingtovmipaddress
while not successfull_ping and nbr_retries < max_retries:
self.debug("ping vm by ipaddress with command: " + cmd)
outputlist = ssh.execute(cmd)
self.debug("command is executed properly " + cmd)
completeoutput = str(outputlist).strip('[]')
self.debug("complete output is " + completeoutput)
if '2 received' in completeoutput:
self.debug("PASS as vm is pingeable: " + completeoutput)
successfull_ping = True
else:
self.debug("FAIL as vm is not pingeable: " + completeoutput)
time.sleep(3)
nbr_retries = nbr_retries + 1
if not successfull_ping:
self.fail("FAILED TEST as excepted value not found in vm")
def tearDown(self):
super(TestNuageManagedSubnets, self).tearDown()
# Cleanup resources used
self.debug("Cleaning up the resources")
for obj in reversed(self.cleanup):
try:
if isinstance(obj, VirtualMachine):
obj.delete(self.api_client, expunge=True)
else:
obj.delete(self.api_client)
except Exception as e:
self.error("Failed to cleanup %s, got %s" % (obj, e))
# cleanup_resources(self.api_client, self.cleanup)
self.cleanup = []
self.debug("Cloudstack Cleanup complete!")
enterprise = self.fetch_by_externalID(self._session.user.enterprises,
self.domain)
domain_template = enterprise.domain_templates.get_first()
domain_template.delete()
self.debug("VSD Cleanup complete!")
return
@attr(tags=["advanced", "nuagevsp", "isonw"], required_hardware="false")
def test_01_nuage_mngd_subnets_isonw(self):
"""Test Nuage VSP Managed Subnets for isolated networks
"""
# 1. Create multiple L3DomainTemplate with Zone and Subnet on VSP
# Create Ingress & Egress ACL Top & Bottom Templates
# Add ACL rules to allow intra-subnet traffic
# Instiantiate these L3Domains and store its Subnet VSD ID
# 2. Create a persistent and non persistent isolated network offering
# create offerings with and without VirtualRouter
# 3. Create isolated networks specifying above offerings and
# specifying the stored Subnet ID's of VSP
# 4. Verify ACL rules and connectivity via deploying VM's ,
# Enabling staticNAT, applying firewall and egress rules
# Create all items on vsd required for this test
enterprise = self.fetch_by_externalID(self._session.user.enterprises,
self.domain)
domain_template = self.create_vsd_domain_template(enterprise)
self.create_vsd_default_acls(domain_template)
domain1 = self.create_vsd_domain(domain_template, enterprise,
"L3DomainToBeConsumedByACS")
zone1 = self.create_vsd_zone(domain1, "ZoneToBeConsumedByACS")
subnet1 = self.create_vsd_subnet(zone1, "SubnetToBeConsumedByACS",
"10.0.0.1/24")
domain2 = self.create_vsd_domain(domain_template, enterprise,
"2ndL3DomainToBeConsumedByACS")
zone2 = self.create_vsd_zone(domain2, "2ndZoneToBeConsumedByACS")
subnet2 = self.create_vsd_subnet(zone2, "2ndSubnetToBeConsumedByACS",
"10.1.0.1/24")
domain3 = self.create_vsd_domain(domain_template, enterprise,
"3rdL3DomainToBeConsumedByACS")
zone3 = self.create_vsd_zone(domain3, "3rdZoneToBeConsumedByACS")
subnet3 = self.create_vsd_subnet(zone3, "3rdSubnetToBeConsumedByACS",
"10.2.0.1/24")
# On ACS create network using non-persistent nw offering allow
isolated_network = self.create_Network(
self.nuage_isolated_network_offering,
gateway="10.0.0.1", netmask="255.255.255.0",
externalid=subnet1.id)
# On ACS create network using persistent nw offering allow
isolated_network2 = self.create_Network(
self.nuage_isolated_network_offering_persistent,
gateway="10.1.0.1", netmask="255.255.255.0",
externalid=subnet2.id)
try:
self.create_Network(
self.nuage_shared_network_offering, gateway="10.2.0.1",
netmask="255.255.255.0", vlan=1201, externalid=subnet3.id)
except Exception as e:
self.debug("Shared Network Creation fails with %s" % e)
# verify floating ip and intra subnet connectivity
vm_1 = self.create_VM(isolated_network)
vm_2 = self.create_VM(isolated_network)
self.debug("Creating Static NAT rule for the deployed VM in the "
"non persistently created Isolated network...")
public_ip = self.acquire_PublicIPAddress(isolated_network)
self.validate_PublicIPAddress(public_ip, isolated_network)
self.create_StaticNatRule_For_VM(vm_1, public_ip, isolated_network)
self.validate_PublicIPAddress(
public_ip, isolated_network, static_nat=True, vm=vm_1)
self.create_FirewallRule(public_ip, self.test_data["ingress_rule"])
if not self.isSimulator:
vm_public_ip = public_ip.ipaddress.ipaddress
try:
vm_1.ssh_ip = vm_public_ip
vm_1.ssh_port = self.test_data["virtual_machine"]["ssh_port"]
vm_1.username = self.test_data["virtual_machine"]["username"]
vm_1.password = self.test_data["virtual_machine"]["password"]
self.debug("SSHing into VM: %s with %s" %
(vm_1.ssh_ip, vm_1.password))
ssh = vm_1.get_ssh_client(ipaddress=vm_public_ip)
except Exception as e:
self.fail("SSH into VM failed with exception %s" % e)
self.verify_pingtovmipaddress(ssh, vm_2.ipaddress)
vm_3 = self.create_VM(isolated_network2)
vm_4 = self.create_VM(isolated_network2)
self.debug("Creating Static NAT rule for the deployed VM in the "
"persistently created Isolated network...")
public_ip2 = self.acquire_PublicIPAddress(isolated_network2)
self.validate_PublicIPAddress(public_ip2, isolated_network2)
self.create_StaticNatRule_For_VM(vm_3, public_ip2, isolated_network2)
self.validate_PublicIPAddress(
public_ip2, isolated_network2, static_nat=True, vm=vm_3)
self.create_FirewallRule(public_ip2, self.test_data["ingress_rule"])
if not self.isSimulator:
vm_public_ip2 = public_ip2.ipaddress.ipaddress
try:
vm_3.ssh_ip = vm_public_ip2
vm_3.ssh_port = self.test_data["virtual_machine"]["ssh_port"]
vm_3.username = self.test_data["virtual_machine"]["username"]
vm_3.password = self.test_data["virtual_machine"]["password"]
self.debug("SSHing into VM: %s with %s" %
(vm_3.ssh_ip, vm_3.password))
ssh2 = vm_3.get_ssh_client(ipaddress=vm_public_ip2)
except Exception as e:
self.fail("SSH into VM failed with exception %s" % e)
self.verify_pingtovmipaddress(ssh2, vm_4.ipaddress)
@attr(tags=["advanced", "nuagevsp", "vpc"], required_hardware="false")
def test_02_nuage_mngd_subnets_vpc(self):
"""Test Nuage VSP Managed Subnets for vpc and tier networks
"""
# 1. Create multiple L3DomainTemplate with Zone and Subnet on VSP
# Create Ingress & Egress ACL Top & Bottom Templates
# Add ACL rules to allow intra-subnet traffic
# Instiantiate these L3Domains and store its Subnet VSD ID
# 2. Create a vpc network offering and create a VPC
# create vpc tier network offerings with and without VirtualRouter
# 3. Create vpc tier networks specifying above offerings and
# specifying the stored Subnet ID's of VSP
# 4. Verify ACL rules and connectivity via deploying VM's ,
# Enabling staticNAT, applying firewall and egress rules
# Create all items on vsd required for this test
enterprise = self.fetch_by_externalID(self._session.user.enterprises,
self.domain)
domain_template = self.create_vsd_domain_template(enterprise)
self.create_vsd_default_acls(domain_template)
domain1 = self.create_vsd_domain(domain_template, enterprise,
"L3DomainToBeConsumedByACS")
zone1 = self.create_vsd_zone(domain1, "ZoneToBeConsumedByACS")
subnet1 = self.create_vsd_subnet(zone1, "SubnetToBeConsumedByACS",
"10.1.0.1/24")
subnet2 = self.create_vsd_subnet(zone1, "2ndSubnetToBeConsumedByACS",
"10.1.128.1/24")
cmd = updateZone.updateZoneCmd()
cmd.id = self.zone.id
cmd.domain = "vpc.com"
self.api_client.updateZone(cmd)
self.debug("Creating a VPC with Static NAT service provider as "
"VpcVirtualRouter")
vpc = self.create_Vpc(self.nuage_vpc_offering, cidr='10.1.0.0/16')
self.validate_Vpc(vpc, state="Enabled")
acl_list = self.create_NetworkAclList(
name="acl", description="acl", vpc=vpc)
self.create_NetworkAclRule(
self.test_data["ingress_rule"], acl_list=acl_list)
self.create_NetworkAclRule(
self.test_data["icmprule"], acl_list=acl_list)
self.debug("Creating a VPC tier network with Static NAT service")
vpc_tier = self.create_Network(self.nuage_vpc_network_offering,
gateway='10.1.0.1',
vpc=vpc,
acl_list=acl_list,
externalid=subnet1.id)
self.validate_Network(vpc_tier, state="Implemented")
self.debug("Creating 2nd VPC tier network with Static NAT service")
vpc_2ndtier = self.create_Network(self.nuage_vpc_network_offering,
gateway='10.1.128.1',
vpc=vpc,
acl_list=acl_list,
externalid=subnet2.id)
self.validate_Network(vpc_2ndtier, state="Implemented")
vpc_vr = self.get_Router(vpc_tier)
self.check_Router_state(vpc_vr, state="Running")
self.debug("Deploying a VM in the created VPC tier network")
self.test_data["virtual_machine"]["displayname"] = "vpcvm1"
self.test_data["virtual_machine"]["name"] = "vpcvm1"
vpc_vm_1 = self.create_VM(vpc_tier)
self.check_VM_state(vpc_vm_1, state="Running")
self.debug("Deploying another VM in the created VPC tier network")
self.test_data["virtual_machine"]["displayname"] = "vpcvm2"
self.test_data["virtual_machine"]["name"] = "vpcvm2"
vpc_vm_2 = self.create_VM(vpc_tier)
self.check_VM_state(vpc_vm_2, state="Running")
self.debug("Deploying a VM in the 2nd VPC tier network")
self.test_data["virtual_machine"]["displayname"] = "vpcvm12"
self.test_data["virtual_machine"]["name"] = "vpcvm12"
vpc_vm_12 = self.create_VM(vpc_2ndtier)
self.check_VM_state(vpc_vm_2, state="Running")
self.test_data["virtual_machine"]["displayname"] = None
self.test_data["virtual_machine"]["name"] = None
self.debug("Creating Static NAT rule for the deployed VM "
"in the created VPC network...")
public_ip_1 = self.acquire_PublicIPAddress(vpc_tier, vpc=vpc)
self.validate_PublicIPAddress(public_ip_1, vpc_tier)
self.create_StaticNatRule_For_VM(vpc_vm_1, public_ip_1, vpc_tier)
self.validate_PublicIPAddress(
public_ip_1, vpc_tier, static_nat=True, vm=vpc_vm_1)
if not self.isSimulator:
vm_public_ip_1 = public_ip_1.ipaddress.ipaddress
try:
vpc_vm_1.ssh_ip = vm_public_ip_1
vpc_vm_1.ssh_port = \
self.test_data["virtual_machine"]["ssh_port"]
vpc_vm_1.username = \
self.test_data["virtual_machine"]["username"]
vpc_vm_1.password = \
self.test_data["virtual_machine"]["password"]
self.debug("SSHing into VM: %s with %s" %
(vpc_vm_1.ssh_ip, vpc_vm_1.password))
ssh = vpc_vm_1.get_ssh_client(ipaddress=vm_public_ip_1)
except Exception as e:
self.fail("SSH into VM failed with exception %s" % e)
self.verify_pingtovmipaddress(ssh, vpc_vm_2.ipaddress)
self.verify_pingtovmipaddress(ssh, vpc_vm_12.ipaddress)
def create_vsd_ingress_acl_template(self, domain_template, priority_type="TOP"):
name = "Ingress ACL " + str(priority_type).capitalize()
acl_template = self.vsdk.NUIngressACLTemplate()
acl_template.name = name
acl_template.description = name
acl_template.priority_type = priority_type
acl_template.active = True
(acl_template, connection) = \
domain_template.create_child(acl_template)
return acl_template
def create_vsd_egress_acl_template(self, domain_template, priority_type='TOP'):
name = "Egress ACL " + str(priority_type).capitalize()
acl_template = self.vsdk.NUEgressACLTemplate()
acl_template.name = name
acl_template.description = name
acl_template.priority_type = priority_type
acl_template.active = True
(acl_template, connection) = \
domain_template.create_child(acl_template)
return acl_template
def create_vsd_domain_template(self, enterprise):
domain_template = self.vsdk.NUDomainTemplate()
domain_template.name = "L3DomainTemplateToBeConsumedByACS"
domain_template.description = "L3DomainTemplateToBeConsumedByACS"
domain_template.external_id = "L3DomainTemplateToBeConsumedByACS@" \
+ str(self.cms_id)
(domain_template, connection) = \
enterprise.create_child(domain_template)
return domain_template
def create_vsd_default_acls(self, domain_template):
ingress_vsd_acl_template1 = self.create_vsd_ingress_acl_template(
domain_template, "TOP")
ingress_vsd_acl_template2 = self.create_vsd_ingress_acl_template(
domain_template, "BOTTOM")
ingress_vsd_acl_entry1 = self.vsdk.NUIngressACLEntryTemplate()
ingress_vsd_acl_entry1.name = "Default Intra-Subnet Allow"
ingress_vsd_acl_entry1.description = "Default Intra-Subnet Allow"
ingress_vsd_acl_entry1.external_id = "ToBeConsumedByACS@" \
+ str(self.cms_id)
ingress_vsd_acl_entry1.priority = '1'
ingress_vsd_acl_entry1.protocol = 'ANY'
ingress_vsd_acl_template1.create_child(ingress_vsd_acl_entry1)
ingress_vsd_acl_entry2 = self.vsdk.NUIngressACLEntryTemplate()
ingress_vsd_acl_entry2.name = "Default Allow TCP"
ingress_vsd_acl_entry2.description = "Default Allow TCP"
ingress_vsd_acl_entry2.external_id = "ToBeConsumedByACS@" \
+ str(self.cms_id)
ingress_vsd_acl_entry2.priority = '1'
ingress_vsd_acl_entry2.protocol = '6'
ingress_vsd_acl_entry2.source_port = '*'
ingress_vsd_acl_entry2.destination_port = '*'
ingress_vsd_acl_template2.create_child(ingress_vsd_acl_entry2)
ingress_vsd_acl_entry3 = self.vsdk.NUIngressACLEntryTemplate()
ingress_vsd_acl_entry3.name = "Default Allow UDP"
ingress_vsd_acl_entry3.description = "Default Allow UDP"
ingress_vsd_acl_entry3.external_id = "ToBeConsumedByACS@" \
+ str(self.cms_id)
ingress_vsd_acl_entry3.priority = '2'
ingress_vsd_acl_entry3.protocol = '17'
ingress_vsd_acl_entry3.source_port = '*'
ingress_vsd_acl_entry3.destination_port = '*'
ingress_vsd_acl_template2.create_child(ingress_vsd_acl_entry3)
ingress_vsd_acl_entry4 = self.vsdk.NUIngressACLEntryTemplate()
ingress_vsd_acl_entry4.name = "Default Allow ICMP"
ingress_vsd_acl_entry4.description = "Default Allow ICMP"
ingress_vsd_acl_entry4.external_id = "ToBeConsumedByACS@" \
+ str(self.cms_id)
ingress_vsd_acl_entry4.priority = '3'
ingress_vsd_acl_entry4.protocol = '1'
ingress_vsd_acl_template2.create_child(ingress_vsd_acl_entry4)
egress_vsd_acl_template1 = self.create_vsd_egress_acl_template(
domain_template, 'TOP')
egress_vsd_acl_template2 = self.create_vsd_egress_acl_template(
domain_template, 'BOTTOM')
egress_vsd_acl_entry1 = self.vsdk.NUEgressACLEntryTemplate()
egress_vsd_acl_entry1.name = "Default Intra-Subnet Allow"
egress_vsd_acl_entry1.description = "Default Intra-Subnet Allow"
egress_vsd_acl_entry1.external_id = "ToBeConsumedByACS@" \
+ str(self.cms_id)
egress_vsd_acl_entry1.priority = '1'
egress_vsd_acl_entry1.protocol = 'ANY'
egress_vsd_acl_template1.create_child(egress_vsd_acl_entry1)
egress_vsd_acl_entry2 = self.vsdk.NUEgressACLEntryTemplate()
egress_vsd_acl_entry2.name = "Default Allow ICMP"
egress_vsd_acl_entry2.description = "Default Allow ICMP"
egress_vsd_acl_entry2.external_id = "ToBeConsumedByACS@" \
+ str(self.cms_id)
egress_vsd_acl_entry2.priority = '3'
egress_vsd_acl_entry2.protocol = '1'
egress_vsd_acl_template2.create_child(egress_vsd_acl_entry2)
def create_vsd_domain(self, domain_template, enterprise, name):
domain = self.vsdk.NUDomain()
domain.name = name
domain.description = name
domain.external_id = name + "@" + str(self.cms_id)
(domain, connection) = \
enterprise.instantiate_child(domain, domain_template)
return domain
def create_vsd_zone(self, domain, name):
zone = self.vsdk.NUZone()
zone.name = name
zone.description = name
zone.external_id = name + "@" + str(self.cms_id)
(zone, connection) = domain.create_child(zone)
return zone
def create_vsd_subnet(self, zone, name, cidr):
subnet = self.vsdk.NUSubnet()
subnet.name = name
subnet.description = name
subnet.external_id = name + "@" + str(self.cms_id)
(subnet.gateway, subnet.netmask, subnet.address) = \
self._cidr_to_netmask(cidr)
(subnet, connection) = zone.create_child(subnet)
return subnet
def _cidr_to_netmask(self, cidr):
import socket
import struct
network, net_bits = cidr.split('/')
host_bits = 32 - int(net_bits)
netmask_bits = (1 << 32) - (1 << host_bits)
netmask = socket.inet_ntoa(struct.pack('!I', netmask_bits))
network_bits = struct.unpack('!I', socket.inet_aton(network))[0]
network_masked = socket.inet_ntoa(
struct.pack('!I', netmask_bits & network_bits)
)
return network, netmask, network_masked

View File

@ -2011,6 +2011,70 @@ test_data = {
"SourceNat": {"SupportedSourceNatTypes": "perzone"}
}
},
# Persistent services supported by the Nuage VSP plugin for Isolated networks
"isolated_network_offering_persistent": {
"name": 'nuage_marvin',
"displaytext": 'nuage_marvin',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,SourceNat,Connectivity,StaticNat,UserData,Firewall,Dns',
"traffictype": 'GUEST',
"availability": 'Optional',
"ispersistent": 'True',
"tags": "nuage",
"serviceProviderList": {
"Dhcp": 'NuageVsp',
"StaticNat": 'NuageVsp',
"SourceNat": 'NuageVsp',
"Firewall": 'NuageVsp',
"Connectivity": 'NuageVsp',
"UserData": 'VirtualRouter',
"Dns": 'VirtualRouter'
},
"serviceCapabilityList": {
"SourceNat": {"SupportedSourceNatTypes": "perzone"}
}
},
# Purely nuage network offering
"isolated_network_offering_without_vr": {
"name": 'nuage_marvin',
"displaytext": 'nuage_marvin',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,SourceNat,Connectivity,StaticNat,Firewall',
"traffictype": 'GUEST',
"availabiliy": 'Optional',
"tags": "nuage",
"serviceProviderList": {
"Dhcp": 'NuageVsp',
"StaticNat": 'NuageVsp',
"SourceNat": 'NuageVsp',
"Firewall": 'NuageVsp',
"Connectivity": 'NuageVsp'
},
"serviceCapabilityList": {
"SourceNat": {"SupportedSourceNatTypes": "perzone"}
}
},
# Purely persistent nuage network offering
"isolated_network_offering_without_vr_persistent": {
"name": 'nuage_marvin',
"displaytext": 'nuage_marvin',
"guestiptype": 'Isolated',
"supportedservices": 'Dhcp,SourceNat,Connectivity,StaticNat,Firewall',
"traffictype": 'GUEST',
"availability": 'Optional',
"tags": "nuage",
"ispersistent": 'True',
"serviceProviderList": {
"Dhcp": 'NuageVsp',
"StaticNat": 'NuageVsp',
"SourceNat": 'NuageVsp',
"Firewall": 'NuageVsp',
"Connectivity": 'NuageVsp'
},
"serviceCapabilityList": {
"SourceNat": {"SupportedSourceNatTypes": "perzone"}
}
},
# Purely nuage network offering
"isolated_network_offering_without_vr": {
"name": 'nuage_marvin',

View File

@ -2910,7 +2910,8 @@ class Network:
def create(cls, apiclient, services, accountid=None, domainid=None,
networkofferingid=None, projectid=None,
subdomainaccess=None, zoneid=None,
gateway=None, netmask=None, vpcid=None, aclid=None, vlan=None):
gateway=None, netmask=None, vpcid=None, aclid=None, vlan=None,
externalid=None):
"""Create Network for account"""
cmd = createNetwork.createNetworkCmd()
cmd.name = services["name"]
@ -2958,6 +2959,8 @@ class Network:
cmd.vpcid = vpcid
if aclid:
cmd.aclid = aclid
if externalid:
cmd.externalid = externalid
return Network(apiclient.createNetwork(cmd).__dict__)
def delete(self, apiclient):

View File

@ -807,6 +807,7 @@ var dictionary = {"ICMP.code":"ICMP Code",
"label.guest":"Guest",
"label.guest.cidr":"Guest CIDR",
"label.guest.end.ip":"Guest end IP",
"label.guest.externalId":"External Id",
"label.guest.gateway":"Guest Gateway",
"label.guest.ip":"Guest IP Address",
"label.guest.ip.range":"Guest IP Range",

View File

@ -395,6 +395,10 @@ cloudStack.docs = {
desc: 'If you want to assign a special domain name to this domain\'s guest VM network, specify the DNS suffix',
externalLink: ''
},
helpDomainId: {
desc: 'A valid domain id. CloudStack will generate one for you if empty.',
externalLink: ''
},
// Add F5
helpF5IPAddress: {
desc: 'The IP address of the device',

View File

@ -269,6 +269,12 @@
});
}
if (args.data.domainid != null && args.data.domainid.length > 0) {
$.extend(data, {
domainid: args.data.domainid
});
}
$.ajax({
url: createURL('createDomain'),
data: data,
@ -308,7 +314,14 @@
validation: {
required: false
}
}
},
domainid: {
label: 'label.domain.id',
docID: 'helpDomainId',
validation: {
required: false
}
}
}
}
},

View File

@ -657,7 +657,9 @@
}
}
},
externalId: {
label: 'label.guest.externalId'
},
guestGateway: {
label: 'label.guest.gateway',
docID: 'helpGuestNetworkGateway'
@ -744,9 +746,14 @@
gateway: args.data.guestGateway
});
}
if (args.data.guestNetmask != null && args.data.guestNetmask.length > 0) {
if (args.data.guestGateway != null && args.data.guestGateway.length > 0) {
$.extend(dataObj, {
netmask: args.data.guestNetmask
gateway: args.data.guestGateway
});
}
if (args.data.externalId != null && args.data.externalId.length > 0) {
$.extend(dataObj, {
externalid: args.data.externalId
});
}
if (args.$form.find('.form-item[rel=vpcid]').css("display") != "none") {

View File

@ -3948,7 +3948,9 @@
required: true
}
},
externalId: {
label: 'label.guest.externalId'
},
aclid: {
label: 'label.acl',
select: function(args) {
@ -4040,11 +4042,17 @@
zoneId: args.context.vpc[0].zoneid
});
if (args.data.externalId != null && args.data.externalId.length > 0) {
$.extend(dataObj, {
externalid: args.data.externalId
});
}
if (args.data.aclid != '')
if (args.data.aclid != '') {
$.extend(dataObj, {
aclid: args.data.aclid
});
}
if (args.$form.find('.form-item[rel=vlan]').is(':visible')) {
$.extend(dataObj, {