Updated Branches:
  refs/heads/master 482ea4a71 -> 13ee8d186

Persistent Networks support

Signed-off-by: Murali Reddy <[email protected]>


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

Branch: refs/heads/master
Commit: 13ee8d18653da5c1a08e5762059452b387f32b61
Parents: 482ea4a
Author: Likitha Shetty <[email protected]>
Authored: Fri Feb 1 15:08:27 2013 +0530
Committer: Murali Reddy <[email protected]>
Committed: Fri Feb 1 15:10:06 2013 +0530

----------------------------------------------------------------------
 api/src/com/cloud/offering/NetworkOffering.java    |    3 +
 .../org/apache/cloudstack/api/ApiConstants.java    |    1 +
 .../admin/network/CreateNetworkOfferingCmd.java    |    7 ++
 .../api/response/NetworkOfferingResponse.java      |    7 ++
 .../cloudstack/api/response/NetworkResponse.java   |    7 ++
 server/src/com/cloud/api/ApiResponseHelper.java    |    2 +
 .../cloud/configuration/ConfigurationManager.java  |    3 +-
 .../configuration/ConfigurationManagerImpl.java    |   12 +++-
 .../src/com/cloud/network/NetworkManagerImpl.java  |   56 +++++++++++----
 .../src/com/cloud/network/NetworkServiceImpl.java  |   54 ++++++++++++--
 .../src/com/cloud/network/dao/NetworkDaoImpl.java  |   22 ++++++-
 .../com/cloud/network/dao/NetworkOpDaoImpl.java    |   23 +------
 .../src/com/cloud/offerings/NetworkOfferingVO.java |   23 +++++--
 .../com/cloud/server/ConfigurationServerImpl.java  |   14 ++--
 server/src/com/cloud/vm/UserVmManagerImpl.java     |   26 +++++++
 .../cloud/vpc/MockConfigurationManagerImpl.java    |    2 +-
 .../test/com/cloud/vpc/MockNetworkManagerImpl.java |    2 -
 .../cloud/vpc/dao/MockNetworkOfferingDaoImpl.java  |   12 ++--
 setup/db/create-schema.sql                         |    1 +
 setup/db/db/schema-40to410.sql                     |    4 +
 20 files changed, 213 insertions(+), 68 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/api/src/com/cloud/offering/NetworkOffering.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/offering/NetworkOffering.java 
b/api/src/com/cloud/offering/NetworkOffering.java
index f2c4de5..741a687 100644
--- a/api/src/com/cloud/offering/NetworkOffering.java
+++ b/api/src/com/cloud/offering/NetworkOffering.java
@@ -110,4 +110,7 @@ public interface NetworkOffering extends 
InfrastructureEntity, InternalIdentity,
     boolean getSpecifyIpRanges();
 
     boolean isInline();
