adding external volume configuring support for IaaSes

Project: http://git-wip-us.apache.org/repos/asf/incubator-stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-stratos/commit/6b561b21
Tree: http://git-wip-us.apache.org/repos/asf/incubator-stratos/tree/6b561b21
Diff: http://git-wip-us.apache.org/repos/asf/incubator-stratos/diff/6b561b21

Branch: refs/heads/master
Commit: 6b561b213e23302cf356e5b56664dff7181de8bc
Parents: 2e89631
Author: Nirmal Fernando <[email protected]>
Authored: Tue Feb 11 15:20:49 2014 +0530
Committer: Nirmal Fernando <[email protected]>
Committed: Tue Feb 11 15:20:49 2014 +0530

----------------------------------------------------------------------
 .../cloud/controller/iaases/AWSEC2Iaas.java     | 114 ++++++++++++++++
 .../controller/iaases/OpenstackNovaIaas.java    | 132 +++++++++++++++++--
 .../cloud/controller/iaases/VCloudIaas.java     |  24 ++++
 .../cloud/controller/interfaces/Iaas.java       |  28 ++++
 4 files changed, 290 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/6b561b21/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java
index 203017e..5796ed5 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/AWSEC2Iaas.java
@@ -43,12 +43,16 @@ import org.jclouds.compute.domain.NodeMetadata;
 import org.jclouds.compute.domain.Template;
 import org.jclouds.compute.domain.TemplateBuilder;
 import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.ec2.domain.Attachment;
 import org.jclouds.ec2.domain.AvailabilityZoneInfo;
 import org.jclouds.ec2.domain.KeyPair;
 import org.jclouds.ec2.domain.PublicIpInstanceIdPair;
+import org.jclouds.ec2.domain.Volume;
 import org.jclouds.ec2.features.AvailabilityZoneAndRegionApi;
+import org.jclouds.ec2.features.ElasticBlockStoreApi;
 import org.jclouds.ec2.features.ElasticIPAddressApi;
 import org.jclouds.ec2.options.DescribeAvailabilityZonesOptions;
+import org.jclouds.ec2.options.DetachVolumeOptions;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -382,5 +386,115 @@ public class AWSEC2Iaas extends Iaas {
         return new AWSEC2PartitionValidator();
     }
 
