You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by bh...@apache.org on 2016/11/25 07:59:41 UTC

[5/6] git commit: updated refs/heads/master to 62c8496

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 <pr...@nuagenetworks.net>, Frank Maximus <fr...@nuagenetworks.net>


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 <ni...@nuagenetworks.net>
Authored: Wed Jun 15 11:04:21 2016 +0200
Committer: Prashanth Manthena <Pr...@alcatel-lucent.com>
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);