Updated Branches:
  refs/heads/4.3 8f6232021 -> 43119bcbd

Added new paramerer "start" to createVPC command. When false is passed in, VPC 
won't be started (its VPC VR won't get implemented) till the point when the 
first netwotrk gets implemented in the VPC.
The parameter is optional and true by default to preserve the original behavior


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

Branch: refs/heads/4.3
Commit: 43119bcbdd928a621a3af2c9386061e751640c4e
Parents: 8f62320
Author: Alena Prokharchyk <[email protected]>
Authored: Thu Nov 21 15:01:01 2013 -0800
Committer: Alena Prokharchyk <[email protected]>
Committed: Fri Nov 22 09:40:12 2013 -0800

----------------------------------------------------------------------
 .../org/apache/cloudstack/api/ApiConstants.java |  7 +-
 .../api/command/user/vpc/CreateVPCCmd.java      | 77 ++++++++++++--------
 .../orchestration/NetworkOrchestrator.java      | 29 ++++----
 3 files changed, 64 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/43119bcb/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 82b2af6..c277788 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -16,7 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api;
 
-
 public class ApiConstants {
     public static final String ACCOUNT = "account";
     public static final String ACCOUNTS = "accounts";
@@ -247,7 +246,7 @@ public class ApiConstants {
     public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids";
     public static final String VLAN = "vlan";
     public static final String VLAN_RANGE = "vlanrange";
-    public static final String REMOVE_VLAN="removevlan";
+    public static final String REMOVE_VLAN = "removevlan";
     public static final String VLAN_ID = "vlanid";
     public static final String ISOLATED_PVLAN = "isolatedpvlan";
     public static final String VM_AVAILABLE = "vmavailable";
@@ -410,7 +409,8 @@ public class ApiConstants {
     public static final String EXTERNAL_SWITCH_MGMT_DEVICE_ID = "vsmdeviceid";
     public static final String EXTERNAL_SWITCH_MGMT_DEVICE_NAME = 
"vsmdevicename";
     public static final String EXTERNAL_SWITCH_MGMT_DEVICE_STATE = 
"vsmdevicestate";
-    // Would we need to have a capacity field for Cisco N1KV VSM? Max hosts 
managed by it perhaps? May remove this later.
+    // Would we need to have a capacity field for Cisco N1KV VSM? Max hosts 
managed by it perhaps? May remove this
+// later.
     public static final String EXTERNAL_SWITCH_MGMT_DEVICE_CAPACITY = 
"vsmdevicecapacity";
     public static final String CISCO_NEXUS_VSM_NAME = "vsmname";
     public static final String VSM_USERNAME = "vsmusername";
@@ -534,6 +534,7 @@ public class ApiConstants {
     public static final String FOR_DISPLAY = "fordisplay";
     public static final String PASSIVE = "passive";
     public static final String VERSION = "version";
+    public static final String START = "start";
 
     public enum HostDetails {
         all, capacity, events, stats, min;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/43119bcb/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
----------------------------------------------------------------------
diff --git 
a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java 
b/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
index 6e86ba0..ebed1ca 100644
--- a/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/vpc/CreateVPCCmd.java
@@ -16,8 +16,6 @@
 // under the License.
 package org.apache.cloudstack.api.command.user.vpc;
 
-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.response.VpcOfferingResponse;
 import org.apache.cloudstack.api.response.VpcResponse;
 import org.apache.cloudstack.api.response.ZoneResponse;
 import org.apache.cloudstack.context.CallContext;
+import org.apache.log4j.Logger;
 
 import com.cloud.event.EventTypes;
 import com.cloud.exception.ConcurrentOperationException;
@@ -38,54 +37,59 @@ import com.cloud.exception.ResourceAllocationException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.network.vpc.Vpc;
 
-@APICommand(name = "createVPC", description="Creates a VPC", 
responseObject=VpcResponse.class)
-public class CreateVPCCmd extends BaseAsyncCreateCmd{
+@APICommand(name = "createVPC", description = "Creates a VPC", responseObject 
= VpcResponse.class)
+public class CreateVPCCmd extends BaseAsyncCreateCmd {
     public static final Logger s_logger = 
Logger.getLogger(CreateVPCCmd.class.getName());
     private static final String s_name = "createvpcresponse";
 
-    /////////////////////////////////////////////////////
-    //////////////// API parameters /////////////////////
-    /////////////////////////////////////////////////////
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
 
-    @Parameter(name=ApiConstants.ACCOUNT, type=CommandType.STRING, 
description="the account associated with the VPC. " +
+    @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, 
description = "the account associated with the VPC. " +
             "Must be used with the domainId parameter.")
     private String accountName;
 
-    @Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.UUID, 
entityType=DomainResponse.class,
-            description="the domain ID associated with the VPC. " +
-            "If used with the account parameter returns the VPC associated 
with the account for the specified domain.")
+    @Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, 
entityType = DomainResponse.class,
+            description = "the domain ID associated with the VPC. " +
+                    "If used with the account parameter returns the VPC 
associated with the account for the specified domain.")
     private Long domainId;
 
-    @Parameter(name=ApiConstants.PROJECT_ID, type=CommandType.UUID, 
entityType=ProjectResponse.class,
-            description="create VPC for the project")
+    @Parameter(name = ApiConstants.PROJECT_ID, type = CommandType.UUID, 
entityType = ProjectResponse.class,
+            description = "create VPC for the project")
     private Long projectId;
 
-    @Parameter(name=ApiConstants.ZONE_ID, type=CommandType.UUID, 
entityType=ZoneResponse.class,
-            required=true, description="the ID of the availability zone")
+    @Parameter(name = ApiConstants.ZONE_ID, type = CommandType.UUID, 
entityType = ZoneResponse.class,
+            required = true, description = "the ID of the availability zone")
     private Long zoneId;
 
-    @Parameter(name=ApiConstants.NAME, type=CommandType.STRING, required=true, 
description="the name of the VPC")
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, required = 
true, description = "the name of the VPC")
     private String vpcName;
 
-    @Parameter(name=ApiConstants.DISPLAY_TEXT, type=CommandType.STRING, 
required=true, description="the display text of " +
+    @Parameter(name = ApiConstants.DISPLAY_TEXT, type = CommandType.STRING, 
required = true, description = "the display text of " +
             "the VPC")
     private String displayText;
 
-    @Parameter(name=ApiConstants.CIDR, type=CommandType.STRING, required=true, 
description="the cidr of the VPC. All VPC " +
+    @Parameter(name = ApiConstants.CIDR, type = CommandType.STRING, required = 
true, description = "the cidr of the VPC. All VPC " +
             "guest networks' cidrs should be within this CIDR")
     private String cidr;
 
-    @Parameter(name=ApiConstants.VPC_OFF_ID, type=CommandType.UUID, 
entityType=VpcOfferingResponse.class,
-            required=true, description="the ID of the VPC offering")
+    @Parameter(name = ApiConstants.VPC_OFF_ID, type = CommandType.UUID, 
entityType = VpcOfferingResponse.class,
+            required = true, description = "the ID of the VPC offering")
     private Long vpcOffering;
 
-    @Parameter(name=ApiConstants.NETWORK_DOMAIN, type=CommandType.STRING,
-            description="VPC network domain. All networks inside the VPC will 
belong to this domain")
+    @Parameter(name = ApiConstants.NETWORK_DOMAIN, type = CommandType.STRING,
+            description = "VPC network domain. All networks inside the VPC 
will belong to this domain")
     private String networkDomain;
 
-    /////////////////////////////////////////////////////
-    /////////////////// Accessors ///////////////////////
-    /////////////////////////////////////////////////////
+    @Parameter(name = ApiConstants.START, type = CommandType.BOOLEAN,
+            description = "If set to false, the VPC won't start (VPC VR will 
not get allocated) until its first network gets implemented. " +
+                    "True by default.", since = "4.3")
+    private Boolean start;
+
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
 
     public String getAccountName() {
         return accountName;
@@ -119,6 +123,13 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd{
         return networkDomain;
     }
 
+    public boolean isStart() {
+        if (start != null) {
+            return start;
+        }
+        return true;
+    }
+
     @Override
     public void create() throws ResourceAllocationException {
         Vpc vpc = _vpcService.createVpc(getZoneId(), getVpcOffering(), 
getEntityOwnerId(), getVpcName(), getDisplayText(),
@@ -134,10 +145,14 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd{
     @Override
     public void execute() {
         Vpc vpc = null;
+        boolean success = true;
         try {
-             if (_vpcService.startVpc(getEntityId(), true)) {
-                vpc = _entityMgr.findById(Vpc.class, getEntityId());
-             }
+            if (isStart()) {
+                success = _vpcService.startVpc(getEntityId(), true);
+            } else {
+                s_logger.debug("Not starting VPC as " + ApiConstants.START + 
"=false was passed to the API");
+            }
+            vpc = _entityMgr.findById(Vpc.class, getEntityId());
         } catch (ResourceUnavailableException ex) {
             s_logger.warn("Exception: ", ex);
             throw new 
ServerApiException(ApiErrorCode.RESOURCE_UNAVAILABLE_ERROR, ex.getMessage());
@@ -150,7 +165,7 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd{
             throw new 
ServerApiException(ApiErrorCode.INSUFFICIENT_CAPACITY_ERROR, ex.getMessage());
         }
 
-        if (vpc != null) {
+        if (vpc != null && success) {
             VpcResponse response = _responseGenerator.createVpcResponse(vpc);
             response.setResponseName(getCommandName());
             setResponseObject(response);
@@ -159,16 +174,14 @@ public class CreateVPCCmd extends BaseAsyncCreateCmd{
         }
     }
 
-
     @Override
     public String getEventType() {
         return EventTypes.EVENT_VPC_CREATE;
     }
 
-
     @Override
     public String getEventDescription() {
-        return  "creating VPC. Id: " + getEntityId();
+        return "creating VPC. Id: " + getEntityId();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/43119bcb/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
----------------------------------------------------------------------
diff --git 
a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
 
b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
index ddec9fc..36926d2 100755
--- 
a/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
+++ 
b/engine/orchestration/src/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java
@@ -36,7 +36,6 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
-import org.apache.log4j.Logger;
 import org.apache.cloudstack.acl.ControlledEntity.ACLType;
 import org.apache.cloudstack.context.CallContext;
 import 
org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
@@ -46,6 +45,7 @@ import org.apache.cloudstack.framework.config.Configurable;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import org.apache.cloudstack.managed.context.ManagedContextRunnable;
 import org.apache.cloudstack.region.PortableIpDao;
+import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
 import com.cloud.agent.Listener;
@@ -146,6 +146,7 @@ import com.cloud.network.rules.StaticNatRule;
 import com.cloud.network.rules.StaticNatRuleImpl;
 import com.cloud.network.rules.dao.PortForwardingRulesDao;
 import com.cloud.network.vpc.NetworkACLManager;
+import com.cloud.network.vpc.Vpc;
 import com.cloud.network.vpc.VpcManager;
 import com.cloud.network.vpc.dao.PrivateIpDao;
 import com.cloud.network.vpn.RemoteAccessVpnService;
@@ -167,14 +168,14 @@ import com.cloud.utils.concurrency.NamedThreadFactory;
 import com.cloud.utils.db.DB;
 import com.cloud.utils.db.EntityManager;
 import com.cloud.utils.db.GlobalLock;
-import com.cloud.utils.db.TransactionCallback;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
-import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.db.JoinBuilder.JoinType;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria.Op;
 import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallback;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionCallbackWithExceptionNoReturn;
+import com.cloud.utils.db.TransactionStatus;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.fsm.NoTransitionException;
 import com.cloud.utils.fsm.StateMachine2;
@@ -1013,25 +1014,25 @@ public class NetworkOrchestrator extends ManagerBase 
implements NetworkOrchestra
         DataCenter zone = _dcDao.findById(network.getDataCenterId());
 
         if (!sharedSourceNat && 
_networkModel.areServicesSupportedInNetwork(network.getId(), Service.SourceNat) 
&&
-            (network.getGuestType() == Network.GuestType.Isolated || 
(network.getGuestType() == Network.GuestType.Shared && zone.getNetworkType() == 
NetworkType.Advanced))) {
+                (network.getGuestType() == Network.GuestType.Isolated || 
(network.getGuestType() == Network.GuestType.Shared && zone.getNetworkType() == 
NetworkType.Advanced))) {
 
             List<IPAddressVO> ips = null;
+            Account owner = _entityMgr.findById(Account.class, 
network.getAccountId());
             if (network.getVpcId() != null) {
                 ips = _ipAddressDao.listByAssociatedVpc(network.getVpcId(), 
true);
                 if (ips.isEmpty()) {
-                    throw new CloudRuntimeException("Vpc is not implemented; 
there is no source nat ip");
+                    Vpc vpc = _vpcMgr.getActiveVpc(network.getVpcId());
+                    s_logger.debug("Creating a source nat ip for vpc " + vpc);
+                    _vpcMgr.assignSourceNatIpAddressToVpc(owner, vpc);
                 }
             } else {
                 ips = _ipAddressDao.listByAssociatedNetwork(network.getId(), 
true);
-            }
-
-            if (ips.isEmpty()) {
-                s_logger.debug("Creating a source nat ip for network " + 
network);
-                Account owner = _entityMgr.findById(Account.class, 
network.getAccountId());
-                _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, 
network);
+                if (ips.isEmpty()) {
+                    s_logger.debug("Creating a source nat ip for network " + 
network);
+                    _ipAddrMgr.assignSourceNatIpAddressToGuestNetwork(owner, 
network);
+                }
             }
         }
-
         // get providers to implement
         List<Provider> providersToImplement = 
getNetworkProviders(network.getId());
         for (NetworkElement element : _networkElements) {

Reply via email to