+       @Override
+       public String createVolume(int sizeGB) {
+               IaasProvider iaasInfo = getIaasProvider();
+
+               ComputeServiceContext context = iaasInfo.getComputeService()
+                               .getContext();
+               
+               String region = 
ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+               String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);
+               
+               if(region == null || zone == null) {
+                       log.fatal("Cannot create a new volume in the [region] : 
"+region
+                                       +", [zone] : "+zone+" of Iaas : 
"+iaasInfo);
+                       return null;
+               }
+               
+               ElasticBlockStoreApi blockStoreApi = 
context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
+               
+               Volume volume = 
blockStoreApi.createVolumeInAvailabilityZone(zone, sizeGB);
+               
+               if (volume == null) {
+                       log.fatal("Volume creation was unsuccessful. [region] : 
" + region
+                                       + ", [zone] : " + zone + " of Iaas : " 
+ iaasInfo);
+                       return null;
+               }
+               
+               log.info("Successfully created a new volume [id]: 
"+volume.getId()
+                               +" in [region] : "+region+", [zone] : "+zone+" 
of Iaas : "+iaasInfo);
+               return volume.getId();
+       }
+
+       @Override
+       public String attachVolume(String instanceId, String volumeId) {
+               IaasProvider iaasInfo = getIaasProvider();
+
+               ComputeServiceContext context = iaasInfo.getComputeService()
+                               .getContext();
+               
+               String region = 
ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+               String zone = ComputeServiceBuilderUtil.extractZone(iaasInfo);
+               String device = 
ComputeServiceBuilderUtil.extractDevice(iaasInfo, "/dev/sdh");
+               
+               if(region == null || zone == null) {
+                       log.fatal("Cannot attach the volume [id]: "+volumeId+" 
in the [region] : "+region
+                                       +", [zone] : "+zone+" of Iaas : 
"+iaasInfo);
+                       return null;
+               }
+               
+               ElasticBlockStoreApi blockStoreApi = 
context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
+               Attachment attachment = 
blockStoreApi.attachVolumeInRegion(region, volumeId, instanceId, device);
+
+               if (attachment == null) {
+                       log.fatal("Volume [id]: "+volumeId+" attachment for 
instance [id]: "+instanceId
+                                       +" was unsuccessful. [region] : " + 
region
+                                       + ", [zone] : " + zone + " of Iaas : " 
+ iaasInfo);
+                       return null;
+               }
+               
+               log.info("Volume [id]: "+volumeId+" attachment for instance 
[id]: "+instanceId
+                               +" was successful [status]: 
"+attachment.getStatus().value()+". [region] : " + region
+                               + ", [zone] : " + zone + " of Iaas : " + 
iaasInfo);
+               return attachment.getStatus().value();
+       }
+
+       @Override
+       public void detachVolume(String instanceId, String volumeId) {
+               IaasProvider iaasInfo = getIaasProvider();
+
+               ComputeServiceContext context = iaasInfo.getComputeService()
+                               .getContext();
+               
+               String region = 
ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+               
+               if(region == null) {
+                       log.fatal("Cannot detach the volume [id]: "+volumeId+" 
from the instance [id]: "+instanceId
+                                       +" of the [region] : "+region
+                                       +" of Iaas : "+iaasInfo);
+                       return;
+               }
+               
+               ElasticBlockStoreApi blockStoreApi = 
context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
+               blockStoreApi.detachVolumeInRegion(region, volumeId, true, 
DetachVolumeOptions.Builder.fromInstance(instanceId));
+
+               log.info("Detachment of Volume [id]: "+volumeId+" from instance 
[id]: "+instanceId
+                               +" was successful. [region] : " + region
+                               + " of Iaas : " + iaasInfo);
+       }
+
+       @Override
+       public void deleteVolume(String volumeId) {
+               IaasProvider iaasInfo = getIaasProvider();
+
+               ComputeServiceContext context = iaasInfo.getComputeService()
+                               .getContext();
+               
+               String region = 
ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+               
+               if(region == null) {
+                       log.fatal("Cannot delete the volume [id]: "+volumeId+" 
of the [region] : "+region
+                                       +" of Iaas : "+iaasInfo);
+                       return;
+               }
+               
+               ElasticBlockStoreApi blockStoreApi = 
context.unwrapApi(AWSEC2Api.class).getElasticBlockStoreApiForRegion(region).get();
+               blockStoreApi.deleteVolumeInRegion(region, volumeId);
+               
+               log.info("Deletion of Volume [id]: "+volumeId+" was successful. 
[region] : " + region
+                               + " of Iaas : " + iaasInfo);
+       }
+
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/6b561b21/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java
index b654696..de1b258 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/OpenstackNovaIaas.java
@@ -44,13 +44,20 @@ import org.jclouds.compute.domain.TemplateBuilder;
 import org.jclouds.compute.options.TemplateOptions;
 import org.jclouds.openstack.nova.v2_0.NovaApi;
 import org.jclouds.openstack.nova.v2_0.NovaApiMetadata;
+import org.jclouds.openstack.nova.v2_0.NovaAsyncApi;
 import org.jclouds.openstack.nova.v2_0.compute.options.NovaTemplateOptions;
 import org.jclouds.openstack.nova.v2_0.domain.FloatingIP;
 import org.jclouds.openstack.nova.v2_0.domain.HostAggregate;
 import org.jclouds.openstack.nova.v2_0.domain.KeyPair;
+import org.jclouds.openstack.nova.v2_0.domain.Volume;
+import org.jclouds.openstack.nova.v2_0.domain.VolumeAttachment;
 import org.jclouds.openstack.nova.v2_0.extensions.FloatingIPApi;
 import org.jclouds.openstack.nova.v2_0.extensions.HostAggregateApi;
 import org.jclouds.openstack.nova.v2_0.extensions.KeyPairApi;
+import org.jclouds.openstack.nova.v2_0.extensions.VolumeApi;
+import org.jclouds.openstack.nova.v2_0.extensions.VolumeAttachmentApi;
+import org.jclouds.openstack.nova.v2_0.options.CreateVolumeOptions;
+import org.jclouds.rest.RestContext;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -58,7 +65,6 @@ import java.util.Set;
 
 public class OpenstackNovaIaas extends Iaas {
 
-
        private static final Log log = 
LogFactory.getLog(OpenstackNovaIaas.class);
        private static final String SUCCESSFUL_LOG_LINE = "A key-pair is 
created successfully in ";
        private static final String FAILED_LOG_LINE = "Key-pair is unable to 
create in ";
@@ -170,8 +176,8 @@ public class OpenstackNovaIaas extends Iaas {
 
                ComputeServiceContext context = iaasInfo.getComputeService()
                                .getContext();
-               
-               KeyPairApi api = 
context.unwrapApi(NovaApi.class).getKeyPairExtensionForZone(region).get();
+               RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap();
+               KeyPairApi api = 
nova.getApi().getKeyPairExtensionForZone(region).get();
 
                KeyPair keyPair = api.createWithPublicKey(keyPairName, 
publicKey);
 
@@ -199,7 +205,8 @@ public class OpenstackNovaIaas extends Iaas {
 
                String region = 
ComputeServiceBuilderUtil.extractRegion(iaasInfo);
 
-               FloatingIPApi floatingIp = 
context.unwrapApi(NovaApi.class).getFloatingIPExtensionForZone(
+               RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap();
+               FloatingIPApi floatingIp = 
nova.getApi().getFloatingIPExtensionForZone(
                                region).get();
 
                String ip = null;
@@ -278,7 +285,8 @@ public class OpenstackNovaIaas extends Iaas {
 
                String region = 
ComputeServiceBuilderUtil.extractRegion(iaasInfo);
 
-               FloatingIPApi floatingIPApi = context.unwrapApi(NovaApi.class)
+               RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap();
+               FloatingIPApi floatingIPApi = nova.getApi()
                                .getFloatingIPExtensionForZone(region).get();
 
                for (FloatingIP floatingIP : floatingIPApi.list()) {
@@ -313,8 +321,8 @@ public class OpenstackNovaIaas extends Iaas {
         }
         
         ComputeServiceContext context = 
iaasInfo.getComputeService().getContext();
-        
-        Set<String> zones = 
context.unwrapApi(NovaApi.class).getConfiguredZones();
+        RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap();
+        Set<String> zones = nova.getApi().getConfiguredZones();
         for (String configuredZone : zones) {
             if (region.equalsIgnoreCase(configuredZone)) {
                 if (log.isDebugEnabled()) {
@@ -351,7 +359,8 @@ public class OpenstackNovaIaas extends Iaas {
             throw new InvalidHostException(msg);
         }
         ComputeServiceContext context = 
iaasInfo.getComputeService().getContext();
-        HostAggregateApi hostApi = 
context.unwrapApi(NovaApi.class).getHostAggregateExtensionForZone(zone).get();
+        RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap();
+        HostAggregateApi hostApi = 
nova.getApi().getHostAggregateExtensionForZone(zone).get();
         for (HostAggregate hostAggregate : hostApi.list()) {
             for (String configuredHost : hostAggregate.getHosts()) {
                 if (host.equalsIgnoreCase(configuredHost)) {
@@ -373,4 +382,111 @@ public class OpenstackNovaIaas extends Iaas {
         return new OpenstackNovaPartitionValidator();
     }
 
+       @Override
+       public String createVolume(int sizeGB) {
+               IaasProvider iaasInfo = getIaasProvider();
+               String region = 
ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+        if (region == null || iaasInfo == null) {
+               log.fatal("Cannot create a new volume in the [region] : "+region
+                                       +" of Iaas : "+iaasInfo);
+            return null;
+        }
+        ComputeServiceContext context = 
iaasInfo.getComputeService().getContext();
+        
+        RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap();
+        VolumeApi api = nova.getApi().getVolumeExtensionForZone(region).get();
+        Volume volume = api.create(sizeGB, 
CreateVolumeOptions.Builder.availabilityZone(region));
+        if (volume == null) {
+                       log.fatal("Volume creation was unsuccessful. [region] : 
" + region
+                                       + " of Iaas : " + iaasInfo);
+                       return null;
+               }
+               
+               log.info("Successfully created a new volume [id]: 
"+volume.getId()
+                               +" in [region] : "+region+" of Iaas : 
"+iaasInfo);
+               return volume.getId();
+       }
+
+       @Override
+       public String attachVolume(String instanceId, String volumeId) {
+               IaasProvider iaasInfo = getIaasProvider();
+
+               ComputeServiceContext context = iaasInfo.getComputeService()
+                               .getContext();
+               
+               String region = 
ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+               String device = 
ComputeServiceBuilderUtil.extractDevice(iaasInfo, "/dev/vdc");
+               
+               if(region == null) {
+                       log.fatal("Cannot attach the volume [id]: "+volumeId+" 
in the [region] : "+region
+                                       +" of Iaas : "+iaasInfo);
+                       return null;
+               }
+               
+               RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap();
+        VolumeAttachmentApi api = 
nova.getApi().getVolumeAttachmentExtensionForZone(region).get();
+        VolumeAttachment attachment = 
api.attachVolumeToServerAsDevice(volumeId, instanceId, device);
+        
+        if (attachment == null) {
+                       log.fatal("Volume [id]: "+volumeId+" attachment for 
instance [id]: "+instanceId
+                                       +" was unsuccessful. [region] : " + 
region
+                                       + " of Iaas : " + iaasInfo);
+                       return null;
+               }
+               
+               log.info("Volume [id]: "+volumeId+" attachment for instance 
[id]: "+instanceId
+                               +" was successful [status]: "+"Attaching"+". 
[region] : " + region
+                               + " of Iaas : " + iaasInfo);
+               return "Attaching";
+       }
+
+       @Override
+       public void detachVolume(String instanceId, String volumeId) {
+               IaasProvider iaasInfo = getIaasProvider();
+
+               ComputeServiceContext context = iaasInfo.getComputeService()
+                               .getContext();
+               
+               String region = 
ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+               
+               if(region == null) {
+                       log.fatal("Cannot detach the volume [id]: "+volumeId+" 
from the instance [id]: "+instanceId
+                                       +" of the [region] : "+region
+                                       +" of Iaas : "+iaasInfo);
+                       return;
+               }
+               
+               RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap();
+        VolumeAttachmentApi api = 
nova.getApi().getVolumeAttachmentExtensionForZone(region).get();
+        if (api.detachVolumeFromServer(volumeId, instanceId)) {
+               log.info("Detachment of Volume [id]: "+volumeId+" from instance 
[id]: "+instanceId
+                               +" was successful. [region] : " + region
+                               + " of Iaas : " + iaasInfo);
+        }
+        
+       }
+
+       @Override
+       public void deleteVolume(String volumeId) {
+               IaasProvider iaasInfo = getIaasProvider();
+
+               ComputeServiceContext context = iaasInfo.getComputeService()
+                               .getContext();
+               
+               String region = 
ComputeServiceBuilderUtil.extractRegion(iaasInfo);
+               
+               if(region == null) {
+                       log.fatal("Cannot delete the volume [id]: "+volumeId+" 
of the [region] : "+region
+                                       +" of Iaas : "+iaasInfo);
+                       return;
+               }
+               
+               RestContext<NovaApi, NovaAsyncApi> nova = context.unwrap();
+               VolumeApi api = 
nova.getApi().getVolumeExtensionForZone(region).get();
+        if (api.delete(volumeId)) {
+               log.info("Deletion of Volume [id]: "+volumeId+" was successful. 
[region] : " + region
+                               + " of Iaas : " + iaasInfo);
+        }
+       }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/6b561b21/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java
index b49f2c8..852bc30 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/VCloudIaas.java
@@ -211,4 +211,28 @@ public class VCloudIaas extends Iaas {
         return null;
     }
 
+       @Override
+       public String createVolume(int sizeGB) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public String attachVolume(String instanceId, String volumeId) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public void detachVolume(String instanceId, String volumeId) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       @Override
+       public void deleteVolume(String volumeId) {
+               // TODO Auto-generated method stub
+               
+       }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/6b561b21/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java
index d6303c2..c66844f 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/Iaas.java
@@ -127,4 +127,32 @@ public abstract class Iaas {
      */
     public abstract void buildTemplate();
     
+    /**
+     * Create a new volume in the respective Iaas.
+     * @param sizeGB size of the volume in Giga Bytes.
+     * @return Id of the created volume.
+     */
+    public abstract String createVolume(int sizeGB);
+   
+    /**
+     * Attach a given volume to an instance at the specified device path.
+     * @param instanceId of the instance.
+     * @param volumeId volume id of the volume to be attached.
+     * @return the status of the attachment.
+     */
+    public abstract String attachVolume(String instanceId, String volumeId);
+    
+    /**
+     * Detach a given volume from the given instance.
+     * @param instanceId of the instance.
+     * @param volumeId volume id of the volume to be detached.
+     */
+    public abstract void detachVolume(String instanceId, String volumeId);
+    
+    /**
+     * Delete a given volume.
+     * @param volumeId volume id of the volume to be detached.
+     */
+    public abstract void deleteVolume(String volumeId);
+    
 }

Reply via email to