CLOUDSTACK-9402 : Support for underlay features (Source & Static NAT to 
underlay) in Nuage VSP plugin

CLOUDSTACK-9402 : Marvin tests for Source NAT and Static NAT features 
verification with NuageVsp (both overlay and underlay infra).

Co-Authored-By: Prashanth Manthena <[email protected]>, 
Frank Maximus <[email protected]>


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/8d4dc812
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/8d4dc812
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/8d4dc812

Branch: refs/heads/master
Commit: 8d4dc81223032f104bd4c7d576aceed329c6a099
Parents: 027409d
Author: Nick Livens <[email protected]>
Authored: Wed Jun 15 11:04:21 2016 +0200
Committer: Prashanth Manthena <[email protected]>
Committed: Thu Nov 24 21:33:02 2016 +0100

----------------------------------------------------------------------
 .../cloudstack/api/ResponseGenerator.java       |    2 +
 core/src/com/cloud/agent/transport/Request.java |    2 +-
 .../spring-engine-schema-core-daos-context.xml  |    1 +
 .../schema/src/com/cloud/dc/VlanDetailsVO.java  |   83 +
 .../src/com/cloud/dc/dao/VlanDetailsDao.java    |   25 +
 .../com/cloud/dc/dao/VlanDetailsDaoImpl.java    |   32 +
 .../dao/NetworkOfferingServiceMapDao.java       |    2 +
 .../dao/NetworkOfferingServiceMapDaoImpl.java   |    9 +
 .../agent/api/manager/EntityExistsCommand.java  |   77 +
 .../DisableNuageUnderlayVlanIpRangeCmd.java     |  110 +
 .../EnableNuageUnderlayVlanIpRangeCmd.java      |  110 +
 .../ListNuageUnderlayVlanIpRangesCmd.java       |   80 +
 .../com/cloud/api/commands/VspConstants.java    |    1 +
 .../api/response/NuageVlanIpRangeResponse.java  |   38 +
 .../cloud/network/element/NuageVspElement.java  |   73 +-
 .../network/guru/NuageVspGuestNetworkGuru.java  |   42 +-
 .../cloud/network/manager/NuageVspManager.java  |   11 +
 .../network/manager/NuageVspManagerImpl.java    |   76 +-
 .../network/resource/NuageVspResource.java      |   20 +
 .../com/cloud/util/NuageVspEntityBuilder.java   |    6 +-
 .../src/com/cloud/util/NuageVspUtil.java        |    8 +
 .../test/com/cloud/agent/api/CommandsTest.java  |  122 +-
 .../network/element/NuageVspElementTest.java    |   10 +-
 .../guru/NuageVspGuestNetworkGuruTest.java      |    7 +-
 .../cloud/util/NuageVspEntityBuilderTest.java   |   13 +
 server/src/com/cloud/api/ApiResponseHelper.java |  131 +-
 setup/db/db/schema-4910to41000.sql              |   12 +-
 .../plugins/nuagevsp/nuageTestCase.py           |   56 +-
 .../plugins/nuagevsp/test_nuage_source_nat.py   | 1454 ++++++++++++
 .../plugins/nuagevsp/test_nuage_static_nat.py   | 2084 ++++++++++++++++++
 tools/marvin/marvin/config/test_data.py         |    8 +
 31 files changed, 4538 insertions(+), 167 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/api/src/org/apache/cloudstack/api/ResponseGenerator.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ResponseGenerator.java 
b/api/src/org/apache/cloudstack/api/ResponseGenerator.java
index 1cc5bc8..8da1ded 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<? extends 
VlanIpRangeResponse> subClass, Vlan vlan);
+
     IPAddressResponse createIPAddressResponse(ResponseView view, IpAddress 
ipAddress);
 
     GuestVlanRangeResponse createDedicatedGuestVlanRangeResponse(GuestVlan 
result);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/core/src/com/cloud/agent/transport/Request.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/transport/Request.java 
b/core/src/com/cloud/agent/transport/Request.java
index 7b8dd0d..f78a96c 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;
                 }
             }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
----------------------------------------------------------------------
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 884bb30..c43e9ff 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 @@
   <bean id="networkOfferingDetailsDaoImpl" 
