diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index 81447d6457c..122ce708327 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -60,7 +60,8 @@ public interface Network extends ControlledEntity, StateObject, I public static final Service PortForwarding = new Service("PortForwarding"); public static final Service SecurityGroup = new Service("SecurityGroup"); public static final Service NetworkACL = new Service("NetworkACL", Capability.SupportedProtocols); - public static final Service Connectivity = new Service("Connectivity", Capability.DistributedRouter, Capability.RegionLevelVpc, Capability.StretchedL2Subnet); + public static final Service Connectivity = new Service("Connectivity", Capability.DistributedRouter, Capability.RegionLevelVpc, Capability.StretchedL2Subnet, + Capability.NoVlan, Capability.PublicAccess); private final String name; private final Capability[] caps; @@ -215,6 +216,8 @@ public interface Network extends ControlledEntity, StateObject, I public static final Capability DistributedRouter = new Capability("DistributedRouter"); public static final Capability StretchedL2Subnet = new Capability("StretchedL2Subnet"); public static final Capability RegionLevelVpc = new Capability("RegionLevelVpc"); + public static final Capability NoVlan = new Capability("NoVlan"); + public static final Capability PublicAccess = new Capability("PublicAccess"); private final String name; diff --git a/api/src/com/cloud/network/NetworkModel.java b/api/src/com/cloud/network/NetworkModel.java index 780f97d22f4..02746d05bd0 100644 --- a/api/src/com/cloud/network/NetworkModel.java +++ b/api/src/com/cloud/network/NetworkModel.java @@ -154,6 +154,8 @@ public interface NetworkModel { boolean checkIpForService(IpAddress ip, Service service, Long networkId); + boolean providerSupportsCapability(Set providers, Service service, Capability cap); + void checkCapabilityForProvider(Set providers, Service service, Capability cap, String capValue); Provider getDefaultUniqueProviderForService(String serviceName); diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index f1ef69c2f68..5eab98ab293 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -131,4 +131,6 @@ public interface NetworkOffering extends InfrastructureEntity, InternalIdentity, boolean isKeepAliveEnabled(); boolean getSupportsStrechedL2(); + + boolean getSupportsPublicAccess(); } diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index ad686587246..00e9d388c28 100644 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -639,6 +639,7 @@ public class ApiConstants { public static final String READ_ONLY = "readonly"; public static final String SUPPORTS_REGION_LEVEL_VPC = "supportsregionLevelvpc"; public static final String SUPPORTS_STRECHED_L2_SUBNET = "supportsstrechedl2subnet"; + public static final String SUPPORTS_PUBLIC_ACCESS = "supportspublicaccess"; public static final String REGION_LEVEL_VPC = "regionlevelvpc"; public static final String STRECHED_L2_SUBNET = "strechedl2subnet"; public static final String NETWORK_SPANNED_ZONES = "zonesnetworkspans"; diff --git a/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java b/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java index 775c9a8fdd1..93cbb12976b 100644 --- a/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java +++ b/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java @@ -120,6 +120,10 @@ public class NetworkOfferingResponse extends BaseResponse { @Param(description = "true if network offering supports network that span multiple zones", since = "4.4") private Boolean supportsStrechedL2Subnet; + @SerializedName(ApiConstants.SUPPORTS_PUBLIC_ACCESS) + @Param(description = "true if network offering supports public access for guest networks", since = "4.10.0") + private Boolean supportsPublicAccess; + public void setId(String id) { this.id = id; } @@ -207,4 +211,8 @@ public class NetworkOfferingResponse extends BaseResponse { public void setSupportsStrechedL2Subnet(Boolean supportsStrechedL2Subnet) { this.supportsStrechedL2Subnet = supportsStrechedL2Subnet; } + + public void setSupportsPublicAccess(Boolean supportsPublicAccess) { + this.supportsPublicAccess = supportsPublicAccess; + } } diff --git a/client/pom.xml b/client/pom.xml index 3954795aa7d..3595aaa91db 100644 --- a/client/pom.xml +++ b/client/pom.xml @@ -166,6 +166,11 @@ cloud-plugin-network-vcs ${project.version} + + org.apache.cloudstack + cloud-plugin-network-vsp + ${project.version} + org.apache.cloudstack cloud-plugin-hypervisor-xenserver @@ -990,21 +995,6 @@ - - nuagevsp - - - noredist - - - - - org.apache.cloudstack - cloud-plugin-network-vsp - ${project.version} - - - srx diff --git a/engine/schema/src/com/cloud/dc/dao/VlanDao.java b/engine/schema/src/com/cloud/dc/dao/VlanDao.java index 485593e8f45..e92a5cc6f1c 100644 --- a/engine/schema/src/com/cloud/dc/dao/VlanDao.java +++ b/engine/schema/src/com/cloud/dc/dao/VlanDao.java @@ -49,6 +49,8 @@ public interface VlanDao extends GenericDao { List listVlansByNetworkId(long networkId); + List listVlansByNetworkIdIncludingRemoved(long networkId); + List listVlansByPhysicalNetworkId(long physicalNetworkId); List listZoneWideNonDedicatedVlans(long zoneId); diff --git a/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java index eabfbaa8b28..0c5914824f4 100644 --- a/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java +++ b/engine/schema/src/com/cloud/dc/dao/VlanDaoImpl.java @@ -105,7 +105,7 @@ public class VlanDaoImpl extends GenericDaoBase implements VlanDao ZoneTypeSearch.done(); NetworkVlanSearch = createSearchBuilder(); - NetworkVlanSearch.and("networkOfferingId", NetworkVlanSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); + NetworkVlanSearch.and("networkId", NetworkVlanSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); NetworkVlanSearch.done(); PhysicalNetworkVlanSearch = createSearchBuilder(); @@ -330,12 +330,18 @@ public class VlanDaoImpl extends GenericDaoBase implements VlanDao } @Override - public List listVlansByNetworkId(long networkOfferingId) { + public List listVlansByNetworkId(long networkId) { SearchCriteria sc = NetworkVlanSearch.create(); - sc.setParameters("networkOfferingId", networkOfferingId); + sc.setParameters("networkId", networkId); return listBy(sc); } + @Override public List listVlansByNetworkIdIncludingRemoved(long networkId) { + SearchCriteria sc = NetworkVlanSearch.create(); + sc.setParameters("networkId", networkId); + return listIncludingRemovedBy(sc); + } + @Override public List listVlansByNetworkIdAndGateway(long networkid, String gateway) { SearchCriteria sc = VlanGatewaysearch.create(); diff --git a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java index c3d849d134c..4325287b273 100644 --- a/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java +++ b/engine/schema/src/com/cloud/offerings/NetworkOfferingVO.java @@ -142,6 +142,9 @@ public class NetworkOfferingVO implements NetworkOffering { @Column(name="supports_streched_l2") boolean supportsStrechedL2 = false; + @Column(name="supports_public_access") + boolean supportsPublicAccess = false; + @Override public String getDisplayText() { return displayText; @@ -334,7 +337,7 @@ public class NetworkOfferingVO implements NetworkOffering { public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, boolean systemOnly, boolean specifyVlan, Integer rateMbps, Integer multicastRateMbps, boolean isDefault, Availability availability, String tags, Network.GuestType guestType, boolean conserveMode, boolean dedicatedLb, boolean sharedSourceNat, boolean redundantRouter, boolean elasticIp, boolean elasticLb, boolean specifyIpRanges, boolean inline, boolean isPersistent, - boolean associatePublicIP, boolean publicLb, boolean internalLb, boolean egressdefaultpolicy, boolean supportsStrechedL2) { + boolean associatePublicIP, boolean publicLb, boolean internalLb, boolean egressdefaultpolicy, boolean supportsStrechedL2, boolean supportsPublicAccess) { this(name, displayText, trafficType, @@ -360,6 +363,7 @@ public class NetworkOfferingVO implements NetworkOffering { this.eipAssociatePublicIp = associatePublicIP; this.egressdefaultpolicy = egressdefaultpolicy; this.supportsStrechedL2 = supportsStrechedL2; + this.supportsPublicAccess = supportsPublicAccess; } public NetworkOfferingVO() { @@ -495,4 +499,9 @@ public class NetworkOfferingVO implements NetworkOffering { public boolean getSupportsStrechedL2() { return supportsStrechedL2; } + + @Override + public boolean getSupportsPublicAccess() { + return supportsPublicAccess; + } } diff --git a/plugins/network-elements/nuage-vsp/pom.xml b/plugins/network-elements/nuage-vsp/pom.xml index d26a3aab2b0..78468dd8cb8 100644 --- a/plugins/network-elements/nuage-vsp/pom.xml +++ b/plugins/network-elements/nuage-vsp/pom.xml @@ -36,9 +36,9 @@ - net.nuage.vsp + net.nuagenetworks.vsp nuage-vsp-acs-client - 3.2.8.1 + 1.0.0 diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/CleanUpDomainCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/CleanUpDomainCommand.java new file mode 100644 index 00000000000..2229b61f813 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/CleanUpDomainCommand.java @@ -0,0 +1,72 @@ +// +// 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.agent.api.manager; + +import com.cloud.agent.api.Command; + +import com.google.common.base.Preconditions; +import net.nuage.vsp.acs.client.api.model.VspDomainCleanUp; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.util.Objects; + +public class CleanUpDomainCommand extends Command { + + private final VspDomainCleanUp _domainCleanUp; + + public CleanUpDomainCommand(VspDomainCleanUp domainCleanUp) { + super(); + Preconditions.checkNotNull(domainCleanUp); + this._domainCleanUp = domainCleanUp; + } + + public VspDomainCleanUp getDomainCleanUp() { + return _domainCleanUp; + } + + @Override + public boolean executeInSequence() { + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof CleanUpDomainCommand)) { + return false; + } + + CleanUpDomainCommand that = (CleanUpDomainCommand) o; + + return super.equals(that) + && Objects.equals(_domainCleanUp, that._domainCleanUp); + } + + @Override + public int hashCode() { + return new HashCodeBuilder() + .appendSuper(super.hashCode()) + .append(_domainCleanUp) + .toHashCode(); + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/EntityExistsCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/EntityExistsCommand.java index 64f37689ca6..8e8fd81dfd8 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/EntityExistsCommand.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/EntityExistsCommand.java @@ -19,6 +19,10 @@ package com.cloud.agent.api.manager; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.util.Objects; + import com.cloud.agent.api.Command; public class EntityExistsCommand extends Command { @@ -55,23 +59,27 @@ public class EntityExistsCommand extends Command { @Override public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof EntityExistsCommand)) return false; - if (!super.equals(o)) return false; + if (this == o) { + return true; + } + + if (!(o instanceof EntityExistsCommand)) { + return false; + } EntityExistsCommand that = (EntityExistsCommand) o; - if (getType() != null ? !getType().equals(that.getType()) : that.getType() != null) return false; - if (_uuid != null ? !_uuid.equals(that._uuid) : that._uuid != null) return false; - - return true; + return super.equals(that) + && Objects.equals(getType(), that.getType()) + && Objects.equals(_uuid, that._uuid); } @Override public int hashCode() { - int result = super.hashCode(); - result = 31 * result + (getType() != null ? getType().hashCode() : 0); - result = 31 * result + (_uuid != null ? _uuid.hashCode() : 0); - return result; + return new HashCodeBuilder() + .appendSuper(super.hashCode()) + .append(getType()) + .append(_uuid) + .toHashCode(); } } \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/UpdateNuageVspDeviceCommand.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/UpdateNuageVspDeviceCommand.java new file mode 100644 index 00000000000..d94ff701a97 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/UpdateNuageVspDeviceCommand.java @@ -0,0 +1,70 @@ +// +// 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.agent.api.manager; + +import org.apache.commons.lang.builder.HashCodeBuilder; + +import java.util.Objects; + +import com.cloud.agent.api.Command; +import com.cloud.network.resource.NuageVspResourceConfiguration; + +public class UpdateNuageVspDeviceCommand extends Command { + + private final NuageVspResourceConfiguration configuration; + + public UpdateNuageVspDeviceCommand(NuageVspResourceConfiguration configuration) { + super(); + this.configuration = configuration; + } + + public NuageVspResourceConfiguration getConfiguration() { + return configuration; + } + + @Override + public boolean executeInSequence() { + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof UpdateNuageVspDeviceCommand)) { + return false; + } + + UpdateNuageVspDeviceCommand that = (UpdateNuageVspDeviceCommand) o; + + return super.equals(that) + && Objects.equals(configuration, that.configuration); + } + + @Override + public int hashCode() { + return new HashCodeBuilder() + .appendSuper(super.hashCode()) + .append(configuration) + .toHashCode(); + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncNuageVspCmsIdAnswer.java b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncNuageVspCmsIdAnswer.java index 289796fcc1c..98730fe7317 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncNuageVspCmsIdAnswer.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/sync/SyncNuageVspCmsIdAnswer.java @@ -24,6 +24,7 @@ import java.util.Objects; import org.apache.commons.lang.builder.HashCodeBuilder; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; public class SyncNuageVspCmsIdAnswer extends Answer { @@ -38,6 +39,13 @@ public class SyncNuageVspCmsIdAnswer extends Answer { this._syncType = syncType; } + public SyncNuageVspCmsIdAnswer(Command command, Exception e, SyncNuageVspCmsIdCommand.SyncType syncType) { + super(command, e); + this._nuageVspCmsId = null; + this._success = false; + this._syncType = syncType; + } + public boolean getSuccess() { return _success; } diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java index d0b9ed9683f..f2c13054f28 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java @@ -20,30 +20,37 @@ package com.cloud.network.element; import java.util.ArrayList; -import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; + import javax.annotation.Nullable; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.commons.collections.CollectionUtils; -import org.apache.log4j.Logger; -import com.google.common.base.Function; -import com.google.common.collect.Lists; - +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; import net.nuage.vsp.acs.client.api.model.VspAclRule; import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption; import net.nuage.vsp.acs.client.api.model.VspNetwork; import net.nuage.vsp.acs.client.api.model.VspStaticNat; +import org.apache.commons.collections.CollectionUtils; +import org.apache.log4j.Logger; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + import org.apache.cloudstack.api.InternalIdentity; import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.cloudstack.network.ExternalNetworkDeviceManager; import org.apache.cloudstack.network.topology.NetworkTopologyContext; import org.apache.cloudstack.resourcedetail.VpcDetailVO; import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao; + import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.StartupCommand; @@ -64,6 +71,7 @@ import com.cloud.domain.dao.DomainDao; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.UnsupportedServiceException; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; @@ -111,6 +119,7 @@ import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; import com.cloud.util.NuageVspEntityBuilder; import com.cloud.util.NuageVspUtil; +import com.cloud.utils.Pair; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.net.NetUtils; import com.cloud.vm.DomainRouterVO; @@ -128,6 +137,26 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider private static final Map> capabilities = setCapabilities(); + private static final Set REQUIRED_SERVICES = ImmutableSet.of( + Service.Connectivity, + Service.Dhcp + ); + private static final Set NUAGE_ONLY_SERVICES = ImmutableSet.of( + Service.SourceNat, + Service.StaticNat, + Service.Gateway + ); + private static final Set UNSUPPORTED_SERVICES = ImmutableSet.of( + Service.Vpn, + Service.Dns, + Service.PortForwarding, + Service.SecurityGroup + ); + private static final Set> ANY_REQUIRED_SERVICES = ImmutableSet.of( + new Pair<>(Service.SourceNat, Service.StaticNat) + ); + + public static final ExternalNetworkDeviceManager.NetworkDevice NuageVspDevice = new ExternalNetworkDeviceManager.NetworkDevice("NuageVsp", Provider.NuageVsp.getName()); @Inject @@ -190,7 +219,6 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider @Inject VpcVirtualNetworkApplianceManager _routerMgr; - @Override public boolean applyIps(Network network, List ipAddress, Set service) throws ResourceUnavailableException { return false; @@ -202,45 +230,32 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider } private static Map> setCapabilities() { - Map> capabilities = new HashMap>(); - - // L2 Support : SDN provisioning - capabilities.put(Service.Connectivity, null); - - // L3 Support : Generic - capabilities.put(Service.Gateway, null); - - // Security Group - capabilities.put(Service.SecurityGroup, null); - - // L3 Support : SourceNat - Map sourceNatCapabilities = new HashMap(); - sourceNatCapabilities.put(Capability.SupportedSourceNatTypes, "perzone"); - sourceNatCapabilities.put(Capability.RedundantRouter, "false"); - capabilities.put(Service.SourceNat, sourceNatCapabilities); - - // L3 support : StaticNat - capabilities.put(Service.StaticNat, null); - - // Set capabilities for Firewall service - Map firewallCapabilities = new HashMap(); - firewallCapabilities.put(Capability.TrafficStatistics, "per public ip"); - firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp"); - firewallCapabilities.put(Capability.SupportedEgressProtocols, "tcp,udp,icmp, all"); - firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress, egress"); - firewallCapabilities.put(Capability.MultipleIps, "true"); - capabilities.put(Service.Firewall, firewallCapabilities); - - // L3 Support : DHCP - Map dhcpCapabilities = new HashMap(); - capabilities.put(Service.Dhcp, dhcpCapabilities); - - //add network ACL capability - Map networkACLCapabilities = new HashMap(); - networkACLCapabilities.put(Network.Capability.SupportedProtocols, "tcp,udp,icmp"); - capabilities.put(Network.Service.NetworkACL, networkACLCapabilities); - - return capabilities; + return ImmutableMap.>builder() + .put(Service.Connectivity, ImmutableMap.of( + Capability.NoVlan, "", + Capability.PublicAccess, "" + )) + .put(Service.Gateway, ImmutableMap.of()) + .put(Service.SourceNat, ImmutableMap.of( + Capability.SupportedSourceNatTypes, "perzone", + Capability.RedundantRouter, "false" + )) + .put(Service.StaticNat, ImmutableMap.of()) + .put(Service.SecurityGroup, ImmutableMap.of()) + .put(Service.Firewall, ImmutableMap.of( + Capability.TrafficStatistics, "per public ip", + Capability.SupportedProtocols, "tcp,udp,icmp", + Capability.SupportedEgressProtocols, "tcp,udp,icmp, all", + Capability.SupportedTrafficDirection, "ingress, egress", + Capability.MultipleIps, "true" + )) + .put(Service.Dhcp, ImmutableMap.of( + Capability.DhcpAccrossMultipleSubnets, "true" + )) + .put(Service.NetworkACL, ImmutableMap.of( + Capability.SupportedProtocols, "tcp,udp,icmp" + )) + .build(); } @Override @@ -266,7 +281,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider return applyACLRulesForVpc(network, offering); } - if (!canHandle(network, Service.Connectivity)) { + if (!canHandle(network, offering, Service.Connectivity)) { return false; } @@ -276,7 +291,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider } - VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network, true); + VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network); List ingressFirewallRules = getFirewallRulesToApply(network, FirewallRule.TrafficType.Ingress); List egressFirewallRules = getFirewallRulesToApply(network, FirewallRule.TrafficType.Egress); @@ -356,7 +371,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider // The network is restarted, possibly the domain name is changed, update the dhcpOptions as soon as possible NetworkOfferingVO networkOfferingVO = _ntwkOfferingDao.findById(network.getNetworkOfferingId()); VspDhcpDomainOption vspDhcpOptions = _nuageVspEntityBuilder.buildNetworkDhcpOption(network, networkOfferingVO); - VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network, false); + VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network); HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId()); ShutDownVspCommand cmd = new ShutDownVspCommand(vspNetwork, vspDhcpOptions); Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd); @@ -387,41 +402,40 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider @Override public boolean destroy(Network network, ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { - if (!canHandle(network, Service.Connectivity)) { - return false; - } - - return true; + return canHandle(network, Service.Connectivity); } @Override public boolean verifyServicesCombination(Set services) { - // This element can only function in a NuageVsp based - // SDN network, so Connectivity needs to be present here - if (!services.contains(Service.Connectivity)) { - s_logger.warn("Unable to support services combination without Connectivity service provided by Nuage VSP."); + Preconditions.checkNotNull(services); + final Sets.SetView missingServices = Sets.difference(REQUIRED_SERVICES, services); + final Sets.SetView unsupportedServices = Sets.intersection(UNSUPPORTED_SERVICES, services); + final Sets.SetView wantedServices = Sets.intersection(NUAGE_ONLY_SERVICES, new HashSet<>()); + + if (!missingServices.isEmpty()) { + throw new UnsupportedServiceException("Provider " + Provider.NuageVsp + " requires services: " + missingServices); + } + + if (!unsupportedServices.isEmpty()) { + // NuageVsp doesn't implement any of these services. + // So if these services are requested, we can't handle it. + s_logger.debug("Unable to support services combination. The services " + unsupportedServices + " are not supported by Nuage VSP."); return false; } - if (!services.contains(Service.SourceNat)) { - s_logger.warn("Unable to support services combination without SourceNat service provided by Nuage VSP."); - return false; - } - - if (services.contains(Service.Vpn) || services.contains(Service.Dns) || services.contains(Service.Lb) || services.contains(Service.PortForwarding) - || services.contains(Service.SecurityGroup)) { - // NuageVsp doesn't implement any of these services, and we don't - // want anyone else to do it for us. So if these services - // exist, we can't handle it. - s_logger.warn("Unable to support services combination. The services list contains service(s) not supported by Nuage VSP."); - return false; + if (!wantedServices.isEmpty()) { + throw new UnsupportedServiceException("Provider " + Provider.NuageVsp + " does not support services to be implemented by another provider: " + wantedServices); } return true; } protected boolean canHandle(Network network, Service service) { + NetworkOffering networkOffering = _ntwkOfferingDao.findById(network.getNetworkOfferingId()); + return canHandle(network, networkOffering, service); + } + protected boolean canHandle(Network network, NetworkOffering networkOffering, Service service) { if (network.getBroadcastDomainType() != Networks.BroadcastDomainType.Vsp) { return false; } @@ -442,28 +456,35 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider } } - if (service != Service.Connectivity && !_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), Service.Connectivity, getProvider())) { + if (service != Service.Connectivity + && !_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), Service.Connectivity, getProvider())) { if (s_logger.isDebugEnabled()) { s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as Connectivity provider"); } return false; } - if (service != Service.SourceNat && !_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, getProvider())) { + if (service != Service.SourceNat + && networkOffering.getGuestType() == Network.GuestType.Isolated + && !_ntwkSrvcDao.canProviderSupportServiceInNetwork(network.getId(), Service.SourceNat, getProvider())) { if (s_logger.isDebugEnabled()) { s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as SourceNat provider"); } return false; } - if (network.getVpcId() != null) { - NetworkOffering networkOffering = _ntwkOfferingDao.findById(network.getNetworkOfferingId()); - if (!networkOffering.getIsPersistent()) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("NuageVsp can't handle VPC tiers which use a network offering which are not persistent"); - } - return false; + if (networkOffering.getSpecifyVlan()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("NuageVsp doesn't support VLAN values for networks"); } + return false; + } + + if (network.getVpcId() != null && !networkOffering.getIsPersistent()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("NuageVsp can't handle VPC tiers which use a network offering which are not persistent"); + } + return false; } return true; @@ -484,7 +505,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider private boolean isDnsSupportedByVR(Network network) { return (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Dns) && ( _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VirtualRouter) || - _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VPCVirtualRouter))); + _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VPCVirtualRouter))); } @Override @@ -506,7 +527,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider vspStaticNatDetails.add(vspStaticNat); } - VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(config, false); + VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(config); HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(config.getPhysicalNetworkId()); ApplyStaticNatVspCommand cmd = new ApplyStaticNatVspCommand(vspNetwork, vspStaticNatDetails); Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd); @@ -566,7 +587,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider protected boolean applyACLRules(final Network network, List rules, boolean isNetworkAcl, boolean networkReset) throws ResourceUnavailableException { - VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network, false); + VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network); List vspAclRules = Lists.transform(rules, new Function() { @Nullable @Override diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java index 6bdd9e496b0..80f6aab315b 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java @@ -21,10 +21,14 @@ package com.cloud.network.guru; import java.util.List; import java.util.Map; +import java.util.Set; import javax.inject.Inject; +import com.google.common.collect.FluentIterable; +import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption; import net.nuage.vsp.acs.client.api.model.VspDhcpVMOption; +import net.nuage.vsp.acs.client.api.model.VspDomain; import net.nuage.vsp.acs.client.api.model.VspNetwork; import net.nuage.vsp.acs.client.api.model.VspNic; import net.nuage.vsp.acs.client.api.model.VspStaticNat; @@ -33,6 +37,8 @@ import net.nuage.vsp.acs.client.api.model.VspVm; import org.apache.log4j.Logger; import com.google.common.base.Strings; +import com.google.common.collect.Iterables; +import com.google.common.collect.LinkedListMultimap; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -56,6 +62,7 @@ import com.cloud.domain.dao.DomainDao; import com.cloud.exception.ConcurrentOperationException; 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; @@ -82,10 +89,12 @@ 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.net.Ip; import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; import com.cloud.vm.ReservationContext; +import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.VMInstanceDao; @@ -157,7 +166,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { NetworkVO implemented = null; try { - if (network.getState() != State.Implementing) { + if (offering.getGuestType() == GuestType.Isolated && network.getState() != State.Implementing) { throw new IllegalStateException("Network " + networkId + " is not in expected state Implementing, but is in state " + network.getState()); } @@ -170,6 +179,9 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { throw new InsufficientVirtualNetworkCapacityException(errorMessage, Account.class, network.getAccountId()); } + //We don't support a shared network with UserData and multiple IP ranges at the same time. + checkMultipleSubnetsCombinedWithUseData(network); + long dcId = dest.getDataCenter().getId(); //Get physical network id Long physicalNetworkId = network.getPhysicalNetworkId(); @@ -190,21 +202,13 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { implemented.setCidr(network.getCidr()); } - VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(implemented, true); + VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(implemented); String tenantId = context.getDomain().getName() + "-" + context.getAccount().getAccountId(); String broadcastUriStr = implemented.getUuid() + "/" + vspNetwork.getVirtualRouterIp(); implemented.setBroadcastUri(Networks.BroadcastDomainType.Vsp.toUri(broadcastUriStr)); implemented.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp); - HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(physicalNetworkId); - ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering)); - Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd); - - if (answer == null || !answer.getResult()) { - s_logger.error("ImplementNetworkVspCommand for network " + network.getUuid() + " failed on Nuage VSD " + nuageVspHost.getDetail("hostname")); - if ((null != answer) && (null != answer.getDetails())) { - s_logger.error(answer.getDetails()); - } + if (!implement(physicalNetworkId, vspNetwork, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering))) { return null; } @@ -225,8 +229,31 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { return implemented; } + private boolean implement(long physicalNetworkId, VspNetwork vspNetwork, VspDhcpDomainOption vspDhcpDomainOption) { + HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(physicalNetworkId); + ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, vspDhcpDomainOption); + 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()); + } + return false; + } + return true; + } + @Override public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapacityException, InsufficientAddressCapacityException { + if (vm.getType() != VirtualMachine.Type.DomainRouter && _nuageVspEntityBuilder.usesVirtualRouter(network.getNetworkOfferingId())) { + VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network); + if (nic != null && nic.getRequestedIPv4() != null && vspNetwork.getVirtualRouterIp().equals(nic.getRequestedIPv4())) { + DataCenter dc = _dcDao.findById(network.getDataCenterId()); + s_logger.error("Unable to acquire requested Guest IP address " + nic.getRequestedIPv4() + " because it is reserved for the VR in network " + network); + throw new InsufficientVirtualNetworkCapacityException("Unable to acquire requested Guest IP address " + nic.getRequestedIPv4() + " because it is reserved " + + "for the VR in network " + network, DataCenter.class,dc.getId()); + } + } return super.allocate(network, nic, vm); } @@ -240,6 +267,9 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { } try { + //We don't support a shared network with UserData and multiple IP ranges at the same time. + checkMultipleSubnetsCombinedWithUseData(network); + if (s_logger.isDebugEnabled()) { s_logger.debug("Handling reserve() call back to with Create a new VM or add an interface to existing VM in network " + network.getName()); } @@ -255,7 +285,32 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { } HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId()); - VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network, false); + VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(vm.getVirtualMachine().getDomainId(), network); + + if (vspNetwork.isShared()) { + vspNetwork = _nuageVspEntityBuilder.updateVspNetworkByPublicIp(vspNetwork, network, nic.getIPv4Address()); + + if (VirtualMachine.Type.DomainRouter.equals(vm.getType()) && !nic.getIPv4Address().equals(vspNetwork.getVirtualRouterIp())) { + if(s_logger.isDebugEnabled()) { + s_logger.debug("VR got spawned with a different IP, releasing the previously allocated public IP " + nic.getIPv4Address()); + } + IPAddressVO oldIpAddress = _ipAddressDao.findByIpAndSourceNetworkId(network.getId(), nic.getIPv4Address()); + _ipAddressDao.unassignIpAddress(oldIpAddress.getId()); + _ipAddressDao.mark(network.getDataCenterId(), new Ip(vspNetwork.getVirtualRouterIp())); + } else if (VirtualMachine.Type.User.equals(vm.getType()) && nic.getIPv4Address().equals(vspNetwork.getVirtualRouterIp())) { + s_logger.error("Deploying a user VM with the same IP as the VR is not allowed."); + throw new InsufficientVirtualNetworkCapacityException("Deploying a user VM with the same IP " + nic.getIPv4Address() + " as the VR is not allowed.", + Network.class, network.getId()); + } + + // Make sure the shared network is present + NetworkOffering offering = _ntwkOfferingDao.findById(network.getNetworkOfferingId()); + if (!implement(network.getPhysicalNetworkId(), vspNetwork, _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()); + } + } // Set flags for dhcp options boolean networkHasDns = networkHasDns(network); @@ -275,7 +330,6 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { //that we create in VSP NicVO nicFromDb = _nicDao.findById(nic.getId()); IPAddressVO staticNatIp = _ipAddressDao.findByVmIdAndNetworkId(network.getId(), vm.getId()); - VspVm vspVm = _nuageVspEntityBuilder.buildVspVm(vm.getVirtualMachine(), network); VspNic vspNic = _nuageVspEntityBuilder.buildVspNic(nicFromDb.getUuid(), nic); VspStaticNat vspStaticNat = null; @@ -317,20 +371,30 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { if(s_logger.isDebugEnabled()) { s_logger.debug(String.format("DomainRouter is added to an existing network: %s in state: %s", network.getName(), network.getState())); } - List dhcpOptions = Lists.newLinkedList(); - for (NicVO userNic :_nicDao.listByNetworkId(network.getId())) { - if (userNic.getVmType() != VirtualMachine.Type.DomainRouter) { - boolean defaultHasDns = getDefaultHasDns(networkHasDnsCache, userNic); - dhcpOptions.add(_nuageVspEntityBuilder.buildVmDhcpOption(userNic, defaultHasDns, networkHasDns)); + + List userNics = _nicDao.listByNetworkId(network.getId()); + LinkedListMultimap dhcpOptionsPerDomain = LinkedListMultimap.create(); + + for (NicVO userNic : userNics) { + if (userNic.getVmType() == VirtualMachine.Type.DomainRouter) { + continue; } + + VMInstanceVO userVm = _vmInstanceDao.findById(userNic.getInstanceId()); + boolean defaultHasDns = getDefaultHasDns(networkHasDnsCache, userNic); + VspDhcpVMOption dhcpOption = _nuageVspEntityBuilder.buildVmDhcpOption(userNic, defaultHasDns, networkHasDns); + dhcpOptionsPerDomain.put(userVm.getDomainId(), dhcpOption); } - if (!dhcpOptions.isEmpty()) { - UpdateDhcpOptionVspCommand cmd = new UpdateDhcpOptionVspCommand(dhcpOptions, vspNetwork); + for (Long domainId : dhcpOptionsPerDomain.keySet()) { + VspDomain vspDomain = _nuageVspEntityBuilder.buildVspDomain(_domainDao.findById(domainId)); + VspNetwork vspNetworkForDomain = new VspNetwork.Builder().fromObject(vspNetwork).domain(vspDomain).build(); + List dhcpOptions = dhcpOptionsPerDomain.get(domainId); + UpdateDhcpOptionVspCommand cmd = new UpdateDhcpOptionVspCommand(dhcpOptions, vspNetworkForDomain); Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd); if (answer == null || !answer.getResult()) { - s_logger.error("UpdateDhcpOptionVspCommand failed at \"reserve\" for network " + vspNetwork.getName()); + s_logger.error("UpdateDhcpOptionVspCommand failed at \"reserve\" for network " + vspNetwork.getName() + " under domain " + vspNetwork.getVspDomain().getName()); if ((null != answer) && (null != answer.getDetails())) { s_logger.error(answer.getDetails()); } @@ -339,34 +403,65 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { } } + private void checkMultipleSubnetsCombinedWithUseData(Network network) { + if (_ntwkOfferingSrvcDao.listServicesForNetworkOffering(network.getNetworkOfferingId()).contains(Network.Service.UserData.getName())) { + List vlanVOs = _vlanDao.listVlansByNetworkId(network.getId()); + if (vlanVOs.size() > 1) { + VlanVO vlanVoItem = vlanVOs.get(0); + for (VlanVO VlanVoItem2 : FluentIterable.from(vlanVOs).skip(1)) { + if (!vlanVoItem.equals(VlanVoItem2) + && !VlanVoItem2.getVlanGateway().equals(vlanVoItem.getVlanGateway())) { + s_logger.error("NuageVsp provider does not support multiple subnets in combination with user data. Network: " + network + ", vlans: " + vlanVOs); + throw new UnsupportedServiceException("NuageVsp provider does not support multiple subnets in combination with user data."); + } + } + } + } + } + @Override protected boolean canHandle(NetworkOffering offering, final NetworkType networkType, final PhysicalNetwork physicalNetwork) { - if (networkType == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && (offering.getGuestType() == Network.GuestType.Isolated || offering.getGuestType() == Network.GuestType.Shared) - && isMyIsolationMethod(physicalNetwork) && hasRequiredServices(offering)) { + if (networkType == NetworkType.Advanced + && isMyTrafficType(offering.getTrafficType()) + && isMyIsolationMethod(physicalNetwork) + && (offering.getGuestType() == Network.GuestType.Isolated || offering.getGuestType() == Network.GuestType.Shared) + && hasRequiredServices(offering)) { if (_configMgr.isOfferingForVpc(offering) && !offering.getIsPersistent()) { if (s_logger.isDebugEnabled()) { s_logger.debug("NuageVsp can't handle VPC tiers which use a network offering which are not persistent"); } return false; + } else if (offering.getGuestType() == GuestType.Shared) { + List supportedSharedNetworkServices = Lists.newArrayList(Network.Service.Connectivity.getName(), Network.Service.Dhcp.getName(), Network.Service.UserData.getName()); + List offeringServices = _ntwkOfferingSrvcDao.listServicesForNetworkOffering(offering.getId()); + if (!supportedSharedNetworkServices.containsAll(offeringServices)) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("We only support " + Iterables.toString(supportedSharedNetworkServices) + " services for shared networks"); + } + return false; + } } return true; } else { if (s_logger.isTraceEnabled()) { - s_logger.trace("We only take care of Guest networks of type " + GuestType.Isolated + " in zone of type " + NetworkType.Advanced); + s_logger.trace("We only take care of networks in zone of type " + NetworkType.Advanced + " without VLAN"); } return false; } } private boolean hasRequiredServices(NetworkOffering networkOffering) { - if (!_ntwkOfferingSrvcDao.canProviderSupportServiceInNetworkOffering(networkOffering.getId(), Network.Service.Connectivity, Network.Provider.NuageVsp)) { + final Map> serviceProviderMap = _networkModel.getNetworkOfferingServiceProvidersMap(networkOffering.getId()); + + if (!serviceProviderMap.get(Network.Service.Connectivity).contains(Network.Provider.NuageVsp)) { if (s_logger.isDebugEnabled()) { s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as Connectivity provider"); } return false; } - if (!_ntwkOfferingSrvcDao.canProviderSupportServiceInNetworkOffering(networkOffering.getId(), Network.Service.SourceNat, Network.Provider.NuageVsp)) { + if (networkOffering.getGuestType() == GuestType.Isolated + && !serviceProviderMap.get(Network.Service.SourceNat).contains(Network.Provider.NuageVsp)) { if (s_logger.isDebugEnabled()) { s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as SourceNat provider"); } @@ -391,7 +486,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { NicVO nicFromDb = _nicDao.findById(nic.getId()); - VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network, false); + VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(vm.getVirtualMachine().getDomainId(), network); VspVm vspVm = _nuageVspEntityBuilder.buildVspVm(vm.getVirtualMachine(), network); VspNic vspNic = _nuageVspEntityBuilder.buildVspNic(nicFromDb.getUuid(), nic); HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId()); @@ -404,6 +499,14 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { s_logger.error(answer.getDetails()); } } + + // In case of shared network, when a User VM is spawned with the same IP as the VR, and it gets cleaned up, make sure we do not release the public IP + // because it is still allocated for the VR. + if (vspNetwork.isShared() && VirtualMachine.Type.User.equals(vm.getType()) && nic.getIPv4Address().equals(vspNetwork.getVirtualRouterIp())) { + nic.deallocate(); + } else { + super.deallocate(network, nic, vm); + } } finally { if (network != null && lockedNetwork) { _networkDao.releaseFromLockTable(network.getId()); @@ -412,8 +515,6 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { } } } - - super.deallocate(network, nic, vm); } private boolean lockNetworkForUserVm(Network network, VirtualMachineProfile vm) { @@ -445,7 +546,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { if (s_logger.isDebugEnabled()) { s_logger.debug("Handling trash() call back to delete the network " + network.getName() + " with uuid " + network.getUuid() + " from VSP"); } - VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network, false); + VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network); HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId()); TrashNetworkVspCommand cmd = new TrashNetworkVspCommand(vspNetwork); Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd); @@ -489,9 +590,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { private Long getDefaultNetwork(long vmId) { NicVO defaultNic = _nicDao.findDefaultNicForVM(vmId); - if (defaultNic != null) { - return defaultNic.getNetworkId(); - } + if (defaultNic != null) return defaultNic.getNetworkId(); return null; } diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java index e5c9871dbef..9f46012dab2 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java @@ -27,7 +27,6 @@ import com.cloud.api.response.NuageVlanIpRangeResponse; import com.cloud.api.response.NuageVspDeviceResponse; import com.cloud.dc.Vlan; import com.cloud.host.HostVO; -import com.cloud.network.Network; import com.cloud.network.NuageVspDeviceVO; import com.cloud.utils.component.PluggableService; import org.apache.cloudstack.framework.config.ConfigKey; @@ -84,7 +83,7 @@ public interface NuageVspManager extends PluggableService { List listNuageVspDevices(ListNuageVspDevicesCmd cmd); - List getDnsDetails(Network network); + List getDnsDetails(long dataCenterId); List getGatewaySystemIds(); diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java index 7bc36e27d85..3a90163893e 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java @@ -19,6 +19,49 @@ package com.cloud.network.manager; +import static com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand.SyncType; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.ExecutionException; + +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import net.nuage.vsp.acs.client.api.NuageVspPluginClientLoader; +import net.nuage.vsp.acs.client.api.model.VspApiDefaults; +import net.nuage.vsp.acs.client.api.model.VspDomain; +import net.nuage.vsp.acs.client.api.model.VspDomainCleanUp; +import net.nuage.vsp.acs.client.api.model.VspHost; +import net.nuage.vsp.acs.client.common.NuageVspApiVersion; +import net.nuage.vsp.acs.client.common.NuageVspConstants; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Strings; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; + +import org.apache.cloudstack.api.ResponseGenerator; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.framework.config.impl.ConfigurationVO; +import org.apache.cloudstack.framework.messagebus.MessageBus; +import org.apache.cloudstack.framework.messagebus.MessageSubscriber; +import org.apache.cloudstack.network.ExternalNetworkDeviceManager; + import com.cloud.agent.AgentManager; import com.cloud.agent.Listener; import com.cloud.agent.api.AgentControlAnswer; @@ -27,11 +70,12 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.PingNuageVspCommand; import com.cloud.agent.api.StartupCommand; +import com.cloud.agent.api.manager.CleanUpDomainCommand; import com.cloud.agent.api.manager.EntityExistsCommand; import com.cloud.agent.api.manager.GetApiDefaultsAnswer; import com.cloud.agent.api.manager.GetApiDefaultsCommand; import com.cloud.agent.api.manager.SupportedApiVersionCommand; -import com.cloud.agent.api.sync.SyncDomainAnswer; +import com.cloud.agent.api.manager.UpdateNuageVspDeviceCommand; import com.cloud.agent.api.sync.SyncDomainCommand; import com.cloud.agent.api.sync.SyncNuageVspCmsIdAnswer; import com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand; @@ -79,6 +123,7 @@ import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; import com.cloud.network.dao.PhysicalNetworkServiceProviderVO; import com.cloud.network.dao.PhysicalNetworkVO; import com.cloud.network.resource.NuageVspResource; +import com.cloud.network.resource.NuageVspResourceConfiguration; import com.cloud.network.vpc.VpcManager; import com.cloud.network.vpc.VpcOffering; import com.cloud.network.vpc.VpcOfferingServiceMapVO; @@ -96,6 +141,7 @@ import com.cloud.resource.ResourceManager; import com.cloud.resource.ResourceState; import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; +import com.cloud.util.NuageVspEntityBuilder; import com.cloud.util.NuageVspUtil; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; @@ -106,41 +152,6 @@ import com.cloud.utils.db.TransactionStatus; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.fsm.StateListener; import com.cloud.utils.fsm.StateMachine2; -import com.google.common.base.Joiner; -import com.google.common.base.MoreObjects; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; -import com.cloud.util.NuageVspEntityBuilder; -import net.nuage.vsp.acs.NuageVspPluginClientLoader; -import net.nuage.vsp.acs.client.api.model.VspApiDefaults; -import net.nuage.vsp.acs.client.api.model.VspDomain; -import org.apache.cloudstack.api.ResponseGenerator; -import org.apache.cloudstack.framework.config.ConfigKey; -import org.apache.cloudstack.framework.config.Configurable; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; -import org.apache.cloudstack.framework.config.impl.ConfigurationVO; -import org.apache.cloudstack.framework.messagebus.MessageBus; -import org.apache.cloudstack.framework.messagebus.MessageSubscriber; -import org.apache.cloudstack.network.ExternalNetworkDeviceManager; -import org.apache.commons.collections.CollectionUtils; -import org.apache.log4j.Logger; - -import javax.inject.Inject; -import javax.naming.ConfigurationException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ExecutionException; - -import static com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand.SyncType; public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, Configurable, StateListener { @@ -149,6 +160,7 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, public static final Map> NUAGE_VSP_VPC_SERVICE_MAP; private static final ConfigKey[] NUAGE_VSP_CONFIG_KEYS = new ConfigKey[] { NuageVspConfigDns, NuageVspDnsExternal, NuageVspConfigGateway, NuageVspSharedNetworkDomainTemplateName, NuageVspVpcDomainTemplateName, NuageVspIsolatedNetworkDomainTemplateName }; + public static final String CMSID_CONFIG_KEY = "nuagevsp.cms.id"; @Inject ResourceManager _resourceMgr; @@ -255,37 +267,65 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, throw new CloudRuntimeException("A NuageVsp device is already configured on this physical network"); } + // While the default VSD port is 8443, clustering via HAProxy will go over port 443 (CLOUD-58) + int port = cmd.getPort() > 0 ? cmd.getPort() : 443; + try { - NuageVspPluginClientLoader clientLoader = NuageVspPluginClientLoader.getClientLoader(null, null, null, null, 1, 1, null); + String apiVersion = null; - VspApiDefaults apiDefaults = clientLoader.getNuageVspManagerClient().getApiDefaults(); - String apiVersion = MoreObjects.firstNonNull(cmd.getApiVersion(), apiDefaults.getVersion()); - if (!clientLoader.getNuageVspManagerClient().isSupportedApiVersion(apiVersion)) { - throw new CloudRuntimeException("Unsupported API version : " + apiVersion); - } - - int port = cmd.getPort(); - if (0 == port) { - port = 443; - } String cmsUserPasswordBase64 = NuageVspUtil.encodePassword(cmd.getPassword()); - String retryCount = String.valueOf(MoreObjects.firstNonNull(cmd.getApiRetryCount(), apiDefaults.getRetryCount())); - String retryInterval = String.valueOf(MoreObjects.firstNonNull(cmd.getApiRetryInterval(), apiDefaults.getRetryInterval())); - NuageVspResource.Configuration resourceConfiguration = new NuageVspResource.Configuration() - .name("Nuage VSD - " + cmd.getHostName()) + + NuageVspResourceConfiguration resourceConfiguration = new NuageVspResourceConfiguration() .guid(UUID.randomUUID().toString()) .zoneId(String.valueOf(physicalNetwork.getDataCenterId())) .hostName(cmd.getHostName()) .cmsUser(cmd.getUserName()) .cmsUserPassword(cmsUserPasswordBase64) .port(String.valueOf(port)) + .apiVersion(NuageVspApiVersion.CURRENT.toString()) + .retryCount(NuageVspConstants.DEFAULT_API_RETRY_COUNT.toString()) + .retryInterval(NuageVspConstants.DEFAULT_API_RETRY_INTERVAL.toString()) + .apiRelativePath("/nuage"); + + VspHost vspHost = resourceConfiguration.buildVspHost(); + NuageVspPluginClientLoader clientLoader = NuageVspPluginClientLoader.getClientLoader(vspHost); + VspApiDefaults apiDefaults = clientLoader.getNuageVspManagerClient().getApiDefaults(); + + + if (StringUtils.isNotBlank(cmd.getApiVersion())){ + if (!clientLoader.getNuageVspManagerClient().isSupportedApiVersion(cmd.getApiVersion())){ + throw new CloudRuntimeException("Unsupported API version : " + cmd.getApiVersion()); + } + apiVersion = cmd.getApiVersion(); + } else { + boolean apiVersionFound = false; + Map supportedVersions = clientLoader.getNuageVspManagerClient().getSupportedVersions(); + for (NuageVspApiVersion selectedVersion : supportedVersions.keySet()) { + if (supportedVersions.get(selectedVersion) == NuageVspApiVersion.Status.CURRENT){ + apiVersion = selectedVersion.toString(); + apiVersionFound = true; + break; + } + } + + if(!apiVersionFound) { + throw new CloudRuntimeException("No supported API version found!"); + } + } + + + String retryCount = String.valueOf(MoreObjects.firstNonNull(cmd.getApiRetryCount(), apiDefaults.getRetryCount())); + String retryInterval = String.valueOf(MoreObjects.firstNonNull(cmd.getApiRetryInterval(), apiDefaults.getRetryInterval())); + + resourceConfiguration .apiVersion(apiVersion) .apiRelativePath("/nuage/api/" + apiVersion) .retryCount(retryCount) .retryInterval(retryInterval); - Map hostDetails = resourceConfiguration.build(); - resource.configure(cmd.getHostName(), Maps.newHashMap(hostDetails)); + resource.configure("Nuage VSD - " + cmd.getHostName(), Maps.newHashMap(hostDetails)); + + Host host = _resourceMgr.addHost(zoneId, resource, Host.Type.L2Networking, hostDetails); if (host == null) { throw new CloudRuntimeException("Failed to add Nuage Vsp Device due to internal error."); @@ -297,11 +337,10 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, DetailVO detail = new DetailVO(host.getId(), "nuagevspdeviceid", String.valueOf(nuageVspDevice.getId())); _hostDetailsDao.persist(detail); - ConfigurationVO cmsIdConfig = _configDao.findByName("nuagevsp.cms.id"); NuageVspDeviceVO matchingNuageVspDevice = findMatchingNuageVspDevice(nuageVspDevice); String cmsId; if (matchingNuageVspDevice != null) { - cmsId = findNuageVspCmsIdForDevice(matchingNuageVspDevice.getId(), cmsIdConfig); + cmsId = findNuageVspCmsIdForDeviceOrHost(matchingNuageVspDevice.getId(), matchingNuageVspDevice.getHostId()); } else { SyncNuageVspCmsIdCommand syncCmd = new SyncNuageVspCmsIdCommand(SyncType.REGISTER, null); SyncNuageVspCmsIdAnswer answer = (SyncNuageVspCmsIdAnswer) _agentMgr.easySend(nuageVspDevice.getHostId(), syncCmd); @@ -313,10 +352,7 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, } host = findNuageVspHost(nuageVspDevice.getHostId()); - registerNewNuageVspDevice(cmsIdConfig, nuageVspDevice.getId() + ":" + cmsId); - - detail = new DetailVO(host.getId(), "nuagevspcmsid", cmsId); - _hostDetailsDao.persist(detail); + registerNewNuageVspDevice(host.getId(), cmsId); resourceConfiguration.nuageVspCmsId(cmsId); resource.configure(cmd.getHostName(), Maps.newHashMap(resourceConfiguration.build())); @@ -368,56 +404,73 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, _hostDao.loadDetails(nuageVspHost); } - boolean updateRequired = false; - NuageVspResource.Configuration resourceConfiguration = NuageVspResource.Configuration.fromConfiguration(nuageVspHost.getDetails()); + boolean resourceConfigurationChanged = false; + NuageVspResourceConfiguration resourceConfiguration = NuageVspResourceConfiguration.fromConfiguration(nuageVspHost.getDetails()); if (!Strings.isNullOrEmpty(command.getHostName()) && !command.getHostName().equals(resourceConfiguration.hostName())) { - resourceConfiguration.name("Nuage VSD - " + command.getHostName()); resourceConfiguration.hostName(command.getHostName()); - updateRequired = true; + resourceConfigurationChanged = true; } if (!Strings.isNullOrEmpty(command.getUserName()) && !command.getUserName().equals(resourceConfiguration.cmsUser())) { resourceConfiguration.cmsUser(command.getUserName()); - updateRequired = true; + resourceConfigurationChanged = true; } if (!Strings.isNullOrEmpty(command.getPassword())) { String encodedNewPassword = NuageVspUtil.encodePassword(command.getPassword()); if (!encodedNewPassword.equals(resourceConfiguration.cmsUserPassword())) { resourceConfiguration.cmsUserPassword(encodedNewPassword); - updateRequired = true; + resourceConfigurationChanged = true; } } if (command.getPort() != null && command.getPort() != Integer.parseInt(resourceConfiguration.port())) { resourceConfiguration.port(String.valueOf(command.getPort())); - updateRequired = true; + resourceConfigurationChanged = true; } - GetApiDefaultsCommand apiDefaultsCmd = new GetApiDefaultsCommand(); - GetApiDefaultsAnswer apiDefaultsAnswer = (GetApiDefaultsAnswer) _agentMgr.easySend(nuageVspHost.getId(), apiDefaultsCmd); String apiVersion = MoreObjects.firstNonNull(command.getApiVersion(), resourceConfiguration.apiVersion()); - SupportedApiVersionCommand supportedApiVersionCmd = new SupportedApiVersionCommand(apiVersion); - Answer supportedApiVersionAnswer = _agentMgr.easySend(nuageVspHost.getId(), supportedApiVersionCmd); - if (!supportedApiVersionAnswer.getResult()) { - throw new CloudRuntimeException("Incorrect API version: Nuage plugin only supports " + apiDefaultsAnswer.getApiDefaults().getVersion()); + NuageVspApiVersion apiVersionObj = NuageVspApiVersion.fromString(apiVersion); + NuageVspApiVersion apiVersionCurrent = null; + try { + apiVersionCurrent = resourceConfiguration.getApiVersion(); + } catch (ConfigurationException e){ + throw new CloudRuntimeException("Current version is not configured correctly"); } - String apiRelativePath = "/nuage/api/" + apiVersion; - if (!apiRelativePath.equals(resourceConfiguration.apiRelativePath())) { - resourceConfiguration.apiVersion(apiVersion); - resourceConfiguration.apiRelativePath(apiRelativePath); - updateRequired = true; + + if(command.getApiVersion() != null){ + if(apiVersionObj.compareTo(apiVersionCurrent) < 0) { + throw new CloudRuntimeException("Downgrading is not supported"); + } + + GetApiDefaultsCommand apiDefaultsCmd = new GetApiDefaultsCommand(); + GetApiDefaultsAnswer apiDefaultsAnswer = (GetApiDefaultsAnswer) _agentMgr.easySend(nuageVspHost.getId(), apiDefaultsCmd); + + SupportedApiVersionCommand supportedApiVersionCmd = new SupportedApiVersionCommand(apiVersion); + Answer supportedApiVersionAnswer = _agentMgr.easySend(nuageVspHost.getId(), supportedApiVersionCmd); + + if (!supportedApiVersionAnswer.getResult()) { + throw new CloudRuntimeException("Incorrect API version: Nuage plugin only supports " + apiDefaultsAnswer.getApiDefaults().getVersion()); + } + + String apiRelativePath = "/nuage/api/" + apiVersion; + if (!apiRelativePath.equals(resourceConfiguration.apiRelativePath())) { + resourceConfiguration.apiVersion(apiVersion); + resourceConfiguration.apiRelativePath(apiRelativePath); + resourceConfigurationChanged = true; + } + } if (command.getApiRetryCount() != null && resourceConfiguration.retryCount() != null) { final int retryCount = Integer.parseInt(resourceConfiguration.retryCount()); if (command.getApiRetryCount() != retryCount) { resourceConfiguration.retryCount(String.valueOf(command.getApiRetryCount())); - updateRequired = true; + resourceConfigurationChanged = true; } } @@ -425,11 +478,11 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, final int apiRetryInterval = Integer.parseInt(resourceConfiguration.retryInterval()); if (command.getApiRetryInterval() != apiRetryInterval) { resourceConfiguration.retryInterval(String.valueOf(command.getApiRetryInterval())); - updateRequired = true; + resourceConfigurationChanged = true; } } - if (!updateRequired) { + if (!resourceConfigurationChanged) { if (s_logger.isDebugEnabled()) { s_logger.debug("No change in the NuageVsp device parameters. None of the NuageVsp device parameters are modified"); } @@ -437,13 +490,21 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, } Map config = resourceConfiguration.build(); - String updateParameters = "{" + Joiner.on(", ").withKeyValueSeparator(": ").join(config) + "}"; - Map hostDetails = Maps.newHashMap(config); try { - resource.configure(resourceConfiguration.hostName(), hostDetails); + resource.validate(config); + + UpdateNuageVspDeviceCommand cmd = new UpdateNuageVspDeviceCommand(resourceConfiguration); + Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer == null || !answer.getResult()) { + s_logger.error("UpdateNuageVspDeviceCommand failed"); + if ((null != answer) && (null != answer.getDetails())) { + throw new CloudRuntimeException(answer.getDetails()); + } + } + _hostDetailsDao.persist(nuageVspDevice.getHostId(), config); } catch (ConfigurationException e) { - throw new CloudRuntimeException("Failed to update Nuage VSP device " + nuageVspDevice.getId() + " with parameters " + updateParameters, e); + throw new CloudRuntimeException("Failed to update Nuage VSP device " + nuageVspDevice.getId() + " with parameters " + resourceConfiguration, e); } return nuageVspDevice; } @@ -453,7 +514,7 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, HostVO nuageVspHost = _hostDao.findById(nuageVspDeviceVO.getHostId()); _hostDao.loadDetails(nuageVspHost); - NuageVspResource.Configuration resourceConfiguration = NuageVspResource.Configuration.fromConfiguration(nuageVspHost.getDetails()); + NuageVspResourceConfiguration resourceConfiguration = NuageVspResourceConfiguration.fromConfiguration(nuageVspHost.getDetails()); NuageVspDeviceResponse response = new NuageVspDeviceResponse(); response.setDeviceName(nuageVspDeviceVO.getDeviceName()); PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(nuageVspDeviceVO.getPhysicalNetworkId()); @@ -500,10 +561,10 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, } NuageVspDeviceVO matchingNuageVspDevice = findMatchingNuageVspDevice(nuageVspDevice); - ConfigurationVO cmsIdConfig = _configDao.findByName("nuagevsp.cms.id"); - HostVO host = findNuageVspHost(nuageVspDevice.getHostId()); - String nuageVspCmsId = findNuageVspCmsIdForDevice(nuageVspDevice.getId(), cmsIdConfig); + + String nuageVspCmsId = findNuageVspCmsIdForDeviceOrHost(nuageVspDevice.getId(), nuageVspDevice.getHostId()); if (matchingNuageVspDevice == null) { + HostVO host = findNuageVspHost(nuageVspDevice.getHostId()); if (!auditDomainsOnVsp(host, false)) { return false; } @@ -515,15 +576,7 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, } } - String newValue = cmsIdConfig.getValue().replace(nuageVspDevice.getId() + ":" + nuageVspCmsId, ""); - if (newValue.startsWith(";")) { - newValue = newValue.substring(1); - } - if (newValue.endsWith(";")) { - newValue = newValue.substring(0, newValue.length() - 1); - } - newValue = newValue.replaceAll(";+", ";"); - _configDao.update("nuagevsp.cms.id", newValue); + removeLegacyNuageVspDeviceCmsId(nuageVspDevice.getId()); HostVO nuageHost = _hostDao.findById(nuageVspDevice.getHostId()); Long hostId = nuageHost.getId(); @@ -537,15 +590,15 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, } private NuageVspDeviceVO findMatchingNuageVspDevice(NuageVspDeviceVO nuageVspDevice) { + DetailVO nuageVspDeviceHost = _hostDetailsDao.findDetail(nuageVspDevice.getHostId(), "hostname"); + String nuageVspDeviceHostName = (nuageVspDeviceHost != null) ? nuageVspDeviceHost.getValue(): null; + List otherNuageVspDevices = _nuageVspDao.listAll(); for (NuageVspDeviceVO otherNuageVspDevice : otherNuageVspDevices) { if (otherNuageVspDevice.getId() == nuageVspDevice.getId()) continue; - HostVO nuageVspDeviceHost = findNuageVspHost(nuageVspDevice.getHostId()); - HostVO otherNuageVspDeviceHost = findNuageVspHost(otherNuageVspDevice.getHostId()); - String nuageVspDeviceHostName = nuageVspDeviceHost.getDetail("hostname"); - String otherNuageVspDeviceHostName = otherNuageVspDeviceHost.getDetail("hostname"); - if (otherNuageVspDeviceHostName != null && otherNuageVspDeviceHostName.equals(nuageVspDeviceHostName)) { + DetailVO otherNuageVspDeviceHostName = _hostDetailsDao.findDetail(otherNuageVspDevice.getHostId(), "hostname"); + if (otherNuageVspDeviceHostName != null && nuageVspDeviceHostName.equals(otherNuageVspDeviceHostName.getValue())) { return otherNuageVspDevice; } } @@ -579,24 +632,51 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, return responseList; } - private void registerNewNuageVspDevice(ConfigurationVO currentConfig, String registeredNuageVspDevice) { - if (currentConfig == null) { - ConfigKey configKey = new ConfigKey("Advanced", String.class, "nuagevsp.cms.id", registeredNuageVspDevice, - ": - Do not edit", false); - ConfigurationVO configuration = new ConfigurationVO("management-server", configKey); - _configDao.persist(configuration); - } else { - String newValue; - String currentValue = currentConfig.getValue(); - if (!Strings.isNullOrEmpty(currentValue)) { - newValue = currentValue + ";" + registeredNuageVspDevice; + private void registerNewNuageVspDevice(long hostId, String cmsId) { + DetailVO detail = new DetailVO(hostId, "nuagevspcmsid", cmsId); + _hostDetailsDao.persist(detail); + } + + @Deprecated + private void removeLegacyNuageVspDeviceCmsId(long deviceId) { + ConfigurationVO cmsIdConfig = _configDao.findByName(CMSID_CONFIG_KEY); + if (cmsIdConfig != null) { + if (!cmsIdConfig.getValue().contains(";") && cmsIdConfig.getValue().startsWith(deviceId + ":")) { + _configDao.update(CMSID_CONFIG_KEY, "Advanced", ""); } else { - newValue = registeredNuageVspDevice; + String newValue = cmsIdConfig.getValue().replace(String.format("(^|;)%d:[0-9a-f\\-]+;?", deviceId), ";"); + _configDao.update(CMSID_CONFIG_KEY, "Advanced", newValue); } - _configDao.update("nuagevsp.cms.id", newValue); } } + public boolean executeSyncCmsId(NuageVspDeviceVO nuageVspDevice, SyncType syncType) { + NuageVspDeviceVO matchingNuageVspDevice = findMatchingNuageVspDevice(nuageVspDevice); + if (syncType == SyncType.REGISTER && matchingNuageVspDevice != null) { + String cmsId = findNuageVspCmsIdForDeviceOrHost(matchingNuageVspDevice.getId(), matchingNuageVspDevice.getHostId()); + registerNewNuageVspDevice(nuageVspDevice.getHostId(), cmsId); + return true; + } + + String cmsId = findNuageVspCmsIdForDeviceOrHost(nuageVspDevice.getId(), nuageVspDevice.getHostId()); + + SyncNuageVspCmsIdCommand syncCmd = new SyncNuageVspCmsIdCommand(syncType, cmsId); + SyncNuageVspCmsIdAnswer answer = (SyncNuageVspCmsIdAnswer) _agentMgr.easySend(nuageVspDevice.getHostId(), syncCmd); + if (answer != null) { + if (answer.getSuccess()) { + if (syncType == SyncType.REGISTER || answer.getSyncType() == SyncType.REGISTER) { + registerNewNuageVspDevice(nuageVspDevice.getHostId(), answer.getNuageVspCmsId()); + } else if (syncType == SyncType.UNREGISTER) { + removeLegacyNuageVspDeviceCmsId(nuageVspDevice.getId()); + } + } else if (syncType == SyncType.AUDIT || syncType == SyncType.AUDIT_ONLY) { + s_logger.fatal("Nuage VSP Device with ID " + nuageVspDevice.getId() + " is configured with an unknown CMS ID!"); + } + } + + return answer != null && answer.getSuccess(); + } + private void auditHost(HostVO host) { if (host == null) return; @@ -606,8 +686,7 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, List nuageVspDevices = _nuageVspDao.listByHost(host.getId()); if (!CollectionUtils.isEmpty(nuageVspDevices)) { for (NuageVspDeviceVO nuageVspDevice : nuageVspDevices) { - ConfigurationVO cmsIdConfig = _configDao.findByName("nuagevsp.cms.id"); - String nuageVspCmsId = findNuageVspCmsIdForDevice(nuageVspDevice.getId(), cmsIdConfig); + String nuageVspCmsId = findNuageVspCmsIdForDeviceOrHost(nuageVspDevice.getId(), nuageVspDevice.getHostId()); SyncNuageVspCmsIdCommand syncCmd = new SyncNuageVspCmsIdCommand(SyncType.AUDIT, nuageVspCmsId); SyncNuageVspCmsIdAnswer answer = (SyncNuageVspCmsIdAnswer) _agentMgr.easySend(nuageVspDevice.getHostId(), syncCmd); @@ -615,7 +694,7 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, s_logger.error("Nuage VSP Device with ID " + nuageVspDevice.getId() + " is configured with an unknown CMS ID!"); validateDomains = false; } else if (answer != null && answer.getSyncType() == SyncType.REGISTER) { - registerNewNuageVspDevice(cmsIdConfig, nuageVspDevice.getId() + ":" + answer.getNuageVspCmsId()); + registerNewNuageVspDevice(nuageVspDevice.getHostId(), answer.getNuageVspCmsId()); } } } @@ -631,42 +710,82 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, return true; } + final SyncDomainCommand.Type action = add ? SyncDomainCommand.Type.ADD : SyncDomainCommand.Type.REMOVE; + _hostDao.loadDetails(host); List allDomains = _domainDao.listAll(); for (DomainVO domain : allDomains) { + if (action == SyncDomainCommand.Type.REMOVE) { + VspDomainCleanUp vspDomainCleanUp = _nuageVspEntityBuilder.buildVspDomainCleanUp(domain); + CleanUpDomainCommand cmd = new CleanUpDomainCommand(vspDomainCleanUp); + Answer answer = _agentMgr.easySend(host.getId(), cmd); + if (!answer.getResult()) { + return false; + } + } + VspDomain vspDomain = _nuageVspEntityBuilder.buildVspDomain(domain); - SyncDomainCommand cmd = new SyncDomainCommand(vspDomain, add ? SyncDomainCommand.Type.ADD : SyncDomainCommand.Type.REMOVE); - SyncDomainAnswer answer = (SyncDomainAnswer) _agentMgr.easySend(host.getId(), cmd); - return answer.getSuccess(); + SyncDomainCommand cmd = new SyncDomainCommand(vspDomain, action); + Answer answer = _agentMgr.easySend(host.getId(), cmd); + if (!answer.getResult()) { + return false; + } } return true; } - private String findNuageVspCmsIdForDevice(long deviceId, ConfigurationVO cmsIdConfig) { - String configValue = cmsIdConfig.getValue(); - if (!Strings.isNullOrEmpty(configValue)) { - String[] configuredNuageVspDevices = configValue.split(";"); - for (String configuredNuageVspDevice : configuredNuageVspDevices) { - if (configuredNuageVspDevice.startsWith(deviceId + ":")) { - String[] split = configuredNuageVspDevice.split(":"); - if (split.length != 2 || (split.length > 1 && Strings.isNullOrEmpty(split[1]))) { - throw new IllegalArgumentException("The configured CMS ID for Nuage VSP device " + deviceId + " is in an incorrect format"); + private String findNuageVspCmsIdForDeviceOrHost(long deviceId, long hostId) { + String cmsId = findNuageVspCmsIdForHostDevice(hostId); + if(cmsId == null) { + cmsId = findNuageVspCmsIdForDevice(deviceId); + + if (cmsId != null) { + // Upgrade + registerNewNuageVspDevice(hostId, cmsId); + removeLegacyNuageVspDeviceCmsId(deviceId); + } + } + + return cmsId; + } + + private String findNuageVspCmsIdForHostDevice(long hostId) { + final DetailVO cmsIdDetailVO = _hostDetailsDao.findDetail(hostId, "nuagevspcmsid"); + if (cmsIdDetailVO != null) { + return cmsIdDetailVO.getValue(); + } + return null; + } + + @Deprecated + private String findNuageVspCmsIdForDevice(long deviceId) { + ConfigurationVO cmsIdConfig = _configDao.findByName(CMSID_CONFIG_KEY); + if(cmsIdConfig != null) { + String configValue = cmsIdConfig.getValue(); + if (!Strings.isNullOrEmpty(configValue)) { + String[] configuredNuageVspDevices = configValue.split(";"); + for (String configuredNuageVspDevice : configuredNuageVspDevices) { + if (configuredNuageVspDevice.startsWith(deviceId + ":")) { + String[] split = configuredNuageVspDevice.split(":"); + if (split.length != 2 || (split.length > 1 && Strings.isNullOrEmpty(split[1]))) { + throw new IllegalArgumentException("The configured CMS ID for Nuage VSP device " + deviceId + " is in an incorrect format"); + } + return split[1]; } - return split[1]; } } } return null; } - public List getDnsDetails(Network network) { + public List getDnsDetails(long dataCenterId) { Boolean configureDns = Boolean.valueOf(_configDao.getValue(NuageVspManager.NuageVspConfigDns.key())); if (!configureDns) { return Lists.newArrayList(); } Boolean configureExternalDns = Boolean.valueOf(_configDao.getValue(NuageVspManager.NuageVspDnsExternal.key())); - DataCenterVO dc = _dataCenterDao.findById(network.getDataCenterId()); + DataCenterVO dc = _dataCenterDao.findById(dataCenterId); List dnsServers = new ArrayList(); if (configureExternalDns) { if (!Strings.isNullOrEmpty(dc.getDns1())) { @@ -799,6 +918,20 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, } }); + // Clean up corresponding resources in VSP when deleting a CS Domain + _messageBus.subscribe(DomainManager.MESSAGE_PRE_REMOVE_DOMAIN_EVENT, new MessageSubscriber() { + @Override + public void onPublishMessage(String senderAddress, String subject, Object args) { + DomainVO domain = (DomainVO) args; + List nuageVspDevices = _nuageVspDao.listAll(); + for (NuageVspDeviceVO nuageVspDevice : nuageVspDevices) { + VspDomainCleanUp vspDomainCleanUp = _nuageVspEntityBuilder.buildVspDomainCleanUp(domain); + CleanUpDomainCommand cmd = new CleanUpDomainCommand(vspDomainCleanUp); + _agentMgr.easySend(nuageVspDevice.getHostId(), cmd); + } + } + }); + // Delete corresponding enterprise and profile in VSP when deleting a CS Domain _messageBus.subscribe(DomainManager.MESSAGE_REMOVE_DOMAIN_EVENT, new MessageSubscriber() { @Override @@ -807,8 +940,8 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, List nuageVspDevices = _nuageVspDao.listAll(); for (NuageVspDeviceVO nuageVspDevice : nuageVspDevices) { VspDomain vspDomain = _nuageVspEntityBuilder.buildVspDomain(domain); - SyncDomainCommand cmd = new SyncDomainCommand(vspDomain, SyncDomainCommand.Type.REMOVE); - _agentMgr.easySend(nuageVspDevice.getHostId(), cmd); + SyncDomainCommand syncCmd = new SyncDomainCommand(vspDomain, SyncDomainCommand.Type.REMOVE); + _agentMgr.easySend(nuageVspDevice.getHostId(), syncCmd); } } }); diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspRequestWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspRequestWrapper.java new file mode 100644 index 00000000000..2a0e0bf3eed --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspRequestWrapper.java @@ -0,0 +1,78 @@ +// +// 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.resource; + +import java.util.Hashtable; +import java.util.Set; + +import org.reflections.Reflections; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.RequestWrapper; +import com.cloud.resource.ServerResource; + +public class NuageVspRequestWrapper extends RequestWrapper { + + private static NuageVspRequestWrapper instance; + + @SuppressWarnings("rawtypes") + private final static Set> baseSet; + + static { + Reflections baseWrappers = new Reflections("com.cloud.network.vsp.resource.wrapper"); + baseSet = baseWrappers.getSubTypesOf(CommandWrapper.class); + instance = new NuageVspRequestWrapper(); + } + + private NuageVspRequestWrapper() { + init(); + } + + @SuppressWarnings("rawtypes") + private void init() { + // NuageVspResource commands + final Hashtable, CommandWrapper> vspCommands = processAnnotations(baseSet); + + resources.put(NuageVspResource.class, vspCommands); + } + + public static NuageVspRequestWrapper getInstance() { + return instance; + } + + @SuppressWarnings("rawtypes") + @Override + public Answer execute(final Command command, final ServerResource serverResource) { + final Class resourceClass = serverResource.getClass(); + + final Hashtable, CommandWrapper> resourceCommands = retrieveResource(command, resourceClass); + + CommandWrapper commandWrapper = retrieveCommands(command.getClass(), resourceCommands); + + while (commandWrapper == null) { + //Could not find the command in the given resource, will traverse the family tree. + commandWrapper = retryWhenAllFails(command, resourceClass, resourceCommands); + } + + return commandWrapper.execute(command, serverResource); + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java index 9d04ab0301a..5ffe683e500 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java @@ -19,19 +19,19 @@ package com.cloud.network.resource; -import java.util.HashMap; import java.util.Map; import java.util.concurrent.ExecutionException; -import java.util.regex.Pattern; import javax.naming.ConfigurationException; -import net.nuage.vsp.acs.NuageVspPluginClientLoader; +import net.nuage.vsp.acs.client.api.NuageVspAclClient; import net.nuage.vsp.acs.client.api.NuageVspApiClient; import net.nuage.vsp.acs.client.api.NuageVspElementClient; import net.nuage.vsp.acs.client.api.NuageVspGuruClient; import net.nuage.vsp.acs.client.api.NuageVspManagerClient; -import net.nuage.vsp.acs.client.common.model.Pair; +import net.nuage.vsp.acs.client.api.NuageVspPluginClientLoader; +import net.nuage.vsp.acs.client.api.model.VspHost; +import net.nuage.vsp.acs.client.exception.NuageVspException; import org.apache.log4j.Logger; @@ -40,191 +40,75 @@ import com.google.common.base.Strings; import com.cloud.agent.IAgentControl; import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; -import com.cloud.agent.api.MaintainAnswer; -import com.cloud.agent.api.MaintainCommand; import com.cloud.agent.api.PingCommand; import com.cloud.agent.api.PingNuageVspCommand; -import com.cloud.agent.api.ReadyAnswer; -import com.cloud.agent.api.ReadyCommand; import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupVspCommand; -import com.cloud.agent.api.element.ApplyAclRuleVspCommand; -import com.cloud.agent.api.element.ApplyStaticNatVspCommand; -import com.cloud.agent.api.element.ImplementVspCommand; -import com.cloud.agent.api.element.ShutDownVpcVspCommand; -import com.cloud.agent.api.element.ShutDownVspCommand; -import com.cloud.agent.api.guru.DeallocateVmVspCommand; -import com.cloud.agent.api.guru.ImplementNetworkVspCommand; -import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand; -import com.cloud.agent.api.guru.TrashNetworkVspCommand; -import com.cloud.agent.api.guru.UpdateDhcpOptionVspCommand; -import com.cloud.agent.api.manager.EntityExistsCommand; -import com.cloud.agent.api.manager.GetApiDefaultsAnswer; -import com.cloud.agent.api.manager.GetApiDefaultsCommand; -import com.cloud.agent.api.manager.SupportedApiVersionCommand; -import com.cloud.agent.api.sync.SyncDomainAnswer; -import com.cloud.agent.api.sync.SyncDomainCommand; -import com.cloud.agent.api.sync.SyncNuageVspCmsIdAnswer; -import com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand; -import com.cloud.dc.Vlan; import com.cloud.host.Host; import com.cloud.resource.ServerResource; -import com.cloud.util.NuageVspUtil; -import com.cloud.utils.StringUtils; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.exception.CloudRuntimeException; -import net.nuage.vsp.acs.client.common.model.NuageVspEntity; - -import static com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand.SyncType; public class NuageVspResource extends ManagerBase implements ServerResource { private static final Logger s_logger = Logger.getLogger(NuageVspResource.class); - private static final String NAME = "name"; - private static final String GUID = "guid"; - private static final String ZONE_ID = "zoneid"; - private static final String HOST_NAME = "hostname"; - private static final String CMS_USER = "cmsuser"; - private static final String CMS_USER_PASSWORD = "cmsuserpass"; - private static final String PORT = "port"; - private static final String API_VERSION = "apiversion"; - private static final String API_RELATIVE_PATH = "apirelativepath"; - private static final String RETRY_COUNT = "retrycount"; - private static final String RETRY_INTERVAL = "retryinterval"; - private static final String NUAGE_VSP_CMS_ID = "nuagevspcmsid"; - - private String _name; private String _guid; private String _zoneId; - private String _cmsUserLogin; - private String _cmsUserPassword; private String _hostName; - private String _relativePath; - private int _numRetries; - private int _retryInterval; - private String _nuageVspCmsId; private boolean _shouldAudit = true; - protected NuageVspApiClient _nuageVspApiClient; - protected NuageVspGuruClient _nuageVspGuruClient; - protected NuageVspElementClient _nuageVspElementClient; - protected NuageVspManagerClient _nuageVspManagerClient; - protected boolean _isNuageVspClientLoaded; + private VspHost _vspHost; - private static final String CMS_USER_ENTEPRISE_NAME = "CSP"; private static final String NUAGE_VSP_PLUGIN_ERROR_MESSAGE = "Nuage Vsp plugin client is not installed"; + protected NuageVspPluginClientLoader _clientLoader; - @Override - public boolean configure(String name, Map params) throws ConfigurationException { + public VspHost validate(Map params) throws ConfigurationException { + return validate(NuageVspResourceConfiguration.fromConfiguration(params)); + } - _name = (String)params.get(NAME); - if (_name == null) { - throw new ConfigurationException("Unable to find name"); + public VspHost validate(NuageVspResourceConfiguration configuration) throws ConfigurationException { + configuration.validate(); + + VspHost newVspHost = configuration.buildVspHost(); + + + if (!newVspHost.getApiVersion().isSupported()) { + s_logger.warn(String.format("[UPGRADE] API version %s of Nuage Vsp Device %s should be updated.", _vspHost.getApiVersion(), configuration.hostName())); } - _guid = (String)params.get(GUID); - if (_guid == null) { - throw new ConfigurationException("Unable to find the guid"); - } - - _zoneId = (String)params.get(ZONE_ID); - if (_zoneId == null) { - throw new ConfigurationException("Unable to find zone"); - } - - _hostName = (String)params.get(HOST_NAME); - if (Strings.isNullOrEmpty(_hostName)) { - throw new ConfigurationException("Unable to find hostname"); - } - - String cmsUser = (String)params.get(CMS_USER); - if (Strings.isNullOrEmpty(cmsUser)) { - throw new ConfigurationException("Unable to find CMS username"); - } - - String cmsUserPassBase64 = (String)params.get(CMS_USER_PASSWORD); - if (Strings.isNullOrEmpty(cmsUserPassBase64)) { - throw new ConfigurationException("Unable to find CMS password"); - } - - String port = (String)params.get(PORT); - if (Strings.isNullOrEmpty(port)) { - throw new ConfigurationException("Unable to find port"); - } - - String apiVersion = (String)params.get(API_VERSION); - if (Strings.isNullOrEmpty(apiVersion)) { - throw new ConfigurationException("Unable to find API version"); - } else if (!Pattern.matches("v\\d+_\\d+", apiVersion)) { - throw new ConfigurationException("Incorrect API version"); - } - - String apiRelativePath = (String)params.get(API_RELATIVE_PATH); - if (Strings.isNullOrEmpty(apiRelativePath) || !apiRelativePath.contains(apiVersion)) { - throw new ConfigurationException("Unable to find API version in relative path"); - } - - String retryCount = (String)params.get(RETRY_COUNT); - if (!Strings.isNullOrEmpty(retryCount)) { - try { - _numRetries = Integer.parseInt(retryCount); - } catch (NumberFormatException ex) { - throw new ConfigurationException("Number of retries has to be between 1 and 10"); - } - if ((_numRetries < 1) || (_numRetries > 10)) { - throw new ConfigurationException("Number of retries has to be between 1 and 10"); - } - } else { - throw new ConfigurationException("Unable to find number of retries"); - } - - String retryInterval = (String)params.get(RETRY_INTERVAL); - if (!Strings.isNullOrEmpty(retryInterval)) { - try { - _retryInterval = Integer.parseInt(retryInterval); - } catch (NumberFormatException ex) { - throw new ConfigurationException("Retry interval has to be between 0 and 10000 ms"); - } - if ((_retryInterval < 0) || (_retryInterval > 10000)) { - throw new ConfigurationException("Retry interval has to be between 0 and 10000 ms"); - } - } else { - throw new ConfigurationException("Unable to find retry interval"); - } - - _relativePath = new StringBuffer().append("https://").append(_hostName).append(":").append(port).append(apiRelativePath).toString(); - - String cmsUserPass = NuageVspUtil.decodePassword(cmsUserPassBase64); - _cmsUserLogin = cmsUser; - _cmsUserPassword = cmsUserPass; - - _nuageVspCmsId = (String)params.get(NUAGE_VSP_CMS_ID); - - loadNuageClient(); + _guid = configuration.guid(); + _zoneId = configuration.zoneId(); + _hostName = configuration.hostName(); + _name = configuration.name(); try { - login(); - } catch (ExecutionException | ConfigurationException e) { + final NuageVspPluginClientLoader clientLoader = getClientLoader(newVspHost); + clientLoader.getNuageVspApiClient().login(); + + _vspHost = newVspHost; + _clientLoader = clientLoader; + } catch (ExecutionException e) { s_logger.error(e.getMessage(), e); throw new CloudRuntimeException(e.getMessage(), e); } + return _vspHost; + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + if(super.configure(name, params)) { + validate(params); + } return true; } - protected void login() throws ConfigurationException, ExecutionException { - isNuageVspApiLoaded(); - _nuageVspApiClient.login(); + protected void login() throws ConfigurationException, NuageVspException { + getNuageVspApiClient().login(); } - protected void loadNuageClient() { - NuageVspPluginClientLoader clientLoader = NuageVspPluginClientLoader.getClientLoader(_relativePath, CMS_USER_ENTEPRISE_NAME, - _cmsUserLogin, _cmsUserPassword, _numRetries, _retryInterval, _nuageVspCmsId); - _nuageVspApiClient = clientLoader.getNuageVspApiClient(); - _nuageVspGuruClient = clientLoader.getNuageVspGuruClient(); - _nuageVspElementClient = clientLoader.getNuageVspElementClient(); - _nuageVspManagerClient = clientLoader.getNuageVspManagerClient(); - _isNuageVspClientLoaded = true; + protected NuageVspPluginClientLoader getClientLoader(VspHost vspHost) { + return NuageVspPluginClientLoader.getClientLoader(vspHost); } @Override @@ -237,11 +121,6 @@ public class NuageVspResource extends ManagerBase implements ServerResource { return true; } - @Override - public String getName() { - return _name; - } - @Override public Host.Type getType() { return Host.Type.L2Networking; @@ -262,20 +141,22 @@ public class NuageVspResource extends ManagerBase implements ServerResource { @Override public PingCommand getCurrentStatus(long id) { - if (Strings.isNullOrEmpty(_relativePath)) { + if (Strings.isNullOrEmpty(_vspHost.getRestRelativePath())) { s_logger.error("Refusing to ping Nuage VSD because the resource configuration is missing the relative path information"); _shouldAudit = true; return null; } - if (Strings.isNullOrEmpty(_cmsUserLogin) || Strings.isNullOrEmpty(_cmsUserPassword)) { + + if (Strings.isNullOrEmpty(_vspHost.getCmsUserLogin()) || Strings.isNullOrEmpty(_vspHost.getCmsUserPassword())) { s_logger.error("Refusing to ping Nuage VSD because the resource configuration is missing the CMS user information"); _shouldAudit = true; return null; } + try { login(); } catch (ExecutionException | ConfigurationException e) { - s_logger.error("Failed to ping to Nuage VSD on " + _name + " as user " + _cmsUserLogin, e); + s_logger.error("Failed to ping to Nuage VSD on " + _name + " as user " +_vspHost.getCmsUserLogin(), e); _shouldAudit = true; return null; } @@ -285,54 +166,16 @@ public class NuageVspResource extends ManagerBase implements ServerResource { } @Override - public Answer executeRequest(Command cmd) { - if (cmd instanceof ReadyCommand) { - return executeRequest((ReadyCommand)cmd); - } else if (cmd instanceof MaintainCommand) { - return executeRequest((MaintainCommand)cmd); + public Answer executeRequest(final Command cmd) { + final NuageVspRequestWrapper wrapper = NuageVspRequestWrapper.getInstance(); + try { + return wrapper.execute(cmd, this); + } catch (final Exception e) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received unsupported command " + cmd.toString()); + } + return Answer.createUnsupportedCommandAnswer(cmd); } - //Guru commands - else if (cmd instanceof ImplementNetworkVspCommand) { - return executeRequest((ImplementNetworkVspCommand)cmd); - } else if (cmd instanceof ReserveVmInterfaceVspCommand) { - return executeRequest((ReserveVmInterfaceVspCommand)cmd); - } else if (cmd instanceof DeallocateVmVspCommand) { - return executeRequest((DeallocateVmVspCommand)cmd); - } else if (cmd instanceof TrashNetworkVspCommand) { - return executeRequest((TrashNetworkVspCommand)cmd); - } else if (cmd instanceof UpdateDhcpOptionVspCommand) { - return executeRequest((UpdateDhcpOptionVspCommand)cmd); - } - //Element commands - else if (cmd instanceof ImplementVspCommand) { - return executeRequest((ImplementVspCommand)cmd); - } else if (cmd instanceof ApplyAclRuleVspCommand) { - return executeRequest((ApplyAclRuleVspCommand)cmd); - } else if (cmd instanceof ApplyStaticNatVspCommand) { - return executeRequest((ApplyStaticNatVspCommand)cmd); - } else if (cmd instanceof ShutDownVpcVspCommand) { - return executeRequest((ShutDownVpcVspCommand)cmd); - } else if (cmd instanceof ShutDownVspCommand) { - return executeRequest((ShutDownVspCommand)cmd); - } - //Sync Commands - else if (cmd instanceof SyncNuageVspCmsIdCommand) { - return executeRequest((SyncNuageVspCmsIdCommand)cmd); - } else if (cmd instanceof SyncDomainCommand) { - return executeRequest((SyncDomainCommand)cmd); - } - //Other commands - else if (cmd instanceof GetApiDefaultsCommand) { - return executeRequest((GetApiDefaultsCommand)cmd); - } else if (cmd instanceof SupportedApiVersionCommand) { - return executeRequest((SupportedApiVersionCommand)cmd); - } else if (cmd instanceof EntityExistsCommand) { - return executeRequest((EntityExistsCommand)cmd); - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Received unsupported command " + cmd.toString()); - } - return Answer.createUnsupportedCommandAnswer(cmd); } @Override @@ -348,369 +191,36 @@ public class NuageVspResource extends ManagerBase implements ServerResource { public void setAgentControl(IAgentControl agentControl) { } - private Answer executeRequest(ReadyCommand cmd) { - return new ReadyAnswer(cmd); - } - - private Answer executeRequest(MaintainCommand cmd) { - return new MaintainAnswer(cmd); - } - - private Answer executeRequest(ImplementNetworkVspCommand cmd) { - try { - isNuageVspGuruLoaded(); - _nuageVspGuruClient.implement(cmd.getNetwork(), cmd.getDhcpOption()); - return new Answer(cmd, true, "Created network mapping to " + cmd.getNetwork().getName() + " on Nuage VSD " + _hostName); - } catch (ExecutionException | ConfigurationException e) { - s_logger.error("Failure during " + cmd.toDetailString() + " on Nuage VSD " + _hostName, e); - return new Answer(cmd, e); - } - } - - private Answer executeRequest(ReserveVmInterfaceVspCommand cmd) { - try { - isNuageVspGuruLoaded(); - _nuageVspGuruClient.reserve(cmd.getNetwork(), cmd.getVm(), cmd.getNic(), cmd.getStaticNat(), cmd.getDhcpOption()); - return new Answer(cmd, true, "Created NIC that maps to nicUuid" + cmd.getNic().getUuid() + " on Nuage VSD " + _hostName); - } catch (ExecutionException | ConfigurationException e) { - s_logger.error("Failure during " + cmd + " on Nuage VSD " + _hostName, e); - return new Answer(cmd, e); - } - } - - private Answer executeRequest(DeallocateVmVspCommand cmd) { - try { - isNuageVspGuruLoaded(); - - _nuageVspGuruClient.deallocate(cmd.getNetwork(), cmd.getVm(), cmd.getNic()); - return new Answer(cmd, true, "Deallocated VM " + cmd.getVm().getName() + " on Nuage VSD " + _hostName); - } catch (ExecutionException | ConfigurationException e) { - s_logger.error("Failure during " + cmd + " on Nuage VSD " + _hostName, e); - return new Answer(cmd, e); - } - } - - private Answer executeRequest(TrashNetworkVspCommand cmd) { - try { - isNuageVspGuruLoaded(); - _nuageVspGuruClient.trash(cmd.getNetwork()); - return new Answer(cmd, true, "Deleted network mapping to " + cmd.getNetwork().getUuid() + " on Nuage VSD " + _hostName); - } catch (ExecutionException | ConfigurationException e) { - s_logger.error("Failure during " + cmd + " on Nuage VSD " + _hostName, e); - return new Answer(cmd, e); - } - } - - private Answer executeRequest(UpdateDhcpOptionVspCommand cmd) { - try { - isNuageVspManagerLoaded(); - _nuageVspGuruClient.applyDhcpOptions(cmd.getDhcpOptions(), cmd.getNetwork()); - return new Answer(cmd, true, "Update DhcpOptions on VM's in network: " + cmd.getNetwork().getName() + " on Nuage VSD " + _hostName); - } catch (ExecutionException | ConfigurationException e) { - s_logger.error("Failure during " + cmd.toDetailString() + " on Nuage VSD " + _hostName, e); - return new Answer(cmd, e); - } - } - - private Answer executeRequest(ApplyStaticNatVspCommand cmd) { - try { - isNuageVspElementLoaded(); - _nuageVspElementClient.applyStaticNats(cmd.getNetwork(), cmd.getStaticNatDetails()); - return new Answer(cmd, true, "Applied Static NAT to network mapping " + cmd.getNetwork().getUuid() + " on Nuage VSD " + _hostName); - } catch (ExecutionException | ConfigurationException e) { - s_logger.error("Failure during " + cmd + " on Nuage VSD " + _hostName, e); - return new Answer(cmd, e); - } - } - - private Answer executeRequest(ImplementVspCommand cmd) { - try { - isNuageVspElementLoaded(); - boolean success = _nuageVspElementClient.implement(cmd.getNetwork(), cmd.getDhcpOption(), cmd.getIngressFirewallRules(), - cmd.getEgressFirewallRules(), cmd.getFloatingIpUuids()); - return new Answer(cmd, success, "Implemented network " + cmd.getNetwork().getUuid() + " on Nuage VSD " + _hostName); - } catch (ExecutionException | ConfigurationException e) { - s_logger.error("Failure during " + cmd + " on Nuage VSD " + _hostName, e); - return new Answer(cmd, e); - } - } - - private Answer executeRequest(ApplyAclRuleVspCommand cmd) { - try { - isNuageVspElementLoaded(); - _nuageVspElementClient.applyAclRules(cmd.getAclType(), cmd.getNetwork(), cmd.getAclRules(), cmd.isNetworkReset()); - return new Answer(cmd, true, "Applied ACL Rule to network mapping " + cmd.getNetwork().getUuid() + " on Nuage VSD " + _hostName); - } catch (ExecutionException | ConfigurationException e) { - s_logger.error("Failure during " + cmd + " on Nuage VSD " + _hostName, e); - return new Answer(cmd, e); - } - } - - private Answer executeRequest(ShutDownVpcVspCommand cmd) { - try { - isNuageVspElementLoaded(); - _nuageVspElementClient.shutdownVpc(cmd.getDomainUuid(), cmd.getVpcUuid(), cmd.getDomainTemplateName(), cmd.getDomainRouterUuids()); - return new Answer(cmd, true, "Shutdown VPC " + cmd.getVpcUuid() + " on Nuage VSD " + _hostName); - } catch (ExecutionException | ConfigurationException e) { - s_logger.error("Failure during " + cmd + " on Nuage VSD " + _hostName, e); - return new Answer(cmd, e); - } - } - - private Answer executeRequest(ShutDownVspCommand cmd) { - try { - isNuageVspElementLoaded(); - _nuageVspElementClient.shutdownNetwork(cmd.getNetwork(), cmd.getDhcpOptions()); - return new Answer(cmd, true, "Shutdown VPC " + cmd.getNetwork().getUuid()+ " on Nuage VSD " + _hostName); - } catch (ConfigurationException e) { - s_logger.error("Failure during " + cmd.toDetailString() + " on Nuage VSD " + _hostName, e); - return new Answer(cmd, e); - } - } - - private Answer executeRequest(SyncNuageVspCmsIdCommand cmd) { - try { - isNuageVspManagerLoaded(); - if (cmd.getSyncType() == SyncType.AUDIT || cmd.getSyncType() == SyncType.AUDIT_ONLY) { - Pair answer = _nuageVspManagerClient.auditNuageVspCmsId(cmd.getNuageVspCmsId(), cmd.getSyncType() == SyncType.AUDIT_ONLY); - return new SyncNuageVspCmsIdAnswer(answer.getLeft(), answer.getRight(), cmd.getSyncType()); - } else if (cmd.getSyncType() == SyncType.REGISTER) { - String registeredNuageVspCmsId = _nuageVspManagerClient.registerNuageVspCmsId(); - return new SyncNuageVspCmsIdAnswer(StringUtils.isNotBlank(registeredNuageVspCmsId), registeredNuageVspCmsId, cmd.getSyncType()); - } else { - boolean success = _nuageVspManagerClient.unregisterNuageVspCmsId(cmd.getNuageVspCmsId()); - return new SyncNuageVspCmsIdAnswer(success, cmd.getNuageVspCmsId(), cmd.getSyncType()); - } - } catch (ExecutionException | ConfigurationException e) { - s_logger.error("Failure during " + cmd + " on Nuage VSD " + _hostName, e); - return new SyncNuageVspCmsIdAnswer(false, null, cmd.getSyncType()); - } - } - - private Answer executeRequest(SyncDomainCommand cmd) { - try { - isNuageVspManagerLoaded(); - boolean success = _nuageVspManagerClient.syncDomainWithNuageVsp(cmd.getDomain(), cmd.isToAdd(), cmd.isToRemove()); - return new SyncDomainAnswer(success); - } catch (ExecutionException | ConfigurationException e) { - s_logger.error("Failure during " + cmd + " on Nuage VSD " + _hostName, e); - return new SyncDomainAnswer(false); - } - } - - private Answer executeRequest(GetApiDefaultsCommand cmd) { - try { - isNuageVspManagerLoaded(); - return new GetApiDefaultsAnswer(cmd, _nuageVspManagerClient.getApiDefaults()); - } catch (ExecutionException | ConfigurationException e) { - s_logger.error("Failure during " + cmd + " on Nuage VSD " + _hostName, e); - return new GetApiDefaultsAnswer(cmd, e); - } - } - - private Answer executeRequest(SupportedApiVersionCommand cmd) { - try { - isNuageVspManagerLoaded(); - boolean supported = _nuageVspManagerClient.isSupportedApiVersion(cmd.getApiVersion()); - return new Answer(cmd, supported, "Check if API version " + cmd.getApiVersion() + " is supported"); - } catch (ConfigurationException e) { - s_logger.error("Failure during " + cmd + " on Nuage VSD " + _hostName, e); - return new Answer(cmd, e); - } - } - - private Answer executeRequest(EntityExistsCommand cmd) { - try { - isNuageVspApiLoaded(); - NuageVspEntity entityType = null; - if (Vlan.class.isAssignableFrom(cmd.getType())) { - entityType = NuageVspEntity.SHARED_NETWORK; - } - boolean exists = _nuageVspApiClient.entityExists(entityType, cmd.getUuid()); - return new Answer(cmd, exists, "Check if entity with UUID " + cmd.getUuid() + " of type " + entityType + " exists"); - } catch (ExecutionException | ConfigurationException e) { - s_logger.error("Failure during " + cmd + " on Nuage VSD " + _hostName, e); - return new Answer(cmd, e); - } - } - - protected void isNuageVspApiLoaded() throws ConfigurationException { - if (!_isNuageVspClientLoaded || _nuageVspApiClient == null) { + protected void assertNuageVspClientsLoaded() throws ConfigurationException { + if (_clientLoader == null) { throw new ConfigurationException(NUAGE_VSP_PLUGIN_ERROR_MESSAGE); } } - protected void isNuageVspGuruLoaded() throws ConfigurationException { - if (!_isNuageVspClientLoaded || _nuageVspGuruClient == null) { - throw new ConfigurationException(NUAGE_VSP_PLUGIN_ERROR_MESSAGE); - } + public NuageVspApiClient getNuageVspApiClient() throws ConfigurationException { + assertNuageVspClientsLoaded(); + return _clientLoader.getNuageVspApiClient(); + } - protected void isNuageVspElementLoaded() throws ConfigurationException { - if (!_isNuageVspClientLoaded || _nuageVspElementClient == null) { - throw new ConfigurationException(NUAGE_VSP_PLUGIN_ERROR_MESSAGE); - } + public NuageVspGuruClient getNuageVspGuruClient() throws ConfigurationException { + assertNuageVspClientsLoaded(); + return _clientLoader.getNuageVspGuruClient(); } - protected void isNuageVspManagerLoaded() throws ConfigurationException { - if (!_isNuageVspClientLoaded || _nuageVspManagerClient == null) { - throw new ConfigurationException(NUAGE_VSP_PLUGIN_ERROR_MESSAGE); - } + public NuageVspAclClient getNuageVspAclClient() throws ConfigurationException { + assertNuageVspClientsLoaded(); + return _clientLoader.getNuageVspAclClient(); } - public static class Configuration { - private String _name; - private String _guid; - private String _zoneId; - private String _hostName; - private String _cmsUser; - private String _cmsUserPassword; - private String _port; - private String _apiVersion; - private String _apiRelativePath; - private String _retryCount; - private String _retryInterval; - private String _nuageVspCmsId; - - public String name() { - return this._name; - } - - public Configuration name(String name) { - this._name = name; - return this; - } - - public String guid() { - return this._guid; - } - - public Configuration guid(String guid) { - this._guid = guid; - return this; - } - - public String zoneId() { - return this._zoneId; - } - - public Configuration zoneId(String zoneId) { - this._zoneId = zoneId; - return this; - } - - public String hostName() { - return this._hostName; - } - - public Configuration hostName(String hostName) { - this._hostName = hostName; - return this; - } - - public String cmsUser() { - return this._cmsUser; - } - - public Configuration cmsUser(String cmsUser) { - this._cmsUser = cmsUser; - return this; - } - - public String cmsUserPassword() { - return this._cmsUserPassword; - } - - public Configuration cmsUserPassword(String cmsUserPassword) { - this._cmsUserPassword = cmsUserPassword; - return this; - } - - public String port() { - return this._port; - } - - public Configuration port(String port) { - this._port = port; - return this; - } - - public String apiVersion() { - return this._apiVersion; - } - - public Configuration apiVersion(String apiVersion) { - this._apiVersion = apiVersion; - return this; - } - - public String apiRelativePath() { - return this._apiRelativePath; - } - - public Configuration apiRelativePath(String apiRelativePath) { - this._apiRelativePath = apiRelativePath; - return this; - } - - public String retryCount() { - return this._retryCount; - } - - public Configuration retryCount(String retryCount) { - this._retryCount = retryCount; - return this; - } - - public String retryInterval() { - return this._retryInterval; - } - - public Configuration retryInterval(String retryInterval) { - this._retryInterval = retryInterval; - return this; - } - - public String nuageVspCmsId() { - return this._nuageVspCmsId; - } - - public Configuration nuageVspCmsId(String nuageVspCmsId) { - this._nuageVspCmsId = nuageVspCmsId; - return this; - } - - public Map build() { - return new HashMap() {{ - if (_name != null) put(NAME, _name); - if (_guid != null) put(GUID, _guid); - if (_zoneId != null) put(ZONE_ID, _zoneId); - if (_hostName != null) put(HOST_NAME, _hostName); - if (_cmsUser != null) put(CMS_USER, _cmsUser); - if (_cmsUserPassword != null) put(CMS_USER_PASSWORD, _cmsUserPassword); - if (_port != null) put(PORT, _port); - if (_apiVersion != null) put(API_VERSION, _apiVersion); - if (_apiRelativePath != null) put(API_RELATIVE_PATH, _apiRelativePath); - if (_retryCount != null) put(RETRY_COUNT, _retryCount); - if (_retryInterval != null) put(RETRY_INTERVAL, _retryInterval); - if (_nuageVspCmsId != null) put(NUAGE_VSP_CMS_ID, _nuageVspCmsId); - }}; - } - - public static Configuration fromConfiguration(Map configuration) { - return new Configuration() - .name(configuration.get(NAME)) - .guid(configuration.get(GUID)) - .zoneId(configuration.get(ZONE_ID)) - .hostName(configuration.get(HOST_NAME)) - .cmsUser(configuration.get(CMS_USER)) - .cmsUserPassword(configuration.get(CMS_USER_PASSWORD)) - .port(configuration.get(PORT)) - .apiVersion(configuration.get(API_VERSION)) - .apiRelativePath(configuration.get(API_RELATIVE_PATH)) - .retryCount(configuration.get(RETRY_COUNT)) - .retryInterval(configuration.get(RETRY_INTERVAL)) - .nuageVspCmsId(configuration.get(NUAGE_VSP_CMS_ID)); - } + public NuageVspElementClient getNuageVspElementClient() throws ConfigurationException { + assertNuageVspClientsLoaded(); + return _clientLoader.getNuageVspElementClient(); } + + public NuageVspManagerClient getNuageVspManagerClient() throws ConfigurationException { + assertNuageVspClientsLoaded(); + return _clientLoader.getNuageVspManagerClient(); + } + } diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResourceConfiguration.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResourceConfiguration.java new file mode 100644 index 00000000000..1861941179c --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResourceConfiguration.java @@ -0,0 +1,359 @@ +// +// 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.resource; + +import java.util.HashMap; +import java.util.Map; +import java.util.Objects; + +import javax.naming.ConfigurationException; + +import com.google.common.base.Preconditions; +import net.nuage.vsp.acs.client.api.model.NuageVspUser; +import net.nuage.vsp.acs.client.api.model.VspHost; +import net.nuage.vsp.acs.client.common.NuageVspApiVersion; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.cloud.util.NuageVspUtil; + +public class NuageVspResourceConfiguration { + private static final String NAME = "name"; + private static final String GUID = "guid"; + private static final String ZONE_ID = "zoneid"; + private static final String HOST_NAME = "hostname"; + private static final String CMS_USER = "cmsuser"; + private static final String CMS_USER_PASSWORD = "cmsuserpass"; + private static final String PORT = "port"; + private static final String API_VERSION = "apiversion"; + private static final String API_RELATIVE_PATH = "apirelativepath"; + private static final String RETRY_COUNT = "retrycount"; + private static final String RETRY_INTERVAL = "retryinterval"; + private static final String NUAGE_VSP_CMS_ID = "nuagevspcmsid"; + + private static final String CMS_USER_ENTEPRISE_NAME = "CSP"; + + private String _name; + private String _guid; + private String _zoneId; + private String _hostName; + private String _cmsUser; + private String _cmsUserPassword; + private String _port; + private String _apiVersion; + private String _apiRelativePath; + private String _retryCount; + private String _retryInterval; + private String _nuageVspCmsId; + + public String name() { + return _name; + } + + public String guid() { + return this._guid; + } + + public NuageVspResourceConfiguration guid(String guid) { + this._guid = guid; + return this; + } + + public String zoneId() { + return this._zoneId; + } + + public NuageVspResourceConfiguration zoneId(String zoneId) { + this._zoneId = zoneId; + return this; + } + + public String hostName() { + return this._hostName; + } + + public NuageVspResourceConfiguration hostName(String hostName) { + this._hostName = hostName; + this._name = "Nuage VSD - " + _hostName; + return this; + } + + public String cmsUser() { + return this._cmsUser; + } + + public NuageVspResourceConfiguration cmsUser(String cmsUser) { + this._cmsUser = cmsUser; + return this; + } + + public String cmsUserPassword() { + return this._cmsUserPassword; + } + + public NuageVspResourceConfiguration cmsUserPassword(String cmsUserPassword) { + this._cmsUserPassword = cmsUserPassword; + return this; + } + + public String port() { + return this._port; + } + + public NuageVspResourceConfiguration port(String port) { + this._port = port; + return this; + } + + public String apiVersion() { + return this._apiVersion; + } + + public NuageVspResourceConfiguration apiVersion(String apiVersion) { + this._apiVersion = apiVersion; + return this; + } + + public String apiRelativePath() { + return this._apiRelativePath; + } + + public NuageVspResourceConfiguration apiRelativePath(String apiRelativePath) { + this._apiRelativePath = apiRelativePath; + return this; + } + + public String retryCount() { + return this._retryCount; + } + + public NuageVspResourceConfiguration retryCount(String retryCount) { + this._retryCount = retryCount; + return this; + } + + public String retryInterval() { + return this._retryInterval; + } + + public NuageVspResourceConfiguration retryInterval(String retryInterval) { + this._retryInterval = retryInterval; + return this; + } + + public String nuageVspCmsId() { + return this._nuageVspCmsId; + } + + public NuageVspResourceConfiguration nuageVspCmsId(String nuageVspCmsId) { + this._nuageVspCmsId = nuageVspCmsId; + return this; + } + + public String getRootPath(){ + return "https://" + _hostName + ":" + _port + "/nuage"; + } + + public String getApiPath() { + return "https://" + _hostName + ":" + _port + "/nuage/api/" + _apiVersion; + } + + public NuageVspApiVersion getApiVersion() throws ConfigurationException { + try { + if(_apiVersion != null) { + return NuageVspApiVersion.fromString(_apiVersion); + } + return null; + } catch (IllegalArgumentException e) { + throw new ConfigurationException("Incorrect API version"); + } + } + + public Map build() { + Map map = new HashMap<>(); + putIfPresent(map, GUID, _guid); + putIfPresent(map, ZONE_ID, _zoneId); + putIfPresent(map, HOST_NAME, _hostName); + putIfPresent(map, CMS_USER, _cmsUser); + putIfPresent(map, CMS_USER_PASSWORD, _cmsUserPassword); + putIfPresent(map, PORT, _port); + putIfPresent(map, API_VERSION, _apiVersion); + putIfPresent(map, API_RELATIVE_PATH, _apiRelativePath); + putIfPresent(map, RETRY_COUNT, _retryCount); + putIfPresent(map, RETRY_INTERVAL, _retryInterval); + putIfPresent(map, NUAGE_VSP_CMS_ID, _nuageVspCmsId); + return map; + } + + private void putIfPresent(Map map, String key, String value) { + Preconditions.checkNotNull(map); + Preconditions.checkNotNull(key); + + if (value != null) { + map.put(key, value); + } + } + + public static NuageVspResourceConfiguration fromConfiguration(Map configuration) { + return new NuageVspResourceConfiguration() + .guid((String)configuration.get(GUID)) + .zoneId((String)configuration.get(ZONE_ID)) + .hostName((String)configuration.get(HOST_NAME)) + .cmsUser((String)configuration.get(CMS_USER)) + .cmsUserPassword((String)configuration.get(CMS_USER_PASSWORD)) + .port((String)configuration.get(PORT)) + .apiVersion((String)configuration.get(API_VERSION)) + .apiRelativePath((String)configuration.get(API_RELATIVE_PATH)) + .retryCount((String)configuration.get(RETRY_COUNT)) + .retryInterval((String)configuration.get(RETRY_INTERVAL)) + .nuageVspCmsId((String)configuration.get(NUAGE_VSP_CMS_ID)); + } + + private void verifyNotNull(String name, String value) throws ConfigurationException { + if (value == null) { + throw new ConfigurationException("Unable to find " + name); + } + } + + private void verifyNotEmpty(String name, String value) throws ConfigurationException { + if (StringUtils.isEmpty(value)) { + throw new ConfigurationException("Unable to find " + name); + } + } + + private int verifyInRange(String name, String value, int min, int max) throws ConfigurationException { + verifyNotEmpty(name, value); + + int parsedValue; + try { + parsedValue = Integer.parseInt(value); + } catch (NumberFormatException ex) { + throw new ConfigurationException(name + " has to be between " + min + " and " + max); + } + if ((parsedValue < min) || (parsedValue > max)) { + throw new ConfigurationException(name + " has to be between " + min + " and " + max); + } + return parsedValue; + } + + public void validate() throws ConfigurationException { + verifyNotNull("name", _name); + verifyNotNull("guid", _guid); + verifyNotNull("zone", _zoneId); + verifyNotNull("hostname", _hostName); + verifyNotNull("CMS username", _cmsUser); + verifyNotNull("CMS password", _cmsUserPassword); + verifyNotEmpty("API version", _apiVersion); + + try { + new NuageVspApiVersion(_apiVersion); + } catch(IllegalArgumentException e) { + throw new ConfigurationException("Incorrect API version"); + } + + verifyNotEmpty("number of retries", _retryCount); + verifyNotEmpty("retry interval", _retryInterval); + } + + public int parseRetryCount() throws ConfigurationException { + return verifyInRange("Number of retries", _retryCount, 1, 10); + } + + public int parseRetryInterval() throws ConfigurationException { + return verifyInRange("Retry interval", _retryInterval, 1, 10000); + } + + public VspHost buildVspHost() throws ConfigurationException { + return new VspHost.Builder() + .cmsUser(new NuageVspUser(CMS_USER_ENTEPRISE_NAME, _cmsUser, NuageVspUtil.decodePassword(_cmsUserPassword))) + .apiVersion(getApiVersion()) + .restRelativePath(getApiPath()) + .rootPath(getRootPath()) + .nuageVspCmsId(_nuageVspCmsId) + .noofRetry(parseRetryCount()) + .retryInterval(parseRetryInterval()) + .build(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (!(o instanceof NuageVspResourceConfiguration)) { + return false; + } + + NuageVspResourceConfiguration that = (NuageVspResourceConfiguration) o; + + return super.equals(that) + && Objects.equals(_name, that._name) + && Objects.equals(_guid, that._guid) + && Objects.equals(_zoneId, that._zoneId) + && Objects.equals(_hostName, that._hostName) + && Objects.equals(_cmsUser, that._cmsUser) + && Objects.equals(_cmsUserPassword, that._cmsUserPassword) + && Objects.equals(_port, that._port) + && Objects.equals(_apiVersion, that._apiVersion) + && Objects.equals(_apiRelativePath, that._apiRelativePath) + && Objects.equals(_retryCount, that._retryCount) + && Objects.equals(_retryInterval, that._retryInterval) + && Objects.equals(_nuageVspCmsId, that._nuageVspCmsId); + } + + @Override + public int hashCode() { + return new HashCodeBuilder() + .appendSuper(super.hashCode()) + .append(_name) + .append(_guid) + .append(_zoneId) + .append(_hostName) + .append(_cmsUser) + .append(_cmsUserPassword) + .append(_port) + .append(_apiVersion) + .append(_apiRelativePath) + .append(_retryCount) + .append(_retryInterval) + .append(_nuageVspCmsId) + .toHashCode(); + } + + @Override public String toString() { + return new ToStringBuilder(this) + .append("_name", _name) + .append("_guid", _guid) + .append("_zoneId", _zoneId) + .append("_hostName", _hostName) + .append("_cmsUser", _cmsUser) + .append("_cmsUserPassword", _cmsUserPassword) + .append("_port", _port) + .append("_apiVersion", _apiVersion) + .append("_apiRelativePath", _apiRelativePath) + .append("_retryCount", _retryCount) + .append("_retryInterval", _retryInterval) + .append("_nuageVspCmsId", _nuageVspCmsId) + .toString(); + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApiSupportCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApiSupportCommandWrapper.java new file mode 100644 index 00000000000..1e84e20515e --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApiSupportCommandWrapper.java @@ -0,0 +1,41 @@ +// +// 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.manager.SupportedApiVersionCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = SupportedApiVersionCommand.class) +public final class NuageVspApiSupportCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(SupportedApiVersionCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + return nuageVspResource.getNuageVspManagerClient().isSupportedApiVersion(cmd.getApiVersion()); + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, SupportedApiVersionCommand cmd) { + return stringBuilder.append("Check if API version ").append(cmd.getApiVersion()).append(" is supported"); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApplyAclRulesCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApplyAclRulesCommandWrapper.java new file mode 100644 index 00000000000..42499c4f788 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApplyAclRulesCommandWrapper.java @@ -0,0 +1,42 @@ +// +// 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.element.ApplyAclRuleVspCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = ApplyAclRuleVspCommand.class) +public final class NuageVspApplyAclRulesCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(ApplyAclRuleVspCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + nuageVspResource.getNuageVspElementClient().applyAclRules(cmd.getAclType(), cmd.getNetwork(), cmd.getAclRules(), cmd.isNetworkReset()); + return true; + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, ApplyAclRuleVspCommand cmd) { + return stringBuilder.append("Applied ACL Rule to network mapping " + cmd.getNetwork().getUuid()); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApplyStaticNatCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApplyStaticNatCommandWrapper.java new file mode 100644 index 00000000000..81fbdef4548 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspApplyStaticNatCommandWrapper.java @@ -0,0 +1,42 @@ +// +// 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.element.ApplyStaticNatVspCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = ApplyStaticNatVspCommand.class) +public final class NuageVspApplyStaticNatCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(ApplyStaticNatVspCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + nuageVspResource.getNuageVspElementClient().applyStaticNats(cmd.getNetwork(), cmd.getStaticNatDetails()); + return true; + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, ApplyStaticNatVspCommand cmd) { + return stringBuilder.append("Applied Static NAT to network mapping ").append(cmd.getNetwork().getUuid()); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCleanupDomainCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCleanupDomainCommandWrapper.java new file mode 100644 index 00000000000..273a719211d --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCleanupDomainCommandWrapper.java @@ -0,0 +1,41 @@ +// +// 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.manager.CleanUpDomainCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = CleanUpDomainCommand.class) +public final class NuageVspCleanupDomainCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(CleanUpDomainCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + return nuageVspResource.getNuageVspManagerClient().cleanUpDomain(cmd.getDomainCleanUp()); + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, CleanUpDomainCommand cmd) { + return stringBuilder.append("Clean Domain ").append(cmd.getDomainCleanUp().getUuid()); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCommandWrapper.java new file mode 100644 index 00000000000..ee3f5c58c83 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspCommandWrapper.java @@ -0,0 +1,52 @@ +// +// 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 org.apache.log4j.Logger; + +import com.cloud.agent.api.Answer; +import com.cloud.agent.api.Command; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.CommandWrapper; + +public abstract class NuageVspCommandWrapper extends CommandWrapper { + + private static final Logger s_logger = Logger.getLogger(NuageVspResource.class); + + @Override + public final Answer execute(final T command, final NuageVspResource nuageVspResource) { + try { + boolean success = executeNuageVspCommand(command, nuageVspResource); + String detail = fillDetail(new StringBuilder(), command).append(" on ").append(nuageVspResource.getName()).toString(); + return new Answer(command, success, detail); + } catch (NuageVspException | ConfigurationException e) { + s_logger.error("Failure during " + command + " on " + nuageVspResource.getName(), e); + return new Answer(command, e); + } + } + + public abstract boolean executeNuageVspCommand(final T command, final NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException; + + public abstract StringBuilder fillDetail(final StringBuilder stringBuilder, final T command); +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspDeallocateVmInterfaceCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspDeallocateVmInterfaceCommandWrapper.java new file mode 100644 index 00000000000..21256531365 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspDeallocateVmInterfaceCommandWrapper.java @@ -0,0 +1,42 @@ +// +// 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.guru.DeallocateVmVspCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = DeallocateVmVspCommand.class) +public final class NuageVspDeallocateVmInterfaceCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(DeallocateVmVspCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + nuageVspResource.getNuageVspGuruClient().deallocate(cmd.getNetwork(), cmd.getVm(), cmd.getNic()); + return true; + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, DeallocateVmVspCommand cmd) { + return stringBuilder.append("Deallocated VM ").append(cmd.getVm().getName()); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspEntityExistsCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspEntityExistsCommandWrapper.java new file mode 100644 index 00000000000..ecf06298ee3 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspEntityExistsCommandWrapper.java @@ -0,0 +1,55 @@ +// +// 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.common.model.NuageVspEntity; +import net.nuage.vsp.acs.client.exception.NuageVspException; + +import com.cloud.agent.api.manager.EntityExistsCommand; +import com.cloud.dc.Vlan; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = EntityExistsCommand.class) +public final class NuageVspEntityExistsCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(EntityExistsCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + NuageVspEntity entityType = getNuageVspEntity(cmd.getType()); + + return nuageVspResource.getNuageVspApiClient().entityExists(entityType, cmd.getUuid()); + } + + private NuageVspEntity getNuageVspEntity(Class clazz) { + NuageVspEntity entityType = null; + + if (Vlan.class.isAssignableFrom(clazz)) { + entityType = NuageVspEntity.SHARED_NETWORK; + } + + return entityType; + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, EntityExistsCommand cmd) { + return stringBuilder.append("Check if entity with UUID " + cmd.getUuid() + " of type " + getNuageVspEntity(cmd.getType()) + " exists"); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGetApiDefaultsCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGetApiDefaultsCommandWrapper.java new file mode 100644 index 00000000000..ac96895bbe4 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGetApiDefaultsCommandWrapper.java @@ -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.manager.GetApiDefaultsAnswer; +import com.cloud.agent.api.manager.GetApiDefaultsCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = GetApiDefaultsCommand.class) +public final class NuageVspGetApiDefaultsCommandWrapper extends CommandWrapper { + + @Override + public GetApiDefaultsAnswer execute(final GetApiDefaultsCommand command, final NuageVspResource nuageVspResource) { + try { + return new GetApiDefaultsAnswer(command, nuageVspResource.getNuageVspManagerClient().getApiDefaults()); + } catch (NuageVspException|ConfigurationException e) { + return new GetApiDefaultsAnswer(command, e); + } + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGuruImplementNetworkCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGuruImplementNetworkCommandWrapper.java new file mode 100644 index 00000000000..1ba77ff2bd0 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGuruImplementNetworkCommandWrapper.java @@ -0,0 +1,42 @@ +// +// 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.guru.ImplementNetworkVspCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = ImplementNetworkVspCommand.class) +public final class NuageVspGuruImplementNetworkCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(ImplementNetworkVspCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + nuageVspResource.getNuageVspGuruClient().implement(cmd.getNetwork(), cmd.getDhcpOption()); + return true; + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, ImplementNetworkVspCommand command) { + return stringBuilder.append("Created network mapping to ").append(command.getNetwork().getName()); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGuruTrashNetworkCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGuruTrashNetworkCommandWrapper.java new file mode 100644 index 00000000000..1f12f94baf6 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspGuruTrashNetworkCommandWrapper.java @@ -0,0 +1,42 @@ +// +// 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.guru.TrashNetworkVspCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = TrashNetworkVspCommand.class) +public final class NuageVspGuruTrashNetworkCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(TrashNetworkVspCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + nuageVspResource.getNuageVspGuruClient().trash(cmd.getNetwork()); + return true; + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, TrashNetworkVspCommand command) { + return stringBuilder; + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspImplementNetworkCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspImplementNetworkCommandWrapper.java new file mode 100644 index 00000000000..d0732dae5cb --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspImplementNetworkCommandWrapper.java @@ -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.element.ImplementVspCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = ImplementVspCommand.class) +public final class NuageVspImplementNetworkCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(ImplementVspCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + nuageVspResource.getNuageVspElementClient().implement(cmd.getNetwork(), cmd.getDhcpOption(), cmd.getIngressFirewallRules(), + cmd.getEgressFirewallRules(), cmd.getFloatingIpUuids()); + return true; + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, ImplementVspCommand cmd) { + return stringBuilder.append("Implemented network ").append(cmd.getNetwork().getUuid()); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspMaintainCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspMaintainCommandWrapper.java new file mode 100644 index 00000000000..b0e6db70040 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspMaintainCommandWrapper.java @@ -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 com.cloud.network.vsp.resource.wrapper; + +import com.cloud.agent.api.MaintainAnswer; +import com.cloud.agent.api.MaintainCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = MaintainCommand.class) +public final class NuageVspMaintainCommandWrapper extends CommandWrapper { + + @Override + public MaintainAnswer execute(final MaintainCommand command, final NuageVspResource nuageVspResource) { + return new MaintainAnswer(command); + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspReadyCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspReadyCommandWrapper.java new file mode 100644 index 00000000000..ca95b465703 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspReadyCommandWrapper.java @@ -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 com.cloud.network.vsp.resource.wrapper; + +import com.cloud.agent.api.ReadyAnswer; +import com.cloud.agent.api.ReadyCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = ReadyCommand.class) +public final class NuageVspReadyCommandWrapper extends CommandWrapper { + + @Override + public ReadyAnswer execute(final ReadyCommand command, final NuageVspResource nuageVspResource) { + return new ReadyAnswer(command); + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspReserveVmInterfaceCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspReserveVmInterfaceCommandWrapper.java new file mode 100644 index 00000000000..fdf1ab27a75 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspReserveVmInterfaceCommandWrapper.java @@ -0,0 +1,42 @@ +// +// 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.guru.ReserveVmInterfaceVspCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = ReserveVmInterfaceVspCommand.class) +public final class NuageVspReserveVmInterfaceCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(ReserveVmInterfaceVspCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + nuageVspResource.getNuageVspGuruClient().reserve(cmd.getNetwork(), cmd.getVm(), cmd.getNic(), cmd.getStaticNat(), cmd.getDhcpOption()); + return true; + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, ReserveVmInterfaceVspCommand command) { + return stringBuilder.append("Created NIC that maps to nicUuid ").append(command.getNic().getUuid()); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspShutdownNetworkCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspShutdownNetworkCommandWrapper.java new file mode 100644 index 00000000000..1852eb60c30 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspShutdownNetworkCommandWrapper.java @@ -0,0 +1,42 @@ +// +// 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.element.ShutDownVspCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = ShutDownVspCommand.class) +public final class NuageVspShutdownNetworkCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(ShutDownVspCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + nuageVspResource.getNuageVspElementClient().shutdownNetwork(cmd.getNetwork(), cmd.getDhcpOptions()); + return true; + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, ShutDownVspCommand cmd) { + return stringBuilder.append("Shutdown Network " + cmd.getNetwork().getUuid()); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspShutdownVpcCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspShutdownVpcCommandWrapper.java new file mode 100644 index 00000000000..d2d9ea705b2 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspShutdownVpcCommandWrapper.java @@ -0,0 +1,42 @@ +// +// 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.element.ShutDownVpcVspCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = ShutDownVpcVspCommand.class) +public final class NuageVspShutdownVpcCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(ShutDownVpcVspCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + nuageVspResource.getNuageVspElementClient().shutdownVpc(cmd.getDomainUuid(), cmd.getVpcUuid(), cmd.getDomainTemplateName(), cmd.getDomainRouterUuids()); + return true; + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, ShutDownVpcVspCommand cmd) { + return stringBuilder.append("Shutdown VPC " + cmd.getVpcUuid()); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspSyncCmsIdCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspSyncCmsIdCommandWrapper.java new file mode 100644 index 00000000000..c10134458ec --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspSyncCmsIdCommandWrapper.java @@ -0,0 +1,62 @@ +// +// 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.api.NuageVspManagerClient; +import net.nuage.vsp.acs.client.common.model.Pair; +import net.nuage.vsp.acs.client.exception.NuageVspException; + +import com.cloud.agent.api.sync.SyncNuageVspCmsIdAnswer; +import com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.CommandWrapper; +import com.cloud.resource.ResourceWrapper; +import com.cloud.utils.StringUtils; + +@ResourceWrapper(handles = SyncNuageVspCmsIdCommand.class) +public final class NuageVspSyncCmsIdCommandWrapper extends CommandWrapper { + + @Override public SyncNuageVspCmsIdAnswer execute(SyncNuageVspCmsIdCommand cmd, NuageVspResource nuageVspResource) { + NuageVspManagerClient client = null; + try { + client = nuageVspResource.getNuageVspManagerClient(); + + Pair answer; + switch (cmd.getSyncType()) { + case REGISTER: + String registeredNuageVspCmsId = client.registerNuageVspCmsId(); + answer = Pair.of(StringUtils.isNotBlank(registeredNuageVspCmsId), registeredNuageVspCmsId); + break; + case UNREGISTER: + boolean success = client.unregisterNuageVspCmsId(cmd.getNuageVspCmsId()); + answer = Pair.of(success, cmd.getNuageVspCmsId()); + break; + default: + answer = client.auditNuageVspCmsId(cmd.getNuageVspCmsId(), cmd.getSyncType() == SyncNuageVspCmsIdCommand.SyncType.AUDIT_ONLY); + break; + } + return new SyncNuageVspCmsIdAnswer(answer.getLeft(), answer.getRight(), cmd.getSyncType()); + } catch (ConfigurationException|NuageVspException e) { + return new SyncNuageVspCmsIdAnswer(cmd, e, cmd.getSyncType()); + } + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspSyncDomainCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspSyncDomainCommandWrapper.java new file mode 100644 index 00000000000..b32e0b1791c --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspSyncDomainCommandWrapper.java @@ -0,0 +1,41 @@ +// +// 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.sync.SyncDomainCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = SyncDomainCommand.class) +public final class NuageVspSyncDomainCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(SyncDomainCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + return nuageVspResource.getNuageVspManagerClient().syncDomainWithNuageVsp(cmd.getDomain(), cmd.isToAdd(), cmd.isToRemove()); + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, SyncDomainCommand cmd) { + return stringBuilder.append("Synced Domain ").append(cmd.getDomain().getUuid()); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspUpdateDhcpOptionsCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspUpdateDhcpOptionsCommandWrapper.java new file mode 100644 index 00000000000..56bde5c68c6 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/NuageVspUpdateDhcpOptionsCommandWrapper.java @@ -0,0 +1,42 @@ +// +// 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.guru.UpdateDhcpOptionVspCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = UpdateDhcpOptionVspCommand.class) +public final class NuageVspUpdateDhcpOptionsCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(UpdateDhcpOptionVspCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + nuageVspResource.getNuageVspGuruClient().applyDhcpOptions(cmd.getDhcpOptions(), cmd.getNetwork()); + return true; + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, UpdateDhcpOptionVspCommand cmd) { + return stringBuilder.append("Update DhcpOptions on VM's in network: ").append(cmd.getNetwork().getName()); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/UpdateNuageVspDeviceCommandWrapper.java b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/UpdateNuageVspDeviceCommandWrapper.java new file mode 100644 index 00000000000..c8953912d59 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/network/vsp/resource/wrapper/UpdateNuageVspDeviceCommandWrapper.java @@ -0,0 +1,46 @@ +// +// 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.manager.UpdateNuageVspDeviceCommand; +import com.cloud.network.resource.NuageVspResource; +import com.cloud.network.resource.NuageVspResourceConfiguration; +import com.cloud.resource.ResourceWrapper; + +@ResourceWrapper(handles = UpdateNuageVspDeviceCommand.class) +public final class UpdateNuageVspDeviceCommandWrapper extends NuageVspCommandWrapper { + + @Override public boolean executeNuageVspCommand(UpdateNuageVspDeviceCommand cmd, NuageVspResource nuageVspResource) throws ConfigurationException, NuageVspException { + final NuageVspResourceConfiguration configuration = cmd.getConfiguration(); + nuageVspResource.validate(configuration); + nuageVspResource.getConfigParams().putAll(configuration.build()); + + return true; + } + + @Override public StringBuilder fillDetail(StringBuilder stringBuilder, UpdateNuageVspDeviceCommand cmd) { + return stringBuilder.append("Updated the NuageVspResource parameters"); + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspEntityBuilder.java b/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspEntityBuilder.java index b1db4fb673f..84afa296ca9 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspEntityBuilder.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspEntityBuilder.java @@ -19,6 +19,7 @@ package com.cloud.util; +import com.cloud.dc.Vlan; import com.cloud.dc.VlanVO; import com.cloud.dc.dao.VlanDao; import com.cloud.dc.dao.VlanDetailsDao; @@ -30,7 +31,9 @@ import com.cloud.network.Network; import com.cloud.network.NetworkModel; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkDetailsDao; +import com.cloud.network.dao.NetworkVO; import com.cloud.network.manager.NuageVspManager; import com.cloud.network.rules.FirewallRule; import com.cloud.network.vpc.NetworkACLItem; @@ -49,12 +52,17 @@ import com.cloud.vm.NicVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.VMInstanceDao; +import com.google.common.base.Function; +import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import net.nuage.vsp.acs.client.api.model.VspAclRule; import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption; +import net.nuage.vsp.acs.client.api.model.VspAddressRange; import net.nuage.vsp.acs.client.api.model.VspDhcpVMOption; import net.nuage.vsp.acs.client.api.model.VspDomain; +import net.nuage.vsp.acs.client.api.model.VspDomainCleanUp; import net.nuage.vsp.acs.client.api.model.VspNetwork; import net.nuage.vsp.acs.client.api.model.VspNic; import net.nuage.vsp.acs.client.api.model.VspStaticNat; @@ -64,16 +72,20 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; +import javax.annotation.Nullable; import javax.inject.Inject; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.TreeSet; public class NuageVspEntityBuilder { private static final Logger s_logger = Logger.getLogger(NuageVspEntityBuilder.class); + @Inject + NetworkDao _networkDao; @Inject VpcDao _vpcDao; @Inject @@ -112,7 +124,31 @@ public class NuageVspEntityBuilder { .build(); } - public VspNetwork buildVspNetwork(Network network, boolean fillAddressRange) { + public VspDomainCleanUp buildVspDomainCleanUp(Domain domain) { + VspDomainCleanUp.Builder vspDomainCleanUpBuilder = new VspDomainCleanUp.Builder().uuid(domain.getUuid()); + + Map> sharedNetworkUuids = Maps.newHashMap(); + List allSharedNetworks = _networkDao.listByGuestType(Network.GuestType.Shared); + for (NetworkVO sharedNetwork : allSharedNetworks) { + if (_networkModel.isNetworkAvailableInDomain(sharedNetwork.getId(), domain.getId())) { + NetworkOffering networkOffering = _networkOfferingDao.findById(sharedNetwork.getNetworkOfferingId()); + String preConfiguredDomainTemplateName = NuageVspUtil.getPreConfiguredDomainTemplateName(_configurationDao, _networkDetailsDao, sharedNetwork, networkOffering); + if (!sharedNetworkUuids.containsKey(preConfiguredDomainTemplateName)) { + sharedNetworkUuids.put(preConfiguredDomainTemplateName, Lists.newArrayList()); + } + sharedNetworkUuids.get(preConfiguredDomainTemplateName).add(sharedNetwork.getUuid()); + } + } + vspDomainCleanUpBuilder.sharedNetworkUuids(sharedNetworkUuids); + + return vspDomainCleanUpBuilder.build(); + } + + public VspNetwork buildVspNetwork(Network network) { + return buildVspNetwork(network.getDomainId(), network); + } + + public VspNetwork buildVspNetwork(long domainId, Network network) { VspNetwork.Builder vspNetworkBuilder = new VspNetwork.Builder() .id(network.getId()) .uuid(network.getUuid()) @@ -120,7 +156,7 @@ public class NuageVspEntityBuilder { .cidr(network.getCidr()) .gateway(network.getGateway()); - DomainVO domain = _domainDao.findById(network.getDomainId()); + DomainVO domain = _domainDao.findById(domainId); VspDomain vspDomain = buildVspDomain(domain); vspNetworkBuilder.domain(vspDomain); @@ -130,7 +166,7 @@ public class NuageVspEntityBuilder { } NetworkOfferingVO networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId()); - vspNetworkBuilder.egressDefaultPolicy(networkOffering.getEgressDefaultPolicy()); + vspNetworkBuilder.egressDefaultPolicy(networkOffering.getEgressDefaultPolicy()).publicAccess(networkOffering.getSupportsPublicAccess()); if (network.getVpcId() != null) { VpcVO vpc = _vpcDao.findById(network.getVpcId()); @@ -139,7 +175,16 @@ public class NuageVspEntityBuilder { .networkType(VspNetwork.NetworkType.Vpc); } else { if (networkOffering.getGuestType() == Network.GuestType.Shared) { - vspNetworkBuilder.networkType(VspNetwork.NetworkType.Shared); + List vlans = _vlanDao.listVlansByNetworkIdIncludingRemoved(network.getId()); + List vspAddressRanges = Lists.transform(vlans, new Function() { + @Nullable + @Override + public VspAddressRange apply(VlanVO vlanVO) { + return new VspAddressRange.Builder().gateway(vlanVO.getVlanGateway()).netmask(vlanVO.getVlanNetmask()).build(); + } + }); + + vspNetworkBuilder.networkType(VspNetwork.NetworkType.Shared).addressRanges(vspAddressRanges); } else if (_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.SourceNat) || _networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(network.getNetworkOfferingId(), Network.Service.StaticNat)) { vspNetworkBuilder.networkType(VspNetwork.NetworkType.L3); @@ -154,11 +199,10 @@ public class NuageVspEntityBuilder { String preConfiguredDomainTemplateName = NuageVspUtil.getPreConfiguredDomainTemplateName(_configurationDao, _networkDetailsDao, network, networkOffering); vspNetworkBuilder.domainTemplateName(preConfiguredDomainTemplateName); - if (fillAddressRange) { + if (usesVirtualRouter(networkOffering.getId())) { try { - List> ipAddressRanges = getIpAddressRanges(networkOffering, network); - vspNetworkBuilder.ipAddressRanges(ipAddressRanges); - + List> ipAddressRanges = + networkOffering.getGuestType() == Network.GuestType.Shared ? getSharedIpAddressRanges(network.getId()) : getIpAddressRanges(network); String virtualRouterIp = getVirtualRouterIP(network, ipAddressRanges); vspNetworkBuilder.virtualRouterIp(virtualRouterIp); } catch (InsufficientVirtualNetworkCapacityException ex) { @@ -170,21 +214,44 @@ public class NuageVspEntityBuilder { return vspNetworkBuilder.build(); } - private List> getIpAddressRanges(NetworkOfferingVO networkOffering, Network network) { - List> ipAddressRanges = Lists.newArrayList(); - if (networkOffering.getGuestType() == Network.GuestType.Shared) { - List vlans = _vlanDao.listVlansByNetworkId(network.getId()); - ipAddressRanges = Lists.newArrayList(); - for (VlanVO vlan : vlans) { - boolean isIpv4 = StringUtils.isNotBlank(vlan.getIpRange()); - String[] range = isIpv4 ? vlan.getIpRange().split("-") : vlan.getIp6Range().split("-"); - if (range.length == 2) { - ipAddressRanges.add(Pair.of(range[0], range[1])); - } - } - return ipAddressRanges; - } + public boolean usesVirtualRouter(long networkOfferingId) { + return _networkOfferingServiceMapDao.isProviderForNetworkOffering(networkOfferingId, Network.Provider.VirtualRouter) || + _networkOfferingServiceMapDao.isProviderForNetworkOffering(networkOfferingId, Network.Provider.VPCVirtualRouter); + } + public VspNetwork updateVspNetworkByPublicIp(VspNetwork vspNetwork, Network network, String publicIp) { + List vlans = _vlanDao.listVlansByNetworkId(network.getId()); + final long ip = NetUtils.ip2Long(publicIp); + VlanVO matchingVlan = Iterables.find(vlans, new Predicate() { + @Override + public boolean apply(@Nullable VlanVO vlan) { + Pair ipAddressRange = getIpAddressRange(vlan); + long startIp = NetUtils.ip2Long(ipAddressRange.getLeft()); + long endIp = NetUtils.ip2Long(ipAddressRange.getRight()); + return startIp <= ip && ip <= endIp; + } + }); + + return new VspNetwork.Builder().fromObject(vspNetwork) + .gateway(matchingVlan.getVlanGateway()) + .cidr(NetUtils.getCidrFromGatewayAndNetmask(matchingVlan.getVlanGateway(), matchingVlan.getVlanNetmask())) + .build(); + } + + private List> getSharedIpAddressRanges(long networkId) { + List vlans = _vlanDao.listVlansByNetworkId(networkId); + List> ipAddressRanges = Lists.newArrayList(); + for (VlanVO vlan : vlans) { + Pair ipAddressRange = getIpAddressRange(vlan); + if (ipAddressRange != null) { + ipAddressRanges.add(ipAddressRange); + } + } + return ipAddressRanges; + } + + private List> getIpAddressRanges(Network network) { + List> ipAddressRanges = Lists.newArrayList(); String subnet = NetUtils.getCidrSubNet(network.getCidr()); String netmask = NetUtils.getCidrNetmask(network.getCidr()); long cidrSize = NetUtils.getCidrSize(netmask); @@ -195,29 +262,53 @@ public class NuageVspEntityBuilder { Iterator ipIterator = allIPsInCidr.iterator(); long ip = ipIterator.next(); - if (NetUtils.ip2Long(network.getGateway()) == ip) { + long gatewayIp = NetUtils.ip2Long(network.getGateway()); + String lastIp = NetUtils.getIpRangeEndIpFromCidr(subnet, cidrSize); + if (gatewayIp == ip) { ip = ipIterator.next(); + ipAddressRanges.add(Pair.of(NetUtils.long2Ip(ip), lastIp)); + } else if (!network.getGateway().equals(lastIp)) { + ipAddressRanges.add(Pair.of(NetUtils.long2Ip(ip), NetUtils.long2Ip(gatewayIp - 1))); + ipAddressRanges.add(Pair.of(NetUtils.long2Ip(gatewayIp + 1), lastIp)); + } else { + ipAddressRanges.add(Pair.of(NetUtils.long2Ip(ip), NetUtils.long2Ip(gatewayIp - 1))); } - ipAddressRanges.add(Pair.of(NetUtils.long2Ip(ip), NetUtils.getIpRangeEndIpFromCidr(subnet, cidrSize))); + return ipAddressRanges; } + public Pair getIpAddressRange(Vlan vlan) { + boolean isIpv4 = StringUtils.isNotBlank(vlan.getIpRange()); + String[] range = isIpv4 ? vlan.getIpRange().split("-") : vlan.getIp6Range().split("-"); + if (range.length == 2) { + return Pair.of(range[0], range[1]); + } + return null; + } + private String getVirtualRouterIP(Network network, List> ipAddressRanges) throws InsufficientVirtualNetworkCapacityException { + if (network.getBroadcastUri() != null) { + return network.getBroadcastUri().getPath().substring(1); + } + Pair lowestIpAddressRange = null; + long ipCount = 0; if (ipAddressRanges.size() == 1) { lowestIpAddressRange = Iterables.getOnlyElement(ipAddressRanges); + ipCount = NetUtils.ip2Long(lowestIpAddressRange.getRight()) - NetUtils.ip2Long(lowestIpAddressRange.getLeft()) + 1; } else { for (Pair ipAddressRange : ipAddressRanges) { if (lowestIpAddressRange == null || NetUtils.ip2Long(ipAddressRange.getLeft()) < NetUtils.ip2Long(lowestIpAddressRange.getLeft())) { lowestIpAddressRange = ipAddressRange; } + ipCount += NetUtils.ip2Long(ipAddressRange.getRight()) - NetUtils.ip2Long(ipAddressRange.getLeft()) + 1; } } - if (lowestIpAddressRange == null) { + if (ipCount == 0) { throw new InsufficientVirtualNetworkCapacityException("VSP allocates an IP for VirtualRouter." + " But no ip address ranges are specified", Network.class, network.getId()); - } else if (NetUtils.ip2Long(lowestIpAddressRange.getRight()) - NetUtils.ip2Long(lowestIpAddressRange.getLeft()) < 2) { + } else if (ipCount < 3) { throw new InsufficientVirtualNetworkCapacityException("VSP allocates an IP for VirtualRouter." + " So, subnet should have atleast minimum 3 hosts", Network.class, network.getId()); } @@ -269,20 +360,23 @@ public class NuageVspEntityBuilder { } public VspNic buildVspNic(String nicUuid, NicProfile nicProfile) { - VspNic.Builder vspNicBuilder = new VspNic.Builder() - .uuid(nicUuid) - .macAddress(nicProfile.getMacAddress()) - .useStaticIp(true) - .ip(nicProfile.getIPv4Address()); - return vspNicBuilder.build(); + return buildVspNic(nicUuid, nicProfile.getMacAddress(), nicProfile.getIPv4Address(), nicProfile.getNetworkId()); } public VspNic buildVspNic(NicVO nic) { + return buildVspNic(nic.getUuid(), nic.getMacAddress(), nic.getIPv4Address(), nic.getNetworkId()); + } + + private VspNic buildVspNic(String uuid, String macAddress, String ip, long networkId) { VspNic.Builder vspNicBuilder = new VspNic.Builder() - .uuid(nic.getUuid()) - .macAddress(nic.getMacAddress()) + .uuid(uuid) + .macAddress(macAddress) .useStaticIp(true) - .ip(nic.getIPv4Address()); + .ip(ip); + + Network network = _networkDao.findById(networkId); + NetworkOffering networkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId()); + return vspNicBuilder.build(); } @@ -403,7 +497,7 @@ public class NuageVspEntityBuilder { List dnsProvider = _ntwkOfferingSrvcDao.listProvidersForServiceForNetworkOffering(offering.getId(), Network.Service.Dns); boolean isVrDnsProvider = dnsProvider.contains("VirtualRouter") || dnsProvider.contains("VpcVirtualRouter"); VspDhcpDomainOption.Builder vspDhcpDomainBuilder = new VspDhcpDomainOption.Builder() - .dnsServers(_nuageVspManager.getDnsDetails(network)) + .dnsServers(_nuageVspManager.getDnsDetails(network.getDataCenterId())) .vrIsDnsProvider(isVrDnsProvider); if (isVrDnsProvider) { diff --git a/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/NuageVspPluginClientLoader.java b/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/NuageVspPluginClientLoader.java deleted file mode 100644 index 72ce2909e21..00000000000 --- a/plugins/network-elements/nuage-vsp/src/net/nuage/vsp/acs/NuageVspPluginClientLoader.java +++ /dev/null @@ -1,86 +0,0 @@ -// -// 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 net.nuage.vsp.acs; - -import net.nuage.vsp.acs.client.api.NuageVspApiClient; -import net.nuage.vsp.acs.client.api.NuageVspElementClient; -import net.nuage.vsp.acs.client.api.NuageVspGuruClient; -import net.nuage.vsp.acs.client.api.NuageVspManagerClient; -import net.nuage.vsp.acs.client.api.impl.NuageVspApiClientImpl; -import net.nuage.vsp.acs.client.api.impl.NuageVspElementClientImpl; -import net.nuage.vsp.acs.client.api.impl.NuageVspGuruClientImpl; -import net.nuage.vsp.acs.client.api.impl.NuageVspManagerClientImpl; -import net.nuage.vsp.acs.client.api.model.VspHost; -import org.apache.log4j.Logger; - - -public class NuageVspPluginClientLoader { - - private static final Logger s_logger = Logger.getLogger(NuageVspPluginClientLoader.class); - - private NuageVspApiClient _nuageVspApiClient; - private NuageVspElementClient _nuageVspElementClient; - private NuageVspGuruClient _nuageVspGuruClient; - private NuageVspManagerClient _nuageVspManagerClient; - - private NuageVspPluginClientLoader() { - - } - - public static NuageVspPluginClientLoader getClientLoader(String relativePath, String cmsUserEnterprise, String cmsUserLogin, - String cmsUserPassword, int numRetries, int retryInterval, String nuageVspCmsId) { - NuageVspPluginClientLoader nuageVspPluginClientClassloader = new NuageVspPluginClientLoader(); - nuageVspPluginClientClassloader.loadClasses(relativePath, cmsUserEnterprise, cmsUserLogin, cmsUserPassword, numRetries, retryInterval, nuageVspCmsId); - return nuageVspPluginClientClassloader; - } - - private void loadClasses(String relativePath, String cmsUserEnterprise, String cmsUserLogin, String cmsUserPassword, int numRetries, - int retryInterval, String nuageVspCmsId) { - VspHost vspHost = new VspHost.Builder() - .restRelativePath(relativePath) - .cmsUserEnterprise(cmsUserEnterprise) - .cmsUserLogin(cmsUserLogin) - .cmsUserPassword(cmsUserPassword) - .noofRetry(numRetries) - .retryInterval(retryInterval) - .nuageVspCmsId(nuageVspCmsId) - .build(); - _nuageVspApiClient = new NuageVspApiClientImpl(vspHost); - _nuageVspElementClient = new NuageVspElementClientImpl(_nuageVspApiClient); - _nuageVspGuruClient = new NuageVspGuruClientImpl(_nuageVspApiClient); - _nuageVspManagerClient = new NuageVspManagerClientImpl(_nuageVspApiClient); - } - - public NuageVspApiClient getNuageVspApiClient() { - return _nuageVspApiClient; - } - - public NuageVspElementClient getNuageVspElementClient() { - return _nuageVspElementClient; - } - - public NuageVspGuruClient getNuageVspGuruClient() { - return _nuageVspGuruClient; - } - - public NuageVspManagerClient getNuageVspManagerClient() { - return _nuageVspManagerClient; - } -} diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/NuageTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/NuageTest.java index 6522d2b39e5..14742657e86 100644 --- a/plugins/network-elements/nuage-vsp/test/com/cloud/NuageTest.java +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/NuageTest.java @@ -29,7 +29,6 @@ import net.nuage.vsp.acs.client.api.model.VspNetwork; import net.nuage.vsp.acs.client.api.model.VspNic; 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.junit.Before; import org.mockito.Mock; @@ -56,6 +55,7 @@ import static com.cloud.network.manager.NuageVspManager.NuageVspSharedNetworkDom import static com.cloud.network.manager.NuageVspManager.NuageVspVpcDomainTemplateName; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.when; @@ -78,7 +78,8 @@ public class NuageTest { when(_configurationDao.getValue(NuageVspSharedNetworkDomainTemplateName.key())).thenReturn("SharedDomainTemplate"); when(_nuageVspEntityBuilder.buildVspDomain(any(Domain.class))).thenReturn(buildVspDomain()); - when(_nuageVspEntityBuilder.buildVspNetwork(any(Network.class), anyBoolean())).thenReturn(buildVspNetwork()); + when(_nuageVspEntityBuilder.buildVspNetwork(any(Network.class))).thenReturn(buildVspNetwork()); + when(_nuageVspEntityBuilder.buildVspNetwork(anyLong(), any(Network.class))).thenReturn(buildVspNetwork()); when(_nuageVspEntityBuilder.buildVspVm(any(VirtualMachine.class), any(Network.class))).thenReturn(buildVspVm()); when(_nuageVspEntityBuilder.buildVspNic(anyString(), any(NicProfile.class))).thenReturn(buildVspNic()); when(_nuageVspEntityBuilder.buildVspNic(any(NicVO.class))).thenReturn(buildVspNic()); @@ -112,7 +113,6 @@ public class NuageTest { .cidr("networkCidr") .gateway("networkGateway") .virtualRouterIp("virtualRouterIp") - .ipAddressRanges(new ArrayList>()) .build(); } diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/agent/api/CommandsTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/agent/api/CommandsTest.java index 03fe5eb9170..5877ab0ce96 100644 --- a/plugins/network-elements/nuage-vsp/test/com/cloud/agent/api/CommandsTest.java +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/agent/api/CommandsTest.java @@ -21,8 +21,13 @@ package com.cloud.agent.api; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; import java.util.Map; +import net.nuage.vsp.acs.client.api.model.Protocol; +import net.nuage.vsp.acs.client.api.model.VspAclRule; +import net.nuage.vsp.acs.client.api.model.VspNetwork; + import org.junit.Assert; import org.junit.Test; @@ -44,6 +49,8 @@ import com.cloud.agent.api.sync.SyncDomainCommand; import com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand; import com.cloud.serializer.GsonHelper; +import static org.hamcrest.core.Is.is; + public class CommandsTest { private static final Gson s_gson = GsonHelper.getGson(); @@ -94,6 +101,38 @@ public class CommandsTest { tester.testEquals(); } + @Test + public void testApplyAclRuleVspCommandGsonEquals() throws IllegalAccessException, InvocationTargetException, InstantiationException { + VspNetwork vspNetwork = new VspNetwork.Builder() + .id(1) + .uuid("uuid") + .name("name") + .cidr("192.168.1.0/24") + .gateway("192.168.1.1") + .build(); + + VspAclRule aclRule = new VspAclRule.Builder() + .action(VspAclRule.ACLAction.Allow) + .uuid("uuid") + .trafficType(VspAclRule.ACLTrafficType.Egress) + .protocol(Protocol.TCP) + .startPort(80) + .endPort(80) + .priority(1) + .state(VspAclRule.ACLState.Active) + .build(); + + ApplyAclRuleVspCommand before = new ApplyAclRuleVspCommand(VspAclRule.ACLType.NetworkACL, vspNetwork, Arrays.asList(aclRule), false); + ApplyAclRuleVspCommand after = serializeAndDeserialize(before); + + Assert.assertThat(after.getAclRules().get(0).getProtocol().hasPort(), is(Protocol.TCP.hasPort())); + } + + private T serializeAndDeserialize(T command) { + Command[] forwardedCommands = s_gson.fromJson(s_gson.toJson(new Command[] { command }), Command[].class); + return (T) forwardedCommands[0]; + } + private void addCommandGsonEqualityGroup(Class clazz) throws IllegalAccessException, InvocationTargetException, InstantiationException{ addCommandGsonEqualityGroup(fillObject(clazz)); } diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java index aad6398f19f..1916271db69 100644 --- a/plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java @@ -24,7 +24,6 @@ import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashSet; import java.util.Set; import org.junit.Before; @@ -33,6 +32,7 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import org.apache.cloudstack.resourcedetail.dao.VpcDetailsDao; @@ -113,6 +113,9 @@ public class NuageVspElementTest extends NuageTest { public void setUp() throws Exception { super.setUp(); _nuageVspElement._nuageVspEntityBuilder = _nuageVspEntityBuilder; + _nuageVspElement._vpcDetailsDao = _vpcDetailsDao; + _nuageVspElement._routerDao = _domainRouterDao; + when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true); when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.SourceNat, Provider.NuageVsp)).thenReturn(true); @@ -152,6 +155,9 @@ public class NuageVspElementTest extends NuageTest { // Only service Connectivity is supported assertFalse(_nuageVspElement.canHandle(net, Service.Dhcp)); + // Can't handle network offerings with specify vlan = true + when(ntwkoffer.getSpecifyVlan()).thenReturn(true); + assertFalse(_nuageVspElement.canHandle(net, Service.Connectivity)); } @Test @@ -163,6 +169,7 @@ public class NuageVspElementTest extends NuageTest { when(network.getBroadcastUri()).thenReturn(new URI("")); when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); when(network.getDomainId()).thenReturn(NETWORK_ID); + when(network.getDataCenterId()).thenReturn(NETWORK_ID); when(_networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(true); final NetworkOffering offering = mock(NetworkOffering.class); @@ -192,27 +199,28 @@ public class NuageVspElementTest extends NuageTest { when(_firewallRulesDao.listByNetworkPurposeTrafficType(NETWORK_ID, FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Ingress)).thenReturn(new ArrayList()); when(_firewallRulesDao.listByNetworkPurposeTrafficType(NETWORK_ID, FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Egress)).thenReturn(new ArrayList()); when(_ipAddressDao.listStaticNatPublicIps(NETWORK_ID)).thenReturn(new ArrayList()); - when(_nuageVspManager.getDnsDetails(network)).thenReturn(new ArrayList()); + when(_nuageVspManager.getDnsDetails(network.getDataCenterId())).thenReturn(new ArrayList()); assertTrue(_nuageVspElement.implement(network, offering, deployDest, context)); } @Test public void testVerifyServiceCombination() { - Set services = new HashSet(); - services.add(Service.Dhcp); - services.add(Service.StaticNat); - services.add(Service.SourceNat); - services.add(Service.Connectivity); - services.add(Service.Firewall); + + Set services = Sets.newHashSet( + Service.Dhcp, + Service.StaticNat, + Service.SourceNat, + Service.Connectivity, + Service.Firewall); assertTrue(_nuageVspElement.verifyServicesCombination(services)); - services = new HashSet(); - services.add(Service.Dhcp); - services.add(Service.StaticNat); - services.add(Service.Connectivity); - services.add(Service.Firewall); - assertFalse(_nuageVspElement.verifyServicesCombination(services)); + services = Sets.newHashSet( + Service.Dhcp, + Service.StaticNat, + Service.Connectivity, + Service.Firewall); + assertTrue(_nuageVspElement.verifyServicesCombination(services)); } @Test diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java index fdfc4d5f251..8f334eba784 100644 --- a/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java @@ -29,8 +29,9 @@ import org.junit.Before; import org.junit.Test; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.internal.util.collections.Sets; -import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import com.google.common.collect.ImmutableMap; import com.cloud.NuageTest; import com.cloud.agent.AgentManager; @@ -53,7 +54,6 @@ import com.cloud.host.dao.HostDao; import com.cloud.network.Network; import com.cloud.network.Network.GuestType; import com.cloud.network.Network.Service; -import com.cloud.network.NetworkModel; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; @@ -100,7 +100,6 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest { @Mock private DataCenterDao _dataCenterDao; @Mock private NetworkOfferingServiceMapDao _networkOfferingServiceMapDao; @Mock private AgentManager _agentManager; - @Mock private NetworkModel _networkModel; @Mock private AccountDao _accountDao; @Mock private DomainDao _domainDao; @Mock private NicDao _nicDao; @@ -108,7 +107,6 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest { @Mock private NuageVspDao _nuageVspDao; @Mock private HostDao _hostDao; @Mock private NetworkDao _networkDao; - @Mock private ConfigurationDao _configurationDao; @Mock private IPAddressDao _ipAddressDao; @Mock private NuageVspManager _nuageVspManager; @Mock private ConfigurationManager _configurationManager; @@ -162,6 +160,11 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest { when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(NETWORK_ID, Service.Connectivity, Network.Provider.NuageVsp)).thenReturn(true); when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(NETWORK_ID, Service.SourceNat, Network.Provider.NuageVsp)).thenReturn(true); + when(_networkModel.getNetworkOfferingServiceProvidersMap(NETWORK_ID)).thenReturn(ImmutableMap.of( + Service.Connectivity, Sets.newSet(Network.Provider.NuageVsp), + Service.SourceNat, Sets.newSet(Network.Provider.NuageVsp) + )); + when(offering.getTrafficType()).thenReturn(TrafficType.Guest); when(offering.getGuestType()).thenReturn(GuestType.Isolated); assertThat(_nuageVspGuestNetworkGuru.canHandle(offering, NetworkType.Advanced, physnet), is(true)); @@ -204,6 +207,11 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest { when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(NETWORK_ID, Service.Connectivity, Network.Provider.NuageVsp)).thenReturn(true); when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(NETWORK_ID, Service.SourceNat, Network.Provider.NuageVsp)).thenReturn(true); + when(_networkModel.getNetworkOfferingServiceProvidersMap(NETWORK_ID)).thenReturn(ImmutableMap.of( + Service.Connectivity, Sets.newSet(Network.Provider.NuageVsp), + Service.SourceNat, Sets.newSet(Network.Provider.NuageVsp) + )); + final DeploymentPlan plan = mock(DeploymentPlan.class); final Network network = mock(Network.class); final Account account = mock(Account.class); @@ -269,10 +277,12 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest { final DataCenterVO dataCenter = mock(DataCenterVO.class); when(_dataCenterDao.findById(NETWORK_ID)).thenReturn(dataCenter); final AccountVO networksAccount = mock(AccountVO.class); + when(networksAccount.getId()).thenReturn(NETWORK_ID); when(networksAccount.getUuid()).thenReturn("aaaa-abbbb"); when(networksAccount.getType()).thenReturn(Account.ACCOUNT_TYPE_NORMAL); when(_accountDao.findById(NETWORK_ID)).thenReturn(networksAccount); final DomainVO networksDomain = mock(DomainVO.class); + when(networksDomain.getId()).thenReturn(NETWORK_ID); when(networksDomain.getUuid()).thenReturn("aaaaa-bbbbb"); when(_domainDao.findById(NETWORK_ID)).thenReturn(networksDomain); @@ -308,7 +318,15 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest { when(_ipAddressDao.findByVmIdAndNetworkId(NETWORK_ID, NETWORK_ID)).thenReturn(null); when(_domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class)); - _nuageVspGuestNetworkGuru.reserve(nicProfile, network, vmProfile, mock(DeployDestination.class), mock(ReservationContext.class)); + final Answer answer = mock(Answer.class); + when(answer.getResult()).thenReturn(true); + when(_agentManager.easySend(eq(NETWORK_ID), (Command)any())).thenReturn(answer); + + final ReservationContext reservationContext = mock(ReservationContext.class); + when(reservationContext.getAccount()).thenReturn(networksAccount); + when(reservationContext.getDomain()).thenReturn(networksDomain); + + _nuageVspGuestNetworkGuru.reserve(nicProfile, network, vmProfile, mock(DeployDestination.class), reservationContext); } @Test @@ -341,9 +359,11 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest { final ReservationContext reserveContext = mock(ReservationContext.class); final Domain domain = mock(Domain.class); + when(domain.getId()).thenReturn(NETWORK_ID); when(reserveContext.getDomain()).thenReturn(domain); when(domain.getName()).thenReturn("aaaaa"); final Account account = mock(Account.class); + when(account.getId()).thenReturn(NETWORK_ID); when(account.getAccountId()).thenReturn(NETWORK_ID); when(reserveContext.getAccount()).thenReturn(account); final DomainVO domainVo = mock(DomainVO.class); @@ -352,7 +372,7 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest { when(_accountDao.findById(NETWORK_ID)).thenReturn(accountVo); when(_networkDao.acquireInLockTable(NETWORK_ID, 1200)).thenReturn(network); - when(_nuageVspManager.getDnsDetails(network)).thenReturn(new ArrayList()); + when(_nuageVspManager.getDnsDetails(network.getDataCenterId())).thenReturn(new ArrayList()); when(_nuageVspManager.getGatewaySystemIds()).thenReturn(new ArrayList()); final DataCenter dc = mock(DataCenter.class); @@ -414,6 +434,7 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest { when(network.getDomainId()).thenReturn(NETWORK_ID); when(network.getNetworkOfferingId()).thenReturn(NETWORK_ID); when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); + when(network.getDataCenterId()).thenReturn(NETWORK_ID); when(network.getVpcId()).thenReturn(null); when(_networkDao.acquireInLockTable(NETWORK_ID, 1200)).thenReturn(network); @@ -426,7 +447,13 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest { when(domain.getUuid()).thenReturn("aaaaaa"); when(_domainDao.findById(NETWORK_ID)).thenReturn(domain); - when(_nuageVspManager.getDnsDetails(network)).thenReturn(new ArrayList()); + final HostVO host = mock(HostVO.class); + when(host.getId()).thenReturn(NETWORK_ID); + final NuageVspDeviceVO nuageVspDevice = mock(NuageVspDeviceVO.class); + when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); + when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(new NuageVspDeviceVO[]{nuageVspDevice})); + when(_hostDao.findById(NETWORK_ID)).thenReturn(host); + when(_nuageVspManager.getDnsDetails(network.getDataCenterId())).thenReturn(new ArrayList()); when(_nuageVspManager.getGatewaySystemIds()).thenReturn(new ArrayList()); assertTrue(_nuageVspGuestNetworkGuru.trash(network, offering)); diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/network/resource/NuageVspResourceTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/network/resource/NuageVspResourceTest.java index 0983ab65d93..e497ec4d396 100644 --- a/plugins/network-elements/nuage-vsp/test/com/cloud/network/resource/NuageVspResourceTest.java +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/network/resource/NuageVspResourceTest.java @@ -28,9 +28,12 @@ import javax.naming.ConfigurationException; import net.nuage.vsp.acs.client.api.NuageVspApiClient; import net.nuage.vsp.acs.client.api.NuageVspElementClient; import net.nuage.vsp.acs.client.api.NuageVspGuruClient; +import net.nuage.vsp.acs.client.api.NuageVspManagerClient; +import net.nuage.vsp.acs.client.api.NuageVspPluginClientLoader; import net.nuage.vsp.acs.client.api.model.VspAclRule; import net.nuage.vsp.acs.client.api.model.VspDhcpDomainOption; import net.nuage.vsp.acs.client.api.model.VspDhcpVMOption; +import net.nuage.vsp.acs.client.api.model.VspHost; import net.nuage.vsp.acs.client.api.model.VspNetwork; import net.nuage.vsp.acs.client.api.model.VspNic; import net.nuage.vsp.acs.client.api.model.VspStaticNat; @@ -38,7 +41,8 @@ import net.nuage.vsp.acs.client.api.model.VspVm; import org.junit.Before; import org.junit.Test; -import org.mockito.invocation.InvocationOnMock; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; import com.google.common.collect.Lists; import com.google.common.collect.Maps; @@ -56,45 +60,36 @@ import com.cloud.agent.api.guru.ReserveVmInterfaceVspCommand; import com.cloud.agent.api.guru.TrashNetworkVspCommand; import com.cloud.host.Host; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; public class NuageVspResourceTest extends NuageTest { private NuageVspResource _resource; - private NuageVspApiClient _mockNuageVspApiClient = mock(NuageVspApiClient.class); - private NuageVspElementClient _mockNuageVspElementClient = mock(NuageVspElementClient.class); - private NuageVspGuruClient _mockNuageVspGuruClient = mock(NuageVspGuruClient.class); - private NuageVspResource.Configuration _resourceConfiguration; + @Mock private NuageVspApiClient _mockNuageVspApiClient; + @Mock private NuageVspElementClient _mockNuageVspElementClient; + @Mock private NuageVspGuruClient _mockNuageVspGuruClient; + @Mock private NuageVspManagerClient _mockNuageVspManagerClient; + @Mock private NuageVspPluginClientLoader _mockNuageVspPluginClientLoader; + private NuageVspResourceConfiguration _resourceConfiguration; private Map _hostDetails; - org.mockito.stubbing.Answer genericAnswer = new org.mockito.stubbing.Answer() { - public Object answer(InvocationOnMock invocation) { - return null; - } - }; - @Before public void setUp() throws Exception { super.setUp(); + MockitoAnnotations.initMocks(this); + + when(_mockNuageVspPluginClientLoader.getNuageVspApiClient()).thenReturn(_mockNuageVspApiClient); + when(_mockNuageVspPluginClientLoader.getNuageVspElementClient()).thenReturn(_mockNuageVspElementClient); + when(_mockNuageVspPluginClientLoader.getNuageVspGuruClient()).thenReturn(_mockNuageVspGuruClient); + when(_mockNuageVspPluginClientLoader.getNuageVspManagerClient()).thenReturn(_mockNuageVspManagerClient); + _resource = new NuageVspResource() { - - @Override - protected void loadNuageClient() { - _isNuageVspClientLoaded = true; - _nuageVspApiClient = _mockNuageVspApiClient; - _nuageVspElementClient = _mockNuageVspElementClient; - _nuageVspGuruClient = _mockNuageVspGuruClient; - } - - protected void isNuageVspApiLoaded() throws ConfigurationException { - } - - protected void isNuageVspGuruLoaded() throws ConfigurationException { - } - - protected void isNuageVspElementLoaded() throws ConfigurationException { + @Override protected NuageVspPluginClientLoader getClientLoader(VspHost vspHost) { + return _mockNuageVspPluginClientLoader; } protected void login() throws ConfigurationException { @@ -102,8 +97,7 @@ public class NuageVspResourceTest extends NuageTest { }; - _resourceConfiguration = new NuageVspResource.Configuration() - .name("nuagevsptestdevice") + _resourceConfiguration = new NuageVspResourceConfiguration() .guid("aaaaa-bbbbb-ccccc") .zoneId("blublub") .hostName("nuagevsd") @@ -124,21 +118,21 @@ public class NuageVspResourceTest extends NuageTest { @Test public void resourceConfigure() throws Exception { - _resource.configure("NuageVspResource", _hostDetails); + _resource.configure("Nuage VSD - nuagevsd", _hostDetails); - assertTrue("nuagevsptestdevice".equals(_resource.getName())); - assertTrue(_resource.getType() == Host.Type.L2Networking); + assertEquals("Nuage VSD - nuagevsd", _resource.getName()); + assertEquals(Host.Type.L2Networking, _resource.getType()); } @Test public void testInitialization() throws Exception { - _resource.configure("NuageVspResource", _hostDetails); + _resource.configure("Nuage VSD - nuagevsd", _hostDetails); StartupCommand[] sc = _resource.initialize(); - assertTrue(sc.length == 1); - assertTrue("aaaaa-bbbbb-ccccc".equals(sc[0].getGuid())); - assertTrue("nuagevsptestdevice".equals(sc[0].getName())); - assertTrue("blublub".equals(sc[0].getDataCenter())); + assertEquals(1, sc.length); + assertEquals("aaaaa-bbbbb-ccccc", sc[0].getGuid()); + assertEquals("Nuage VSD - nuagevsd", sc[0].getName()); + assertEquals("blublub", sc[0].getDataCenter()); } @Test @@ -146,9 +140,9 @@ public class NuageVspResourceTest extends NuageTest { _resource.configure("NuageVspResource", _hostDetails); PingCommand ping = _resource.getCurrentStatus(42); - assertTrue(ping != null); - assertTrue(ping.getHostId() == 42); - assertTrue(ping.getHostType() == Host.Type.L2Networking); + assertNotNull(ping); + assertEquals(42, ping.getHostId()); + assertEquals(Host.Type.L2Networking, ping.getHostType()); } @Test @@ -158,9 +152,9 @@ public class NuageVspResourceTest extends NuageTest { VspNetwork vspNetwork = buildVspNetwork(); VspDhcpDomainOption vspDhcpOptions = buildspDhcpDomainOption(); ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, vspDhcpOptions); - doAnswer(genericAnswer).when(_mockNuageVspGuruClient).implement(vspNetwork, vspDhcpOptions); com.cloud.agent.api.Answer implNtwkAns = _resource.executeRequest(cmd); assertTrue(implNtwkAns.getResult()); + verify(_mockNuageVspGuruClient).implement(vspNetwork, vspDhcpOptions); } @Test @@ -173,7 +167,6 @@ public class NuageVspResourceTest extends NuageTest { VspStaticNat vspStaticNat = buildVspStaticNat(); VspDhcpVMOption vspDhcpOption = buildspDhcpVMOption(); ReserveVmInterfaceVspCommand cmd = new ReserveVmInterfaceVspCommand(vspNetwork, vspVm, vspNic, vspStaticNat, vspDhcpOption); - doAnswer(genericAnswer).when(_mockNuageVspGuruClient).reserve(vspNetwork, vspVm, vspNic, vspStaticNat, vspDhcpOption); Answer rsrvVmInfAns = _resource.executeRequest(cmd); assertTrue(rsrvVmInfAns.getResult()); } @@ -186,7 +179,6 @@ public class NuageVspResourceTest extends NuageTest { VspVm vspVm = buildVspVm(); VspNic vspNic = buildVspNic(); DeallocateVmVspCommand cmd = new DeallocateVmVspCommand(vspNetwork, vspVm, vspNic); - doAnswer(genericAnswer).when(_mockNuageVspGuruClient).deallocate(vspNetwork, vspVm, vspNic); Answer dellocateVmAns = _resource.executeRequest(cmd); assertTrue(dellocateVmAns.getResult()); } @@ -197,7 +189,6 @@ public class NuageVspResourceTest extends NuageTest { VspNetwork vspNetwork = buildVspNetwork(); TrashNetworkVspCommand cmd = new TrashNetworkVspCommand(vspNetwork); - doAnswer(genericAnswer).when(_mockNuageVspGuruClient).trash(vspNetwork); Answer trashNtwkAns = _resource.executeRequest(cmd); assertTrue(trashNtwkAns.getResult()); } @@ -209,7 +200,6 @@ public class NuageVspResourceTest extends NuageTest { VspNetwork vspNetwork = buildVspNetwork(); List vspStaticNatDetails = Lists.newArrayList(buildVspStaticNat()); ApplyStaticNatVspCommand cmd = new ApplyStaticNatVspCommand(vspNetwork, vspStaticNatDetails); - doAnswer(genericAnswer).when(_mockNuageVspElementClient).applyStaticNats(vspNetwork, vspStaticNatDetails); Answer applyNatAns = _resource.executeRequest(cmd); assertTrue(applyNatAns.getResult()); } @@ -221,7 +211,6 @@ public class NuageVspResourceTest extends NuageTest { VspNetwork vspNetwork = buildVspNetwork(); List vspAclRules = Lists.newArrayList(buildVspAclRule()); ApplyAclRuleVspCommand cmd = new ApplyAclRuleVspCommand(VspAclRule.ACLType.NetworkACL, vspNetwork, vspAclRules, false); - doAnswer(genericAnswer).when(_mockNuageVspElementClient).applyAclRules(VspAclRule.ACLType.NetworkACL, vspNetwork, vspAclRules, false); Answer applyAclAns = _resource.executeRequest(cmd); assertTrue(applyAclAns.getResult()); } @@ -231,7 +220,6 @@ public class NuageVspResourceTest extends NuageTest { _resource.configure("NuageVspResource", _hostDetails); ShutDownVpcVspCommand cmd = new ShutDownVpcVspCommand("domainUuid", "vpcUuid", "domainTemplateName", Lists.newArrayList()); - doAnswer(genericAnswer).when(_mockNuageVspElementClient).shutdownVpc("domainUuid", "vpcUuid", "domainTemplateName", Lists.newArrayList()); Answer shutVpcAns = _resource.executeRequest(cmd); assertTrue(shutVpcAns.getResult()); } diff --git a/plugins/network-elements/nuage-vsp/test/com/cloud/util/NuageVspEntityBuilderTest.java b/plugins/network-elements/nuage-vsp/test/com/cloud/util/NuageVspEntityBuilderTest.java index 26e36b4e56c..a3f87529b52 100644 --- a/plugins/network-elements/nuage-vsp/test/com/cloud/util/NuageVspEntityBuilderTest.java +++ b/plugins/network-elements/nuage-vsp/test/com/cloud/util/NuageVspEntityBuilderTest.java @@ -19,6 +19,19 @@ package com.cloud.util; +import net.nuage.vsp.acs.client.api.model.Protocol; +import net.nuage.vsp.acs.client.api.model.VspAclRule; +import net.nuage.vsp.acs.client.api.model.VspDomain; +import net.nuage.vsp.acs.client.api.model.VspNetwork; +import net.nuage.vsp.acs.client.api.model.VspNic; +import net.nuage.vsp.acs.client.api.model.VspStaticNat; +import net.nuage.vsp.acs.client.api.model.VspVm; + +import org.junit.Before; +import org.junit.Test; + +import com.google.common.collect.Lists; + import com.cloud.NuageTest; import com.cloud.dc.VlanDetailsVO; import com.cloud.dc.VlanVO; @@ -29,6 +42,7 @@ import com.cloud.domain.dao.DomainDao; import com.cloud.network.Network; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkDetailsDao; import com.cloud.network.dao.NetworkVO; import com.cloud.network.rules.FirewallRule; @@ -44,18 +58,6 @@ import com.cloud.utils.net.Ip; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; import com.cloud.vm.VirtualMachine; -import com.google.common.collect.Lists; -import net.nuage.vsp.acs.client.api.model.VspAclRule; -import net.nuage.vsp.acs.client.api.model.VspDomain; -import net.nuage.vsp.acs.client.api.model.VspNetwork; -import net.nuage.vsp.acs.client.api.model.VspNic; -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.junit.Before; -import org.junit.Test; - -import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -78,6 +80,7 @@ public class NuageVspEntityBuilderTest extends NuageTest { private VpcDao _vpcDao = mock(VpcDao.class); private DomainDao _domainDao = mock(DomainDao.class); private AccountDao _accountDao = mock(AccountDao.class); + private NetworkDao _networkDao = mock(NetworkDao.class); private NetworkOfferingDao _networkOfferingDao = mock(NetworkOfferingDao.class); private NetworkOfferingServiceMapDao _networkOfferingServiceMapDao = mock(NetworkOfferingServiceMapDao.class); private VlanDao _vlanDao = mock(VlanDao.class); @@ -114,6 +117,7 @@ public class NuageVspEntityBuilderTest extends NuageTest { _nuageVspEntityBuilder._vpcDao = _vpcDao; _nuageVspEntityBuilder._domainDao = _domainDao; _nuageVspEntityBuilder._accountDao = _accountDao; + _nuageVspEntityBuilder._networkDao = _networkDao; _nuageVspEntityBuilder._networkOfferingDao = _networkOfferingDao; _nuageVspEntityBuilder._networkOfferingServiceMapDao = _networkOfferingServiceMapDao; _nuageVspEntityBuilder._vlanDao = _vlanDao; @@ -154,29 +158,29 @@ public class NuageVspEntityBuilderTest extends NuageTest { @Test public void testBuildVspNetwork() { - VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedL2Network, true); - validateVspNetwork(vspNetwork, true, false, false, false, "IsolatedDomainTemplate", true); + VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedL2Network); + validateVspNetwork(vspNetwork, true, false, false, false, "IsolatedDomainTemplate"); - vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedL2Network, false); - validateVspNetwork(vspNetwork, true, false, false, false, "IsolatedDomainTemplate", false); + vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedL2Network); + validateVspNetwork(vspNetwork, true, false, false, false, "IsolatedDomainTemplate"); - vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedNetwork, true); - validateVspNetwork(vspNetwork, false, true, false, false, "IsolatedDomainTemplate", true); + vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedNetwork); + validateVspNetwork(vspNetwork, false, true, false, false, "IsolatedDomainTemplate"); - vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedNetwork, false); - validateVspNetwork(vspNetwork, false, true, false, false, "IsolatedDomainTemplate", false); + vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedNetwork); + validateVspNetwork(vspNetwork, false, true, false, false, "IsolatedDomainTemplate"); - vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedVpcNetwork, true); - validateVspNetwork(vspNetwork, false, false, true, false, "VpcDomainTemplate", true); + vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedVpcNetwork); + validateVspNetwork(vspNetwork, false, false, true, false, "VpcDomainTemplate"); - vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedVpcNetwork, false); - validateVspNetwork(vspNetwork, false, false, true, false, "VpcDomainTemplate", false); + vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedVpcNetwork); + validateVspNetwork(vspNetwork, false, false, true, false, "VpcDomainTemplate"); - vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedSharedNetwork, true); - validateVspNetwork(vspNetwork, false, false, false, true, "SharedDomainTemplate", true); + vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedSharedNetwork); + validateVspNetwork(vspNetwork, false, false, false, true, "SharedDomainTemplate"); - vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedSharedNetwork, false); - validateVspNetwork(vspNetwork, false, false, false, true, "SharedDomainTemplate", false); + vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(_mockedSharedNetwork); + validateVspNetwork(vspNetwork, false, false, false, true, "SharedDomainTemplate"); } @Test @@ -219,7 +223,7 @@ public class NuageVspEntityBuilderTest extends NuageTest { } private void validateVspNetwork(VspNetwork vspNetwork, boolean isL2, boolean isL3, boolean isVpc, boolean isShared, - String domainTemplateName, boolean hasAddressRanges) { + String domainTemplateName) { assertEquals(NETWORK_ID, vspNetwork.getId()); assertEquals("networkUuid", vspNetwork.getUuid()); assertEquals("networkName", vspNetwork.getName()); @@ -245,22 +249,6 @@ public class NuageVspEntityBuilderTest extends NuageTest { assertEquals(domainTemplateName, vspNetwork.getDomainTemplateName()); assertEquals("10.10.10.0/24", vspNetwork.getCidr()); assertEquals("10.10.10.1", vspNetwork.getGateway()); - - if (hasAddressRanges) { - if (isShared) { - assertEquals("192.168.2.2", vspNetwork.getVirtualRouterIp()); - } else { - assertEquals("10.10.10.2", vspNetwork.getVirtualRouterIp()); - } - - List> ipAddressRanges; - if (isShared) { - ipAddressRanges = Lists.newArrayList(Pair.of("192.168.2.3", "192.168.2.200")); - } else { - ipAddressRanges = Lists.newArrayList(Pair.of("10.10.10.3", "10.10.10.254")); - } - assertEquals(ipAddressRanges, vspNetwork.getIpAddressRanges()); - } } private void validateVspVm(VspVm vspVm, boolean isDomainRouter) { @@ -289,7 +277,7 @@ public class NuageVspEntityBuilderTest extends NuageTest { private void validateVspAclRule(VspAclRule vspAclRule, boolean isFirewall) { assertEquals("aclUuid", vspAclRule.getUuid()); - assertEquals("aclProtocol", vspAclRule.getProtocol()); + assertEquals(Protocol.TCP, vspAclRule.getProtocol()); assertEquals(new Integer(1), vspAclRule.getStartPort()); assertEquals(new Integer(20), vspAclRule.getEndPort()); assertEquals(Lists.newArrayList("10.10.0.0/16"), vspAclRule.getSourceCidrList()); @@ -358,12 +346,14 @@ public class NuageVspEntityBuilderTest extends NuageTest { private void setUpMockedNicProfile() { when(_mockedNicProfile.getMacAddress()).thenReturn("macAddress"); when(_mockedNicProfile.getIPv4Address()).thenReturn("10.10.10.2"); + when(_mockedNicProfile.getNetworkId()).thenReturn(NETWORK_ID); } private void setUpMockedNic() { when(_mockedNic.getUuid()).thenReturn("nicUuid"); when(_mockedNic.getMacAddress()).thenReturn("macAddress"); when(_mockedNic.getIPv4Address()).thenReturn("10.10.10.2"); + when(_mockedNic.getNetworkId()).thenReturn(NETWORK_ID); } private void setUpMockedStaticNatIp() { @@ -381,7 +371,7 @@ public class NuageVspEntityBuilderTest extends NuageTest { private void setUpMockedFirewallRule() { when(_mockedFirewallRule.getUuid()).thenReturn("aclUuid"); - when(_mockedFirewallRule.getProtocol()).thenReturn("aclProtocol"); + when(_mockedFirewallRule.getProtocol()).thenReturn("TCP"); when(_mockedFirewallRule.getSourcePortStart()).thenReturn(1); when(_mockedFirewallRule.getSourcePortEnd()).thenReturn(20); when(_mockedFirewallRule.getSourceCidrList()).thenReturn(Lists.newArrayList("10.10.0.0/16")); @@ -392,7 +382,7 @@ public class NuageVspEntityBuilderTest extends NuageTest { private void setUpMockedNetworkAclItem() { when(_mockedNetworkAclItem.getUuid()).thenReturn("aclUuid"); - when(_mockedNetworkAclItem.getProtocol()).thenReturn("aclProtocol"); + when(_mockedNetworkAclItem.getProtocol()).thenReturn("TCP"); when(_mockedNetworkAclItem.getSourcePortStart()).thenReturn(1); when(_mockedNetworkAclItem.getSourcePortEnd()).thenReturn(20); when(_mockedNetworkAclItem.getSourceCidrList()).thenReturn(Lists.newArrayList("10.10.0.0/16")); @@ -405,6 +395,7 @@ public class NuageVspEntityBuilderTest extends NuageTest { private void setUpMockedDaoCalls() { when(_domainDao.findById(DOMAIN_ID)).thenReturn(_mockedDomain); when(_accountDao.findById(ACCOUNT_ID)).thenReturn(_mockedAccount); + when(_networkDao.findById(NETWORK_ID)).thenReturn(_mockedNetwork); when(_networkOfferingDao.findById(NETWORK_OFFERING_ID)).thenReturn(_mockedNetworkOffering); when(_networkOfferingDao.findById(SHARED_NETWORK_OFFERING_ID)).thenReturn(_mockedSharedNetworkOffering); when(_networkOfferingDao.findById(L2_NETWORK_OFFERING_ID)).thenReturn(_mockedL2NetworkOffering); diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index e661a9bacb6..8563e1cebf1 100644 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -1820,6 +1820,7 @@ public class ApiResponseHelper implements ResponseGenerator { response.setEgressDefaultPolicy(offering.getEgressDefaultPolicy()); response.setConcurrentConnections(offering.getConcurrentConnections()); response.setSupportsStrechedL2Subnet(offering.getSupportsStrechedL2()); + response.setSupportsPublicAccess(offering.getSupportsPublicAccess()); Long so = null; if (offering.getServiceOfferingId() != null) { so = offering.getServiceOfferingId(); diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 1fe973ed87c..f33bd1a9d2c 100644 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -34,6 +34,9 @@ import java.util.UUID; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.google.common.base.MoreObjects; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; import org.apache.log4j.Logger; import org.apache.cloudstack.acl.SecurityChecker; @@ -158,7 +161,6 @@ import com.cloud.network.dao.PhysicalNetworkDao; import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao; import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO; import com.cloud.network.dao.PhysicalNetworkVO; -import com.cloud.network.element.NetworkElement; import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.vpc.VpcManager; import com.cloud.offering.DiskOffering; @@ -2851,16 +2853,16 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati String newVlanNetmask = newVlanNetmaskFinal; String newVlanGateway = newVlanGatewayFinal; - if ((sameSubnet == null || sameSubnet.first() == false) && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == GuestType.Shared + if ((sameSubnet == null || !sameSubnet.first()) && network.getTrafficType() == TrafficType.Guest && network.getGuestType() == GuestType.Shared && _vlanDao.listVlansByNetworkId(networkId) != null) { final Map dhcpCapabilities = _networkSvc.getNetworkOfferingServiceCapabilities(_networkOfferingDao.findById(network.getNetworkOfferingId()), Service.Dhcp); final String supportsMultipleSubnets = dhcpCapabilities.get(Capability.DhcpAccrossMultipleSubnets); if (supportsMultipleSubnets == null || !Boolean.valueOf(supportsMultipleSubnets)) { - throw new InvalidParameterValueException("The Dhcp serivice provider for this network dose not support the dhcp across multiple subnets"); + throw new InvalidParameterValueException("The dhcp service provider for this network does not support dhcp across multiple subnets"); } s_logger.info("adding a new subnet to the network " + network.getId()); - } else if (sameSubnet != null) { + } else if (sameSubnet != null) { // if it is same subnet the user might not send the vlan and the // netmask details. so we are // figuring out while validation and setting them here. @@ -2876,13 +2878,13 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati }); } - public NetUtils.SupersetOrSubset checkIfSubsetOrSuperset(String newVlanGateway, String newVlanNetmask, final VlanVO vlan, final String startIP, final String endIP) { + public NetUtils.SupersetOrSubset checkIfSubsetOrSuperset(String vlanGateway, String vlanNetmask, String newVlanGateway, String newVlanNetmask, final String newStartIP, final String newEndIP) { if (newVlanGateway == null && newVlanNetmask == null) { - newVlanGateway = vlan.getVlanGateway(); - newVlanNetmask = vlan.getVlanNetmask(); + newVlanGateway = vlanGateway; + newVlanNetmask = vlanNetmask; // this means he is trying to add to the existing subnet. - if (NetUtils.sameSubnet(startIP, newVlanGateway, newVlanNetmask)) { - if (NetUtils.sameSubnet(endIP, newVlanGateway, newVlanNetmask)) { + if (NetUtils.sameSubnet(newStartIP, newVlanGateway, newVlanNetmask)) { + if (NetUtils.sameSubnet(newEndIP, newVlanGateway, newVlanNetmask)) { return NetUtils.SupersetOrSubset.sameSubnet; } } @@ -2891,15 +2893,15 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati throw new InvalidParameterValueException( "either both netmask and gateway should be passed or both should me omited."); } else { - if (!NetUtils.sameSubnet(startIP, newVlanGateway, newVlanNetmask)) { + if (!NetUtils.sameSubnet(newStartIP, newVlanGateway, newVlanNetmask)) { throw new InvalidParameterValueException("The start ip and gateway do not belong to the same subnet"); } - if (!NetUtils.sameSubnet(endIP, newVlanGateway, newVlanNetmask)) { + if (!NetUtils.sameSubnet(newEndIP, newVlanGateway, newVlanNetmask)) { throw new InvalidParameterValueException("The end ip and gateway do not belong to the same subnet"); } } final String cidrnew = NetUtils.getCidrFromGatewayAndNetmask(newVlanGateway, newVlanNetmask); - final String existing_cidr = NetUtils.getCidrFromGatewayAndNetmask(vlan.getVlanGateway(), vlan.getVlanNetmask()); + final String existing_cidr = NetUtils.getCidrFromGatewayAndNetmask(vlanGateway, vlanNetmask); return NetUtils.isNetowrkASubsetOrSupersetOfNetworkB(cidrnew, existing_cidr); } @@ -2909,51 +2911,21 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati String vlanGateway = null; String vlanNetmask = null; boolean sameSubnet = false; - if (vlans != null && vlans.size() > 0) { + if (CollectionUtils.isNotEmpty(vlans)) { for (final VlanVO vlan : vlans) { - if (ipv4) { - vlanGateway = vlan.getVlanGateway(); - vlanNetmask = vlan.getVlanNetmask(); - // check if subset or super set or neither. - final NetUtils.SupersetOrSubset val = checkIfSubsetOrSuperset(newVlanGateway, newVlanNetmask, vlan, startIP, endIP); - if (val == NetUtils.SupersetOrSubset.isSuperset) { - // this means that new cidr is a superset of the - // existing subnet. - throw new InvalidParameterValueException("The subnet you are trying to add is a superset of the existing subnet having gateway" + vlan.getVlanGateway() - + " and netmask " + vlan.getVlanNetmask()); - } else if (val == NetUtils.SupersetOrSubset.neitherSubetNorSuperset) { - // this implies the user is trying to add a new subnet - // which is not a superset or subset of this subnet. - // checking with the other subnets. - continue; - } else if (val == NetUtils.SupersetOrSubset.isSubset) { - // this means he is trying to add to the same subnet. - throw new InvalidParameterValueException("The subnet you are trying to add is a subset of the existing subnet having gateway" + vlan.getVlanGateway() - + " and netmask " + vlan.getVlanNetmask()); - } else if (val == NetUtils.SupersetOrSubset.sameSubnet) { - sameSubnet = true; - //check if the gateway provided by the user is same as that of the subnet. - if (newVlanGateway != null && !newVlanGateway.equals(vlanGateway)) { - throw new InvalidParameterValueException("The gateway of the subnet should be unique. The subnet alreaddy has a gateway " + vlanGateway); - } - break; - } - } - if (ipv6) { - if (ip6Gateway != null && !ip6Gateway.equals(network.getIp6Gateway())) { - throw new InvalidParameterValueException("The input gateway " + ip6Gateway + " is not same as network gateway " + network.getIp6Gateway()); - } - if (ip6Cidr != null && !ip6Cidr.equals(network.getIp6Cidr())) { - throw new InvalidParameterValueException("The input cidr " + ip6Cidr + " is not same as network ciddr " + network.getIp6Cidr()); - } - ip6Gateway = network.getIp6Gateway(); - ip6Cidr = network.getIp6Cidr(); - _networkModel.checkIp6Parameters(startIPv6, endIPv6, ip6Gateway, ip6Cidr); - sameSubnet = true; - } + vlanGateway = vlan.getVlanGateway(); + vlanNetmask = vlan.getVlanNetmask(); + sameSubnet = hasSameSubnet(ipv4, vlanGateway, vlanNetmask, newVlanGateway, newVlanNetmask, startIP, endIP, + ipv6, ip6Gateway, ip6Cidr, startIPv6, endIPv6, network); + if (sameSubnet) break; } + } else { + vlanGateway = network.getGateway(); + vlanNetmask = NetUtils.getCidrNetmask(network.getCidr()); + sameSubnet = hasSameSubnet(ipv4, vlanGateway, vlanNetmask, newVlanGateway, newVlanNetmask, startIP, endIP, + ipv6, ip6Gateway, ip6Cidr, startIPv6, endIPv6, network); } - if (newVlanGateway == null && newVlanNetmask == null && sameSubnet == false) { + if (newVlanGateway == null && newVlanNetmask == null && !sameSubnet) { throw new InvalidParameterValueException("The ip range dose not belong to any of the existing subnets, Provide the netmask and gateway if you want to add new subnet"); } Pair vlanDetails = null; @@ -2968,8 +2940,48 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati throw new InvalidParameterValueException("The gateway ip should not be the part of the ip range being added."); } - final Pair> result = new Pair>(sameSubnet, vlanDetails); - return result; + return new Pair>(sameSubnet, vlanDetails); + } + + public boolean hasSameSubnet(boolean ipv4, String vlanGateway, String vlanNetmask, String newVlanGateway, String newVlanNetmask, String newStartIp, String newEndIp, + boolean ipv6, String newIp6Gateway, String newIp6Cidr, String newIp6StartIp, String newIp6EndIp, Network network) { + if (ipv4) { + // check if subset or super set or neither. + final NetUtils.SupersetOrSubset val = checkIfSubsetOrSuperset(vlanGateway, vlanNetmask, newVlanGateway, newVlanNetmask, newStartIp, newEndIp); + if (val == NetUtils.SupersetOrSubset.isSuperset) { + // this means that new cidr is a superset of the + // existing subnet. + throw new InvalidParameterValueException("The subnet you are trying to add is a superset of the existing subnet having gateway " + vlanGateway + + " and netmask " + vlanNetmask); + } else if (val == NetUtils.SupersetOrSubset.neitherSubetNorSuperset) { + // this implies the user is trying to add a new subnet + // which is not a superset or subset of this subnet. + } else if (val == NetUtils.SupersetOrSubset.isSubset) { + // this means he is trying to add to the same subnet. + throw new InvalidParameterValueException("The subnet you are trying to add is a subset of the existing subnet having gateway " + vlanGateway + + " and netmask " + vlanNetmask); + } else if (val == NetUtils.SupersetOrSubset.sameSubnet) { + //check if the gateway provided by the user is same as that of the subnet. + if (newVlanGateway != null && !newVlanGateway.equals(vlanGateway)) { + throw new InvalidParameterValueException("The gateway of the subnet should be unique. The subnet already has a gateway " + vlanGateway); + } + return true; + } + } + if (ipv6) { + if (newIp6Gateway != null && !newIp6Gateway.equals(network.getIp6Gateway())) { + throw new InvalidParameterValueException("The input gateway " + newIp6Gateway + " is not same as network gateway " + network.getIp6Gateway()); + } + if (newIp6Cidr != null && !newIp6Cidr.equals(network.getIp6Cidr())) { + throw new InvalidParameterValueException("The input cidr " + newIp6Cidr + " is not same as network cidr " + network.getIp6Cidr()); + } + + newIp6Gateway = MoreObjects.firstNonNull(newIp6Gateway, network.getIp6Gateway()); + newIp6Cidr = MoreObjects.firstNonNull(newIp6Cidr, network.getIp6Cidr()); + _networkModel.checkIp6Parameters(newIp6StartIp, newIp6EndIp, newIp6Gateway, newIp6Cidr); + return true; + } + return false; } @Override @@ -3021,20 +3033,32 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } + // 1) if vlan is specified for the guest network range, it should be the // same as network's vlan // 2) if vlan is missing, default it to the guest network's vlan if (network.getTrafficType() == TrafficType.Guest) { String networkVlanId = null; - final URI uri = network.getBroadcastUri(); - if (uri != null) { - final String[] vlan = uri.toString().split("vlan:\\/\\/"); - networkVlanId = vlan[1]; - // For pvlan - networkVlanId = networkVlanId.split("-")[0]; + boolean connectivityWithoutVlan = false; + if (_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Connectivity)) { + Map connectivityCapabilities = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Connectivity); + connectivityWithoutVlan = MapUtils.isNotEmpty(connectivityCapabilities) && connectivityCapabilities.containsKey(Capability.NoVlan); } - if (vlanId != null) { + final URI uri = network.getBroadcastUri(); + if (connectivityWithoutVlan) { + networkVlanId = network.getBroadcastDomainType().toUri(network.getUuid()).toString(); + } else if (uri != null) { + // Do not search for the VLAN tag when the network doesn't support VLAN + if (uri.toString().startsWith("vlan")) { + final String[] vlan = uri.toString().split("vlan:\\/\\/"); + networkVlanId = vlan[1]; + // For pvlan + networkVlanId = networkVlanId.split("-")[0]; + } + } + + if (vlanId != null && !connectivityWithoutVlan) { // if vlan is specified, throw an error if it's not equal to // network's vlanId if (networkVlanId != null && !NetUtils.isSameIsolationId(networkVlanId, vlanId)) { @@ -4068,7 +4092,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati throw new InvalidParameterValueException("Capabilities for 'Connectivity' service can be specified " + "only when Connectivity service is enabled for network offering."); } - validateConnectivityServiceCapablities(serviceProviderMap.get(Service.Connectivity), connectivityServiceCapabilityMap); + validateConnectivityServiceCapablities(guestType, serviceProviderMap.get(Service.Connectivity), connectivityServiceCapabilityMap); final Map> serviceCapabilityMap = new HashMap>(); serviceCapabilityMap.put(Service.Lb, lbServiceCapabilityMap); @@ -4210,15 +4234,18 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } } - void validateConnectivityServiceCapablities(final Set providers, final Map connectivityServiceCapabilityMap) { + void validateConnectivityServiceCapablities(final Network.GuestType guestType, final Set providers, final Map connectivityServiceCapabilityMap) { if (connectivityServiceCapabilityMap != null && !connectivityServiceCapabilityMap.isEmpty()) { for (final Map.Entryentry: connectivityServiceCapabilityMap.entrySet()) { final Capability capability = entry.getKey(); - if (capability == Capability.StretchedL2Subnet) { + if (capability == Capability.StretchedL2Subnet || capability == Capability.PublicAccess) { final String value = entry.getValue().toLowerCase(); if (!(value.contains("true") ^ value.contains("false"))) { throw new InvalidParameterValueException("Invalid value (" + value + ") for " + capability + " should be true/false"); + } else if (capability == Capability.PublicAccess && guestType != GuestType.Shared) { + throw new InvalidParameterValueException("Capability " + capability.getName() + " can only be enabled for network offerings " + + "with guest type Shared."); } } else { throw new InvalidParameterValueException("Capability " + capability.getName() + " can not be " @@ -4228,16 +4255,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // validate connectivity service provider actually supports specified capabilities if (providers != null && !providers.isEmpty()) { - for (final Provider provider: providers) { - final NetworkElement element = _networkModel.getElementImplementingProvider(provider.getName()); - final Map> capabilities = element.getCapabilities(); - if (capabilities != null && !capabilities.isEmpty()) { - final Map connectivityCapabilities = capabilities.get(Service.Connectivity); - if (connectivityCapabilities == null || connectivityCapabilities != null && !connectivityCapabilities.keySet().contains(Capability.StretchedL2Subnet)) { - throw new InvalidParameterValueException("Provider: " + provider.getName() + " does not support " - + Capability.StretchedL2Subnet.getName()); - } - } + for (Capability capability : connectivityServiceCapabilityMap.keySet()) { + _networkModel.providerSupportsCapability(providers, Service.Connectivity, capability); } } } @@ -4255,7 +4274,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati // specifyVlan should always be true for Shared network offerings if (!specifyVlan && type == GuestType.Shared) { - throw new InvalidParameterValueException("SpecifyVlan should be true if network offering's type is " + type); + Set connectivityProviders = serviceProviderMap != null ? serviceProviderMap.get(Service.Connectivity) : null; + if (CollectionUtils.isEmpty(connectivityProviders) || !_networkModel.providerSupportsCapability(connectivityProviders, Service.Connectivity, Capability.NoVlan)) { + throw new InvalidParameterValueException("SpecifyVlan should be true if network offering's type is " + type); + } } // specifyIpRanges should always be true for Shared networks @@ -4303,6 +4325,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati boolean publicLb = false; boolean internalLb = false; boolean strechedL2Subnet = false; + boolean publicAccess = false; if (serviceCapabilityMap != null && !serviceCapabilityMap.isEmpty()) { final Map lbServiceCapabilityMap = serviceCapabilityMap.get(Service.Lb); @@ -4374,9 +4397,18 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati final Map connectivityServiceCapabilityMap = serviceCapabilityMap.get(Service.Connectivity); if (connectivityServiceCapabilityMap != null && !connectivityServiceCapabilityMap.isEmpty()) { - final String value = connectivityServiceCapabilityMap.get(Capability.StretchedL2Subnet); - if ("true".equalsIgnoreCase(value)) { - strechedL2Subnet = true; + if (connectivityServiceCapabilityMap.containsKey(Capability.StretchedL2Subnet)) { + final String value = connectivityServiceCapabilityMap.get(Capability.StretchedL2Subnet); + if ("true".equalsIgnoreCase(value)) { + strechedL2Subnet = true; + } + } + + if (connectivityServiceCapabilityMap.containsKey(Capability.PublicAccess)) { + final String value = connectivityServiceCapabilityMap.get(Capability.PublicAccess); + if ("true".equalsIgnoreCase(value)) { + publicAccess = true; + } } } } @@ -4388,7 +4420,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati final NetworkOfferingVO offeringFinal = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, networkRate, multicastRate, isDefault, availability, tags, type, conserveMode, dedicatedLb, sharedSourceNat, redundantRouter, elasticIp, elasticLb, specifyIpRanges, inline, isPersistent, associatePublicIp, publicLb, - internalLb, egressDefaultPolicy, strechedL2Subnet); + internalLb, egressDefaultPolicy, strechedL2Subnet, publicAccess); if (serviceOfferingId != null) { offeringFinal.setServiceOfferingId(serviceOfferingId); diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java index f3e25e8695b..131da26a370 100644 --- a/server/src/com/cloud/network/NetworkModelImpl.java +++ b/server/src/com/cloud/network/NetworkModelImpl.java @@ -1557,6 +1557,32 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { return true; } + @Override + public boolean providerSupportsCapability(Set providers, Service service, Capability cap) { + for (Provider provider : providers) { + NetworkElement element = getElementImplementingProvider(provider.getName()); + if (element != null) { + Map> elementCapabilities = element.getCapabilities(); + if (elementCapabilities == null || !elementCapabilities.containsKey(service)) { + throw new UnsupportedServiceException("Service " + service.getName() + " is not supported by the element=" + element.getName() + + " implementing Provider=" + provider.getName()); + } + Map serviceCapabilities = elementCapabilities.get(service); + if (serviceCapabilities == null || serviceCapabilities.isEmpty()) { + throw new UnsupportedServiceException("Service " + service.getName() + " doesn't have capabilites for element=" + element.getName() + + " implementing Provider=" + provider.getName()); + } + + if (serviceCapabilities.containsKey(cap)) { + return true; + } + } else { + throw new UnsupportedServiceException("Unable to find network element for provider " + provider.getName()); + } + } + return false; + } + @Override public void checkCapabilityForProvider(Set providers, Service service, Capability cap, String capValue) { for (Provider provider : providers) { @@ -1569,7 +1595,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { } Map serviceCapabilities = elementCapabilities.get(service); if (serviceCapabilities == null || serviceCapabilities.isEmpty()) { - throw new UnsupportedServiceException("Service " + service.getName() + " doesn't have capabilites for element=" + element.getName() + + throw new UnsupportedServiceException("Service " + service.getName() + " doesn't have capabilities for element=" + element.getName() + " implementing Provider=" + provider.getName()); } diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index 13f98a2f488..0d6f6cd7eb3 100644 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -1203,7 +1203,7 @@ public class ConfigurationServerImpl extends ManagerBase implements Configuratio NetworkOfferingVO defaultNetscalerNetworkOffering = new NetworkOfferingVO(NetworkOffering.DefaultSharedEIPandELBNetworkOffering, "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, false, true, null, null, true, - Availability.Optional, null, Network.GuestType.Shared, true, false, false, false, true, true, true, false, false, true, true, false, false, false); + Availability.Optional, null, Network.GuestType.Shared, true, false, false, false, true, true, true, false, false, true, true, false, false, false, false); defaultNetscalerNetworkOffering.setState(NetworkOffering.State.Enabled); defaultNetscalerNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetscalerNetworkOffering); diff --git a/server/src/com/cloud/user/DomainManager.java b/server/src/com/cloud/user/DomainManager.java index f72b18a94ba..9bb2e01e0d3 100644 --- a/server/src/com/cloud/user/DomainManager.java +++ b/server/src/com/cloud/user/DomainManager.java @@ -49,5 +49,6 @@ public interface DomainManager extends DomainService { Domain updateDomain(UpdateDomainCmd cmd); public static final String MESSAGE_ADD_DOMAIN_EVENT = "Message.AddDomain.Event"; + public static final String MESSAGE_PRE_REMOVE_DOMAIN_EVENT = "Message.PreRemoveDomain.Event"; public static final String MESSAGE_REMOVE_DOMAIN_EVENT = "Message.RemoveDomain.Event"; } diff --git a/server/src/com/cloud/user/DomainManagerImpl.java b/server/src/com/cloud/user/DomainManagerImpl.java index 13dcd90f421..e8f0a500160 100644 --- a/server/src/com/cloud/user/DomainManagerImpl.java +++ b/server/src/com/cloud/user/DomainManagerImpl.java @@ -301,6 +301,7 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom hasDedicatedResources = true; } if (accountsForCleanup.isEmpty() && networkIds.isEmpty() && !hasDedicatedResources) { + _messageBus.publish(_name, MESSAGE_PRE_REMOVE_DOMAIN_EVENT, PublishScope.LOCAL, domain); if (!_domainDao.remove(domain.getId())) { rollBackState = true; CloudRuntimeException e = @@ -309,6 +310,7 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom e.addProxyObject(domain.getUuid(), "domainId"); throw e; } + _messageBus.publish(_name, MESSAGE_REMOVE_DOMAIN_EVENT, PublishScope.LOCAL, domain); } else { rollBackState = true; String msg = null; @@ -328,7 +330,6 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom cleanupDomainOfferings(domain.getId()); CallContext.current().putContextParameter(Domain.class, domain.getUuid()); - _messageBus.publish(_name, MESSAGE_REMOVE_DOMAIN_EVENT, PublishScope.LOCAL, domain); return true; } catch (Exception ex) { s_logger.error("Exception deleting domain with id " + domain.getId(), ex); @@ -363,8 +364,8 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom private boolean cleanupDomain(Long domainId, Long ownerId) throws ConcurrentOperationException, ResourceUnavailableException { s_logger.debug("Cleaning up domain id=" + domainId); boolean success = true; + DomainVO domainHandle = _domainDao.findById(domainId); { - DomainVO domainHandle = _domainDao.findById(domainId); domainHandle.setState(Domain.State.Inactive); _domainDao.update(domainId, domainHandle); @@ -452,7 +453,9 @@ public class DomainManagerImpl extends ManagerBase implements DomainManager, Dom } } //delete domain + _messageBus.publish(_name, MESSAGE_PRE_REMOVE_DOMAIN_EVENT, PublishScope.LOCAL, domainHandle); deleteDomainSuccess = _domainDao.remove(domainId); + _messageBus.publish(_name, MESSAGE_REMOVE_DOMAIN_EVENT, PublishScope.LOCAL, domainHandle); // Delete resource count and resource limits entries set for this domain (if there are any). _resourceCountDao.removeEntriesByOwner(domainId, ResourceOwnerType.Domain); diff --git a/server/test/com/cloud/configuration/ConfigurationManagerTest.java b/server/test/com/cloud/configuration/ConfigurationManagerTest.java index 496b5a01778..74f9ca25cc6 100644 --- a/server/test/com/cloud/configuration/ConfigurationManagerTest.java +++ b/server/test/com/cloud/configuration/ConfigurationManagerTest.java @@ -23,6 +23,8 @@ import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.lang.reflect.Field; @@ -791,4 +793,72 @@ public class ConfigurationManagerTest { configurationMgr.checkIfZoneIsDeletable(new Random().nextLong()); } + + @Test + public void hasSameSubnetTest() { + //Ipv4 Test + boolean result; + result = configurationMgr.hasSameSubnet(false, null, null, null, null, null, null, false, null, null, null, null, null); + Assert.assertFalse(result); + try { + configurationMgr.hasSameSubnet(true, "10.0.0.1", "255.255.255.0", "10.0.0.2", "255.255.255.0", "10.0.0.2", "10.0.0.10", false, null, null, null, null, null); + Assert.fail(); + } catch (InvalidParameterValueException e) { + Assert.assertEquals(e.getMessage(), "The gateway of the subnet should be unique. The subnet already has a gateway 10.0.0.1"); + } + try { + configurationMgr.hasSameSubnet(true, "10.0.0.1", "255.255.0.0", "10.0.0.2", "255.255.255.0", "10.0.0.2", "10.0.0.10", false, null, null, null, null, null); + Assert.fail(); + } catch (InvalidParameterValueException e){ + Assert.assertEquals(e.getMessage(), "The subnet you are trying to add is a subset of the existing subnet having gateway 10.0.0.1 and netmask 255.255.0.0"); + } + try { + configurationMgr.hasSameSubnet(true, "10.0.0.1", "255.255.255.0", "10.0.0.2", "255.255.0.0", "10.0.0.2", "10.0.0.10", false, null, null, null, null, null); + Assert.fail(); + } catch (InvalidParameterValueException e) { + Assert.assertEquals(e.getMessage(), "The subnet you are trying to add is a superset of the existing subnet having gateway 10.0.0.1 and netmask 255.255.255.0"); + } + result = configurationMgr.hasSameSubnet(true, "10.0.0.1", "255.255.255.0", "10.0.0.1", "255.255.255.0", "10.0.0.2", "10.0.0.10", false, null, null, null, null, null); + Assert.assertTrue(result); + + //Ipv6 Test + Network ipV6Network = mock(Network.class); + when(ipV6Network.getIp6Gateway()).thenReturn("2001:db8:0:f101::1"); + when(ipV6Network.getIp6Cidr()).thenReturn("2001:db8:0:f101::0/64"); + doThrow(new InvalidParameterValueException("Exception from Mock: startIPv6 is not in ip6cidr indicated network!")).when(configurationMgr._networkModel).checkIp6Parameters("2001:db9:0:f101::2", "2001:db9:0:f101::a", "2001:db8:0:f101::1", "2001:db8:0:f101::0/64"); + doThrow(new InvalidParameterValueException("Exception from Mock: endIPv6 is not in ip6cidr indicated network!")).when(configurationMgr._networkModel).checkIp6Parameters("2001:db8:0:f101::a", "2001:db9:0:f101::2", "2001:db8:0:f101::1", "2001:db8:0:f101::0/64"); + doThrow(new InvalidParameterValueException("ip6Gateway and ip6Cidr should be defined when startIPv6/endIPv6 are passed in")).when(configurationMgr._networkModel).checkIp6Parameters(Mockito.anyString(), Mockito.anyString(), Mockito.isNull(String.class), Mockito.isNull(String.class)); + + + configurationMgr.hasSameSubnet(false, null, null, null, null, null, null, true, "2001:db8:0:f101::1", "2001:db8:0:f101::0/64", "2001:db8:0:f101::2", "2001:db8:0:f101::a", ipV6Network); + Assert.assertTrue(result); + try { + configurationMgr.hasSameSubnet(false, null, null, null, null, null, null, true, "2001:db8:0:f101::2", "2001:db8:0:f101::0/64", "2001:db8:0:f101::2", "2001:db8:0:f101::a", ipV6Network); + Assert.fail(); + } catch (InvalidParameterValueException e){ + Assert.assertEquals(e.getMessage(), "The input gateway 2001:db8:0:f101::2 is not same as network gateway 2001:db8:0:f101::1"); + } + try { + configurationMgr.hasSameSubnet(false, null, null, null, null, null, null, true, "2001:db8:0:f101::1", "2001:db8:0:f101::0/63", "2001:db8:0:f101::2", "2001:db8:0:f101::a", ipV6Network); + Assert.fail(); + } catch (InvalidParameterValueException e){ + Assert.assertEquals(e.getMessage(), "The input cidr 2001:db8:0:f101::0/63 is not same as network cidr 2001:db8:0:f101::0/64"); + } + + try { + configurationMgr.hasSameSubnet(false, null, null, null, null, null, null, true, "2001:db8:0:f101::1", "2001:db8:0:f101::0/64", "2001:db9:0:f101::2", "2001:db9:0:f101::a", ipV6Network); + Assert.fail(); + } catch (InvalidParameterValueException e) { + Assert.assertEquals(e.getMessage(), "Exception from Mock: startIPv6 is not in ip6cidr indicated network!"); + } + try { + configurationMgr.hasSameSubnet(false, null, null, null, null, null, null, true, "2001:db8:0:f101::1", "2001:db8:0:f101::0/64", "2001:db8:0:f101::a", "2001:db9:0:f101::2", ipV6Network); + Assert.fail(); + } catch(InvalidParameterValueException e){ + Assert.assertEquals(e.getMessage(), "Exception from Mock: endIPv6 is not in ip6cidr indicated network!"); + } + + result = configurationMgr.hasSameSubnet(false, null, null, null, null, null, null, true, null, null, "2001:db8:0:f101::2", "2001:db8:0:f101::a", ipV6Network); + Assert.assertTrue(result); + } } diff --git a/server/test/com/cloud/network/CreatePrivateNetworkTest.java b/server/test/com/cloud/network/CreatePrivateNetworkTest.java index 2e6cfa14369..8a7b54cb20f 100644 --- a/server/test/com/cloud/network/CreatePrivateNetworkTest.java +++ b/server/test/com/cloud/network/CreatePrivateNetworkTest.java @@ -103,7 +103,7 @@ public class CreatePrivateNetworkTest { NetworkOfferingVO ntwkOff = new NetworkOfferingVO("offer", "fakeOffer", TrafficType.Guest, true, true, null, null, false, null, null, GuestType.Isolated, false, false, false, false, - false, false, false, false, false, false, false, false, false, false); + false, false, false, false, false, false, false, false, false, false, false); when(networkService._networkOfferingDao.findById(anyLong())).thenReturn(ntwkOff); List netofferlist = new ArrayList(); netofferlist.add(ntwkOff); diff --git a/server/test/com/cloud/network/MockNetworkModelImpl.java b/server/test/com/cloud/network/MockNetworkModelImpl.java index c00d83f7265..f3d1f3827bd 100644 --- a/server/test/com/cloud/network/MockNetworkModelImpl.java +++ b/server/test/com/cloud/network/MockNetworkModelImpl.java @@ -491,6 +491,11 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { return false; } + @Override + public boolean providerSupportsCapability(Set providers, Service service, Capability cap) { + return false; + } + /* (non-Javadoc) * @see com.cloud.network.NetworkModel#checkCapabilityForProvider(java.util.Set, com.cloud.network.Network.Service, com.cloud.network.Network.Capability, java.lang.String) */ diff --git a/server/test/com/cloud/network/NetworkModelTest.java b/server/test/com/cloud/network/NetworkModelTest.java index 55f620b6513..ba575420ed8 100644 --- a/server/test/com/cloud/network/NetworkModelTest.java +++ b/server/test/com/cloud/network/NetworkModelTest.java @@ -19,11 +19,17 @@ package com.cloud.network; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyLong; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.mockito.Mockito.spy; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; import junit.framework.Assert; @@ -32,13 +38,16 @@ import org.junit.Test; import com.cloud.dc.VlanVO; import com.cloud.dc.dao.VlanDao; +import com.cloud.exception.UnsupportedServiceException; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.IPAddressVO; +import com.cloud.network.element.NetworkElement; import com.cloud.user.Account; import com.cloud.utils.db.Filter; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; import com.cloud.utils.net.Ip; +import com.cloud.network.Network.Provider; public class NetworkModelTest { @Before @@ -77,4 +86,53 @@ public class NetworkModelTest { } + @Test + public void testCapabilityForProvider() { + NetworkModelImpl modelImpl = spy(NetworkModelImpl.class); + Set providers = new HashSet<>(); + providers.add(Provider.NuageVsp); + NetworkElement nuageVspElement = mock(NetworkElement.class); + HashMap> nuageVspCap = new HashMap>(); + HashMap nuageVspConnectivity = new HashMap(); + nuageVspConnectivity.put(Network.Capability.NoVlan, "FindMe"); + nuageVspConnectivity.put(Network.Capability.PublicAccess, ""); + + nuageVspCap.put(Network.Service.Connectivity, nuageVspConnectivity); + when(nuageVspElement.getName()).thenReturn("NuageVsp"); + doReturn(nuageVspCap).when(nuageVspElement).getCapabilities(); + doReturn(nuageVspElement).when(modelImpl).getElementImplementingProvider("NuageVsp"); + + try { + modelImpl.checkCapabilityForProvider(providers, Network.Service.UserData, null, null); + Assert.fail(); + } catch (UnsupportedServiceException e) { + Assert.assertEquals(e.getMessage(), "Service " + Network.Service.UserData.getName() + " is not supported by the element=NuageVsp implementing Provider=" + Provider.NuageVsp.getName()); + } + + try { + modelImpl.checkCapabilityForProvider(providers, Network.Service.Connectivity, Network.Capability.ElasticIp, null); + Assert.fail(); + } catch (UnsupportedServiceException e) { + Assert.assertEquals(e.getMessage(), "Service " + Network.Service.Connectivity.getName() + " doesn't have capability " + Network.Capability.ElasticIp.getName() + " for element=NuageVsp implementing Provider=" + Provider.NuageVsp.getName()); + } + try { + modelImpl.checkCapabilityForProvider(providers, Network.Service.Connectivity, Network.Capability.PublicAccess, "NonExistingVal"); + Assert.fail(); + } catch (UnsupportedServiceException e){ + Assert.assertEquals(e.getMessage(),"Service Connectivity doesn't have capability PublicAccess for element=NuageVsp implementing Provider=NuageVsp"); + } + + modelImpl.checkCapabilityForProvider(providers, Network.Service.Connectivity, Network.Capability.NoVlan, "FindMe"); + + NetworkElement nuageVspElement2 = mock(NetworkElement.class); + doReturn(null).when(nuageVspElement).getCapabilities(); + try { + modelImpl.checkCapabilityForProvider(providers, Network.Service.Connectivity, Network.Capability.PublicAccess, ""); + Assert.fail(); + } catch (UnsupportedServiceException e) { + Assert.assertEquals(e.getMessage(), "Service Connectivity is not supported by the element=NuageVsp implementing Provider=NuageVsp"); + } + } + + } diff --git a/server/test/com/cloud/vpc/MockNetworkModelImpl.java b/server/test/com/cloud/vpc/MockNetworkModelImpl.java index 93b31e95f9c..89a7ab7068b 100644 --- a/server/test/com/cloud/vpc/MockNetworkModelImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkModelImpl.java @@ -508,9 +508,14 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { return false; } + @Override + public boolean providerSupportsCapability(Set providers, Service service, Capability cap) { + return false; + } + /* (non-Javadoc) - * @see com.cloud.network.NetworkModel#checkCapabilityForProvider(java.util.Set, com.cloud.network.Network.Service, com.cloud.network.Network.Capability, java.lang.String) - */ + * @see com.cloud.network.NetworkModel#checkCapabilityForProvider(java.util.Set, com.cloud.network.Network.Service, com.cloud.network.Network.Capability, java.lang.String) + */ @Override public void checkCapabilityForProvider(Set providers, Service service, Capability cap, String capValue) { // TODO Auto-generated method stub diff --git a/setup/db/db/schema-4910to41000.sql b/setup/db/db/schema-4910to41000.sql index 127d7f84f82..beabe963af2 100644 --- a/setup/db/db/schema-4910to41000.sql +++ b/setup/db/db/schema-4910to41000.sql @@ -45,4 +45,6 @@ CREATE TABLE `cloud`.`vlan_details` ( `display` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Should detail be displayed to the end user', PRIMARY KEY (`id`), CONSTRAINT `fk_vlan_details__vlan_id` FOREIGN KEY `fk_vlan_details__vlan_id`(`vlan_id`) REFERENCES `vlan`(`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8; \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `cloud`.`network_offerings` ADD COLUMN supports_public_access boolean default false; diff --git a/test/integration/plugins/nuagevsp/nuageTestCase.py b/test/integration/plugins/nuagevsp/nuageTestCase.py index 530dcedca5a..1a11fd68312 100644 --- a/test/integration/plugins/nuagevsp/nuageTestCase.py +++ b/test/integration/plugins/nuagevsp/nuageTestCase.py @@ -19,7 +19,8 @@ """ # Import Local Modules from marvin.cloudstackTestCase import cloudstackTestCase, unittest -from marvin.lib.base import (EgressFireWallRule, +from marvin.lib.base import (Domain, + EgressFireWallRule, FireWallRule, Host, Hypervisor, @@ -36,7 +37,8 @@ from marvin.lib.base import (EgressFireWallRule, StaticNATRule, VirtualMachine, VPC, - VpcOffering) + VpcOffering, + Zone) from marvin.lib.common import (get_domain, get_template, get_zone) @@ -84,11 +86,18 @@ class nuageTestCase(cloudstackTestCase): # We want to fail quicker, if it's a failure socket.setdefaulttimeout(60) + # Get test client and test data cls.test_client = super(nuageTestCase, cls).getClsTestClient() cls.api_client = cls.test_client.getApiClient() cls.db_client = cls.test_client.getDbConnection() cls.test_data = cls.test_client.getParsedTestDataConfig() + # Get Zones and Domains + cls.zones = Zone.list(cls.api_client) + cls.domains = Domain.list(cls.api_client, listall=True) + cls.domain = get_domain(cls.api_client) + cls.root_domain = get_domain(cls.api_client, domain_name="ROOT") + # Get Zone details cls.getZoneDetails() @@ -106,12 +115,11 @@ class nuageTestCase(cloudstackTestCase): @classmethod def getZoneDetails(cls, zone=None): - # Get Zone, Domain and templates + # Get Zone details cls.zone = zone if zone else get_zone( cls.api_client, zone_name=cls.test_client.getZoneForTests() ) - cls.domain = get_domain(cls.api_client) cls.template = get_template(cls.api_client, cls.zone.id, cls.test_data["ostype"] @@ -160,34 +168,33 @@ class nuageTestCase(cloudstackTestCase): # Get data center Internet connectivity information from the Marvin # config file, which is required to perform Internet connectivity and # traffic tests from the guest VMs. - cls.isInternetConnectivityAvailable = False - cls.http_proxy = None - cls.https_proxy = None - dc_internet_conn_info = cls.config.dcInternetConnectivityInfo if \ - cls.config.dcInternetConnectivityInfo else None - if dc_internet_conn_info: - dc_internet_conn_available = dc_internet_conn_info.available if \ - dc_internet_conn_info.available else None - if dc_internet_conn_available: - cls.isInternetConnectivityAvailable = True if \ - dc_internet_conn_available == "true" else False - dc_internet_conn_http_proxy = dc_internet_conn_info.httpProxy if \ - dc_internet_conn_info.httpProxy else None - if dc_internet_conn_http_proxy: - cls.http_proxy = dc_internet_conn_http_proxy - dc_internet_conn_https_proxy = dc_internet_conn_info.httpsProxy \ - if dc_internet_conn_info.httpsProxy else None - if dc_internet_conn_https_proxy: - cls.https_proxy = dc_internet_conn_https_proxy + cls.dcInternetConnectivityInfo() # Check if the configured Nuage VSP SDN platform infrastructure # supports underlay networking cmd = listNuageUnderlayVlanIpRanges.listNuageUnderlayVlanIpRangesCmd() + cmd.zoneid = cls.zone.id cmd.underlay = True cls.isNuageInfraUnderlay = isinstance( cls.api_client.listNuageUnderlayVlanIpRanges(cmd), list) return + @classmethod + def dcInternetConnectivityInfo(cls): + cls.isInternetConnectivityAvailable = False + cls.http_proxy = None + cls.https_proxy = None + zone = next(zone for zone in cls.config.zones + if zone.name == cls.zone.name) + if zone.dcInternetConnectivityInfo.available: + cls.isInternetConnectivityAvailable = \ + zone.dcInternetConnectivityInfo.available == "true" + if cls.isInternetConnectivityAvailable: + if zone.dcInternetConnectivityInfo.httpProxy: + cls.http_proxy = zone.dcInternetConnectivityInfo.httpProxy + if zone.dcInternetConnectivityInfo.httpsProxy: + cls.https_proxy = zone.dcInternetConnectivityInfo.httpsProxy + @classmethod def configureVSDSessions(cls): # VSD is a programmable policy and analytics engine of Nuage VSP SDN @@ -906,6 +913,66 @@ class nuageTestCase(cloudstackTestCase): self.debug("Successfully verified the creation and state of Network " "- %s in VSD" % network.name) + # get_subnet_id - Calculates and returns the subnet ID in VSD with the + # given CloudStack network ID and subnet gateway + def get_subnet_id(self, network_id, gateway): + try: + import uuid + + class NULL_NAMESPACE: + bytes = b'' + # The UUID of the shared network in ACS + # The gateway IP of the address range + network_id = str(network_id) + bytes = bytearray(network_id) + ipbytes = bytearray(gateway) + subnet_id = uuid.uuid3(NULL_NAMESPACE, bytes + ipbytes) + self.debug("The required subnet id is %s in VSD" % subnet_id) + return str(subnet_id) + except Exception as e: + self.debug("Failed to get the subnet id due to %s" % e) + self.fail("Unable to get the subnet id, failing the test case") + + # verify_vsd_shared_network - Verifies the given CloudStack domain and + # shared network against the corresponding installed enterprise, domain, + # zone, subnet, and shared network resource in VSD + def verify_vsd_shared_network(self, domain_id, network, + gateway="10.1.1.1"): + self.debug("Verifying the creation and state of Shared Network - %s " + "in VSD" % network.name) + vsd_enterprise = self.vsd.get_enterprise( + filter=self.get_externalID_filter(domain_id)) + ext_network_id_filter = self.get_externalID_filter(network.id) + vsd_domain = self.vsd.get_domain(filter=ext_network_id_filter) + vsd_zone = self.vsd.get_zone(filter=ext_network_id_filter) + subnet_id = self.get_subnet_id(network.id, gateway) + vsd_subnet = self.vsd.get_subnet( + filter=self.get_externalID_filter(subnet_id)) + self.assertNotEqual(vsd_enterprise, None, + "VSD enterprise (CloudStack domain) data format " + "should not be of type None" + ) + self.assertEqual(vsd_domain.description, network.name, + "VSD domain description should match network name in " + "CloudStack" + ) + self.assertEqual(vsd_zone.description, network.name, + "VSD zone description should match network name in " + "CloudStack" + ) + self.assertEqual(vsd_subnet.description, network.name, + "VSD subnet description '%s' should match network " + "name in CloudStack" % vsd_subnet.description + ) + shared_resource = self.vsd.get_shared_network_resource( + filter=self.get_externalID_filter(subnet_id)) + self.assertEqual(shared_resource.description, network.name, + "VSD shared resources description should match " + "network name in CloudStack" + ) + self.debug("Successfully verified the creation and state of Shared " + "Network - %s in VSD" % network.name) + # verify_vsd_object_status - Verifies the given CloudStack object status in # VSD def verify_vsd_object_status(self, cs_object, stopped): @@ -914,7 +981,7 @@ class nuageTestCase(cloudstackTestCase): expected_status = cs_object.state.upper() if not stopped \ else "DELETE_PENDING" tries = 0 - while (vsd_object.status != expected_status) and (tries < 3): + while (vsd_object.status != expected_status) and (tries < 10): self.debug("Waiting for the CloudStack object " + cs_object.name + " to be fully resolved in VSD...") time.sleep(30) @@ -957,6 +1024,82 @@ class nuageTestCase(cloudstackTestCase): self.debug("Successfully verified the deployment and state of VM - %s " "in VSD" % vm.name) + # verify_vsd_enterprise_vm - Verifies the given CloudStack domain VM + # deployment and status in the corresponding VSD enterprise + def verify_vsd_enterprise_vm(self, domain_id, network, vm, vpc=None, + stopped=False, sharedsubnetid=None): + self.debug("Verifying the creation and state of Network - %s in VSD" % + network.name) + vsd_enterprise = self.vsd.get_enterprise( + filter=self.get_externalID_filter(domain_id)) + ext_network_id_filter = self.get_externalID_filter(vpc.id) if vpc \ + else self.get_externalID_filter(network.id) + vsd_domain = self.vsd.get_domain( + enterprise=vsd_enterprise, filter=ext_network_id_filter) + vsd_zone = self.vsd.get_zone( + domain=vsd_domain, filter=ext_network_id_filter) + if sharedsubnetid: + vsd_subnet = self.vsd.get_subnet( + zone=vsd_zone, + filter=self.get_externalID_filter(sharedsubnetid)) + else: + vsd_subnet = self.vsd.get_subnet( + zone=vsd_zone, filter=self.get_externalID_filter(network.id)) + self.assertNotEqual(vsd_enterprise, None, + "VSD enterprise (CloudStack domain) data format " + "should not be of type None" + ) + if vpc: + self.assertEqual(vsd_domain.description, "VPC_" + vpc.name, + "VSD domain description should match VPC name in " + "CloudStack" + ) + self.assertEqual(vsd_zone.description, "VPC_" + vpc.name, + "VSD zone description should match VPC name in " + "CloudStack" + ) + else: + self.assertEqual(vsd_domain.description, network.name, + "VSD domain description should match network " + "name in CloudStack" + ) + self.assertEqual(vsd_zone.description, network.name, + "VSD zone description should match network name " + "in CloudStack" + ) + self.assertEqual(vsd_subnet.description, network.name, + "VSD subnet description '%s' should match network " + "name in CloudStack" % vsd_subnet.description + ) + self.debug("Successfully verified the creation and state of Network - " + "%s in VSD" % network.name) + self.debug("Verifying the deployment and state of VM - %s in VSD" % + vm.name) + vsd_vm = self.vsd.get_vm( + subnet=vsd_subnet, filter=self.get_externalID_filter(vm.id)) + self.assertNotEqual(vsd_vm, None, + "VM data format in VSD should not be of type None" + ) + vm_info = VirtualMachine.list(self.api_client, id=vm.id)[0] + for nic in vm_info.nic: + if nic.networkid == network.id: + vsd_vport = self.vsd.get_vport( + subnet=vsd_subnet, + filter=self.get_externalID_filter(nic.id)) + vsd_vm_interface = self.vsd.get_vm_interface( + filter=self.get_externalID_filter(nic.id)) + self.assertEqual(vsd_vport.active, True, + "VSD VM vport should be active" + ) + self.assertEqual(vsd_vm_interface.ip_address, nic.ipaddress, + "VSD VM interface IP address should match " + "VM's NIC IP address in CloudStack" + ) + if not self.isSimulator: + self.verify_vsd_object_status(vm, stopped) + self.debug("Successfully verified the deployment and state of VM - %s " + "in VSD" % vm.name) + # verify_vsd_router - Verifies the given CloudStack network router # deployment and status in VSD def verify_vsd_router(self, router, stopped=False): diff --git a/test/integration/plugins/nuagevsp/test_nuage_non_public_sharednetwork_ip_range.py b/test/integration/plugins/nuagevsp/test_nuage_non_public_sharednetwork_ip_range.py new file mode 100644 index 00000000000..a3d550a4e9a --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_non_public_sharednetwork_ip_range.py @@ -0,0 +1,654 @@ +# 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 Shared Network functionality with Nuage VSP SDN plugin: +Non Public Shared Network IP Range +""" +# Import Local Modules +from nuageTestCase import nuageTestCase +from marvin.lib.utils import cleanup_resources +from marvin.lib.base import Account, Domain, User, Network, NetworkOffering +from marvin.lib.common import list_virtual_machines +from marvin.cloudstackAPI import (createVlanIpRange, + listVlanIpRanges, + deleteVlanIpRange, + updateVmNicIp) +# Import System Modules +from nose.plugins.attrib import attr + + +class TestNuageSharedNetworkNonPublicIPRange(nuageTestCase): + """Test Shared Network functionality with Nuage VSP SDN plugin: + Non Public Shared Network IP Range + """ + + @classmethod + def setUpClass(cls): + """ + Create the following domain tree and accounts that are required for + executing Nuage VSP SDN plugin test cases for shared networks: + Under ROOT - create domain D1 + Under domain D1 - Create two subdomains D11 and D12 + Under each of the domains - create one admin user and couple of + regular users. + Create shared network with the following scope: + 1. Network with scope="all" + 2. Network with scope="domain" with no subdomain access + 3. Network with scope="domain" with subdomain access + 4. Network with scope="account" + """ + + super(TestNuageSharedNetworkNonPublicIPRange, cls).setUpClass() + cls.sharednetworkdata = cls.test_data["acl"] + cls.nuagenetworkdata = cls.test_data["nuagevsp"] + + cls.domain_1 = None + cls.domain_2 = None + + try: + # backup default apikey and secretkey + cls.default_apikey = cls.api_client.connection.apiKey + cls.default_secretkey = cls.api_client.connection.securityKey + + # Create domains + cls.domain_1 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain1"] + ) + cls.domain_11 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain11"], + parentdomainid=cls.domain_1.id + ) + cls.domain_12 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain12"], + parentdomainid=cls.domain_1.id + ) + # Create 1 admin account and 2 user accounts for domain_1 + cls.account_d1 = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1"], + admin=True, + domainid=cls.domain_1.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d1) + cls.user_d1_apikey = user.apikey + cls.user_d1_secretkey = user.secretkey + + cls.account_d1a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1A"], + admin=False, + domainid=cls.domain_1.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d1a) + cls.user_d1a_apikey = user.apikey + cls.user_d1a_secretkey = user.secretkey + + cls.account_d1b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1B"], + admin=False, + domainid=cls.domain_1.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d1b) + cls.user_d1b_apikey = user.apikey + cls.user_d1b_secretkey = user.secretkey + + # Create 1 admin and 2 user accounts for doamin_11 + cls.account_d11 = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11"], + admin=True, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11) + cls.user_d11_apikey = user.apikey + cls.user_d11_secretkey = user.secretkey + + cls.account_d11a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11A"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11a) + cls.user_d11a_apikey = user.apikey + cls.user_d11a_secretkey = user.secretkey + + cls.account_d11b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11B"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11b) + cls.user_d11b_apikey = user.apikey + cls.user_d11b_secretkey = user.secretkey + + # Create 2 user accounts for doamin_12 + cls.account_d12a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD12A"], + admin=False, + domainid=cls.domain_12.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d12a) + cls.user_d12a_apikey = user.apikey + cls.user_d12a_secretkey = user.secretkey + + cls.account_d12b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD12B"], + admin=False, + domainid=cls.domain_12.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d12b) + cls.user_d12b_apikey = user.apikey + cls.user_d12b_secretkey = user.secretkey + + # Create 1 user account and admin account in "ROOT" domain + + cls.account_roota = Account.create( + cls.api_client, + cls.sharednetworkdata["accountROOTA"], + admin=False, + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_roota) + cls.user_roota_apikey = user.apikey + cls.user_roota_secretkey = user.secretkey + + cls.account_root = Account.create( + cls.api_client, + cls.sharednetworkdata["accountROOTA"], + admin=True, + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_root) + cls.user_root_apikey = user.apikey + cls.user_root_secretkey = user.secretkey + + # service offering is already created in Nuagetestcase + cls.sharednetworkdata['mode'] = cls.zone.networktype + + # As admin user, create shared network with scope "all", "domain" + # with subdomain access, "domain" without subdomain access and + # "account" + + cls.api_client.connection.apiKey = cls.default_apikey + cls.api_client.connection.securityKey = cls.default_secretkey + + cls.shared_network_offering = NetworkOffering.create( + cls.api_client, + cls.nuagenetworkdata["shared_nuage_network_offering"], + conservemode=False + ) + # Enable Network offering + cls.shared_network_offering.update(cls.api_client, state='Enabled') + cls.shared_network_offering_id = cls.shared_network_offering.id + + cls.shared_network_all = Network.create( + cls.api_client, + cls.nuagenetworkdata["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id + ) + + cls.shared_network_domain_d11 = Network.create( + cls.api_client, + cls.nuagenetworkdata["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + subdomainaccess=False + ) + + cls.shared_network_domain_with_subdomain_d11 = Network.create( + cls.api_client, + cls.nuagenetworkdata["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + subdomainaccess=True + ) + + cls.shared_network_account_d111a = Network.create( + cls.api_client, + cls.nuagenetworkdata["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + accountid=cls.account_d11a.user[0].username + ) + + cls._cleanup = [ + cls.account_root, + cls.account_roota, + cls.shared_network_all, + cls.shared_network_offering, + cls.service_offering, + ] + except Exception as e: + cls.domain_1.delete(cls.api_client, cleanup="true") + cleanup_resources(cls.api_client, cls._cleanup) + raise Exception("Failed to create the setup required to execute " + "the test cases: %s" % e) + + return + + @classmethod + def tearDownClass(cls): + cls.api_client.connection.apiKey = cls.default_apikey + cls.api_client.connection.securityKey = cls.default_secretkey + cls.domain_1.delete(cls.api_client, cleanup="true") + cleanup_resources(cls.api_client, cls._cleanup) + return + + def setUp(self): + self.api_client = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + + def tearDown(self): + # restore back default apikey and secretkey + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + return + + def add_subnet_verify(self, network, services): + """verify required nic is present in the VM""" + + self.debug("Going to add new ip range in shared network %s" % + network.name) + cmd = createVlanIpRange.createVlanIpRangeCmd() + cmd.networkid = network.id + cmd.gateway = services["gateway"] + cmd.netmask = services["netmask"] + cmd.startip = services["startip"] + cmd.endip = services["endip"] + cmd.forVirtualNetwork = services["forvirtualnetwork"] + addedsubnet = self.api_client.createVlanIpRange(cmd) + + self.debug("verify above iprange is successfully added in shared " + "network %s or not" % network.name) + + cmd1 = listVlanIpRanges.listVlanIpRangesCmd() + cmd1.networkid = network.id + cmd1.id = addedsubnet.vlan.id + + allsubnets = self.api_client.listVlanIpRanges(cmd1) + self.assertEqual( + allsubnets[0].id, + addedsubnet.vlan.id, + "Check New subnet is successfully added to the shared Network" + ) + return addedsubnet + + def delete_subnet_verify(self, network, subnet): + """verify required nic is present in the VM""" + + self.debug("Going to delete ip range in shared network %s" % + network.name) + cmd = deleteVlanIpRange.deleteVlanIpRangeCmd() + cmd.id = subnet.vlan.id + self.api_client.deleteVlanIpRange(cmd) + + self.debug("verify above iprange is successfully deleted from shared " + "network %s or not" % network.name) + + cmd1 = listVlanIpRanges.listVlanIpRangesCmd() + cmd1.networkid = network.id + cmd1.id = subnet.vlan.id + + try: + allsubnets = self.api_client.listVlanIpRanges(cmd1) + self.assertEqual( + allsubnets[0].id, + subnet.vlan.id, + "Check Subnet is not present to the shared Network" + ) + self.fail("iprange is not successfully deleted from shared " + "network %s" % network.name) + except Exception as e: + self.debug("iprange is not successfully deleted from shared " + "network %s" % network.name) + self.debug("exception msg is %s" % e) + + def shared_subnet_not_present(self, network, subnetid): + shared_resources = self.vsd.get_shared_network_resource( + filter=self.get_externalID_filter(subnetid)) + try: + self.assertEqual(shared_resources.description, network.name, + "VSD shared resources description should match " + "network name in CloudStack" + ) + self.fail("still shared resource are present on VSD") + except Exception as e: + self.debug("sharedNetwork resources is successfully deleted from " + "VSD") + self.debug("exception msg is %s" % e) + + # Test cases relating to add/delete Shared Network IP ranges + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_01_add_delete_Subnet_in_sharednetwork_scope_all(self): + """Validate that subnet of same and different public gateway can be + added to shared network with scope=all + """ + + # Add subnet with same cidr + self.debug("Adding subnet of same cidr to shared Network scope as all") + subnet1 = self.add_subnet_verify( + self.shared_network_all, self.nuagenetworkdata["publiciprange1"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange1"]["startip"] + vm_1 = self.create_VM( + self.shared_network_all, account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_all, + gateway=self.nuagenetworkdata["publiciprange1"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["publiciprange1"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_all, vm_1, + sharedsubnetid=subnet_id) + + # Add subnet with different cidr + self.debug("Adding subnet of different cidr to shared Network scope " + "as all") + subnet2 = self.add_subnet_verify( + self.shared_network_all, self.nuagenetworkdata["publiciprange2"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange2"]["startip"] + vm_2 = self.create_VM( + self.shared_network_all, account=self.account_d11a) + + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_all, + gateway=self.nuagenetworkdata["publiciprange2"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["publiciprange2"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_all, vm_2, + sharedsubnetid=subnet_id) + # put ping here + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_subnet_verify(self.shared_network_all, subnet1) + self.delete_subnet_verify(self.shared_network_all, subnet2) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_02_add_delete_Subnet_in_sharednetwork_scope_domain(self): + """Validate subnet of same and different gateway can be added to public + shared network scope=domain with subdomain access + """ + + # Add subnet with same cidr + self.debug("Adding subnet of same cidr to shared Network scope domain " + "with subdomain access") + subnet1 = self.add_subnet_verify( + self.shared_network_domain_with_subdomain_d11, + self.nuagenetworkdata["publiciprange1"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange1"]["startip"] + vm_1 = self.create_VM( + self.shared_network_domain_with_subdomain_d11, + account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata["publiciprange1"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata["publiciprange1"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, vm_1, + sharedsubnetid=subnet_id) + + # Add subnet with different cidr + self.debug("Adding subnet of different cidr to shared Network") + subnet2 = self.add_subnet_verify( + self.shared_network_domain_with_subdomain_d11, + self.nuagenetworkdata["publiciprange2"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange2"]["startip"] + vm_2 = self.create_VM( + self.shared_network_domain_with_subdomain_d11, + account=self.account_d11a) + + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata["publiciprange2"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata["publiciprange2"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, vm_2, + sharedsubnetid=subnet_id) + # put ping here + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_subnet_verify( + self.shared_network_domain_with_subdomain_d11, subnet1) + self.delete_subnet_verify( + self.shared_network_domain_with_subdomain_d11, subnet2) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_03_add_delete_Subnet_in_sharednetwork_scope_nosubdomain(self): + """Validate subnet of same and different gateway can added to public + shared network scope=domain without subdomain access + """ + + # Add subnet with same cidr + self.debug("Adding subnet of same cidr to shared Network scope domain " + "without subdomain access") + subnet1 = self.add_subnet_verify( + self.shared_network_domain_d11, + self.nuagenetworkdata["publiciprange1"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange1"]["startip"] + vm_1 = self.create_VM( + self.shared_network_domain_d11, account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_domain_d11, + gateway=self.nuagenetworkdata["publiciprange1"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata["publiciprange1"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_domain_d11, vm_1, + sharedsubnetid=subnet_id) + + # Add subnet with different cidr + self.debug("Adding subnet of different cidr to shared Network") + subnet2 = self.add_subnet_verify( + self.shared_network_domain_d11, + self.nuagenetworkdata["publiciprange2"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange2"]["startip"] + vm_2 = self.create_VM( + self.shared_network_domain_d11, account=self.account_d11a) + + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_domain_d11, + gateway=self.nuagenetworkdata["publiciprange2"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata["publiciprange2"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_domain_d11, vm_2, + sharedsubnetid=subnet_id) + # put ping here + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_subnet_verify(self.shared_network_domain_d11, subnet1) + self.delete_subnet_verify(self.shared_network_domain_d11, subnet2) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_04_add_delete_Subnet_in_sharednetwork_scope_account(self): + """Validate subnet of same and different gateway can be added to shared + network scope=Account + """ + + # Add subnet with same cidr + self.debug("Adding subnet of same cidr to shared Network scope as " + "Account") + subnet1 = self.add_subnet_verify( + self.shared_network_account_d111a, + self.nuagenetworkdata["publiciprange1"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange1"]["startip"] + vm_1 = self.create_VM( + self.shared_network_account_d111a, account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_account_d111a, + gateway=self.nuagenetworkdata["publiciprange1"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_account_d111a.id, + self.nuagenetworkdata["publiciprange1"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_account_d111a, + vm_1, sharedsubnetid=subnet_id) + + # Add subnet with different cidr + self.debug("Adding subnet of different cidr to shared Network") + subnet2 = self.add_subnet_verify( + self.shared_network_account_d111a, + self.nuagenetworkdata["publiciprange2"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange2"]["startip"] + vm_2 = self.create_VM( + self.shared_network_account_d111a, account=self.account_d11a) + + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_account_d111a, + gateway=self.nuagenetworkdata["publiciprange2"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_account_d111a.id, + self.nuagenetworkdata["publiciprange2"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_account_d111a, + vm_2, sharedsubnetid=subnet_id) + # put ping here + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_subnet_verify(self.shared_network_account_d111a, subnet1) + self.delete_subnet_verify(self.shared_network_account_d111a, subnet2) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_05_change_ip_from_different_Subnet_in_sharednetwork(self): + """Validate that ip of a vm can be changed to a different subnet ip for + shared_network_scope_all + """ + + # Add subnet with same cidr + self.debug("Adding subnet of same cidr to shared Network scope as all") + subnet1 = self.add_subnet_verify( + self.shared_network_all, self.nuagenetworkdata["publiciprange1"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange1"]["startip"] + vm_1 = self.create_VM( + self.shared_network_all, account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_all, + gateway=self.nuagenetworkdata["publiciprange1"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["publiciprange1"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_all, vm_1, + sharedsubnetid=subnet_id) + + # Add subnet with different cidr + self.debug("Adding subnet of different cidr to shared Network scope " + "as all") + subnet2 = self.add_subnet_verify( + self.shared_network_all, self.nuagenetworkdata["publiciprange2"]) + + # stop VM to update the ipaddress + try: + vm_1.stop(self.api_client) + except Exception as e: + self.fail("Failed to stop the virtual instances, %s" % e) + vm_list = list_virtual_machines(self.api_client, id=vm_1.id) + nics = [x for x in vm_list[0].nic + if x.networkid == self.shared_network_all.id] + self.debug("Filtered nics list: %s:" % nics) + + cmd = updateVmNicIp.updateVmNicIpCmd() + for x in vm_list[0].nic: + cmd.nicid = x.id + cmd.ipaddress = self.nuagenetworkdata["publiciprange2"]["startip"] + self.api_client.updateVmNicIp(cmd) + + try: + vm_1.start(self.api_client) + except Exception as e: + self.fail("Failed to start the virtual instances, %s" % e) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_all, + gateway=self.nuagenetworkdata["publiciprange2"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["publiciprange2"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_all, vm_1, + sharedsubnetid=subnet_id) + + self.delete_VM(vm_1) + self.delete_subnet_verify(self.shared_network_all, subnet1) + self.delete_subnet_verify(self.shared_network_all, subnet2) + + @staticmethod + def generateKeysForUser(api_client, account): + user = User.list( + api_client, + account=account.name, + domainid=account.domainid)[0] + return (User.registerUserKeys( + api_client, + user.id)) diff --git a/test/integration/plugins/nuagevsp/test_nuage_password_reset.py b/test/integration/plugins/nuagevsp/test_nuage_password_reset.py index 1ab6d57e61a..7973a3e2bae 100644 --- a/test/integration/plugins/nuagevsp/test_nuage_password_reset.py +++ b/test/integration/plugins/nuagevsp/test_nuage_password_reset.py @@ -199,138 +199,148 @@ class TestNuagePasswordReset(nuageTestCase): # template. # 13. Delete all the created objects (cleanup). - self.debug("Testing user data & password reset functionality in an " - "Isolated network...") + for zone in self.zones: + self.debug("Zone - %s" % zone.name) + # Get Zone details + self.getZoneDetails(zone=zone) + # Configure VSD sessions + self.configureVSDSessions() - self.debug("Creating an Isolated network...") - net_off = self.create_NetworkOffering( - self.test_data["nuagevsp"]["isolated_network_offering"]) - self.network = self.create_Network(net_off) - self.validate_Network(self.network, state="Allocated") + self.debug("Testing user data & password reset functionality in " + "an Isolated network...") - self.debug("Setting password enabled to false in the guest VM " - "template...") - self.defaultTemplateVal = self.template.passwordenabled - if self.template.passwordenabled: - self.updateTemplate(False) + self.debug("Creating an Isolated network...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"]) + self.network = self.create_Network(net_off) + self.validate_Network(self.network, state="Allocated") - self.debug("Deploying a VM in the created Isolated network with user " - "data...") - expected_user_data = "hello world vm1" - user_data = base64.b64encode(expected_user_data) - self.test_data["virtual_machine_userdata"]["userdata"] = user_data - self.vm_1 = self.create_VM( - self.network, testdata=self.test_data["virtual_machine_userdata"]) - self.validate_Network(self.network, state="Implemented") - vr = self.get_Router(self.network) - self.check_Router_state(vr, state="Running") - self.check_VM_state(self.vm_1, state="Running") + self.debug("Setting password enabled to false in the guest VM " + "template...") + self.defaultTemplateVal = self.template.passwordenabled + if self.template.passwordenabled: + self.updateTemplate(False) - # VSD verification - self.verify_vsd_network(self.domain.id, self.network) - self.verify_vsd_router(vr) - self.verify_vsd_vm(self.vm_1) - - self.debug("verifying that the guest VM template is not password " - "enabled...") - self.debug("VM - %s password - %s !" % - (self.vm_1.name, self.vm_1.password)) - self.assertEqual( - self.vm_1.password, - self.test_data["virtual_machine_userdata"]["password"], - "Password is enabled for the VM (vm_1)" - ) - - self.debug("SSHing into the VM for verifying its user data...") - public_ip_1 = self.acquire_PublicIPAddress(self.network) - self.create_and_verify_fw(self.vm_1, public_ip_1, self.network) - ssh = self.ssh_into_VM(self.vm_1, public_ip_1) - user_data_cmd = self.get_userdata_url(self.vm_1) - self.debug("Getting user data with command: " + user_data_cmd) - actual_user_data = base64.b64decode(self.execute_cmd - (ssh, user_data_cmd)) - self.debug("Actual user data - " + actual_user_data + - ", Expected user data - " + expected_user_data) - self.assertEqual(actual_user_data, expected_user_data, - "Un-expected VM (VM_1) user data" - ) - - self.debug("Checking for cloud-set-guest-password script in the VM " - "for testing password reset functionality...") - ls_cmd = "ls /etc/init.d/cloud-set-guest-password" - ls_result = self.execute_cmd(ssh, ls_cmd) - ls_result = ls_result.lower() - self.debug("Response from ls_cmd: " + ls_result) - if "no such file" in ls_result: - self.debug("No cloud-set-guest-password script in the VM") - self.debug("Installing the cloud-set-guest-password script from " - "people.apache.org in the VM...") - self.install_cloud_set_guest_password_script(ssh) - self.debug("Stopping the VM, and creating a new password enabled " - "guest VM template with it...") - self.stop_vm(self.vm_1) - self.create_template(self.vm_1) - - self.debug("Deploying a new VM in the created Isolated network " - "with the newly created guest VM template...") - self.vm_2 = self.create_VM( + self.debug("Deploying a VM in the created Isolated network with " + "user data...") + expected_user_data = "hello world vm1" + user_data = base64.b64encode(expected_user_data) + self.test_data["virtual_machine_userdata"]["userdata"] = user_data + self.vm_1 = self.create_VM( self.network, testdata=self.test_data["virtual_machine_userdata"]) - self.debug("Starting the VM...") - vm_2a = self.vm_2.start(self.api_client) - self.vm_2.password = vm_2a.password.strip() - self.vm_2.nic = vm_2a.nic + self.validate_Network(self.network, state="Implemented") + vr = self.get_Router(self.network) + self.check_Router_state(vr, state="Running") + self.check_VM_state(self.vm_1, state="Running") # VSD verification - self.verify_vsd_vm(self.vm_2) + self.verify_vsd_network(self.domain.id, self.network) + self.verify_vsd_router(vr) + self.verify_vsd_vm(self.vm_1) + + self.debug("verifying that the guest VM template is not password " + "enabled...") + self.debug("VM - %s password - %s !" % + (self.vm_1.name, self.vm_1.password)) + self.assertEqual( + self.vm_1.password, + self.test_data["virtual_machine_userdata"]["password"], + "Password is enabled for the VM (vm_1)" + ) + + self.debug("SSHing into the VM for verifying its user data...") + public_ip_1 = self.acquire_PublicIPAddress(self.network) + self.create_and_verify_fw(self.vm_1, public_ip_1, self.network) + ssh = self.ssh_into_VM(self.vm_1, public_ip_1) + user_data_cmd = self.get_userdata_url(self.vm_1) + self.debug("Getting user data with command: " + user_data_cmd) + actual_user_data = base64.b64decode(self.execute_cmd + (ssh, user_data_cmd)) + self.debug("Actual user data - " + actual_user_data + + ", Expected user data - " + expected_user_data) + self.assertEqual(actual_user_data, expected_user_data, + "Un-expected VM (VM_1) user data" + ) + + self.debug("Checking for cloud-set-guest-password script in the " + "VM for testing password reset functionality...") + ls_cmd = "ls /etc/init.d/cloud-set-guest-password" + ls_result = self.execute_cmd(ssh, ls_cmd) + ls_result = ls_result.lower() + self.debug("Response from ls_cmd: " + ls_result) + if "no such file" in ls_result: + self.debug("No cloud-set-guest-password script in the VM") + self.debug("Installing the cloud-set-guest-password script " + "from people.apache.org in the VM...") + self.install_cloud_set_guest_password_script(ssh) + self.debug("Stopping the VM, and creating a new password " + "enabled guest VM template with it...") + self.stop_vm(self.vm_1) + self.create_template(self.vm_1) + + self.debug("Deploying a new VM in the created Isolated " + "network with the newly created guest VM " + "template...") + self.vm_2 = self.create_VM( + self.network, + testdata=self.test_data["virtual_machine_userdata"]) + self.debug("Starting the VM...") + vm_2a = self.vm_2.start(self.api_client) + self.vm_2.password = vm_2a.password.strip() + self.vm_2.nic = vm_2a.nic + + # VSD verification + self.verify_vsd_vm(self.vm_2) + + self.debug("verifying that the guest VM template is password " + "enabled...") + self.debug("VM - %s password - %s !" % + (self.vm_2.name, self.vm_2.password)) + self.assertNotEqual( + self.vm_2.password, + self.test_data["virtual_machine_userdata"]["password"], + "Password is not enabled for the VM" + ) + + self.debug("SSHing into the VM for verifying its password...") + public_ip_2 = self.acquire_PublicIPAddress(self.network) + self.create_and_verify_fw(self.vm_2, public_ip_2, self.network) + self.ssh_into_VM(self.vm_2, public_ip_2) + + vm_test = self.vm_2 + vm_test_public_ip = public_ip_2 + else: + self.debug("Updating the guest VM template to password " + "enabled") + self.updateTemplate(True) + self.assertEqual(self.template.passwordenabled, True, + "Guest VM template is not password enabled" + ) + vm_test = self.vm_1 + vm_test_public_ip = public_ip_1 + + self.debug("Resetting password for VM - %s" % vm_test.name) + vm_test.password = vm_test.resetPassword(self.api_client) + self.debug("Password reset to - %s" % vm_test.password) + + self.debug("Starting the VM") + vm_test.start(self.api_client) self.debug("verifying that the guest VM template is password " "enabled...") self.debug("VM - %s password - %s !" % - (self.vm_2.name, self.vm_2.password)) + (vm_test.name, vm_test.password)) self.assertNotEqual( - self.vm_2.password, + vm_test.password, self.test_data["virtual_machine_userdata"]["password"], "Password is not enabled for the VM" ) - self.debug("SSHing into the VM for verifying its password...") - public_ip_2 = self.acquire_PublicIPAddress(self.network) - self.create_and_verify_fw(self.vm_2, public_ip_2, self.network) - self.ssh_into_VM(self.vm_2, public_ip_2) + self.debug("SSHing into the VM for verifying its new password " + "after its password reset...") + self.ssh_into_VM(vm_test, vm_test_public_ip) - vm_test = self.vm_2 - vm_test_public_ip = public_ip_2 - else: - self.debug("Updating the guest VM template to password enabled") - self.updateTemplate(True) - self.assertEqual(self.template.passwordenabled, True, - "Guest VM template is not password enabled" - ) - vm_test = self.vm_1 - vm_test_public_ip = public_ip_1 - - self.debug("Resetting password for VM - %s" % vm_test.name) - vm_test.password = vm_test.resetPassword(self.api_client) - self.debug("Password reset to - %s" % vm_test.password) - - self.debug("Starting the VM") - vm_test.start(self.api_client) - - self.debug("verifying that the guest VM template is password " - "enabled...") - self.debug("VM - %s password - %s !" % - (vm_test.name, vm_test.password)) - self.assertNotEqual( - vm_test.password, - self.test_data["virtual_machine_userdata"]["password"], - "Password is not enabled for the VM" - ) - - self.debug("SSHing into the VM for verifying its new password after " - "its password reset...") - self.ssh_into_VM(vm_test, vm_test_public_ip) - - self.debug("Setting password enabled to the default value in the " - "guest VM template...") - self.updateTemplate(self.defaultTemplateVal) + self.debug("Setting password enabled to the default value in the " + "guest VM template...") + self.updateTemplate(self.defaultTemplateVal) diff --git a/test/integration/plugins/nuagevsp/test_nuage_public_sharednetwork_ip_range.py b/test/integration/plugins/nuagevsp/test_nuage_public_sharednetwork_ip_range.py new file mode 100644 index 00000000000..b0a5ae9426c --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_public_sharednetwork_ip_range.py @@ -0,0 +1,823 @@ +# 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 Shared Network functionality with Nuage VSP SDN plugin: +Public Shared Network IP Range +""" +# Import Local Modules +from nuageTestCase import nuageTestCase +from marvin.lib.utils import cleanup_resources, validateList +from marvin.lib.base import (Account, + Domain, + User, + VirtualMachine, + Network, + NetworkOffering) +from marvin.lib.common import list_virtual_machines +from marvin.cloudstackAPI import (createVlanIpRange, + listVlanIpRanges, + deleteVlanIpRange, + updateVmNicIp) +from marvin.codes import PASS +# Import System Modules +from nose.plugins.attrib import attr + + +class TestNuageSharedNetworkPublicIPRange(nuageTestCase): + """Test Shared Network functionality with Nuage VSP SDN plugin: + Public Shared Network IP Range + """ + + @classmethod + def setUpClass(cls): + """ + Create the following domain tree and accounts that are required for + executing Nuage VSP SDN plugin test cases for shared networks: + Under ROOT - create domain D1 + Under domain D1 - Create two subdomains D11 and D12 + Under each of the domains - create one admin user and couple of + regular users. + Create shared network with the following scope: + 1. Network with scope="all" + 2. Network with scope="domain" with no subdomain access + 3. Network with scope="domain" with subdomain access + 4. Network with scope="account" + """ + + super(TestNuageSharedNetworkPublicIPRange, cls).setUpClass() + cls.sharednetworkdata = cls.test_data["acl"] + cls.nuagenetworkdata = cls.test_data["nuagevsp"] + + cls.domain_1 = None + cls.domain_2 = None + + try: + # backup default apikey and secretkey + cls.default_apikey = cls.api_client.connection.apiKey + cls.default_secretkey = cls.api_client.connection.securityKey + + # Create domains + cls.domain_1 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain1"] + ) + cls.domain_11 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain11"], + parentdomainid=cls.domain_1.id + ) + cls.domain_12 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain12"], + parentdomainid=cls.domain_1.id + ) + # Create 1 admin account and 2 user accounts for doamin_1 + cls.account_d1 = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1"], + admin=True, + domainid=cls.domain_1.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d1) + cls.user_d1_apikey = user.apikey + cls.user_d1_secretkey = user.secretkey + + cls.account_d1a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1A"], + admin=False, + domainid=cls.domain_1.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d1a) + cls.user_d1a_apikey = user.apikey + cls.user_d1a_secretkey = user.secretkey + + cls.account_d1b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1B"], + admin=False, + domainid=cls.domain_1.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d1b) + cls.user_d1b_apikey = user.apikey + cls.user_d1b_secretkey = user.secretkey + + # Create 1 admin and 2 user accounts for doamin_11 + cls.account_d11 = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11"], + admin=True, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11) + cls.user_d11_apikey = user.apikey + cls.user_d11_secretkey = user.secretkey + + cls.account_d11a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11A"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11a) + cls.user_d11a_apikey = user.apikey + cls.user_d11a_secretkey = user.secretkey + + cls.account_d11b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11B"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11b) + cls.user_d11b_apikey = user.apikey + cls.user_d11b_secretkey = user.secretkey + + # Create 2 user accounts for doamin_12 + cls.account_d12a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD12A"], + admin=False, + domainid=cls.domain_12.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d12a) + cls.user_d12a_apikey = user.apikey + cls.user_d12a_secretkey = user.secretkey + + cls.account_d12b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD12B"], + admin=False, + domainid=cls.domain_12.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d12b) + cls.user_d12b_apikey = user.apikey + cls.user_d12b_secretkey = user.secretkey + + # Create 1 user account and admin account in "ROOT" domain + + cls.account_roota = Account.create( + cls.api_client, + cls.sharednetworkdata["accountROOTA"], + admin=False, + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_roota) + cls.user_roota_apikey = user.apikey + cls.user_roota_secretkey = user.secretkey + + cls.account_root = Account.create( + cls.api_client, + cls.sharednetworkdata["accountROOTA"], + admin=True, + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_root) + cls.user_root_apikey = user.apikey + cls.user_root_secretkey = user.secretkey + + # service offering is already created in Nuagetestcase + cls.sharednetworkdata['mode'] = cls.zone.networktype + + # As admin user , create shared network with scope "all", "domain" + # with subdomain access ,"domain" without subdomain access and + # "account" + + cls.api_client.connection.apiKey = cls.default_apikey + cls.api_client.connection.securityKey = cls.default_secretkey + + cls.shared_network_offering = NetworkOffering.create( + cls.api_client, + cls.nuagenetworkdata["shared_nuage_public_network_offering"], + conservemode=False + ) + + # Enable Network offering + cls.shared_network_offering.update(cls.api_client, state='Enabled') + cls.shared_network_offering_id = cls.shared_network_offering.id + + cls.shared_network_all = Network.create( + cls.api_client, + cls.nuagenetworkdata["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id + ) + + cls.shared_network_domain_d11 = Network.create( + cls.api_client, + cls.nuagenetworkdata["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + subdomainaccess=False + ) + + cls.shared_network_domain_with_subdomain_d11 = Network.create( + cls.api_client, + cls.nuagenetworkdata["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + subdomainaccess=True + ) + + cls.shared_network_account_d111a = Network.create( + cls.api_client, + cls.nuagenetworkdata["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + accountid=cls.account_d11a.user[0].username + ) + + cls._cleanup = [ + cls.account_root, + cls.account_roota, + cls.shared_network_all, + cls.shared_network_offering, + cls.service_offering, + ] + except Exception as e: + cls.domain_1.delete(cls.api_client, cleanup="true") + cleanup_resources(cls.api_client, cls._cleanup) + raise Exception("Failed to create the setup required to execute " + "the test cases: %s" % e) + + return + + @classmethod + def tearDownClass(cls): + cls.api_client.connection.apiKey = cls.default_apikey + cls.api_client.connection.securityKey = cls.default_secretkey + cleanup_resources(cls.api_client, cls._cleanup) + return + + def setUp(self): + self.api_client = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + + def tearDown(self): + # restore back default apikey and secretkey + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + 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("Cleanup complete!") + return + + def add_subnet_verify(self, network, services): + """verify required nic is present in the VM""" + + self.debug("Going to add new ip range in shared network %s" % + network.name) + cmd = createVlanIpRange.createVlanIpRangeCmd() + cmd.networkid = network.id + cmd.gateway = services["gateway"] + cmd.netmask = services["netmask"] + cmd.startip = services["startip"] + cmd.endip = services["endip"] + cmd.forVirtualNetwork = services["forvirtualnetwork"] + addedsubnet = self.api_client.createVlanIpRange(cmd) + + self.debug("verify above iprange is successfully added in shared " + "network %s or not" % network.name) + + cmd1 = listVlanIpRanges.listVlanIpRangesCmd() + cmd1.networkid = network.id + cmd1.id = addedsubnet.vlan.id + + allsubnets = self.api_client.listVlanIpRanges(cmd1) + self.assertEqual( + allsubnets[0].id, + addedsubnet.vlan.id, + "Check New subnet is successfully added to the shared Network" + ) + return addedsubnet + + def delete_subnet_verify(self, network, subnet): + """verify required nic is present in the VM""" + + self.debug("Going to delete ip range in shared network %s" % + network.name) + cmd = deleteVlanIpRange.deleteVlanIpRangeCmd() + cmd.id = subnet.vlan.id + self.api_client.deleteVlanIpRange(cmd) + + self.debug("verify above iprange is successfully deleted from shared " + "network %s or not" % network.name) + + cmd1 = listVlanIpRanges.listVlanIpRangesCmd() + cmd1.networkid = network.id + cmd1.id = subnet.vlan.id + + try: + allsubnets = self.api_client.listVlanIpRanges(cmd1) + self.assertEqual( + allsubnets[0].id, + subnet.vlan.id, + "Check Subnet is not present to the shared Network" + ) + self.fail("iprange is not successfully deleted from shared " + "network %s" % network.name) + except Exception as e: + self.debug("iprange is not successfully deleted from shared " + "network %s" % network.name) + self.debug("exception msg is %s" % e) + + def shared_subnet_not_present(self, network, subnetid): + shared_resources = self.vsd.get_shared_network_resource( + filter=self.get_externalID_filter(subnetid)) + try: + self.assertEqual(shared_resources.description, network.name, + "VSD shared resources description should match " + "network name in CloudStack" + ) + self.fail("still shared resource are present on VSD") + except Exception as e: + self.debug("sharedNetwork resources is successfully deleted from " + "VSD") + self.debug("exception msg is %s" % e) + + # Test cases relating to add/delete Shared Network IP ranges + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_01_add_delete_Subnet_in_public_sharednetwork_scope_all(self): + """Validate that subnet of same and different public gateway can be + added to shared network with scope=all + """ + + # Add subnet with same cidr + self.debug("Adding subnet of same cidr to shared Network scope as all") + subnet1 = self.add_subnet_verify( + self.shared_network_all, self.nuagenetworkdata["publiciprange1"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange1"]["startip"] + vm_1 = self.create_VM( + self.shared_network_all, account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_all, + gateway=self.nuagenetworkdata["publiciprange1"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["publiciprange1"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_all, vm_1, + sharedsubnetid=subnet_id) + + # Add subnet with different cidr + self.debug("Adding subnet of different cidr to shared Network scope " + "as all") + subnet2 = self.add_subnet_verify( + self.shared_network_all, self.nuagenetworkdata["publiciprange2"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange2"]["startip"] + vm_2 = self.create_VM( + self.shared_network_all, account=self.account_d11a) + + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_all, + gateway=self.nuagenetworkdata["publiciprange2"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["publiciprange2"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_all, vm_2, + sharedsubnetid=subnet_id) + # put ping here + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_subnet_verify(self.shared_network_all, subnet1) + self.delete_subnet_verify(self.shared_network_all, subnet2) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_02_add_delete_Subnet_in_public_sharednetwork_scope_domain(self): + """Validate subnet of same and different gateway can be added to public + shared network scope=domain with subdomain access + """ + + # Add subnet with same cidr + self.debug("Adding subnet of same cidr to shared Network scope domain " + "with subdomain access") + subnet1 = self.add_subnet_verify( + self.shared_network_domain_with_subdomain_d11, + self.nuagenetworkdata["publiciprange1"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange1"]["startip"] + vm_1 = self.create_VM( + self.shared_network_domain_with_subdomain_d11, + account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata["publiciprange1"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata["publiciprange1"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, vm_1, + sharedsubnetid=subnet_id) + + # Add subnet with different cidr + self.debug("Adding subnet of different cidr to shared Network") + subnet2 = self.add_subnet_verify( + self.shared_network_domain_with_subdomain_d11, + self.nuagenetworkdata["publiciprange2"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange2"]["startip"] + vm_2 = self.create_VM( + self.shared_network_domain_with_subdomain_d11, + account=self.account_d11a) + + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata["publiciprange2"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata["publiciprange2"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, vm_2, + sharedsubnetid=subnet_id) + # put ping here + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_subnet_verify( + self.shared_network_domain_with_subdomain_d11, subnet1) + self.delete_subnet_verify( + self.shared_network_domain_with_subdomain_d11, subnet2) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_03_add_delete_Subnet_in_pub_sharednetwork_scope_nosubdomain(self): + """Validate subnet of same and different gateway can added to public + shared network scope=domain without subdomain access + """ + + # Add subnet with same cidr + self.debug("Adding subnet of same cidr to shared Network scope domain " + "without subdomain access") + subnet1 = self.add_subnet_verify( + self.shared_network_domain_d11, + self.nuagenetworkdata["publiciprange1"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange1"]["startip"] + vm_1 = self.create_VM( + self.shared_network_domain_d11, account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_domain_d11, + gateway=self.nuagenetworkdata["publiciprange1"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata["publiciprange1"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_domain_d11, vm_1, + sharedsubnetid=subnet_id) + + # Add subnet with different cidr + self.debug("Adding subnet of different cidr to shared Network") + subnet2 = self.add_subnet_verify( + self.shared_network_domain_d11, + self.nuagenetworkdata["publiciprange2"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange2"]["startip"] + vm_2 = self.create_VM( + self.shared_network_domain_d11, account=self.account_d11a) + + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_domain_d11, + gateway=self.nuagenetworkdata["publiciprange2"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata["publiciprange2"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_domain_d11, vm_2, + sharedsubnetid=subnet_id) + # put ping here + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_subnet_verify(self.shared_network_domain_d11, subnet1) + self.delete_subnet_verify(self.shared_network_domain_d11, subnet2) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_04_add_delete_Subnet_in_public_sharednetwork_scope_account(self): + """Validate subnet of same and different gateway can be added to shared + network scope=Account + """ + + # Add subnet with same cidr + self.debug("Adding subnet of same cidr to shared Network scope as " + "Account") + subnet1 = self.add_subnet_verify( + self.shared_network_account_d111a, + self.nuagenetworkdata["publiciprange1"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange1"]["startip"] + vm_1 = self.create_VM( + self.shared_network_account_d111a, account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_account_d111a, + gateway=self.nuagenetworkdata["publiciprange1"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_account_d111a.id, + self.nuagenetworkdata["publiciprange1"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_account_d111a, + vm_1, sharedsubnetid=subnet_id) + + # Add subnet with different cidr + self.debug("Adding subnet of different cidr to shared Network") + subnet2 = self.add_subnet_verify( + self.shared_network_account_d111a, + self.nuagenetworkdata["publiciprange2"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange2"]["startip"] + vm_2 = self.create_VM( + self.shared_network_account_d111a, account=self.account_d11a) + + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_account_d111a, + gateway=self.nuagenetworkdata["publiciprange2"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_account_d111a.id, + self.nuagenetworkdata["publiciprange2"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_account_d111a, + vm_2, sharedsubnetid=subnet_id) + # put ping here + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_subnet_verify(self.shared_network_account_d111a, subnet1) + self.delete_subnet_verify(self.shared_network_account_d111a, subnet2) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_05_change_ip_from_different_Subnet_public_shared(self): + """Validate that ip of a vm can be changed to a different subnet ip for + shared_network_scope_all + """ + + # Add subnet with same cidr + self.debug("Adding subnet of same cidr to shared Network scope as all") + subnet1 = self.add_subnet_verify( + self.shared_network_all, self.nuagenetworkdata["publiciprange1"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange1"]["startip"] + vm_1 = self.create_VM( + self.shared_network_all, account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_all, + gateway=self.nuagenetworkdata["publiciprange1"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["publiciprange1"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_all, vm_1, + sharedsubnetid=subnet_id) + # Add subnet with different cidr + self.debug("Adding subnet of different cidr to shared Network scope " + "as all") + subnet2 = self.add_subnet_verify( + self.shared_network_all, self.nuagenetworkdata["publiciprange2"]) + + # stop VM to update the ipaddress + try: + vm_1.stop(self.api_client) + except Exception as e: + self.fail("Failed to stop the virtual instances, %s" % e) + vm_list = list_virtual_machines(self.api_client, id=vm_1.id) + nics = [x for x in vm_list[0].nic + if x.networkid == self.shared_network_all.id] + self.debug("Filtered nics list: %s:" % nics) + + cmd = updateVmNicIp.updateVmNicIpCmd() + for x in vm_list[0].nic: + cmd.nicid = x.id + cmd.ipaddress = self.nuagenetworkdata["publiciprange2"]["startip"] + self.api_client.updateVmNicIp(cmd) + + try: + vm_1.start(self.api_client) + except Exception as e: + self.fail("Failed to start the virtual instances, %s" % e) + + vm_list = list_virtual_machines(self.api_client, id=vm_1.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, + "vm list validation failed due to %s" % + vm_list_validation_result[2]) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_all, + gateway=self.nuagenetworkdata["publiciprange2"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["publiciprange2"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_all, vm_list[0], + sharedsubnetid=subnet_id) + + self.delete_VM(vm_1) + self.delete_subnet_verify(self.shared_network_all, subnet1) + self.delete_subnet_verify(self.shared_network_all, subnet2) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_06_restart_public_sharedNetwork_scope_all(self): + """Validate that restart Shared Network is done successfully without + any Error + """ + + self.debug("Adding subnet of same cidr to shared Network scope as all") + try: + self.add_subnet_verify( + self.shared_network_all, + self.nuagenetworkdata["publiciprange1"]) + except Exception as e: + self.debug("seems above test case is not able to clean the subnet") + self.debug("exception msg is %s" % e) + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange1"]["startip"] + vm_1 = self.create_VM( + self.shared_network_all, account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_all, + gateway=self.nuagenetworkdata["publiciprange1"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["publiciprange1"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_all, vm_1, + sharedsubnetid=subnet_id) + + # Restart network with cleanup + self.debug("Restarting shared Network with cleanup") + self.shared_network_all.restart(self.api_client, cleanup=True) + + self.debug("validating SharedNetwork on VSD") + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_all, + gateway=self.nuagenetworkdata["publiciprange1"]["gateway"]) + self.delete_VM(vm_1) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_07_delete_first_subnet_public_sharednetwork_scope_all(self): + """Validate that when first subnet is removed then deletion of Network + works fine + """ + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["startip"] + vm_2 = self.create_VM( + self.shared_network_all, account=self.account_d11a) + + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_all, vm_2, + sharedsubnetid=subnet_id) + # Restart network with cleanup + cmd = listVlanIpRanges.listVlanIpRangesCmd() + cmd.networkid = self.shared_network_all.id + allsubnets = self.api_client.listVlanIpRanges(cmd) + self.delete_VM(vm_2) + firstsubnet = None + for subnet in allsubnets: + if subnet.endip == self.nuagenetworkdata["network_all"]["endip"]: + firstsubnet = subnet + + self.debug("cleanning first subnet") + try: + cmd = deleteVlanIpRange.deleteVlanIpRangeCmd() + cmd.id = firstsubnet.id + self.api_client.deleteVlanIpRange(cmd) + except Exception as e: + self.fail("Fail to delete the first subnet of shared Network") + self.debug("exception msg is %s" % e) + + self.shared_network_all.delete(self.api_client) + if self.shared_network_all in self._cleanup: + self._cleanup.remove(self.shared_network_all) + self.shared_subnet_not_present(self.shared_network_all, subnet_id) + + def test_08_public_sharednetwork_domain_cleanup(self): + """Validate that sharedNetwork Parent domain is cleaned up properly + """ + + try: + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["startip"] + vm_1 = self.create_VM( + self.shared_network_domain_with_subdomain_d11, + account=self.account_d11a) + + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id_subdomain = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + vm_1, sharedsubnetid=subnet_id_subdomain) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["endip"] + vm_2 = self.create_VM( + self.shared_network_domain_d11, account=self.account_d11a) + + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_domain_d11, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id_nosubdomain = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_domain_d11, + vm_2, sharedsubnetid=subnet_id_nosubdomain) + subnet_id_nosubdomain1 = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata["publiciprange2"]["gateway"]) + subnet_id_subdomain1 = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata["publiciprange2"]["gateway"]) + self.domain_1.delete(self.api_client, cleanup="true") + except Exception as e: + self.debug("test case Fail") + self.debug("exception msg is %s" % e) + self.domain_1.delete(self.api_client, cleanup="true") + self.fail("Fail to delete the Parent domain") + + self.shared_subnet_not_present( + self.shared_network_domain_with_subdomain_d11, + subnet_id_subdomain) + self.shared_subnet_not_present( + self.shared_network_domain_d11, subnet_id_nosubdomain) + self.shared_subnet_not_present( + self.shared_network_domain_with_subdomain_d11, + subnet_id_subdomain1) + self.shared_subnet_not_present( + self.shared_network_domain_d11, subnet_id_nosubdomain1) + + @staticmethod + def generateKeysForUser(api_client, account): + user = User.list( + api_client, + account=account.name, + domainid=account.domainid)[0] + + return (User.registerUserKeys( + api_client, + user.id)) diff --git a/test/integration/plugins/nuagevsp/test_nuage_public_sharednetwork_userdata.py b/test/integration/plugins/nuagevsp/test_nuage_public_sharednetwork_userdata.py new file mode 100644 index 00000000000..d33d076aab0 --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_public_sharednetwork_userdata.py @@ -0,0 +1,948 @@ +# 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 Shared Network functionality with Nuage VSP SDN plugin: +Public Shared Network IP Range +""" +# Import Local Modules +from nuageTestCase import nuageTestCase +from marvin.lib.utils import cleanup_resources +from marvin.lib.common import list_templates +from marvin.lib.base import (Account, + Domain, + User, + VirtualMachine, + Network, + NetworkOffering) +from marvin.cloudstackAPI import (createVlanIpRange, + listVlanIpRanges, + deleteVlanIpRange, + updateTemplate) +# Import System Modules +from nose.plugins.attrib import attr +import random +import string + + +class TestNuageSharedNetworkUserdata(nuageTestCase): + """Test Shared Network functionality with Nuage VSP SDN plugin: + Public Shared Network IP Range + """ + + @classmethod + def setUpClass(cls): + """ + Create the following domain tree and accounts that are required for + executing Nuage VSP SDN plugin test cases for shared networks: + Under ROOT - create domain D1 + Under domain D1 - Create two subdomains D11 and D12 + Under each of the domains - create one admin user and couple of + regular users. + Create shared network with the following scope: + 1. Network with scope="all" + 2. Network with scope="domain" with no subdomain access + 3. Network with scope="domain" with subdomain access + 4. Network with scope="account" + """ + + super(TestNuageSharedNetworkUserdata, cls).setUpClass() + cls.sharednetworkdata = cls.test_data["acl"] + cls.nuagenetworkdata = cls.test_data["nuagevsp"] + + cls.domain_1 = None + cls.domain_2 = None + + try: + # backup default apikey and secretkey + cls.default_apikey = cls.api_client.connection.apiKey + cls.default_secretkey = cls.api_client.connection.securityKey + + # Create domains + cls.domain_1 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain1"] + ) + cls.domain_11 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain11"], + parentdomainid=cls.domain_1.id + ) + cls.domain_12 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain12"], + parentdomainid=cls.domain_1.id + ) + # Create 1 admin account and 2 user accounts for doamin_1 + cls.account_d1 = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1"], + admin=True, + domainid=cls.domain_1.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d1) + cls.user_d1_apikey = user.apikey + cls.user_d1_secretkey = user.secretkey + + cls.account_d1a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1A"], + admin=False, + domainid=cls.domain_1.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d1a) + cls.user_d1a_apikey = user.apikey + cls.user_d1a_secretkey = user.secretkey + + cls.account_d1b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1B"], + admin=False, + domainid=cls.domain_1.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d1b) + cls.user_d1b_apikey = user.apikey + cls.user_d1b_secretkey = user.secretkey + + # Create 1 admin and 2 user accounts for doamin_11 + cls.account_d11 = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11"], + admin=True, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11) + cls.user_d11_apikey = user.apikey + cls.user_d11_secretkey = user.secretkey + + cls.account_d11a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11A"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11a) + cls.user_d11a_apikey = user.apikey + cls.user_d11a_secretkey = user.secretkey + + cls.account_d11b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11B"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11b) + cls.user_d11b_apikey = user.apikey + cls.user_d11b_secretkey = user.secretkey + + # Create 2 user accounts for doamin_12 + cls.account_d12a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD12A"], + admin=False, + domainid=cls.domain_12.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d12a) + cls.user_d12a_apikey = user.apikey + cls.user_d12a_secretkey = user.secretkey + + cls.account_d12b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD12B"], + admin=False, + domainid=cls.domain_12.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d12b) + cls.user_d12b_apikey = user.apikey + cls.user_d12b_secretkey = user.secretkey + + # Create 1 user account and admin account in "ROOT" domain + + cls.account_roota = Account.create( + cls.api_client, + cls.sharednetworkdata["accountROOTA"], + admin=False, + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_roota) + cls.user_roota_apikey = user.apikey + cls.user_roota_secretkey = user.secretkey + + cls.account_root = Account.create( + cls.api_client, + cls.sharednetworkdata["accountROOTA"], + admin=True, + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_root) + cls.user_root_apikey = user.apikey + cls.user_root_secretkey = user.secretkey + + # service offering is already created in Nuagetestcase + cls.sharednetworkdata['mode'] = cls.zone.networktype + + # As admin user , create shared network with scope "all", "domain" + # with subdomain access ,"domain" without subdomain access and + # "account" + + cls.api_client.connection.apiKey = cls.default_apikey + cls.api_client.connection.securityKey = cls.default_secretkey + cls.nuagenetworkdata["shared_nuage_public_network_offering"][ + "serviceProviderList"].update({"UserData": 'VirtualRouter'}) + cls.nuagenetworkdata["shared_nuage_public_network_offering"][ + "supportedservices"] = 'Dhcp,Connectivity,UserData' + for key, value in cls.test_data["nuagevsp"][ + "shared_nuage_public_network_offering"]["serviceProviderList"]\ + .iteritems(): + cls.debug("elements are %s and value is %s" % (key, value)) + + cls.shared_network_offering = NetworkOffering.create( + cls.api_client, + cls.nuagenetworkdata["shared_nuage_public_network_offering"], + conservemode=False + ) + + # Enable Network offering + cls.shared_network_offering.update(cls.api_client, state='Enabled') + cls.shared_network_offering_id = cls.shared_network_offering.id + + cls.shared_network_all = Network.create( + cls.api_client, + cls.nuagenetworkdata["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id + ) + + cls.shared_network_domain_d11 = Network.create( + cls.api_client, + cls.nuagenetworkdata["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + subdomainaccess=False + ) + + cls.shared_network_domain_with_subdomain_d11 = Network.create( + cls.api_client, + cls.nuagenetworkdata["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + subdomainaccess=True + ) + + cls.shared_network_account_d111a = Network.create( + cls.api_client, + cls.nuagenetworkdata["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + accountid=cls.account_d11a.user[0].username + ) + + cls._cleanup = [ + cls.account_root, + cls.account_roota, + cls.shared_network_all, + cls.shared_network_offering, + cls.service_offering, + ] + user_data = ''.join(random.choice( + string.ascii_uppercase + string.digits) for x in range(2500)) + cls.test_data["virtual_machine"]["userdata"] = user_data + except Exception as e: + cls.domain_1.delete(cls.api_client, cleanup="true") + cleanup_resources(cls.api_client, cls._cleanup) + raise Exception("Failed to create the setup required to execute " + "the test cases: %s" % e) + + return + + @classmethod + def tearDownClass(cls): + cls.api_client.connection.apiKey = cls.default_apikey + cls.api_client.connection.securityKey = cls.default_secretkey + cleanup_resources(cls.api_client, cls._cleanup) + return + + def setUp(self): + self.api_client = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + self.cleanup = [] + + def tearDown(self): + # restore back default apikey and secretkey + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + 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("Cleanup complete!") + self.updateTemplate(False) + return + + def add_subnet_verify(self, network, services): + """verify required nic is present in the VM""" + + self.debug("Going to add new ip range in shared network %s" % + network.name) + cmd = createVlanIpRange.createVlanIpRangeCmd() + cmd.networkid = network.id + cmd.gateway = services["gateway"] + cmd.netmask = services["netmask"] + cmd.startip = services["startip"] + cmd.endip = services["endip"] + cmd.forVirtualNetwork = services["forvirtualnetwork"] + addedsubnet = self.api_client.createVlanIpRange(cmd) + + self.debug("verify above iprange is successfully added in shared " + "network %s or not" % network.name) + + cmd1 = listVlanIpRanges.listVlanIpRangesCmd() + cmd1.networkid = network.id + cmd1.id = addedsubnet.vlan.id + + allsubnets = self.api_client.listVlanIpRanges(cmd1) + self.assertEqual( + allsubnets[0].id, + addedsubnet.vlan.id, + "Check New subnet is successfully added to the shared Network" + ) + return addedsubnet + + def delete_subnet_verify(self, network, subnet): + """verify required nic is present in the VM""" + + self.debug("Going to delete ip range in shared network %s" % + network.name) + cmd = deleteVlanIpRange.deleteVlanIpRangeCmd() + cmd.id = subnet.vlan.id + self.api_client.deleteVlanIpRange(cmd) + + self.debug("verify above iprange is successfully deleted from shared " + "network %s or not" % network.name) + + cmd1 = listVlanIpRanges.listVlanIpRangesCmd() + cmd1.networkid = network.id + cmd1.id = subnet.vlan.id + + try: + allsubnets = self.api_client.listVlanIpRanges(cmd1) + self.assertEqual( + allsubnets[0].id, + subnet.vlan.id, + "Check Subnet is not present to the shared Network" + ) + self.fail("iprange is not successfully deleted from shared " + "network %s" % network.name) + except Exception as e: + self.debug("iprange is successfully deleted from shared " + "network %s" % network.name) + self.debug("exception msg is %s" % e) + + def shared_subnet_not_present(self, network, subnetid): + shared_resources = self.vsd.get_shared_network_resource( + filter=self.get_externalID_filter(subnetid)) + try: + self.assertEqual(shared_resources.description, network.name, + "VSD shared resources description should match " + "network name in CloudStack" + ) + self.fail("still shared resource are present on VSD") + except Exception as e: + self.debug("sharedNetwork resources is successfully deleted from " + "VSD") + self.debug("exception msg is %s" % e) + + # updateTemplate - Updates value of the guest VM template's password + # enabled setting + def updateTemplate(self, value): + self.debug("Updating value of guest VM template's password enabled " + "setting") + cmd = updateTemplate.updateTemplateCmd() + cmd.id = self.template.id + cmd.passwordenabled = value + self.api_client.updateTemplate(cmd) + list_template_response = list_templates(self.api_client, + templatefilter="all", + id=self.template.id) + self.template = list_template_response[0] + self.debug("Updated guest VM template") + + # Test cases relating to VR IP check on Shared Network + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_01_verify_deployvm_fail_startip_sharednetwork_scope_all(self): + """Validate that deploy vm fails if user specify the first ip of subnet + because that is reserved for VR shared network with scope=all + """ + # Add vm as start ip of subnet + self.debug("Adding VM as start IP of Subnet") + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["startip"] + try: + self.create_VM(self.shared_network_all, account=self.account_d11a) + self.fail("VM with subnet start IP is deployed successfully") + except Exception as e: + self.debug("Deploy vm fails as expected with exception %s" % e) + self.debug("Going to verify the exception message") + excetionmsg = "it is reserved for the VR in network" + if excetionmsg in str(e): + self.debug("correct exception is raised") + else: + self.fail("correct exception is not raised") + + # Test cases relating to add/delete Shared Network IP ranges + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_02_add_delete_Subnet_restart_public_sharednetwork_scope_all(self): + """Validate that subnet of same gateway can be added to shared network + with scope=all and restart network with clean up works + """ + self.debug("Deploy VM to shared Network scope as all") + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["endip"] + vm_1 = self.create_VM( + self.shared_network_all, account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_all, vm_1, + sharedsubnetid=subnet_id) + # verify VR + vr = self.get_Router(self.shared_network_all) + self.check_Router_state(vr, state="Running") + self.verify_vsd_router(vr) + + # Add subnet with same cidr + self.debug("Adding subnet of same cidr to shared Network scope as all") + subnet1 = self.add_subnet_verify( + self.shared_network_all, self.nuagenetworkdata["publiciprange3"]) + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange3"]["startip"] + vm_2 = self.create_VM( + self.shared_network_all, account=self.account_d11a) + # verify on VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_all, + gateway=self.nuagenetworkdata["publiciprange3"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["publiciprange3"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_all, vm_2, + sharedsubnetid=subnet_id) + # Restart network with cleanup + self.debug("Restarting shared Network with cleanup") + self.shared_network_all.restart(self.api_client, cleanup=True) + + self.debug("validating SharedNetwork on VSD") + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + # verify VR + vr = self.get_Router(self.shared_network_all) + self.check_Router_state(vr, state="Running") + self.verify_vsd_router(vr) + # put ping here + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_subnet_verify(self.shared_network_all, subnet1) + + # Test cases relating to add/delete Shared Network IP ranges + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_03_add_delete_Subnet_restart_sharednetwork_scope_domain(self): + """Validate that subnet of same gateway can be added to shared network + with scope=all and restart network with clean up works + """ + self.debug("Deploy VM to shared Network scope domain as all") + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["endip"] + vm_1 = self.create_VM( + self.shared_network_domain_with_subdomain_d11, + account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, vm_1, + sharedsubnetid=subnet_id) + # verify VR + vr = self.get_Router(self.shared_network_domain_with_subdomain_d11) + self.check_Router_state(vr, state="Running") + self.verify_vsd_router(vr) + + # Add subnet with same cidr + self.debug("Adding subnet of same cidr to shared Network scope as all") + subnet1 = self.add_subnet_verify( + self.shared_network_domain_with_subdomain_d11, + self.nuagenetworkdata["publiciprange3"]) + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange3"]["startip"] + vm_2 = self.create_VM( + self.shared_network_domain_with_subdomain_d11, + account=self.account_d11a) + # VSD check points + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata["publiciprange3"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata["publiciprange3"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, vm_2, + sharedsubnetid=subnet_id) + # Restart network with cleanup + self.debug("Restarting shared Network with cleanup") + self.shared_network_domain_with_subdomain_d11.restart(self.api_client, + cleanup=True) + + self.debug("validating SharedNetwork on VSD") + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + # verify VR + vr = self.get_Router(self.shared_network_domain_with_subdomain_d11) + self.check_Router_state(vr, state="Running") + self.verify_vsd_router(vr) + # put ping here + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_subnet_verify( + self.shared_network_domain_with_subdomain_d11, subnet1) + + # Test cases relating to add/delete Shared Network IP ranges + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_04_add_delete_Subnet_restart_scope_domain_nosubdomain(self): + """Validate that subnet of same gateway can be added to shared network + with scope domain nosubdomain and restart network with clean up works + """ + + self.debug("Deploy VM to shared Network scope domain no subdomain") + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["endip"] + vm_1 = self.create_VM( + self.shared_network_domain_d11, account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_domain_d11, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_domain_d11, vm_1, + sharedsubnetid=subnet_id) + # verify VR + vr = self.get_Router(self.shared_network_domain_d11) + self.check_Router_state(vr, state="Running") + self.verify_vsd_router(vr) + + # Add subnet with same cidr + self.debug("Adding subnet of same cidr to shared Network scope as all") + subnet1 = self.add_subnet_verify( + self.shared_network_domain_d11, + self.nuagenetworkdata["publiciprange3"]) + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange3"]["startip"] + vm_2 = self.create_VM( + self.shared_network_domain_d11, account=self.account_d11a) + + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_domain_d11, + gateway=self.nuagenetworkdata["publiciprange3"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata["publiciprange3"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_domain_d11, vm_2, + sharedsubnetid=subnet_id) + # Restart network with cleanup + self.debug("Restarting shared Network with cleanup") + self.shared_network_domain_d11.restart(self.api_client, cleanup=True) + + self.debug("validating SharedNetwork on VSD") + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_domain_d11, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + # verify VR + vr = self.get_Router(self.shared_network_domain_d11) + self.check_Router_state(vr, state="Running") + self.verify_vsd_router(vr) + # put ping here + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_subnet_verify(self.shared_network_domain_d11, subnet1) + + # Test cases relating to add/delete Shared Network IP ranges + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_05_add_delete_Subnet_restart_scope_account(self): + """Validate that subnet of same gateway can be added to shared network + with scope as account and restart network with clean up works + """ + + self.debug("Deploy VM to shared Network scope as account") + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["endip"] + vm_1 = self.create_VM( + self.shared_network_account_d111a, account=self.account_d11a) + + # Verify shared Network and VM in VSD + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_account_d111a, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_account_d111a.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_account_d111a, + vm_1, sharedsubnetid=subnet_id) + # verify VR + vr = self.get_Router(self.shared_network_account_d111a) + self.check_Router_state(vr, state="Running") + self.verify_vsd_router(vr) + + # Add subnet with same cidr + self.debug("Add subnet of same cidr shared Network scope as account") + subnet1 = self.add_subnet_verify( + self.shared_network_account_d111a, + self.nuagenetworkdata["publiciprange3"]) + + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["publiciprange3"]["startip"] + vm_2 = self.create_VM( + self.shared_network_account_d111a, account=self.account_d11a) + + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_account_d111a, + gateway=self.nuagenetworkdata["publiciprange3"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_account_d111a.id, + self.nuagenetworkdata["publiciprange3"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, self.shared_network_account_d111a, + vm_2, sharedsubnetid=subnet_id) + # Restart network with cleanup + self.debug("Restarting shared Network with cleanup") + self.shared_network_account_d111a.restart(self.api_client, + cleanup=True) + + self.debug("validating SharedNetwork on VSD") + self.verify_vsd_shared_network( + self.account_d11a.domainid, self.shared_network_account_d111a, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + # verify VR + vr = self.get_Router(self.shared_network_account_d111a) + self.check_Router_state(vr, state="Running") + self.verify_vsd_router(vr) + # put ping here + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_subnet_verify(self.shared_network_account_d111a, subnet1) + + # Test cases relating to VR IP check on Shared Network + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_06_verify_different_gateway_subnet_fails_sharednetwork_all(self): + """Validate that Different gateway subnet fail as it is not supported + for userdata service shared network with scope=all + """ + # Add subnet of different gateway + self.debug("Adding subnet of different gateway") + + try: + subnet2 = self.add_subnet_verify( + self.shared_network_all, + self.nuagenetworkdata["publiciprange2"]) + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["endip"] + vm_1 = self.create_VM( + self.shared_network_all, account=self.account_d11a) + self.delete_VM(vm_1) + self.delete_subnet_verify(self.shared_network_all, subnet2) + self.fail("VM is successfully added which is not expected") + except Exception as e: + self.debug("different gateway subnet " + "fails as expected with exception %s" % e) + self.debug("Going to verify the exception message") + self.delete_subnet_verify(self.shared_network_all, subnet2) + excetionmsg = "Failed to deploy VM" + if excetionmsg in str(e): + self.debug("correct exception is raised") + else: + self.fail("correct exception is not raised") + + # Test cases relating to different gateway subnet check on Shared Network + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_07_different_gateway_subnet_fails_sharednetwork_domain(self): + """Validate that Different gateway subnet fail as it is not supported + for userdata service shared network with scope domain + """ + # Add subnet of different gateway + self.debug("Adding subnet of different gateway") + + try: + subnet2 = self.add_subnet_verify( + self.shared_network_domain_with_subdomain_d11, + self.nuagenetworkdata["publiciprange2"]) + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["endip"] + vm_1 = self.create_VM( + self.shared_network_domain_with_subdomain_d11, + account=self.account_d11a) + self.delete_VM(vm_1) + self.delete_subnet_verify( + self.shared_network_domain_with_subdomain_d11, subnet2) + self.fail("VM is successfully added which is not expected") + except Exception as e: + self.debug("different gateway subnet " + "fails as expected with exception %s" % e) + self.debug("Going to verify the exception message") + self.delete_subnet_verify( + self.shared_network_domain_with_subdomain_d11, subnet2) + excetionmsg = "Failed to deploy VM" + if excetionmsg in str(e): + self.debug("correct exception is raised") + else: + self.fail("correct exception is not raised") + + # Test cases relating to different gateway subnet check on Shared Network + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_08_different_gateway_subnet_fails_sharednetwork_nosubdomain(self): + """Validate that Different gateway subnet fail as it is not supported + for userdata service shared network with scope nosubdomain + """ + # Add subnet of different gateway + self.debug("Adding subnet of different gateway") + + try: + subnet2 = self.add_subnet_verify( + self.shared_network_domain_d11, + self.nuagenetworkdata["publiciprange2"]) + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["endip"] + vm_1 = self.create_VM( + self.shared_network_domain_d11, account=self.account_d11a) + self.delete_VM(vm_1) + self.delete_subnet_verify( + self.shared_network_domain_d11, subnet2) + self.fail("VM is successfully added which is not expected") + except Exception as e: + self.debug("different gateway subnet" + " fails as expected with exception %s" % e) + self.debug("Going to verify the exception message") + self.delete_subnet_verify( + self.shared_network_domain_d11, subnet2) + excetionmsg = "Failed to deploy VM" + if excetionmsg in str(e): + self.debug("correct exception is raised") + else: + self.fail("correct exception is not raised") + + # Test cases relating to different gateway subnet check on Shared Network + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_09_different_gateway_subnet_fails_sharednetwork_account(self): + """Validate that Different gateway subnet fail as it is not supported + for userdata service shared network with scope account + """ + # Add subnet of different gateway + self.debug("Adding subnet of different gateway") + + try: + subnet2 = self.add_subnet_verify( + self.shared_network_account_d111a, + self.nuagenetworkdata["publiciprange2"]) + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["endip"] + vm_1 = self.create_VM( + self.shared_network_account_d111a, account=self.account_d11a) + self.delete_VM(vm_1) + self.delete_subnet_verify( + self.shared_network_account_d111a, subnet2) + self.fail("VM is successfully added which is not expected") + except Exception as e: + self.debug("different gateway subnet" + " fails as expected with exception %s" % e) + self.debug("Going to verify the exception message") + self.delete_subnet_verify( + self.shared_network_account_d111a, subnet2) + excetionmsg = "Failed to deploy VM" + if excetionmsg in str(e): + self.debug("correct exception is raised") + else: + self.fail("correct exception is not raised") + + # Test cases relating to reset password in Shared Network + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_10_password_reset_public_sharednetwork_scope_all(self): + """Validate that reset password works fine in shared network + with scope=all + """ + self.updateTemplate(True) + self.debug("Deploy VM to shared Network scope as all") + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["endip"] + vm_1 = self.create_VM( + self.shared_network_all, account=self.account_d11a) + + # verify VR + vr = self.get_Router(self.shared_network_all) + self.check_Router_state(vr, state="Running") + self.verify_vsd_router(vr) + + self.debug("Stopping VM: %s" % vm_1.name) + vm_1.stop(self.api_client) + self.debug("Resetting VM password for VM: %s" % vm_1.name) + password = vm_1.resetPassword(self.api_client) + self.debug("Password reset to: %s" % password) + vm_1.start(self.api_client) + + # put login to vm here + self.delete_VM(vm_1) + + # Test cases relating to reset password in Shared Network + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_11_password_reset_public_sharednetwork_scope_domain(self): + """Validate that reset password works fine in shared network + with scope as domain with subdomain access + """ + self.updateTemplate(True) + self.debug("Deploy VM to shared Network scope as all") + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["endip"] + vm_1 = self.create_VM( + self.shared_network_domain_with_subdomain_d11, + account=self.account_d11a) + + # verify VR + vr = self.get_Router(self.shared_network_domain_with_subdomain_d11) + self.check_Router_state(vr, state="Running") + self.verify_vsd_router(vr) + + self.debug("Stopping VM: %s" % vm_1.name) + vm_1.stop(self.api_client) + self.debug("Resetting VM password for VM: %s" % vm_1.name) + password = vm_1.resetPassword(self.api_client) + self.debug("Password reset to: %s" % password) + vm_1.start(self.api_client) + + # put login to vm here + self.delete_VM(vm_1) + + # Test cases relating to reset password in Shared Network + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_12_password_reset_public_sharednetwork_scope_account(self): + """Validate that reset password works fine in shared network + with scope as Account + """ + self.updateTemplate(True) + self.debug("Deploy VM to shared Network scope as all") + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["endip"] + vm_1 = self.create_VM( + self.shared_network_account_d111a, account=self.account_d11a) + + # verify VR + vr = self.get_Router(self.shared_network_account_d111a) + self.check_Router_state(vr, state="Running") + self.verify_vsd_router(vr) + + self.debug("Stopping VM: %s" % vm_1.name) + vm_1.stop(self.api_client) + self.debug("Resetting VM password for VM: %s" % vm_1.name) + password = vm_1.resetPassword(self.api_client) + self.debug("Password reset to: %s" % password) + vm_1.start(self.api_client) + + # put login to vm here + self.delete_VM(vm_1) + + def test_13_public_sharednetwork_domain_cleanup(self): + """Validate that sharedNetwork Parent domain is cleaned up properly + """ + + try: + self.test_data["virtual_machine"]["ipaddress"] = \ + self.nuagenetworkdata["network_all"]["endip"] + vm_1 = self.create_VM( + self.shared_network_domain_with_subdomain_d11, + account=self.account_d11a) + + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id_subdomain = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + vm_1, sharedsubnetid=subnet_id_subdomain) + + subnet_id_subdomain1 = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata["publiciprange2"]["gateway"]) + self.domain_1.delete(self.api_client, cleanup="true") + except Exception as e: + self.debug("test case Fail") + self.debug("exception msg is %s" % e) + self.domain_1.delete(self.api_client, cleanup="true") + self.fail("Fail to delete the Parent domain") + + self.shared_subnet_not_present( + self.shared_network_domain_with_subdomain_d11, + subnet_id_subdomain) + self.shared_subnet_not_present( + self.shared_network_domain_with_subdomain_d11, + subnet_id_subdomain1) + + @staticmethod + def generateKeysForUser(api_client, account): + user = User.list( + api_client, + account=account.name, + domainid=account.domainid)[0] + + return (User.registerUserKeys( + api_client, + user.id)) diff --git a/test/integration/plugins/nuagevsp/test_nuage_publicsharednetwork.py b/test/integration/plugins/nuagevsp/test_nuage_publicsharednetwork.py new file mode 100644 index 00000000000..dca034e2508 --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_publicsharednetwork.py @@ -0,0 +1,2575 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# 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 Shared Network functionality with Nuage VSP SDN plugin: +Public Shared Network +""" +# Import Local Modules +from nuageTestCase import nuageTestCase +from marvin.lib.utils import cleanup_resources +from marvin.lib.base import (Account, + Domain, + User, + VirtualMachine, + Network, + NetworkOffering) +from marvin.cloudstackException import CloudstackAclException +# Import System modules +from nose.plugins.attrib import attr +import random +import string + + +class TestNuagePublicSharedNetwork(nuageTestCase): + """Test Shared Network functionality with Nuage VSP SDN plugin: + Public Shared Network + """ + + @classmethod + def setUpClass(cls): + """ + Create the following domain tree and accounts that are required for + executing Nuage VSP SDN plugin test cases for shared networks: + Under ROOT - create domain D1 + Under domain D1 - Create two subdomains D11 and D12 + Under each of the domains - create one admin user and couple of + regular users. + Create shared network with the following scope: + 1. Network with scope="all" + 2. Network with scope="domain" with no subdomain access + 3. Network with scope="domain" with subdomain access + 4. Network with scope="account" + """ + + super(TestNuagePublicSharedNetwork, cls).setUpClass() + cls.sharednetworkdata = cls.test_data["acl"] + cls.nuagenetworkdata = cls.test_data["nuagevsp"] + + cls.domain_1 = None + cls.domain_2 = None + + try: + # backup default apikey and secretkey + cls.default_apikey = cls.api_client.connection.apiKey + cls.default_secretkey = cls.api_client.connection.securityKey + + # Create domains + cls.domain_1 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain1"] + ) + cls.domain_11 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain11"], + parentdomainid=cls.domain_1.id + ) + cls.domain_111 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain111"], + parentdomainid=cls.domain_11.id, + ) + cls.domain_12 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain12"], + parentdomainid=cls.domain_1.id + ) + cls.domain_2 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain2"] + ) + # Create 1 admin account and 2 user accounts for doamin_1 + cls.account_d1 = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1"], + admin=True, + domainid=cls.domain_1.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d1) + cls.user_d1_apikey = user.apikey + cls.user_d1_secretkey = user.secretkey + + cls.account_d1a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1A"], + admin=False, + domainid=cls.domain_1.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d1a) + cls.user_d1a_apikey = user.apikey + cls.user_d1a_secretkey = user.secretkey + + cls.account_d1b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1B"], + admin=False, + domainid=cls.domain_1.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d1b) + cls.user_d1b_apikey = user.apikey + cls.user_d1b_secretkey = user.secretkey + + # Create 1 admin and 2 user accounts for doamin_11 + cls.account_d11 = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11"], + admin=True, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11) + cls.user_d11_apikey = user.apikey + cls.user_d11_secretkey = user.secretkey + + cls.account_d11a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11A"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11a) + cls.user_d11a_apikey = user.apikey + cls.user_d11a_secretkey = user.secretkey + + cls.account_d11b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11B"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11b) + cls.user_d11b_apikey = user.apikey + cls.user_d11b_secretkey = user.secretkey + + # Create 2 user accounts and 1 admin account for doamin_111 + + cls.account_d111 = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD111"], + admin=True, + domainid=cls.domain_111.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d111) + cls.user_d111_apikey = user.apikey + cls.user_d111_secretkey = user.secretkey + + cls.account_d111a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD111A"], + admin=False, + domainid=cls.domain_111.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d111a) + cls.user_d111a_apikey = user.apikey + cls.user_d111a_secretkey = user.secretkey + + cls.account_d111b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD111B"], + admin=False, + domainid=cls.domain_111.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d111b) + cls.user_d111b_apikey = user.apikey + cls.user_d111b_secretkey = user.secretkey + + # Create 2 user accounts for doamin_12 + cls.account_d12a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD12A"], + admin=False, + domainid=cls.domain_12.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d12a) + cls.user_d12a_apikey = user.apikey + cls.user_d12a_secretkey = user.secretkey + + cls.account_d12b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD12B"], + admin=False, + domainid=cls.domain_12.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d12b) + cls.user_d12b_apikey = user.apikey + cls.user_d12b_secretkey = user.secretkey + + # Create 1 user account for domain_2 + + cls.account_d2a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD2"], + admin=False, + domainid=cls.domain_2.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d2a) + cls.user_d2a_apikey = user.apikey + cls.user_d2a_secretkey = user.secretkey + + # Create 1 user account and admin account in "ROOT" domain + + cls.account_roota = Account.create( + cls.api_client, + cls.sharednetworkdata["accountROOTA"], + admin=False, + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_roota) + cls.user_roota_apikey = user.apikey + cls.user_roota_secretkey = user.secretkey + + cls.account_root = Account.create( + cls.api_client, + cls.sharednetworkdata["accountROOTA"], + admin=True, + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_root) + cls.user_root_apikey = user.apikey + cls.user_root_secretkey = user.secretkey + + # service offering is already created in Nuagetestcase + cls.sharednetworkdata['mode'] = cls.zone.networktype + + # As admin user , create shared network with scope "all", + # "domain" with subdomain access, + # "domain" without subdomain access and "account" + + cls.api_client.connection.apiKey = cls.default_apikey + cls.api_client.connection.securityKey = cls.default_secretkey + cls.test_data["nuagevsp"]["shared_nuage_public_network_offering"][ + "serviceProviderList"].update({"UserData": 'VirtualRouter'}) + cls.test_data["nuagevsp"]["shared_nuage_public_network_offering"][ + "supportedservices"] = 'Dhcp,Connectivity,UserData' + + cls.shared_network_offering = NetworkOffering.create( + cls.api_client, + cls.test_data["nuagevsp"][ + "shared_nuage_public_network_offering"], + conservemode=False + ) + # Enable Network offering + cls.shared_network_offering.update(cls.api_client, state='Enabled') + cls.shared_network_offering_id = cls.shared_network_offering.id + + cls.shared_network_all = Network.create( + cls.api_client, + cls.test_data["nuagevsp"]["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id + ) + + cls.shared_network_domain_d11 = Network.create( + cls.api_client, + cls.test_data["nuagevsp"][ + "network_domain_with_no_subdomain_access"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + subdomainaccess=False + ) + + cls.shared_network_domain_with_subdomain_d11 = Network.create( + cls.api_client, + cls.test_data["nuagevsp"][ + "network_domain_with_subdomain_access"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + subdomainaccess=True + ) + + cls.shared_network_account_d111a = Network.create( + cls.api_client, + cls.test_data["nuagevsp"]["network_account"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_111.id, + accountid=cls.account_d111a.user[0].username + ) + cls.vmdata = {"name": "test", + "displayname": "test" + } + + cls._cleanup = [ + cls.account_root, + cls.account_roota, + cls.shared_network_all, + cls.shared_network_offering, + cls.service_offering, + ] + user_data = ''.join(random.choice( + string.ascii_uppercase + string.digits) for x in range(2500)) + cls.vmdata["userdata"] = user_data + except Exception as e: + cls.domain_1.delete(cls.api_client, cleanup="true") + cls.domain_2.delete(cls.api_client, cleanup="true") + cleanup_resources(cls.api_client, cls._cleanup) + raise Exception( + "Failed to create the setup required to execute the test " + "cases: %s" % e) + + return + + @classmethod + def tearDownClass(cls): + + cls.api_client.connection.apiKey = cls.default_apikey + cls.api_client.connection.securityKey = cls.default_secretkey + cls.domain_1.delete(cls.api_client, cleanup="true") + cls.domain_2.delete(cls.api_client, cleanup="true") + cleanup_resources(cls.api_client, cls._cleanup) + return + + def setUp(self): + self.api_client = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + + def tearDown(self): + # restore back default apikey and secretkey + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + return + + # Test cases relating to deploying Virtual Machine as ROOT admin for other + # users in shared network with scope=all + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_all_domainuser(self): + """Validate that ROOT admin is able to deploy a VM for other users in + a shared network with scope=all + """ + + # Deploy VM for a user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1A"]["name"] + \ + "-shared-scope-all-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1A"]["displayname"] + \ + "-shared-scope-all-root-admin" + + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d1a, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d1a.name and + vm.domainid == self.account_d1a.domainid, + True, + "ROOT admin is not able to deploy a VM for other users in a " + "shared network with scope=all") + subnet_id = self.get_subnet_id(self.shared_network_all.id, + self.nuagenetworkdata["network_all"][ + "gateway"]) + self.verify_vsd_enterprise_vm(self.account_d1a.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_all_domainadminuser( + self): + """Validate that ROOT admin is able to deploy a VM for a domain admin + users in a shared network with scope=all + """ + + # Deploy VM for an admin user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1"]["name"] + \ + "-shared-scope-all-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1"]["displayname"] + \ + "-shared-scope-all-root-admin" + + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d1, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d1.name and + vm.domainid == self.account_d1.domainid, + True, + "ROOT admin is not able to deploy a VM " + "for a domain admin users in a shared network with scope=all") + + self.verify_vsd_shared_network( + self.account_d1.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id(self.shared_network_all.id, + self.nuagenetworkdata["network_all"][ + "gateway"]) + self.verify_vsd_enterprise_vm(self.account_d1.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_all_subdomainuser(self): + """Validate that ROOT admin is able to deploy a VM for any user in a + subdomain in a shared network with scope=all + """ + # Deploy VM as user in a subdomain under ROOT + + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-all-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-all-root-admin" + + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d11a, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11a.name and + vm.domainid == self.account_d11a.domainid, + True, + "ROOT admin is not able to deploy a VM" + " for any user in a subdomain in a shared network with scope=all") + + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id(self.shared_network_all.id, + self.nuagenetworkdata["network_all"][ + "gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_all_subdomainadminuser( + self): + """Validate that ROOT admin is able to deploy a VM for admin user in a + domain in a shared network with scope=all + """ + + # Deploy VM as an admin user in a subdomain under ROOT + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11"]["name"] + \ + "-shared-scope-all-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11"]["displayname"] + \ + "-shared-scope-all-root-admin" + + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d11, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11.name and + vm.domainid == self.account_d11.domainid, + True, + "ROOT admin is not able to deploy a VM for admin user in a domain " + "in a shared network with scope=all") + self.verify_vsd_shared_network( + self.account_d11.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id(self.shared_network_all.id, + self.nuagenetworkdata["network_all"][ + "gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_all_ROOTuser(self): + """Validate that ROOT admin is able to deploy a VM for user in ROOT + domain in a shared network with scope=all + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-all-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-all-root-admin" + + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_roota, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_roota.name and + vm.domainid == self.account_roota.domainid, + True, + "ROOT admin is not able to deploy a VM for user in ROOT domain " + "in a shared network with scope=all") + self.verify_vsd_shared_network( + self.account_roota.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id(self.shared_network_all.id, + self.nuagenetworkdata["network_all"][ + "gateway"]) + self.verify_vsd_enterprise_vm(self.account_roota.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + # Test cases relating to deploying Virtual Machine as ROOT admin for other + # users in shared network with scope=Domain and no subdomain access + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_nosubdomaccess_domainuser( + self): + """Validate that ROOT admin is able to deploy a VM for domain user in a + shared network with scope=domain with no subdomain access + """ + + # Deploy VM as user in a domain that has shared network with no + # subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + + vm = self.create_VM(self.shared_network_domain_d11, + testdata=self.vmdata, account=self.account_d11a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11a.name and + vm.domainid == self.account_d11a.domainid, + True, + "ROOT admin is not able to deploy a VM for domain user in a " + "shared network with scope=domain with no subdomain access") + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_domain_d11, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_nosubdomaccess_domainadminuser( + self): + """Validate that ROOT admin is able to deploy a VM for domain admin + user in a shared network with scope=domain with no subdomain access + """ + + # Deploy VM as an admin user in a domain that has shared network with + # no subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + + vm = self.create_VM(self.shared_network_domain_d11, + testdata=self.vmdata, account=self.account_d11, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11.name and + vm.domainid == self.account_d11.domainid, + True, + "ROOT admin is not able to deploy VM for domain admin user in " + "shared network with scope=domain with no subdomain access") + self.verify_vsd_shared_network( + self.account_d11.domainid, + self.shared_network_domain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11.domainid, + self.shared_network_domain_d11, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_nosubdomaccess_subdomainuser( + self): + """Validate that ROOT admin is NOT able to deploy a VM for sub domain + user in a shared network with scope=domain with no subdomain access + """ + + # Deploy VM as user in a subdomain under a domain that has shared + # network with no subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111A"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111A"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d111a.name, + domainid=self.account_d111a.domainid + ) + self.fail( + "ROOT admin is able to deploy a VM for sub domain user in a " + "shared network with scope=domain with no subdomain access") + + except Exception as e: + self.debug( + "When a user from a subdomain deploys a VM in a shared " + "network with scope=domain with no subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for sub domain user in a shared network with " + "scope=domain with no subdomain access ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_nosubdomaccess_subdomainadmin( + self): + """Validate that ROOT admin is NOT able to deploy a VM for sub domain + admin user in a shared network with scope=domain with no subdomain + access + """ + + # Deploy VM as an admin user in a subdomain under a domain that has + # shared network with no subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d111.name, + domainid=self.account_d111.domainid + ) + self.fail( + "ROOT admin is able to deploy VM for sub domain admin user in " + "a shared network with scope=domain with no subdomain access") + except Exception as e: + self.debug( + "When a admin user from a subdomain deploys a VM in a shared " + "network with scope=domain with no subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for sub domain admin user in a shared " + "network with scope=domain with no subdomain access") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_nosubdomaccess_parentdomuser( + self): + """Validate that ROOT admin is NOT able to deploy a VM for parent + domain user in a shared network with scope=domain with no subdomain + access + """ + + # Deploy VM as user in parentdomain of a domain that has shared network + # with no subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1A"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1A"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d1a.name, + domainid=self.account_d1a.domainid + ) + self.fail( + " ROOT admin is able to deploy a VM for parent domain user in " + "a shared network with scope=domain with no subdomain access") + except Exception as e: + self.debug( + "When a user from parent domain deploys a VM in a shared " + "network with scope=domain with no subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries " + "to deploy a VM for parent domain user in a shared " + "network with scope=domain with no subdomain access") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_nosubdomaccess_parentdomadmin( + self): + """Validate that ROOT admin is NOT able to deploy a VM for parent + domain admin user in a shared network with scope=domain with no + subdomain access + """ + + # Deploy VM as an admin user in parentdomain of a domain that has + # shared network with no subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d1.name, + domainid=self.account_d1.domainid + ) + self.fail( + "ROOT admin is able to deploy a VM for parent domain admin " + "user in a shared network with scope=domain with no subdomain " + "access") + except Exception as e: + self.debug( + "When an admin user from parent domain deploys a VM in a " + "shared network with scope=domain with no subdomain access %s" + % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for parent domain admin user in a shared " + "network with scope=domain with no subdomain access ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_nosubdomaccess_ROOTuser(self): + """Validate that ROOT admin is NOT able to deploy a VM for parent + domain admin user in a shared network with scope=domain with no + subdomain access + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + self.fail( + "ROOT admin is able to deploy a VM for parent domain admin " + "user in a shared network with scope=domain with no subdomain " + "access") + except Exception as e: + self.debug( + "When a regular user from ROOT domain deploys a VM in a " + "shared network with scope=domain with no subdomain access %s" + % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for parent domain admin user in a shared " + "network with scope=domain with no subdomain access") + + # Test cases relating to deploying Virtual Machine as ROOT admin for other + # users in shared network with scope=Domain and with subdomain access + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_subdomaccess_domainuser( + self): + """Validate that ROOT admin is able to deploy a VM for domain user in a + shared network with scope=domain with subdomain access + """ + + # Deploy VM as user in a domain that has shared network with subdomain + # access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d11a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11a.name and + vm.domainid == self.account_d11a.domainid, + True, + "ROOT admin is NOT able to deploy a VM for domain user in a " + "shared network with scope=domain with subdomain access") + + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_subdomaccess_domainadminuser( + self): + """Validate that ROOT admin is able to deploy a VM for domain admin + user in a shared network with scope=domain with subdomain access + """ + + # Deploy VM as an admin user in a domain that has shared network with + # subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d11, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11.name and + vm.domainid == self.account_d11.domainid, + True, + "ROOT admin is not able to deploy a VM for domain admin user in a " + "shared network with scope=domain with subdomain access") + + self.verify_vsd_shared_network( + self.account_d11.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_subdomaccess_subdomainuser( + self): + """Validate that ROOT admin is able to deploy a VM for subdomain user + in a shared network with scope=domain with subdomain access + """ + + # Deploy VM as user in a subdomain under a domain that has shared + # network with subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d111a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d111a.name and + vm.domainid == self.account_d111a.domainid, + True, + "ROOT admin is not able to deploy a VM for subdomain user in a " + "shared network with scope=domain with subdomain access") + + self.verify_vsd_shared_network( + self.account_d111a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d111a.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_subdomaccess_subdomainadmin( + self): + """Validate that ROOT admin is able to deploy a VM for subdomain admin + user in a shared network with scope=domain with subdomain access + """ + + # Deploy VM as an admin user in a subdomain under a domain that has + # shared network with subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d111, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d111.name and + vm.domainid == self.account_d111.domainid, + True, + "ROOT admin is not able to deploy VM for subdomain admin user in " + "a shared network with scope=domain subdomain access") + + self.verify_vsd_shared_network( + self.account_d111.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d111.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_subdomaccess_parentdomainuser( + self): + """Validate that ROOT admin is NOT able to deploy a VM for parent + domain user in a shared network with scope=domain with subdomain access + """ + + # Deploy VM as user in parentdomain of a domain that has shared network + # with subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_with_subdomain_d11.id, + accountid=self.account_d1a.name, + domainid=self.account_d1a.domainid + ) + self.fail( + "ROOT admin is NOT able to deploy a VM for parent domain user " + "in a shared network with scope=domain with subdomain access") + except Exception as e: + self.debug( + "When a user from parent domain deploys a VM in a shared " + "network with scope=domain with subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for parent domain user in a shared network " + "with scope=domain with subdomain access ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_subdomaccess_parentdomainadmin( + self): + """Validate that ROOT admin is NOT able to deploy a VM for parent + domain admin user in a shared network with scope=domain with subdomain + access + """ + # Deploy VM as an admin user in parentdomain of a domain that has + # shared network with subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_with_subdomain_d11.id, + accountid=self.account_d1.name, + domainid=self.account_d1.domainid + ) + self.fail( + "ROOT admin is able to deploy VM for parent domain admin user " + "in a shared network with scope=domain subdomain access ") + except Exception as e: + self.debug( + "When an admin user from parent domain deploys a VM in a " + "shared network with scope=domain with subdomain access %s" % + e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for parent domain admin user in a shared " + "network with scope=domain with subdomain access ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_subdomaccess_ROOTuser(self): + """Validate that ROOT admin is NOT able to deploy a VM for user in ROOT + domain in a shared network with scope=domain with subdomain access + """ + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.user_roota_apikey + self.api_client.connection.securityKey = self.user_roota_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_with_subdomain_d11.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + self.fail( + "ROOT admin is able to deploy a VM for user in ROOT domain in " + "a shared network with scope=domain with subdomain access") + except Exception as e: + self.debug( + "When a user from ROOT domain deploys a VM in a shared " + "network with scope=domain with subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for user in ROOT domain in a shared network " + "with scope=domain with subdomain access") + + # Test cases relating to deploying Virtual Machine as ROOT admin for other + # users in shared network with scope=account + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_account_domainuser(self): + """Validate that ROOT admin is NOT able to deploy a VM for user in the + same domain but in a different account in a shared network with + scope=account + """ + + # Deploy VM as user in a domain under the same domain but different + # account from the account that has a shared network with scope=account + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111B"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111B"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_d111b.name, + domainid=self.account_d111b.domainid + ) + self.fail( + "ROOT admin is able to deploy VM for user in the same domain " + "but in different account in shared network scope=account") + except Exception as e: + self.debug( + "When a user from same domain but different account deploys a " + "VM in a shared network with scope=account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for user in the same domain but in a " + "different account in a shared network with scope=account") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_account_domainadminuser( + self): + """Validate that ROOT admin is NOT able to deploy a VM for admin user + in the same domain but in a different account in a shared network with + scope=account + """ + + # Deploy VM as admin user for a domain that has an account with shared + # network with scope=account + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_d111.name, + domainid=self.account_d111.domainid + ) + self.fail( + "ROOT admin is able to deploy VM for admin user in same " + "domain but in different account in shared network with " + "scope=account") + except Exception as e: + self.debug( + "When a user from same domain but different account deploys a " + "VM in a shared network with scope=account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for admin user in the same domain but in a " + "different account in a shared network with scope=account") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_account_user(self): + """Validate that ROOT admin is able to deploy a VM for regular user in + a shared network with scope=account + """ + + # Deploy VM as account with shared network with scope=account + + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + + vm = self.create_VM(self.shared_network_account_d111a, + testdata=self.vmdata, account=self.account_d111a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d111a.name and + vm.domainid == self.account_d111a.domainid, + True, + "ROOT admin is not able to deploy a VM for regular user in a " + "shared network with scope=account") + + self.verify_vsd_shared_network(self.account_d111a.domainid, + self.shared_network_account_d111a, + gateway=self.nuagenetworkdata[ + "network_account"]["gateway"]) + subnet_id = self.get_subnet_id(self.shared_network_account_d111a.id, + self.nuagenetworkdata[ + "network_account"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d111a.domainid, + self.shared_network_account_d111a, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_account_differentdomain( + self): + """Validate that ROOT admin is NOT able to deploy a VM for a admin user + in a shared network with scope=account which the admin user does not + have access to + """ + + # Deploy VM as an admin user in a subdomain under ROOT + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD2A"]["name"] + \ + "-shared-scope-account-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD2A"]["displayname"] + \ + "-shared-scope-account-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_d2a.name, + domainid=self.account_d2a.domainid + ) + self.fail( + "ROOT admin is able to deploy VM for admin user in shared " + "network scope=account which admin user does not have access") + except Exception as e: + self.debug("account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for a admin user in a shared network with " + "scope=account which the admin user does not have access " + "to ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_account_ROOTuser(self): + """Validate that ROOT admin is NOT able to deploy a VM for a user in + ROOT domain in a shared network with scope=account which the user does + not have access to + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-account-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-account-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + self.fail( + "ROOT admin is able to deploy VM for a user in ROOT domain in " + "shared network scope=account which user does not have access") + except Exception as e: + self.debug( + "When a user from ROOT domain deploys a VM in a shared " + "network with scope=account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for a user in ROOT domain in a shared " + "network with scope=account which the user does not have " + "access to ") + + # Test cases relating to deploying Virtual Machine as Domain admin for + # other users in shared network with scope=all + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_all_domainuser( + self): + """Validate that Domain admin is able to deploy a VM for a domain user + in a shared network with scope=all + """ + + # Deploy VM for a user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1A"]["name"] + \ + "-shared-scope-all-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1A"]["displayname"] + \ + "-shared-scope-all-domain-admin" + + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d1a, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d1a.name and + vm.domainid == self.account_d1a.domainid, + True, + "Domain admin is not able to deploy a VM for a domain user in a " + "shared network with scope=all") + + self.verify_vsd_shared_network( + self.account_d1a.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d1a.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_all_domadminuser( + self): + """Validate that Domain admin is able to deploy a VM for a domain admin + user in a shared network with scope=all + """ + + # Deploy VM for an admin user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1"]["name"] + \ + "-shared-scope-all-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1"]["displayname"] + \ + "-shared-scope-all-domain-admin" + + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d1, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d1.name and + vm.domainid == self.account_d1.domainid, + True, + "Domain admin is not able to deploy a VM for a domain admin user " + "in a shared network with scope=all") + + self.verify_vsd_shared_network( + self.account_d1.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d1.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_all_subdomainuser( + self): + """Validate that Domain admin is able to deploy a VM for a sub domain + user in a shared network with scope=all + """ + + # Deploy VM as user in a subdomain under ROOT + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-all-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-all-domain-admin" + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d11a, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11a.name and + vm.domainid == self.account_d11a.domainid, + True, + "Domain admin is not able to deploy a VM for a sub domain user in " + "a shared network with scope=all") + + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_all_subdomadmin( + self): + """Validate that Domain admin is able to deploy a VM for a sub domain + admin user in a shared network with scope=all + """ + + # Deploy VM as an admin user in a subdomain under ROOT + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11"]["name"] + \ + "-shared-scope-all-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11"]["displayname"] + \ + "-shared-scope-all-domain-admin" + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d11, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11.name and + vm.domainid == self.account_d11.domainid, + True, + "Domain admin is not able to deploy a VM for a sub domain admin " + "user in a shared network with scope=all") + + self.verify_vsd_shared_network( + self.account_d11.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_all_ROOTuser(self): + """Validate that Domain admin is NOT able to deploy a VM for user in + ROOT domain in a shared network with scope=all + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-all" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-all" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_all.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + self.fail( + "Domain admin is NOT able to deploy a VM for user in ROOT " + "domain in a shared network with scope=all") + except Exception as e: + self.debug( + "When a Domain admin user deploys a VM for ROOT user in a " + "shared network with scope=all %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail( + "Error message validation failed when Domain admin is NOT " + "able to deploy a VM for user in ROOT domain in a shared " + "network with scope=all") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_all_crossdomuser( + self): + """Validate that Domain admin is NOT able to deploy a VM for user in + other domain in a shared network with scope=all + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + "-shared-scope-all" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-all" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_all.id, + accountid=self.account_d2a.name, + domainid=self.account_d2a.domainid + ) + self.fail( + "Domain admin user is able to Deploy VM for a domain user he " + "does not have access to in a shared network with " + "scope=domain with no subdomain access ") + except Exception as e: + self.debug( + "When a Domain admin user deploys a VM for a domain user he " + "does not have access to in a shared network with " + "scope=domain with no subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail( + "Error mesage validation failed when Domain admin user " + "tries to Deploy VM for a domain user he does not have " + "access to in a shared network with scope=domain with no " + "subdomain access ") + + # Test cases relating to deploying Virtual Machine as Domain admin for + # other users in shared network with scope=Domain and no subdomain access + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_nosubdomaccess_domuser( + self): + """Validate that Domain admin is able to deploy a VM for domain user in + a shared network with scope=Domain and no subdomain access + """ + + # Deploy VM as user in a domain that has shared network with no + # subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + + vm = self.create_VM(self.shared_network_domain_d11, + testdata=self.vmdata, account=self.account_d11a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11a.name and + vm.domainid == self.account_d11a.domainid, + True, + "Domain admin is not able to deploy a VM for domain user in a " + "shared network with scope=Domain and no subdomain access") + + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_domain_d11, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_nosubdomaccess_domadmin( + self): + """Validate that Domain admin is able to deploy a VM for domain admin + user in a shared network with scope=Domain and no subdomain access + """ + + # Deploy VM as an admin user in a domain that has shared network with + # no subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + vm = self.create_VM(self.shared_network_domain_d11, + testdata=self.vmdata, account=self.account_d11, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11.name and + vm.domainid == self.account_d11.domainid, + True, + "Admin User in a domain that has a shared network with no " + "subdomain access failed to Deploy VM in a shared network with " + "scope=domain with no subdomain access") + self.verify_vsd_shared_network( + self.account_d11.domainid, + self.shared_network_domain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11.domainid, + self.shared_network_domain_d11, vm, + sharedsubnetid=subnet_id) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_nosubdomaccess_subdomusr( + self): + """Validate that Domain admin is NOT able to deploy a VM for sub domain + user in a shared network with scope=Domain and no subdomain access + """ + + # Deploy VM as user in a subdomain under a domain that has shared + # network with no subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111A"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111A"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d111a.name, + domainid=self.account_d111a.domainid + ) + self.fail( + "Domain admin is able to deploy VM for sub domain user in a " + "shared network with scope=Domain and no subdomain access") + except Exception as e: + self.debug( + "When a user from a subdomain deploys a VM in a shared " + "network with scope=domain with no subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for sub domain user in a shared network " + "with scope=Domain and no subdomain access") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_nosubdomaccess_subdomadm( + self): + """Valiadte that Domain admin is NOT able to deploy a VM for sub domain + admin user in a shared network with scope=Domain and no subdomain + access + """ + + # Deploy VM as an admin user in a subdomain under a domain that has + # shared network with no subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d111.name, + domainid=self.account_d111.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for sub domain admin " + "user in a shared network with scope=Domain no subdomain " + "access") + except Exception as e: + self.debug( + "When a admin user from a subdomain deploys a VM in a shared " + "network with scope=domain with no subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for sub domain admin user in a shared " + "network with scope=Domain and no subdomain access ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_nosubdomaccess_pardomusr( + self): + """Validate that Domain admin is NOT able to deploy a VM for parent + domain user in a shared network with scope=Domain and no subdomain + access + """ + + # Deploy VM as user in parentdomain of a domain that has shared network + # with no subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1A"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1A"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d1a.name, + domainid=self.account_d1a.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for parent domain user " + "in a shared network with scope=Domain and no subdomain " + "access") + except Exception as e: + self.debug( + "When a user from parent domain deploys a VM in a shared " + "network with scope=domain with no subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for parent domain user in a shared " + "network with scope=Domain and no subdomain access ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_nosubdomaccess_pardomadm( + self): + """Validate that Domain admin is NOT able to deploy VM for parent + domain admin user in shared network with scope=Domain and no subdomain + access + """ + + # Deploy VM as an admin user in parentdomain of a domain that has + # shared network with no subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d1.name, + domainid=self.account_d1.domainid + ) + self.fail( + "Domain admin is able to deploy VM for parent domain admin " + "user in a shared network with scope=Domain no subdomain " + "access") + except Exception as e: + self.debug( + "When an admin user from parent domain deploys a VM in a " + "shared network with scope=domain with no subdomain access %s" + % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for parent domain admin user in a shared " + "network with scope=Domain and no subdomain access ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_nosubdomaccess_ROOTuser( + self): + """Validate that Domain admin is NOT able to deploy a VM for user in + ROOT domain in a shared network with scope=Domain and no subdomain + access + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for user in ROOT domain " + "in a shared network with scope=Domain and no subdomain " + "access") + except Exception as e: + self.debug( + "When a regular user from ROOT domain deploys a VM in a " + "shared network with scope=domain with no subdomain access %s" + % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for user in ROOT domain in a shared " + "network with scope=Domain and no subdomain access") + + # Test cases relating to deploying Virtual Machine as Domain admin for + # other users in shared network with scope=Domain and with subdomain access + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_subdomaccess_domainuser( + self): + """Validate that Domain admin is able to deploy a VM for regular user + in domain in a shared network with scope=Domain and subdomain access + """ + + # Deploy VM as user in a domain that has shared network with subdomain + # access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d11a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11a.name and + vm.domainid == self.account_d11a.domainid, + True, + "Domain admin is not able to deploy VM for regular user in domain " + "in a shared network with scope=Domain subdomain access") + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_subdomaccess_domainadmin( + self): + """Validate that Domain admin is able to deploy a VM for admin user in + domain in a shared network with scope=Domain and subdomain access + """ + + # Deploy VM as an admin user in a domain that has shared network with + # subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d11, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11.name and + vm.domainid == self.account_d11.domainid, + True, + "Domain admin is not able to deploy a VM for admin user in domain " + "in a shared network with scope=Domain subdomain access") + self.verify_vsd_shared_network( + self.account_d11.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_subdomaccess_subdomuser( + self): + """Validate that Domain admin is able to deploy a VM for regular user + in subdomain in a shared network with scope=Domain and subdomain access + """ + + # Deploy VM as user in a subdomain under a domain that has shared + # network with subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d111a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d111a.name and + vm.domainid == self.account_d111a.domainid, + True, + "Domain admin not able to deploy VM for regular user in subdomain " + "in shared network with scope=Domain subdomain access") + self.verify_vsd_shared_network( + self.account_d111a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d111a.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_subdomaccess_subdomadmin( + self): + """Validate that Domain admin is able to deploy a VM for admin user in + subdomain in a shared network with scope=Domain and subdomain access + """ + + # Deploy VM as an admin user in a subdomain under a domain that has + # shared network with subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d111, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d111.name and + vm.domainid == self.account_d111.domainid, + True, + "Domain admin is not able to deploy VM for admin user in " + "subdomain in a shared network with scope=Domain subdomain access") + self.verify_vsd_shared_network( + self.account_d111.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d111.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_subdomaccess_pardomuser( + self): + """Validate that Domain admin NOT able to deploy VM for regular user in + parent domain in shared network with scope=Domain subdomain access + """ + + # Deploy VM as user in parentdomain of a domain that has shared network + # with subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_with_subdomain_d11.id, + accountid=self.account_d1a.name, + domainid=self.account_d1a.domainid + ) + self.fail( + " Domain admin is able to deploy VM for regular user in " + "parent domain in a shared network with scope=Domain " + "subdomain access") + except Exception as e: + self.debug( + "When a user from parent domain deploys a VM in a shared " + "network with scope=domain with subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for regular user in parent domain in a " + "shared network with scope=Domain and subdomain access") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_subdomaccess_pardomadmin( + self): + """Validate that Domain admin is NOT able to deploy VM for admin user + in parent domain in shared network with scope=Domain subdomain access + """ + + # Deploy VM as an admin user in parentdomain of a domain that has + # shared network with subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_with_subdomain_d11.id, + accountid=self.account_d1.name, + domainid=self.account_d1.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for admin user in parent " + "domain in a shared network with scope=Domain subdomain " + "access") + except Exception as e: + self.debug( + "When an admin user from parent domain deploys a VM in a " + "shared network with scope=domain with subdomain access %s" % + e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for admin user in parent domain in a " + "shared network with scope=Domain and subdomain access") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_subdomainaccess_ROOTuser( + self): + """Validate that Domain admin is NOT able to deploy a VM for user in + ROOT domain in a shared network with scope=Domain and subdomain access + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_with_subdomain_d11.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for user in ROOT domain " + "in a shared network with scope=Domain and subdomain access") + except Exception as e: + self.debug( + "When a user from ROOT domain deploys a VM in a shared " + "network with scope=domain with subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for user in ROOT domain in a shared " + "network with scope=Domain and subdomain access") + + # Test cases relating to deploying Virtual Machine as Domain admin for + # other users in shared network with scope=account + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_account_domainuser( + self): + """Validate that Domain admin is NOT able to deploy a VM for user in + the same domain but belonging to a different account in a shared + network with scope=account + """ + + # Deploy VM as user in a domain under the same domain but different + # account from the acount that has a shared network with scope=account + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111B"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111B"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_d111b.name, + domainid=self.account_d111b.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for user in the same " + "domain but belonging to a different account in a shared " + "network with scope=account") + except Exception as e: + self.debug( + "When a user from same domain but different account deploys a " + "VM in a shared network with scope=account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for user in the same domain but belonging " + "to a different account in a shared network with " + "scope=account") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_account_domadmin( + self): + """Validate that Domain admin is NOT able to deploy a VM for an admin + user in the same domain but belonging to a different account in a + shared network with scope=account + """ + + # Deploy VM as admin user for a domain that has an account with shared + # network with scope=account + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_d111.name, + domainid=self.account_d111.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for user in the same " + "domain but belonging to a different account in a shared " + "network with scope=account") + except Exception as e: + self.debug( + "When a user from same domain but different account deploys a " + "VM in a shared network with scope=account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for user in the same domain but belonging " + "to a different account in a shared network with " + "scope=account") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_account_user(self): + """Validate that Domain admin is able to deploy a VM for an regular + user in a shared network with scope=account + """ + + # Deploy VM as account with shared network with scope=account + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + + vm = self.create_VM(self.shared_network_account_d111a, + testdata=self.vmdata, account=self.account_d111a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d111a.name and + vm.domainid == self.account_d111a.domainid, + True, + "Domain admin is not able to deploy a VM for an regular user in a " + "shared network with scope=account") + self.verify_vsd_shared_network(self.account_d111a.domainid, + self.shared_network_account_d111a, + gateway=self.nuagenetworkdata[ + "network_account"]["gateway"]) + subnet_id = self.get_subnet_id(self.shared_network_account_d111a.id, + self.nuagenetworkdata[ + "network_account"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d111a.domainid, + self.shared_network_account_d111a, vm, + sharedsubnetid=subnet_id) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_account_diffdomain( + self): + """Validate that Domain admin is NOT able to deploy a VM for an + regular user from a different domain in a shared network with + scope=account + """ + + # Deploy VM as an admin user in a subdomain under ROOT + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD2A"]["name"] + \ + "-shared-scope-account-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD2A"]["displayname"] + \ + "-shared-scope-account-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_d2a.name, + domainid=self.account_d2a.domainid + ) + self.fail( + "Domain admin is able able to deploy a VM for an regular user " + "from a differnt domain in a shared network with " + "scope=account") + except Exception as e: + self.debug( + "When a user from different domain deploys a VM in a shared " + "network with scope=account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for an regular user from a differnt " + "domain in a shared network with scope=account") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_account_ROOTuser( + self): + """Validate that Domain admin is NOT able to deploy a VM for an regular + user in ROOT domain in a shared network with scope=account + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-account-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-account-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for an regular user in " + "ROOT domain in a shared network with scope=account") + except Exception as e: + self.debug( + "When a user from ROOT domain deploys a VM in a shared " + "network with scope=account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for an regular user in ROOT domain in a " + "shared network with scope=account") + + # Test cases relating to deploying Virtual Machine as Regular user for + # other users in shared network with scope=all + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_regularuser_scope_all_anotherusers( + self): + """Validate that regular user is NOT able to deploy a VM for + another user in the same domain in a shared network with scope=all + """ + + # Deploy VM for a user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.user_d11a_apikey + self.api_client.connection.securityKey = self.user_d11a_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-all-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-all-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_all.id, + accountid=self.account_d12a.name, + domainid=self.account_d12a.domainid + ) + self.fail( + "Regular user is allowed to deploy a VM for another user in " + "the same domain in a shared network with scope=all") + except Exception as e: + self.debug( + "When a regular user deploys a VM for another user in the " + "same domain in a shared network with scope=all %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_ACCOUNT): + self.fail( + "Error message validation failed when Regular user tries " + "to deploy a VM for another user in the same domain in a " + "shared network with scope=all") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_regularuser_scope_all_crossdomain( + self): + """Validate that regular user is NOT able to deploy a VM for + another user in a different domain in a shared network with scope=all + """ + + # Deploy VM for a user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.user_d11a_apikey + self.api_client.connection.securityKey = self.user_d11a_secretkey + self.vmdata["name"] = self.sharednetworkdata["vmD11A"][ + "name"] + "-shared-scope-all-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-all-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_all.id, + accountid=self.account_d2a.name, + domainid=self.account_d2a.domainid + ) + self.fail( + "Regular user is allowed to deploy a VM for another user in " + "the same domain in a shared network with scope=all") + except Exception as e: + self.debug( + "When a regular user deploys a VM for another user in the " + "same domain in a shared network with scope=all %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_ACCOUNT): + self.fail( + "Error message validation failed when Regular user tries " + "to deploy a VM for another user in the same domain in a " + "shared network with scope=all") + + @staticmethod + def generateKeysForUser(api_client, account): + user = User.list( + api_client, + account=account.name, + domainid=account.domainid + )[0] + + return (User.registerUserKeys( + api_client, + user.id + )) diff --git a/test/integration/plugins/nuagevsp/test_nuage_sharednetwork_deployVM.py b/test/integration/plugins/nuagevsp/test_nuage_sharednetwork_deployVM.py new file mode 100644 index 00000000000..1433cf024ad --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_sharednetwork_deployVM.py @@ -0,0 +1,2573 @@ +# 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 Shared Network functionality with Nuage VSP SDN plugin: +Deploying Virtual Machines using impersonation +(passing account and domainId parameters) +""" +# Import Local Modules +from marvin.lib.utils import cleanup_resources +from marvin.lib.base import (Account, + Domain, + User, + VirtualMachine, + Network, + NetworkOffering) +from marvin.cloudstackException import CloudstackAclException +from nuageTestCase import nuageTestCase +# Import System modules +from nose.plugins.attrib import attr +import random +import string + + +class TestNuageSharedNetworkDeployVm(nuageTestCase): + @classmethod + def setUpClass(cls): + """ + Create the following domain tree and accounts that are required for + executing Nuage VSP SDN plugin test cases for shared networks: + Under ROOT - create domain D1 + Under domain D1 - Create two subdomains D11 and D12 + Under each of the domains - create one admin user and couple of + regular users. + Create shared network with the following scope: + 1. Network with scope="all" + 2. Network with scope="domain" with no subdomain access + 3. Network with scope="domain" with subdomain access + 4. Network with scope="account" + """ + + super(TestNuageSharedNetworkDeployVm, cls).setUpClass() + cls.sharednetworkdata = cls.test_data["acl"] + cls.nuagenetworkdata = cls.test_data["nuagevsp"] + + cls.domain_1 = None + cls.domain_2 = None + + try: + # backup default apikey and secretkey + cls.default_apikey = cls.api_client.connection.apiKey + cls.default_secretkey = cls.api_client.connection.securityKey + + # Create domains + cls.domain_1 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain1"] + ) + cls.domain_11 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain11"], + parentdomainid=cls.domain_1.id + ) + cls.domain_111 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain111"], + parentdomainid=cls.domain_11.id, + ) + cls.domain_12 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain12"], + parentdomainid=cls.domain_1.id + ) + cls.domain_2 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain2"] + ) + # Create 1 admin account and 2 user accounts for doamin_1 + cls.account_d1 = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1"], + admin=True, + domainid=cls.domain_1.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d1) + cls.user_d1_apikey = user.apikey + cls.user_d1_secretkey = user.secretkey + + cls.account_d1a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1A"], + admin=False, + domainid=cls.domain_1.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d1a) + cls.user_d1a_apikey = user.apikey + cls.user_d1a_secretkey = user.secretkey + + cls.account_d1b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1B"], + admin=False, + domainid=cls.domain_1.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d1b) + cls.user_d1b_apikey = user.apikey + cls.user_d1b_secretkey = user.secretkey + + # Create 1 admin and 2 user accounts for doamin_11 + cls.account_d11 = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11"], + admin=True, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11) + cls.user_d11_apikey = user.apikey + cls.user_d11_secretkey = user.secretkey + + cls.account_d11a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11A"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11a) + cls.user_d11a_apikey = user.apikey + cls.user_d11a_secretkey = user.secretkey + + cls.account_d11b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11B"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11b) + cls.user_d11b_apikey = user.apikey + cls.user_d11b_secretkey = user.secretkey + + # Create 2 user accounts and 1 admin account for doamin_111 + + cls.account_d111 = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD111"], + admin=True, + domainid=cls.domain_111.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d111) + cls.user_d111_apikey = user.apikey + cls.user_d111_secretkey = user.secretkey + + cls.account_d111a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD111A"], + admin=False, + domainid=cls.domain_111.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d111a) + cls.user_d111a_apikey = user.apikey + cls.user_d111a_secretkey = user.secretkey + + cls.account_d111b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD111B"], + admin=False, + domainid=cls.domain_111.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d111b) + cls.user_d111b_apikey = user.apikey + cls.user_d111b_secretkey = user.secretkey + + # Create 2 user accounts for doamin_12 + cls.account_d12a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD12A"], + admin=False, + domainid=cls.domain_12.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d12a) + cls.user_d12a_apikey = user.apikey + cls.user_d12a_secretkey = user.secretkey + + cls.account_d12b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD12B"], + admin=False, + domainid=cls.domain_12.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d12b) + cls.user_d12b_apikey = user.apikey + cls.user_d12b_secretkey = user.secretkey + + # Create 1 user account for domain_2 + + cls.account_d2a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD2"], + admin=False, + domainid=cls.domain_2.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d2a) + cls.user_d2a_apikey = user.apikey + cls.user_d2a_secretkey = user.secretkey + + # Create 1 user account and admin account in "ROOT" domain + + cls.account_roota = Account.create( + cls.api_client, + cls.sharednetworkdata["accountROOTA"], + admin=False, + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_roota) + cls.user_roota_apikey = user.apikey + cls.user_roota_secretkey = user.secretkey + + cls.account_root = Account.create( + cls.api_client, + cls.sharednetworkdata["accountROOTA"], + admin=True, + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_root) + cls.user_root_apikey = user.apikey + cls.user_root_secretkey = user.secretkey + + # service offering is already created in Nuagetestcase + cls.sharednetworkdata['mode'] = cls.zone.networktype + + # As admin user , create shared network with scope "all", "domain" + # with subdomain access , "domain" without subdomain access and + # "account" + cls.api_client.connection.apiKey = cls.default_apikey + cls.api_client.connection.securityKey = cls.default_secretkey + + cls.test_data["nuagevsp"][ + "shared_nuage_network_offering"]["serviceProviderList"]\ + .update({"UserData": 'VirtualRouter'}) + cls.test_data["nuagevsp"]["shared_nuage_network_offering"][ + "supportedservices"] = 'Dhcp,Connectivity,UserData' + for key, value in cls.test_data["nuagevsp"][ + "shared_nuage_network_offering"]["serviceProviderList"]\ + .iteritems(): + cls.debug("elements are %s and value is %s" % (key, value)) + + cls.shared_network_offering = NetworkOffering.create( + cls.api_client, + cls.test_data["nuagevsp"]["shared_nuage_network_offering"], + conservemode=False + ) + # Enable Network offering + cls.shared_network_offering.update(cls.api_client, state='Enabled') + cls.shared_network_offering_id = cls.shared_network_offering.id + + cls.shared_network_all = Network.create( + cls.api_client, + cls.test_data["nuagevsp"]["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id + ) + + cls.shared_network_domain_d11 = Network.create( + cls.api_client, + cls.test_data["nuagevsp"][ + "network_domain_with_no_subdomain_access"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + subdomainaccess=False + ) + + cls.shared_network_domain_with_subdomain_d11 = Network.create( + cls.api_client, + cls.test_data["nuagevsp"][ + "network_domain_with_subdomain_access"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + subdomainaccess=True + ) + + cls.shared_network_account_d111a = Network.create( + cls.api_client, + cls.test_data["nuagevsp"]["network_account"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_111.id, + accountid=cls.account_d111a.user[0].username + ) + cls.vmdata = {"name": "test", + "displayname": "test" + } + + cls._cleanup = [ + cls.account_root, + cls.account_roota, + cls.shared_network_all, + cls.shared_network_offering, + cls.service_offering, + ] + user_data = ''.join(random.choice( + string.ascii_uppercase + string.digits) for x in range(2500)) + cls.vmdata["userdata"] = user_data + except Exception as e: + cls.domain_1.delete(cls.api_client, cleanup="true") + cls.domain_2.delete(cls.api_client, cleanup="true") + cleanup_resources(cls.api_client, cls._cleanup) + raise Exception( + "Failed to create the setup required to execute the test " + "cases: %s" % e) + + return + + @classmethod + def tearDownClass(cls): + + cls.api_client.connection.apiKey = cls.default_apikey + cls.api_client.connection.securityKey = cls.default_secretkey + cls.domain_1.delete(cls.api_client, cleanup="true") + cls.domain_2.delete(cls.api_client, cleanup="true") + cleanup_resources(cls.api_client, cls._cleanup) + return + + def setUp(self): + self.api_client = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + + def tearDown(self): + # restore back default apikey and secretkey + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + return + + # Test cases relating to deploying Virtual Machine as ROOT admin for other + # users in shared network with scope=all + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_all_domainuser(self): + """Validate that ROOT admin is able to deploy a VM for other users in a + shared network with scope=all + """ + + # Deploy VM for a user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1A"]["name"] + \ + "-shared-scope-all-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1A"]["displayname"] + \ + "-shared-scope-all-root-admin" + + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d1a, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d1a.name and + vm.domainid == self.account_d1a.domainid, + True, + "ROOT admin is not able to deploy a VM for other users in a " + "shared network with scope=all") + subnet_id = self.get_subnet_id(self.shared_network_all.id, + self.nuagenetworkdata["network_all"][ + "gateway"]) + self.verify_vsd_enterprise_vm(self.account_d1a.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_all_domainadminuser( + self): + """Validate that ROOT admin is able to deploy a VM for a domain admin + users in a shared network with scope=all + """ + + # Deploy VM for an admin user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1"]["name"] + \ + "-shared-scope-all-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1"]["displayname"] + \ + "-shared-scope-all-root-admin" + + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d1, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d1.name and + vm.domainid == self.account_d1.domainid, + True, + "ROOT admin is not able to deploy a VM " + "for a domain admin users in a shared network with scope=all") + + self.verify_vsd_shared_network( + self.account_d1.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d1.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_all_subdomainuser(self): + """Validate that ROOT admin is able to deploy a VM for any user in a + subdomain in a shared network with scope=all + """ + + # Deploy VM as user in a subdomain under ROOT + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-all-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-all-root-admin" + + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d11a, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11a.name and + vm.domainid == self.account_d11a.domainid, + True, + "ROOT admin is not able to deploy a VM" + " for any user in a subdomain in a shared network with scope=all") + + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_all_subdomainadminuser( + self): + """Validate that ROOT admin is able to deploy a VM for admin user in a + domain in a shared network with scope=all + """ + + # Deploy VM as an admin user in a subdomain under ROOT + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11"]["name"] + \ + "-shared-scope-all-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11"]["displayname"] + \ + "-shared-scope-all-root-admin" + + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d11, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11.name and + vm.domainid == self.account_d11.domainid, + True, + "ROOT admin is not able to deploy a VM for admin user in a domain " + "in a shared network with scope=all") + self.verify_vsd_shared_network( + self.account_d11.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_all_ROOTuser(self): + """Validate that ROOT admin is able to deploy a VM for user in ROOT + domain in a shared network with scope=all + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-all-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-all-root-admin" + + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_roota, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_roota.name and + vm.domainid == self.account_roota.domainid, + True, + "ROOT admin is not able to deploy a VM for user in ROOT domain in " + "a shared network with scope=all") + self.verify_vsd_shared_network( + self.account_roota.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_roota.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + # Test cases relating to deploying Virtual Machine as ROOT admin for other + # users in shared network with scope=Domain and no subdomain access + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_nosubdomccess_domainuser(self): + """Validate that ROOT admin is able to deploy a VM for domain user in + a shared network with scope=domain with no subdomain access + """ + + # Deploy VM as user in a domain that has shared network with no + # subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + + vm = self.create_VM(self.shared_network_domain_d11, + testdata=self.vmdata, account=self.account_d11a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11a.name and + vm.domainid == self.account_d11a.domainid, + True, + "ROOT admin is not able to deploy a VM for domain user in a " + "shared network with scope=domain with no subdomain access") + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_domain_d11, vm, + sharedsubnetid=subnet_id) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_nosubdomccess_domainadminuser( + self): + """Validate that ROOT admin is able to deploy a VM for domain admin + user in a shared network with scope=domain with no subdomain access + """ + + # Deploy VM as an admin user in a domain that has shared network with + # no subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + + vm = self.create_VM(self.shared_network_domain_d11, + testdata=self.vmdata, account=self.account_d11, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11.name and + vm.domainid == self.account_d11.domainid, + True, + "ROOT admin is not able to deploy VM for domain admin user in " + "shared network with scope=domain with no subdomain access") + self.verify_vsd_shared_network( + self.account_d11.domainid, + self.shared_network_domain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11.domainid, + self.shared_network_domain_d11, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_nosubdomccess_subdomainuser( + self): + """Validate that ROOT admin is NOT able to deploy a VM for sub domain + user in a shared network with scope=domain with no subdomain access + """ + + # Deploy VM as user in a subdomain under a domain that has shared + # network with no subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111A"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111A"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d111a.name, + domainid=self.account_d111a.domainid + ) + self.fail( + "ROOT admin is able to deploy a VM for sub domain user in a " + "shared network with scope=domain with no subdomain access") + + except Exception as e: + self.debug( + "When a user from a subdomain deploys a VM in a shared " + "network with scope=domain with no subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for sub domain user in a shared network with " + "scope=domain with no subdomain access ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_nosubdomccess_subdomainadmin( + self): + """Validate that ROOT admin is NOT able to deploy a VM for sub domain + admin user in a shared network with scope=domain with no subdomain + access + """ + + # Deploy VM as an admin user in a subdomain under a domain that has + # shared network with no subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d111.name, + domainid=self.account_d111.domainid + ) + self.fail( + "ROOT admin is able to deploy VM for sub domain admin user in " + "a shared network with scope=domain with no subdomain access") + except Exception as e: + self.debug( + "When a admin user from a subdomain deploys a VM in a shared " + "network with scope=domain with no subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for sub domain admin user in a shared " + "network with scope=domain with no subdomain access") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_nosubdomccess_parentdomainuser( + self): + """Validate that ROOT admin is NOT able to deploy a VM for parent + domain user in a shared network with scope=domain with no subdomain + access + """ + + # Deploy VM as user in parentdomain of a domain that has shared network + # with no subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1A"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1A"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d1a.name, + domainid=self.account_d1a.domainid + ) + self.fail( + " ROOT admin is able to deploy a VM for parent domain user in " + "a shared network with scope=domain with no subdomain access") + except Exception as e: + self.debug( + "When a user from parent domain deploys a VM in a shared " + "network with scope=domain with no subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries " + "to deploy a VM for parent domain user in a shared " + "network with scope=domain with no subdomain access") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_nosubdomccess_parentdomadmin( + self): + """Validate that ROOT admin is NOT able to deploy a VM for parent + domain admin user in a shared network with scope=domain with no + subdomain access + """ + + # Deploy VM as an admin user in parentdomain of a domain that has + # shared network with no subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d1.name, + domainid=self.account_d1.domainid + ) + self.fail( + "ROOT admin is able to deploy a VM for parent domain admin " + "user in a shared network with scope=domain with no subdomain " + "access") + except Exception as e: + self.debug( + "When an admin user from parent domain deploys a VM in a " + "shared network with scope=domain with no subdomain access %s" + % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for parent domain " + "admin user in a shared network with scope=domain with no " + "subdomain access ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_nosubdomccess_ROOTuser( + self): + """Validate that ROOT admin is NOT able to deploy a VM for parent + domain admin user in a shared network with scope=domain with no + subdomain access + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + self.fail( + "ROOT admin is able to deploy a VM for parent domain admin " + "user in a shared network with scope=domain with no subdomain " + "access") + except Exception as e: + self.debug( + "When a regular user from ROOT domain deploys a VM in a " + "shared network with scope=domain with no subdomain access %s" + % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for parent domain admin user in a shared " + "network with scope=domain with no subdomain access") + + # Test cases relating to deploying Virtual Machine as ROOT admin for other + # users in shared network with scope=Domain and with subdomain access + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_subdomaccess_domainuser(self): + """Validate that ROOT admin is able to deploy a VM for domain user in a + shared network with scope=domain with subdomain access + """ + + # Deploy VM as user in a domain that has shared network with subdomain + # access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d11a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11a.name and + vm.domainid == self.account_d11a.domainid, + True, + "ROOT admin is NOT able to deploy a VM for domain user in a " + "shared network with scope=domain with subdomain access") + + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_subdomaccess_domainadminuser( + self): + """Validate that ROOT admin is able to deploy a VM for domain admin + user in a shared network with scope=domain with subdomain access + """ + + # Deploy VM as an admin user in a domain that has shared network with + # subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d11, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11.name and + vm.domainid == self.account_d11.domainid, + True, + "ROOT admin is not able to deploy a VM for domain admin user in a " + "shared network with scope=domain with subdomain access") + + self.verify_vsd_shared_network( + self.account_d11.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_subdomaccess_subdomainuser( + self): + """Validate that ROOT admin is able to deploy a VM for subdomain user + in a shared network with scope=domain with subdomain access + """ + + # Deploy VM as user in a subdomain under a domain that has shared + # network with subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d111a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d111a.name and + vm.domainid == self.account_d111a.domainid, + True, + "ROOT admin is not able to deploy a VM for subdomain user in a " + "shared network with scope=domain with subdomain access") + + self.verify_vsd_shared_network( + self.account_d111a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d111a.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_subdomaccess_subdomainadmin( + self): + """Validate that ROOT admin is able to deploy a VM for subdomain admin + user in a shared network with scope=domain with subdomain access + """ + + # Deploy VM as an admin user in a subdomain under a domain that has + # shared network with subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d111, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d111.name and + vm.domainid == self.account_d111.domainid, + True, + "ROOT admin is not able to deploy VM for subdomain admin user in " + "a shared network with scope=domain subdomain access") + + self.verify_vsd_shared_network( + self.account_d111.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d111.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_subdomaccess_parentdomainuser( + self): + """Validate that ROOT admin is NOT able to deploy a VM for parent + domain user in a shared network with scope=domain with subdomain access + """ + + # Deploy VM as user in parentdomain of a domain that has shared network + # with subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_with_subdomain_d11.id, + accountid=self.account_d1a.name, + domainid=self.account_d1a.domainid + ) + self.fail( + "ROOT admin is NOT able to deploy a VM for parent domain user " + "in a shared network with scope=domain with subdomain access") + except Exception as e: + self.debug( + "When a user from parent domain deploys a VM in a shared " + "network with scope=domain with subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for parent domain user in a shared network " + "with scope=domain with subdomain access ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_subdomaccess_parentdomainadmin( + self): + """Validate that ROOT admin is NOT able to deploy a VM for parent + domain admin user in a shared network with scope=domain with subdomain + access + """ + + # Deploy VM as an admin user in parentdomain of a domain that has + # shared network with subdomain access + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_with_subdomain_d11.id, + accountid=self.account_d1.name, + domainid=self.account_d1.domainid + ) + self.fail( + "ROOT admin is able to deploy VM for parent domain admin user " + "in a shared network with scope=domain subdomain access ") + except Exception as e: + self.debug( + "When an admin user from parent domain deploys a VM in a " + "shared network with scope=domain with subdomain access %s" + % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for parent domain admin user in a shared " + "network with scope=domain with subdomain access ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_subdomaccess_ROOTuser(self): + """Validate that ROOT admin is NOT able to deploy a VM for user in ROOT + domain in a shared network with scope=domain with subdomain access + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.user_roota_apikey + self.api_client.connection.securityKey = self.user_roota_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_with_subdomain_d11.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + self.fail( + "ROOT admin is able to deploy a VM for user in ROOT domain in " + "a shared network with scope=domain with subdomain access") + except Exception as e: + self.debug( + "When a user from ROOT domain deploys a VM in a shared " + "network with scope=domain with subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for user in ROOT domain in a shared network " + "with scope=domain with subdomain access") + + # Test cases relating to deploying Virtual Machine as ROOT admin for other + # users in shared network with scope=account + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_account_domainuser(self): + """ + Valiate that ROOT admin is NOT able to deploy a VM for user in the same + domain but in a different account in a shared network with + scope=account + """ + + # Deploy VM as user in a domain under the same domain but different + # account from the account that has a shared network with scope=account + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111B"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111B"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_d111b.name, + domainid=self.account_d111b.domainid + ) + self.fail( + "ROOT admin is able to deploy VM for user in the same domain " + "but in different account in shared network scope=account") + except Exception as e: + self.debug( + "When a user from same domain but different account deploys " + "a VM in a shared network with scope=account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for user in the same domain but in a " + "different account in a shared network with scope=account") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_account_domainadminuser( + self): + """Validate that ROOT admin is NOT able to deploy a VM for admin user + in the same domain but in a different account in a shared network with + scope=account + """ + + # Deploy VM as admin user for a domain that has an account with shared + # network with scope=account + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_d111.name, + domainid=self.account_d111.domainid + ) + self.fail( + "ROOT admin is able to deploy VM for admin user in same " + "domain but in different account in shared network with " + "scope=account") + except Exception as e: + self.debug( + "When a user from same domain but different account deploys a " + "VM in a shared network with scope=account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for admin user in the same domain but in a " + "different account in a shared network with scope=account") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_account_user(self): + """Validate that ROOT admin is able to deploy a VM for regular user in + a shared network with scope=account + """ + + # Deploy VM as account with shared network with scope=account + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-root-admin" + + vm = self.create_VM(self.shared_network_account_d111a, + testdata=self.vmdata, account=self.account_d111a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d111a.name and + vm.domainid == self.account_d111a.domainid, + True, + "ROOT admin is not able to deploy a VM for regular user in a " + "shared network with scope=account") + + self.verify_vsd_shared_network(self.account_d111a.domainid, + self.shared_network_account_d111a, + gateway=self.nuagenetworkdata[ + "network_account"]["gateway"]) + subnet_id = self.get_subnet_id(self.shared_network_account_d111a.id, + self.nuagenetworkdata[ + "network_account"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d111a.domainid, + self.shared_network_account_d111a, vm, + sharedsubnetid=subnet_id) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_account_differentdomain( + self): + """Validate that ROOT admin is NOT able to deploy a VM for a admin user + in a shared network with scope=account which the admin user does not + have access to + """ + + # Deploy VM as an admin user in a subdomain under ROOT + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD2A"]["name"] + \ + "-shared-scope-account-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD2A"]["displayname"] + \ + "-shared-scope-account-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_d2a.name, + domainid=self.account_d2a.domainid + ) + self.fail( + "ROOT admin is able to deploy VM for admin user in shared " + "network scope=account which admin user does not have access") + except Exception as e: + self.debug("account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for a admin user in a shared network with " + "scope=account which the admin user does not have access " + "to ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_admin_scope_account_ROOTuser(self): + """Validate that ROOT admin is NOT able to deploy a VM for a user in + ROOT domain in a shared network with scope=account which the user does + not have access to + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-account-root-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-account-root-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + self.fail( + "ROOT admin is able to deploy VM for a user in ROOT domain in " + "shared network scope=account which user does not have access") + except Exception as e: + self.debug( + "When a user from ROOT domain deploys a VM in a shared " + "network with scope=account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail( + "Error message validation failed when ROOT admin tries to " + "deploy a VM for a user in ROOT domain in a shared " + "network with scope=account which the user does not have " + "access to ") + + # Test cases relating to deploying Virtual Machine as Domain admin for + # other users in shared network with scope=all + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_all_domainuser( + self): + """Validate that Domain admin is able to deploy a VM for a domain user + in a shared network with scope=all + """ + + # Deploy VM for a user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1A"]["name"] + \ + "-shared-scope-all-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1A"]["displayname"] + \ + "-shared-scope-all-domain-admin" + + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d1a, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d1a.name and + vm.domainid == self.account_d1a.domainid, + True, + "Domain admin is not able to deploy a VM for a domain user in a " + "shared network with scope=all") + + self.verify_vsd_shared_network( + self.account_d1a.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id(self.shared_network_all.id, + self.nuagenetworkdata["network_all"][ + "gateway"]) + self.verify_vsd_enterprise_vm(self.account_d1a.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_all_domainadmin( + self): + """Validate that Domain admin is able to deploy a VM for a domain admin + user in a shared network with scope=all + """ + + # Deploy VM for an admin user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1"]["name"] + \ + "-shared-scope-all-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1"]["displayname"] + \ + "-shared-scope-all-domain-admin" + + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d1, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d1.name and + vm.domainid == self.account_d1.domainid, + True, + "Domain admin is not able to deploy a VM for a domain admin user " + "in a shared network with scope=all") + + self.verify_vsd_shared_network( + self.account_d1.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d1.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_all_subdomainuser( + self): + """Validate that Domain admin is able to deploy a VM for a sub domain + user in a shared network with scope=all + """ + + # Deploy VM as user in a subdomain under ROOT + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-all-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-all-domain-admin" + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d11a, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11a.name and + vm.domainid == self.account_d11a.domainid, + True, + "Domain admin is not able to deploy a VM for a sub domain user in " + "a shared network with scope=all") + + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_all_subdomainadmin( + self): + """Validate that Domain admin is able to deploy a VM for a sub domain + admin user in a shared network with scope=all + """ + + # Deploy VM as an admin user in a subdomain under ROOT + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11"]["name"] + \ + "-shared-scope-all-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11"]["displayname"] + \ + "-shared-scope-all-domain-admin" + vm = self.create_VM(self.shared_network_all, testdata=self.vmdata, + account=self.account_d11, cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11.name and + vm.domainid == self.account_d11.domainid, + True, + "Domain admin is not able to deploy a VM for a sub domain admin " + "user in a shared network with scope=all") + + self.verify_vsd_shared_network( + self.account_d11.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11.domainid, + self.shared_network_all, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_all_ROOTuser(self): + """Validate that Domain admin is NOT able to deploy a VM for user in + ROOT domain in a shared network with scope=all + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-all" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-all" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_all.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + self.fail( + "Domain admin is NOT able to deploy a VM for user in ROOT " + "domain in a shared network with scope=all") + except Exception as e: + self.debug( + "When a Domain admin user deploys a VM for ROOT user in a " + "shared network with scope=all %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail( + "Error message validation failed when Domain admin is NOT " + "able to deploy a VM for user in ROOT domain in a shared " + "network with scope=all") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_all_crossdomuser( + self): + """Validate that Domain admin is NOT able to deploy a VM for user in + other domain in a shared network with scope=all + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-all" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-all" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_all.id, + accountid=self.account_d2a.name, + domainid=self.account_d2a.domainid + ) + self.fail( + "Domain admin user is able to Deploy VM for a domain user he " + "does not have access to in a shared network with " + "scope=domain with no subdomain access ") + except Exception as e: + self.debug( + "When a Domain admin user deploys a VM for a domain user he " + "does not have access to in a shared network with " + "scope=domain with no subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail( + "Error mesage validation failed when Domain admin user " + "tries to Deploy VM for a domain user he does not have " + "access to in a shared network with scope=domain with no " + "subdomain access ") + + # Test cases relating to deploying Virtual Machine as Domain admin for + # other users in shared network with scope=Domain and no subdomain access + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_nosubdomaccess_domuser( + self): + """Validate that Domain admin is able to deploy a VM for domain user in + a shared network with scope=Domain and no subdomain access + """ + + # Deploy VM as user in a domain that has shared network with no + # subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + + vm = self.create_VM(self.shared_network_domain_d11, + testdata=self.vmdata, account=self.account_d11a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11a.name and + vm.domainid == self.account_d11a.domainid, + True, + "Domain admin is not able to deploy a VM for domain user in a " + "shared network with scope=Domain and no subdomain access") + + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_domain_d11, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_nosubdomaccess_domadmin( + self): + """Validate that Domain admin is able to deploy a VM for domain admin + user in a shared network with scope=Domain and no subdomain access + """ + + # Deploy VM as an admin user in a domain that has shared network with + # no subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + vm = self.create_VM(self.shared_network_domain_d11, + testdata=self.vmdata, account=self.account_d11, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11.name and + vm.domainid == self.account_d11.domainid, + True, + "Admin User in a domain that has a shared network with no " + "subdomain access failed to Deploy VM in a shared network with " + "scope=domain with no subdomain access") + self.verify_vsd_shared_network( + self.account_d11.domainid, + self.shared_network_domain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11.domainid, + self.shared_network_domain_d11, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_nosubdomaccess_subdomain( + self): + """Validate that Domain admin is NOT able to deploy a VM for sub domain + user in a shared network with scope=Domain and no subdomain access + """ + + # Deploy VM as user in a subdomain under a domain that has shared + # network with no subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111A"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111A"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d111a.name, + domainid=self.account_d111a.domainid + ) + self.fail( + "Domain admin is able to deploy VM for sub domain user in a " + "shared network with scope=Domain and no subdomain access") + except Exception as e: + self.debug( + "When a user from a subdomain deploys a VM in a shared " + "network with scope=domain with no subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for sub domain user in a shared network " + "with scope=Domain and no subdomain access") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_nosubdomaccess_subdomadm( + self): + """Validate that Domain admin is NOT able to deploy a VM for sub domain + admin user in a shared network with scope=Domain and no subdomain + access + """ + + # Deploy VM as an admin user in a subdomain under a domain that has + # shared network with no subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d111.name, + domainid=self.account_d111.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for sub domain admin " + "user in a shared network with scope=Domain no subdomain " + "access") + except Exception as e: + self.debug( + "When a admin user from a subdomain deploys a VM in a shared " + "network with scope=domain with no subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for sub domain admin user in a shared " + "network with scope=Domain and no subdomain access ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_nosubdomaccess_parentdom( + self): + """Validate that Domain admin is NOT able to deploy a VM for parent + domain user in a shared network with scope=Domain and no subdomain + access + """ + + # Deploy VM as user in parentdomain of a domain that has shared network + # with no subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1A"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1A"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d1a.name, + domainid=self.account_d1a.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for parent domain user " + "in a shared network with scope=Domain and no subdomain " + "access") + except Exception as e: + self.debug( + "When a user from parent domain deploys a VM in a shared " + "network with scope=domain with no subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for parent domain user in a shared " + "network with scope=Domain and no subdomain access ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_nosubdomaccess_pardomadm( + self): + """Validate that Domain admin is NOT able to deploy VM for parent + domain admin user in shared network with scope=Domain and no subdomain + access + """ + + # Deploy VM as an admin user in parentdomain of a domain that has + # shared network with no subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_d1.name, + domainid=self.account_d1.domainid + ) + self.fail( + "Domain admin is able to deploy VM for parent domain admin " + "user in a shared network with scope=Domain no subdomain " + "access") + except Exception as e: + self.debug( + "When an admin user from parent domain deploys a VM in a " + "shared network with scope=domain with no subdomain access %s" + % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for parent domain admin user in a shared " + "network with scope=Domain and no subdomain access ") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_nosubdomaccess_ROOTuser( + self): + """Validate that Domain admin is NOT able to deploy a VM for user in + ROOT domain in a shared network with scope=Domain and no subdomain + access + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-domain-nosubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_d11.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for user in ROOT domain " + "in a shared network with scope=Domain and no subdomain " + "access") + except Exception as e: + self.debug( + "When a regular user from ROOT domain deploys a VM in a " + "shared network with scope=domain with no subdomain access %s" + % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for user in ROOT domain in a shared " + "network with scope=Domain and no subdomain access") + + # Test cases relating to deploying Virtual Machine as Domain admin for + # other users in shared network with scope=Domain and with subdomain access + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_subdomaccess_domainuser( + self): + """Validate that Domain admin is able to deploy a VM for regular user + in domain in a shared network with scope=Domain and subdomain access + """ + + # Deploy VM as user in a domain that has shared network with subdomain + # access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d11a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11a.name and + vm.domainid == self.account_d11a.domainid, + True, + "Domain admin is not able to deploy VM for regular user in domain " + "in a shared network with scope=Domain subdomain access") + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_subdomaccess_domainadmin( + self): + """Validate that Domain admin is able to deploy a VM for admin user in + domain in a shared network with scope=Domain and subdomain access + """ + + # Deploy VM as an admin user in a domain that has shared network with + # subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d11, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d11.name and + vm.domainid == self.account_d11.domainid, + True, + "Domain admin is not able to deploy a VM for admin user in " + "domain in a shared network with scope=Domain subdomain access") + self.verify_vsd_shared_network( + self.account_d11.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_subdomaccess_subdomain( + self): + """Validate that Domain admin is able to deploy a VM for regular user + in subdomain in a shared network with scope=Domain and subdomain access + """ + + # Deploy VM as user in a subdomain under a domain that has shared + # network with subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d111a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d111a.name and + vm.domainid == self.account_d111a.domainid, + True, + "Domain admin not able to deploy VM for regular user in subdomain " + "in shared network with scope=Domain subdomain access") + self.verify_vsd_shared_network( + self.account_d111a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d111a.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_subdomaccess_subdomadm( + self): + """Validate that Domain admin is able to deploy a VM for admin user in + subdomain in a shared network with scope=Domain and subdomain access + """ + + # Deploy VM as an admin user in a subdomain under a domain that has + # shared network with subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + + vm = self.create_VM(self.shared_network_domain_with_subdomain_d11, + testdata=self.vmdata, account=self.account_d111, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d111.name and + vm.domainid == self.account_d111.domainid, + True, + "Domain admin is not able to deploy VM for admin user in " + "subdomain in a shared network with scope=Domain subdomain access") + self.verify_vsd_shared_network( + self.account_d111.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d111.domainid, + self.shared_network_domain_with_subdomain_d11, + vm, sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_subdomaccess_parentdom( + self): + """Validate that Domain admin NOT able to deploy VM for regular user in + parent domain in shared network with scope=Domain subdomain access + """ + + # Deploy VM as user in parentdomain of a domain that has shared network + # with subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_with_subdomain_d11.id, + accountid=self.account_d1a.name, + domainid=self.account_d1a.domainid + ) + self.fail( + " Domain admin is able to deploy VM for regular user in " + "parent domain in a shared network with scope=Domain " + "subdomain access") + except Exception as e: + self.debug( + "When a user from parent domain deploys a VM in a shared " + "network with scope=domain with subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for regular user in parent domain in a " + "shared network with scope=Domain and subdomain access") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_subdomaccess_pardomadmin( + self): + """Validate that Domain admin is NOT able to deploy VM for admin user + in parent domain in shared network with scope=Domain subdomain access + """ + + # Deploy VM as an admin user in parentdomain of a domain that has + # shared network with subdomain access + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD1"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD1"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_with_subdomain_d11.id, + accountid=self.account_d1.name, + domainid=self.account_d1.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for admin user in parent " + "domain in a shared network with scope=Domain subdomain " + "access") + except Exception as e: + self.debug( + "When an admin user from parent domain deploys a VM in a " + "shared network with scope=domain with subdomain access %s" + % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NOT_AVAILABLE_IN_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for admin user in parent domain in a " + "shared network with scope=Domain and subdomain access") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_subdomaccess_ROOTuser( + self): + """Validate that Domain admin is NOT able to deploy a VM for user in + ROOT domain in a shared network with scope=Domain and subdomain access + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_domain_with_subdomain_d11.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for user in ROOT domain " + "in a shared network with scope=Domain and subdomain access") + except Exception as e: + self.debug( + "When a user from ROOT domain deploys a VM in a shared " + "network with scope=domain with subdomain access %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for user in ROOT domain in a shared " + "network with scope=Domain and subdomain access") + + # Test cases relating to deploying Virtual Machine as Domain admin for + # other users in shared network with scope=account + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_account_domainuser( + self): + """Validate that Domain admin is NOT able to deploy a VM for user in + the same domain but belonging to a different account in a shared + network with scope=account + """ + + # Deploy VM as user in a domain under the same domain but different + # account from the acount that has a shared network with scope=account + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111B"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111B"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_d111b.name, + domainid=self.account_d111b.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for user in the same " + "domain but belonging to a different account in a shared " + "network with scope=account") + except Exception as e: + self.debug( + "When a user from same domain but different account deploys " + "a VM in a shared network with scope=account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for user in the same domain but belonging " + "to a different account in a shared network with " + "scope=account") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_account_domainadm( + self): + """Validate that Domain admin is NOT able to deploy a VM for an admin + user in the same domain but belonging to a different account in a + shared network with scope=account + """ + + # Deploy VM as admin user for a domain that has an account with shared + # network with scope=account + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_d111.name, + domainid=self.account_d111.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for user in the same " + "domain but belonging to a different account in a shared " + "network with scope=account") + except Exception as e: + self.debug( + "When a user from same domain but different account deploys a " + "VM in a shared network with scope=account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.UNABLE_TO_USE_NETWORK): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for user in the same domain but belonging " + "to a different account in a shared network with " + "scope=account") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_account_user(self): + """Validate that Domain admin is able to deploy a VM for an regular + user in a shared network with scope=account + """ + + # Deploy VM as account with shared network with scope=account + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD111A"]["name"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD111A"]["displayname"] + \ + "-shared-scope-domain-withsubdomainaccess-domain-admin" + + vm = self.create_VM(self.shared_network_account_d111a, + testdata=self.vmdata, account=self.account_d111a, + cleanup=False) + + self.assertEqual( + vm.state == "Running" and vm.account == self.account_d111a.name and + vm.domainid == self.account_d111a.domainid, + True, + "Domain admin is not able to deploy a VM for an regular user in " + "a shared network with scope=account") + self.verify_vsd_shared_network(self.account_d111a.domainid, + self.shared_network_account_d111a, + gateway=self.nuagenetworkdata[ + "network_account"]["gateway"]) + subnet_id = self.get_subnet_id(self.shared_network_account_d111a.id, + self.nuagenetworkdata[ + "network_account"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d111a.domainid, + self.shared_network_account_d111a, vm, + sharedsubnetid=subnet_id) + + # Deleting the VM + vm.delete(self.api_client, expunge=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_account_diffdom( + self): + """Validate that Domain admin is NOT able to deploy a VM for an + regular user from a differnt domain in a shared network with + scope=account + """ + + # Deploy VM as an admin user in a subdomain under ROOT + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD2A"]["name"] + \ + "-shared-scope-account-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD2A"]["displayname"] + \ + "-shared-scope-account-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_d2a.name, + domainid=self.account_d2a.domainid + ) + self.fail( + "Domain admin is able able to deploy a VM for an regular " + "user from a differnt domain in a shared network with " + "scope=account") + except Exception as e: + self.debug( + "When a user from different domain deploys a VM in a shared " + "network with scope=account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for an regular user from a differnt " + "domain in a shared network with scope=account") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_domainadmin_scope_account_ROOTuser( + self): + """Validate that Domain admin is NOT able to deploy a VM for an regular + user in ROOT domain in a shared network with scope=account + """ + + # Deploy VM as user in ROOT domain + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmROOTA"]["name"] + \ + "-shared-scope-account-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmROOTA"]["displayname"] + \ + "-shared-scope-account-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_account_d111a.id, + accountid=self.account_roota.name, + domainid=self.account_roota.domainid + ) + self.fail( + "Domain admin is able to deploy a VM for an regular user in " + "ROOT domain in a shared network with scope=account") + except Exception as e: + self.debug( + "When a user from ROOT domain deploys a VM in a shared " + "network with scope=account %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_DOMAIN): + self.fail( + "Error message validation failed when Domain admin tries " + "to deploy a VM for an regular user in ROOT domain in a " + "shared network with scope=account") + + # Test cases relating to deploying Virtual Machine as Regular user for + # other users in shared network with scope=all + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_regularuser_scope_all_anotheruser( + self): + """Validate that regular user is NOT able to deploy a VM for + another user in the same domain in a shared network with scope=all + """ + + # Deploy VM for a user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.user_d11a_apikey + self.api_client.connection.securityKey = self.user_d11a_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-all-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-all-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_all.id, + accountid=self.account_d12a.name, + domainid=self.account_d12a.domainid + ) + self.fail( + "Regular user is allowed to deploy a VM for another user in " + "the same domain in a shared network with scope=all") + except Exception as e: + self.debug( + "When a regular user deploys a VM for another user in the " + "same domain in a shared network with scope=all %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_ACCOUNT): + self.fail( + "Error message validation failed when Regular user tries " + "to deploy a VM for another user in the same domain in a " + "shared network with scope=all") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_deployVM_in_sharedNetwork_as_regularuser_scope_all_crossdomain( + self): + """Validate that regular user is NOT able to deploy a VM for + another user in a different domain in a shared network with scope=all + """ + + # Deploy VM for a user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.user_d11a_apikey + self.api_client.connection.securityKey = self.user_d11a_secretkey + self.vmdata["name"] = \ + self.sharednetworkdata["vmD11A"]["name"] + \ + "-shared-scope-all-domain-admin" + self.vmdata["displayname"] = \ + self.sharednetworkdata["vmD11A"]["displayname"] + \ + "-shared-scope-all-domain-admin" + try: + VirtualMachine.create( + self.api_client, + self.vmdata, + zoneid=self.zone.id, + serviceofferingid=self.service_offering.id, + templateid=self.template.id, + networkids=self.shared_network_all.id, + accountid=self.account_d2a.name, + domainid=self.account_d2a.domainid + ) + self.fail( + "Regular user is allowed to deploy a VM for another user in " + "the same domain in a shared network with scope=all") + except Exception as e: + self.debug( + "When a regular user deploys a VM for another user in the " + "same domain in a shared network with scope=all %s" % e) + if not CloudstackAclException.verifyMsginException( + e, + CloudstackAclException.NO_PERMISSION_TO_OPERATE_ACCOUNT): + self.fail( + "Error message validation failed when Regular user tries " + "to deploy a VM for another user in the same domain in a " + "shared network with scope=all") + + @staticmethod + def generateKeysForUser(api_client, account): + user = User.list( + api_client, + account=account.name, + domainid=account.domainid + )[0] + + return (User.registerUserKeys( + api_client, + user.id + )) diff --git a/test/integration/plugins/nuagevsp/test_nuage_sharednetwork_vpc_vm_monitor.py b/test/integration/plugins/nuagevsp/test_nuage_sharednetwork_vpc_vm_monitor.py new file mode 100644 index 00000000000..d8ca41ff100 --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_sharednetwork_vpc_vm_monitor.py @@ -0,0 +1,704 @@ +# 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 Shared Network functionality with Nuage VSP SDN plugin: +VPC Virtual Machine Monitoring +""" +# Import Local Modules +from nuageTestCase import nuageTestCase +from marvin.lib.utils import cleanup_resources, validateList +from marvin.lib.base import (VPC, + Account, + Domain, + User, + VirtualMachine, + Network, + NetworkOffering, + VpcOffering) +from marvin.lib.common import list_virtual_machines +from marvin.codes import PASS +# Import System modules +from nose.plugins.attrib import attr + + +class TestNuageSharedNetworkVpcVmMonitor(nuageTestCase): + @classmethod + def setUpClass(cls): + """ + Create the following domain tree and accounts that are required for + executing Nuage VSP SDN plugin test cases for shared networks: + Under ROOT - create domain D1 + Under domain D1 - Create two subdomains D11 and D12 + Under each of the domains - create one admin user and couple of + regular users. + Create shared network with the following scope: + 1. Network with scope="all" + 2. Network with scope="domain" with no subdomain access + 3. Network with scope="domain" with subdomain access + 4. Network with scope="account" + """ + + super(TestNuageSharedNetworkVpcVmMonitor, cls).setUpClass() + cls.sharednetworkdata = cls.test_data["acl"] + cls.nuagenetworkdata = cls.test_data["nuagevsp"] + + cls.domain_1 = None + cls.domain_2 = None + + try: + # backup default apikey and secretkey + cls.default_apikey = cls.api_client.connection.apiKey + cls.default_secretkey = cls.api_client.connection.securityKey + + # Create domains + cls.domain_1 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain1"] + ) + cls.domain_11 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain11"], + parentdomainid=cls.domain_1.id + ) + cls.domain_12 = Domain.create( + cls.api_client, + cls.sharednetworkdata["domain12"], + parentdomainid=cls.domain_1.id + ) + # Create 1 admin account and 2 user accounts for doamin_1 + cls.account_d1 = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1"], + admin=True, + domainid=cls.domain_1.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d1) + cls.user_d1_apikey = user.apikey + cls.user_d1_secretkey = user.secretkey + + cls.account_d1a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1A"], + admin=False, + domainid=cls.domain_1.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d1a) + cls.user_d1a_apikey = user.apikey + cls.user_d1a_secretkey = user.secretkey + + cls.account_d1b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD1B"], + admin=False, + domainid=cls.domain_1.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d1b) + cls.user_d1b_apikey = user.apikey + cls.user_d1b_secretkey = user.secretkey + + # Create 1 admin and 2 user accounts for doamin_11 + cls.account_d11 = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11"], + admin=True, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11) + cls.user_d11_apikey = user.apikey + cls.user_d11_secretkey = user.secretkey + + cls.account_d11a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11A"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11a) + cls.user_d11a_apikey = user.apikey + cls.user_d11a_secretkey = user.secretkey + + cls.account_d11b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD11B"], + admin=False, + domainid=cls.domain_11.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d11b) + cls.user_d11b_apikey = user.apikey + cls.user_d11b_secretkey = user.secretkey + + # Create 2 user accounts for doamin_12 + cls.account_d12a = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD12A"], + admin=False, + domainid=cls.domain_12.id + ) + user = cls.generateKeysForUser(cls.api_client, cls.account_d12a) + cls.user_d12a_apikey = user.apikey + cls.user_d12a_secretkey = user.secretkey + + cls.account_d12b = Account.create( + cls.api_client, + cls.sharednetworkdata["accountD12B"], + admin=False, + domainid=cls.domain_12.id + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_d12b) + cls.user_d12b_apikey = user.apikey + cls.user_d12b_secretkey = user.secretkey + + # Create 1 user account and admin account in "ROOT" domain + + cls.account_roota = Account.create( + cls.api_client, + cls.sharednetworkdata["accountROOTA"], + admin=False, + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_roota) + cls.user_roota_apikey = user.apikey + cls.user_roota_secretkey = user.secretkey + + cls.account_root = Account.create( + cls.api_client, + cls.sharednetworkdata["accountROOTA"], + admin=True, + ) + + user = cls.generateKeysForUser(cls.api_client, cls.account_root) + cls.user_root_apikey = user.apikey + cls.user_root_secretkey = user.secretkey + + # service offering is already created in Nuagetestcase + cls.sharednetworkdata['mode'] = cls.zone.networktype + + # As admin user , create shared network with scope "all", "domain" + # with subdomain access , "domain" without subdomain access and + # "account" + cls.api_client.connection.apiKey = cls.default_apikey + cls.api_client.connection.securityKey = cls.default_secretkey + + cls.shared_network_offering = NetworkOffering.create( + cls.api_client, + cls.test_data["nuagevsp"]["shared_nuage_network_offering"], + conservemode=False + ) + # Enable Network offering + cls.shared_network_offering.update(cls.api_client, state='Enabled') + cls.shared_network_offering_id = cls.shared_network_offering.id + + cls.shared_network_all = Network.create( + cls.api_client, + cls.test_data["nuagevsp"]["network_all"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id + ) + + cls.shared_network_domain_d11 = Network.create( + cls.api_client, + cls.test_data["nuagevsp"][ + "network_domain_with_no_subdomain_access"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + subdomainaccess=False + ) + + cls.shared_network_domain_with_subdomain_d11 = Network.create( + cls.api_client, + cls.test_data["nuagevsp"][ + "network_domain_with_subdomain_access"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + subdomainaccess=True + ) + + cls.shared_network_account_d111a = Network.create( + cls.api_client, + cls.test_data["nuagevsp"]["network_account"], + networkofferingid=cls.shared_network_offering_id, + zoneid=cls.zone.id, + domainid=cls.domain_11.id, + accountid=cls.account_d11a.user[0].username + ) + + cls.debug("Creating Nuage VSP VPC offering...") + cls.vpc_offering = VpcOffering.create(cls.api_client, + cls.test_data["nuagevsp"][ + "vpc_offering"] + ) + + cls.vpc_offering.update(cls.api_client, state="Enabled") + + # Creating a VPC + cls.debug("Creating a VPC with Nuage VSP VPC offering...") + cls.test_data["vpc"]["cidr"] = '10.1.0.0/16' + cls.vpcd11 = VPC.create(cls.api_client, + cls.test_data["vpc"], + vpcofferingid=cls.vpc_offering.id, + zoneid=cls.zone.id, + account=cls.account_d11a.name, + domainid=cls.account_d11a.domainid + ) + + # Creating a network offering + cls.debug("Creating Nuage Vsp VPC Network offering...") + cls.network_offering = NetworkOffering.create( + cls.api_client, + cls.test_data["nuagevsp"]["vpc_network_offering"], + conservemode=False + ) + cls.network_offering.update(cls.api_client, state="Enabled") + + # Creating two VPC network in the VPC + cls.debug( + "Creating a VPC network with Nuage Vsp VPC Network " + "offering...") + cls.test_data["network"]["netmask"] = "255.255.255.0" + cls.vpc_network1 = Network.create( + cls.api_client, + cls.test_data["network"], + accountid=cls.account_d11a.name, + domainid=cls.account_d11a.domainid, + networkofferingid=cls.network_offering.id, + zoneid=cls.zone.id, + gateway="10.1.1.1", + vpcid=cls.vpcd11.id + ) + + cls.debug( + "Creating a VPC Tier2 network with Nuage Vsp VPC Network " + "offering...") + cls.test_data["network"]["name"] = "Tier2" + cls.vpc_network2 = Network.create( + cls.api_client, + cls.test_data["network"], + accountid=cls.account_d11a.name, + domainid=cls.account_d11a.domainid, + networkofferingid=cls.network_offering.id, + zoneid=cls.zone.id, + gateway="10.1.2.1", + vpcid=cls.vpcd11.id + ) + + cls.vmdata = {"name": "vmvpc1", + "displayname": "vmvpc1" + } + + # Deploying a VM in the VPC network + cls.vmvpc1 = VirtualMachine.create( + cls.api_client, + cls.vmdata, + zoneid=cls.zone.id, + serviceofferingid=cls.service_offering.id, + templateid=cls.template.id, + networkids=cls.vpc_network1.id, + accountid=cls.account_d11a.name, + domainid=cls.account_d11a.domainid + ) + + cls.vmdata = {"name": "vmvpc2", + "displayname": "vmvpc2" + } + + cls.vmvpc2 = VirtualMachine.create( + cls.api_client, + cls.vmdata, + zoneid=cls.zone.id, + serviceofferingid=cls.service_offering.id, + templateid=cls.template.id, + networkids=cls.vpc_network2.id, + accountid=cls.account_d11a.name, + domainid=cls.account_d11a.domainid + ) + + cls._cleanup = [ + cls.account_root, + cls.account_roota, + cls.shared_network_all, + cls.shared_network_offering, + cls.network_offering, + cls.vpc_offering, + cls.service_offering, + ] + except Exception as e: + cls.domain_1.delete(cls.api_client, cleanup="true") + cleanup_resources(cls.api_client, cls._cleanup) + raise Exception( + "Failed to create the setup required to execute the test " + "cases: %s" % e) + + return + + @classmethod + def tearDownClass(cls): + cls.api_client.connection.apiKey = cls.default_apikey + cls.api_client.connection.securityKey = cls.default_secretkey + cls.domain_1.delete(cls.api_client, cleanup="true") + cleanup_resources(cls.api_client, cls._cleanup) + return + + def setUp(self): + self.api_client = self.testClient.getApiClient() + self.dbclient = self.testClient.getDbConnection() + + def tearDown(self): + # restore back default apikey and secretkey + self.api_client.connection.apiKey = self.default_apikey + self.api_client.connection.securityKey = self.default_secretkey + return + + def verify_nic(self, network, vm): + """verify required nic is present in the VM""" + self.debug( + "Going to verify if %s Network nic is present in virtual machine " + "%s" % (network.name, vm.id)) + vm_list = list_virtual_machines(self.api_client, id=vm.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, + "vm list validation failed due to %s" % + vm_list_validation_result[2]) + self.debug("virtual machine nics: %s" % vm_list[0].nic) + # filter nic of virtual machine based on Network + nics = [x for x in vm_list[0].nic if x.networkid == network.id] + self.debug("Filtered nics list: %s:" % nics) + if len(nics) == 1: + return True + else: + return False + + # Test cases relating to MonitorVM through SharedNetwork + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_01_addNic_in_sharedNetwork_scope_all_as_domainuser(self): + """Validate that Normal user in the same domain able to add NIC in a + shared network with scope=all + """ + + # Deploy VM for a user in a domain under ROOT as admin + + self.api_client.connection.apiKey = self.user_d11a_apikey + self.api_client.connection.securityKey = self.user_d11a_secretkey + self.debug("Adding NIC of shared Network as user d11a") + + self.vmvpc1.add_nic(self.api_client, self.shared_network_all.id) + + if self.verify_nic(self.shared_network_all, self.vmvpc1): + self.debug( + "virtual machine has NIC is SharedNetwork: %s" % + self.shared_network_all.name) + else: + self.fail( + "Expected network %s NIC is not present in the virtual " + "Machine %s" % + (self.shared_network_all.name, self.vmvpc1.id)) + + self.debug("validating Network and VM on VSD") + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_all, self.vmvpc1, + sharedsubnetid=subnet_id) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_02_addNic_in_sharedNetwork_scope_all_as_domain_parentAdmin(self): + """Validate that Parent domain admin is able to add a NIC in a shared + network with scope=all + """ + + # Add NIC as D1 user + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.debug("Adding NIC of shared Network as user d1") + + self.vmvpc2.add_nic(self.api_client, self.shared_network_all.id) + + if self.verify_nic(self.shared_network_all, self.vmvpc2): + self.debug( + "virtual machine has NIC is SharedNetwork: %s" % + self.shared_network_all.name) + else: + self.fail( + "Expected network %s NIC is not present in the virtual " + "Machine %s" % + (self.shared_network_all.name, self.vmvpc2.id)) + + self.debug("validating Network and VM on VSD") + self.verify_vsd_shared_network( + self.account_d1.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_all, self.vmvpc2, + sharedsubnetid=subnet_id) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_03_staticNat_in_VPC_secondNic_sharedNetwork_scope_all(self): + """Validate that User can enable staticNat on VPC NIC where second nic + is in a shared network with scope=all + """ + + self.api_client.connection.apiKey = self.user_d11a_apikey + self.api_client.connection.securityKey = self.user_d11a_secretkey + self.debug("Enabling StaticNat as user d11a") + public_ip_1 = self.acquire_PublicIPAddress(self.vpc_network1, + self.vpcd11, + account=self.account_d11a) + self.create_StaticNatRule_For_VM(self.vmvpc1, public_ip_1, + self.vpc_network1) + self.validate_PublicIPAddress(public_ip_1, self.vpc_network1, + static_nat=True, vm=self.vmvpc1) + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_all, self.vmvpc2, + sharedsubnetid=subnet_id) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_04_rebootVM_after_sharedNetwork_nic(self): + """Validate that reboot VM is done successfully without any Error + """ + + # Deploy VM for a user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.user_d11a_apikey + self.api_client.connection.securityKey = self.user_d11a_secretkey + + self.debug("Rebooting VMs as user d1") + + try: + self.vmvpc1.reboot(self.api_client) + self.vmvpc2.reboot(self.api_client) + except Exception as e: + self.fail("Failed to reboot the virtual instances, %s" % e) + + self.debug("validating VM on VSD") + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_all, self.vmvpc1, + sharedsubnetid=subnet_id) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_all, self.vmvpc2, + sharedsubnetid=subnet_id) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_05_restart_Tier_VPC_Network_sharedNetwork_nic(self): + """Validate that restart Tier Network is done successfully with cleanup + """ + + # Deploy VM for a user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.user_d11a_apikey + self.api_client.connection.securityKey = self.user_d11a_secretkey + + self.debug("Restarting Tier Networks and VPC") + + self.vpc_network1.restart(self.api_client, cleanup=True) + self.vpc_network2.restart(self.api_client, cleanup=True) + self.restart_Vpc(self.vpcd11, cleanup=False) + + self.debug("validating VM on VSD") + subnet_id = self.get_subnet_id( + self.shared_network_all.id, + self.nuagenetworkdata["network_all"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_all, self.vmvpc1, + sharedsubnetid=subnet_id) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_all, self.vmvpc2, + sharedsubnetid=subnet_id) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_06_restart_sharedNetwork_scope_all(self): + """Validate that restart Shared Network is done successfully without + any Error + """ + + self.debug("Restarting shared Network with cleanup") + self.shared_network_all.restart(self.api_client, cleanup=True) + + self.debug("validating SharedNetwork on VSD") + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_all, + gateway=self.nuagenetworkdata["network_all"]["gateway"]) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_07_removeNic_in_sharedNetwork_scope_all_as_domainuser(self): + """Validate that Normal user in the same domain able to remove NIC in a + shared network which is added by Parent Domain Admin + """ + + self.api_client.connection.apiKey = self.user_d11a_apikey + self.api_client.connection.securityKey = self.user_d11a_secretkey + + self.debug("Removing NIC of shared Network as user d11a") + + vm_list = list_virtual_machines(self.api_client, id=self.vmvpc2.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, + "vm list validation failed due to %s" % + vm_list_validation_result[2]) + self.debug("virtual machine nics: %s" % vm_list[0].nic) + for nic in vm_list[0].nic: + if nic.networkid == self.shared_network_all.id: + reqNic = nic + + self.vmvpc2.remove_nic(self.api_client, reqNic.id) + if not self.verify_nic(self.shared_network_all, self.vmvpc2): + self.debug( + "virtual machine has NIC is SharedNetwork: %s" % + self.shared_network_all.name) + else: + self.fail("network %s NIC is present in the virtual Machine %s" % + (self.shared_network_all.name, self.vmvpc2.id)) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_08_removeNic_in_sharedNetwork_scope_all_as_domain_parentAdmin( + self): + """Validate that Parent domain admin is able to remove a NIC which is + added by child domain user + """ + + self.api_client.connection.apiKey = self.user_d1_apikey + self.api_client.connection.securityKey = self.user_d1_secretkey + self.debug("Removing NIC od shared Network as user d1") + + vm_list = list_virtual_machines(self.api_client, id=self.vmvpc1.id) + vm_list_validation_result = validateList(vm_list) + self.assertEqual(vm_list_validation_result[0], PASS, + "vm list validation failed due to %s" % + vm_list_validation_result[2]) + self.debug("virtual machine nics: %s" % vm_list[0].nic) + for nic in vm_list[0].nic: + if nic.networkid == self.shared_network_all.id: + reqNic = nic + + self.vmvpc1.remove_nic(self.api_client, reqNic.id) + + if not self.verify_nic(self.shared_network_all, self.vmvpc1): + self.debug( + "virtual machine has mot NIC is SharedNetwork: %s" % + self.shared_network_all.name) + else: + self.fail("network %s NIC is present in the virtual Machine %s" % + (self.shared_network_all.name, self.vmvpc1.id)) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_09_addNic_in_sharedNetwork_scope_domain_as_domainuser(self): + """Validate that Normal user in the same domain able to add NIC in a + shared network with scope=domain without subdomain Access + """ + + # Deploy VM for a user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.user_d11a_apikey + self.api_client.connection.securityKey = self.user_d11a_secretkey + self.debug("Adding NIC of shared Network as user d11a") + + self.vmvpc1.add_nic(self.api_client, self.shared_network_domain_d11.id) + + if self.verify_nic(self.shared_network_domain_d11, self.vmvpc1): + self.debug( + "virtual machine has NIC is SharedNetwork: %s" % + self.shared_network_domain_d11.name) + else: + self.fail( + "Expected network %s NIC is not present in the virtual " + "Machine %s" % + (self.shared_network_domain_d11.name, self.vmvpc1.id)) + + self.debug("validating Network and VM on VSD") + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_no_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm(self.account_d11a.domainid, + self.shared_network_domain_d11, + self.vmvpc1, sharedsubnetid=subnet_id) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_10_addNic_in_sharedNetwork_scope_domain_subdomain_as_domainuser( + self): + """Validate that Normal user in the same domain able to add NIC in a + shared network with scope=domain with subdomain Access + """ + + # Deploy VM for a user in a domain under ROOT as admin + self.api_client.connection.apiKey = self.user_d11a_apikey + self.api_client.connection.securityKey = self.user_d11a_secretkey + self.debug("Adding NIC of shared Network as user d11a") + + self.vmvpc2.add_nic(self.api_client, + self.shared_network_domain_with_subdomain_d11.id) + + if self.verify_nic(self.shared_network_domain_with_subdomain_d11, + self.vmvpc2): + self.debug( + "virtual machine has NIC is SharedNetwork: %s" % + self.shared_network_domain_with_subdomain_d11.name) + else: + self.fail( + "Expected network %s NIC is not present in the virtual " + "Machine %s" % + (self.shared_network_domain_with_subdomain_d11.name, + self.vmvpc2.id)) + + self.debug("validating Network and VM on VSD") + self.verify_vsd_shared_network( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + gateway=self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + subnet_id = self.get_subnet_id( + self.shared_network_domain_with_subdomain_d11.id, + self.nuagenetworkdata[ + "network_domain_with_subdomain_access"]["gateway"]) + self.verify_vsd_enterprise_vm( + self.account_d11a.domainid, + self.shared_network_domain_with_subdomain_d11, + self.vmvpc2, sharedsubnetid=subnet_id) + + @staticmethod + def generateKeysForUser(api_client, account): + user = User.list( + api_client, + account=account.name, + domainid=account.domainid + )[0] + + return (User.registerUserKeys( + api_client, + user.id + )) diff --git a/test/integration/plugins/nuagevsp/test_nuage_source_nat.py b/test/integration/plugins/nuagevsp/test_nuage_source_nat.py index f0b231997e5..2d9e3b9fb8a 100644 --- a/test/integration/plugins/nuagevsp/test_nuage_source_nat.py +++ b/test/integration/plugins/nuagevsp/test_nuage_source_nat.py @@ -218,11 +218,11 @@ class TestNuageSourceNat(nuageTestCase): Source NAT service providers """ - # 1. Create Nuage VSP Isolated Network offering with different - # combinations of Source NAT service providers - # (NuageVsp, VirtualRouter, no SourceNat service), check if only the - # network offering with Source NAT service provider as NuageVsp is - # successfully created and enabled. + # 1. Create Nuage VSP Isolated Network offerings and corresponding + # Isolated networks with different combinations of Source NAT + # service providers (NuageVsp, VirtualRouter, no SourceNat service), + # check if only the Isolated networks with Source NAT service + # provider as NuageVsp are successfully created. # 2. Recreate the above created Network offering with ispersistent flag # set to True, check if the network offering is successfully created # and enabled. @@ -303,10 +303,7 @@ class TestNuageSourceNat(nuageTestCase): 'Dhcp,Connectivity,StaticNat,UserData,Firewall,Dns' del network_offering["serviceProviderList"]["SourceNat"] del network_offering["serviceCapabilityList"] - with self.assertRaises(Exception): - self.create_NetworkOffering(network_offering) - self.debug("Nuage VSP does not support Network offerings without " - "Source NAT service") + net_off_4 = self.create_NetworkOffering(network_offering) # Creating Isolated networks, and deploying VMs self.debug("Creating an Isolated network with Source NAT service " @@ -376,6 +373,13 @@ class TestNuageSourceNat(nuageTestCase): # VSD verification for Source NAT functionality self.verify_vsd_SourceNAT_network(network_3) + self.debug("Creating an Isolated network without Source NAT " + "service...") + with self.assertRaises(Exception): + self.create_Network(net_off_4, gateway='10.1.4.1') + self.debug("Nuage VSP does not support creation of Isolated networks " + "without Source NAT service") + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") def test_02_nuage_SourceNAT_vpc_networks(self): """Test Nuage VSP VPC networks with different combinations of Source diff --git a/test/integration/plugins/nuagevsp/test_nuage_vpc_internal_lb.py b/test/integration/plugins/nuagevsp/test_nuage_vpc_internal_lb.py index 0cb9b159b12..97319aa2b1f 100644 --- a/test/integration/plugins/nuagevsp/test_nuage_vpc_internal_lb.py +++ b/test/integration/plugins/nuagevsp/test_nuage_vpc_internal_lb.py @@ -167,12 +167,79 @@ class TestNuageInternalLb(nuageTestCase): self.debug("InternalLbVm instance - %s is in the expected state - %s" % (internal_lb_vms[0].name, state)) + # verify_vpc_vm_ingress_traffic - Verifies ingress traffic to the given VM + # (SSH into VM) via a created Static NAT rule in the given VPC network + def verify_vpc_vm_ingress_traffic(self, vm, network, vpc): + self.debug("Verifying ingress traffic to the VM (SSH into VM) - %s " + "via a created Static NAT rule in the VPC network - %s" % + (vm, network)) + + # Creating Static NAT rule for the given VM in the given VPC network + self.debug("Creating Static NAT Rule...") + test_public_ip = self.acquire_PublicIPAddress(network, vpc) + self.validate_PublicIPAddress(test_public_ip, network) + self.create_StaticNatRule_For_VM(vm, test_public_ip, network) + self.validate_PublicIPAddress( + test_public_ip, network, static_nat=True, vm=vm) + + # VSD verification + self.verify_vsd_floating_ip(network, vm, test_public_ip.ipaddress, vpc) + + # Adding Network ACL rule in the given VPC network + self.debug("Creating Network ACL rule ...") + test_public_ssh_rule = self.create_NetworkAclRule( + self.test_data["ingress_rule"], network=network) + + # VSD verification + self.verify_vsd_firewall_rule(test_public_ssh_rule) + + # SSH into VM + self.debug("Verifying VM ingress traffic (SSH into VM)...") + self.ssh_into_VM(vm, test_public_ip) + + # Removing Network ACL rule in the given VPC network + self.debug("Removing the created Network ACL rule...") + test_public_ssh_rule.delete(self.api_client) + + # VSD verification + with self.assertRaises(Exception): + self.verify_vsd_firewall_rule(test_public_ssh_rule) + self.debug("Network ACL rule successfully deleted in VSD") + + # Deleting Static NAT Rule + self.debug("Deleting the created Static NAT Rule...") + self.delete_StaticNatRule_For_VM(test_public_ip) + with self.assertRaises(Exception): + self.validate_PublicIPAddress( + test_public_ip, network, static_nat=True, vm=vm) + self.debug("Static NAT Rule successfully deleted in CloudStack") + + # VSD verification + with self.assertRaises(Exception): + self.verify_vsd_floating_ip( + network, vm, test_public_ip.ipaddress, vpc=vpc) + self.debug("Floating IP successfully deleted in VSD") + + # Releasing acquired public IP + self.debug("Releasing the acquired public IP...") + test_public_ip.delete(self.api_client) + with self.assertRaises(Exception): + self.validate_PublicIPAddress(test_public_ip, network) + self.debug("Acquired public IP in the network successfully released " + "in CloudStack") + + self.debug("Successfully verified ingress traffic to the VM " + "(SSH into VM) - %s via a created Static NAT rule in the " + "VPC network - %s" % (vm, network)) + # wget_from_vm_cmd - From within the given VM (ssh client), # fetches index.html file of web server running with the given public IP def wget_from_vm_cmd(self, ssh_client, ip_address, port): wget_file = "" - cmd = "wget --no-cache --output-document=index.html -t 1 http://" + \ - ip_address + ":" + str(port) + "/" + cmd = "rm -rf index.html*" + self.execute_cmd(ssh_client, cmd) + cmd = "wget --no-cache -t 1 http://" + ip_address + ":" + str(port) + \ + "/" response = self.execute_cmd(ssh_client, cmd) if "200 OK" in response: self.debug("wget from a VM with http server IP address " @@ -181,7 +248,7 @@ class TestNuageInternalLb(nuageTestCase): cmd = "cat index.html" wget_file = self.execute_cmd(ssh_client, cmd) # Removing the wget file - cmd = "rm -r index.html" + cmd = "rm -rf index.html*" self.execute_cmd(ssh_client, cmd) else: self.debug("Failed to wget from a VM with http server IP address " @@ -198,11 +265,11 @@ class TestNuageInternalLb(nuageTestCase): if str(nic.ipaddress) in str(wget_file): wget_server_ip = str(nic.ipaddress) if wget_server_ip: - self.debug("Verified wget file from an Internal Load Balanced VM " - "with http server IP address - %s" % wget_server_ip) + self.debug("Verified wget file from Internal Load Balanced VMs - " + "%s" % vm_array) else: - self.fail("Did not wget file from the Internal Load Balanced VMs " - "- %s" % vm_array) + self.fail("Failed to verify wget file from Internal Load Balanced " + "VMs - %s" % vm_array) return wget_server_ip # validate_internallb_algorithm_traffic - Validates Internal LB algorithms @@ -1207,9 +1274,7 @@ class TestNuageInternalLb(nuageTestCase): # Adding Network ACL rules in the Internal tier self.debug("Adding Network ACL rules to make the created Internal LB " - "rules (SSH & HTTP) accessible...") - ssh_rule = self.create_NetworkAclRule( - self.test_data["ingress_rule"], network=internal_tier_1) + "rules (HTTP) accessible...") http_rule_1 = self.create_NetworkAclRule( self.test_data["http_rule"], network=internal_tier_1) http_rule = copy.deepcopy(self.test_data["http_rule"]) @@ -1221,7 +1286,6 @@ class TestNuageInternalLb(nuageTestCase): http_rule, network=internal_tier_1) # VSD verification - self.verify_vsd_firewall_rule(ssh_rule) self.verify_vsd_firewall_rule(http_rule_1) self.verify_vsd_firewall_rule(http_rule_2) @@ -1294,19 +1358,33 @@ class TestNuageInternalLb(nuageTestCase): # Adding Network ACL rules in the Internal tier self.debug("Adding Network ACL rules to make the created Internal LB " - "rules (SSH & HTTP) accessible...") - ssh_rule = self.create_NetworkAclRule( - self.test_data["ingress_rule"], network=internal_tier_2) + "rules (HTTP) accessible...") http_rule_1 = self.create_NetworkAclRule( self.test_data["http_rule"], network=internal_tier_2) http_rule_2 = self.create_NetworkAclRule( http_rule, network=internal_tier_2) # VSD verification - self.verify_vsd_firewall_rule(ssh_rule) self.verify_vsd_firewall_rule(http_rule_1) self.verify_vsd_firewall_rule(http_rule_2) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic( + internal_vm_1, internal_tier_1, vpc) + self.verify_vpc_vm_ingress_traffic( + internal_vm_1_1, internal_tier_1, vpc) + self.verify_vpc_vm_ingress_traffic( + internal_vm_1_2, internal_tier_1, vpc) + self.verify_vpc_vm_ingress_traffic( + internal_vm_2, internal_tier_2, vpc) + self.verify_vpc_vm_ingress_traffic( + internal_vm_2_1, internal_tier_2, vpc) + self.verify_vpc_vm_ingress_traffic( + internal_vm_2_2, internal_tier_2, vpc) + # Creating Static NAT rule for the VM in the Public tier public_ip = self.acquire_PublicIPAddress(public_tier, vpc) self.validate_PublicIPAddress(public_ip, public_tier) @@ -1548,16 +1626,21 @@ class TestNuageInternalLb(nuageTestCase): # Adding Network ACL rules in the Internal tier self.debug("Adding Network ACL rules to make the created Internal LB " - "rules (SSH & HTTP) accessible...") - ssh_rule = self.create_NetworkAclRule( - self.test_data["ingress_rule"], network=internal_tier) + "rules (HTTP) accessible...") http_rule = self.create_NetworkAclRule( self.test_data["http_rule"], network=internal_tier) # VSD verification - self.verify_vsd_firewall_rule(ssh_rule) self.verify_vsd_firewall_rule(http_rule) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Creating Static NAT rule for the VM in the Public tier public_ip = self.acquire_PublicIPAddress(public_tier, vpc) self.validate_PublicIPAddress(public_ip, public_tier) @@ -1742,16 +1825,21 @@ class TestNuageInternalLb(nuageTestCase): # Adding Network ACL rules in the Internal tier self.debug("Adding Network ACL rules to make the created Internal LB " - "rules (SSH & HTTP) accessible...") - ssh_rule = self.create_NetworkAclRule( - self.test_data["ingress_rule"], network=internal_tier) + "rules (HTTP) accessible...") http_rule = self.create_NetworkAclRule( self.test_data["http_rule"], network=internal_tier) # VSD verification - self.verify_vsd_firewall_rule(ssh_rule) self.verify_vsd_firewall_rule(http_rule) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Creating Static NAT rule for the VM in the Public tier public_ip = self.acquire_PublicIPAddress(public_tier, vpc) self.validate_PublicIPAddress(public_ip, public_tier) @@ -1798,7 +1886,6 @@ class TestNuageInternalLb(nuageTestCase): self.verify_vsd_vm(internal_vm) self.verify_vsd_vm(internal_vm_1) self.verify_vsd_vm(internal_vm_2) - self.verify_vsd_firewall_rule(ssh_rule) self.verify_vsd_firewall_rule(http_rule) # Validating InternalLbVm state @@ -1811,6 +1898,14 @@ class TestNuageInternalLb(nuageTestCase): # VSD Verification self.verify_vsd_lb_device(int_lb_vm) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Internal LB (wget) traffic test ssh_client = self.ssh_into_VM(public_vm, public_ip) wget_file = self.wget_from_vm_cmd( @@ -1837,7 +1932,6 @@ class TestNuageInternalLb(nuageTestCase): self.verify_vsd_vm(internal_vm) self.verify_vsd_vm(internal_vm_1) self.verify_vsd_vm(internal_vm_2) - self.verify_vsd_firewall_rule(ssh_rule) self.verify_vsd_firewall_rule(http_rule) # Validating InternalLbVm state @@ -1850,6 +1944,14 @@ class TestNuageInternalLb(nuageTestCase): # VSD Verification self.verify_vsd_lb_device(int_lb_vm) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Internal LB (wget) traffic test ssh_client = self.ssh_into_VM(public_vm, public_ip) wget_file = self.wget_from_vm_cmd( @@ -1885,6 +1987,14 @@ class TestNuageInternalLb(nuageTestCase): # VSD Verification self.verify_vsd_lb_device(int_lb_vm) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Internal LB (wget) traffic test ssh_client = self.ssh_into_VM(public_vm, public_ip) wget_file = self.wget_from_vm_cmd( @@ -1920,6 +2030,14 @@ class TestNuageInternalLb(nuageTestCase): # VSD Verification self.verify_vsd_lb_device(int_lb_vm) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Internal LB (wget) traffic test ssh_client = self.ssh_into_VM(public_vm, public_ip) wget_file = self.wget_from_vm_cmd( @@ -1949,7 +2067,6 @@ class TestNuageInternalLb(nuageTestCase): self.verify_vsd_vm(internal_vm, stopped=True) self.verify_vsd_vm(internal_vm_1, stopped=True) self.verify_vsd_vm(internal_vm_2, stopped=True) - self.verify_vsd_firewall_rule(ssh_rule) self.verify_vsd_firewall_rule(http_rule) # Validating InternalLbVm state @@ -1991,7 +2108,6 @@ class TestNuageInternalLb(nuageTestCase): self.verify_vsd_vm(internal_vm) self.verify_vsd_vm(internal_vm_1) self.verify_vsd_vm(internal_vm_2) - self.verify_vsd_firewall_rule(ssh_rule) self.verify_vsd_firewall_rule(http_rule) # Validating InternalLbVm state @@ -2001,6 +2117,14 @@ class TestNuageInternalLb(nuageTestCase): # VSD Verification self.verify_vsd_lb_device(int_lb_vm) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Internal LB (wget) traffic test ssh_client = self.ssh_into_VM(public_vm, public_ip) tries = 0 @@ -2047,7 +2171,6 @@ class TestNuageInternalLb(nuageTestCase): self.verify_vsd_floating_ip( public_tier, public_vm, public_ip.ipaddress, vpc) self.verify_vsd_firewall_rule(public_ssh_rule) - self.verify_vsd_firewall_rule(ssh_rule) self.verify_vsd_firewall_rule(http_rule) # Validating InternalLbVm state @@ -2057,6 +2180,14 @@ class TestNuageInternalLb(nuageTestCase): # VSD Verification self.verify_vsd_lb_device(int_lb_vm) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Internal LB (wget) traffic test ssh_client = self.ssh_into_VM(public_vm, public_ip) wget_file = self.wget_from_vm_cmd( @@ -2094,7 +2225,6 @@ class TestNuageInternalLb(nuageTestCase): self.verify_vsd_floating_ip( public_tier, public_vm, public_ip.ipaddress, vpc) self.verify_vsd_firewall_rule(public_ssh_rule) - self.verify_vsd_firewall_rule(ssh_rule) self.verify_vsd_firewall_rule(http_rule) # Validating InternalLbVm state @@ -2104,6 +2234,14 @@ class TestNuageInternalLb(nuageTestCase): # VSD Verification self.verify_vsd_lb_device(int_lb_vm) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Internal LB (wget) traffic test ssh_client = self.ssh_into_VM(public_vm, public_ip) wget_file = self.wget_from_vm_cmd( @@ -2259,16 +2397,21 @@ class TestNuageInternalLb(nuageTestCase): # Adding Network ACL rules in the Internal tier self.debug("Adding Network ACL rules to make the created Internal LB " - "rules (SSH & HTTP) accessible...") - ssh_rule = self.create_NetworkAclRule( - self.test_data["ingress_rule"], network=internal_tier) + "rules (HTTP) accessible...") http_rule = self.create_NetworkAclRule( self.test_data["http_rule"], network=internal_tier) # VSD verification - self.verify_vsd_firewall_rule(ssh_rule) self.verify_vsd_firewall_rule(http_rule) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Creating Static NAT rule for the VM in the Public tier public_ip = self.acquire_PublicIPAddress(public_tier, vpc) self.validate_PublicIPAddress(public_ip, public_tier) @@ -2307,6 +2450,14 @@ class TestNuageInternalLb(nuageTestCase): # VSD Verification self.verify_vsd_lb_device(int_lb_vm, stopped=True) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Internal LB (wget) traffic test ssh_client = self.ssh_into_VM(public_vm, public_ip) wget_file = self.wget_from_vm_cmd( @@ -2328,6 +2479,14 @@ class TestNuageInternalLb(nuageTestCase): # VSD Verification self.verify_vsd_lb_device(int_lb_vm) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Internal LB (wget) traffic test ssh_client = self.ssh_into_VM(public_vm, public_ip) wget_file = self.wget_from_vm_cmd( @@ -2358,6 +2517,14 @@ class TestNuageInternalLb(nuageTestCase): # VSD Verification self.verify_vsd_lb_device(int_lb_vm, stopped=True) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Internal LB (wget) traffic test ssh_client = self.ssh_into_VM(public_vm, public_ip) wget_file = self.wget_from_vm_cmd( @@ -2379,6 +2546,14 @@ class TestNuageInternalLb(nuageTestCase): # VSD Verification self.verify_vsd_lb_device(int_lb_vm) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Internal LB (wget) traffic test ssh_client = self.ssh_into_VM(public_vm, public_ip) wget_file = self.wget_from_vm_cmd( @@ -2397,6 +2572,14 @@ class TestNuageInternalLb(nuageTestCase): # VSD Verification self.verify_vsd_lb_device(int_lb_vm, stopped=True) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Internal LB (wget) traffic test ssh_client = self.ssh_into_VM(public_vm, public_ip) wget_file = self.wget_from_vm_cmd( @@ -2418,6 +2601,14 @@ class TestNuageInternalLb(nuageTestCase): # VSD Verification self.verify_vsd_lb_device(int_lb_vm) + # Verifying Internal Load Balanced VMs ingress traffic + # (SSH into VM via Static NAT rule) + self.debug("Verifying Internal Load Balanced VMs ingress traffic " + "(SSH into VM via Static NAT rule)...") + self.verify_vpc_vm_ingress_traffic(internal_vm, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_1, internal_tier, vpc) + self.verify_vpc_vm_ingress_traffic(internal_vm_2, internal_tier, vpc) + # Internal LB (wget) traffic test ssh_client = self.ssh_into_VM(public_vm, public_ip) wget_file = self.wget_from_vm_cmd( diff --git a/test/integration/plugins/nuagevsp/test_nuage_vpc_network.py b/test/integration/plugins/nuagevsp/test_nuage_vpc_network.py index ca16efb8c4a..088517756f7 100644 --- a/test/integration/plugins/nuagevsp/test_nuage_vpc_network.py +++ b/test/integration/plugins/nuagevsp/test_nuage_vpc_network.py @@ -20,7 +20,7 @@ Nuage VSP SDN plugin """ # Import Local Modules from nuageTestCase import nuageTestCase -from marvin.lib.base import Account, Zone +from marvin.lib.base import Account # Import System Modules from nose.plugins.attrib import attr @@ -123,13 +123,12 @@ class TestNuageVpcNetwork(nuageTestCase): self.debug("Testing basic VPC Network functionality with Nuage VSP " "SDN plugin on multiple zones...") - zones = Zone.list(self.api_client) - if len(zones) == 1: + if len(self.zones) == 1: self.skipTest("There is only one Zone configured: skipping test") - for zone in zones: + for zone in self.zones: self.debug("Zone - %s" % zone.name) # Get Zone details - self.getZoneDetails() + self.getZoneDetails(zone=zone) # Configure VSD sessions self.configureVSDSessions() self.test_nuage_vpc_network() diff --git a/test/integration/plugins/nuagevsp/test_nuage_vsp.py b/test/integration/plugins/nuagevsp/test_nuage_vsp.py index 38b5b234c0d..9f2d1f23456 100644 --- a/test/integration/plugins/nuagevsp/test_nuage_vsp.py +++ b/test/integration/plugins/nuagevsp/test_nuage_vsp.py @@ -97,59 +97,66 @@ class TestNuageVsp(nuageTestCase): # valid VSD credentials, verify that the Nuage VSP device is # successfully added in the Nuage VSP Physical Network. - # Nuage VSP network service provider validation - self.debug("Validating the Nuage VSP network service provider in the " - "Nuage VSP Physical Network...") - self.validate_NetworkServiceProvider("NuageVsp", state="Enabled") + for zone in self.zones: + self.debug("Zone - %s" % zone.name) + # Get Zone details + self.getZoneDetails(zone=zone) + # Configure VSD sessions + self.configureVSDSessions() - # Nuage VSP device validation - self.debug("Validating the Nuage VSP device in the Nuage VSP Physical " - "Network...") - self.validate_NuageVspDevice() + # Nuage VSP network service provider validation + self.debug("Validating the Nuage VSP network service provider in " + "the Nuage VSP Physical Network...") + self.validate_NetworkServiceProvider("NuageVsp", state="Enabled") - # Nuage VSP device deletion - self.debug("Deleting the Nuage VSP device in the Nuage VSP Physical " - "Network...") - self.delete_NuageVspDevice() - - # Nuage VSP device validation - self.debug("Validating the Nuage VSP device in the Nuage VSP Physical " - "Network...") - with self.assertRaises(Exception): + # Nuage VSP device validation + self.debug("Validating the Nuage VSP device in the Nuage VSP " + "Physical Network...") self.validate_NuageVspDevice() - self.debug("Successfully deleted the Nuage VSP device in the Nuage " - "VSP Physical Network") - # Adding the Nuage VSP device with invalid VSD credentials - self.debug("Adding the Nuage VSP device in the Nuage VSP Physical " - "Network with invalid VSD credentials...") - vsd_info = self.nuage_vsp_device.__dict__ - invalid_vsd_info = copy.deepcopy(vsd_info) - invalid_vsd_info["password"] = "" - with self.assertRaises(Exception): - Nuage.add( - self.api_client, invalid_vsd_info, - self.vsp_physical_network.id) - self.debug("Failed to add the Nuage VSP device in the Nuage VSP " - "Physical Network due to invalid VSD credentials") + # Nuage VSP device deletion + self.debug("Deleting the Nuage VSP device in the Nuage VSP " + "Physical Network...") + self.delete_NuageVspDevice() - # Nuage VSP device validation - self.debug("Validating the Nuage VSP device in the Nuage VSP " - "Physical Network...") - with self.assertRaises(Exception): + # Nuage VSP device validation + self.debug("Validating the Nuage VSP device in the Nuage VSP " + "Physical Network...") + with self.assertRaises(Exception): + self.validate_NuageVspDevice() + self.debug("Successfully deleted the Nuage VSP device in the " + "Nuage VSP Physical Network") + + # Adding the Nuage VSP device with invalid VSD credentials + self.debug("Adding the Nuage VSP device in the Nuage VSP Physical " + "Network with invalid VSD credentials...") + vsd_info = self.nuage_vsp_device.__dict__ + invalid_vsd_info = copy.deepcopy(vsd_info) + invalid_vsd_info["password"] = "" + with self.assertRaises(Exception): + Nuage.add( + self.api_client, invalid_vsd_info, + self.vsp_physical_network.id) + self.debug("Failed to add the Nuage VSP device in the Nuage VSP " + "Physical Network due to invalid VSD credentials") + + # Nuage VSP device validation + self.debug("Validating the Nuage VSP device in the Nuage VSP " + "Physical Network...") + with self.assertRaises(Exception): + self.validate_NuageVspDevice() + self.debug("The Nuage VSP device is not added in the Nuage VSP " + "Physical Network") + + # Adding the Nuage VSP device with valid VSD credentials + self.debug("Adding the Nuage VSP device in the Nuage VSP Physical " + "Network with valid VSD credentials...") + Nuage.add(self.api_client, vsd_info, self.vsp_physical_network.id) + + # Nuage VSP device validation + self.debug("Validating the Nuage VSP device in the Nuage VSP " + "Physical Network...") self.validate_NuageVspDevice() - self.debug("The Nuage VSP device is not added in the Nuage VSP " - "Physical Network") - - # Adding the Nuage VSP device with valid VSD credentials - self.debug("Adding the Nuage VSP device in the Nuage VSP Physical " - "Network with valid VSD credentials...") - Nuage.add(self.api_client, vsd_info, self.vsp_physical_network.id) - - # Nuage VSP device validation - self.debug("Validating the Nuage VSP device in the Nuage VSP Physical " - "Network...") - self.validate_NuageVspDevice() @attr(tags=["advanced", "nuagevsp"], required_hardware="false") def test_nuage_vsp(self): @@ -172,49 +179,56 @@ class TestNuageVsp(nuageTestCase): # check if the Isolated network is successfully deleted. # 7. Delete all the created objects (cleanup). - # Creating a network offering - self.debug("Creating and enabling Nuage VSP Isolated Network " - "offering...") - network_offering = self.create_NetworkOffering( - self.test_data["nuagevsp"]["isolated_network_offering"]) - self.validate_NetworkOffering(network_offering, state="Enabled") + for zone in self.zones: + self.debug("Zone - %s" % zone.name) + # Get Zone details + self.getZoneDetails(zone=zone) + # Configure VSD sessions + self.configureVSDSessions() - # Creating a network - self.debug("Creating an Isolated Network with Nuage VSP Isolated " - "Network offering...") - network = self.create_Network(network_offering) - self.validate_Network(network, state="Allocated") + # Creating a network offering + self.debug("Creating and enabling Nuage VSP Isolated Network " + "offering...") + network_offering = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"]) + self.validate_NetworkOffering(network_offering, state="Enabled") - # Deploying a VM in the network - vm_1 = self.create_VM(network) - self.validate_Network(network, state="Implemented") - vr = self.get_Router(network) - self.check_Router_state(vr, state="Running") - self.check_VM_state(vm_1, state="Running") + # Creating a network + self.debug("Creating an Isolated Network with Nuage VSP Isolated " + "Network offering...") + network = self.create_Network(network_offering) + self.validate_Network(network, state="Allocated") - # VSD verification - self.verify_vsd_network(self.domain.id, network) - self.verify_vsd_router(vr) - self.verify_vsd_vm(vm_1) + # Deploying a VM in the network + vm_1 = self.create_VM(network) + self.validate_Network(network, state="Implemented") + vr = self.get_Router(network) + self.check_Router_state(vr, state="Running") + self.check_VM_state(vm_1, state="Running") - # Deploying one more VM in the network - vm_2 = self.create_VM(network) - self.check_VM_state(vm_2, state="Running") - - # VSD verification - self.verify_vsd_vm(vm_2) - - # Deleting the network - self.debug("Deleting the Isolated Network with Nuage VSP Isolated " - "Network offering...") - self.delete_VM(vm_1) - self.delete_VM(vm_2) - self.delete_Network(network) - with self.assertRaises(Exception): - self.validate_Network(network) - self.debug("Isolated Network successfully deleted in CloudStack") - - # VSD verification - with self.assertRaises(Exception): + # VSD verification self.verify_vsd_network(self.domain.id, network) - self.debug("Isolated Network successfully deleted in VSD") + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm_1) + + # Deploying one more VM in the network + vm_2 = self.create_VM(network) + self.check_VM_state(vm_2, state="Running") + + # VSD verification + self.verify_vsd_vm(vm_2) + + # Deleting the network + self.debug("Deleting the Isolated Network with Nuage VSP Isolated " + "Network offering...") + self.delete_VM(vm_1) + self.delete_VM(vm_2) + self.delete_Network(network) + with self.assertRaises(Exception): + self.validate_Network(network) + self.debug("Isolated Network successfully deleted in CloudStack") + + # VSD verification + with self.assertRaises(Exception): + self.verify_vsd_network(self.domain.id, network) + self.debug("Isolated Network successfully deleted in VSD") diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py index d84eac975d1..c4d1aed3daf 100644 --- a/tools/marvin/marvin/config/test_data.py +++ b/tools/marvin/marvin/config/test_data.py @@ -1847,6 +1847,100 @@ test_data = { "UserData": "VpcVirtualRouter", "Dns": "VpcVirtualRouter" } + }, + "shared_nuage_network_offering": { + "name": 'nuage_marvin', + "displaytext": 'nuage_marvin', + "guestiptype": 'shared', + "supportedservices": 'Dhcp,Connectivity', + "traffictype": 'GUEST', + "specifyVlan": "False", + "specifyIpRanges": "True", + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": "NuageVsp", + "Connectivity": "NuageVsp" + } + }, + "shared_nuage_public_network_offering": { + "name": 'nuage_marvin', + "displaytext": 'nuage_marvin', + "guestiptype": 'shared', + "supportedservices": 'Dhcp,Connectivity', + "traffictype": 'GUEST', + "specifyVlan": "False", + "specifyIpRanges": "True", + "availability": 'Optional', + "serviceProviderList": { + "Dhcp": "NuageVsp", + "Connectivity": "NuageVsp" + }, + "serviceCapabilityList": { + "Connectivity": { + "PublicAccess": "true" + } + } + + }, + # Test data for Shared Network creation + "network_all": { + "name": "SharedNetwork-All-nuage", + "displaytext": "SharedNetwork-All-nuage", + "gateway": "10.223.1.1", + "netmask": "255.255.255.0", + "startip": "10.223.1.21", + "endip": "10.223.1.100", + "acltype": "Domain" + }, + "network_domain_with_no_subdomain_access": { + "name": "SharedNetwork-Domain-nosubdomain-nuage", + "displaytext": "SharedNetwork-Domain-nosubdomain-nuage", + "gateway": "10.222.1.1", + "netmask": "255.255.255.0", + "startip": "10.222.1.2", + "endip": "10.222.1.100", + "acltype": "Domain", + "subdomainaccess": "false" + }, + "network_domain_with_subdomain_access": { + "name": "SharedNetwork-Domain-withsubdomain-nuage", + "displaytext": "SharedNetwork-Domain-withsubdomain-nuage", + "gateway": "10.221.1.1", + "netmask": "255.255.255.0", + "startip": "10.221.1.2", + "endip": "10.221.1.100", + "acltype": "Domain", + "subdomainaccess": "true" + }, + "network_account": { + "name": "SharedNetwork-Account-nuage", + "displaytext": "SharedNetwork-Account-nuage", + "gateway": "10.220.1.1", + "netmask": "255.255.255.0", + "startip": "10.220.1.2", + "endip": "10.220.1.100", + "acltype": "Account" + }, + "publiciprange1": { + "gateway": "10.223.1.1", + "netmask": "255.255.255.0", + "startip": "10.223.1.101", + "endip": "10.223.1.105", + "forvirtualnetwork": "false" + }, + "publiciprange2": { + "gateway": "10.219.1.1", + "netmask": "255.255.255.0", + "startip": "10.219.1.2", + "endip": "10.219.1.5", + "forvirtualnetwork": "false" + }, + "publiciprange3": { + "gateway": "10.223.1.1", + "netmask": "255.255.255.0", + "startip": "10.223.1.2", + "endip": "10.223.1.20", + "forvirtualnetwork": "false" } } } diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py index 474fde5c50b..c0cc28a57a8 100755 --- a/tools/marvin/marvin/lib/base.py +++ b/tools/marvin/marvin/lib/base.py @@ -513,7 +513,7 @@ class VirtualMachine: if ipaddress: cmd.ipaddress = ipaddress - elif ipaddress in services: + elif "ipaddress" in services: cmd.ipaddress = services["ipaddress"] if securitygroupids: diff --git a/ui/l10n/en.js b/ui/l10n/en.js index 3fc3631438f..075a0d801f1 100644 --- a/ui/l10n/en.js +++ b/ui/l10n/en.js @@ -1575,6 +1575,7 @@ var dictionary = {"ICMP.code":"ICMP Code", "label.supported.services":"Supported Services", "label.supported.source.NAT.type":"Supported Source NAT type", "label.supportsstrechedl2subnet":"Supports Streched L2 Subnet", +"label.supportspublicaccess":"Supports Public Access", "label.suspend.project":"Suspend Project", "label.switch.type":"Switch Type", "label.system.capacity":"System Capacity", diff --git a/ui/scripts/configuration.js b/ui/scripts/configuration.js index 81770f4fe66..512ccf7c738 100644 --- a/ui/scripts/configuration.js +++ b/ui/scripts/configuration.js @@ -2367,6 +2367,7 @@ var $serviceofferingid = args.$form.find('.form-item[rel=serviceofferingid]'); var $conservemode = args.$form.find('.form-item[rel=conservemode]'); var $supportsstrechedl2subnet = args.$form.find('.form-item[rel=supportsstrechedl2subnet]'); + var $supportspublicaccess = args.$form.find('.form-item[rel=supportspublicaccess]'); var $serviceSourceNatRedundantRouterCapabilityCheckbox = args.$form.find('.form-item[rel="service.SourceNat.redundantRouterCapabilityCheckbox"]'); var hasAdvancedZones = false; @@ -2675,6 +2676,20 @@ } else { $supportsstrechedl2subnet.hide(); } + + //PublicAccess checkbox should be displayed only when 'Connectivity' service is checked + if (args.$form.find('.form-item[rel=\"service.Connectivity.isEnabled\"]').find('input[type=checkbox]').is(':checked') && $guestTypeField.val() == 'Shared' && + args.$form.find('.form-item[rel=\"service.Connectivity.provider\"]').find('select').val() == 'NuageVsp') { + $supportspublicaccess.css('display', 'inline-block'); + } else { + $supportspublicaccess.hide(); + } + + //Uncheck specifyVlan checkbox when (1)guest type is Shared and (2)NuageVsp is selected as a Connectivity provider + if ($guestTypeField.val() == 'Shared') { + var $specifyVlanCheckbox = args.$form.find('.form-item[rel=specifyVlan]').find('input[type=checkbox]'); + $specifyVlanCheckbox.attr('checked', args.$form.find('.form-item[rel=\"service.Connectivity.provider\"]').find('select').val() != 'NuageVsp') + } }); args.$form.change(); @@ -3055,6 +3070,13 @@ isHidden: true }, + supportspublicaccess: { + label: 'label.supportspublicaccess', + isBoolean: true, + isChecked: false, + isHidden: true + }, + conservemode: { label: 'label.conserve.mode', isBoolean: true, @@ -3187,18 +3209,23 @@ } } - //passing supportsstrechedl2subnet's value as capability + //passing supportsstrechedl2subnet and supportspublicaccess's value as capability for (var k in inputData) { if (k == 'supportsstrechedl2subnet' && ("Connectivity" in serviceProviderMap)) { - inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].service'] = 'Connectivity'; - inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilitytype'] = 'StretchedL2Subnet'; - inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilityvalue'] = true; - serviceCapabilityIndex++; - break; + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].service'] = 'Connectivity'; + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilitytype'] = 'StretchedL2Subnet'; + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilityvalue'] = true; + serviceCapabilityIndex++; + } else if (k == 'supportspublicaccess' && ("Connectivity" in serviceProviderMap) && serviceProviderMap['Connectivity'] == 'NuageVsp') { + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].service'] = 'Connectivity'; + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilitytype'] = 'PublicAccess'; + inputData['servicecapabilitylist[' + serviceCapabilityIndex + '].capabilityvalue'] = true; + serviceCapabilityIndex++; } } - //removing supportsstrechedl2subnet from parameters, it has been set as capability + //removing supportsstrechedl2subnet and supportspublicaccess from parameters, it has been set as capability delete inputData['supportsstrechedl2subnet']; + delete inputData['supportspublicaccess']; // Make supported services list inputData['supportedServices'] = $.map(serviceProviderMap, function(value, key) { @@ -3207,7 +3234,8 @@ if (inputData['guestIpType'] == "Shared") { //specifyVlan checkbox is disabled, so inputData won't include specifyVlan - inputData['specifyVlan'] = true; //hardcode inputData['specifyVlan'] + var $specifyVlanCheckbox = args.$form.find('.form-item[rel=specifyVlan]').find('input[type=checkbox]'); + inputData['specifyVlan'] = $specifyVlanCheckbox.is(':checked'); //hardcode inputData['specifyVlan'] inputData['specifyIpRanges'] = true; delete inputData.isPersistent; //if Persistent checkbox is unchecked, do not pass isPersistent parameter to API call since we need to keep API call's size as small as possible (p.s. isPersistent is defaulted as false at server-side) } else if (inputData['guestIpType'] == "Isolated") { //specifyVlan checkbox is shown @@ -3538,6 +3566,10 @@ label: 'label.supportsstrechedl2subnet', converter: cloudStack.converters.toBooleanText }, + supportspublicaccess: { + label: 'label.supportspublicaccess', + converter: cloudStack.converters.toBooleanText + }, supportedServices: { label: 'label.supported.services' },