Merge branch 'master' of ssh://git.onelab.eu/git/sfa
[sfa.git] / sfa / openstack / osaggregate.py
index 5cfe86a..d2aff6a 100644 (file)
@@ -1,3 +1,8 @@
+import os
+import base64
+import string
+import random    
+from collections import defaultdict
 from nova.exception import ImageNotFound
 from nova.api.ec2.cloud import CloudController
 from sfa.util.faults import SfaAPIError
@@ -12,7 +17,8 @@ from sfa.util.xrn import Xrn
 from sfa.util.osxrn import OSXrn
 from sfa.rspecs.version_manager import VersionManager
 from sfa.openstack.image import Image
-
+from sfa.openstack.security_group import SecurityGroup
+from sfa.util.sfalogging import logger
 
 def instance_to_sliver(instance, slice_xrn=None):
     # should include?
@@ -40,7 +46,7 @@ def instance_to_sliver(instance, slice_xrn=None):
 
     sliver = Sliver({'slice_id': sliver_id,
                      'name': name,
-                     'type': 'plos-' + type,
+                     'type':  type,
                      'tags': []})
     return sliver
             
@@ -123,10 +129,10 @@ class OSAggregate:
         Create the slice if it doesn't alredy exist. Create user
         accounts that don't already exist   
         """
-        import nova.exception.ProjectNotFound
+        from nova.exception import ProjectNotFound
         try:
             slice = self.driver.shell.auth_manager.get_project(slicename)
-        except nova.exception.ProjectNotFound:
+        except ProjectNotFound:
             # assume that the first user is the project manager
             proj_manager = Xrn(users[0]['urn']).get_leaf() 
             self.driver.shell.auth_manager.create_project(slicename, proj_manager)
@@ -164,15 +170,15 @@ class OSAggregate:
                     self.driver.shell.db.key_pair_destroy(username, key.name)
 
 
-    def create_security_group(self, slicename, fw_rules):
-        group_name = slicename
+    def create_security_group(self, group_name, fw_rules=[]):
         security_group = SecurityGroup(self.driver)
         security_group.create_security_group(group_name)
         for rule in fw_rules:
-            security_group.add_rule_to_group(group_name, rule.get('protocol'), 
-                                             rule.get('cidr_ip'), 
-                                             rule.get('port_range'), 
-                                             rule.get('icmp_type_code'))
+            security_group.add_rule_to_group(group_name, 
+                                             protocol = rule.get('protocol'), 
+                                             cidr_ip = rule.get('cidr_ip'), 
+                                             port_range = rule.get('port_range'), 
+                                             icmp_type_code = rule.get('icmp_type_code'))
 
     def add_rule_to_security_group(self, group_name, **kwds):
         security_group = SecurityGroup(self.driver)
@@ -183,9 +189,9 @@ class OSAggregate:
 
  
     def reserve_instance(self, image_id, kernel_id, ramdisk_id, \
-                         instance_type, key_name, user_data):
-        conn  = self.driver.euca_shell
-        logger.info('Reserving an instance: image: %s, kernel: ' \
+                         instance_type, key_name, user_data, group_name):
+        conn  = self.driver.euca_shell.get_euca_connection()
+        logger.info('Reserving an instance: image: %s, kernel: ' \
                     '%s, ramdisk: %s, type: %s, key: %s' % \
                     (image_id, kernel_id, ramdisk_id,
                     instance_type, key_name))
@@ -196,13 +202,13 @@ class OSAggregate:
                                              instance_type=instance_type,
                                              key_name=key_name,
                                              user_data = user_data,
-                                             security_groups=group_names)
+                                             security_groups=[group_name])
                                              #placement=zone,
                                              #min_count=min_count,
                                              #max_count=max_count,           
                                               
-        except EC2ResponseError, ec2RespError:
-            logger.log_exc(ec2RespError)
+        except Exception, err:
+            logger.log_exc(err)
                
     def run_instances(self, slicename, rspec, keyname, pubkeys):
         """
@@ -213,13 +219,14 @@ class OSAggregate:
         # Just choose the first available image for now.
         image_manager = Image(self.driver)
         available_images = image_manager.get_available_disk_images()
-        default_image = image_manager.get_disk_images()[0]    
-        default_ami_id = CloudController.image_ec2_id(default_image['ami']['id'])  
-        default_aki_id = CloudController.image_ec2_id(default_image['aki']['id'])  
-        default_ari_id = CloudController.image_ec2_id(default_image['ari']['id'])
+        default_image = available_images[0]   
+        default_ami_id = CloudController.image_ec2_id(default_image['ami']['id'], 'ami')  
+        default_aki_id = CloudController.image_ec2_id(default_image['aki']['id'], 'aki')  
+        default_ari_id = CloudController.image_ec2_id(default_image['ari']['id'], 'ari')
 
         # get requested slivers
         rspec = RSpec(rspec)
+        user_data = "\n".join(pubkeys)
         requested_instances = defaultdict(list)
         # iterate over clouds/zones/nodes
         for node in rspec.version.get_nodes_with_slivers():
@@ -227,7 +234,14 @@ class OSAggregate:
             if isinstance(instance_types, list):
                 # iterate over sliver/instance types
                 for instance_type in instance_types:
-                    group_name = self.create_security_group(slicename, instance_type.get('fw_rules', []))
+                    fw_rules = instance_type.get('fw_rules', [])
+                    # Each sliver get's its own security group.  
+                    # Keep security group names unique by appending some random 
+                    # characters on end.
+                    random_name = "".join([random.choice(string.letters+string.digits) 
+                                           for i in xrange(6)])
+                    group_name = slicename + random_name
+                    self.create_security_group(group_name, fw_rules)
                     ami_id = default_ami_id
                     aki_id = default_aki_id
                     ari_id = default_ari_id
@@ -236,15 +250,37 @@ class OSAggregate:
                         req_image_name = req_image[0]['name']
                         disk_image = image_manager.get_disk_image(name=req_image_name)
                         if disk_image:
-                            ami_id = CloudController.image_ec2_id(disk_image['ami']['id'])
-                            aki_id = CloudController.image_ec2_id(disk_image['aki']['id'])
-                            ari_id = CloudController.image_ec2_id(disk_image['ari']['id'])
+                            ami_id = CloudController.image_ec2_id(disk_image['ami']['id'], 'ami')
+                            aki_id = CloudController.image_ec2_id(disk_image['aki']['id'], 'aki')
+                            ari_id = CloudController.image_ec2_id(disk_image['ari']['id'], 'ari')
                     # start the instance
                     self.reserve_instance(image_id=ami_id, 
                                           kernel_id=aki_id, 
                                           ramdisk_id=ari_id, 
                                           instance_type=instance_type['name'], 
                                           key_name=keyname, 
-                                          user_data=pubkeys
+                                          user_data=user_data
                                           group_name=group_name)
 
+
+    def delete_instances(self, project_name):
+        instances = self.driver.shell.db.instance_get_all_by_project(project_name)
+        security_group_manager = SecurityGroup(self.driver)
+        for instance in instances:
+            # deleate this instance's security groups
+            for security_group in instance.security_groups:
+                # dont delete the default security group
+                if security_group.name != 'default': 
+                    security_group_manager.delete_security_group(security_group.name)
+            # destroy instance
+            self.driver.shell.db.instance_destroy(instance.id)
+        return 1
+
+    def stop_instances(self, project_name):
+        instances = self.driver.shell.db.instance_get_all_by_project(project_name)
+        for instance in instances:
+            self.driver.shell.db.instance_stop(instance.id)
+        return 1
+
+    def update_instances(self, project_name):
+        pass