diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java b/api/src/org/apache/cloudstack/api/ResponseGenerator.java index 1cc5bc8ae01..8da1dedcee5 100644 --- a/api/src/org/apache/cloudstack/api/ResponseGenerator.java +++ b/api/src/org/apache/cloudstack/api/ResponseGenerator.java @@ -237,6 +237,8 @@ public interface ResponseGenerator { VlanIpRangeResponse createVlanIpRangeResponse(Vlan vlan); + VlanIpRangeResponse createVlanIpRangeResponse(Class subClass, Vlan vlan); + IPAddressResponse createIPAddressResponse(ResponseView view, IpAddress ipAddress); GuestVlanRangeResponse createDedicatedGuestVlanRangeResponse(GuestVlan result); diff --git a/core/src/com/cloud/agent/transport/Request.java b/core/src/com/cloud/agent/transport/Request.java index 7b8dd0dc0c0..f78a96cb132 100644 --- a/core/src/com/cloud/agent/transport/Request.java +++ b/core/src/com/cloud/agent/transport/Request.java @@ -399,7 +399,7 @@ public class Request { try { _cmds = s_gson.fromJson(_content, this instanceof Response ? Answer[].class : Command[].class); } catch (RuntimeException e) { - s_logger.error("Unable to convert to json: " + _content); + s_logger.error("Unable to deserialize from json: " + _content); throw e; } } diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index 884bb30c8ef..c43e9ff6cd8 100644 --- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -325,6 +325,7 @@ + diff --git a/engine/schema/src/com/cloud/dc/VlanDetailsVO.java b/engine/schema/src/com/cloud/dc/VlanDetailsVO.java new file mode 100644 index 00000000000..1a1db3a5681 --- /dev/null +++ b/engine/schema/src/com/cloud/dc/VlanDetailsVO.java @@ -0,0 +1,83 @@ +// 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.dc; + +import org.apache.cloudstack.api.ResourceDetail; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +@Entity +@Table(name = "vlan_details") +public class VlanDetailsVO implements ResourceDetail { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "vlan_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Column(name = "value", length = 1024) + private String value; + + @Column(name = "display") + private boolean display = true; + + public VlanDetailsVO() { + } + + public VlanDetailsVO(long networkId, String name, String value, boolean display) { + this.resourceId = networkId; + this.name = name; + this.value = value; + this.display = display; + } + + @Override + public long getId() { + return id; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getValue() { + return value; + } + + @Override + public long getResourceId() { + return resourceId; + } + + @Override + public boolean isDisplay() { + return display; + } + +} diff --git a/engine/schema/src/com/cloud/dc/dao/VlanDetailsDao.java b/engine/schema/src/com/cloud/dc/dao/VlanDetailsDao.java new file mode 100644 index 00000000000..dfc72a0d3be --- /dev/null +++ b/engine/schema/src/com/cloud/dc/dao/VlanDetailsDao.java @@ -0,0 +1,25 @@ +// 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 +// 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.dc.dao; + +import com.cloud.dc.VlanDetailsVO; +import com.cloud.utils.db.GenericDao; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; + +public interface VlanDetailsDao extends GenericDao, ResourceDetailsDao { + +} \ No newline at end of file diff --git a/engine/schema/src/com/cloud/dc/dao/VlanDetailsDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/VlanDetailsDaoImpl.java new file mode 100644 index 00000000000..43f9087c0f6 --- /dev/null +++ b/engine/schema/src/com/cloud/dc/dao/VlanDetailsDaoImpl.java @@ -0,0 +1,32 @@ +// 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 +// 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.dc.dao; + + +import com.cloud.dc.VlanDetailsVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.springframework.stereotype.Component; + +@Component +public class VlanDetailsDaoImpl extends ResourceDetailsDaoBase implements VlanDetailsDao { + + @Override + public void addDetail(long resourceId, String key, String value, boolean display) { + super.addDetail(new VlanDetailsVO(resourceId, key, value, display)); + } + +} \ No newline at end of file diff --git a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java index 861644986c3..8fb5d6dff84 100644 --- a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java +++ b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java @@ -31,6 +31,8 @@ import com.cloud.utils.db.GenericDao; public interface NetworkOfferingServiceMapDao extends GenericDao { boolean areServicesSupportedByNetworkOffering(long networkOfferingId, Service... services); + boolean canProviderSupportServiceInNetworkOffering(long networkOfferingId, Service service, Provider provider); + List listByNetworkOfferingId(long networkOfferingId); void deleteByOfferingId(long networkOfferingId); diff --git a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java index b667e58b555..7868be2ad69 100644 --- a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java +++ b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java @@ -103,6 +103,15 @@ public class NetworkOfferingServiceMapDaoImpl extends GenericDaoBase sc = AllFieldsSearch.create(); + sc.setParameters("networkOfferingId", networkOfferingId); + sc.setParameters("service", service.getName()); + sc.setParameters("provider", provider.getName()); + return findOneBy(sc) != null; + } + @Override public List listByNetworkOfferingId(long networkOfferingId) { SearchCriteria sc = AllFieldsSearch.create(); 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 new file mode 100644 index 00000000000..64f37689ca6 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/EntityExistsCommand.java @@ -0,0 +1,77 @@ +// +// 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; + +public class EntityExistsCommand extends Command { + + private transient Class _type; + private final String _className; + private final String _uuid; + + public EntityExistsCommand(Class type, String uuid) { + super(); + this._type = type; + this._className = type.getName(); + this._uuid = uuid; + } + + public Class getType() { + if (_type == null) { + try { + _type = (Class)Class.forName(_className); + } catch (ClassNotFoundException e) { + } + } + return _type; + } + + public String getUuid() { + return _uuid; + } + + @Override + public boolean executeInSequence() { + return false; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof EntityExistsCommand)) return false; + if (!super.equals(o)) 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; + } + + @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; + } +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DisableNuageUnderlayVlanIpRangeCmd.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DisableNuageUnderlayVlanIpRangeCmd.java new file mode 100644 index 00000000000..bcc804c8da5 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DisableNuageUnderlayVlanIpRangeCmd.java @@ -0,0 +1,110 @@ +// +// 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.api.commands; + +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.manager.NuageVspManager; +import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.api.response.VlanIpRangeResponse; +import org.apache.cloudstack.context.CallContext; + +import javax.inject.Inject; + +@APICommand(name = DisableNuageUnderlayVlanIpRangeCmd.APINAME, description = "disable Nuage underlay on vlan ip range", responseObject = SuccessResponse.class, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, + since = "4.10", + authorized = {RoleType.Admin}) +public class DisableNuageUnderlayVlanIpRangeCmd extends BaseAsyncCmd { + public static final String APINAME = "disableNuageUnderlayVlanIpRange"; + + @Inject + NuageVspManager _nuageVspManager; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VlanIpRangeResponse.class, required = true, description = "VLAN IP Range ID") + private long vlanIpRangeId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public long getVlanIpRangeId() { + return vlanIpRangeId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + try { + boolean result = _nuageVspManager.updateNuageUnderlayVlanIpRange(vlanIpRangeId, false); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to disable underlay, VLAN IP range is already pushed to the Nuage VSP device."); + } + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + + @Override + public String getEventType() { + return "VLAN.DISABLE.NUAGE.UNDERLAY"; + } + + @Override + public String getEventDescription() { + return "Disable VLAN IP range Nuage underlay"; + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/EnableNuageUnderlayVlanIpRangeCmd.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/EnableNuageUnderlayVlanIpRangeCmd.java new file mode 100644 index 00000000000..b1eb9d73032 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/EnableNuageUnderlayVlanIpRangeCmd.java @@ -0,0 +1,110 @@ +// +// 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.api.commands; + +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.ResourceAllocationException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.manager.NuageVspManager; +import com.cloud.utils.exception.CloudRuntimeException; +import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseAsyncCmd; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.SuccessResponse; +import org.apache.cloudstack.api.response.VlanIpRangeResponse; +import org.apache.cloudstack.context.CallContext; + +import javax.inject.Inject; + +@APICommand(name = EnableNuageUnderlayVlanIpRangeCmd.APINAME, description = "enable Nuage underlay on vlan ip range", responseObject = SuccessResponse.class, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, + since = "4.10", + authorized = {RoleType.Admin}) +public class EnableNuageUnderlayVlanIpRangeCmd extends BaseAsyncCmd { + public static final String APINAME = "enableNuageUnderlayVlanIpRange"; + + @Inject + NuageVspManager _nuageVspManager; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = VlanIpRangeResponse.class, required = true, description = "VLAN IP Range ID") + private long vlanIpRangeId; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public long getVlanIpRangeId() { + return vlanIpRangeId; + } + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException { + try { + boolean result = _nuageVspManager.updateNuageUnderlayVlanIpRange(vlanIpRangeId, true); + if (result) { + SuccessResponse response = new SuccessResponse(getCommandName()); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } else { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to enable underlay, VLAN IP range is already pushed to the Nuage VSP device."); + } + } catch (InvalidParameterValueException invalidParamExcp) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, invalidParamExcp.getMessage()); + } catch (CloudRuntimeException runtimeExcp) { + throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, runtimeExcp.getMessage()); + } + } + + @Override + public String getCommandName() { + return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX; + } + + @Override + public long getEntityOwnerId() { + return CallContext.current().getCallingAccount().getId(); + } + + @Override + public String getEventType() { + return "VLAN.ENABLE.NUAGE.UNDERLAY"; + } + + @Override + public String getEventDescription() { + return "Enable VLAN IP range Nuage underlay"; + } + +} \ No newline at end of file diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageUnderlayVlanIpRangesCmd.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageUnderlayVlanIpRangesCmd.java new file mode 100644 index 00000000000..38bc788c37c --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageUnderlayVlanIpRangesCmd.java @@ -0,0 +1,80 @@ +// +// 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.api.commands; + +import com.cloud.api.response.NuageVlanIpRangeResponse; +import com.cloud.dc.Vlan; +import com.cloud.network.manager.NuageVspManager; +import com.cloud.utils.Pair; +import org.apache.cloudstack.acl.RoleType; +import org.apache.cloudstack.api.APICommand; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.Parameter; +import org.apache.cloudstack.api.command.admin.vlan.ListVlanIpRangesCmd; +import org.apache.cloudstack.api.response.ListResponse; + +import javax.inject.Inject; +import java.util.List; + +@APICommand(name = "listNuageUnderlayVlanIpRanges", description = "enable Nuage underlay on vlan ip range", responseObject = NuageVlanIpRangeResponse.class, + requestHasSensitiveInfo = false, responseHasSensitiveInfo = false, + since = "4.10", + authorized = {RoleType.Admin}) +public class ListNuageUnderlayVlanIpRangesCmd extends ListVlanIpRangesCmd { + public static final String APINAME = "listNuageUnderlayVlanIpRanges"; + + @Inject + NuageVspManager _nuageVspManager; + + ///////////////////////////////////////////////////// + //////////////// API parameters ///////////////////// + ///////////////////////////////////////////////////// + + @Parameter(name = VspConstants.NUAGE_VSP_API_UNDERLAY, type = CommandType.BOOLEAN, description = "true to list only underlay enabled, false if not, empty for all") + private Boolean underlay; + + ///////////////////////////////////////////////////// + /////////////////// Accessors /////////////////////// + ///////////////////////////////////////////////////// + + public Boolean getUnderlay() { + return underlay; + } + + + ///////////////////////////////////////////////////// + /////////////// API Implementation/////////////////// + ///////////////////////////////////////////////////// + + @Override + public void execute() { + Pair, Integer> vlans = _mgr.searchForVlans(this); + ListResponse response = new ListResponse(); + List vlanIpRanges = _nuageVspManager.filterNuageVlanIpRanges(vlans.first(), underlay); + response.setResponses(vlanIpRanges); + response.setResponseName(getCommandName()); + this.setResponseObject(response); + } + + @Override + public String getCommandName() { + return APINAME.toLowerCase() + BaseCmd.RESPONSE_SUFFIX; + } +} diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java index 7abcdfb8d03..55e6b474cae 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java @@ -33,4 +33,5 @@ public class VspConstants { public static final String NUAGE_VSP_API_RESOURCE_FILTER = "resourcefilter"; public static final String NUAGE_VSP_API_RESOURCE_INFO = "resourceinfo"; public static final String NUAGE_VSP_CMS_ID = "cmsid"; + public static final String NUAGE_VSP_API_UNDERLAY = "underlay"; } diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVlanIpRangeResponse.java b/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVlanIpRangeResponse.java new file mode 100644 index 00000000000..cc3204d9709 --- /dev/null +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVlanIpRangeResponse.java @@ -0,0 +1,38 @@ +// +// 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.api.response; + +import com.cloud.api.commands.VspConstants; +import com.cloud.dc.Vlan; +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; +import org.apache.cloudstack.api.EntityReference; +import org.apache.cloudstack.api.response.VlanIpRangeResponse; + +@EntityReference(value = Vlan.class) +public class NuageVlanIpRangeResponse extends VlanIpRangeResponse { + @SerializedName(VspConstants.NUAGE_VSP_API_UNDERLAY) + @Param(description = "true if Nuage underlay enabled, false if not") + private boolean underlay; + + public void setUnderlay(boolean underlay) { + this.underlay = underlay; + } +} 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 aae16b89af6..d0b9ed9683f 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 @@ -53,9 +53,11 @@ 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.dc.Vlan; import com.cloud.dc.VlanVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.VlanDao; +import com.cloud.dc.dao.VlanDetailsDao; import com.cloud.deploy.DeployDestination; import com.cloud.domain.Domain; import com.cloud.domain.dao.DomainDao; @@ -71,7 +73,6 @@ import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.NetworkModel; import com.cloud.network.Networks; -import com.cloud.network.NuageVspDeviceVO; import com.cloud.network.PhysicalNetwork; import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PublicIpAddress; @@ -109,8 +110,9 @@ import com.cloud.resource.ResourceStateAdapter; import com.cloud.resource.ServerResource; import com.cloud.resource.UnableDeleteHostException; import com.cloud.util.NuageVspEntityBuilder; +import com.cloud.util.NuageVspUtil; import com.cloud.utils.component.AdapterBase; -import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; @@ -149,6 +151,8 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider @Inject VlanDao _vlanDao; @Inject + VlanDetailsDao _vlanDetailsDao; + @Inject NicDao _nicDao; @Inject VpcDao _vpcDao; @@ -282,7 +286,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider floatingIpUuids.add(ip.getUuid()); } VspDhcpDomainOption vspDhcpOptions = _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering); - HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId()); ImplementVspCommand cmd = new ImplementVspCommand(vspNetwork, ingressFirewallRules, egressFirewallRules, floatingIpUuids, vspDhcpOptions); Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd); if (answer == null || !answer.getResult()) { @@ -353,7 +357,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider NetworkOfferingVO networkOfferingVO = _ntwkOfferingDao.findById(network.getNetworkOfferingId()); VspDhcpDomainOption vspDhcpOptions = _nuageVspEntityBuilder.buildNetworkDhcpOption(network, networkOfferingVO); VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network, false); - HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId()); ShutDownVspCommand cmd = new ShutDownVspCommand(vspNetwork, vspDhcpOptions); Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd); if (answer == null || !answer.getResult()) { @@ -399,8 +403,8 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider return false; } - if ((services.contains(Service.StaticNat)) && (!services.contains(Service.SourceNat))) { - s_logger.warn("Unable to provide StaticNat without the SourceNat service."); + if (!services.contains(Service.SourceNat)) { + s_logger.warn("Unable to support services combination without SourceNat service provided by Nuage VSP."); return false; } @@ -438,6 +442,20 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider } } + 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 (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()) { @@ -481,13 +499,15 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider for (StaticNat staticNat : rules) { IPAddressVO sourceNatIp = _ipAddressDao.findById(staticNat.getSourceIpAddressId()); VlanVO sourceNatVlan = _vlanDao.findById(sourceNatIp.getVlanId()); + checkVlanUnderlayCompatibility(sourceNatVlan); + NicVO nicVO = _nicDao.findByIp4AddressAndNetworkId(staticNat.getDestIpAddress(), staticNat.getNetworkId()); VspStaticNat vspStaticNat = _nuageVspEntityBuilder.buildVspStaticNat(staticNat.isForRevoke(), sourceNatIp, sourceNatVlan, nicVO); vspStaticNatDetails.add(vspStaticNat); } VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(config, false); - HostVO nuageVspHost = getNuageVspHost(config.getPhysicalNetworkId()); + HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(config.getPhysicalNetworkId()); ApplyStaticNatVspCommand cmd = new ApplyStaticNatVspCommand(vspNetwork, vspStaticNatDetails); Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd); if (answer == null || !answer.getResult()) { @@ -500,6 +520,28 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider return true; } + private void checkVlanUnderlayCompatibility(VlanVO newVlan) throws ResourceUnavailableException { + List vlans = _vlanDao.listByZone(newVlan.getDataCenterId()); + if (CollectionUtils.isNotEmpty(vlans)) { + boolean newVlanUnderlay = NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, newVlan); + for (VlanVO vlan : vlans) { + if (vlan.getId() == newVlan.getId()) continue; + + final String newCidr = NetUtils.getCidrFromGatewayAndNetmask(newVlan.getVlanGateway(), newVlan.getVlanNetmask()); + final String existingCidr = NetUtils.getCidrFromGatewayAndNetmask(vlan.getVlanGateway(), vlan.getVlanNetmask()); + + NetUtils.SupersetOrSubset supersetOrSubset = NetUtils.isNetowrkASubsetOrSupersetOfNetworkB(newCidr, existingCidr); + if (supersetOrSubset == NetUtils.SupersetOrSubset.sameSubnet) { + boolean vlanUnderlay = NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, vlan); + if (newVlanUnderlay != vlanUnderlay) { + throw new ResourceUnavailableException("Mixed values for the underlay flag for IP ranges in the same subnet is not supported", Vlan.class, newVlan.getId()); + } + break; + } + } + } + } + @Override public IpDeployer getIpDeployer(Network network) { return this; @@ -536,7 +578,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider } }); - HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId()); VspAclRule.ACLType vspAclType = isNetworkAcl ? VspAclRule.ACLType.NetworkACL : VspAclRule.ACLType.Firewall; ApplyAclRuleVspCommand cmd = new ApplyAclRuleVspCommand(vspAclType, vspNetwork, vspAclRules, networkReset); Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd); @@ -605,7 +647,7 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider }); Domain vpcDomain = _domainDao.findById(vpc.getDomainId()); - HostVO nuageVspHost = getNuageVspHost(getPhysicalNetworkId(vpc.getZoneId())); + HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(getPhysicalNetworkId(vpc.getZoneId())); String preConfiguredDomainTemplateName; VpcDetailVO domainTemplateNameDetail = _vpcDetailsDao.findDetail(vpc.getId(), NuageVspManager.nuageDomainTemplateDetailName); @@ -680,17 +722,4 @@ public class NuageVspElement extends AdapterBase implements ConnectivityProvider } return new DeleteHostAnswer(true); } - - private HostVO getNuageVspHost(Long physicalNetworkId) { - HostVO nuageVspHost; - List nuageVspDevices = _nuageVspDao.listByPhysicalNetwork(physicalNetworkId); - if (nuageVspDevices != null && (!nuageVspDevices.isEmpty())) { - NuageVspDeviceVO config = nuageVspDevices.iterator().next(); - nuageVspHost = _hostDao.findById(config.getHostId()); - _hostDao.loadDetails(nuageVspHost); - } else { - throw new CloudRuntimeException("There is no Nuage VSP device configured on physical network " + physicalNetworkId); - } - return nuageVspHost; - } } \ No newline at end of file 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 aedf646ae1e..6bdd9e496b0 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 @@ -63,7 +63,6 @@ import com.cloud.network.Network.GuestType; import com.cloud.network.Network.State; import com.cloud.network.NetworkProfile; import com.cloud.network.Networks; -import com.cloud.network.NuageVspDeviceVO; import com.cloud.network.PhysicalNetwork; import com.cloud.network.PhysicalNetwork.IsolationMethod; import com.cloud.network.dao.IPAddressVO; @@ -83,7 +82,6 @@ import com.cloud.user.dao.AccountDao; import com.cloud.util.NuageVspEntityBuilder; import com.cloud.utils.StringUtils; import com.cloud.utils.db.DB; -import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.Nic; import com.cloud.vm.NicProfile; import com.cloud.vm.NicVO; @@ -198,7 +196,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { implemented.setBroadcastUri(Networks.BroadcastDomainType.Vsp.toUri(broadcastUriStr)); implemented.setBroadcastDomainType(Networks.BroadcastDomainType.Vsp); - HostVO nuageVspHost = getNuageVspHost(physicalNetworkId); + HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(physicalNetworkId); ImplementNetworkVspCommand cmd = new ImplementNetworkVspCommand(vspNetwork, _nuageVspEntityBuilder.buildNetworkDhcpOption(network, offering)); Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd); @@ -256,7 +254,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { throw new IllegalStateException("The broadcast URI path " + network.getBroadcastUri() + " is empty or in an incorrect format."); } - HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId()); VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network, false); // Set flags for dhcp options @@ -344,7 +342,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { @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)) { + && isMyIsolationMethod(physicalNetwork) && 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"); @@ -360,6 +358,23 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { } } + private boolean hasRequiredServices(NetworkOffering networkOffering) { + if (!_ntwkOfferingSrvcDao.canProviderSupportServiceInNetworkOffering(networkOffering.getId(), Network.Service.Connectivity, 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 (s_logger.isDebugEnabled()) { + s_logger.debug("NuageVsp can't handle networks which use a network offering without NuageVsp as SourceNat provider"); + } + return false; + } + return true; + } + @Override @DB public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) { @@ -379,7 +394,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { VspNetwork vspNetwork = _nuageVspEntityBuilder.buildVspNetwork(network, false); VspVm vspVm = _nuageVspEntityBuilder.buildVspVm(vm.getVirtualMachine(), network); VspNic vspNic = _nuageVspEntityBuilder.buildVspNic(nicFromDb.getUuid(), nic); - HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId()); DeallocateVmVspCommand cmd = new DeallocateVmVspCommand(vspNetwork, vspVm, vspNic); Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd); @@ -431,7 +446,7 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { 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); - HostVO nuageVspHost = getNuageVspHost(network.getPhysicalNetworkId()); + HostVO nuageVspHost = _nuageVspManager.getNuageVspHost(network.getPhysicalNetworkId()); TrashNetworkVspCommand cmd = new TrashNetworkVspCommand(vspNetwork); Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd); if (answer == null || !answer.getResult()) { @@ -447,19 +462,6 @@ public class NuageVspGuestNetworkGuru extends GuestNetworkGuru { return super.trash(network, offering); } - private HostVO getNuageVspHost(long physicalNetworkId) { - HostVO nuageVspHost; - List nuageVspDevices = _nuageVspDao.listByPhysicalNetwork(physicalNetworkId); - if (nuageVspDevices != null && (!nuageVspDevices.isEmpty())) { - NuageVspDeviceVO config = nuageVspDevices.iterator().next(); - nuageVspHost = _hostDao.findById(config.getHostId()); - _hostDao.loadDetails(nuageVspHost); - } else { - throw new CloudRuntimeException("There is no Nuage VSP device configured on physical network " + physicalNetworkId); - } - return nuageVspHost; - } - private boolean networkHasDns(Network network) { if (network != 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 4861fb240df..e5c9871dbef 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 @@ -23,7 +23,10 @@ import com.cloud.api.commands.AddNuageVspDeviceCmd; import com.cloud.api.commands.DeleteNuageVspDeviceCmd; import com.cloud.api.commands.ListNuageVspDevicesCmd; import com.cloud.api.commands.UpdateNuageVspDeviceCmd; +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; @@ -42,6 +45,8 @@ public interface NuageVspManager extends PluggableService { static final String nuageDomainTemplateDetailName = "domainTemplateName"; + static final String nuageUnderlayVlanIpRangeDetailKey = "nuage.underlay"; + static final ConfigKey NuageVspConfigDns = new ConfigKey(Boolean.class, "nuagevsp.configure.dns", "Advanced", "true", "Defines if NuageVsp plugin needs to configure DNS setting for a VM or not. True will configure the DNS and false will not configure the DNS settings", true, Scope.Global, null); @@ -83,4 +88,10 @@ public interface NuageVspManager extends PluggableService { List getGatewaySystemIds(); + HostVO getNuageVspHost(long physicalNetworkId); + + boolean updateNuageUnderlayVlanIpRange(long vlanIpRangeId, boolean enabled); + + List filterNuageVlanIpRanges(List vlanIpRanges, Boolean underlay); + } 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 b82b194be2d..7bc36e27d85 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 @@ -27,6 +27,7 @@ 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.EntityExistsCommand; import com.cloud.agent.api.manager.GetApiDefaultsAnswer; import com.cloud.agent.api.manager.GetApiDefaultsCommand; import com.cloud.agent.api.manager.SupportedApiVersionCommand; @@ -37,11 +38,20 @@ import com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand; import com.cloud.api.ApiDBUtils; import com.cloud.api.commands.AddNuageVspDeviceCmd; import com.cloud.api.commands.DeleteNuageVspDeviceCmd; +import com.cloud.api.commands.DisableNuageUnderlayVlanIpRangeCmd; +import com.cloud.api.commands.EnableNuageUnderlayVlanIpRangeCmd; +import com.cloud.api.commands.ListNuageUnderlayVlanIpRangesCmd; import com.cloud.api.commands.ListNuageVspDevicesCmd; import com.cloud.api.commands.UpdateNuageVspDeviceCmd; +import com.cloud.api.response.NuageVlanIpRangeResponse; import com.cloud.api.response.NuageVspDeviceResponse; import com.cloud.dc.DataCenterVO; +import com.cloud.dc.Vlan; +import com.cloud.dc.VlanDetailsVO; +import com.cloud.dc.VlanVO; import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.dc.dao.VlanDetailsDao; import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; @@ -108,6 +118,7 @@ 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; @@ -185,6 +196,12 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, NetworkOfferingServiceMapDao _networkOfferingServiceMapDao; @Inject NuageVspEntityBuilder _nuageVspEntityBuilder; + @Inject + VlanDao _vlanDao; + @Inject + VlanDetailsDao _vlanDetailsDao; + @Inject + ResponseGenerator _responseGenerator; @Inject MessageBus _messageBus; @@ -209,7 +226,7 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, @Override public List> getCommands() { return Lists.>newArrayList(AddNuageVspDeviceCmd.class, DeleteNuageVspDeviceCmd.class, ListNuageVspDevicesCmd.class, - UpdateNuageVspDeviceCmd.class); + UpdateNuageVspDeviceCmd.class, EnableNuageUnderlayVlanIpRangeCmd.class, DisableNuageUnderlayVlanIpRangeCmd.class, ListNuageUnderlayVlanIpRangesCmd.class); } @Override @@ -677,6 +694,63 @@ public class NuageVspManagerImpl extends ManagerBase implements NuageVspManager, return Lists.newArrayList(); } + @Override + public HostVO getNuageVspHost(long physicalNetworkId) { + HostVO nuageVspHost; + List nuageVspDevices = _nuageVspDao.listByPhysicalNetwork(physicalNetworkId); + if (CollectionUtils.isEmpty(nuageVspDevices)) { + // Perhaps another physical network is passed from within the same zone, find the VSP physical network in that case + PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); + List physicalNetworksInZone = _physicalNetworkDao.listByZone(physicalNetwork.getDataCenterId()); + for (PhysicalNetworkVO physicalNetworkInZone : physicalNetworksInZone) { + if (physicalNetworkInZone.getIsolationMethods().contains(PhysicalNetwork.IsolationMethod.VSP.name())) { + nuageVspDevices = _nuageVspDao.listByPhysicalNetwork(physicalNetworkInZone.getId()); + break; + } + } + } + + if (CollectionUtils.isNotEmpty(nuageVspDevices)) { + NuageVspDeviceVO config = nuageVspDevices.iterator().next(); + nuageVspHost = _hostDao.findById(config.getHostId()); + _hostDao.loadDetails(nuageVspHost); + } else { + throw new CloudRuntimeException("There is no Nuage VSP device configured on physical network " + physicalNetworkId); + } + return nuageVspHost; + } + + @Override + public boolean updateNuageUnderlayVlanIpRange(long vlanIpRangeId, boolean enabled) { + VlanVO staticNatVlan = _vlanDao.findById(vlanIpRangeId); + HostVO nuageVspHost = getNuageVspHost(staticNatVlan.getPhysicalNetworkId()); + EntityExistsCommand cmd = new EntityExistsCommand(Vlan.class, staticNatVlan.getUuid()); + Answer answer = _agentMgr.easySend(nuageVspHost.getId(), cmd); + if (answer != null && !answer.getResult()) { + _vlanDetailsDao.addDetail(staticNatVlan.getId(), NuageVspManager.nuageUnderlayVlanIpRangeDetailKey, String.valueOf(enabled), false); + return true; + } + + return false; + } + + @Override + public List filterNuageVlanIpRanges(List vlanIpRanges, Boolean underlay) { + List nuageVlanIpRanges = Lists.newArrayList(); + for (Vlan vlanIpRange : vlanIpRanges) { + NuageVlanIpRangeResponse nuageVlanIpRange = (NuageVlanIpRangeResponse) _responseGenerator.createVlanIpRangeResponse(NuageVlanIpRangeResponse.class, vlanIpRange); + + VlanDetailsVO nuageUnderlayDetail = _vlanDetailsDao.findDetail(vlanIpRange.getId(), NuageVspManager.nuageUnderlayVlanIpRangeDetailKey); + boolean underlayEnabled = nuageUnderlayDetail != null && nuageUnderlayDetail.getValue().equalsIgnoreCase(String.valueOf(true)); + nuageVlanIpRange.setUnderlay(underlayEnabled); + if (underlay == null || underlayEnabled == underlay) { + nuageVlanIpRanges.add(nuageVlanIpRange); + } + nuageVlanIpRange.setObjectName("nuagevlaniprange"); + } + return nuageVlanIpRanges; + } + @Override public boolean preStateTransitionEvent(Status oldState, Status.Event event, Status newState, Host host, boolean status, Object opaque) { return true; 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 5cb6683c2b5..9d04ab0301a 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 @@ -58,6 +58,7 @@ 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; @@ -65,12 +66,14 @@ 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; @@ -323,6 +326,8 @@ public class NuageVspResource extends ManagerBase implements ServerResource { 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()); @@ -514,6 +519,21 @@ public class NuageVspResource extends ManagerBase implements ServerResource { } } + 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) { throw new ConfigurationException(NUAGE_VSP_PLUGIN_ERROR_MESSAGE); 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 6b0e26ebec2..b1db4fb673f 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 @@ -21,6 +21,7 @@ package com.cloud.util; import com.cloud.dc.VlanVO; import com.cloud.dc.dao.VlanDao; +import com.cloud.dc.dao.VlanDetailsDao; import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; @@ -88,6 +89,8 @@ public class NuageVspEntityBuilder { @Inject VlanDao _vlanDao; @Inject + VlanDetailsDao _vlanDetailsDao; + @Inject ConfigurationDao _configurationDao; @Inject IPAddressDao _ipAddressDao; @@ -291,7 +294,8 @@ public class NuageVspEntityBuilder { .oneToOneNat(staticNatIp.isOneToOneNat()) .vlanUuid(staticNatVlan.getUuid()) .vlanGateway(staticNatVlan.getVlanGateway()) - .vlanNetmask(staticNatVlan.getVlanNetmask()); + .vlanNetmask(staticNatVlan.getVlanNetmask()) + .vlanUnderlay(NuageVspUtil.isUnderlayEnabledForVlan(_vlanDetailsDao, staticNatVlan)); if (nic != null) { VspNic vspNic = buildVspNic(nic); diff --git a/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspUtil.java b/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspUtil.java index fedf048db39..7eff324a738 100644 --- a/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspUtil.java +++ b/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspUtil.java @@ -19,6 +19,9 @@ package com.cloud.util; +import com.cloud.dc.Vlan; +import com.cloud.dc.VlanDetailsVO; +import com.cloud.dc.dao.VlanDetailsDao; import com.cloud.network.Network; import com.cloud.network.dao.NetworkDetailVO; import com.cloud.network.dao.NetworkDetailsDao; @@ -58,4 +61,9 @@ public class NuageVspUtil { byte[] passwordBytes = Base64.decodeBase64(encodedPasswordBytes); return new String(passwordBytes, StringUtils.getPreferredCharset()); } + + public static boolean isUnderlayEnabledForVlan(VlanDetailsDao vlanDetailsDao, Vlan vlan) { + VlanDetailsVO nuageUnderlayDetail = vlanDetailsDao.findDetail(vlan.getId(), NuageVspManager.nuageUnderlayVlanIpRangeDetailKey); + return nuageUnderlayDetail != null && nuageUnderlayDetail.getValue().equalsIgnoreCase(String.valueOf(true)); + } } 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 2a0b07ad992..03fe5eb9170 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 @@ -19,6 +19,17 @@ package com.cloud.agent.api; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.Map; + +import org.junit.Assert; +import org.junit.Test; + +import com.google.common.collect.Maps; +import com.google.common.testing.EqualsTester; +import com.google.gson.Gson; + import com.cloud.agent.api.element.ApplyAclRuleVspCommand; import com.cloud.agent.api.element.ApplyStaticNatVspCommand; import com.cloud.agent.api.element.ImplementVspCommand; @@ -27,71 +38,76 @@ 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.manager.EntityExistsCommand; import com.cloud.agent.api.manager.SupportedApiVersionCommand; import com.cloud.agent.api.sync.SyncDomainCommand; import com.cloud.agent.api.sync.SyncNuageVspCmsIdCommand; -import com.google.common.collect.Maps; -import com.google.common.testing.EqualsTester; -import org.junit.Test; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.Map; +import com.cloud.serializer.GsonHelper; public class CommandsTest { + private static final Gson s_gson = GsonHelper.getGson(); + + private EqualsTester tester = new EqualsTester(); @Test public void testCommandEquals() throws IllegalAccessException, InvocationTargetException, InstantiationException { - ApplyAclRuleVspCommand applyAclRuleVspCommand = fillObject(ApplyAclRuleVspCommand.class); - ApplyAclRuleVspCommand otherApplyAclRuleVspCommand = fillObject(ApplyAclRuleVspCommand.class); + addCommandEqualityGroup(ApplyAclRuleVspCommand.class); + addCommandEqualityGroup(ImplementVspCommand.class); + addCommandEqualityGroup(ApplyStaticNatVspCommand.class); + addCommandEqualityGroup(ShutDownVpcVspCommand.class); + addCommandEqualityGroup(DeallocateVmVspCommand.class); + addCommandEqualityGroup(ImplementNetworkVspCommand.class); + addCommandEqualityGroup(ReserveVmInterfaceVspCommand.class); + addCommandEqualityGroup(TrashNetworkVspCommand.class); + addCommandEqualityGroup(SyncDomainCommand.class); + addCommandEqualityGroup(SyncNuageVspCmsIdCommand.class); + addCommandEqualityGroup(PingNuageVspCommand.class); - ApplyStaticNatVspCommand applyStaticNatVspCommand = fillObject(ApplyStaticNatVspCommand.class); - ApplyStaticNatVspCommand otherApplyStaticNatVspCommand = fillObject(ApplyStaticNatVspCommand.class); + SupportedApiVersionCommand supportedApiVersionCommandA = new SupportedApiVersionCommand("3.2"); + SupportedApiVersionCommand supportedApiVersionCommandB = new SupportedApiVersionCommand("3.2"); - ImplementVspCommand implementVspCommand = fillObject(ImplementVspCommand.class); - ImplementVspCommand otherImplementVspCommand = fillObject(ImplementVspCommand.class); + EntityExistsCommand entityExistsCommandA = new EntityExistsCommand(Command.class, "uuid"); + EntityExistsCommand entityExistsCommandB = new EntityExistsCommand(Command.class, "uuid"); - ShutDownVpcVspCommand shutDownVpcVspCommand = fillObject(ShutDownVpcVspCommand.class); - ShutDownVpcVspCommand otherShutDownVpcVspCommand = fillObject(ShutDownVpcVspCommand.class); + tester + .addEqualityGroup(supportedApiVersionCommandA, supportedApiVersionCommandB) + .addEqualityGroup(entityExistsCommandA, entityExistsCommandB) + .testEquals(); + } - DeallocateVmVspCommand deallocateVmVspCommand = fillObject(DeallocateVmVspCommand.class); - DeallocateVmVspCommand otherDeallocateVmVspCommand = fillObject(DeallocateVmVspCommand.class); + @Test + public void testCommandGsonEquals() throws IllegalAccessException, InvocationTargetException, InstantiationException { + addCommandGsonEqualityGroup(ApplyAclRuleVspCommand.class); + addCommandGsonEqualityGroup(ImplementVspCommand.class); + addCommandGsonEqualityGroup(ApplyStaticNatVspCommand.class); + addCommandGsonEqualityGroup(ShutDownVpcVspCommand.class); + addCommandGsonEqualityGroup(DeallocateVmVspCommand.class); + addCommandGsonEqualityGroup(ImplementNetworkVspCommand.class); + addCommandGsonEqualityGroup(ReserveVmInterfaceVspCommand.class); + addCommandGsonEqualityGroup(TrashNetworkVspCommand.class); + addCommandGsonEqualityGroup(new SupportedApiVersionCommand("3.2")); + addCommandGsonEqualityGroup(SyncDomainCommand.class); + addCommandGsonEqualityGroup(SyncNuageVspCmsIdCommand.class); + addCommandGsonEqualityGroup(PingNuageVspCommand.class); + addCommandGsonEqualityGroup(new EntityExistsCommand(Command.class, "uuid")); - ImplementNetworkVspCommand implementNetworkVspCommand = fillObject(ImplementNetworkVspCommand.class); - ImplementNetworkVspCommand otherImplementNetworkVspCommand = fillObject(ImplementNetworkVspCommand.class); + tester.testEquals(); + } - ReserveVmInterfaceVspCommand reserveVmInterfaceVspCommand = fillObject(ReserveVmInterfaceVspCommand.class); - ReserveVmInterfaceVspCommand otherReserveVmInterfaceVspCommand = fillObject(ReserveVmInterfaceVspCommand.class); + private void addCommandGsonEqualityGroup(Class clazz) throws IllegalAccessException, InvocationTargetException, InstantiationException{ + addCommandGsonEqualityGroup(fillObject(clazz)); + } - TrashNetworkVspCommand trashNetworkVspCommand = fillObject(TrashNetworkVspCommand.class); - TrashNetworkVspCommand otherTrashNetworkVspCommand = fillObject(TrashNetworkVspCommand.class); + private void addCommandGsonEqualityGroup(Command command) throws IllegalAccessException, InvocationTargetException, InstantiationException{ + Command[] forwardedCommands = s_gson.fromJson(s_gson.toJson(new Command[] { command }), Command[].class); + Assert.assertEquals(command, forwardedCommands[0]); + tester.addEqualityGroup(command, forwardedCommands[0]); + } - SupportedApiVersionCommand supportedApiVersionCommand = new SupportedApiVersionCommand("3.2"); - SupportedApiVersionCommand otherSupportedApiVersionCommand = new SupportedApiVersionCommand("3.2"); - - SyncDomainCommand syncDomainCommand = fillObject(SyncDomainCommand.class); - SyncDomainCommand otherSyncDomainCommand = fillObject(SyncDomainCommand.class); - - SyncNuageVspCmsIdCommand syncNuageVspCmsIdCommand = fillObject(SyncNuageVspCmsIdCommand.class); - SyncNuageVspCmsIdCommand otherSyncNuageVspCmsIdCommand = fillObject(SyncNuageVspCmsIdCommand.class); - - PingNuageVspCommand pingNuageVspCommand = fillObject(PingNuageVspCommand.class); - PingNuageVspCommand otherPingNuageVspCommand = fillObject(PingNuageVspCommand.class); - - new EqualsTester() - .addEqualityGroup(applyAclRuleVspCommand, otherApplyAclRuleVspCommand) - .addEqualityGroup(applyStaticNatVspCommand, otherApplyStaticNatVspCommand) - .addEqualityGroup(implementVspCommand, otherImplementVspCommand) - .addEqualityGroup(shutDownVpcVspCommand, otherShutDownVpcVspCommand) - .addEqualityGroup(deallocateVmVspCommand, otherDeallocateVmVspCommand) - .addEqualityGroup(implementNetworkVspCommand, otherImplementNetworkVspCommand) - .addEqualityGroup(reserveVmInterfaceVspCommand, otherReserveVmInterfaceVspCommand) - .addEqualityGroup(trashNetworkVspCommand, otherTrashNetworkVspCommand) - .addEqualityGroup(supportedApiVersionCommand, otherSupportedApiVersionCommand) - .addEqualityGroup(syncDomainCommand, otherSyncDomainCommand) - .addEqualityGroup(syncNuageVspCmsIdCommand, otherSyncNuageVspCmsIdCommand) - .addEqualityGroup(pingNuageVspCommand, otherPingNuageVspCommand) - .testEquals(); + private void addCommandEqualityGroup(Class clazz) throws IllegalAccessException, InvocationTargetException, InstantiationException { + Command a = fillObject(clazz); + Command b = fillObject(clazz); + tester.addEqualityGroup(a, b); } private T fillObject(Class clazz) throws IllegalAccessException, InvocationTargetException, InstantiationException { 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 929aba71993..aad6398f19f 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 @@ -113,6 +113,9 @@ public class NuageVspElementTest extends NuageTest { public void setUp() throws Exception { super.setUp(); _nuageVspElement._nuageVspEntityBuilder = _nuageVspEntityBuilder; + when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true); + when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.SourceNat, Provider.NuageVsp)).thenReturn(true); + _nuageVspElement.configure("NuageVspTestElement", Collections.emptyMap()); } @@ -128,7 +131,6 @@ public class NuageVspElementTest extends NuageTest { when(ntwkoffer.getIsPersistent()).thenReturn(true); when(_networkOfferingDao.findById(NETWORK_ID)).thenReturn(ntwkoffer); - when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true); // Golden path assertTrue(_nuageVspElement.canHandle(net, Service.Connectivity)); @@ -162,7 +164,6 @@ public class NuageVspElementTest extends NuageTest { when(network.getPhysicalNetworkId()).thenReturn(NETWORK_ID); when(network.getDomainId()).thenReturn(NETWORK_ID); when(_networkModel.isProviderForNetwork(Provider.NuageVsp, NETWORK_ID)).thenReturn(true); - when(_networkServiceMapDao.canProviderSupportServiceInNetwork(NETWORK_ID, Service.Connectivity, Provider.NuageVsp)).thenReturn(true); final NetworkOffering offering = mock(NetworkOffering.class); when(offering.getId()).thenReturn(NETWORK_ID); @@ -186,6 +187,7 @@ public class NuageVspElementTest extends NuageTest { 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.getNuageVspHost(NETWORK_ID)).thenReturn(host); 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()); @@ -235,6 +237,7 @@ public class NuageVspElementTest extends NuageTest { 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.getNuageVspHost(NETWORK_ID)).thenReturn(host); when(_domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class)); final Answer answer = mock(Answer.class); @@ -263,6 +266,7 @@ public class NuageVspElementTest extends NuageTest { 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.getNuageVspHost(NETWORK_ID)).thenReturn(host); when(_domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class)); @@ -292,6 +296,7 @@ public class NuageVspElementTest extends NuageTest { 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.getNuageVspHost(NETWORK_ID)).thenReturn(host); when(_domainDao.findById(NETWORK_ID)).thenReturn(mock(DomainVO.class)); final Answer answer = mock(Answer.class); @@ -329,6 +334,7 @@ public class NuageVspElementTest extends NuageTest { when(nuageVspDevice.getHostId()).thenReturn(NETWORK_ID); when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Lists.newArrayList(nuageVspDevice)); when(_hostDao.findById(NETWORK_ID)).thenReturn(host); + when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host); DomainRouterVO domainRouter = mock(DomainRouterVO.class); when(domainRouter.getUuid()).thenReturn("aaaaaa"); 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 d0de4475cb1..fdfc4d5f251 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 @@ -144,6 +144,7 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest { when(_hostDao.findById(NETWORK_ID)).thenReturn(host); when(host.getId()).thenReturn(NETWORK_ID); when(_agentManager.easySend(eq(NETWORK_ID), any(Command.class))).thenReturn(new Answer(null)); + when(_nuageVspManager.getNuageVspHost(NETWORK_ID)).thenReturn(host); final NuageVspDeviceVO device = mock(NuageVspDeviceVO.class); when(_nuageVspDao.listByPhysicalNetwork(NETWORK_ID)).thenReturn(Arrays.asList(device)); @@ -158,7 +159,8 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest { when(offering.getIsPersistent()).thenReturn(false); when(_configurationManager.isOfferingForVpc(any(NetworkOffering.class))).thenReturn(false); - when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(NETWORK_ID, Service.Connectivity)).thenReturn(true); + 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(offering.getTrafficType()).thenReturn(TrafficType.Guest); when(offering.getGuestType()).thenReturn(GuestType.Isolated); @@ -199,7 +201,8 @@ public class NuageVspGuestNetworkGuruTest extends NuageTest { when(offering.getIsPersistent()).thenReturn(false); when(_configurationManager.isOfferingForVpc(any(NetworkOffering.class))).thenReturn(false); - when(_networkOfferingServiceMapDao.areServicesSupportedByNetworkOffering(NETWORK_ID, Service.Connectivity)).thenReturn(true); + when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(NETWORK_ID, Service.Connectivity, Network.Provider.NuageVsp)).thenReturn(true); + when(_networkOfferingServiceMapDao.canProviderSupportServiceInNetworkOffering(NETWORK_ID, Service.SourceNat, Network.Provider.NuageVsp)).thenReturn(true); final DeploymentPlan plan = mock(DeploymentPlan.class); final Network network = mock(Network.class); 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 1ddc106877f..26e36b4e56c 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 @@ -20,8 +20,10 @@ package com.cloud.util; import com.cloud.NuageTest; +import com.cloud.dc.VlanDetailsVO; import com.cloud.dc.VlanVO; import com.cloud.dc.dao.VlanDao; +import com.cloud.dc.dao.VlanDetailsDao; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.network.Network; @@ -58,6 +60,8 @@ import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -77,6 +81,7 @@ public class NuageVspEntityBuilderTest extends NuageTest { private NetworkOfferingDao _networkOfferingDao = mock(NetworkOfferingDao.class); private NetworkOfferingServiceMapDao _networkOfferingServiceMapDao = mock(NetworkOfferingServiceMapDao.class); private VlanDao _vlanDao = mock(VlanDao.class); + private VlanDetailsDao _vlanDetailsDao = mock(VlanDetailsDao.class); private IPAddressDao _ipAddressDao = mock(IPAddressDao.class); private NetworkDetailsDao _networkDetailsDao = mock(NetworkDetailsDao.class); private NuageVspEntityBuilder _nuageVspEntityBuilder = new NuageVspEntityBuilder(); @@ -87,6 +92,7 @@ public class NuageVspEntityBuilderTest extends NuageTest { private NetworkOfferingVO _mockedSharedNetworkOffering = mock(NetworkOfferingVO.class); private NetworkOfferingVO _mockedL2NetworkOffering = mock(NetworkOfferingVO.class); private VlanVO _mockedVlan = mock(VlanVO.class); + private VlanDetailsVO _mockedVlanDetail = mock(VlanDetailsVO.class); private VpcVO _mockedVpc = mock(VpcVO.class); private NetworkVO _mockedNetwork = mock(NetworkVO.class); private NetworkVO _mockedVpcNetwork = mock(NetworkVO.class); @@ -111,6 +117,7 @@ public class NuageVspEntityBuilderTest extends NuageTest { _nuageVspEntityBuilder._networkOfferingDao = _networkOfferingDao; _nuageVspEntityBuilder._networkOfferingServiceMapDao = _networkOfferingServiceMapDao; _nuageVspEntityBuilder._vlanDao = _vlanDao; + _nuageVspEntityBuilder._vlanDetailsDao = _vlanDetailsDao; _nuageVspEntityBuilder._configurationDao = _configurationDao; _nuageVspEntityBuilder._ipAddressDao = _ipAddressDao; _nuageVspEntityBuilder._networkModel = _networkModel; @@ -122,6 +129,7 @@ public class NuageVspEntityBuilderTest extends NuageTest { setUpMockedNetworkOffering(_mockedSharedNetworkOffering, Network.GuestType.Shared); setUpMockedNetworkOffering(_mockedL2NetworkOffering, Network.GuestType.Isolated); setUpMockedVlan(); + setUpMockedVlanDetail(); setUpMockedVpc(); setUpMockedNetwork(_mockedNetwork, NETWORK_OFFERING_ID, null); setUpMockedNetwork(_mockedVpcNetwork, NETWORK_OFFERING_ID, VPC_ID); @@ -319,6 +327,10 @@ public class NuageVspEntityBuilderTest extends NuageTest { when(_mockedVlan.getIpRange()).thenReturn("192.168.2.2-192.168.2.200"); } + private void setUpMockedVlanDetail() { + when(_mockedVlanDetail.getValue()).thenReturn("true"); + } + private void setUpMockedVpc() { when(_mockedVpc.getUuid()).thenReturn("vpcUuid"); when(_mockedVpc.getName()).thenReturn("vpcName"); @@ -406,6 +418,7 @@ public class NuageVspEntityBuilderTest extends NuageTest { when(_networkModel.areServicesSupportedByNetworkOffering(SHARED_NETWORK_OFFERING_ID, Network.Service.Firewall)).thenReturn(true); when(_networkModel.areServicesSupportedByNetworkOffering(L2_NETWORK_OFFERING_ID, Network.Service.Firewall)).thenReturn(true); when(_vlanDao.listVlansByNetworkId(NETWORK_ID)).thenReturn(Lists.newArrayList(_mockedVlan)); + when(_vlanDetailsDao.findDetail(anyLong(), anyString())).thenReturn(_mockedVlanDetail); when(_vpcDao.findById(VPC_ID)).thenReturn(_mockedVpc); when(_ipAddressDao.findById(SOURCE_IP_ADDRESS_ID)).thenReturn(_mockedStaticNatIp); } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 1b4b88ff32d..e661a9bacb6 100644 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -634,83 +634,92 @@ public class ApiResponseHelper implements ResponseGenerator { @Override public VlanIpRangeResponse createVlanIpRangeResponse(Vlan vlan) { - Long podId = ApiDBUtils.getPodIdForVlan(vlan.getId()); + return createVlanIpRangeResponse(VlanIpRangeResponse.class, vlan); + } - VlanIpRangeResponse vlanResponse = new VlanIpRangeResponse(); - vlanResponse.setId(vlan.getUuid()); - if (vlan.getVlanType() != null) { - vlanResponse.setForVirtualNetwork(vlan.getVlanType().equals(VlanType.VirtualNetwork)); - } - vlanResponse.setVlan(vlan.getVlanTag()); - DataCenter zone = ApiDBUtils.findZoneById(vlan.getDataCenterId()); - if (zone != null) { - vlanResponse.setZoneId(zone.getUuid()); - } + @Override + public VlanIpRangeResponse createVlanIpRangeResponse(Class subClass, Vlan vlan) { + try { + Long podId = ApiDBUtils.getPodIdForVlan(vlan.getId()); - if (podId != null) { - HostPodVO pod = ApiDBUtils.findPodById(podId); - if (pod != null) { - vlanResponse.setPodId(pod.getUuid()); - vlanResponse.setPodName(pod.getName()); + VlanIpRangeResponse vlanResponse = subClass.newInstance(); + vlanResponse.setId(vlan.getUuid()); + if (vlan.getVlanType() != null) { + vlanResponse.setForVirtualNetwork(vlan.getVlanType().equals(VlanType.VirtualNetwork)); } - } - - vlanResponse.setGateway(vlan.getVlanGateway()); - vlanResponse.setNetmask(vlan.getVlanNetmask()); - - // get start ip and end ip of corresponding vlan - String ipRange = vlan.getIpRange(); - if (ipRange != null) { - String[] range = ipRange.split("-"); - vlanResponse.setStartIp(range[0]); - vlanResponse.setEndIp(range[1]); - } - - vlanResponse.setIp6Gateway(vlan.getIp6Gateway()); - vlanResponse.setIp6Cidr(vlan.getIp6Cidr()); - - String ip6Range = vlan.getIp6Range(); - if (ip6Range != null) { - String[] range = ip6Range.split("-"); - vlanResponse.setStartIpv6(range[0]); - vlanResponse.setEndIpv6(range[1]); - } - - if (vlan.getNetworkId() != null) { - Network nw = ApiDBUtils.findNetworkById(vlan.getNetworkId()); - if (nw != null) { - vlanResponse.setNetworkId(nw.getUuid()); + vlanResponse.setVlan(vlan.getVlanTag()); + DataCenter zone = ApiDBUtils.findZoneById(vlan.getDataCenterId()); + if (zone != null) { + vlanResponse.setZoneId(zone.getUuid()); } - } - Account owner = ApiDBUtils.getVlanAccount(vlan.getId()); - if (owner != null) { - populateAccount(vlanResponse, owner.getId()); - populateDomain(vlanResponse, owner.getDomainId()); - } else { - Domain domain = ApiDBUtils.getVlanDomain(vlan.getId()); - if (domain != null) { - populateDomain(vlanResponse, domain.getId()); + + if (podId != null) { + HostPodVO pod = ApiDBUtils.findPodById(podId); + if (pod != null) { + vlanResponse.setPodId(pod.getUuid()); + vlanResponse.setPodName(pod.getName()); + } + } + + vlanResponse.setGateway(vlan.getVlanGateway()); + vlanResponse.setNetmask(vlan.getVlanNetmask()); + + // get start ip and end ip of corresponding vlan + String ipRange = vlan.getIpRange(); + if (ipRange != null) { + String[] range = ipRange.split("-"); + vlanResponse.setStartIp(range[0]); + vlanResponse.setEndIp(range[1]); + } + + vlanResponse.setIp6Gateway(vlan.getIp6Gateway()); + vlanResponse.setIp6Cidr(vlan.getIp6Cidr()); + + String ip6Range = vlan.getIp6Range(); + if (ip6Range != null) { + String[] range = ip6Range.split("-"); + vlanResponse.setStartIpv6(range[0]); + vlanResponse.setEndIpv6(range[1]); + } + + if (vlan.getNetworkId() != null) { + Network nw = ApiDBUtils.findNetworkById(vlan.getNetworkId()); + if (nw != null) { + vlanResponse.setNetworkId(nw.getUuid()); + } + } + Account owner = ApiDBUtils.getVlanAccount(vlan.getId()); + if (owner != null) { + populateAccount(vlanResponse, owner.getId()); + populateDomain(vlanResponse, owner.getDomainId()); } else { - Long networkId = vlan.getNetworkId(); - if (networkId != null) { - Network network = _ntwkModel.getNetwork(networkId); - if (network != null) { - Long accountId = network.getAccountId(); - populateAccount(vlanResponse, accountId); - populateDomain(vlanResponse, ApiDBUtils.findAccountById(accountId).getDomainId()); + Domain domain = ApiDBUtils.getVlanDomain(vlan.getId()); + if (domain != null) { + populateDomain(vlanResponse, domain.getId()); + } else { + Long networkId = vlan.getNetworkId(); + if (networkId != null) { + Network network = _ntwkModel.getNetwork(networkId); + if (network != null) { + Long accountId = network.getAccountId(); + populateAccount(vlanResponse, accountId); + populateDomain(vlanResponse, ApiDBUtils.findAccountById(accountId).getDomainId()); + } } } } - } - if (vlan.getPhysicalNetworkId() != null) { - PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(vlan.getPhysicalNetworkId()); - if (pnw != null) { - vlanResponse.setPhysicalNetworkId(pnw.getUuid()); + if (vlan.getPhysicalNetworkId() != null) { + PhysicalNetwork pnw = ApiDBUtils.findPhysicalNetworkById(vlan.getPhysicalNetworkId()); + if (pnw != null) { + vlanResponse.setPhysicalNetworkId(pnw.getUuid()); + } } + vlanResponse.setObjectName("vlan"); + return vlanResponse; + } catch (InstantiationException | IllegalAccessException e) { + throw new CloudRuntimeException("Failed to create Vlan IP Range response", e); } - vlanResponse.setObjectName("vlan"); - return vlanResponse; } @Override diff --git a/setup/db/db/schema-4910to41000.sql b/setup/db/db/schema-4910to41000.sql index 19226b04479..127d7f84f82 100644 --- a/setup/db/db/schema-4910to41000.sql +++ b/setup/db/db/schema-4910to41000.sql @@ -35,4 +35,14 @@ INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervi INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created) VALUES (UUID(), 'KVM', 'default', 'Windows 10', 257, now()); INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created) VALUES (UUID(), 'KVM', 'default', 'Windows 10', 258, now()); -INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created) VALUES (UUID(), 'KVM', 'default', 'Windows Server 2012', 259, now()); \ No newline at end of file +INSERT IGNORE INTO `cloud`.`guest_os_hypervisor` (uuid, hypervisor_type, hypervisor_version, guest_os_name, guest_os_id, created) VALUES (UUID(), 'KVM', 'default', 'Windows Server 2012', 259, now()); + +CREATE TABLE `cloud`.`vlan_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `vlan_id` bigint unsigned NOT NULL COMMENT 'vlan id', + `name` varchar(255) NOT NULL, + `value` varchar(1024) NOT NULL, + `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 diff --git a/test/integration/plugins/nuagevsp/nuageTestCase.py b/test/integration/plugins/nuagevsp/nuageTestCase.py index 5c1daab2e1f..530dcedca5a 100644 --- a/test/integration/plugins/nuagevsp/nuageTestCase.py +++ b/test/integration/plugins/nuagevsp/nuageTestCase.py @@ -40,7 +40,7 @@ from marvin.lib.base import (EgressFireWallRule, from marvin.lib.common import (get_domain, get_template, get_zone) -from marvin.cloudstackAPI import restartVPC +from marvin.cloudstackAPI import restartVPC, listNuageUnderlayVlanIpRanges # Import System Modules import importlib import functools @@ -139,7 +139,7 @@ class nuageTestCase(cloudstackTestCase): cls.api_client, physicalnetworkid=cls.vsp_physical_network.id)[0] - # Take username and password from the datacenter config file, + # Get username and password from the Marvin config file, # as they are not returned by the API. config_nuage_device = next(device for zone in cls.config.zones if zone.name == cls.zone.name @@ -156,6 +156,36 @@ class nuageTestCase(cloudstackTestCase): cls.tearDownClass() raise unittest.SkipTest("Warning: Could not get configured " "Nuage VSP device details - %s" % e) + + # 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 + + # Check if the configured Nuage VSP SDN platform infrastructure + # supports underlay networking + cmd = listNuageUnderlayVlanIpRanges.listNuageUnderlayVlanIpRangesCmd() + cmd.underlay = True + cls.isNuageInfraUnderlay = isinstance( + cls.api_client.listNuageUnderlayVlanIpRanges(cmd), list) return @classmethod @@ -596,8 +626,11 @@ class nuageTestCase(cloudstackTestCase): # wget_from_server - Fetches file with the given file name from a web # server listening on the given public IP address and port - def wget_from_server(self, public_ip, port, file_name="index.html"): + def wget_from_server(self, public_ip, port=80, file_name="index.html", + disable_system_proxies=True): import urllib + if disable_system_proxies: + urllib.getproxies = lambda: {} self.debug("wget file - %s from a http web server listening on " "public IP address - %s and port - %s" % (file_name, public_ip.ipaddress.ipaddress, port)) @@ -606,6 +639,9 @@ class nuageTestCase(cloudstackTestCase): (public_ip.ipaddress.ipaddress, port, file_name), filename=file_name ) + self.debug("Successful to wget file - %s from a http web server " + "listening on public IP address - %s and port - %s" % + (file_name, public_ip.ipaddress.ipaddress, port)) return filename, headers # validate_NetworkServiceProvider - Validates the given Network Service @@ -971,6 +1007,20 @@ class nuageTestCase(cloudstackTestCase): self.assertEqual(vsd_fip.assigned, True, "Floating IP in VSD should be assigned" ) + ext_fip_subnet_filter = self.get_externalID_filter( + public_ipaddress.vlanid) + vsd_fip_subnet = self.vsd.get_shared_network_resource( + filter=ext_fip_subnet_filter) + if self.isNuageInfraUnderlay: + self.assertEqual(vsd_fip_subnet.underlay, True, + "Floating IP subnet in VSD should be underlay " + "enabled" + ) + else: + self.assertEqual(vsd_fip_subnet.underlay, False, + "Floating IP subnet in VSD should be underlay " + "disabled" + ) ext_network_filter = self.get_externalID_filter(vpc.id) if vpc \ else self.get_externalID_filter(network.id) vsd_domain = self.vsd.get_domain(filter=ext_network_filter) diff --git a/test/integration/plugins/nuagevsp/test_nuage_source_nat.py b/test/integration/plugins/nuagevsp/test_nuage_source_nat.py new file mode 100644 index 00000000000..f0b231997e5 --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_source_nat.py @@ -0,0 +1,1454 @@ +# 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 Source NAT functionality with Nuage VSP SDN plugin +""" +# Import Local Modules +from nuageTestCase import nuageTestCase +from marvin.lib.base import (Account, + Network, + VirtualMachine) +# Import System Modules +from nose.plugins.attrib import attr +import copy +import time + + +class TestNuageSourceNat(nuageTestCase): + """Test Source NAT functionality with Nuage VSP SDN plugin + """ + + @classmethod + def setUpClass(cls): + super(TestNuageSourceNat, cls).setUpClass() + return + + def setUp(self): + # Create an account + self.account = Account.create(self.api_client, + self.test_data["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + # verify_vsd_SourceNAT_network - Verifies if Source NAT functionality of + # the given network is enabled in VSD + def verify_vsd_SourceNAT_network(self, network, vpc=None): + self.debug("Verifying if Source NAT functionality of Network - %s is " + "enabled in VSD" % network.name) + 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(filter=ext_network_id_filter) + self.assertEqual(vsd_domain.pat_enabled, "ENABLED", + "VSD domain address translation support " + "(pat_enabled flag) should be enabled for Source NAT " + "service enabled network in CloudStack" + ) + self.assertEqual(vsd_domain.underlay_enabled, "ENABLED", + "VSD domain underlay support (underlay_enabled flag) " + "should be enabled for Source NAT service enabled " + "network in CloudStack" + ) + self.debug("Successfully verified that Source NAT functionality of " + "Network - %s is enabled in VSD" % network.name) + + # verify_SourceNAT_VM_traffic - Verifies Source NAT traffic + # (wget www.google.com) to the Internet from the given VM. This Source NAT + # traffic test is done through a custom init script in the guest VM + # template upon the VM boot up. + def verify_SourceNAT_VM_traffic(self, vm, network, vpc=None, + negative_test=False): + self.debug("Verifying Source NAT traffic (wget www.google.com) to the " + "Internet from VM - %s" % vm.name) + if self.isInternetConnectivityAvailable: + # Adding Egress Network ACL rule + if vpc and self.http_proxy and not negative_test: + self.debug("Adding Egress Network ACL rule in the created VPC " + "network to allow access to the configured " + "Internet proxy servers...") + proxy_rule = copy.deepcopy(self.test_data["http_rule"]) + proxy_rule["privateport"] = 1080 + proxy_rule["publicport"] = 1080 + proxy_rule["startport"] = 1080 + proxy_rule["endport"] = 1080 + internet_proxy_server_rule = self.create_NetworkAclRule( + proxy_rule, traffic_type="Egress", network=network) + + # VSD verification + self.verify_vsd_firewall_rule( + internet_proxy_server_rule, traffic_type="Egress") + + # Triggering Source NAT traffic test + # Rebooting (stop - start) VM + self.debug("Triggering the Source NAT traffic test by rebooting " + "the given VM...") + vm.stop(self.api_client) + vm.start(self.api_client) + self.check_VM_state(vm, state="Running") + + # VSD verification + self.verify_vsd_vm(vm) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network, vpc) + + self.debug("Waiting for the VM to perform the Source NAT traffic " + "test (wget www.google.com) to the Internet...") + time.sleep(180) if negative_test else time.sleep(300) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule to SSH into the VM for " + "verifying its Source NAT traffic test...") + public_ip = self.acquire_PublicIPAddress(network, vpc=vpc) + self.validate_PublicIPAddress(public_ip, network) + self.create_StaticNatRule_For_VM(vm, public_ip, network) + self.validate_PublicIPAddress( + public_ip, network, static_nat=True, vm=vm) + + # VSD verification + updated_vm_info = VirtualMachine.list(self.api_client, id=vm.id)[0] + self.verify_vsd_floating_ip( + network, updated_vm_info, public_ip.ipaddress, vpc=vpc) + + # Adding Ingress Firewall/Network ACL rule + self.debug("Adding Ingress Firewall/Network ACL rule to make the " + "created Static NAT rule (SSH) accessible...") + if vpc: + public_ssh_rule = self.create_NetworkAclRule( + self.test_data["ingress_rule"], network=network) + else: + public_ssh_rule = self.create_FirewallRule( + public_ip, self.test_data["ingress_rule"]) + + # VSD verification + self.verify_vsd_firewall_rule(public_ssh_rule) + + # Checking for wget file + ssh_client = self.ssh_into_VM(vm, public_ip) + cmd = "ls /" + file_list = self.execute_cmd(ssh_client, cmd) + if "index.html" in str(file_list): + cmd = "rm -rf /index.html*" + self.execute_cmd(ssh_client, cmd) + + # Removing Ingress Firewall/Network ACL rule + self.debug("Removing the created Ingress Firewall/Network ACL " + "rule in the network...") + public_ssh_rule.delete(self.api_client) + + # VSD verification + with self.assertRaises(Exception): + self.verify_vsd_firewall_rule(public_ssh_rule) + self.debug("Ingress Firewall/Network ACL rule successfully " + "deleted in VSD") + + # Deleting Static NAT Rule + self.debug("Deleting Static NAT Rule for the VM...") + self.delete_StaticNatRule_For_VM(public_ip) + with self.assertRaises(Exception): + self.validate_PublicIPAddress( + public_ip, network, static_nat=True, vm=vm) + self.debug("Static NAT Rule for the VM successfully deleted in " + "CloudStack") + + # VSD verification + with self.assertRaises(Exception): + self.verify_vsd_floating_ip( + network, updated_vm_info, public_ip.ipaddress, vpc=vpc) + self.debug("Floating IP for the VM successfully deleted in VSD") + + # Releasing acquired public IP + self.debug("Releasing the acquired public IP in the network...") + public_ip.delete(self.api_client) + with self.assertRaises(Exception): + self.validate_PublicIPAddress(public_ip, network) + self.debug("Acquired public IP in the network successfully " + "released in CloudStack") + + # Removing Egress Network ACL rule + if vpc and self.http_proxy: + self.debug("Removing the created Egress Network ACL rule in " + "the VPC network...") + internet_proxy_server_rule.delete(self.api_client) + + # VSD verification + with self.assertRaises(Exception): + self.verify_vsd_firewall_rule(internet_proxy_server_rule) + self.debug("Egress Network ACL rule successfully deleted in " + "VSD") + + # Final test result + if "index.html" in str(file_list): + self.debug("Successfully verified Source NAT traffic " + "(wget www.google.com) to the Internet from VM - %s" + % vm.name) + else: + self.fail("Failed to verify Source NAT traffic " + "(wget www.google.com) to the Internet from VM - %s" + % vm.name) + else: + if negative_test: + self.fail("Skipping Source NAT traffic (wget www.google.com) " + "verification to the Internet from VM as there is " + "no Internet connectivity in the data center") + else: + self.debug("Skipping Source NAT traffic (wget www.google.com) " + "verification to the Internet from VM as there is " + "no Internet connectivity in the data center") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_01_nuage_SourceNAT_isolated_networks(self): + """Test Nuage VSP Isolated networks with different combinations of + 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. + # 2. Recreate the above created Network offering with ispersistent flag + # set to True, check if the network offering is successfully created + # and enabled. + # 3. Recreate the above created Network offering with conserve mode On + # (conserve_mode flag set to True), check if the network offering is + # successfully created and enabled. + # 4. Recreate the above created Network offering with Source NAT + # Service Capability SupportedSourceNatTypes as per account, check + # if the network offering creation failed as Nuage VSP supports only + # SupportedSourceNatTypes as per zone. + # 5. Create an Isolated network with Source NAT service provider as + # NuageVsp and spawn a VM, check if the network is successfully + # created, and the VM along with the VR is deployed successfully in + # the network. Verify if the Source NAT functionality for this + # network is successfully enabled in VSD. + # 6. Create a persistent Isolated network with Source NAT service + # provider as NuageVsp and spawn a VM, check if the network is + # successfully created, and the VM along with the VR is deployed + # successfully in the network. Verify if the Source NAT + # functionality for this network is successfully enabled in VSD. + # 7. Create a conserved Isolated network (conserve mode On) with Source + # NAT service provider as NuageVsp and spawn a VM, check if the + # network is successfully created, and the VM along with the VR is + # deployed successfully in the network. Verify if the Source NAT + # functionality for this network is successfully enabled in VSD. + # 8. Delete all the created objects (cleanup). + + # Creating network offerings + self.debug("Creating Nuage VSP Isolated Network offering with Source " + "NAT service provider as NuageVsp...") + net_off_1 = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"]) + self.validate_NetworkOffering(net_off_1, state="Enabled") + + self.debug("Recreating above Network offering with ispersistent " + "True...") + network_offering = copy.deepcopy( + self.test_data["nuagevsp"]["isolated_network_offering"]) + network_offering["ispersistent"] = "True" + net_off_2 = self.create_NetworkOffering(network_offering) + self.validate_NetworkOffering(net_off_2, state="Enabled") + + self.debug("Recreating above Network offering with conserve mode " + "On...") + net_off_3 = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"], + conserve_mode=True) + self.validate_NetworkOffering(net_off_3, state="Enabled") + + self.debug("Recreating above Network offering with Source NAT Service " + "Capability SupportedSourceNatTypes as per account...") + network_offering = copy.deepcopy( + self.test_data["nuagevsp"]["isolated_network_offering"]) + service_list = network_offering["serviceCapabilityList"] + service_list["SourceNat"]["SupportedSourceNatTypes"] = "peraccount" + network_offering["serviceCapabilityList"] = service_list + with self.assertRaises(Exception): + self.create_NetworkOffering(network_offering) + self.debug("Nuage VSP does not support Network offerings with Source " + "NAT Service Capability " + "SupportedSourceNatTypes as per account") + + self.debug("Creating Nuage VSP Isolated Network offering with Source " + "NAT service provider as VirtualRouter...") + network_offering = copy.deepcopy( + self.test_data["nuagevsp"]["isolated_network_offering"]) + network_offering["serviceProviderList"]["SourceNat"] = "VirtualRouter" + with self.assertRaises(Exception): + self.create_NetworkOffering(network_offering) + self.debug("Nuage VSP does not support Network offerings with Source " + "NAT service provider as VirtualRouter") + + self.debug("Creating Nuage VSP Isolated Network offering without " + "Source NAT service...") + network_offering = copy.deepcopy( + self.test_data["nuagevsp"]["isolated_network_offering"]) + network_offering["supportedservices"] = \ + '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") + + # Creating Isolated networks, and deploying VMs + self.debug("Creating an Isolated network with Source NAT service " + "provider as NuageVsp...") + network_1 = self.create_Network(net_off_1, gateway='10.1.1.1') + self.validate_Network(network_1, state="Allocated") + + self.debug("Deploying a VM in the created Isolated network...") + vm_1 = self.create_VM(network_1) + self.validate_Network(network_1, state="Implemented") + vr_1 = self.get_Router(network_1) + self.check_Router_state(vr_1, state="Running") + self.check_VM_state(vm_1, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_1) + self.verify_vsd_router(vr_1) + self.verify_vsd_vm(vm_1) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network_1) + + # Bug CLOUDSTACK-9398 + """ + self.debug("Creating a persistent Isolated network with Source NAT " + "service...") + network_2 = self.create_Network(net_off_2, gateway='10.1.2.1') + self.validate_Network(network_2, state="Implemented") + vr_2 = self.get_Router(network_2) + self.check_Router_state(vr_2, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_2) + self.verify_vsd_router(vr_2) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network_2) + + self.debug("Deploying a VM in the created Isolated network...") + vm_2 = self.create_VM(network_2) + self.check_VM_state(vm_2, state="Running") + + # VSD verification + self.verify_vsd_vm(vm_2) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network_2) + """ + + self.debug("Creating an Isolated network with Source NAT service and " + "conserve mode On...") + network_3 = self.create_Network(net_off_3, gateway='10.1.3.1') + self.validate_Network(network_3, state="Allocated") + + self.debug("Deploying a VM in the created Isolated network...") + vm_3 = self.create_VM(network_3) + self.validate_Network(network_3, state="Implemented") + vr_3 = self.get_Router(network_3) + self.check_Router_state(vr_3, state="Running") + self.check_VM_state(vm_3, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_3) + self.verify_vsd_router(vr_3) + self.verify_vsd_vm(vm_3) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network_3) + + @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 + NAT service providers + """ + + # 1. Create Nuage VSP VPC offering with different combinations of + # Source NAT service providers + # (NuageVsp, VirtualRouter, no SourceNat service), check if all the + # VPC offerings are successfully created and enabled. + # 2. Create VPCs with different combinations of Source NAT service + # providers (NuageVsp, VirtualRouter, no SourceNat service), check + # if only the VPCs with Source NAT service provider as NuageVsp and + # no SourceNat service are successfully created and enabled. + # 3. Create Nuage VSP VPC 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. + # 4. Recreate the above created Network offering with ispersistent flag + # set to False, check if the network offering is successfully + # created and enabled. + # 5. Recreate the above created Network offering with conserve mode On + # (conserve_mode flag set to True), check if the network offering + # creation failed as only networks with conserve mode Off can belong + # to VPC. + # 6. Recreate the above created Network offering with with Source NAT + # Service Capability SupportedSourceNatTypes as per account, check + # if the network offering creation failed as Nuage VSP supports only + # SupportedSourceNatTypes as per zone. + # 7. Create a VPC network with Source NAT service provider as NuageVsp + # in the VPC with SourceNat service and spawn a VM, check if the + # tier is added to the VPC VR, and the VM is deployed successfully + # in the tier. Verify if the Source NAT functionality for this + # network is successfully enabled in VSD. + # 8. Create a non persistent VPC network with Source NAT service + # provider as NuageVsp in the VPC with SourceNat service and spawn a + # VM, check if the tier creation failed as Nuage VSP does not + # support non persistent VPC networks. + # 9. Create another VPC network with Source NAT service provider as + # NuageVsp in the VPC with SourceNat service and spawn a VM, check + # if the tier is added to the VPC VR, and the VM is deployed + # successfully in the tier. Verify if the Source NAT functionality + # for this network is successfully enabled in VSD. + # 10. Create a VPC network with Source NAT service provider as NuageVsp + # in the VPC without SourceNat service, check if the tier creation + # failed as the VPC does not support Source NAT service. + # 11. Delete all the created objects (cleanup). + + # Creating VPC offerings + self.debug("Creating Nuage VSP VPC offering with Source NAT service " + "provider as NuageVsp...") + vpc_off_1 = self.create_VpcOffering( + self.test_data["nuagevsp"]["vpc_offering"]) + self.validate_VpcOffering(vpc_off_1, state="Enabled") + + self.debug("Creating Nuage VSP VPC offering with Source NAT service " + "provider as VpcVirtualRouter...") + vpc_offering = copy.deepcopy( + self.test_data["nuagevsp"]["vpc_offering"]) + vpc_offering["serviceProviderList"]["SourceNat"] = "VpcVirtualRouter" + vpc_off_2 = self.create_VpcOffering(vpc_offering) + self.validate_VpcOffering(vpc_off_2, state="Enabled") + + self.debug("Creating Nuage VSP VPC offering without Source NAT " + "service...") + vpc_offering = copy.deepcopy( + self.test_data["nuagevsp"]["vpc_offering"]) + vpc_offering["supportedservices"] = \ + 'Dhcp,StaticNat,NetworkACL,Connectivity,UserData,Dns' + del vpc_offering["serviceProviderList"]["SourceNat"] + vpc_off_3 = self.create_VpcOffering(vpc_offering) + self.validate_VpcOffering(vpc_off_3, state="Enabled") + + # Creating VPCs + self.debug("Creating a VPC with Source NAT service provider as " + "NuageVsp...") + vpc_1 = self.create_Vpc(vpc_off_1, cidr='10.1.0.0/16') + self.validate_Vpc(vpc_1, state="Enabled") + + self.debug("Creating a VPC with Source NAT service provider as " + "VpcVirtualRouter...") + with self.assertRaises(Exception): + self.create_Vpc(vpc_off_2, cidr='10.1.0.0/16') + self.debug("Nuage VSP does not support provider VpcVirtualRouter for " + "service Source NAT for VPCs") + + self.debug("Creating a VPC without Source NAT service...") + with self.assertRaises(Exception): + self.create_Vpc(vpc_off_3, cidr='10.1.0.0/16') + self.debug("Nuage VSP does not support VPCs without Source NAT " + "service") + + # Creating network offerings + self.debug("Creating Nuage VSP VPC Network offering with Source NAT " + "service provider as NuageVsp...") + net_off_1 = self.create_NetworkOffering( + self.test_data["nuagevsp"]["vpc_network_offering"]) + self.validate_NetworkOffering(net_off_1, state="Enabled") + + self.debug("Recreating above Network offering with ispersistent " + "False...") + network_offering = copy.deepcopy( + self.test_data["nuagevsp"]["vpc_network_offering"]) + network_offering["ispersistent"] = "False" + net_off_2 = self.create_NetworkOffering(network_offering) + self.validate_NetworkOffering(net_off_2, state="Enabled") + + self.debug("Recreating above Network offering with conserve mode " + "On...") + with self.assertRaises(Exception): + self.create_NetworkOffering( + self.test_data["nuagevsp"]["vpc_network_offering"], + conserve_mode=True) + self.debug("Network offering creation failed as only networks with " + "conserve mode Off can belong to VPC") + + self.debug("Recreating above Network offering with Source NAT Service " + "Capability SupportedSourceNatTypes as per account...") + network_offering = copy.deepcopy( + self.test_data["nuagevsp"]["vpc_network_offering"]) + service_list = network_offering["serviceCapabilityList"] + service_list["SourceNat"]["SupportedSourceNatTypes"] = "peraccount" + network_offering["serviceCapabilityList"] = service_list + with self.assertRaises(Exception): + self.create_NetworkOffering(network_offering) + self.debug("Nuage VSP does not support Network offerings with Source " + "NAT Service Capability SupportedSourceNatTypes as per " + "account") + + self.debug("Creating Nuage VSP VPC Network offering with Source NAT " + "service provider as VpcVirtualRouter...") + network_offering = copy.deepcopy( + self.test_data["nuagevsp"]["vpc_network_offering"]) + network_offering["serviceProviderList"]["SourceNat"] = \ + "VpcVirtualRouter" + with self.assertRaises(Exception): + self.create_NetworkOffering(network_offering) + self.debug("Nuage VSP does not support Network offerings with Source " + "NAT service provider as VpcVirtualRouter") + + self.debug("Creating Nuage VSP VPC Network offering without Source " + "NAT service...") + network_offering = copy.deepcopy( + self.test_data["nuagevsp"]["vpc_network_offering"]) + network_offering["supportedservices"] = \ + 'Dhcp,StaticNat,NetworkACL,Connectivity,UserData,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") + + # Creating VPC networks in the VPCs, and deploying VMs + self.debug("Creating a VPC network with Source NAT service provider " + "as NuageVsp in vpc_1...") + vpc_tier_1 = self.create_Network( + net_off_1, gateway='10.1.1.1', vpc=vpc_1) + self.validate_Network(vpc_tier_1, state="Implemented") + vpc_vr = self.get_Router(vpc_tier_1) + self.check_Router_state(vpc_vr, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier_1, vpc_1) + self.verify_vsd_router(vpc_vr) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(vpc_tier_1, vpc=vpc_1) + + self.debug("Deploying a VM in the created VPC network...") + vpc_vm_1 = self.create_VM(vpc_tier_1) + self.check_VM_state(vpc_vm_1, state="Running") + + # VSD verification + self.verify_vsd_vm(vpc_vm_1) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(vpc_tier_1, vpc=vpc_1) + + self.debug("Creating a non persistent VPC network with Source NAT " + "service in vpc_1...") + with self.assertRaises(Exception): + self.create_Network(net_off_2, gateway='10.1.2.1', vpc=vpc_1) + self.debug("Nuage VSP does not support non persistent VPC networks") + + self.debug("Creating another VPC network with Source NAT service in " + "vpc_1...") + vpc_tier_2 = self.create_Network( + net_off_1, gateway='10.1.2.1', vpc=vpc_1) + self.validate_Network(vpc_tier_2, state="Implemented") + vpc_vr = self.get_Router(vpc_tier_2) + self.check_Router_state(vpc_vr, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier_2, vpc_1) + self.verify_vsd_router(vpc_vr) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(vpc_tier_2, vpc=vpc_1) + + self.debug("Deploying a VM in the created VPC network...") + vpc_vm_2 = self.create_VM(vpc_tier_2) + self.check_VM_state(vpc_vm_2, state="Running") + + # VSD verification + self.verify_vsd_vm(vpc_vm_2) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(vpc_tier_2, vpc=vpc_1) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_03_nuage_SourceNAT_isolated_network_traffic(self): + """Test Nuage VSP Source NAT functionality for Isolated network by + performing (wget) traffic tests to the Internet + """ + + # 1. Check if the configured Nuage VSP SDN platform infrastructure + # supports underlay networking, if not, skip this test. + # 2. Create an Isolated network with Source NAT service provider as + # NuageVsp and spawn a VM, check if the network is successfully + # created, and the VM along with the VR is deployed successfully in + # the network. Verify if the Source NAT functionality for this + # network is successfully enabled in VSD. + # 3. Verify Source NAT traffic test (wget www.google.com) to the + # Internet from the deployed VM. + # 4. Deploy another VM in the created Isolated network, check if the VM + # is deployed successfully in the network. Verify if the Source NAT + # functionality for this network is successfully enabled in VSD. + # 5. Verify Source NAT traffic test (wget www.google.com) to the + # Internet from the deployed VM. + # 6. Delete all the created objects (cleanup). + # Note: Above mentioned Source NAT traffic tests are done through a + # custom init script in the guest VM template upon the VM boot + # up. This traffic tests are verified by SSHing into the VM + # using a Static NAT rule. + + if not self.isNuageInfraUnderlay: + self.skipTest("Configured Nuage VSP SDN platform infrastructure " + "does not support underlay networking: " + "skipping test") + + # Creating network offering + self.debug("Creating Nuage VSP Isolated Network offering with Source " + "NAT service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating Isolated networks, deploying VMs, and verifying Source NAT + # traffic + self.debug("Creating an Isolated network with Source NAT service...") + network = self.create_Network(net_off, gateway='10.1.1.1') + self.validate_Network(network, state="Allocated") + + self.debug("Deploying a VM in the created Isolated 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") + + # VSD verification + self.verify_vsd_network(self.domain.id, network) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm_1) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm_1, network) + + self.debug("Deploying another VM in the created Isolated network...") + vm_2 = self.create_VM(network) + self.check_VM_state(vm_2, state="Running") + + # VSD verification + self.verify_vsd_vm(vm_2) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm_2, network) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_04_nuage_SourceNAT_vpc_network_traffic(self): + """Test Nuage VSP Source NAT functionality for VPC network by + performing (wget) traffic tests to the Internet + """ + + # 1. Check if the configured Nuage VSP SDN platform infrastructure + # supports underlay networking, if not, skip this test. + # 2. Create a VPC network with Source NAT service provider as NuageVsp + # in the VPC with SourceNat service and spawn a VM, check if the + # tier is added to the VPC VR, and the VM is deployed successfully + # in the tier. Verify if the Source NAT functionality for this + # network is successfully enabled in VSD. + # 3. Verify Source NAT traffic test (wget www.google.com) to the + # Internet from the deployed VM. + # 4. Deploy another VM in the created VPC network, check if the VM is + # deployed successfully in the network. Verify if the Source NAT + # functionality for this network is successfully enabled in VSD. + # 5. Verify Source NAT traffic test (wget www.google.com) to the + # Internet from the deployed VM. + # 6. Delete all the created objects (cleanup). + # Note: Above mentioned Source NAT traffic tests are done through a + # custom init script in the guest VM template upon the VM boot + # up. This traffic tests are verified by SSHing into the VM using + # a Static NAT rule. + + if not self.isNuageInfraUnderlay: + self.skipTest("Configured Nuage VSP SDN platform infrastructure " + "does not support underlay networking: " + "skipping test") + + # Creating VPC offering + self.debug("Creating Nuage VSP VPC offering with Source NAT service " + "provider as NuageVsp...") + vpc_off = self.create_VpcOffering( + self.test_data["nuagevsp"]["vpc_offering"]) + self.validate_VpcOffering(vpc_off, state="Enabled") + + # Creating VPC + self.debug("Creating a VPC with Source NAT service provider as " + "NuageVsp...") + vpc = self.create_Vpc(vpc_off, cidr='10.1.0.0/16') + self.validate_Vpc(vpc, state="Enabled") + + # Creating network offering + self.debug("Creating Nuage VSP VPC Network offering with Source NAT " + "service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["vpc_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating VPC networks in the VPC, deploying VMs, and verifying + # Source NAT traffic + self.debug("Creating a VPC network with Source NAT service...") + vpc_tier = self.create_Network(net_off, gateway='10.1.1.1', vpc=vpc) + self.validate_Network(vpc_tier, state="Implemented") + vpc_vr = self.get_Router(vpc_tier) + self.check_Router_state(vpc_vr, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vpc_vr) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(vpc_tier, vpc=vpc) + + # Adding Egress Network ACL rules + self.debug("Adding Egress Network ACL rules in the created VPC " + "network to allow Source NAT (DNS & HTTP) traffic to the " + "Internet from the VMs in the network...") + dns_rule = self.create_NetworkAclRule( + self.test_data["dns_rule"], traffic_type="Egress", + network=vpc_tier) + http_rule = self.create_NetworkAclRule( + self.test_data["http_rule"], traffic_type="Egress", + network=vpc_tier) + + # VSD verification for added Egress Network ACL rules + self.verify_vsd_firewall_rule(dns_rule, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + self.debug("Deploying a VM in the created VPC network...") + vpc_vm_1 = self.create_VM(vpc_tier) + self.check_VM_state(vpc_vm_1, state="Running") + + # VSD verification + self.verify_vsd_vm(vpc_vm_1) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(vpc_tier, vpc=vpc) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vpc_vm_1, vpc_tier, vpc=vpc) + + self.debug("Deploying another VM in the created VPC network...") + vpc_vm_2 = self.create_VM(vpc_tier) + self.check_VM_state(vpc_vm_2, state="Running") + + # VSD verification + self.verify_vsd_vm(vpc_vm_2) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(vpc_tier, vpc=vpc) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vpc_vm_2, vpc_tier, vpc=vpc) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_05_nuage_SourceNAT_acl_rules_traffic(self): + """Test Nuage VSP Source NAT functionality with different Egress + Firewall/Network ACL rules by performing (wget) traffic tests to the + Internet + """ + + # Check if the configured Nuage VSP SDN platform infrastructure + # supports underlay networking, if not, skip this test. + # Repeat the tests in the testcases + # "test_03_nuage_SourceNAT_isolated_network_traffic" and + # "test_04_nuage_SourceNAT_vpc_network_traffic" with different Egress + # Firewall/Network ACL rules: + # 1. Allow and block Egress Firewall rules + # 2. Allow and block Egress Network ACL rules + # Verify the above Egress Firewall/Network ACL rules by verifying its + # Source NAT traffic test (wget www.google.com) to the Internet. + # Delete all the created objects (cleanup). + + if not self.isNuageInfraUnderlay: + self.skipTest("Configured Nuage VSP SDN platform infrastructure " + "does not support underlay networking: " + "skipping test") + + # Creating Isolated network offering + self.debug("Creating Nuage VSP Isolated Network offering with Source " + "NAT service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating an Isolated network, deploying a VM, and verifying Source + # NAT traffic with Egress Firewall rules + self.debug("Creating an Isolated network with Source NAT service...") + network = self.create_Network(net_off, gateway='10.1.1.1') + self.validate_Network(network, state="Allocated") + + self.debug("Deploying a VM in the created Isolated network...") + vm = 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, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm, network) + + # Adding Egress Firewall rule + self.debug("Adding an Egress Firewall rule in the created Isolated " + "network to block/drop Source NAT (DNS) traffic to the " + "Internet from the VMs in the network...") + dns_rule_1 = self.create_EgressFirewallRule( + network, self.test_data["dns_rule"]) + + # VSD verification for added Egress Firewall rule + self.verify_vsd_firewall_rule(dns_rule_1, traffic_type="Egress") + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + with self.assertRaises(Exception): + self.verify_SourceNAT_VM_traffic(vm, network, negative_test=True) + self.debug("Source NAT (DNS) traffic to the Internet from the " + "deployed VM is blocked/dropped by the added Egress " + "Firewall rule") + + # Removing Egress Firewall rule + self.debug("Removing the added Egress Firewall rule in the created " + "Isolated network to allow Source NAT (DNS) traffic to " + "the Internet from the VMs in the network " + "(Default Egress Firewall rule)...") + dns_rule_1.delete(self.api_client) + + # VSD verification for removed Egress Firewall rule + with self.assertRaises(Exception): + self.verify_vsd_firewall_rule(dns_rule_1, traffic_type="Egress") + self.debug("Egress Firewall rule successfully deleted in VSD") + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm, network) + + # Creating VPC offering + self.debug("Creating Nuage VSP VPC offering with Source NAT service " + "provider as NuageVsp...") + vpc_off = self.create_VpcOffering( + self.test_data["nuagevsp"]["vpc_offering"]) + self.validate_VpcOffering(vpc_off, state="Enabled") + + # Creating VPC + self.debug("Creating a VPC with Source NAT service provider as " + "NuageVsp...") + vpc = self.create_Vpc(vpc_off, cidr='10.1.0.0/16') + self.validate_Vpc(vpc, state="Enabled") + + # Creating VPC network offering + self.debug("Creating Nuage VSP VPC Network offering with Source NAT " + "service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["vpc_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating a VPC network in the VPC, deploying a VM, and verifying + # Source NAT traffic with Network ACl rules + self.debug("Creating a VPC network with Source NAT service...") + vpc_tier = self.create_Network(net_off, gateway='10.1.1.1', vpc=vpc) + self.validate_Network(vpc_tier, state="Implemented") + vpc_vr = self.get_Router(vpc_tier) + self.check_Router_state(vpc_vr, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vpc_vr) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(vpc_tier, vpc=vpc) + + # Adding Egress Network ACL rules + self.debug("Adding Egress Network ACL rules in the created VPC " + "network to allow Source NAT (DNS & HTTP) traffic to the " + "Internet from the VMs in the network...") + dns_rule_2 = self.create_NetworkAclRule( + self.test_data["dns_rule"], traffic_type="Egress", + network=vpc_tier) + http_rule = self.create_NetworkAclRule( + self.test_data["http_rule"], traffic_type="Egress", + network=vpc_tier) + + # VSD verification for added Egress Network ACL rules + self.verify_vsd_firewall_rule(dns_rule_2, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + self.debug("Deploying a VM in the created VPC network...") + vpc_vm = self.create_VM(vpc_tier) + self.check_VM_state(vpc_vm, state="Running") + + # VSD verification + self.verify_vsd_vm(vpc_vm) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(vpc_tier, vpc=vpc) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vpc_vm, vpc_tier, vpc=vpc) + + # Removing Egress Network ACL rule + self.debug("Removing the added Egress Network ACL rule in the created " + "VPC network to block Source NAT (DNS) traffic to the " + "Internet from the VMs in the network " + "(Default Egress Network ACL rule)...") + dns_rule_2.delete(self.api_client) + + # VSD verification for removed Egress Network ACL rule + with self.assertRaises(Exception): + self.verify_vsd_firewall_rule(dns_rule_2, traffic_type="Egress") + self.debug("Egress Network ACL rule successfully deleted in VSD") + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + with self.assertRaises(Exception): + self.verify_SourceNAT_VM_traffic(vpc_vm, vpc_tier, vpc=vpc, + negative_test=True) + self.debug("Source NAT (DNS) traffic to the Internet from the " + "deployed VM is blocked by the Default Egress Network ACL " + "rule") + + # Re-adding Egress Network ACL rule + self.debug("Re-adding the Egress Network ACL rule in the created VPC " + "network to allow Source NAT (DNS) traffic to the " + "Internet from the VMs in the network...") + dns_rule_2 = self.create_NetworkAclRule( + self.test_data["dns_rule"], traffic_type="Egress", + network=vpc_tier) + + # VSD verification for re-added Egress Network ACL rule + self.verify_vsd_firewall_rule(dns_rule_2, traffic_type="Egress") + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vpc_vm, vpc_tier, vpc=vpc) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_06_nuage_SourceNAT_vm_nic_operations_traffic(self): + """Test Nuage VSP Source NAT functionality with VM NIC operations by + performing (wget) traffic tests to the + Internet + """ + + # Check if the configured Nuage VSP SDN platform infrastructure + # supports underlay networking, if not, skip this test. + # Repeat the tests in the testcase "test_03_nuage_SourceNAT_isolated_ + # network_traffic" with VM NIC operations: + # 1. Updating default VM NIC + # 2. Removing non-default VM NIC + # 3. Adding and updating default VM NIC + # Verify the above VM NIC operations by verifying its Source NAT + # traffic test (wget www.google.com) to the Internet. + # Delete all the created objects (cleanup). + + if not self.isNuageInfraUnderlay: + self.skipTest("Configured Nuage VSP SDN platform infrastructure " + "does not support underlay networking: " + "skipping test") + + # Creating network offering + self.debug("Creating Nuage VSP Isolated Network offering with Source " + "NAT service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating Isolated networks, deploying a multi-nic VM, and verifying + # Source NAT traffic with VM NIC operations + self.debug("Creating an Isolated network with Source NAT service...") + network_1 = self.create_Network(net_off, gateway='10.1.1.1') + self.validate_Network(network_1, state="Allocated") + + self.debug("Creating another Isolated network with Source NAT " + "service...") + network_2 = self.create_Network(net_off, gateway='10.1.2.1') + self.validate_Network(network_2, state="Allocated") + + self.debug("Deploying a multi-nic VM in the created Isolated " + "networks...") + vm = self.create_VM([network_1, network_2]) + self.validate_Network(network_1, state="Implemented") + vr_1 = self.get_Router(network_1) + self.check_Router_state(vr_1, state="Running") + self.validate_Network(network_2, state="Implemented") + vr_2 = self.get_Router(network_2) + self.check_Router_state(vr_2, state="Running") + self.check_VM_state(vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_1) + self.verify_vsd_router(vr_1) + self.verify_vsd_network(self.domain.id, network_2) + self.verify_vsd_router(vr_2) + self.verify_vsd_vm(vm) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network_1) + self.verify_vsd_SourceNAT_network(network_2) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm, network_1) + + # Updating default VM NIC + # This VM NIC operation has no effect on the Source NAT functionality + self.debug("Updating the default nic of the multi-nic VM...") + self.nic_operation_VM(vm, network_2, operation="update") + + # Rebooting (stop - start) VM + self.debug("Rebooting the multi-nic VM after updating its default nic " + "for changes to apply to the VM...") + vm.stop(self.api_client) + vm.start(self.api_client) + self.check_VM_state(vm, state="Running") + + # VSD verification + updated_vm_info = VirtualMachine.list(self.api_client, id=vm.id)[0] + self.verify_vsd_vm(updated_vm_info) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network_1) + self.verify_vsd_SourceNAT_network(network_2) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm, network_2) + + # Removing non-default VM NIC + # This VM NIC operation has no effect on the Source NAT functionality + self.debug("Removing the non-default nic of the multi-nic VM...") + self.nic_operation_VM(vm, network_1, operation="remove") + + # Rebooting (stop - start) VM + self.debug("Rebooting the multi-nic VM after removing its non-default " + "nic for changes to apply to the VM...") + vm.stop(self.api_client) + vm.start(self.api_client) + self.check_VM_state(vm, state="Running") + + # VSD verification + updated_vm_info = VirtualMachine.list(self.api_client, id=vm.id)[0] + self.verify_vsd_vm(updated_vm_info) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network_1) + self.verify_vsd_SourceNAT_network(network_2) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm, network_2) + + # Adding and updating default VM NIC + # This VM NIC operation has no effect on the Source NAT functionality + self.debug("Re-adding the non-default nic and updating the default " + "nic of the multi-nic VM...") + self.nic_operation_VM(vm, network_1, operation="add") + self.nic_operation_VM(vm, network_1, operation="update") + + # Rebooting (stop - start) VM + self.debug("Rebooting the multi-nic VM after re-adding its " + "non-default nic for changes to apply to the VM...") + vm.stop(self.api_client) + vm.start(self.api_client) + self.check_VM_state(vm, state="Running") + + # VSD verification + updated_vm_info = VirtualMachine.list(self.api_client, id=vm.id)[0] + self.verify_vsd_vm(updated_vm_info) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network_1) + self.verify_vsd_SourceNAT_network(network_2) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm, network_1) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_07_nuage_SourceNAT_vm_migration_traffic(self): + """Test Nuage VSP Source NAT functionality with VM migration by + performing (wget) traffic tests to the Internet + """ + + # Check if the configured Nuage VSP SDN platform infrastructure + # supports underlay networking, if not, skip this test. + # Repeat the tests in the testcase + # "test_03_nuage_SourceNAT_isolated_network_traffic" with migration of + # one of the VMs to another host (if available). + # Verify the above VM migration by verifying its Source NAT traffic + # test (wget www.google.com) to the Internet. + # Delete all the created objects (cleanup). + + if not self.isNuageInfraUnderlay: + self.skipTest("Configured Nuage VSP SDN platform infrastructure " + "does not support underlay networking: " + "skipping test") + + # Creating network offering + self.debug("Creating Nuage VSP Isolated Network offering with Source " + "NAT service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating an Isolated network, deploying VMs, and verifying Source NAT + # traffic with VM migrations + self.debug("Creating an Isolated network with Source NAT service...") + network = self.create_Network(net_off, gateway='10.1.1.1') + self.validate_Network(network, state="Allocated") + + self.debug("Deploying a VM in the created Isolated 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") + + # VSD verification + self.verify_vsd_network(self.domain.id, network) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm_1) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm_1, network) + + self.debug("Deploying another VM in the created Isolated network...") + vm_2 = self.create_VM(network) + self.check_VM_state(vm_2, state="Running") + + # VSD verification + self.verify_vsd_vm(vm_2) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm_2, network) + + # VM migration + # This VM migration has no effect on the Source NAT functionality + self.debug("Migrating one of the VMs in the created Isolated network " + "to another host, if available...") + self.migrate_VM(vm_1) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm_1, network) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm_2, network) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_08_nuage_SourceNAT_network_restarts_traffic(self): + """Test Nuage VSP Source NAT functionality with network restarts by + performing (wget) traffic tests to the Internet + """ + + # Check if the configured Nuage VSP SDN platform infrastructure + # supports underlay networking, if not, skip this test. + # Repeat the tests in the testcases + # "test_03_nuage_SourceNAT_isolated_network_traffic" and + # "test_04_nuage_SourceNAT_vpc_network_traffic" with network restarts: + # 1. Restart Isolated Network (cleanup = false) + # 2. Restart Isolated Network (cleanup = true) + # 3. Reboot VM in the Isolated Network + # 4. Restart VPC Network (cleanup = false) + # 5. Restart VPC Network (cleanup = true) + # 6. Reboot VM in the VPC Network + # 7. Restart VPC (cleanup = false) + # 8. Restart VPC (cleanup = true) + # Verify the above with network restarts by verifying its Source NAT + # traffic test (wget www.google.com) to the Internet. + # Delete all the created objects (cleanup). + + if not self.isNuageInfraUnderlay: + self.skipTest("Configured Nuage VSP SDN platform infrastructure " + "does not support underlay networking: " + "skipping test") + + # Creating network offering + self.debug("Creating Nuage VSP Isolated Network offering with Source " + "NAT service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating an Isolated network, deploying a VM, and verifying Source + # NAT traffic with Isolated network restarts + self.debug("Creating an Isolated network with Source NAT service...") + network = self.create_Network(net_off, gateway='10.1.1.1') + self.validate_Network(network, state="Allocated") + + self.debug("Deploying a VM in the created Isolated network...") + vm = 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, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(network) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm, network) + + # Restarting Isolated network (cleanup = false) + # VR gets destroyed and deployed again in the Isolated network + # This restart has no effect on the Source NAT functionality + self.debug("Restarting the created Isolated network without " + "cleanup...") + Network.restart(network, self.api_client, cleanup=False) + self.validate_Network(network, state="Implemented") + vr = self.get_Router(network) + self.check_Router_state(vr, state="Running") + self.check_VM_state(vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm, network) + + # Restarting Isolated network (cleanup = true) + # VR gets destroyed and deployed again in the Isolated network + # This restart has no effect on the Source NAT functionality + self.debug("Restarting the created Isolated network with cleanup...") + Network.restart(network, self.api_client, cleanup=True) + self.validate_Network(network, state="Implemented") + vr = self.get_Router(network) + self.check_Router_state(vr, state="Running") + self.check_VM_state(vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vm, network) + + # Creating VPC offering + self.debug("Creating Nuage VSP VPC offering with Source NAT service " + "provider as NuageVsp...") + vpc_off = self.create_VpcOffering( + self.test_data["nuagevsp"]["vpc_offering"]) + self.validate_VpcOffering(vpc_off, state="Enabled") + + # Creating VPC + self.debug("Creating a VPC with Source NAT service provider as " + "NuageVsp...") + vpc = self.create_Vpc(vpc_off, cidr='10.1.0.0/16') + self.validate_Vpc(vpc, state="Enabled") + + # Creating VPC network offering + self.debug("Creating Nuage VSP VPC Network offering with Source NAT " + "service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["vpc_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating a VPC network in the VPC, deploying a VM, and verifying + # Source NAT traffic with VPC network restarts + self.debug("Creating a VPC network with Source NAT service...") + vpc_tier = self.create_Network(net_off, gateway='10.1.1.1', vpc=vpc) + self.validate_Network(vpc_tier, state="Implemented") + vpc_vr = self.get_Router(vpc_tier) + self.check_Router_state(vpc_vr, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vpc_vr) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(vpc_tier, vpc=vpc) + + # Adding Egress Network ACL rules + self.debug("Adding Egress Network ACL rules in the created VPC " + "network to allow Source NAT (DNS & HTTP) traffic to the " + "Internet from the VMs in the network...") + dns_rule = self.create_NetworkAclRule( + self.test_data["dns_rule"], traffic_type="Egress", + network=vpc_tier) + http_rule = self.create_NetworkAclRule( + self.test_data["http_rule"], traffic_type="Egress", + network=vpc_tier) + + # VSD verification for added Egress Network ACL rules + self.verify_vsd_firewall_rule(dns_rule, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + self.debug("Deploying a VM in the created VPC network...") + vpc_vm = self.create_VM(vpc_tier) + self.check_VM_state(vpc_vm, state="Running") + + # VSD verification + self.verify_vsd_vm(vpc_vm) + + # VSD verification for Source NAT functionality + self.verify_vsd_SourceNAT_network(vpc_tier, vpc=vpc) + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vpc_vm, vpc_tier, vpc=vpc) + + # Restarting VPC network (cleanup = false) + # This restart has no effect on the Source NAT functionality + self.debug("Restarting the created VPC network without cleanup...") + Network.restart(vpc_tier, self.api_client, cleanup=False) + self.validate_Network(vpc_tier, state="Implemented") + self.check_Router_state(vpc_vr, state="Running") + self.check_VM_state(vpc_vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vpc_vr) + self.verify_vsd_vm(vpc_vm) + self.verify_vsd_firewall_rule(dns_rule, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vpc_vm, vpc_tier, vpc=vpc) + + # Restarting VPC network (cleanup = true) + # This restart has no effect on the Source NAT functionality + self.debug("Restarting the created VPC network with cleanup...") + Network.restart(vpc_tier, self.api_client, cleanup=True) + self.validate_Network(vpc_tier, state="Implemented") + self.check_Router_state(vpc_vr, state="Running") + self.check_VM_state(vpc_vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vpc_vr) + self.verify_vsd_vm(vpc_vm) + self.verify_vsd_firewall_rule(dns_rule, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vpc_vm, vpc_tier, vpc=vpc) + + # Restarting VPC (cleanup = false) + # VPC VR gets destroyed and deployed again in the VPC + # This restart has no effect on the Source NAT functionality + self.debug("Restarting the VPC without cleanup...") + self.restart_Vpc(vpc, cleanup=False) + self.validate_Network(vpc_tier, state="Implemented") + vpc_vr = self.get_Router(vpc_tier) + self.check_Router_state(vpc_vr, state="Running") + self.check_VM_state(vpc_vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vpc_vr) + self.verify_vsd_vm(vpc_vm) + self.verify_vsd_firewall_rule(dns_rule, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vpc_vm, vpc_tier, vpc=vpc) + + # Restarting VPC (cleanup = true) + # VPC VR gets destroyed and deployed again in the VPC + # This restart has no effect on the Source NAT functionality + self.debug("Restarting the VPC with cleanup...") + self.restart_Vpc(vpc, cleanup=True) + self.validate_Network(vpc_tier, state="Implemented") + vpc_vr = self.get_Router(vpc_tier) + self.check_Router_state(vpc_vr, state="Running") + self.check_VM_state(vpc_vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vpc_vr) + self.verify_vsd_vm(vpc_vm) + self.verify_vsd_firewall_rule(dns_rule, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + # Verifying Source NAT traffic (wget www.google.com) to the Internet + # from the deployed VM. This Source NAT traffic test is done through a + # custom init script in the guest VM template upon the VM boot up. + self.verify_SourceNAT_VM_traffic(vpc_vm, vpc_tier, vpc=vpc) diff --git a/test/integration/plugins/nuagevsp/test_nuage_static_nat.py b/test/integration/plugins/nuagevsp/test_nuage_static_nat.py new file mode 100644 index 00000000000..bc35241fe29 --- /dev/null +++ b/test/integration/plugins/nuagevsp/test_nuage_static_nat.py @@ -0,0 +1,2084 @@ +# 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 Static NAT functionality with Nuage VSP SDN plugin +""" +# Import Local Modules +from nuageTestCase import nuageTestCase +from marvin.lib.base import (Account, + PublicIpRange, + Network, + VirtualMachine) +from marvin.cloudstackAPI import (enableNuageUnderlayVlanIpRange, + disableNuageUnderlayVlanIpRange, + listNuageUnderlayVlanIpRanges) +# Import System Modules +from nose.plugins.attrib import attr +import copy +import time + + +class TestNuageStaticNat(nuageTestCase): + """Test Static NAT functionality with Nuage VSP SDN plugin + """ + + @classmethod + def setUpClass(cls): + super(TestNuageStaticNat, cls).setUpClass() + return + + def setUp(self): + # Create an account + self.account = Account.create(self.api_client, + self.test_data["account"], + admin=True, + domainid=self.domain.id + ) + self.cleanup = [self.account] + return + + # enable_NuageUnderlayPublicIpRange - Enables/configures underlay + # networking for the given public IP range in Nuage VSP + def enable_NuageUnderlayPublicIpRange(self, public_ip_range): + cmd = enableNuageUnderlayVlanIpRange.\ + enableNuageUnderlayVlanIpRangeCmd() + cmd.id = public_ip_range.vlan.id + self.api_client.enableNuageUnderlayVlanIpRange(cmd) + + # disable_NuageUnderlayPublicIpRange - Disables/de-configures underlay + # networking for the given public IP range in Nuage VSP + def disable_NuageUnderlayPublicIpRange(self, public_ip_range): + cmd = disableNuageUnderlayVlanIpRange.\ + disableNuageUnderlayVlanIpRangeCmd() + cmd.id = public_ip_range.vlan.id + self.api_client.enableNuageUnderlayVlanIpRange(cmd) + + # list_NuageUnderlayPublicIpRanges - Lists underlay networking + # enabled/configured public IP ranges in Nuage VSP + def list_NuageUnderlayPublicIpRanges(self, public_ip_range=None): + cmd = listNuageUnderlayVlanIpRanges.listNuageUnderlayVlanIpRangesCmd() + if public_ip_range: + cmd.id = public_ip_range.vlan.id + cmd.underlay = True + return self.api_client.listNuageUnderlayVlanIpRanges(cmd) + + # create_PublicIpRange - Creates public IP range + def create_PublicIpRange(self): + self.debug("Creating public IP range") + self.test_data["vlan_ip_range"]["startip"] = "20.200.200.100" + self.test_data["vlan_ip_range"]["endip"] = "20.200.200.200" + self.test_data["vlan_ip_range"]["netmask"] = "255.255.255.0" + self.test_data["vlan_ip_range"]["gateway"] = "20.200.200.1" + self.test_data["vlan_ip_range"]["forvirtualnetwork"] = "true" + self.test_data["vlan_ip_range"]["zoneid"] = self.zone.id + public_ip_range = PublicIpRange.create(self.api_client, + self.test_data["vlan_ip_range"] + ) + self.debug("Created public IP range") + return public_ip_range + + # validate_PublicIpRange - Validates public IP range creation and state + def validate_PublicIpRange(self, public_ip_range): + public_ip_ranges = PublicIpRange.list(self.api_client, + id=public_ip_range.vlan.id + ) + self.assertEqual(isinstance(public_ip_ranges, list), True, + "List Public IP Range should return a valid list" + ) + self.assertEqual(public_ip_range.vlan.startip, + public_ip_ranges[0].startip, + "Start IP of the public IP range should match with " + "the returned list data" + ) + self.assertEqual(public_ip_range.vlan.endip, public_ip_ranges[0].endip, + "End IP of the public IP range should match with the " + "returned list data" + ) + + # validate_NuageUnderlayPublicIpRange - Validates Nuage underlay enabled + # public IP range creation and state + def validate_NuageUnderlayPublicIpRange(self, public_ip_range): + nuage_underlay_public_ip_ranges = \ + self.list_NuageUnderlayPublicIpRanges(public_ip_range) + self.assertEqual(isinstance(nuage_underlay_public_ip_ranges, list), + True, + "List Nuage Underlay Public IP Range should return " + "a valid list" + ) + self.assertEqual(public_ip_range.vlan.startip, + nuage_underlay_public_ip_ranges[0].startip, + "Start IP of the public IP range should match with " + "the returned list data" + ) + self.assertEqual(public_ip_range.vlan.endip, + nuage_underlay_public_ip_ranges[0].endip, + "End IP of the public IP range should match with the " + "returned list data" + ) + + # verify_StaticNAT_traffic - Verifies Static NAT traffic by performing + # wget traffic test with the given Static NAT enabled public IP, http web + # server running on the corresponding VM in the given network + def verify_StaticNAT_traffic(self, network, public_ip, vpc=None, + non_default_nic=False): + # Adding Ingress Firewall/Network ACL rule + self.debug("Adding Ingress Firewall/Network ACL rule to make the " + "created Static NAT rule (wget) accessible...") + if vpc: + public_http_rule = self.create_NetworkAclRule( + self.test_data["http_rule"], network=network) + else: + public_http_rule = self.create_FirewallRule( + public_ip, self.test_data["http_rule"]) + + # VSD verification + self.verify_vsd_firewall_rule(public_http_rule) + + # wget from VM + tries = 0 + max_tries = 3 if non_default_nic else 10 + filename = None + headers = None + while tries < max_tries: + try: + filename, headers = self.wget_from_server(public_ip) + if filename and headers: + self.debug("wget from VM is successful") + break + except Exception as e: + self.debug("Failed to wget from VM - %s" % e) + self.debug("Retrying wget from VM after some time...") + time.sleep(60) + tries += 1 + + if not filename and not headers: + if non_default_nic: + self.debug("Failed to wget from VM via this NIC as it is not " + "the default NIC") + else: + self.fail("Failed to wget from VM") + + # Removing Ingress Firewall/Network ACL rule + self.debug("Removing the created Ingress Firewall/Network ACL " + "rule in the network...") + public_http_rule.delete(self.api_client) + + # VSD verification + with self.assertRaises(Exception): + self.verify_vsd_firewall_rule(public_http_rule) + self.debug("Ingress Firewall/Network ACL rule successfully " + "deleted in VSD") + + self.debug("Successfully verified Static NAT traffic by performing " + "wget traffic test with the given Static NAT enabled " + "public IP - %s" % public_ip) + + # wget_from_internet - From within the given VM (ssh client), + # fetches index.html file of an Internet web server, wget www.google.com + def wget_from_Internet(self, ssh_client, timeout): + if self.http_proxy: + cmd = "wget --no-cache --output-document=index.html " \ + "http://www.google.com/ -e use_proxy=yes -e http_proxy=" + \ + self.http_proxy + " --timeout=" + str(timeout) + else: + cmd = "wget --no-cache --output-document=index.html " \ + "http://www.google.com/ --timeout=" + str(timeout) + test_result = self.execute_cmd(ssh_client, cmd) + if "200 OK" in test_result: + cmd = "rm -rf index.html*" + self.execute_cmd(ssh_client, cmd) + return test_result + + # verify_StaticNAT_Internet_traffic - Verifies Static NAT traffic to the + # Internet (wget www.google.com) from the given VM + def verify_StaticNAT_Internet_traffic(self, vm, network, public_ip, + vpc=None, non_default_nic=False, + negative_test=False): + # Adding Ingress Firewall/Network ACL rule + self.debug("Adding Ingress Firewall/Network ACL rule to make the " + "created Static NAT rule (SSH) accessible...") + if vpc: + public_ssh_rule = self.create_NetworkAclRule( + self.test_data["ingress_rule"], network=network) + else: + public_ssh_rule = self.create_FirewallRule( + public_ip, self.test_data["ingress_rule"]) + + # VSD verification + self.verify_vsd_firewall_rule(public_ssh_rule) + + # Adding Egress Network ACL rule + if vpc and self.http_proxy and not negative_test: + self.debug("Adding Egress Network ACL rule in the created VPC " + "network to allow access to the configured Internet " + "proxy servers...") + proxy_rule = copy.deepcopy(self.test_data["http_rule"]) + proxy_rule["privateport"] = 1080 + proxy_rule["publicport"] = 1080 + proxy_rule["startport"] = 1080 + proxy_rule["endport"] = 1080 + internet_proxy_server_rule = self.create_NetworkAclRule( + proxy_rule, traffic_type="Egress", network=network) + + # VSD verification + self.verify_vsd_firewall_rule( + internet_proxy_server_rule, traffic_type="Egress") + + # SSH into VM + ssh_client = None + if non_default_nic: + with self.assertRaises(Exception): + self.ssh_into_VM(vm, public_ip, negative_test=True) + self.debug("Can not SSH into the VM via this NIC as it is not the " + "default NIC") + else: + ssh_client = self.ssh_into_VM(vm, public_ip) + + # wget from Internet + test_result = None + if ssh_client and self.isInternetConnectivityAvailable: + timeout = 100 if negative_test else 300 + test_result = self.wget_from_Internet(ssh_client, timeout) + + # Removing Ingress Firewall/Network ACL rule + self.debug("Removing the created Ingress Firewall/Network ACL " + "rule in the network...") + public_ssh_rule.delete(self.api_client) + + # VSD verification + with self.assertRaises(Exception): + self.verify_vsd_firewall_rule(public_ssh_rule) + self.debug("Ingress Firewall/Network ACL rule successfully " + "deleted in VSD") + + # Removing Egress Network ACL rule + if vpc and self.http_proxy: + self.debug("Removing the created Egress Network ACL rule in the " + "VPC network...") + internet_proxy_server_rule.delete(self.api_client) + + # VSD verification + with self.assertRaises(Exception): + self.verify_vsd_firewall_rule(internet_proxy_server_rule) + self.debug("Egress Network ACL rule successfully deleted in VSD") + + if test_result: + if "200 OK" in test_result: + self.debug("Successfully verified Static NAT Internet traffic " + "(wget www.google.com) from VM - %s" % vm.name) + else: + self.fail("Failed to verify Static NAT Internet traffic " + "(wget www.google.com) from VM - %s" % vm.name) + else: + if negative_test: + self.fail("Skipped Static NAT Internet traffic " + "(wget www.google.com) test from VM as there is no " + "Internet connectivity in the data center") + else: + self.debug("Skipped Static NAT Internet traffic " + "(wget www.google.com) test from VM as there is no " + "Internet connectivity in the data center") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_01_nuage_StaticNAT_public_ip_range(self): + """Test Nuage VSP Public IP Range creation and deletion + """ + + # 1. Create a public IP range (VLAN IP range), check if it is + # successfully created in the zone and the physical network. + # 2. Delete the created public IP range (VLAN IP range), check if it is + # successfully deleted from the zone and the physical network. + # 3. Delete all the created objects (cleanup). + + self.debug("Creating a public IP range...") + public_ip_range = self.create_PublicIpRange() + self.validate_PublicIpRange(public_ip_range) + self.debug("Public IP range successfully created") + + self.debug("Deleting the created public IP range...") + public_ip_range.delete(self.api_client) + with self.assertRaises(Exception): + self.validate_PublicIpRange(public_ip_range) + self.debug("Public IP range successfully deleted") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_02_nuage_StaticNAT_underlay_public_ip_range(self): + """Test Nuage VSP Nuage Underlay (underlay networking) enabled Public + IP Range creation and deletion + """ + + # 1. Create a public IP range (VLAN IP range), check if it is + # successfully created in the zone and the physical network. + # 2. Enable Nuage underlay capability (underlay networking) for the + # created public IP range (VLAN IP range), check if the Nuage + # underlay (underlay networking) capability is successfully enabled + # for the created public IP range (VLAN IP range). + # 3. Disable Nuage underlay capability (underlay networking) for the + # created public IP range (VLAN IP range), check if the Nuage + # underlay (underlay networking) capability is successfully disabled + # for the created public IP range (VLAN IP range). + # 4. Delete the created public IP range (VLAN IP range), check if it is + # successfully deleted from the zone and the physical network. + # 5. Delete all the created objects (cleanup). + + self.debug("Creating a public IP range...") + public_ip_range = self.create_PublicIpRange() + self.validate_PublicIpRange(public_ip_range) + self.debug("Public IP range successfully created") + + self.debug("Enabling Nuage underlay capability (underlay networking) " + "for the created public IP range...") + self.enable_NuageUnderlayPublicIpRange(public_ip_range) + self.validate_NuageUnderlayPublicIpRange(public_ip_range) + self.debug("Nuage underlay capability (underlay networking) for the " + "created public IP range is successfully enabled") + + self.debug("Disabling Nuage underlay capability (underlay networking) " + "for the created public IP range...") + self.disable_NuageUnderlayPublicIpRange(public_ip_range) + with self.assertRaises(Exception): + self.validate_NuageUnderlayPublicIpRange(public_ip_range) + self.debug("Nuage underlay capability (underlay networking) for the " + "created public IP range is successfully disabled") + + self.debug("Deleting the created public IP range...") + public_ip_range.delete(self.api_client) + with self.assertRaises(Exception): + self.validate_PublicIpRange(public_ip_range) + self.debug("Public IP range successfully deleted") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_03_nuage_StaticNAT_isolated_networks(self): + """Test Nuage VSP Isolated networks with different combinations of + Static NAT service providers + """ + + # 1. Create Nuage VSP Isolated Network offering with different + # combinations of Static NAT service providers + # (NuageVsp, VirtualRouter, no StaticNat service), check if all the + # network offerings are successfully created and enabled. + # 2. Recreate the above created Network offering + # (Static NAT service provider as NuageVsp) with ispersistent flag + # set to True, check if the network offering is successfully created + # and enabled. + # 3. Recreate the above created Network offering + # (Static NAT service provider as NuageVsp) with conserve mode On + # (conserve_mode flag set to True), check if the network offering is + # successfully created and enabled. + # 4. Create an Isolated network with Static NAT service provider as + # NuageVsp, spawn a VM, and create a Static NAT rule. Check if the + # network is successfully created, and the VM along with the VR is + # deployed successfully in the network, verify if the Static NAT + # functionality for this network is successfully enabled in VSD. + # 5. Create a persistent Isolated network with Static NAT service + # provider as NuageVsp, spawn a VM, and create a Static NAT rule. + # Check if the network is successfully created, and the VM along + # with the VR is deployed successfully in the network, verify if the + # Static NAT functionality for this network is successfully enabled + # in VSD. + # 6. Create a conserved Isolated network (conserve mode On) with Static + # NAT service provider as NuageVsp, spawn a VM, and create a Static + # NAT rule. Check if the network is successfully created, and the VM + # along with the VR is deployed successfully in the network, verify + # if the Static NAT functionality for this network is successfully + # enabled in VSD. + # 7. Create an Isolated network with Static NAT service provider as + # VirtualRouter, spawn a VM, and create a Static NAT rule. Check if + # the network is successfully created, and the VM along with the VR + # is deployed successfully in the network, verify if the Static NAT + # functionality for this network is not enabled in VSD as Nuage VSP + # does not support VirtualRouter as the Static NAT service provider. + # 8. Create an Isolated network with no Static NAT service, spawn a VM, + # and create a Static NAT rule. Check if the network is successfully + # created, and the VM along with the VR is deployed successfully in + # the network, verify if the Static NAT functionality for this + # network is not enabled in both CloudStack and VSD as the network + # does not support Static NAT service. + # 9. Delete all the created objects (cleanup). + + # Creating network offerings + self.debug("Creating Nuage VSP Isolated Network offering with Static " + "NAT service provider as NuageVsp...") + net_off_1 = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"]) + self.validate_NetworkOffering(net_off_1, state="Enabled") + + self.debug("Recreating above Network offering with ispersistent " + "True...") + network_offering = copy.deepcopy( + self.test_data["nuagevsp"]["isolated_network_offering"]) + network_offering["ispersistent"] = "True" + net_off_2 = self.create_NetworkOffering(network_offering) + self.validate_NetworkOffering(net_off_2, state="Enabled") + + self.debug("Recreating above Network offering with conserve mode " + "On...") + net_off_3 = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"], + conserve_mode=True) + self.validate_NetworkOffering(net_off_3, state="Enabled") + + self.debug("Creating Nuage VSP Isolated Network offering with Static " + "NAT service provider as VirtualRouter...") + network_offering = copy.deepcopy( + self.test_data["nuagevsp"]["isolated_network_offering"]) + network_offering["serviceProviderList"]["StaticNat"] = "VirtualRouter" + net_off_4 = self.create_NetworkOffering(network_offering) + self.validate_NetworkOffering(net_off_4, state="Enabled") + + self.debug("Creating Nuage VSP Isolated Network offering without " + "Static NAT service...") + network_offering = copy.deepcopy( + self.test_data["nuagevsp"]["isolated_network_offering"]) + network_offering["supportedservices"] = \ + 'Dhcp,SourceNat,Connectivity,UserData,Firewall,Dns' + del network_offering["serviceProviderList"]["StaticNat"] + net_off_5 = self.create_NetworkOffering(network_offering) + self.validate_NetworkOffering(net_off_5, state="Enabled") + + # Creating Isolated networks, and deploying VMs + self.debug("Creating an Isolated network with Static NAT service " + "provider as NuageVsp...") + network_1 = self.create_Network(net_off_1, gateway='10.1.1.1') + self.validate_Network(network_1, state="Allocated") + + self.debug("Deploying a VM in the created Isolated network...") + vm_1 = self.create_VM(network_1) + self.validate_Network(network_1, state="Implemented") + vr_1 = self.get_Router(network_1) + self.check_Router_state(vr_1, state="Running") + self.check_VM_state(vm_1, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_1) + self.verify_vsd_router(vr_1) + self.verify_vsd_vm(vm_1) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule for the deployed VM in the " + "created Isolated network...") + public_ip = self.acquire_PublicIPAddress(network_1) + self.validate_PublicIPAddress(public_ip, network_1) + self.create_StaticNatRule_For_VM(vm_1, public_ip, network_1) + self.validate_PublicIPAddress( + public_ip, network_1, static_nat=True, vm=vm_1) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network_1, vm_1, public_ip.ipaddress) + + # Deleting Static NAT Rule + self.debug("Deleting Static NAT Rule for the deployed VM...") + self.delete_StaticNatRule_For_VM(public_ip) + with self.assertRaises(Exception): + self.validate_PublicIPAddress( + public_ip, network_1, static_nat=True, vm=vm_1) + self.debug("Static NAT Rule for the deployed VM successfully deleted " + "in CloudStack") + + # VSD verification + with self.assertRaises(Exception): + self.verify_vsd_floating_ip(network_1, vm_1, public_ip.ipaddress) + self.debug("Floating IP for the deployed VM successfully deleted in " + "VSD") + + # Releasing acquired public IP + self.debug("Releasing the acquired public IP in the created Isolated " + "network...") + public_ip.delete(self.api_client) + with self.assertRaises(Exception): + self.validate_PublicIPAddress(public_ip, network_1) + self.debug("Acquired public IP in the created Isolated network " + "successfully released in CloudStack") + + # Bug CLOUDSTACK-9398 + """ + self.debug("Creating a persistent Isolated network with Static NAT " + "service...") + network_2 = self.create_Network(net_off_2, gateway='10.1.1.1') + self.validate_Network(network_2, state="Implemented") + vr_2 = self.get_Router(network_2) + self.check_Router_state(vr_2, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_2) + self.verify_vsd_router(vr_2) + + self.debug("Deploying a VM in the created Isolated network...") + vm_2 = self.create_VM(network_2) + self.check_VM_state(vm_2, state="Running") + + # VSD verification + self.verify_vsd_vm(vm_2) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule in the created Isolated network " + "with its deployed VM...") + public_ip = self.acquire_PublicIPAddress(network_2) + self.validate_PublicIPAddress(public_ip, network_2) + self.create_StaticNatRule_For_VM(vm_2, public_ip, network_2) + self.validate_PublicIPAddress( + public_ip, network_2, static_nat=True, vm=vm_2) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network_2, vm_2, public_ip.ipaddress) + + # Deleting Static NAT Rule + self.debug("Deleting Static NAT Rule for the deployed VM...") + self.delete_StaticNatRule_For_VM(public_ip) + with self.assertRaises(Exception): + self.validate_PublicIPAddress( + public_ip, network_2, static_nat=True, vm=vm_2) + self.debug("Static NAT Rule for the deployed VM successfully deleted " + "in CloudStack") + + # VSD verification + with self.assertRaises(Exception): + self.verify_vsd_floating_ip(network_2, vm_2, public_ip.ipaddress) + self.debug("Floating IP for the deployed VM successfully deleted in " + "VSD") + + # Releasing acquired public IP + self.debug("Releasing the acquired public IP in the created Isolated " + "network...") + public_ip.delete(self.api_client) + with self.assertRaises(Exception): + self.validate_PublicIPAddress(public_ip, network_2) + self.debug("Acquired public IP in the created Isolated network " + "successfully released in CloudStack") + """ + + self.debug("Creating an Isolated network with Static NAT service and " + "conserve mode On...") + network_3 = self.create_Network(net_off_3, gateway='10.1.1.1') + self.validate_Network(network_3, state="Allocated") + + self.debug("Deploying a VM in the created Isolated network...") + vm_3 = self.create_VM(network_3) + self.validate_Network(network_3, state="Implemented") + vr_3 = self.get_Router(network_3) + self.check_Router_state(vr_3, state="Running") + self.check_VM_state(vm_3, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_3) + self.verify_vsd_router(vr_3) + self.verify_vsd_vm(vm_3) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule in the created Isolated network " + "with its deployed VM...") + public_ip = self.acquire_PublicIPAddress(network_3) + self.validate_PublicIPAddress(public_ip, network_3) + self.create_StaticNatRule_For_VM(vm_3, public_ip, network_3) + self.validate_PublicIPAddress( + public_ip, network_3, static_nat=True, vm=vm_3) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network_3, vm_3, public_ip.ipaddress) + + # Deleting Static NAT Rule + self.debug("Deleting Static NAT Rule for the deployed VM...") + self.delete_StaticNatRule_For_VM(public_ip) + with self.assertRaises(Exception): + self.validate_PublicIPAddress( + public_ip, network_3, static_nat=True, vm=vm_3) + self.debug("Static NAT Rule for the deployed VM successfully deleted " + "in CloudStack") + + # VSD verification + with self.assertRaises(Exception): + self.verify_vsd_floating_ip(network_3, vm_3, public_ip.ipaddress) + self.debug("Floating IP for the deployed VM successfully deleted in " + "VSD") + + # Releasing acquired public IP + self.debug("Releasing the acquired public IP in the created Isolated " + "network...") + public_ip.delete(self.api_client) + with self.assertRaises(Exception): + self.validate_PublicIPAddress(public_ip, network_3) + self.debug("Acquired public IP in the created Isolated network " + "successfully released in CloudStack") + + self.debug("Creating an Isolated network with Static NAT service " + "provider as VirtualRouter...") + network_4 = self.create_Network(net_off_4, gateway='10.1.1.1') + self.validate_Network(network_4, state="Allocated") + + self.debug("Deploying a VM in the created Isolated network...") + vm_4 = self.create_VM(network_4) + self.validate_Network(network_4, state="Implemented") + vr_4 = self.get_Router(network_4) + self.check_Router_state(vr_4, state="Running") + self.check_VM_state(vm_4, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_4) + self.verify_vsd_router(vr_4) + self.verify_vsd_vm(vm_4) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule in the created Isolated network " + "with its deployed VM...") + public_ip = self.acquire_PublicIPAddress(network_4) + self.validate_PublicIPAddress(public_ip, network_4) + self.create_StaticNatRule_For_VM(vm_4, public_ip, network_4) + self.validate_PublicIPAddress( + public_ip, network_4, static_nat=True, vm=vm_4) + + # VSD verification for Static NAT functionality + with self.assertRaises(Exception): + self.verify_vsd_floating_ip(network_4, vm_4, public_ip.ipaddress) + self.debug("Nuage VSP does not support VirtualRouter as the Static " + "NAT service provider") + + # Deleting Static NAT Rule + self.debug("Deleting Static NAT Rule for the deployed VM...") + self.delete_StaticNatRule_For_VM(public_ip) + with self.assertRaises(Exception): + self.validate_PublicIPAddress( + public_ip, network_4, static_nat=True, vm=vm_4) + self.debug("Static NAT Rule for the deployed VM successfully deleted " + "in CloudStack") + + # Releasing acquired public IP + self.debug("Releasing the acquired public IP in the created Isolated " + "network...") + public_ip.delete(self.api_client) + with self.assertRaises(Exception): + self.validate_PublicIPAddress(public_ip, network_4) + self.debug("Acquired public IP in the created Isolated network " + "successfully released in CloudStack") + + self.debug("Creating an Isolated network with no Static NAT " + "service...") + network_5 = self.create_Network(net_off_5, gateway='10.1.1.1') + self.validate_Network(network_5, state="Allocated") + + self.debug("Deploying a VM in the created Isolated network...") + vm_5 = self.create_VM(network_5) + self.validate_Network(network_5, state="Implemented") + vr_5 = self.get_Router(network_5) + self.check_Router_state(vr_5, state="Running") + self.check_VM_state(vm_5, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_5) + self.verify_vsd_router(vr_5) + self.verify_vsd_vm(vm_5) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule in the created Isolated network " + "with its deployed VM...") + public_ip = self.acquire_PublicIPAddress(network_5) + self.validate_PublicIPAddress(public_ip, network_5) + with self.assertRaises(Exception): + self.create_StaticNatRule_For_VM(vm_5, public_ip, network_5) + self.debug("Static NAT rule creation failed as the network does not " + "support Static NAT service") + + # Releasing acquired public IP + self.debug("Releasing the acquired public IP in the created Isolated " + "network...") + public_ip.delete(self.api_client) + with self.assertRaises(Exception): + self.validate_PublicIPAddress(public_ip, network_5) + self.debug("Acquired public IP in the created Isolated network " + "successfully released in CloudStack") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="false") + def test_04_nuage_StaticNAT_vpc_networks(self): + """Test Nuage VSP VPC networks with different combinations of Static + NAT service providers + """ + + # 1. Create Nuage VSP VPC offering with different combinations of + # Static NAT service providers + # (NuageVsp, VirtualRouter, no StaticNat service), check if all the + # VPC offerings are successfully created and enabled. + # 2. Create VPCs with different combinations of Static NAT service + # providers (NuageVsp, VirtualRouter, no StaticNat service), check + # if only the VPCs with Static NAT service provider as NuageVsp and + # no StaticNat service are successfully created and enabled. + # 3. Create Nuage VSP VPC Network offering with different combinations + # of Static NAT service providers + # (NuageVsp, VirtualRouter, no StaticNat service), check if all the + # network offerings are successfully created and enabled. + # 4. Recreate the above created Network offering + # (Static NAT service provider as NuageVsp) with ispersistent flag + # set to False, check if the network offering is successfully + # created and enabled. + # 5. Recreate the above created Network offering + # (Static NAT service provider as NuageVsp) with conserve mode On + # (conserve_mode flag set to True), check if the network offering + # creation failed as only networks with conserve mode Off can belong + # to VPC. + # 6. Create a VPC network with Static NAT service provider as NuageVsp + # in the VPC with StaticNat service, spawn a VM, and create a Static + # NAT rule. Check if the tier is added to the VPC VR, and the VM is + # deployed successfully in the tier, verify if the Static NAT + # functionality for this network is successfully enabled in VSD. + # 7. Create a non persistent VPC network with Static NAT service + # provider as NuageVsp in the VPC with StaticNat service, spawn a + # VM, and create a Static NAT rule. Check if the tier creation + # failed as Nuage VSP does not support non persistent VPC networks. + # 8. Create a VPC network with Static NAT service provider as + # VpcVirtualRouter in the VPC with StaticNat service, spawn a VM, + # and create a Static NAT rule. Check if the tier is added to the + # VPC VR, and the VM is deployed successfully in the tier, verify if + # the Static NAT functionality for this network is not enabled in + # VSD as Nuage VSP does not support VirtualRouter as the Static NAT + # service provider. + # 9. Create a VPC network with no Static NAT service in the VPC with + # StaticNat service, spawn a VM, and create a Static NAT rule. Check + # if the tier is added to the VPC VR, and the VM is deployed + # successfully in the tier, verify if the Static NAT functionality + # for this network is not enabled in both CloudStack and VSD as the + # network does not support Static NAT service. + # 10. Create a VPC network with Static NAT service provider as NuageVsp + # in the VPC without StaticNat service, check if the tier creation + # failed as the VPC does not support Static NAT service. + # 11. Delete all the created objects (cleanup). + + # Creating VPC offerings + self.debug("Creating Nuage VSP VPC offering with Static NAT service " + "provider as NuageVsp...") + vpc_off_1 = self.create_VpcOffering( + self.test_data["nuagevsp"]["vpc_offering"]) + self.validate_VpcOffering(vpc_off_1, state="Enabled") + + self.debug("Creating Nuage VSP VPC offering with Static NAT service " + "provider as VpcVirtualRouter...") + vpc_offering = copy.deepcopy( + self.test_data["nuagevsp"]["vpc_offering"]) + vpc_offering["serviceProviderList"]["StaticNat"] = "VpcVirtualRouter" + vpc_off_2 = self.create_VpcOffering(vpc_offering) + self.validate_VpcOffering(vpc_off_2, state="Enabled") + + self.debug("Creating Nuage VSP VPC offering without Static NAT " + "service...") + vpc_offering = copy.deepcopy( + self.test_data["nuagevsp"]["vpc_offering"]) + vpc_offering["supportedservices"] = \ + 'Dhcp,SourceNat,NetworkACL,Connectivity,UserData,Dns' + del vpc_offering["serviceProviderList"]["StaticNat"] + vpc_off_3 = self.create_VpcOffering(vpc_offering) + self.validate_VpcOffering(vpc_off_3, state="Enabled") + + # Creating VPCs + self.debug("Creating a VPC with Static NAT service provider as " + "NuageVsp...") + vpc_1 = self.create_Vpc(vpc_off_1, cidr='10.1.0.0/16') + self.validate_Vpc(vpc_1, state="Enabled") + + self.debug("Creating a VPC with Static NAT service provider as " + "VpcVirtualRouter...") + with self.assertRaises(Exception): + self.create_Vpc(vpc_off_2, cidr='10.1.0.0/16') + self.debug("Nuage VSP does not support provider VpcVirtualRouter for " + "service Static NAT for VPCs") + + self.debug("Creating a VPC without Static NAT service...") + vpc_2 = self.create_Vpc(vpc_off_3, cidr='10.1.0.0/16') + self.validate_Vpc(vpc_2, state="Enabled") + + # Creating network offerings + self.debug("Creating Nuage VSP VPC Network offering with Static NAT " + "service provider as NuageVsp...") + net_off_1 = self.create_NetworkOffering( + self.test_data["nuagevsp"]["vpc_network_offering"]) + self.validate_NetworkOffering(net_off_1, state="Enabled") + + self.debug("Recreating above Network offering with ispersistent " + "False...") + network_offering = copy.deepcopy( + self.test_data["nuagevsp"]["vpc_network_offering"]) + network_offering["ispersistent"] = "False" + net_off_2 = self.create_NetworkOffering(network_offering) + self.validate_NetworkOffering(net_off_2, state="Enabled") + + self.debug("Recreating above Network offering with conserve mode " + "On...") + with self.assertRaises(Exception): + self.create_NetworkOffering( + self.test_data["nuagevsp"]["vpc_network_offering"], + conserve_mode=True) + self.debug("Network offering creation failed as only networks with " + "conserve mode Off can belong to VPC") + + self.debug("Creating Nuage VSP VPC Network offering with Static NAT " + "service provider as VpcVirtualRouter...") + network_offering = copy.deepcopy( + self.test_data["nuagevsp"]["vpc_network_offering"]) + network_offering["serviceProviderList"]["StaticNat"] = \ + "VpcVirtualRouter" + net_off_3 = self.create_NetworkOffering(network_offering) + self.validate_NetworkOffering(net_off_3, state="Enabled") + + self.debug("Creating Nuage VSP VPC Network offering without Static " + "NAT service...") + network_offering = copy.deepcopy( + self.test_data["nuagevsp"]["vpc_network_offering"]) + network_offering["supportedservices"] = \ + 'Dhcp,SourceNat,NetworkACL,Connectivity,UserData,Dns' + del network_offering["serviceProviderList"]["StaticNat"] + net_off_4 = self.create_NetworkOffering(network_offering) + self.validate_NetworkOffering(net_off_4, state="Enabled") + + # Creating VPC networks in the VPCs, and deploying VMs + self.debug("Creating a VPC network with Static NAT service provider " + "as NuageVsp in vpc_1...") + vpc_tier_1 = self.create_Network( + net_off_1, gateway='10.1.1.1', vpc=vpc_1) + self.validate_Network(vpc_tier_1, state="Implemented") + vpc_vr = self.get_Router(vpc_tier_1) + self.check_Router_state(vpc_vr, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier_1, vpc_1) + self.verify_vsd_router(vpc_vr) + + self.debug("Deploying a VM in the created VPC network...") + vpc_vm_1 = self.create_VM(vpc_tier_1) + self.check_VM_state(vpc_vm_1, state="Running") + + # VSD verification + self.verify_vsd_vm(vpc_vm_1) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule in the created VPC network with " + "its deployed VM...") + public_ip = self.acquire_PublicIPAddress(vpc_tier_1, vpc=vpc_1) + self.validate_PublicIPAddress(public_ip, vpc_tier_1) + self.create_StaticNatRule_For_VM(vpc_vm_1, public_ip, vpc_tier_1) + self.validate_PublicIPAddress( + public_ip, vpc_tier_1, static_nat=True, vm=vpc_vm_1) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip( + vpc_tier_1, vpc_vm_1, public_ip.ipaddress, vpc=vpc_1) + + # Deleting Static NAT Rule + self.debug("Deleting Static NAT Rule for the deployed VM...") + self.delete_StaticNatRule_For_VM(public_ip) + with self.assertRaises(Exception): + self.validate_PublicIPAddress( + public_ip, vpc_tier_1, static_nat=True, vm=vpc_vm_1) + self.debug("Static NAT Rule for the deployed VM successfully deleted " + "in CloudStack") + + # VSD verification + with self.assertRaises(Exception): + self.verify_vsd_floating_ip( + vpc_tier_1, vpc_vm_1, public_ip.ipaddress, vpc=vpc_1) + self.debug("Floating IP for the deployed VM successfully deleted in " + "VSD") + + # Releasing acquired public IP + self.debug("Releasing the acquired public IP in the created VPC " + "network...") + public_ip.delete(self.api_client) + with self.assertRaises(Exception): + self.validate_PublicIPAddress(public_ip, vpc_tier_1) + self.debug("Acquired public IP in the created VPC network " + "successfully released in CloudStack") + + self.debug("Creating a non persistent VPC network with Static NAT " + "service in vpc_1...") + with self.assertRaises(Exception): + self.create_Network(net_off_2, gateway='10.1.2.1', vpc=vpc_1) + self.debug("Nuage VSP does not support non persistent VPC networks") + + self.debug("Creating a VPC network with Static NAT service provider " + "as VpcVirtualRouter in vpc_1...") + with self.assertRaises(Exception): + self.create_Network(net_off_3, gateway='10.1.2.1', vpc=vpc_1) + self.debug("Provider VpcVirtualRouter is not supported for Static NAT " + "service in VPC vpc_1") + + self.debug("Creating a VPC network with no Static NAT service in " + "vpc_1...") + vpc_tier_2 = self.create_Network( + net_off_4, gateway='10.1.2.1', vpc=vpc_1) + self.validate_Network(vpc_tier_2, state="Implemented") + vpc_vr = self.get_Router(vpc_tier_2) + self.check_Router_state(vpc_vr, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier_2, vpc_1) + self.verify_vsd_router(vpc_vr) + + self.debug("Deploying a VM in the created VPC network...") + vpc_vm_2 = self.create_VM(vpc_tier_2) + self.check_VM_state(vpc_vm_2, state="Running") + + # VSD verification + self.verify_vsd_vm(vpc_vm_2) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule in the created VPC network with " + "its deployed VM...") + public_ip = self.acquire_PublicIPAddress(vpc_tier_2, vpc=vpc_1) + self.validate_PublicIPAddress(public_ip, vpc_tier_2) + with self.assertRaises(Exception): + self.create_StaticNatRule_For_VM(vpc_vm_2, public_ip, vpc_tier_2) + self.debug("Static NAT rule creation failed as the network does not " + "support Static NAT service") + + # Releasing acquired public IP + self.debug("Releasing the acquired public IP in the created VPC " + "network...") + public_ip.delete(self.api_client) + with self.assertRaises(Exception): + self.validate_PublicIPAddress(public_ip, vpc_tier_2) + self.debug("Acquired public IP in the created VPC network " + "successfully released in CloudStack") + + self.debug("Creating a VPC network with Static NAT service provider " + "as NuageVsp in vpc_2...") + with self.assertRaises(Exception): + self.create_Network(net_off_1, gateway='10.1.1.1', vpc=vpc_2) + self.debug("VPC Network creation failed as vpc_2 does not support " + "Static NAT service") + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_05_nuage_StaticNAT_isolated_networks_traffic(self): + """Test Nuage VSP Static NAT functionality for Isolated network by + performing (wget) traffic tests to the Internet + """ + + # 1. Create an Isolated network with Static NAT service provider as + # NuageVsp, spawn a VM, and create a Static NAT rule. Check if the + # network is successfully created, and the VM along with the VR is + # deployed successfully in the network, verify if the Static NAT + # functionality for this network is successfully enabled in VSD. + # 2. Perform and verify Static NAT traffic test (wget www.google.com) + # to the Internet from the deployed VM. + # 3. Deploy another VM in the created Isolated network and create a + # Static NAT rule. Check if the VM is deployed successfully in the + # network, verify if the Static NAT functionality for this network + # is successfully enabled in VSD. + # 4. Perform and verify Static NAT traffic test (wget www.google.com) + # to the Internet from the deployed VM. + # 5. Delete all the created objects (cleanup). + # Note: Above mentioned Static NAT traffic test is done by SSHing into + # the VM using a Static NAT rule, and performing wget traffic + # test (wget www.google.com) to the Internet from the VM. + + # Creating network offering + self.debug("Creating Nuage VSP Isolated Network offering with Static " + "NAT service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating Isolated network, deploying VMs, and verifying Static NAT + # traffic + self.debug("Creating an Isolated network with Static NAT service...") + network = self.create_Network(net_off, gateway='10.1.1.1') + self.validate_Network(network, state="Allocated") + + self.debug("Deploying a VM in the created Isolated 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") + + # VSD verification + self.verify_vsd_network(self.domain.id, network) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm_1) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule for the deployed VM in the " + "created Isolated network...") + public_ip_1 = self.acquire_PublicIPAddress(network) + self.validate_PublicIPAddress(public_ip_1, network) + self.create_StaticNatRule_For_VM(vm_1, public_ip_1, network) + self.validate_PublicIPAddress( + public_ip_1, network, static_nat=True, vm=vm_1) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network, vm_1, public_ip_1.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(network, public_ip_1) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic(vm_1, network, public_ip_1) + + self.debug("Deploying another VM in the created Isolated network...") + vm_2 = self.create_VM(network) + self.check_VM_state(vm_2, state="Running") + + # VSD verification + self.verify_vsd_vm(vm_2) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule for the deployed VM in the " + "created Isolated network...") + public_ip_2 = self.acquire_PublicIPAddress(network) + self.validate_PublicIPAddress(public_ip_2, network) + self.create_StaticNatRule_For_VM(vm_2, public_ip_2, network) + self.validate_PublicIPAddress( + public_ip_2, network, static_nat=True, vm=vm_2) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network, vm_2, public_ip_2.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(network, public_ip_2) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic(vm_2, network, public_ip_2) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_06_nuage_StaticNAT_vpc_network_traffic(self): + """Test Nuage VSP Static NAT functionality for VPC network by + performing (wget) traffic tests to the Internet + """ + + # 1. Create a VPC network with Static NAT service provider as NuageVsp + # in the VPC with StaticNat service, spawn a VM, and create a Static + # NAT rule. Check if the tier is added to the VPC VR, and the VM is + # deployed successfully in the tier, verify if the Static NAT + # functionality for this network is successfully enabled in VSD. + # 2. Perform and verify Static NAT traffic test (wget www.google.com) + # to the Internet from the deployed VM. + # 3. Deploy another VM in the created VPC network and create a Static + # NAT rule. Check if the VM is deployed successfully in the network, + # verify if the Static NAT functionality for this network is + # successfully enabled in VSD. + # 4. Perform and verify Static NAT traffic test (wget www.google.com) + # to the Internet from the deployed VM. + # 5. Delete all the created objects (cleanup). + # Note: Above mentioned Static NAT traffic test is done by SSHing into + # the VM using a Static NAT rule, and performing wget traffic + # test (wget www.google.com) to the Internet from the VM. + + # Creating VPC offering + self.debug("Creating Nuage VSP VPC offering with Static NAT service " + "provider as NuageVsp...") + vpc_off = self.create_VpcOffering( + self.test_data["nuagevsp"]["vpc_offering"]) + self.validate_VpcOffering(vpc_off, state="Enabled") + + # Creating VPC + self.debug("Creating a VPC with Static NAT service provider as " + "NuageVsp...") + vpc = self.create_Vpc(vpc_off, cidr='10.1.0.0/16') + self.validate_Vpc(vpc, state="Enabled") + + # Creating network offering + self.debug("Creating Nuage VSP VPC Network offering with Static NAT " + "service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["vpc_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating VPC network in the VPC, deploying VMs, and verifying Static + # NAT traffic + self.debug("Creating a VPC network with Static NAT service...") + vpc_tier = self.create_Network(net_off, gateway='10.1.1.1', vpc=vpc) + self.validate_Network(vpc_tier, state="Implemented") + vpc_vr = self.get_Router(vpc_tier) + self.check_Router_state(vpc_vr, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vpc_vr) + + # Adding Egress Network ACL rules + self.debug("Adding Egress Network ACL rules in the created VPC " + "network to allow Static NAT (DNS & HTTP) traffic to the " + "Internet from the VMs in the network...") + dns_rule = self.create_NetworkAclRule( + self.test_data["dns_rule"], traffic_type="Egress", + network=vpc_tier) + http_rule = self.create_NetworkAclRule( + self.test_data["http_rule"], traffic_type="Egress", + network=vpc_tier) + + # VSD verification for added Egress Network ACL rules + self.verify_vsd_firewall_rule(dns_rule, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + self.debug("Deploying a VM in the created VPC network...") + vpc_vm_1 = self.create_VM(vpc_tier) + self.check_VM_state(vpc_vm_1, state="Running") + + # VSD verification + self.verify_vsd_vm(vpc_vm_1) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule for the deployed VM in the " + "created VPC network...") + public_ip_1 = self.acquire_PublicIPAddress(vpc_tier, vpc=vpc) + self.validate_PublicIPAddress(public_ip_1, vpc_tier) + self.create_StaticNatRule_For_VM(vpc_vm_1, public_ip_1, vpc_tier) + self.validate_PublicIPAddress( + public_ip_1, vpc_tier, static_nat=True, vm=vpc_vm_1) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip( + vpc_tier, vpc_vm_1, public_ip_1.ipaddress, vpc=vpc) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(vpc_tier, public_ip_1, vpc=vpc) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic( + vpc_vm_1, vpc_tier, public_ip_1, vpc=vpc) + + self.debug("Deploying another VM in the created VPC network...") + vpc_vm_2 = self.create_VM(vpc_tier) + self.check_VM_state(vpc_vm_2, state="Running") + + # VSD verification + self.verify_vsd_vm(vpc_vm_2) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule for the deployed VM in the " + "created VPC network...") + public_ip_2 = self.acquire_PublicIPAddress(vpc_tier, vpc=vpc) + self.validate_PublicIPAddress(public_ip_2, vpc_tier) + self.create_StaticNatRule_For_VM(vpc_vm_2, public_ip_2, vpc_tier) + self.validate_PublicIPAddress( + public_ip_2, vpc_tier, static_nat=True, vm=vpc_vm_2) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip( + vpc_tier, vpc_vm_2, public_ip_2.ipaddress, vpc=vpc) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(vpc_tier, public_ip_2, vpc=vpc) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic( + vpc_vm_2, vpc_tier, public_ip_2, vpc=vpc) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_07_nuage_StaticNAT_acl_rules_traffic(self): + """Test Nuage VSP Static NAT functionality with different Egress + Firewall/Network ACL rules by performing (wget) traffic tests to the + Internet + """ + + # Repeat the tests in the testcases + # "test_05_nuage_StaticNAT_isolated_networks_traffic" and + # "test_06_nuage_StaticNAT_vpc_network_traffic" with different Egress + # Firewall/Network ACL rules: + # 1. Allow and block Egress Firewall rules + # 2. Allow and block Egress Network ACL rules + # Verify the above Egress Firewall/Network ACL rules by performing and + # verifying Static NAT traffic test (wget www.google.com) to the + # Internet from the VM. + # Delete all the created objects (cleanup). + + # Creating network offering + self.debug("Creating Nuage VSP Isolated Network offering with Static " + "NAT service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating Isolated network, deploying VMs, and verifying Static NAT + # traffic with Egress Firewall rules + self.debug("Creating an Isolated network with Static NAT service...") + network = self.create_Network(net_off, gateway='10.1.1.1') + self.validate_Network(network, state="Allocated") + + self.debug("Deploying a VM in the created Isolated network...") + vm = 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, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule for the deployed VM in the " + "created Isolated network...") + public_ip_1 = self.acquire_PublicIPAddress(network) + self.validate_PublicIPAddress(public_ip_1, network) + self.create_StaticNatRule_For_VM(vm, public_ip_1, network) + self.validate_PublicIPAddress( + public_ip_1, network, static_nat=True, vm=vm) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network, vm, public_ip_1.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(network, public_ip_1) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic(vm, network, public_ip_1) + + # Adding Egress Firewall rule + self.debug("Adding an Egress Firewall rule in the created Isolated " + "network to block/drop Static NAT (DNS) traffic to the " + "Internet from the VMs in the network...") + dns_rule_1 = self.create_EgressFirewallRule( + network, self.test_data["dns_rule"]) + + # VSD verification for added Egress Firewall rule + self.verify_vsd_firewall_rule(dns_rule_1, traffic_type="Egress") + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network, vm, public_ip_1.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(network, public_ip_1) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + with self.assertRaises(Exception): + self.verify_StaticNAT_Internet_traffic( + vm, network, public_ip_1, negative_test=True) + self.debug("Static NAT (DNS) traffic to the Internet from the " + "deployed VM is blocked/dropped by the added Egress " + "Firewall rule") + + # Removing Egress Firewall rule + self.debug("Removing the added Egress Firewall rule in the created " + "Isolated network to allow Static NAT (DNS) traffic to " + "the Internet from the VMs in the network " + "(Default Egress Firewall rule)...") + dns_rule_1.delete(self.api_client) + + # VSD verification for removed Egress Firewall rule + with self.assertRaises(Exception): + self.verify_vsd_firewall_rule(dns_rule_1, traffic_type="Egress") + self.debug("Egress Firewall rule successfully deleted in VSD") + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network, vm, public_ip_1.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(network, public_ip_1) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic(vm, network, public_ip_1) + + # Creating VPC offering + self.debug("Creating Nuage VSP VPC offering with Static NAT service " + "provider as NuageVsp...") + vpc_off = self.create_VpcOffering( + self.test_data["nuagevsp"]["vpc_offering"]) + self.validate_VpcOffering(vpc_off, state="Enabled") + + # Creating VPC + self.debug("Creating a VPC with Static NAT service provider as " + "NuageVsp...") + vpc = self.create_Vpc(vpc_off, cidr='10.1.0.0/16') + self.validate_Vpc(vpc, state="Enabled") + + # Creating network offering + self.debug("Creating Nuage VSP VPC Network offering with Static NAT " + "service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["vpc_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating VPC network in the VPC, deploying VMs, and verifying Static + # NAT traffic with Network ACl rules + self.debug("Creating a VPC network with Static NAT service...") + vpc_tier = self.create_Network(net_off, gateway='10.1.1.1', vpc=vpc) + self.validate_Network(vpc_tier, state="Implemented") + vpc_vr = self.get_Router(vpc_tier) + self.check_Router_state(vpc_vr, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vpc_vr) + + # Adding Egress Network ACL rules + self.debug("Adding Egress Network ACL rules in the created VPC " + "network to allow Static NAT (DNS & HTTP) traffic to the " + "Internet from the VMs in the network...") + dns_rule_2 = self.create_NetworkAclRule( + self.test_data["dns_rule"], traffic_type="Egress", + network=vpc_tier) + http_rule = self.create_NetworkAclRule( + self.test_data["http_rule"], traffic_type="Egress", + network=vpc_tier) + + # VSD verification for added Egress Network ACL rules + self.verify_vsd_firewall_rule(dns_rule_2, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + self.debug("Deploying a VM in the created VPC network...") + vpc_vm = self.create_VM(vpc_tier) + self.check_VM_state(vpc_vm, state="Running") + + # VSD verification + self.verify_vsd_vm(vpc_vm) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule for the deployed VM in the " + "created VPC network...") + public_ip_2 = self.acquire_PublicIPAddress(vpc_tier, vpc=vpc) + self.validate_PublicIPAddress(public_ip_2, vpc_tier) + self.create_StaticNatRule_For_VM(vpc_vm, public_ip_2, vpc_tier) + self.validate_PublicIPAddress( + public_ip_2, vpc_tier, static_nat=True, vm=vpc_vm) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip( + vpc_tier, vpc_vm, public_ip_2.ipaddress, vpc=vpc) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(vpc_tier, public_ip_2, vpc=vpc) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic( + vpc_vm, vpc_tier, public_ip_2, vpc=vpc) + + # Removing Egress Network ACL rule + self.debug("Removing the added Egress Network ACL rule in the created " + "VPC network to block Static NAT (DNS) traffic to the " + "Internet from the VMs in the network " + "(Default Egress Network ACL rule)...") + dns_rule_2.delete(self.api_client) + + # VSD verification for removed Egress Network ACL rule + with self.assertRaises(Exception): + self.verify_vsd_firewall_rule(dns_rule_2, traffic_type="Egress") + self.debug("Egress Network ACL rule successfully deleted in VSD") + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip( + vpc_tier, vpc_vm, public_ip_2.ipaddress, vpc=vpc) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(vpc_tier, public_ip_2, vpc=vpc) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + with self.assertRaises(Exception): + self.verify_StaticNAT_Internet_traffic( + vpc_vm, vpc_tier, public_ip_2, vpc=vpc, negative_test=True) + self.debug("Static NAT (DNS) traffic to the Internet from the " + "deployed VM is blocked by the Default Egress Network ACL " + "rule") + + # Re-adding Egress Network ACL rule + self.debug("Re-adding the Egress Network ACL rule in the created VPC " + "network to allow Static NAT (DNS) traffic to the " + "Internet from the VMs in the network...") + dns_rule_2 = self.create_NetworkAclRule( + self.test_data["dns_rule"], traffic_type="Egress", + network=vpc_tier) + + # VSD verification for re-added Egress Network ACL rule + self.verify_vsd_firewall_rule(dns_rule_2, traffic_type="Egress") + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip( + vpc_tier, vpc_vm, public_ip_2.ipaddress, vpc=vpc) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(vpc_tier, public_ip_2, vpc=vpc) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic( + vpc_vm, vpc_tier, public_ip_2, vpc=vpc) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_08_nuage_StaticNAT_vm_nic_operations_traffic(self): + """Test Nuage VSP Static NAT functionality with VM NIC operations by + performing (wget) traffic tests to the Internet + """ + + # Repeat the tests in the testcase + # "test_05_nuage_StaticNAT_isolated_networks_traffic" with VM NIC + # operations: + # 1. Updating default VM NIC + # 2. Removing non-default VM NIC + # 3. Adding and updating default VM NIC + # Verify the above VM NIC operations by performing and verifying Static + # NAT traffic test (wget www.google.com) to the Internet from the VM. + # Delete all the created objects (cleanup). + + # Creating network offering + self.debug("Creating Nuage VSP Isolated Network offering with Static " + "NAT service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating Isolated networks, deploying a multi-nic VM, and verifying + # Static NAT traffic with VM NIC operations + self.debug("Creating an Isolated network with Static NAT service...") + network_1 = self.create_Network(net_off, gateway='10.1.1.1') + self.validate_Network(network_1, state="Allocated") + + self.debug("Creating another Isolated network with Static NAT " + "service...") + network_2 = self.create_Network(net_off, gateway='10.1.1.1') + self.validate_Network(network_2, state="Allocated") + + self.debug("Deploying a multi-nic VM in the created Isolated " + "networks...") + vm = self.create_VM([network_1, network_2]) + self.validate_Network(network_1, state="Implemented") + vr_1 = self.get_Router(network_1) + self.check_Router_state(vr_1, state="Running") + self.validate_Network(network_2, state="Implemented") + vr_2 = self.get_Router(network_2) + self.check_Router_state(vr_2, state="Running") + self.check_VM_state(vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network_1) + self.verify_vsd_router(vr_1) + self.verify_vsd_network(self.domain.id, network_2) + self.verify_vsd_router(vr_2) + self.verify_vsd_vm(vm) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule for the deployed VM in the " + "created Isolated network...") + public_ip_1 = self.acquire_PublicIPAddress(network_1) + self.validate_PublicIPAddress(public_ip_1, network_1) + self.create_StaticNatRule_For_VM(vm, public_ip_1, network_1) + self.validate_PublicIPAddress( + public_ip_1, network_1, static_nat=True, vm=vm) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network_1, vm, public_ip_1.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(network_1, public_ip_1) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic(vm, network_1, public_ip_1) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule for the deployed VM in the " + "created Isolated network...") + public_ip_2 = self.acquire_PublicIPAddress(network_2) + self.validate_PublicIPAddress(public_ip_2, network_2) + self.create_StaticNatRule_For_VM(vm, public_ip_2, network_2) + self.validate_PublicIPAddress( + public_ip_2, network_2, static_nat=True, vm=vm) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network_2, vm, public_ip_2.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic( + network_2, public_ip_2, non_default_nic=True) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic( + vm, network_2, public_ip_2, non_default_nic=True) + + # Updating default VM NIC + self.debug("Updating the default nic of the multi-nic VM...") + self.nic_operation_VM(vm, network_2, operation="update") + + # Rebooting (stop - start) VM + self.debug("Rebooting the multi-nic VM after updating its default nic " + "for changes to apply to the VM...") + vm.stop(self.api_client) + vm.start(self.api_client) + self.check_VM_state(vm, state="Running") + + # VSD verification + updated_vm_info = VirtualMachine.list(self.api_client, id=vm.id)[0] + self.verify_vsd_vm(updated_vm_info) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network_1, vm, public_ip_1.ipaddress) + self.verify_vsd_floating_ip(network_2, vm, public_ip_2.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic( + network_1, public_ip_1, non_default_nic=True) + self.verify_StaticNAT_traffic(network_2, public_ip_2) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic( + vm, network_1, public_ip_1, non_default_nic=True) + self.verify_StaticNAT_Internet_traffic(vm, network_2, public_ip_2) + + # Removing non-default VM NIC + self.debug("Removing the non-default nic of the multi-nic VM...") + with self.assertRaises(Exception): + self.nic_operation_VM(vm, network_1, operation="remove") + self.debug("Can not remove this NIC as Static NAT rule is enabled on " + "it") + + # Deleting Static NAT Rule + self.debug("Deleting Static NAT Rule for the deployed VM...") + self.delete_StaticNatRule_For_VM(public_ip_1) + with self.assertRaises(Exception): + self.validate_PublicIPAddress( + public_ip_1, network_1, static_nat=True, vm=vm) + self.debug("Static NAT Rule for the deployed VM successfully deleted " + "in CloudStack") + + # VSD verification + with self.assertRaises(Exception): + self.verify_vsd_floating_ip(network_1, vm, public_ip_1.ipaddress) + self.debug("Floating IP for the deployed VM successfully deleted in " + "VSD") + + self.nic_operation_VM(vm, network_1, operation="remove") + + # Rebooting (stop - start) VM + self.debug("Rebooting the multi-nic VM after removing its non-default " + "nic for changes to apply to the VM...") + vm.stop(self.api_client) + vm.start(self.api_client) + self.check_VM_state(vm, state="Running") + + # VSD verification + updated_vm_info = VirtualMachine.list(self.api_client, id=vm.id)[0] + self.verify_vsd_vm(updated_vm_info) + + # VSD verification for Static NAT functionality + with self.assertRaises(Exception): + self.verify_vsd_floating_ip(network_1, vm, public_ip_1.ipaddress) + self.debug("Static NAT rule not enabled in this VM NIC") + self.verify_vsd_floating_ip(network_2, vm, public_ip_2.ipaddress) + + # Verifying Static NAT traffic + with self.assertRaises(Exception): + self.verify_StaticNAT_traffic(network_1, public_ip_1) + self.debug("Static NAT rule not enabled in this VM NIC") + self.verify_StaticNAT_traffic(network_2, public_ip_2) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + with self.assertRaises(Exception): + self.verify_StaticNAT_Internet_traffic(vm, network_1, public_ip_1) + self.debug("Static NAT rule not enabled in this VM NIC") + self.verify_StaticNAT_Internet_traffic(vm, network_2, public_ip_2) + + # Adding and updating default VM NIC + self.debug("Re-adding the non-default nic and updating the default " + "nic of the multi-nic VM...") + self.nic_operation_VM(vm, network_1, operation="add") + self.nic_operation_VM(vm, network_1, operation="update") + + # Rebooting (stop - start) VM + self.debug("Rebooting the multi-nic VM after re-adding its " + "non-default nic for changes to apply to the VM...") + vm.stop(self.api_client) + vm.start(self.api_client) + self.check_VM_state(vm, state="Running") + + # VSD verification + updated_vm_info = VirtualMachine.list(self.api_client, id=vm.id)[0] + self.verify_vsd_vm(updated_vm_info) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule for the deployed VM in the " + "created Isolated network...") + self.create_StaticNatRule_For_VM(vm, public_ip_1, network_1) + self.validate_PublicIPAddress( + public_ip_1, network_1, static_nat=True, vm=vm) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network_1, vm, public_ip_1.ipaddress) + self.verify_vsd_floating_ip(network_2, vm, public_ip_2.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(network_1, public_ip_1) + self.verify_StaticNAT_traffic( + network_2, public_ip_2, non_default_nic=True) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic(vm, network_1, public_ip_1) + self.verify_StaticNAT_Internet_traffic( + vm, network_2, public_ip_2, non_default_nic=True) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_09_nuage_StaticNAT_vm_migration_traffic(self): + """Test Nuage VSP Static NAT functionality with VM migration by + performing (wget) traffic tests to the Internet + """ + + # Repeat the tests in the testcase + # "test_05_nuage_StaticNAT_isolated_networks_traffic" with migration of + # one of the VMs to another host (if available). + # Verify the above VM migration by performing and verifying Static NAT + # traffic test (wget www.google.com) to the Internet from the VM. + # Delete all the created objects (cleanup). + + # Creating network offering + self.debug("Creating Nuage VSP Isolated Network offering with Static " + "NAT service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating an Isolated network, deploying VMs, and verifying Static + # NAT traffic with VM migrations + self.debug("Creating an Isolated network with Static NAT service...") + network = self.create_Network(net_off, gateway='10.1.1.1') + self.validate_Network(network, state="Allocated") + + self.debug("Deploying a VM in the created Isolated 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") + + # VSD verification + self.verify_vsd_network(self.domain.id, network) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm_1) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule for the deployed VM in the " + "created Isolated network...") + public_ip_1 = self.acquire_PublicIPAddress(network) + self.validate_PublicIPAddress(public_ip_1, network) + self.create_StaticNatRule_For_VM(vm_1, public_ip_1, network) + self.validate_PublicIPAddress( + public_ip_1, network, static_nat=True, vm=vm_1) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network, vm_1, public_ip_1.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(network, public_ip_1) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic(vm_1, network, public_ip_1) + + self.debug("Deploying another VM in the created Isolated network...") + vm_2 = self.create_VM(network) + self.check_VM_state(vm_2, state="Running") + + # VSD verification + self.verify_vsd_vm(vm_2) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule for the deployed VM in the " + "created Isolated network...") + public_ip_2 = self.acquire_PublicIPAddress(network) + self.validate_PublicIPAddress(public_ip_2, network) + self.create_StaticNatRule_For_VM(vm_2, public_ip_2, network) + self.validate_PublicIPAddress( + public_ip_2, network, static_nat=True, vm=vm_2) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network, vm_2, public_ip_2.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(network, public_ip_2) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic(vm_2, network, public_ip_2) + + # VM migration + # This VM migration has no effect on the Static NAT functionality + self.debug("Migrating one of the VMs in the created Isolated network " + "to another host, if available...") + self.migrate_VM(vm_1) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network, vm_1, public_ip_1.ipaddress) + self.verify_vsd_floating_ip(network, vm_2, public_ip_2.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(network, public_ip_1) + self.verify_StaticNAT_traffic(network, public_ip_2) + + # VSD verification for Static NAT functionality + self.verify_StaticNAT_Internet_traffic(vm_1, network, public_ip_1) + self.verify_StaticNAT_Internet_traffic(vm_2, network, public_ip_2) + + @attr(tags=["advanced", "nuagevsp"], required_hardware="true") + def test_10_nuage_StaticNAT_network_restarts_traffic(self): + """Test Nuage VSP Static NAT functionality with network restarts by + performing (wget) traffic tests to the Internet + """ + + # Repeat the tests in the testcases + # "test_05_nuage_StaticNAT_isolated_networks_traffic" and + # "test_06_nuage_StaticNAT_vpc_network_traffic" with network restarts: + # 1. Restart Isolated Network (cleanup = false) + # 2. Restart Isolated Network (cleanup = true) + # 3. Reboot VM in the Isolated Network + # 4. Restart VPC Network (cleanup = false) + # 5. Restart VPC Network (cleanup = true) + # 6. Reboot VM in the VPC Network + # 7. Restart VPC (cleanup = false) + # 8. Restart VPC (cleanup = true) + # Verify the above network restarts by performing and verifying Static + # NAT traffic test (wget www.google.com) to the Internet from the VM. + # Delete all the created objects (cleanup). + + # Creating network offering + self.debug("Creating Nuage VSP Isolated Network offering with Static " + "NAT service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["isolated_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating an Isolated network, deploying a VM, and verifying Static + # NAT traffic with Isolated network restarts + self.debug("Creating an Isolated network with Static NAT service...") + network = self.create_Network(net_off, gateway='10.1.1.1') + self.validate_Network(network, state="Allocated") + + self.debug("Deploying a VM in the created Isolated network...") + vm = 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, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule for the deployed VM in the " + "created Isolated network...") + public_ip_1 = self.acquire_PublicIPAddress(network) + self.validate_PublicIPAddress(public_ip_1, network) + self.create_StaticNatRule_For_VM(vm, public_ip_1, network) + self.validate_PublicIPAddress( + public_ip_1, network, static_nat=True, vm=vm) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network, vm, public_ip_1.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(network, public_ip_1) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic(vm, network, public_ip_1) + + # Restarting Isolated network (cleanup = false) + # VR gets destroyed and deployed again in the Isolated network + # This restart has no effect on the Static NAT functionality + self.debug("Restarting the created Isolated network without " + "cleanup...") + Network.restart(network, self.api_client, cleanup=False) + self.validate_Network(network, state="Implemented") + vr = self.get_Router(network) + self.check_Router_state(vr, state="Running") + self.check_VM_state(vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network, vm, public_ip_1.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(network, public_ip_1) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic(vm, network, public_ip_1) + + # Restarting Isolated network (cleanup = true) + # VR gets destroyed and deployed again in the Isolated network + # This restart has no effect on the Static NAT functionality + self.debug("Restarting the created Isolated network with cleanup...") + Network.restart(network, self.api_client, cleanup=True) + self.validate_Network(network, state="Implemented") + vr = self.get_Router(network) + self.check_Router_state(vr, state="Running") + self.check_VM_state(vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network, vm, public_ip_1.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(network, public_ip_1) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic(vm, network, public_ip_1) + + # Rebooting (stop - start) VM + # This reboot has no effect on the Static NAT functionality + self.debug("Rebooting the deployed VM in the created Isolated " + "network...") + vm.stop(self.api_client) + vm.start(self.api_client) + self.validate_Network(network, state="Implemented") + self.check_Router_state(vr, state="Running") + self.check_VM_state(vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, network) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip(network, vm, public_ip_1.ipaddress) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(network, public_ip_1) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic(vm, network, public_ip_1) + + # Creating VPC offering + self.debug("Creating Nuage VSP VPC offering with Static NAT service " + "provider as NuageVsp...") + vpc_off = self.create_VpcOffering( + self.test_data["nuagevsp"]["vpc_offering"]) + self.validate_VpcOffering(vpc_off, state="Enabled") + + # Creating VPC + self.debug("Creating a VPC with Static NAT service provider as " + "NuageVsp...") + vpc = self.create_Vpc(vpc_off, cidr='10.1.0.0/16') + self.validate_Vpc(vpc, state="Enabled") + + # Creating VPC network offering + self.debug("Creating Nuage VSP VPC Network offering with Static NAT " + "service provider as NuageVsp...") + net_off = self.create_NetworkOffering( + self.test_data["nuagevsp"]["vpc_network_offering"]) + self.validate_NetworkOffering(net_off, state="Enabled") + + # Creating a VPC network in the VPC, deploying a VM, and verifying + # Static NAT traffic with VPC network restarts + self.debug("Creating a VPC network with Static NAT service...") + vpc_tier = self.create_Network(net_off, gateway='10.1.1.1', vpc=vpc) + self.validate_Network(vpc_tier, state="Implemented") + vpc_vr = self.get_Router(vpc_tier) + self.check_Router_state(vpc_vr, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vpc_vr) + + # Adding Egress Network ACL rules + self.debug("Adding Egress Network ACL rules in the created VPC " + "network to allow Static NAT (DNS & HTTP) traffic to the " + "Internet from the VMs in the network...") + dns_rule = self.create_NetworkAclRule( + self.test_data["dns_rule"], traffic_type="Egress", + network=vpc_tier) + http_rule = self.create_NetworkAclRule( + self.test_data["http_rule"], traffic_type="Egress", + network=vpc_tier) + + # VSD verification for added Egress Network ACL rules + self.verify_vsd_firewall_rule(dns_rule, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + self.debug("Deploying a VM in the created VPC network...") + vpc_vm = self.create_VM(vpc_tier) + self.check_VM_state(vpc_vm, state="Running") + + # VSD verification + self.verify_vsd_vm(vpc_vm) + + # Creating Static NAT rule + self.debug("Creating Static NAT rule for the deployed VM in the " + "created VPC network...") + public_ip_2 = self.acquire_PublicIPAddress(vpc_tier, vpc=vpc) + self.validate_PublicIPAddress(public_ip_2, vpc_tier) + self.create_StaticNatRule_For_VM(vpc_vm, public_ip_2, vpc_tier) + self.validate_PublicIPAddress( + public_ip_2, vpc_tier, static_nat=True, vm=vpc_vm) + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip( + vpc_tier, vpc_vm, public_ip_2.ipaddress, vpc=vpc) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(vpc_tier, public_ip_2, vpc=vpc) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic( + vpc_vm, vpc_tier, public_ip_2, vpc=vpc) + + # Restarting VPC network (cleanup = false) + # This restart has no effect on the Static NAT functionality + self.debug("Restarting the created VPC network without cleanup...") + Network.restart(vpc_tier, self.api_client, cleanup=False) + self.validate_Network(vpc_tier, state="Implemented") + self.check_Router_state(vpc_vr, state="Running") + self.check_VM_state(vpc_vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vpc_vr) + self.verify_vsd_vm(vpc_vm) + self.verify_vsd_firewall_rule(dns_rule, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip( + vpc_tier, vpc_vm, public_ip_2.ipaddress, vpc=vpc) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(vpc_tier, public_ip_2, vpc=vpc) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic( + vpc_vm, vpc_tier, public_ip_2, vpc=vpc) + + # Restarting VPC network (cleanup = true) + # This restart has no effect on the Static NAT functionality + self.debug("Restarting the created VPC network with cleanup...") + Network.restart(vpc_tier, self.api_client, cleanup=True) + self.validate_Network(vpc_tier, state="Implemented") + self.check_Router_state(vpc_vr, state="Running") + self.check_VM_state(vpc_vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vpc_vr) + self.verify_vsd_vm(vpc_vm) + self.verify_vsd_firewall_rule(dns_rule, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip( + vpc_tier, vpc_vm, public_ip_2.ipaddress, vpc=vpc) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(vpc_tier, public_ip_2, vpc=vpc) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic( + vpc_vm, vpc_tier, public_ip_2, vpc=vpc) + + # Rebooting (stop - start) VM + # This reboot has no effect on the Static NAT functionality + self.debug("Rebooting the deployed VM in the created VPC network...") + vpc_vm.stop(self.api_client) + vpc_vm.start(self.api_client) + self.validate_Network(vpc_tier, state="Implemented") + self.check_Router_state(vpc_vr, state="Running") + self.check_VM_state(vpc_vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vr) + self.verify_vsd_vm(vm) + self.verify_vsd_firewall_rule(dns_rule, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip( + vpc_tier, vpc_vm, public_ip_2.ipaddress, vpc=vpc) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(vpc_tier, public_ip_2, vpc=vpc) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic( + vpc_vm, vpc_tier, public_ip_2, vpc=vpc) + + # Restarting VPC (cleanup = false) + # VPC VR gets destroyed and deployed again in the VPC + # This restart has no effect on the Static NAT functionality + self.debug("Restarting the VPC without cleanup...") + self.restart_Vpc(vpc, cleanup=False) + self.validate_Network(vpc_tier, state="Implemented") + vpc_vr = self.get_Router(vpc_tier) + self.check_Router_state(vpc_vr, state="Running") + self.check_VM_state(vpc_vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vpc_vr) + self.verify_vsd_vm(vpc_vm) + self.verify_vsd_firewall_rule(dns_rule, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip( + vpc_tier, vpc_vm, public_ip_2.ipaddress, vpc=vpc) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(vpc_tier, public_ip_2, vpc=vpc) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic( + vpc_vm, vpc_tier, public_ip_2, vpc=vpc) + + # Restarting VPC (cleanup = true) + # VPC VR gets destroyed and deployed again in the VPC + # This restart has no effect on the Static NAT functionality + self.debug("Restarting the VPC with cleanup...") + self.restart_Vpc(vpc, cleanup=True) + self.validate_Network(vpc_tier, state="Implemented") + vpc_vr = self.get_Router(vpc_tier) + self.check_Router_state(vpc_vr, state="Running") + self.check_VM_state(vpc_vm, state="Running") + + # VSD verification + self.verify_vsd_network(self.domain.id, vpc_tier, vpc) + self.verify_vsd_router(vpc_vr) + self.verify_vsd_vm(vpc_vm) + self.verify_vsd_firewall_rule(dns_rule, traffic_type="Egress") + self.verify_vsd_firewall_rule(http_rule, traffic_type="Egress") + + # VSD verification for Static NAT functionality + self.verify_vsd_floating_ip( + vpc_tier, vpc_vm, public_ip_2.ipaddress, vpc=vpc) + + # Verifying Static NAT traffic + self.verify_StaticNAT_traffic(vpc_tier, public_ip_2, vpc=vpc) + + # Verifying Static NAT traffic (wget www.google.com) to the Internet + # from the deployed VM + self.verify_StaticNAT_Internet_traffic( + vpc_vm, vpc_tier, public_ip_2, vpc=vpc) diff --git a/tools/marvin/marvin/config/test_data.py b/tools/marvin/marvin/config/test_data.py index 7612989cc67..0a69b045894 100644 --- a/tools/marvin/marvin/config/test_data.py +++ b/tools/marvin/marvin/config/test_data.py @@ -763,6 +763,14 @@ test_data = { "protocol": "TCP", "cidrlist": '0.0.0.0/0', }, + "dns_rule": { + "privateport": 53, + "publicport": 53, + "startport": 53, + "endport": 53, + "protocol": "UDP", + "cidrlist": '0.0.0.0/0', + }, "icmprule": { "icmptype": -1, "icmpcode": -1,