You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ek...@apache.org on 2015/06/10 22:49:57 UTC

[17/19] git commit: updated refs/heads/feature/vpc-ipv6 to c1b0900

Enhanced Zone API to support Ipv6 attributes like IPv6 Super CIDR and ASN


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

Branch: refs/heads/feature/vpc-ipv6
Commit: c198d44afd16bb9c3914eae5e44379aec03a6063
Parents: 277964e
Author: Suresh Ramamurthy <su...@gmail.com>
Authored: Tue Jun 9 03:55:06 2015 -0400
Committer: wilderrodrigues <wr...@schubergphilis.com>
Committed: Wed Jun 10 22:19:48 2015 +0200

----------------------------------------------------------------------
 .../org/apache/cloudstack/api/ApiConstants.java |   2 +
 .../api/command/admin/zone/CreateZoneCmd.java   |  14 +++
 .../api/command/admin/zone/UpdateZoneCmd.java   |  17 ++-
 .../cloudstack/api/response/ZoneResponse.java   |  17 ++-
 .../configuration/ConfigurationManager.java     |  16 +--
 .../src/com/cloud/dc/dao/DataCenterDao.java     |   4 +
 .../src/com/cloud/dc/dao/DataCenterDaoImpl.java |  25 +++++
 .../management/ManagementServerMock.java        |   2 +-
 .../configuration/ConfigurationManagerImpl.java | 106 +++++++++++++++----
 .../configuration/ConfigurationManagerTest.java |  79 ++++++++++++++
 .../cloud/vpc/MockConfigurationManagerImpl.java |   6 +-
 tools/marvin/marvin/deployDataCenter.py         |   4 +
 utils/src/com/cloud/utils/net/NetUtils.java     |  30 ++++++
 .../test/com/cloud/utils/net/NetUtilsTest.java  |  19 ++++
 14 files changed, 304 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c198d44a/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java