+
+    boolean getIsPersistent();
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/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 f704aec..d895191 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -103,6 +103,7 @@ public class ApiConstants {
     public static final String IS_EXTRACTABLE = "isextractable";
     public static final String IS_FEATURED = "isfeatured";
     public static final String IS_PUBLIC = "ispublic";
+    public static final String IS_PERSISTENT = "ispersistent";
     public static final String IS_READY = "isready";
     public static final String IS_RECURSIVE = "isrecursive";
     public static final String ISO_FILTER = "isofilter";

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
----------------------------------------------------------------------
diff --git 
a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
 
b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
index 9d3ceb8..abd1d3b 100644
--- 
a/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
+++ 
b/api/src/org/apache/cloudstack/api/command/admin/network/CreateNetworkOfferingCmd.java
@@ -88,6 +88,9 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
     @Parameter(name=ApiConstants.SPECIFY_IP_RANGES, type=CommandType.BOOLEAN, 
description="true if network offering supports specifying ip ranges; defaulted 
to false if not specified")
     private Boolean specifyIpRanges;
 
+    @Parameter(name=ApiConstants.IS_PERSISTENT, type=CommandType.BOOLEAN, 
description="true if network offering supports persistent networks; defaulted 
to false if not specified")
+    private Boolean isPersistent;
+
     /////////////////////////////////////////////////////
     /////////////////// Accessors ///////////////////////
     /////////////////////////////////////////////////////
@@ -147,6 +150,10 @@ public class CreateNetworkOfferingCmd extends BaseCmd {
         return conserveMode;
     }
 
+    public Boolean getIsPersistent() {
+        return isPersistent == null ? false : isPersistent;
+    }
+
     public Map<String, List<String>> getServiceProviders() {
         Map<String, List<String>> serviceProviderMap = null;
         if (serviceProviderList != null && !serviceProviderList.isEmpty()) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
----------------------------------------------------------------------
diff --git 
a/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java 
b/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
index 5c14791..b83b29b 100644
--- a/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/NetworkOfferingResponse.java
@@ -80,6 +80,8 @@ public class NetworkOfferingResponse extends BaseResponse {
     @SerializedName(ApiConstants.FOR_VPC) @Param(description="true if network 
offering can be used by VPC networks only")
     private Boolean forVpc;
 
+    @SerializedName(ApiConstants.IS_PERSISTENT) @Param(description="true if 
network offering supports persistent networks, false otherwise")
+    private Boolean isPersistent;
 
     public void setId(String id) {
         this.id = id;
@@ -149,4 +151,9 @@ public class NetworkOfferingResponse extends BaseResponse {
     public void setForVpc(Boolean forVpc) {
         this.forVpc = forVpc;
     }
+
+    public void setIsPersistent(Boolean isPersistent) {
+        this.isPersistent = isPersistent;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/api/src/org/apache/cloudstack/api/response/NetworkResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java 
b/api/src/org/apache/cloudstack/api/response/NetworkResponse.java
index ba8ea32..40d6850 100644
--- a/api/src/org/apache/cloudstack/api/response/NetworkResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/NetworkResponse.java
@@ -141,6 +141,9 @@ public class NetworkResponse extends BaseResponse 
implements ControlledEntityRes
     @SerializedName(ApiConstants.CAN_USE_FOR_DEPLOY) @Param(description="list 
networks available for vm deployment")
     private Boolean canUseForDeploy;
 
+    @SerializedName(ApiConstants.IS_PERSISTENT) @Param(description="list 
networks that are persistent")
+    private Boolean isPersistent;
+
     @SerializedName(ApiConstants.TAGS)  @Param(description="the list of 
resource tags associated with network", responseObject = 
ResourceTagResponse.class)
     private List<ResourceTagResponse> tags;
 
@@ -301,6 +304,10 @@ public class NetworkResponse extends BaseResponse 
implements ControlledEntityRes
         this.canUseForDeploy = canUseForDeploy;
     }
 
+    public void setIsPersistent(Boolean isPersistent) {
+        this.isPersistent = isPersistent;
+    }
+
     public void setTags(List<ResourceTagResponse> tags) {
         this.tags = tags;
     }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java 
b/server/src/com/cloud/api/ApiResponseHelper.java
index 0ae4f0f..2dcd09c 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -1901,6 +1901,7 @@ public class ApiResponseHelper implements 
ResponseGenerator {
         response.setConserveMode(offering.isConserveMode());
         response.setSpecifyIpRanges(offering.getSpecifyIpRanges());
         response.setAvailability(offering.getAvailability().toString());
+        response.setIsPersistent(offering.getIsPersistent());
         response.setNetworkRate(ApiDBUtils.getNetworkRate(offering.getId()));
         Long so = null;
         if (offering.getServiceOfferingId() != null) {
@@ -2053,6 +2054,7 @@ public class ApiResponseHelper implements 
ResponseGenerator {
             
response.setNetworkOfferingDisplayText(networkOffering.getDisplayText());
             response.setIsSystem(networkOffering.isSystemOnly());
             
response.setNetworkOfferingAvailability(networkOffering.getAvailability().toString());
+            response.setIsPersistent(networkOffering.getIsPersistent());
         }
 
         if (network.getAclType() != null) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/server/src/com/cloud/configuration/ConfigurationManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManager.java 
b/server/src/com/cloud/configuration/ConfigurationManager.java
index 09e8ac9..5c1b0d5 100644
--- a/server/src/com/cloud/configuration/ConfigurationManager.java
+++ b/server/src/com/cloud/configuration/ConfigurationManager.java
@@ -173,6 +173,7 @@ public interface ConfigurationManager extends 
ConfigurationService, Manager {
      * @param trafficType
      * @param tags
      * @param specifyVlan
+     * @param isPersistent
      *            ;
      * @param networkRate
      *            TODO
@@ -196,7 +197,7 @@ public interface ConfigurationManager extends 
ConfigurationService, Manager {
 
     NetworkOfferingVO createNetworkOffering(String name, String displayText, 
TrafficType trafficType, String tags, boolean specifyVlan, Availability 
availability, Integer networkRate, Map<Service, Set<Provider>> 
serviceProviderMap,
             boolean isDefault, Network.GuestType type, boolean systemOnly, 
Long serviceOfferingId, boolean conserveMode, Map<Service, Map<Capability, 
String>> serviceCapabilityMap,
-            boolean specifyIpRanges);
+            boolean specifyIpRanges, boolean isPersistent);
 
     Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long 
physicalNetworkId, boolean forVirtualNetwork, Long podId, String startIP, 
String endIP, String vlanGateway, String vlanNetmask, String vlanId, Account 
vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String 
vlanIp6Cidr) throws InsufficientCapacityException, 
ConcurrentOperationException, InvalidParameterValueException;
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/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 c8acf3b..9443447 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -2995,6 +2995,7 @@ public class ConfigurationManagerImpl implements 
ConfigurationManager, Configura
         Availability availability = null;
         Network.GuestType guestType = null;
         boolean specifyIpRanges = cmd.getSpecifyIpRanges();
+        boolean isPersistent = cmd.getIsPersistent();
 
         // Verify traffic type
         for (TrafficType tType : TrafficType.values()) {
@@ -3165,7 +3166,7 @@ public class ConfigurationManagerImpl implements 
ConfigurationManager, Configura
         }
 
         return createNetworkOffering(name, displayText, trafficType, tags, 
specifyVlan, availability, networkRate, serviceProviderMap, false, guestType, 
false,
-                serviceOfferingId, conserveMode, serviceCapabilityMap, 
specifyIpRanges);
+                serviceOfferingId, conserveMode, serviceCapabilityMap, 
specifyIpRanges, isPersistent);
     }
 
     void validateLoadBalancerServiceCapabilities(Map<Capability, String> 
lbServiceCapabilityMap) {
@@ -3253,7 +3254,7 @@ public class ConfigurationManagerImpl implements 
ConfigurationManager, Configura
     @DB
     public NetworkOfferingVO createNetworkOffering(String name, String 
displayText, TrafficType trafficType, String tags, boolean specifyVlan, 
Availability availability, Integer networkRate,
             Map<Service, Set<Provider>> serviceProviderMap, boolean isDefault, 
Network.GuestType type, boolean systemOnly, Long serviceOfferingId,
-            boolean conserveMode, Map<Service, Map<Capability, String>> 
serviceCapabilityMap, boolean specifyIpRanges) {
+            boolean conserveMode, Map<Service, Map<Capability, String>> 
serviceCapabilityMap, boolean specifyIpRanges, boolean isPersistent) {
 
         String multicastRateStr = 
_configDao.getValue("multicast.throttling.rate");
         int multicastRate = ((multicastRateStr == null) ? 10 : 
Integer.parseInt(multicastRateStr));
@@ -3274,6 +3275,11 @@ public class ConfigurationManagerImpl implements 
ConfigurationManager, Configura
                                                         + type + " and service 
" + Service.SourceNat.getName() + " is supported");
         }
 
+        // isPersistent should always be false for Shared network Offerings
+        if (isPersistent && type == GuestType.Shared) {
+            throw new InvalidParameterValueException("isPersistent should be 
false if network offering's type is " + type);
+        }
+
         // validate availability value
         if (availability == NetworkOffering.Availability.Required) {
             boolean canOffBeRequired = (type == GuestType.Isolated && 
serviceProviderMap.containsKey(Service.SourceNat));
@@ -3352,7 +3358,7 @@ public class ConfigurationManagerImpl implements 
ConfigurationManager, Configura
 
         NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, 
trafficType, systemOnly, specifyVlan, 
                 networkRate, multicastRate, isDefault, availability, tags, 
type, conserveMode, dedicatedLb,
-                sharedSourceNat, redundantRouter, elasticIp, elasticLb, 
specifyIpRanges, inline);
+                sharedSourceNat, redundantRouter, elasticIp, elasticLb, 
specifyIpRanges, inline, isPersistent);
 
         if (serviceOfferingId != null) {
             offering.setServiceOfferingId(serviceOfferingId);

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java 
b/server/src/com/cloud/network/NetworkManagerImpl.java
index 218583b..6fe810e 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -77,6 +77,8 @@ import com.cloud.offerings.dao.NetworkOfferingServiceMapDao;
 import com.cloud.org.Grouping;
 import com.cloud.user.*;
 import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.UserDao;
+import com.cloud.utils.Journal;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
 import com.cloud.utils.component.Adapters;
@@ -127,6 +129,8 @@ public class NetworkManagerImpl implements NetworkManager, 
Manager, Listener {
     @Inject
     DomainDao _domainDao = null;
     @Inject
+    UserDao _userDao = null;
+    @Inject
     ConfigurationDao _configDao;
     @Inject
     UserVmDao _userVmDao = null;
@@ -856,14 +860,14 @@ public class NetworkManagerImpl implements 
NetworkManager, Manager, Listener {
         NetworkOfferingVO offering = null;
         if 
(_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOfferingWithSGService)
 == null) {
             offering = 
_configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOfferingWithSGService,
 "Offering for Shared Security group enabled networks", TrafficType.Guest, null,
-                    true, Availability.Optional, null, 
defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, 
null, true, null, true);
+                    true, Availability.Optional, null, 
defaultSharedNetworkOfferingProviders, true, Network.GuestType.Shared, false, 
null, true, null, true, false);
             offering.setState(NetworkOffering.State.Enabled);
             _networkOfferingDao.update(offering.getId(), offering);
         }
 
         if 
(_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedNetworkOffering)
 == null) {
             offering = 
_configMgr.createNetworkOffering(NetworkOffering.DefaultSharedNetworkOffering, 
"Offering for Shared networks", TrafficType.Guest, null, true, 
Availability.Optional, null,
-                    defaultSharedNetworkOfferingProviders, true, 
Network.GuestType.Shared, false, null, true, null, true);
+                    defaultSharedNetworkOfferingProviders, true, 
Network.GuestType.Shared, false, null, true, null, true, false);
             offering.setState(NetworkOffering.State.Enabled);
             _networkOfferingDao.update(offering.getId(), offering);
         }
@@ -886,7 +890,7 @@ public class NetworkManagerImpl implements NetworkManager, 
Manager, Listener {
             offering = 
_configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingWithSourceNatService,
                     "Offering for Isolated networks with Source Nat service 
enabled", TrafficType.Guest,
                     null, false, Availability.Required, null, 
defaultINetworkOfferingProvidersForVpcNetwork,
-                    true, Network.GuestType.Isolated, false, null, true, null, 
false);
+                    true, Network.GuestType.Isolated, false, null, true, null, 
false, false);
             offering.setState(NetworkOffering.State.Enabled);
             _networkOfferingDao.update(offering.getId(), offering);
         }
@@ -895,7 +899,7 @@ public class NetworkManagerImpl implements NetworkManager, 
Manager, Listener {
             offering = 
_configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworks,
                     "Offering for Isolated VPC networks with Source Nat 
service enabled", TrafficType.Guest,
                     null, false, Availability.Optional, null, 
defaultVPCOffProviders,
-                    true, Network.GuestType.Isolated, false, null, false, 
null, false);
+                    true, Network.GuestType.Isolated, false, null, false, 
null, false, false);
             offering.setState(NetworkOffering.State.Enabled);
             _networkOfferingDao.update(offering.getId(), offering);
         }
@@ -906,7 +910,7 @@ public class NetworkManagerImpl implements NetworkManager, 
Manager, Listener {
             offering = 
_configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOfferingForVpcNetworksNoLB,
                     "Offering for Isolated VPC networks with Source Nat 
service enabled and LB service disabled", TrafficType.Guest,
                     null, false, Availability.Optional, null, 
defaultVPCOffProviders,
-                    true, Network.GuestType.Isolated, false, null, false, 
null, false);
+                    true, Network.GuestType.Isolated, false, null, false, 
null, false, false);
             offering.setState(NetworkOffering.State.Enabled);
             _networkOfferingDao.update(offering.getId(), offering);
         }
@@ -915,7 +919,7 @@ public class NetworkManagerImpl implements NetworkManager, 
Manager, Listener {
             offering = 
_configMgr.createNetworkOffering(NetworkOffering.DefaultIsolatedNetworkOffering,
                     "Offering for Isolated networks with no Source Nat 
service", TrafficType.Guest, null, true,
                     Availability.Optional, null, 
defaultIsolatedNetworkOfferingProviders, true, Network.GuestType.Isolated,
-                    false, null, true, null, true);
+                    false, null, true, null, true, false);
             offering.setState(NetworkOffering.State.Enabled);
             _networkOfferingDao.update(offering.getId(), offering);
         }
@@ -944,7 +948,7 @@ public class NetworkManagerImpl implements NetworkManager, 
Manager, Listener {
 
         if 
(_networkOfferingDao.findByUniqueName(NetworkOffering.DefaultSharedEIPandELBNetworkOffering)
 == null) {
             offering = 
_configMgr.createNetworkOffering(NetworkOffering.DefaultSharedEIPandELBNetworkOffering,
 "Offering for Shared networks with Elastic IP and Elastic LB capabilities", 
TrafficType.Guest, null, true,
-                    Availability.Optional, null, netscalerServiceProviders, 
true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true);
+                    Availability.Optional, null, netscalerServiceProviders, 
true, Network.GuestType.Shared, false, null, true, serviceCapabilityMap, true, 
false);
             offering.setState(NetworkOffering.State.Enabled);
             offering.setDedicatedLB(false);
             _networkOfferingDao.update(offering.getId(), offering);
@@ -1999,8 +2003,6 @@ public class NetworkManagerImpl implements 
NetworkManager, Manager, Listener {
         return network;
     }
 
-    
-
     @Override
     @DB
     public boolean shutdownNetwork(long networkId, ReservationContext context, 
boolean cleanupElements) {
@@ -2533,14 +2535,13 @@ public class NetworkManagerImpl implements 
NetworkManager, Manager, Listener {
         }
 
         // create new Virtual network (Isolated with SourceNAT) for the user 
if it doesn't exist
+        List<NetworkOfferingVO> requiredOfferings = 
_networkOfferingDao.listByAvailability(Availability.Required, false);
+        if (requiredOfferings.size() < 1) {
+            throw new CloudRuntimeException("Unable to find network offering 
with availability=" +
+        Availability.Required + " to automatically create the network as part 
of createVlanIpRange");
+        }
         if (createNetwork) {
-            List<NetworkOfferingVO> requiredOfferings = 
_networkOfferingDao.listByAvailability(Availability.Required, false);
-            if (requiredOfferings.size() < 1) {
-                throw new CloudRuntimeException("Unable to find network 
offering with availability=" +
-            Availability.Required + " to automatically create the network as 
part of createVlanIpRange");
-            }
             if (requiredOfferings.get(0).getState() == 
NetworkOffering.State.Enabled) {
-                
                 long physicalNetworkId = 
_networkModel.findPhysicalNetworkId(zoneId, requiredOfferings.get(0).getTags(), 
requiredOfferings.get(0).getTrafficType());
                 // Validate physical network
                 PhysicalNetwork physicalNetwork = 
_physicalNetworkDao.findById(physicalNetworkId);
@@ -2595,6 +2596,31 @@ public class NetworkManagerImpl implements 
NetworkManager, Manager, Listener {
         }
 
         txn.commit();
+
+        // if the network offering has persistent set to true, implement the 
network
+        if ( createNetwork && requiredOfferings.get(0).getIsPersistent() ) {
+            DataCenter zone = _dcDao.findById(zoneId);
+            DeployDestination dest = new DeployDestination(zone, null, null, 
null);
+            Account callerAccount = UserContext.current().getCaller();
+            UserVO callerUser = 
_userDao.findById(UserContext.current().getCallerUserId());
+            Journal journal = new Journal.LogJournal("Implementing " + 
guestNetwork, s_logger);
+            ReservationContext context = new 
ReservationContextImpl(UUID.randomUUID().toString(), journal, callerUser, 
callerAccount);
+            s_logger.debug("Implementing network " + guestNetwork + " as a 
part of network provision for persistent network");
+            try {
+                Pair<NetworkGuru, NetworkVO> implementedNetwork = 
implementNetwork(guestNetwork.getId(), dest, context);
+                if (implementedNetwork.first() == null) {
+                    s_logger.warn("Failed to implement the network " + 
guestNetwork);
+                }
+                guestNetwork = implementedNetwork.second();
+            } catch (Exception ex) {
+                s_logger.warn("Failed to implement network " + guestNetwork + 
" elements and resources as a part of" +
+                        " network provision due to ", ex);
+                CloudRuntimeException e = new CloudRuntimeException("Failed to 
implement network (with specified id)" +
+                        " elements and resources as a part of network 
provision for persistent network");
+                e.addProxyObject(guestNetwork, guestNetwork.getId(), 
"networkId");
+                throw e;
+            }
+        }
         return true;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/server/src/com/cloud/network/NetworkServiceImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java 
b/server/src/com/cloud/network/NetworkServiceImpl.java
index 622b448..5c70caa 100755
--- a/server/src/com/cloud/network/NetworkServiceImpl.java
+++ b/server/src/com/cloud/network/NetworkServiceImpl.java
@@ -70,7 +70,9 @@ import com.cloud.tags.ResourceTagVO;
 import com.cloud.tags.dao.ResourceTagDao;
 import com.cloud.user.*;
 import com.cloud.user.dao.AccountDao;
+import com.cloud.user.dao.UserDao;
 import com.cloud.utils.AnnotationHelper;
+import com.cloud.utils.Journal;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
 import com.cloud.utils.component.Adapters;
@@ -117,7 +119,8 @@ public class NetworkServiceImpl implements  NetworkService, 
Manager {
     AccountDao _accountDao = null;
     @Inject
     DomainDao _domainDao = null;
-
+    @Inject
+    UserDao _userDao = null;
     @Inject
     EventDao _eventDao = null;
     @Inject
@@ -887,11 +890,33 @@ public class NetworkServiceImpl implements  
NetworkService, Manager {
 
         txn.commit();
 
+        // if the network offering has persistent set to true, implement the 
network
+        if ( ntwkOff.getIsPersistent() ) {
+            try {
+                if ( network.getState() == Network.State.Setup ) {
+                    s_logger.debug("Network id=" + network.getId() + " is 
already provisioned");
+                    return network;
+                }
+                DeployDestination dest = new DeployDestination(zone, null, 
null, null);
+                UserVO callerUser = 
_userDao.findById(UserContext.current().getCallerUserId());
+                Journal journal = new Journal.LogJournal("Implementing " + 
network, s_logger);
+                ReservationContext context = new 
ReservationContextImpl(UUID.randomUUID().toString(), journal, callerUser, 
caller);
+                s_logger.debug("Implementing network " + network + " as a part 
of network provision for persistent network");
+                Pair<NetworkGuru, NetworkVO> implementedNetwork = 
_networkMgr.implementNetwork(network.getId(), dest, context);
+                if (implementedNetwork.first() == null) {
+                    s_logger.warn("Failed to provision the network " + 
network);
+                }
+                network = implementedNetwork.second();
+            } catch (ResourceUnavailableException ex) {
+                s_logger.warn("Failed to implement persistent guest network " 
+ network + "due to ", ex);
+                CloudRuntimeException e = new CloudRuntimeException("Failed to 
implement persistent guest network");
+                e.addProxyObject(network, network.getId(), "networkId");
+                throw e;
+            }
+        }
         return network;
     }
 
-   
-
     @Override
     public List<? extends Network> searchForNetworks(ListNetworksCmd cmd) {
         Long id = cmd.getId();
@@ -1507,9 +1532,9 @@ public class NetworkServiceImpl implements  
NetworkService, Manager {
         boolean networkOfferingChanged = false;
 
         long oldNetworkOfferingId = network.getNetworkOfferingId();
+        NetworkOffering oldNtwkOff = 
_networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
+        NetworkOfferingVO networkOffering = 
_networkOfferingDao.findById(networkOfferingId);
         if (networkOfferingId != null) {
-
-            NetworkOfferingVO networkOffering = 
_networkOfferingDao.findById(networkOfferingId);
             if (networkOffering == null || networkOffering.isSystemOnly()) {
                 InvalidParameterValueException ex = new 
InvalidParameterValueException("Unable to find network offering with specified 
id");
                 ex.addProxyObject(networkOffering, networkOfferingId, 
"networkOfferingId");                
@@ -1533,7 +1558,6 @@ public class NetworkServiceImpl implements  
NetworkService, Manager {
             }
 
             if (networkOfferingId != oldNetworkOfferingId) {
-                NetworkOffering oldNtwkOff = 
_networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
                 Collection<String> newProviders = 
_networkMgr.finalizeServicesAndProvidersForNetwork(networkOffering, 
network.getPhysicalNetworkId()).values();
                 Collection<String> oldProviders = 
_networkMgr.finalizeServicesAndProvidersForNetwork(oldNtwkOff, 
network.getPhysicalNetworkId()).values();
                 
@@ -1680,6 +1704,24 @@ public class NetworkServiceImpl implements  
NetworkService, Manager {
             }
         }
 
+        // 4) if network has been upgraded from a non persistent ntwk offering 
to a persistent ntwk offering,
+        // implement the network if its not already
+        if ( !oldNtwkOff.getIsPersistent() && 
networkOffering.getIsPersistent()) {
+            if( network.getState() == Network.State.Allocated) {
+                try {
+                    DeployDestination dest = new 
DeployDestination(_dcDao.findById(network.getDataCenterId()), null, null, null);
+                    _networkMgr.implementNetwork(network.getId(), dest, 
context);
+                } catch (Exception ex) {
+                    s_logger.warn("Failed to implement network " + network + " 
elements and resources as a part o" +
+                            "f network update due to ", ex);
+                    CloudRuntimeException e = new 
CloudRuntimeException("Failed to implement network (with specified" +
+                            " id) elements and resources as a part of network 
update");
+                    e.addProxyObject(network, networkId, "networkId");
+                    throw e;
+                }
+            }
+        }
+
         return getNetwork(network.getId());
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/server/src/com/cloud/network/dao/NetworkDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/dao/NetworkDaoImpl.java 
b/server/src/com/cloud/network/dao/NetworkDaoImpl.java
index 2c5b46d..f21854e 100644
--- a/server/src/com/cloud/network/dao/NetworkDaoImpl.java
+++ b/server/src/com/cloud/network/dao/NetworkDaoImpl.java
@@ -74,6 +74,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, 
Long> implements N
     final GenericSearchBuilder<NetworkVO, Long>  CountByZoneAndURI;
     final GenericSearchBuilder<NetworkVO, Long> VpcNetworksCount;
     final SearchBuilder<NetworkVO> OfferingAccountNetworkSearch;
+    final GenericSearchBuilder<NetworkVO, Long> GarbageCollectedSearch;
 
     ResourceTagsDaoImpl _tagsDao = 
ComponentLocator.inject(ResourceTagsDaoImpl.class);
     NetworkAccountDaoImpl _accountsDao = 
ComponentLocator.inject(NetworkAccountDaoImpl.class);
@@ -81,6 +82,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, 
Long> implements N
     NetworkOpDaoImpl _opDao = ComponentLocator.inject(NetworkOpDaoImpl.class);
     NetworkServiceMapDaoImpl _ntwkSvcMap = 
ComponentLocator.inject(NetworkServiceMapDaoImpl.class);
     NetworkOfferingDaoImpl _ntwkOffDao = 
ComponentLocator.inject(NetworkOfferingDaoImpl.class);
+    NetworkOpDaoImpl _ntwkOpDao = 
ComponentLocator.inject(NetworkOpDaoImpl.class);
 
 
     final TableGenerator _tgMacAddress;
@@ -215,6 +217,19 @@ public class NetworkDaoImpl extends 
GenericDaoBase<NetworkVO, Long> implements N
         OfferingAccountNetworkSearch.and("zoneId", 
OfferingAccountNetworkSearch.entity().getDataCenterId(), Op.EQ);
         OfferingAccountNetworkSearch.and("type", 
OfferingAccountNetworkSearch.entity().getGuestType(), Op.EQ);
         OfferingAccountNetworkSearch.done();
+
+        GarbageCollectedSearch = createSearchBuilder(Long.class);
+        
GarbageCollectedSearch.selectField(GarbageCollectedSearch.entity().getId());
+        SearchBuilder<NetworkOpVO> join7 = _ntwkOpDao.createSearchBuilder();
+        join7.and("activenics", join7.entity().getActiveNicsCount(), Op.EQ);
+        join7.and("gc", join7.entity().isGarbageCollected(), Op.EQ);
+        join7.and("check", join7.entity().isCheckForGc(), Op.EQ);
+        GarbageCollectedSearch.join("ntwkOpGC", join7, 
GarbageCollectedSearch.entity().getId(), join7.entity().getId(), 
JoinBuilder.JoinType.INNER);
+        SearchBuilder<NetworkOfferingVO> join8 = 
_ntwkOffDao.createSearchBuilder();
+        join8.and("isPersistent", join8.entity().getIsPersistent(), Op.EQ);
+        GarbageCollectedSearch.join("ntwkOffGC", join8, 
GarbageCollectedSearch.entity().getNetworkOfferingId(), join8.entity().getId(), 
JoinBuilder.JoinType.INNER);
+        GarbageCollectedSearch.done();
+
     }
 
     @Override
@@ -398,7 +413,12 @@ public class NetworkDaoImpl extends 
GenericDaoBase<NetworkVO, Long> implements N
 
     @Override
     public List<Long> findNetworksToGarbageCollect() {
-        return _opDao.getNetworksToGarbageCollect();
+        SearchCriteria<Long> sc = GarbageCollectedSearch.create();
+        sc.setJoinParameters("ntwkOffGC", "isPersistent", false);
+        sc.setJoinParameters("ntwkOpGC", "activenics", 0);
+        sc.setJoinParameters("ntwkOpGC", "gc", true);
+        sc.setJoinParameters("ntwkOpGC", "check", true);
+        return customSearch(sc, null);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/server/src/com/cloud/network/dao/NetworkOpDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/dao/NetworkOpDaoImpl.java 
b/server/src/com/cloud/network/dao/NetworkOpDaoImpl.java
index 298156e..bc46481 100644
--- a/server/src/com/cloud/network/dao/NetworkOpDaoImpl.java
+++ b/server/src/com/cloud/network/dao/NetworkOpDaoImpl.java
@@ -16,8 +16,6 @@
 // under the License.
 package com.cloud.network.dao;
 
-import java.util.List;
-
 import com.cloud.utils.db.Attribute;
 import com.cloud.utils.db.GenericDao;
 import com.cloud.utils.db.GenericDaoBase;
@@ -31,7 +29,6 @@ import com.cloud.utils.db.UpdateBuilder;
 public class NetworkOpDaoImpl extends GenericDaoBase<NetworkOpVO, Long> 
implements GenericDao<NetworkOpVO, Long> {
     protected final SearchBuilder<NetworkOpVO> AllFieldsSearch;
     protected final GenericSearchBuilder<NetworkOpVO, Integer> 
ActiveNicsSearch;
-    protected final GenericSearchBuilder<NetworkOpVO, Long> 
GarbageCollectSearch;
     protected final Attribute _activeNicsAttribute;
     
     protected NetworkOpDaoImpl() {
@@ -45,27 +42,11 @@ public class NetworkOpDaoImpl extends 
GenericDaoBase<NetworkOpVO, Long> implemen
         AllFieldsSearch = createSearchBuilder();
         AllFieldsSearch.and("network", AllFieldsSearch.entity().getId(), 
Op.EQ);
         AllFieldsSearch.done();
-        
-        GarbageCollectSearch = createSearchBuilder(Long.class);
-        
GarbageCollectSearch.selectField(GarbageCollectSearch.entity().getId());
-        GarbageCollectSearch.and("activenics", 
GarbageCollectSearch.entity().getActiveNicsCount(), Op.EQ);
-        GarbageCollectSearch.and("gc", 
GarbageCollectSearch.entity().isGarbageCollected(), Op.EQ);
-        GarbageCollectSearch.and("check", 
GarbageCollectSearch.entity().isCheckForGc(), Op.EQ);
-        GarbageCollectSearch.done();
-        
+
         _activeNicsAttribute = _allAttributes.get("activeNicsCount");
         assert _activeNicsAttribute != null : "Cannot find activeNicsCount";
     }
-    
-    public List<Long> getNetworksToGarbageCollect() {
-        SearchCriteria<Long> sc = GarbageCollectSearch.create();
-        sc.setParameters("activenics", 0);
-        sc.setParameters("gc", true);
-        sc.setParameters("check", true);
-        
-        return customSearch(sc, null);
-    }
-    
+
     public int getActiveNics(long networkId) {
         SearchCriteria<Integer> sc = ActiveNicsSearch.create();
         sc.setParameters("network", networkId);

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/server/src/com/cloud/offerings/NetworkOfferingVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/offerings/NetworkOfferingVO.java 
b/server/src/com/cloud/offerings/NetworkOfferingVO.java
index efaca76..5de76a5 100755
--- a/server/src/com/cloud/offerings/NetworkOfferingVO.java
+++ b/server/src/com/cloud/offerings/NetworkOfferingVO.java
@@ -116,6 +116,9 @@ public class NetworkOfferingVO implements NetworkOffering {
     @Column(name = "inline")
     boolean inline;
 
+    @Column(name = "is_persistent")
+    boolean isPersistent;
+
     @Override
     public String getDisplayText() {
         return displayText;
@@ -256,7 +259,7 @@ public class NetworkOfferingVO implements NetworkOffering {
     }
 
     public NetworkOfferingVO(String name, String displayText, TrafficType 
trafficType, boolean systemOnly, boolean specifyVlan, Integer rateMbps, Integer 
multicastRateMbps, boolean isDefault,
-            Availability availability, String tags, Network.GuestType 
guestType, boolean conserveMode, boolean specifyIpRanges) {
+            Availability availability, String tags, Network.GuestType 
guestType, boolean conserveMode, boolean specifyIpRanges, boolean isPersistent) 
{
         this.name = name;
         this.displayText = displayText;
         this.rateMbps = rateMbps;
@@ -278,12 +281,13 @@ public class NetworkOfferingVO implements NetworkOffering 
{
         this.elasticLb = false;
         this.inline = false;
         this.specifyIpRanges = specifyIpRanges;
+        this.isPersistent=isPersistent;
     }
 
     public NetworkOfferingVO(String name, String displayText, TrafficType 
trafficType, boolean systemOnly, boolean specifyVlan, Integer rateMbps, Integer 
multicastRateMbps, boolean isDefault,
             Availability availability, String tags, Network.GuestType 
guestType, boolean conserveMode, boolean dedicatedLb, boolean sharedSourceNat, 
boolean redundantRouter, boolean elasticIp, boolean elasticLb,
-            boolean specifyIpRanges, boolean inline) {
-        this(name, displayText, trafficType, systemOnly, specifyVlan, 
rateMbps, multicastRateMbps, isDefault, availability, tags, guestType, 
conserveMode, specifyIpRanges);
+            boolean specifyIpRanges, boolean inline, boolean isPersistent) {
+        this(name, displayText, trafficType, systemOnly, specifyVlan, 
rateMbps, multicastRateMbps, isDefault, availability, tags, guestType, 
conserveMode, specifyIpRanges, isPersistent);
         this.dedicatedLB = dedicatedLb;
         this.sharedSourceNat = sharedSourceNat;
         this.redundantRouter = redundantRouter;
@@ -304,13 +308,13 @@ public class NetworkOfferingVO implements NetworkOffering 
{
      *            TODO
      */
     public NetworkOfferingVO(String name, TrafficType trafficType, boolean 
specifyIpRanges) {
-        this(name, "System Offering for " + name, trafficType, true, false, 0, 
0, true, Availability.Required, null, null, true, specifyIpRanges);
+        this(name, "System Offering for " + name, trafficType, true, false, 0, 
0, true, Availability.Required, null, null, true, specifyIpRanges, false);
         this.state = State.Enabled;
     }
 
     public NetworkOfferingVO(String name, Network.GuestType guestType) {
         this(name, "System Offering for " + name, TrafficType.Guest, true, 
true, 0, 0, true, Availability.Optional,
-                null, Network.GuestType.Isolated, true, false);
+                null, Network.GuestType.Isolated, true, false, false);
         this.state = State.Enabled;
     }
 
@@ -365,4 +369,13 @@ public class NetworkOfferingVO implements NetworkOffering {
     public boolean isInline() {
         return inline;
     }
+
+    public void setIsPersistent(Boolean isPersistent) {
+        this.isPersistent = isPersistent;
+    }
+
+    public boolean getIsPersistent() {
+        return isPersistent;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/server/src/com/cloud/server/ConfigurationServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java 
b/server/src/com/cloud/server/ConfigurationServerImpl.java
index 98a6737..ebf140f 100755
--- a/server/src/com/cloud/server/ConfigurationServerImpl.java
+++ b/server/src/com/cloud/server/ConfigurationServerImpl.java
@@ -911,7 +911,7 @@ public class ConfigurationServerImpl implements 
ConfigurationServer {
                 "Offering for Shared Security group enabled networks",
                 TrafficType.Guest,
                 false, true, null, null, true, Availability.Optional,
-                null, Network.GuestType.Shared, true, true);
+                null, Network.GuestType.Shared, true, true, false);
 
         defaultSharedSGNetworkOffering.setState(NetworkOffering.State.Enabled);
         defaultSharedSGNetworkOffering = 
_networkOfferingDao.persistDefaultNetworkOffering(defaultSharedSGNetworkOffering);
@@ -928,7 +928,7 @@ public class ConfigurationServerImpl implements 
ConfigurationServer {
                 "Offering for Shared networks",
                 TrafficType.Guest,
                 false, true, null, null, true, Availability.Optional,
-                null, Network.GuestType.Shared, true, true);
+                null, Network.GuestType.Shared, true, true, false);
 
         defaultSharedNetworkOffering.setState(NetworkOffering.State.Enabled);
         defaultSharedNetworkOffering = 
_networkOfferingDao.persistDefaultNetworkOffering(defaultSharedNetworkOffering);
@@ -945,7 +945,7 @@ public class ConfigurationServerImpl implements 
ConfigurationServer {
                 "Offering for Isolated networks with Source Nat service 
enabled",
                 TrafficType.Guest,
                 false, false, null, null, true, Availability.Required,
-                null, Network.GuestType.Isolated, true, false);
+                null, Network.GuestType.Isolated, true, false, false);
 
         
defaultIsolatedSourceNatEnabledNetworkOffering.setState(NetworkOffering.State.Enabled);
         defaultIsolatedSourceNatEnabledNetworkOffering = 
_networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedSourceNatEnabledNetworkOffering);
@@ -963,7 +963,7 @@ public class ConfigurationServerImpl implements 
ConfigurationServer {
                 "Offering for Isolated networks with no Source Nat service",
                 TrafficType.Guest,
                 false, true, null, null, true, Availability.Optional,
-                null, Network.GuestType.Isolated, true, true);
+                null, Network.GuestType.Isolated, true, true, false);
 
         
defaultIsolatedEnabledNetworkOffering.setState(NetworkOffering.State.Enabled);
         defaultIsolatedEnabledNetworkOffering = 
_networkOfferingDao.persistDefaultNetworkOffering(defaultIsolatedEnabledNetworkOffering);
@@ -980,7 +980,7 @@ public class ConfigurationServerImpl implements 
ConfigurationServer {
                 "Offering for Shared networks with Elastic IP and Elastic LB 
capabilities",
                 TrafficType.Guest,
                 false, true, null, null, true, Availability.Optional,
-                null, Network.GuestType.Shared, true, false, false, false, 
true, true, true, false);
+                null, Network.GuestType.Shared, true, false, false, false, 
true, true, true, false, false);
 
         
defaultNetscalerNetworkOffering.setState(NetworkOffering.State.Enabled);
         defaultNetscalerNetworkOffering = 
_networkOfferingDao.persistDefaultNetworkOffering(defaultNetscalerNetworkOffering);
@@ -997,7 +997,7 @@ public class ConfigurationServerImpl implements 
ConfigurationServer {
                 "Offering for Isolated Vpc networks with Source Nat service 
enabled",
                 TrafficType.Guest,
                 false, false, null, null, true, Availability.Optional,
-                null, Network.GuestType.Isolated, false, false);
+                null, Network.GuestType.Isolated, false, false, false);
 
         
defaultNetworkOfferingForVpcNetworks.setState(NetworkOffering.State.Enabled);
         defaultNetworkOfferingForVpcNetworks = 
_networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworks);
@@ -1027,7 +1027,7 @@ public class ConfigurationServerImpl implements 
ConfigurationServer {
                 "Offering for Isolated Vpc networks with Source Nat service 
enabled and LB service Disabled",
                 TrafficType.Guest,
                 false, false, null, null, true, Availability.Optional,
-                null, Network.GuestType.Isolated, false, false);
+                null, Network.GuestType.Isolated, false, false, false);
 
         
defaultNetworkOfferingForVpcNetworksNoLB.setState(NetworkOffering.State.Enabled);
         defaultNetworkOfferingForVpcNetworksNoLB = 
_networkOfferingDao.persistDefaultNetworkOffering(defaultNetworkOfferingForVpcNetworksNoLB);

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java 
b/server/src/com/cloud/vm/UserVmManagerImpl.java
index a53e132..afa6545 100644
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -70,6 +70,7 @@ import com.cloud.network.Network.Service;
 import com.cloud.network.Networks.TrafficType;
 import com.cloud.network.dao.*;
 import com.cloud.network.element.UserDataServiceProvider;
+import com.cloud.network.guru.NetworkGuru;
 import com.cloud.network.lb.LoadBalancingRulesManager;
 import com.cloud.network.rules.FirewallManager;
 import com.cloud.network.rules.FirewallRuleVO;
@@ -112,6 +113,7 @@ import com.cloud.user.dao.AccountDao;
 import com.cloud.user.dao.SSHKeyPairDao;
 import com.cloud.user.dao.UserDao;
 import com.cloud.uservm.UserVm;
+import com.cloud.utils.Journal;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
 import com.cloud.utils.PasswordGenerator;
@@ -3917,6 +3919,30 @@ public class UserVmManagerImpl implements UserVmManager, 
UserVmService, Manager
                             Network newNetwork = 
_networkMgr.createGuestNetwork(requiredOfferings.get(0).getId(),
                                     newAccount.getAccountName() + "-network", 
newAccount.getAccountName() + "-network", null, null,
                                     null, null, newAccount, null, 
physicalNetwork, zone.getId(), ACLType.Account, null, null, null, null);
+                            // if the network offering has persistent set to 
true, implement the network
+                            if (requiredOfferings.get(0).getIsPersistent()) {
+                                DeployDestination dest = new 
DeployDestination(zone, null, null, null);
+                                UserVO callerUser = 
_userDao.findById(UserContext.current().getCallerUserId());
+                                Journal journal = new 
Journal.LogJournal("Implementing " + newNetwork, s_logger);
+                                ReservationContext context = new 
ReservationContextImpl(UUID.randomUUID().toString(),
+                                        journal, callerUser, caller);
+                                s_logger.debug("Implementing the network for 
account" + newNetwork + " as a part of" +
+                                        " network provision for persistent 
networks");
+                                try {
+                                    Pair<NetworkGuru, NetworkVO> 
implementedNetwork = _networkMgr.implementNetwork(newNetwork.getId(), dest, 
context);
+                                    if (implementedNetwork.first() == null) {
+                                        s_logger.warn("Failed to implement the 
network " + newNetwork);
+                                    }
+                                    newNetwork = implementedNetwork.second();
+                                } catch (Exception ex) {
+                                    s_logger.warn("Failed to implement network 
" + newNetwork + " elements and" +
+                                            " resources as a part of network 
provision for persistent network due to ", ex);
+                                    CloudRuntimeException e = new 
CloudRuntimeException("Failed to implement network" +
+                                            " (with specified id) elements and 
resources as a part of network provision");
+                                    e.addProxyObject(newNetwork, 
newNetwork.getId(), "networkId");
+                                    throw e;
+                                }
+                            }
                             defaultNetwork = 
_networkDao.findById(newNetwork.getId());
                         } else if (virtualNetworks.size() > 1) {
                             throw new InvalidParameterValueException("More 
than 1 default Isolated networks are found " +

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/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 17ad2e1..6fb057e 100644
--- a/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockConfigurationManagerImpl.java
@@ -482,7 +482,7 @@ public class MockConfigurationManagerImpl implements 
ConfigurationManager, Confi
     @Override
     public NetworkOfferingVO createNetworkOffering(String name, String 
displayText, TrafficType trafficType, String tags, boolean specifyVlan, 
Availability availability, Integer networkRate,
             Map<Service, Set<Provider>> serviceProviderMap, boolean isDefault, 
GuestType type, boolean systemOnly, Long serviceOfferingId, boolean 
conserveMode,
-            Map<Service, Map<Capability, String>> serviceCapabilityMap, 
boolean specifyIpRanges) {
+            Map<Service, Map<Capability, String>> serviceCapabilityMap, 
boolean specifyIpRanges, boolean isPersistent) {
         // TODO Auto-generated method stub
         return null;
     }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java 
b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
index 5d9c436..382068a 100644
--- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
+++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java
@@ -215,8 +215,6 @@ public class MockNetworkManagerImpl implements 
NetworkManager, NetworkService, M
 
 
 
-
-
     /* (non-Javadoc)
      * @see 
com.cloud.network.NetworkService#searchForNetworks(com.cloud.api.commands.ListNetworksCmd)
      */

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/server/test/com/cloud/vpc/dao/MockNetworkOfferingDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/dao/MockNetworkOfferingDaoImpl.java 
b/server/test/com/cloud/vpc/dao/MockNetworkOfferingDaoImpl.java
index 496864b..865daa4 100644
--- a/server/test/com/cloud/vpc/dao/MockNetworkOfferingDaoImpl.java
+++ b/server/test/com/cloud/vpc/dao/MockNetworkOfferingDaoImpl.java
@@ -100,28 +100,28 @@ public class MockNetworkOfferingDaoImpl extends 
GenericDaoBase<NetworkOfferingVO
         if (id.longValue() == 1) {
             //network offering valid for vpc
             vo = new NetworkOfferingVO("vpc", "vpc", TrafficType.Guest, false, 
true, null, null, false,
-                    Availability.Optional, null, Network.GuestType.Isolated, 
false, false);
+                    Availability.Optional, null, Network.GuestType.Isolated, 
false, false, false);
         } else if (id.longValue() == 2) {
             //invalid offering - source nat is not included
             vo = new NetworkOfferingVO("vpc", "vpc", TrafficType.Guest, false, 
true, null, null, false,
-                    Availability.Optional, null, Network.GuestType.Isolated, 
false, false);
+                    Availability.Optional, null, Network.GuestType.Isolated, 
false, false, false);
         } else if (id.longValue() == 3) {
             //network offering invalid for vpc (conserve mode off)
             vo = new NetworkOfferingVO("non vpc", "non vpc", 
TrafficType.Guest, false, true, null, null, false,
-                    Availability.Optional, null, Network.GuestType.Isolated, 
true, false);
+                    Availability.Optional, null, Network.GuestType.Isolated, 
true, false, false);
         } else if (id.longValue() == 4) {
             //network offering invalid for vpc (Shared)
             vo = new NetworkOfferingVO("non vpc", "non vpc", 
TrafficType.Guest, false, true, null, null, false,
-                    Availability.Optional, null, Network.GuestType.Shared, 
false, false);
+                    Availability.Optional, null, Network.GuestType.Shared, 
false, false, false);
         } else if (id.longValue() == 5) {
             //network offering invalid for vpc (has redundant router)
             vo = new NetworkOfferingVO("vpc", "vpc", TrafficType.Guest, false, 
true, null, null, false,
-                    Availability.Optional, null, Network.GuestType.Isolated, 
false, false);
+                    Availability.Optional, null, Network.GuestType.Isolated, 
false, false, false);
             vo.setRedundantRouter(true);
         } else if (id.longValue() == 6) {
             //network offering invalid for vpc (has lb service)   
             vo = new NetworkOfferingVO("vpc", "vpc", TrafficType.Guest, false, 
true, null, null, false,
-                    Availability.Optional, null, Network.GuestType.Isolated, 
false, false);
+                    Availability.Optional, null, Network.GuestType.Isolated, 
false, false, false);
         }
         
         if (vo != null) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/setup/db/create-schema.sql
----------------------------------------------------------------------
diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql
index beb9103..a847b43 100755
--- a/setup/db/create-schema.sql
+++ b/setup/db/create-schema.sql
@@ -315,6 +315,7 @@ CREATE TABLE `cloud`.`network_offerings` (
   `elastic_lb_service` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the 
network offering provides elastic lb service',
   `specify_ip_ranges` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the 
network offering provides an ability to define ip ranges',
   `inline` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Is this network 
offering LB provider is in inline mode',
+  `is_persistent` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the 
network offering provides an ability to create persistent networks',
   PRIMARY KEY (`id`),
   INDEX `i_network_offerings__system_only`(`system_only`),
   INDEX `i_network_offerings__removed`(`removed`),

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/13ee8d18/setup/db/db/schema-40to410.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-40to410.sql b/setup/db/db/schema-40to410.sql
index 39b686e..6d5b262 100644
--- a/setup/db/db/schema-40to410.sql
+++ b/setup/db/db/schema-40to410.sql
@@ -77,8 +77,12 @@ ALTER TABLE `cloud`.`inline_load_balancer_nic_map` DROP 
COLUMN load_balancer_id;
 ALTER TABLE upload ADD uuid VARCHAR(40);
 ALTER TABLE async_job modify job_cmd VARCHAR(255);
 
+
 ALTER TABLE `cloud`.`alert` ADD INDEX `last_sent` (`last_sent` DESC) ;
 
+ALTER TABLE `cloud`.`network_offerings` ADD COLUMN `is_persistent` int(1) 
unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides an 
ability to create persistent networks';
+
+
 -- populate uuid column with db id if uuid is null
 UPDATE `cloud`.`account` set uuid=id WHERE uuid is NULL;
 UPDATE `cloud`.`alert` set uuid=id WHERE uuid is NULL;

Reply via email to