class="com.cloud.offerings.dao.NetworkOfferingDetailsDaoImpl" />
   <bean id="serviceOfferingDetailsDaoImpl" 
class="com.cloud.service.dao.ServiceOfferingDetailsDaoImpl"/>
   <bean id="networkDetailsDaoImpl" 
class="com.cloud.network.dao.NetworkDetailsDaoImpl" />
+  <bean id="vlanDetailsDaoImpl" class="com.cloud.dc.dao.VlanDetailsDaoImpl" />
   <bean id="hostGpuGroupsDaoImpl" 
class="com.cloud.gpu.dao.HostGpuGroupsDaoImpl" />
   <bean id="vGPUTypesDaoImpl" class="com.cloud.gpu.dao.VGPUTypesDaoImpl" />
   <bean id="AffinityGroupDaoImpl" 
class="org.apache.cloudstack.affinity.dao.AffinityGroupDaoImpl" />

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/engine/schema/src/com/cloud/dc/VlanDetailsVO.java
----------------------------------------------------------------------
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 0000000..1a1db3a
--- /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;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/engine/schema/src/com/cloud/dc/dao/VlanDetailsDao.java
----------------------------------------------------------------------
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 0000000..dfc72a0
--- /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<VlanDetailsVO, Long>, 
ResourceDetailsDao<VlanDetailsVO> {
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/engine/schema/src/com/cloud/dc/dao/VlanDetailsDaoImpl.java
----------------------------------------------------------------------
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 0000000..43f9087
--- /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<VlanDetailsVO> 
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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java
----------------------------------------------------------------------
diff --git 
a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java 
b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDao.java
index 8616449..8fb5d6d 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<NetworkOfferingServiceMapVO, Long> {
     boolean areServicesSupportedByNetworkOffering(long networkOfferingId, 
Service... services);
 
+    boolean canProviderSupportServiceInNetworkOffering(long networkOfferingId, 
Service service, Provider provider);
+
     List<NetworkOfferingServiceMapVO> listByNetworkOfferingId(long 
networkOfferingId);
 
     void deleteByOfferingId(long networkOfferingId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java
----------------------------------------------------------------------
diff --git 
a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java
 
b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java
index b667e58..7868be2 100644
--- 
a/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java
+++ 
b/engine/schema/src/com/cloud/offerings/dao/NetworkOfferingServiceMapDaoImpl.java
@@ -104,6 +104,15 @@ public class NetworkOfferingServiceMapDaoImpl extends 
GenericDaoBase<NetworkOffe
     }
 
     @Override
+    public boolean canProviderSupportServiceInNetworkOffering(long 
networkOfferingId, Service service, Provider provider) {
+        SearchCriteria<NetworkOfferingServiceMapVO> sc = 
AllFieldsSearch.create();
+        sc.setParameters("networkOfferingId", networkOfferingId);
+        sc.setParameters("service", service.getName());
+        sc.setParameters("provider", provider.getName());
+        return findOneBy(sc) != null;
+    }
+
+    @Override
     public List<NetworkOfferingServiceMapVO> listByNetworkOfferingId(long 
networkOfferingId) {
         SearchCriteria<NetworkOfferingServiceMapVO> sc = 
AllFieldsSearch.create();
         sc.setParameters("networkOfferingId", networkOfferingId);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/src/com/cloud/agent/api/manager/EntityExistsCommand.java
----------------------------------------------------------------------
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 0000000..64f3768
--- /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<T> extends Command {
+
+    private transient Class<T> _type;
+    private final String _className;
+    private final String _uuid;
+
+    public EntityExistsCommand(Class<T> type, String uuid) {
+        super();
+        this._type = type;
+        this._className = type.getName();
+        this._uuid = uuid;
+    }
+
+    public Class<T> getType() {
+        if (_type == null) {
+            try {
+                _type = (Class<T>)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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/DisableNuageUnderlayVlanIpRangeCmd.java
----------------------------------------------------------------------
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 0000000..bcc804c
--- /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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/EnableNuageUnderlayVlanIpRangeCmd.java
----------------------------------------------------------------------
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 0000000..b1eb9d7
--- /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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/ListNuageUnderlayVlanIpRangesCmd.java
----------------------------------------------------------------------
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 0000000..38bc788
--- /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<List<? extends Vlan>, Integer> vlans = _mgr.searchForVlans(this);
+        ListResponse<NuageVlanIpRangeResponse> response = new 
ListResponse<NuageVlanIpRangeResponse>();
+        List<NuageVlanIpRangeResponse> 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;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/src/com/cloud/api/commands/VspConstants.java
----------------------------------------------------------------------
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 7abcdfb..55e6b47 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";
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/src/com/cloud/api/response/NuageVlanIpRangeResponse.java
----------------------------------------------------------------------
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 0000000..cc3204d
--- /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;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/src/com/cloud/network/element/NuageVspElement.java
----------------------------------------------------------------------
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 aae16b8..d0b9ed9 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<VlanVO> 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<NuageVspDeviceVO> 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

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/src/com/cloud/network/guru/NuageVspGuestNetworkGuru.java
----------------------------------------------------------------------
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 aedf646..6bdd9e4 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<NuageVspDeviceVO> 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) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManager.java
----------------------------------------------------------------------
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 4861fb2..e5c9871 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<Boolean> NuageVspConfigDns = new 
ConfigKey<Boolean>(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<String> getGatewaySystemIds();
 
+    HostVO getNuageVspHost(long physicalNetworkId);
+
+    boolean updateNuageUnderlayVlanIpRange(long vlanIpRangeId, boolean 
enabled);
+
+    List<NuageVlanIpRangeResponse> filterNuageVlanIpRanges(List<? extends 
Vlan> vlanIpRanges, Boolean underlay);
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/src/com/cloud/network/manager/NuageVspManagerImpl.java
----------------------------------------------------------------------
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 b82b194..7bc36e2 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<Class<?>> getCommands() {
         return Lists.<Class<?>>newArrayList(AddNuageVspDeviceCmd.class, 
DeleteNuageVspDeviceCmd.class, ListNuageVspDevicesCmd.class,
-                UpdateNuageVspDeviceCmd.class);
+                UpdateNuageVspDeviceCmd.class, 
EnableNuageUnderlayVlanIpRangeCmd.class, 
DisableNuageUnderlayVlanIpRangeCmd.class, 
ListNuageUnderlayVlanIpRangesCmd.class);
     }
 
     @Override
@@ -678,6 +695,63 @@ public class NuageVspManagerImpl extends ManagerBase 
implements NuageVspManager,
     }
 
     @Override
+    public HostVO getNuageVspHost(long physicalNetworkId) {
+        HostVO nuageVspHost;
+        List<NuageVspDeviceVO> 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<PhysicalNetworkVO> 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<Vlan> cmd = new 
EntityExistsCommand<Vlan>(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<NuageVlanIpRangeResponse> filterNuageVlanIpRanges(List<? 
extends Vlan> vlanIpRanges, Boolean underlay) {
+        List<NuageVlanIpRangeResponse> 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;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/src/com/cloud/network/resource/NuageVspResource.java
----------------------------------------------------------------------
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 5cb6683..9d04ab0 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);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspEntityBuilder.java
----------------------------------------------------------------------
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 6b0e26e..b1db4fb 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);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/src/com/cloud/util/NuageVspUtil.java
----------------------------------------------------------------------
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 fedf048..7eff324 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));
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/test/com/cloud/agent/api/CommandsTest.java
----------------------------------------------------------------------
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 2a0b07a..03fe5eb 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);
-
-        ApplyStaticNatVspCommand applyStaticNatVspCommand = 
fillObject(ApplyStaticNatVspCommand.class);
-        ApplyStaticNatVspCommand otherApplyStaticNatVspCommand = 
fillObject(ApplyStaticNatVspCommand.class);
-
-        ImplementVspCommand implementVspCommand = 
fillObject(ImplementVspCommand.class);
-        ImplementVspCommand otherImplementVspCommand = 
fillObject(ImplementVspCommand.class);
-
-        ShutDownVpcVspCommand shutDownVpcVspCommand = 
fillObject(ShutDownVpcVspCommand.class);
-        ShutDownVpcVspCommand otherShutDownVpcVspCommand = 
fillObject(ShutDownVpcVspCommand.class);
-
-        DeallocateVmVspCommand deallocateVmVspCommand = 
fillObject(DeallocateVmVspCommand.class);
-        DeallocateVmVspCommand otherDeallocateVmVspCommand = 
fillObject(DeallocateVmVspCommand.class);
-
-        ImplementNetworkVspCommand implementNetworkVspCommand = 
fillObject(ImplementNetworkVspCommand.class);
-        ImplementNetworkVspCommand otherImplementNetworkVspCommand = 
fillObject(ImplementNetworkVspCommand.class);
-
-        ReserveVmInterfaceVspCommand reserveVmInterfaceVspCommand = 
fillObject(ReserveVmInterfaceVspCommand.class);
-        ReserveVmInterfaceVspCommand otherReserveVmInterfaceVspCommand = 
fillObject(ReserveVmInterfaceVspCommand.class);
-
-        TrashNetworkVspCommand trashNetworkVspCommand = 
fillObject(TrashNetworkVspCommand.class);
-        TrashNetworkVspCommand otherTrashNetworkVspCommand  = 
fillObject(TrashNetworkVspCommand.class);
-
-        SupportedApiVersionCommand supportedApiVersionCommand = new 
SupportedApiVersionCommand("3.2");
-        SupportedApiVersionCommand otherSupportedApiVersionCommand = new 
SupportedApiVersionCommand("3.2");
+        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);
+
+        SupportedApiVersionCommand supportedApiVersionCommandA = new 
SupportedApiVersionCommand("3.2");
+        SupportedApiVersionCommand supportedApiVersionCommandB = new 
SupportedApiVersionCommand("3.2");
+
+        EntityExistsCommand entityExistsCommandA = new 
EntityExistsCommand(Command.class, "uuid");
+        EntityExistsCommand entityExistsCommandB = new 
EntityExistsCommand(Command.class, "uuid");
+
+        tester
+            .addEqualityGroup(supportedApiVersionCommandA, 
supportedApiVersionCommandB)
+            .addEqualityGroup(entityExistsCommandA, entityExistsCommandB)
+            .testEquals();
+    }
 
-        SyncDomainCommand syncDomainCommand = 
fillObject(SyncDomainCommand.class);
-        SyncDomainCommand otherSyncDomainCommand = 
fillObject(SyncDomainCommand.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"));
+
+        tester.testEquals();
+    }
 
-        SyncNuageVspCmsIdCommand syncNuageVspCmsIdCommand = 
fillObject(SyncNuageVspCmsIdCommand.class);
-        SyncNuageVspCmsIdCommand otherSyncNuageVspCmsIdCommand = 
fillObject(SyncNuageVspCmsIdCommand.class);
+    private <T extends Command> void addCommandGsonEqualityGroup(Class<T> 
clazz) throws IllegalAccessException, InvocationTargetException, 
InstantiationException{
+        addCommandGsonEqualityGroup(fillObject(clazz));
+    }
 
-        PingNuageVspCommand pingNuageVspCommand = 
fillObject(PingNuageVspCommand.class);
-        PingNuageVspCommand otherPingNuageVspCommand = 
fillObject(PingNuageVspCommand.class);
+    private <T extends Command> 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]);
+    }
 
-        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 <T extends Command> void addCommandEqualityGroup(Class<T> clazz) 
throws IllegalAccessException, InvocationTargetException, 
InstantiationException {
+        Command a = fillObject(clazz);
+        Command b = fillObject(clazz);
+        tester.addEqualityGroup(a, b);
     }
 
     private <T> T fillObject(Class<T> clazz) throws IllegalAccessException, 
InvocationTargetException, InstantiationException {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/test/com/cloud/network/element/NuageVspElementTest.java
----------------------------------------------------------------------
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 929aba7..aad6398 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.<String, 
Object>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<FirewallRuleVO>());
         when(_firewallRulesDao.listByNetworkPurposeTrafficType(NETWORK_ID, 
FirewallRule.Purpose.Firewall, FirewallRule.TrafficType.Egress)).thenReturn(new 
ArrayList<FirewallRuleVO>());
@@ -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");

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8d4dc812/plugins/network-elements/nuage-vsp/test/com/cloud/network/guru/NuageVspGuestNetworkGuruTest.java
----------------------------------------------------------------------
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 d0de447..fdfc4d5 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);

Reply via email to