index 2b64258..80b22a0 100644
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -115,6 +115,8 @@ public class ApiConstants {
     public static final String GSLB_STICKY_SESSION_METHOD = "gslbstickysessionmethodname";
     public static final String GSLB_LBRULE_WEIGHT_MAP = "gslblbruleweightsmap";
     public static final String GUEST_CIDR_ADDRESS = "guestcidraddress";
+    public static final String IP6_SUPER_CIDR_ADDRESS = "ip6supercidraddress";
+    public static final String AUTONOMOUS_NUMBER = "asnumber";
     public static final String GUEST_VLAN_RANGE = "guestvlanrange";
     public static final String HA_ENABLE = "haenable";
     public static final String HOST_ID = "hostid";

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c198d44a/api/src/org/apache/cloudstack/api/command/admin/zone/CreateZoneCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/zone/CreateZoneCmd.java b/api/src/org/apache/cloudstack/api/command/admin/zone/CreateZoneCmd.java
index 414c058..c69285c 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/zone/CreateZoneCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/zone/CreateZoneCmd.java
@@ -58,6 +58,12 @@ public class CreateZoneCmd extends BaseCmd {
     @Parameter(name = ApiConstants.GUEST_CIDR_ADDRESS, type = CommandType.STRING, description = "the guest CIDR address for the Zone")
     private String guestCidrAddress;
 
+    @Parameter(name = ApiConstants.IP6_SUPER_CIDR_ADDRESS, type = CommandType.STRING, description = "the IPv6 super CIDR address for the Zone. IPv6 CIDR of all the VPCs in this zone should be within this CIDR")
+    private String ip6SuperCidrAddress;
+
+    @Parameter(name = ApiConstants.AUTONOMOUS_NUMBER, type = CommandType.STRING, description = "private autonomous system number for the Zone")
+    private String asNumber;
+
     @Parameter(name = ApiConstants.INTERNAL_DNS1, type = CommandType.STRING, required = true, description = "the first internal DNS for the Zone")
     private String internalDns1;
 
@@ -112,6 +118,14 @@ public class CreateZoneCmd extends BaseCmd {
         return guestCidrAddress;
     }
 
+    public String getIp6SuperCidrAddress() {
+        return ip6SuperCidrAddress;
+    }
+
+    public String getAsNumber() {
+        return asNumber;
+    }
+
     public String getInternalDns1() {
         return internalDns1;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c198d44a/api/src/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java b/api/src/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java
index 9ad8972..f9267e5 100644
--- a/api/src/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/admin/zone/UpdateZoneCmd.java
@@ -19,8 +19,6 @@ package org.apache.cloudstack.api.command.admin.zone;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.api.APICommand;
 import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.ApiErrorCode;
@@ -30,6 +28,7 @@ import org.apache.cloudstack.api.ResponseObject.ResponseView;
 import org.apache.cloudstack.api.ServerApiException;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.dc.DataCenter;
 import com.cloud.user.Account;
@@ -60,6 +59,12 @@ public class UpdateZoneCmd extends BaseCmd {
     @Parameter(name = ApiConstants.GUEST_CIDR_ADDRESS, type = CommandType.STRING, description = "the guest CIDR address for the Zone")
     private String guestCidrAddress;
 
+    @Parameter(name = ApiConstants.IP6_SUPER_CIDR_ADDRESS, type = CommandType.STRING, description = "the IPv6 super CIDR address for the Zone. IPv6 CIDR of all the VPCs in this zone should be within this CIDR")
+    private String ip6SuperCidrAddress;
+
+    @Parameter(name = ApiConstants.AUTONOMOUS_NUMBER, type = CommandType.STRING, description = "private autonomous system number for the Zone")
+    private String asNumber;
+
     @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = ZoneResponse.class, required = true, description = "the ID of the Zone")
     private Long id;
 
@@ -111,6 +116,14 @@ public class UpdateZoneCmd extends BaseCmd {
         return guestCidrAddress;
     }
 
+    public String getIp6SuperCidrAddress() {
+        return ip6SuperCidrAddress;
+    }
+
+    public String getAsNumber() {
+        return asNumber;
+    }
+
     public Long getId() {
         return id;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c198d44a/api/src/org/apache/cloudstack/api/response/ZoneResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/ZoneResponse.java b/api/src/org/apache/cloudstack/api/response/ZoneResponse.java
index 7aee448..1288bee 100644
--- a/api/src/org/apache/cloudstack/api/response/ZoneResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/ZoneResponse.java
@@ -29,7 +29,6 @@ import com.cloud.dc.DataCenter;
 import com.cloud.serializer.Param;
 import com.google.gson.annotations.SerializedName;
 
-@SuppressWarnings("unused")
 @EntityReference(value = DataCenter.class)
 public class ZoneResponse extends BaseResponse {
     @SerializedName(ApiConstants.ID)
@@ -72,6 +71,14 @@ public class ZoneResponse extends BaseResponse {
     @Param(description = "the guest CIDR address for the Zone")
     private String guestCidrAddress;
 
+    @SerializedName(ApiConstants.IP6_SUPER_CIDR_ADDRESS)
+    @Param(description = "the IPv6 super CIDR address for the Zone. IPv6 CIDR of all the VPCs in this zone should be within this CIDR")
+    private String ip6SuperCidrAddress;
+
+    @SerializedName(ApiConstants.AUTONOMOUS_NUMBER)
+    @Param(description = "private autonomous system number for the Zone")
+    private String asNumber;
+
     //TODO - generate description
     @SerializedName("status")
     private String status;
@@ -164,6 +171,14 @@ public class ZoneResponse extends BaseResponse {
         this.guestCidrAddress = guestCidrAddress;
     }
 
+    public void setIp6SuperCidrAddress(String ip6SuperCidrAddress) {
+        this.ip6SuperCidrAddress = ip6SuperCidrAddress;
+    }
+
+    public void setAsNumber(String asNumber) {
+        this.asNumber = asNumber;
+    }
+
     public void setStatus(String status) {
         this.status = status;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c198d44a/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java
----------------------------------------------------------------------
diff --git a/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java b/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java
index 13ca3f9..c291e8d 100644
--- a/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java
+++ b/engine/components-api/src/com/cloud/configuration/ConfigurationManager.java
@@ -149,19 +149,19 @@ public interface ConfigurationManager {
      * @param guestCidr
      * @param zoneType
      * @param allocationState
-     * @param networkDomain
-     *            TODO
+     * @param networkDomainTODO
      * @param isSecurityGroupEnabled
-     *            TODO
-     * @param ip6Dns1 TODO
-     * @param ip6Dns2 TODO
+     * @param ip6Dns1
+     * @param ip6Dns2
+     * @param ip6SuperCidr
+     * @param asNumber
      * @return
      * @throws
      * @throws
      */
-    DataCenterVO createZone(long userId, String zoneName, String dns1, String dns2, String internalDns1, String internalDns2, String guestCidr, String domain,
-        Long domainId, NetworkType zoneType, String allocationState, String networkDomain, boolean isSecurityGroupEnabled, boolean isLocalStorageEnabled, String ip6Dns1,
-        String ip6Dns2);
+    DataCenterVO createZone(long userId, String zoneName, String dns1, String dns2, String internalDns1, String internalDns2, String guestCidr, String domain, Long domainId,
+        NetworkType zoneType, String allocationState, String networkDomain, boolean isSecurityGroupEnabled, boolean isLocalStorageEnabled, String ip6Dns1, String ip6Dns2,
+        String ip6SuperCidr, String asNumber);
 
     /**
      * Deletes a VLAN from the database, along with all of its IP addresses. Will not delete VLANs that have allocated

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c198d44a/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java b/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java
index 4fc055e..ffaa7c1 100644
--- a/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java
+++ b/engine/schema/src/com/cloud/dc/dao/DataCenterDao.java
@@ -96,4 +96,8 @@ public interface DataCenterDao extends GenericDao<DataCenterVO, Long> {
     List<DataCenterVO> findByKeyword(String keyword);
 
     List<DataCenterVO> listAllZones();
+
+    DataCenterVO findByIp6SuperCidr(String ip6SuperCidr);
+
+    DataCenterVO findByAsn(String asNumber);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c198d44a/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java b/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java
index 373446e..eb6ceb1 100644
--- a/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java
+++ b/engine/schema/src/com/cloud/dc/dao/DataCenterDaoImpl.java
@@ -61,6 +61,8 @@ public class DataCenterDaoImpl extends GenericDaoBase<DataCenterVO, Long> implem
     private static final Logger s_logger = Logger.getLogger(DataCenterDaoImpl.class);
 
     protected SearchBuilder<DataCenterVO> NameSearch;
+    protected SearchBuilder<DataCenterVO> Ip6SuperCidrSearch;
+    protected SearchBuilder<DataCenterVO> AsnSearch;
     protected SearchBuilder<DataCenterVO> ListZonesByDomainIdSearch;
     protected SearchBuilder<DataCenterVO> PublicZonesSearch;
     protected SearchBuilder<DataCenterVO> ChildZonesSearch;
@@ -92,6 +94,20 @@ public class DataCenterDaoImpl extends GenericDaoBase<DataCenterVO, Long> implem
     }
 
     @Override
+    public DataCenterVO findByIp6SuperCidr(String ip6SuperCidr) {
+        SearchCriteria<DataCenterVO> sc = Ip6SuperCidrSearch.create();
+        sc.setParameters("ip6SuperNetworkCidr", ip6SuperCidr);
+        return findOneBy(sc);
+    }
+
+    @Override
+    public DataCenterVO findByAsn(String asNumber) {
+        SearchCriteria<DataCenterVO> sc = AsnSearch.create();
+        sc.setParameters("asNumber", asNumber);
+        return findOneBy(sc);
+    }
+
+    @Override
     public DataCenterVO findByToken(String zoneToken) {
         SearchCriteria<DataCenterVO> sc = TokenSearch.create();
         sc.setParameters("zoneToken", zoneToken);
@@ -323,6 +339,15 @@ public class DataCenterDaoImpl extends GenericDaoBase<DataCenterVO, Long> implem
         NameSearch.and("name", NameSearch.entity().getName(), SearchCriteria.Op.EQ);
         NameSearch.done();
 
+        Ip6SuperCidrSearch = createSearchBuilder();
+        Ip6SuperCidrSearch.and("ip6SuperNetworkCidr", Ip6SuperCidrSearch.entity().getIp6SuperNetworkCidr(), SearchCriteria.Op.EQ);
+        Ip6SuperCidrSearch.done();
+
+
+        AsnSearch = createSearchBuilder();
+        AsnSearch.and("asNumber", AsnSearch.entity().getAsNumber(), SearchCriteria.Op.EQ);
+        AsnSearch.done();
+
         ListZonesByDomainIdSearch = createSearchBuilder();
         ListZonesByDomainIdSearch.and("domainId", ListZonesByDomainIdSearch.entity().getDomainId(), SearchCriteria.Op.EQ);
         ListZonesByDomainIdSearch.done();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c198d44a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
index db06c88..c048b9d 100644
--- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
+++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java
@@ -386,7 +386,7 @@ public class ManagementServerMock {
             ConfigurationManager mgr = (ConfigurationManager)_configService;
             _zone =
                 mgr.createZone(User.UID_SYSTEM, "default", "8.8.8.8", null, "8.8.4.4", null, null /* cidr */, "ROOT", Domain.ROOT_DOMAIN, NetworkType.Advanced, null,
-                    null /* networkDomain */, false, false, null, null);
+                    null /* networkDomain */, false, false, null, null, null, null);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c198d44a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index 6594dd9..8ee5af3 100644
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -38,11 +38,11 @@ import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
 import org.apache.log4j.Logger;
-
 import org.apache.cloudstack.acl.SecurityChecker;
 import org.apache.cloudstack.affinity.AffinityGroup;
 import org.apache.cloudstack.affinity.AffinityGroupService;
 import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
+import org.apache.cloudstack.api.ApiConstants;
 import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
 import org.apache.cloudstack.api.command.admin.network.CreateNetworkOfferingCmd;
 import org.apache.cloudstack.api.command.admin.network.DeleteNetworkOfferingCmd;
@@ -1422,9 +1422,10 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
 
     }
 
-    private void checkZoneParameters(final String zoneName, final String dns1, final String dns2, final String internalDns1, final String internalDns2, final boolean checkForDuplicates, final Long domainId,
-            final String allocationStateStr, final String ip6Dns1, final String ip6Dns2) {
-        if (checkForDuplicates) {
+    private void checkZoneParameters(final boolean checkForDuplicateName, final String zoneName, final String dns1, final String dns2, final String internalDns1, final String internalDns2, final Long domainId,
+            final String allocationStateStr, final String ip6Dns1, final String ip6Dns2, boolean checkForDuplicateIp6SuperCidr, String ip6SuperCidr, boolean checkForDuplicateAsn, String asNumber) {
+
+        if (checkForDuplicateName) {
             // Check if a zone with the specified name already exists
             if (validZone(zoneName)) {
                 throw new InvalidParameterValueException("A zone with that name already exists. Please specify a unique zone name.");
@@ -1458,13 +1459,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
             throw new InvalidParameterValueException("Please enter a valid IP address for internal DNS2");
         }
 
-        if (ip6Dns1 != null && ip6Dns1.length() > 0 && !NetUtils.isValidIpv6(ip6Dns1)) {
-            throw new InvalidParameterValueException("Please enter a valid IPv6 address for IP6 DNS1");
-        }
-
-        if (ip6Dns2 != null && ip6Dns2.length() > 0 && !NetUtils.isValidIpv6(ip6Dns2)) {
-            throw new InvalidParameterValueException("Please enter a valid IPv6 address for IP6 DNS2");
-        }
+        //Check all the IPv6 parameters
+        validateIp6Parameters(ip6Dns1, ip6Dns2, ip6SuperCidr, asNumber, checkForDuplicateName, checkForDuplicateIp6SuperCidr, checkForDuplicateAsn);
 
         if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
             try {
@@ -1589,6 +1585,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
         String internalDns1 = cmd.getInternalDns1();
         String internalDns2 = cmd.getInternalDns2();
         String guestCidr = cmd.getGuestCidrAddress();
+        String ip6SuperCidr = cmd.getIp6SuperCidrAddress();
+        String asNumber = cmd.getAsNumber();
         final List<String> dnsSearchOrder = cmd.getDnsSearchOrder();
         final Boolean isPublic = cmd.isPublic();
         final String allocationStateStr = cmd.getAllocationState();
@@ -1683,6 +1681,16 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
             guestCidr = zone.getGuestNetworkCidr();
         }
 
+        final String oldIp6SuperCidr = zone.getIp6SuperNetworkCidr();
+        if (ip6SuperCidr == null) {
+            ip6SuperCidr = oldIp6SuperCidr;
+        }
+
+        final String oldAsNumber = zone.getAsNumber();
+        if (asNumber == null) {
+            asNumber = oldAsNumber;
+        }
+
         // validate network domain
         if (networkDomain != null && !networkDomain.isEmpty()) {
             if (!NetUtils.verifyDomainName(networkDomain)) {
@@ -1692,8 +1700,12 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
             }
         }
 
-        final boolean checkForDuplicates = !zoneName.equals(oldZoneName);
-        checkZoneParameters(zoneName, dns1, dns2, internalDns1, internalDns2, checkForDuplicates, null, allocationStateStr, ip6Dns1, ip6Dns2);// not allowing updating
+        final boolean checkForDuplicateName = !zoneName.equals(oldZoneName);
+        final boolean checkForDuplicateIp6SuperCidr = !org.apache.commons.lang.StringUtils.equals(ip6SuperCidr, oldIp6SuperCidr);
+        final boolean checkForDuplicateAsn = !org.apache.commons.lang.StringUtils.equals(asNumber, oldAsNumber);
+        checkZoneParameters(checkForDuplicateName, zoneName, dns1, dns2, internalDns1, internalDns2, null, allocationStateStr, ip6Dns1, ip6Dns2, checkForDuplicateIp6SuperCidr,
+                ip6SuperCidr, checkForDuplicateAsn, asNumber);
+        // not allowing updating
         // domain associated with
         // a zone, once created
 
@@ -1705,6 +1717,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
         zone.setInternalDns1(internalDns1);
         zone.setInternalDns2(internalDns2);
         zone.setGuestNetworkCidr(guestCidr);
+        zone.setIp6SuperNetworkCidr(ip6SuperCidr);
+        zone.setAsNumber(asNumber);
         if (localStorageEnabled != null) {
             zone.setLocalStorageEnabled(localStorageEnabled.booleanValue());
         }
@@ -1799,9 +1813,9 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
 
     @Override
     @DB
-    public DataCenterVO createZone(final long userId, final String zoneName, final String dns1, final String dns2, final String internalDns1, final String internalDns2, final String guestCidr, final String domain,
-            final Long domainId, final NetworkType zoneType, final String allocationStateStr, final String networkDomain, final boolean isSecurityGroupEnabled, final boolean isLocalStorageEnabled,
-            final String ip6Dns1, final String ip6Dns2) {
+    public DataCenterVO createZone(final long userId, final String zoneName, final String dns1, final String dns2, final String internalDns1, final String internalDns2, final String guestCidr, final String domain, final Long domainId,
+            final NetworkType zoneType, final String allocationStateStr, final String networkDomain, final boolean isSecurityGroupEnabled, final boolean isLocalStorageEnabled, final String ip6Dns1,
+            final String ip6Dns2, final String ip6SuperCidr, String asNumber) {
 
         // checking the following params outside checkzoneparams method as we do
         // not use these params for updatezone
@@ -1819,14 +1833,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
             }
         }
 
-        checkZoneParameters(zoneName, dns1, dns2, internalDns1, internalDns2, true, domainId, allocationStateStr, ip6Dns1, ip6Dns2);
+        checkZoneParameters(true, zoneName, dns1, dns2, internalDns1, internalDns2, domainId, allocationStateStr, ip6Dns1, ip6Dns2, true, ip6SuperCidr, true, asNumber);
 
         final byte[] bytes = (zoneName + System.currentTimeMillis()).getBytes();
         final String zoneToken = UUID.nameUUIDFromBytes(bytes).toString();
 
         // Create the new zone in the database
         final DataCenterVO zoneFinal = new DataCenterVO(zoneName, null, dns1, dns2, internalDns1, internalDns2, guestCidr, domain, domainId, zoneType, zoneToken, networkDomain,
-                isSecurityGroupEnabled, isLocalStorageEnabled, ip6Dns1, ip6Dns2, null, null);
+                isSecurityGroupEnabled, isLocalStorageEnabled, ip6Dns1, ip6Dns2, ip6SuperCidr, asNumber);
         if (allocationStateStr != null && !allocationStateStr.isEmpty()) {
             final Grouping.AllocationState allocationState = Grouping.AllocationState.valueOf(allocationStateStr);
             zoneFinal.setAllocationState(allocationState);
@@ -1856,6 +1870,36 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
         });
     }
 
+    void validateIp6Parameters(String ip6Dns1, String ip6Dns2, String ip6SuperCidr, String asNumber, boolean checkDuplicateName, boolean checkDuplicateIp6SuperCidr, boolean checkDuplicateAsn) {
+        if (StringUtils.isNotBlank(ip6Dns1) && !NetUtils.isValidIpv6(ip6Dns1)) {
+            throw new InvalidParameterValueException("Please enter a valid IPv6 address for IP6 DNS1");
+        }
+
+        if (StringUtils.isNotBlank(ip6Dns2) && !NetUtils.isValidIpv6(ip6Dns2)) {
+            throw new InvalidParameterValueException("Please enter a valid IPv6 address for IP6 DNS2");
+        }
+
+        if (StringUtils.isNotBlank(ip6SuperCidr)) {
+            if (!NetUtils.isValidIp6Cidr(ip6SuperCidr)) {
+                throw new InvalidParameterValueException("Please enter a valid IPv6 cidr");
+            }
+
+            if (!NetUtils.isValidPrivateAsn(asNumber)) {
+                throw new InvalidParameterValueException(String.format("Please specify a valid private autonomous system number", ApiConstants.AUTONOMOUS_NUMBER));
+            }
+
+            // If IPv6 guest CIDR is configured, make sure that the CIDR/Private ASN is not duplicate.
+            if (checkDuplicateIp6SuperCidr && !isIp6SuperCidrAvailable(ip6SuperCidr)) {
+                    throw new InvalidParameterValueException(String.format("A zone with %s already exists. Please specify a unique IPv6 Guest CIDR.", ip6SuperCidr));
+            }
+            if (checkDuplicateAsn && !isAsnAvailable(asNumber)) {
+                    throw new InvalidParameterValueException(String.format("A zone with %s already exists. Please specify a unique private ASN.", asNumber));
+            }
+        } else if (StringUtils.isNotBlank(asNumber)) {
+            throw new InvalidParameterValueException(String.format("%s parameter can not be set if IPv6 super CIDR is not configured", ApiConstants.AUTONOMOUS_NUMBER));
+        }
+    }
+
     private AffinityGroup createDedicatedAffinityGroup(String affinityGroupName, final Long domainId, final Long accountId) {
         if (affinityGroupName == null) {
             // default to a groupname with account/domain information
@@ -1937,6 +1981,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
         final String internalDns1 = cmd.getInternalDns1();
         final String internalDns2 = cmd.getInternalDns2();
         final String guestCidr = cmd.getGuestCidrAddress();
+        final String ip6SuperCidr = cmd.getIp6SuperCidrAddress();
+        final String asNumber = cmd.getAsNumber();
         final Long domainId = cmd.getDomainId();
         final String type = cmd.getNetworkType();
         Boolean isBasic = false;
@@ -1958,8 +2004,16 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
         final NetworkType zoneType = isBasic ? NetworkType.Basic : NetworkType.Advanced;
 
         // error out when the parameter specified for Basic zone
-        if (zoneType == NetworkType.Basic && guestCidr != null) {
-            throw new InvalidParameterValueException("guestCidrAddress parameter is not supported for Basic zone");
+        if (zoneType == NetworkType.Basic) {
+            if (StringUtils.isNotBlank(guestCidr)) {
+                throw new InvalidParameterValueException(String.format("%s parameter is not supported for Basic zone", ApiConstants.GUEST_CIDR_ADDRESS));
+            }
+            if (StringUtils.isNotBlank(ip6SuperCidr)) {
+                throw new InvalidParameterValueException(String.format("%s parameter is not supported for Basic zone", ApiConstants.IP6_SUPER_CIDR_ADDRESS));
+            }
+            if (StringUtils.isNotBlank(asNumber)) {
+                throw new InvalidParameterValueException(String.format("%s parameter is not supported for Basic zone", ApiConstants.AUTONOMOUS_NUMBER));
+            }
         }
 
         DomainVO domainVO = null;
@@ -1972,8 +2026,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
             isSecurityGroupEnabled = true;
         }
 
-        return createZone(userId, zoneName, dns1, dns2, internalDns1, internalDns2, guestCidr, domainVO != null ? domainVO.getName() : null, domainId, zoneType, allocationState,
-                networkDomain, isSecurityGroupEnabled, isLocalStorageEnabled, ip6Dns1, ip6Dns2);
+        return createZone(userId, zoneName, dns1, dns2, internalDns1, internalDns2, guestCidr, domainVO != null ? domainVO.getName() : null, domainId, zoneType, allocationState, networkDomain,
+                isSecurityGroupEnabled, isLocalStorageEnabled, ip6Dns1, ip6Dns2, ip6SuperCidr, asNumber);
     }
 
     @Override
@@ -3742,6 +3796,14 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
         return _zoneDao.findById(zoneId) != null;
     }
 
+    private boolean isIp6SuperCidrAvailable(String ip6SuperCidr) {
+        return (_zoneDao.findByIp6SuperCidr(ip6SuperCidr) == null);
+    }
+
+    private boolean isAsnAvailable(String asNumber) {
+        return (_zoneDao.findByAsn(asNumber) == null);
+    }
+
     private String getZoneName(final long zoneId) {
         final DataCenterVO zone = _zoneDao.findById(new Long(zoneId));
         if (zone != null) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c198d44a/server/test/com/cloud/configuration/ConfigurationManagerTest.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/configuration/ConfigurationManagerTest.java b/server/test/com/cloud/configuration/ConfigurationManagerTest.java
index 5926a34..1125050 100644
--- a/server/test/com/cloud/configuration/ConfigurationManagerTest.java
+++ b/server/test/com/cloud/configuration/ConfigurationManagerTest.java
@@ -33,6 +33,7 @@ import java.util.Map;
 import java.util.UUID;
 
 import com.cloud.user.User;
+
 import org.apache.log4j.Logger;
 import org.junit.After;
 import org.junit.Assert;
@@ -533,4 +534,82 @@ public class ConfigurationManagerTest {
         Mockito.when(_accountMgr.getAccount(1l)).thenReturn(account);
         Assert.assertNotNull(configurationMgr.getVlanAccount(42l));
     }
+
+    @Test
+    public void validateIp6Parameters() {
+
+        //Validate Zone create
+            //** with no IPv6
+            validateIp6ParameterTest(false, null, null, null, null, true, true, true, "Zone create with no IPv6 parameters should be accepted");
+
+            //** with invalid IPv6 DNS1 and invalid IPv6 DNS2
+            validateIp6ParameterTest(true, "8.8.8.8", "8.8.4.4", null, null, true, true, true, "Zone create with invalid IPv6 DNS1/DNS1 parameters should not be accepted");
+
+            //** with valid IPv6 DNS1 and DNS2
+            validateIp6ParameterTest(false, "2620:0:ccc::2", "2620:0:ccd::2", null, null, true, true, true, "Zone create with valid IPv6 DNS1/DNS1 parameters should be accepted");
+
+            //** with valid IPv6 DNS and invalid IPv6 Super Cidr
+            validateIp6ParameterTest(true, "2620:0:ccc::2", "2620:0:ccd::2", "8.8.8.8", null, true, true, true, "Zone create with valid IPv6 DNS1/DNS1 and invalid IPv6 Super CIDR parameters should not be accepted");
+
+            //** with valid IPv6 DNS, valid IPv6 Super Cidr and invalid asNumber
+            validateIp6ParameterTest(true, "2620:0:ccc::2", "2620:0:ccd::2", "2001:67c:2834:0:0:0:0:0/50", "6500", true, true, true, "Zone create with valid IPv6 DNS1/DNS1, IPv6 Super CIDR and invalid asNumber parameters should not be accepted");
+
+            //** with valid IPv6 DNS, valid IPv6 Super Cidr and no asNumber
+            validateIp6ParameterTest(true, "2620:0:ccc::2", "2620:0:ccd::2", "2001:67c:2834:0:0:0:0:0/50", null, true, true, true, "Zone create with valid IPv6 DNS1/DNS1, IPv6 Super CIDR and no asNumber parameters should not be accepted");
+
+            //** with valid IPv6 DNS, invalid IPv6 Super Cidr and valid asNumber
+            validateIp6ParameterTest(true, "2620:0:ccc::2", "2620:0:ccd::2", "2001:67c:2834:0:0:0:0:0:0/50", "65000", true, true, true, "Zone create with valid IPv6 DNS1/DNS1, invalid IPv6 Super CIDR and valid asNumber parameters should not be accepted");
+
+            //** with valid IPv6 DNS, no IPv6 Super Cidr and valid asNumber
+            validateIp6ParameterTest(true, "2620:0:ccc::2", "2620:0:ccd::2", "", "65000", true, true, true, "Zone create with valid IPv6 DNS1/DNS1, no IPv6 Super CIDR and valid asNumber parameters should not be accepted");
+
+            when(configurationMgr._zoneDao.findByIp6SuperCidr(anyString())).thenReturn(null);
+            when(configurationMgr._zoneDao.findByAsn(anyString())).thenReturn(null);
+            //** with valid IPv6 DNS, Unique valid IPv6 Super Cidr and Unique valid asNumber
+            validateIp6ParameterTest(false, "2620:0:ccc::2", "2620:0:ccd::2", "2001:67c:2834:0:0:0:0:0/50", "65000", true, true, true, "Zone create with valid IPv6 DNS1/DNS1, unique IPv6 Super CIDR and asNumber parameters should be accepted");
+
+            when(configurationMgr._zoneDao.findByIp6SuperCidr(anyString())).thenReturn(new DataCenterVO(0l, null, null, null, null, null, null, null, null, null, null, null, null));
+            when(configurationMgr._zoneDao.findByAsn(anyString())).thenReturn(null);
+            //** with valid IPv6 DNS, duplicate valid IPv6 Super Cidr and Unique valid asNumber
+            validateIp6ParameterTest(true, "2620:0:ccc::2", "2620:0:ccd::2", "2001:67c:2834:0:0:0:0:0/50", "65000", true, true, true, "Zone create with valid IPv6 DNS1/DNS1, with duplicate IPv6 Super CIDR and unique asNumber parameters should not be accepted");
+
+            when(configurationMgr._zoneDao.findByIp6SuperCidr(anyString())).thenReturn(null);
+            when(configurationMgr._zoneDao.findByAsn(anyString())).thenReturn(new DataCenterVO(0l, null, null, null, null, null, null, null, null, null, null, null, null));
+            //** with valid IPv6 DNS, Unique valid IPv6 Super Cidr and duplicate valid asNumber
+            validateIp6ParameterTest(true, "2620:0:ccc::2", "2620:0:ccd::2", "2001:67c:2834:0:0:0:0:0/50", "65000", true, true, true, "Zone create with valid IPv6 DNS1/DNS1, with unique IPv6 Super CIDR and duplicate asNumber parameters should not be accepted");
+
+        //Validate Zone Edit which check no duplicate
+
+            when(configurationMgr._zoneDao.findByIp6SuperCidr(anyString())).thenReturn(null);
+            when(configurationMgr._zoneDao.findByAsn(anyString())).thenReturn(null);
+            //** with valid IPv6 DNS, Unique valid IPv6 Super Cidr and Unique valid asNumber
+            validateIp6ParameterTest(false, "2620:0:ccc::2", "2620:0:ccd::2", "2001:67c:2834:0:0:0:0:0/50", "65000", false, false, false, "Zone create with valid IPv6 DNS1/DNS1, unique IPv6 Super CIDR and asNumber parameters should be accepted with no duplicate checks");
+
+            when(configurationMgr._zoneDao.findByIp6SuperCidr(anyString())).thenReturn(new DataCenterVO(0l, null, null, null, null, null, null, null, null, null, null, null, null));
+            when(configurationMgr._zoneDao.findByAsn(anyString())).thenReturn(new DataCenterVO(0l, null, null, null, null, null, null, null, null, null, null, null, null));
+            //** with valid IPv6 DNS, duplicate valid IPv6 Super Cidr and duplicate valid asNumber, with no duplicate checks.
+            validateIp6ParameterTest(false, "2620:0:ccc::2", "2620:0:ccd::2", "2001:67c:2834:0:0:0:0:0/50", "65000", false, false, false, "Zone create with valid IPv6 DNS1/DNS1, duplicate IPv6 Super CIDR and asNumber parameters should be accepted with no duplicate checks");
+
+            when(configurationMgr._zoneDao.findByIp6SuperCidr(anyString())).thenReturn(new DataCenterVO(0l, null, null, null, null, null, null, null, null, null, null, null, null));
+            when(configurationMgr._zoneDao.findByAsn(anyString())).thenReturn(null);
+            //** with valid IPv6 DNS, duplicate valid IPv6 Super Cidr and Unique valid asNumber
+            validateIp6ParameterTest(true, "2620:0:ccc::2", "2620:0:ccd::2", "2001:67c:2834:0:0:0:0:0/50", "65000", false, true, false, "Zone create with valid IPv6 DNS1/DNS1, duplicate IPv6 Super CIDR and unique asNumber parameters should not be accepted with no duplicate checks");
+
+            when(configurationMgr._zoneDao.findByIp6SuperCidr(anyString())).thenReturn(null);
+            when(configurationMgr._zoneDao.findByAsn(anyString())).thenReturn(new DataCenterVO(0l, null, null, null, null, null, null, null, null, null, null, null, null));
+            //** with valid IPv6 DNS, Unique valid IPv6 Super Cidr and duplicate valid asNumber
+            validateIp6ParameterTest(true, "2620:0:ccc::2", "2620:0:ccd::2", "2001:67c:2834:0:0:0:0:0/50", "65000", false, false, true, "Zone create with valid IPv6 DNS1/DNS1, unique IPv6 Super CIDR and duplicate asNumber parameters should not be accepted");
+
+    }
+
+    private void validateIp6ParameterTest(boolean shouldConditionFail, String ip6Dns1, String ip6Dns2, String ip6SuperCidr, String asNumber, boolean checkDuplicateName,
+            boolean checkDuplicateIp6SuperCidr, boolean checkDuplicateAsn, String message) {
+        boolean validationCheck = shouldConditionFail;
+        try {
+            configurationMgr.validateIp6Parameters(ip6Dns1, ip6Dns2, ip6SuperCidr, asNumber, checkDuplicateName, checkDuplicateIp6SuperCidr, checkDuplicateAsn);
+        } catch (InvalidParameterValueException e) {
+            validationCheck = !shouldConditionFail;
+        }
+        Assert.assertFalse(message, validationCheck);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c198d44a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
index fc535bd..7bac9b6 100644
--- a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
@@ -505,9 +505,9 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu
      * @see com.cloud.configuration.ConfigurationManager#createZone(long, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.Long, com.cloud.dc.DataCenter.NetworkType, java.lang.String, java.lang.String, boolean, boolean)
      */
     @Override
-    public DataCenterVO createZone(long userId, String zoneName, String dns1, String dns2, String internalDns1, String internalDns2, String guestCidr, String domain,
-        Long domainId, NetworkType zoneType, String allocationState, String networkDomain, boolean isSecurityGroupEnabled, boolean isLocalStorageEnabled, String ip6Dns1,
-        String ip6Dns2) {
+    public DataCenterVO createZone(long userId, String zoneName, String dns1, String dns2, String internalDns1, String internalDns2, String guestCidr, String domain, Long domainId,
+        NetworkType zoneType, String allocationState, String networkDomain, boolean isSecurityGroupEnabled, boolean isLocalStorageEnabled, String ip6Dns1, String ip6Dns2,
+        String ip6SuperCidr, String asNumber) {
         // TODO Auto-generated method stub
         return null;
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c198d44a/tools/marvin/marvin/deployDataCenter.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/deployDataCenter.py b/tools/marvin/marvin/deployDataCenter.py
index 4fcd696..b8725a9 100644
--- a/tools/marvin/marvin/deployDataCenter.py
+++ b/tools/marvin/marvin/deployDataCenter.py
@@ -704,6 +704,10 @@ class DeployDataCenters(object):
                 zonecmd.domain = zone.domain
                 if zone.securitygroupenabled != "true":
                     zonecmd.guestcidraddress = zone.guestcidraddress
+                if zone.asNumber != "":
+                    zonecmd.asNumber = zone.asNumber
+                if zone.ip6supercidraddress != "":
+                    zonecmd.ip6supercidraddress = zone.ip6supercidraddress
                 zoneId = self.createZone(zonecmd)
                 if zoneId == FAILED:
                     self.__tcRunLogger.\

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c198d44a/utils/src/com/cloud/utils/net/NetUtils.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java
index 2cd4753..e263dce 100644
--- a/utils/src/com/cloud/utils/net/NetUtils.java
+++ b/utils/src/com/cloud/utils/net/NetUtils.java
@@ -31,6 +31,7 @@ import java.net.URI;
 import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Formatter;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Random;
 import java.util.Set;
@@ -40,6 +41,7 @@ import java.util.TreeSet;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.SystemUtils;
 import org.apache.commons.net.util.SubnetUtils;
 import org.apache.commons.validator.routines.InetAddressValidator;
@@ -51,6 +53,7 @@ import com.cloud.utils.script.Script;
 import com.googlecode.ipv6.IPv6Address;
 import com.googlecode.ipv6.IPv6AddressRange;
 import com.googlecode.ipv6.IPv6Network;
+import com.googlecode.ipv6.IPv6NetworkMask;
 
 public class NetUtils {
     protected final static Logger s_logger = Logger.getLogger(NetUtils.class);
@@ -1399,6 +1402,16 @@ public class NetUtils {
         return resultIp;
     }
 
+    /**
+     * Split a given IPv6 CIDR into multiple subnets based on the given prefix length
+     * @param ip6SuperNetworkCidr
+     * @param prefixLength
+     * @return Iterator<IPv6Network>
+     */
+    public static Iterator<IPv6Network> splitIp6Network(String ip6NetworkCidr, int prefixLength) {
+        return IPv6Network.fromString(ip6NetworkCidr).split(IPv6NetworkMask.fromPrefixLength(prefixLength));
+    }
+
     public static String standardizeIp6Address(final String ip6Addr) {
         try {
             return IPv6Address.fromString(ip6Addr).toString();
@@ -1415,6 +1428,23 @@ public class NetUtils {
         }
     }
 
+    /**
+     * Validate if asNumber is in valid private ASN range as defined in rfc6996
+     * @param asNumber
+     * @return true if valid
+     */
+    public static boolean isValidPrivateAsn(String asNumber) {
+        if (StringUtils.isNotBlank(asNumber)) {
+            try {
+                Long asNumberLong = Long.parseLong(asNumber);
+                return ((asNumberLong >= 64512 && asNumberLong <= 65534) || (asNumberLong >= 4200000000l && asNumberLong <= 4294967294l));
+            } catch (NumberFormatException nfe) {
+                return false;
+            }
+        }
+        return false;
+    }
+
     static final String VLAN_PREFIX = "vlan://";
     static final int VLAN_PREFIX_LENGTH = VLAN_PREFIX.length();
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/c198d44a/utils/test/com/cloud/utils/net/NetUtilsTest.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/net/NetUtilsTest.java b/utils/test/com/cloud/utils/net/NetUtilsTest.java
index 1ab4459..44fd91a 100644
--- a/utils/test/com/cloud/utils/net/NetUtilsTest.java
+++ b/utils/test/com/cloud/utils/net/NetUtilsTest.java
@@ -32,6 +32,7 @@ import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
 import java.math.BigInteger;
+import java.util.Iterator;
 import java.util.SortedSet;
 import java.util.TreeSet;
 
@@ -39,6 +40,7 @@ import org.apache.log4j.Logger;
 import org.junit.Test;
 
 import com.googlecode.ipv6.IPv6Address;
+import com.googlecode.ipv6.IPv6Network;
 
 public class NetUtilsTest {
 
@@ -418,4 +420,21 @@ public class NetUtilsTest {
 
         assertTrue("It should pass! 31 bit prefix.", is31PrefixCidr);
     }
+
+    @Test
+    public void testIp6NetworkSplit() {
+        Iterator<IPv6Network> ipv6networks = NetUtils.splitIp6Network("2001:67c:2834:0:0:0:0:0/50", 60);
+        assertTrue("IPv6 address should be split with out error", ipv6networks.hasNext());
+    }
+
+    @Test
+    public void testValidAsn() {
+        assertTrue("65000 is a valid private ASN", NetUtils.isValidPrivateAsn("65000"));
+        assertTrue("4200000000l is a valid private ASN", NetUtils.isValidPrivateAsn("4200000000"));
+
+        assertFalse("6500 is an invalid ASN", NetUtils.isValidPrivateAsn("6500"));
+        assertFalse("null is an invalid ASN", NetUtils.isValidPrivateAsn(null));
+        assertFalse("empty string is an invalid ASN", NetUtils.isValidPrivateAsn(""));
+        assertFalse("abc string is an invalid ASN", NetUtils.isValidPrivateAsn("abc"));
+    }
 }
\ No newline at end of file