Exemple #1
0
def _add_instance_to_load_balancer(conn, instance, instance_info) :
    if 'load_balancer' in instance_info : 
        load_balancer_name = instance_info['load_balancer']
                
        elb_conn = ELBConnection()
        
        if _instance_in_load_balancer(elb_conn, load_balancer_name, instance.id) :
            print("Removing Instance(s) " + str([instance.id]) + " from load balancer " + load_balancer_name)
            elb_conn.deregister_instances(load_balancer_name, [instance.id])

        print("Adding Instance(s) " + str([instance.id]) + " to load balancer " + load_balancer_name)
        elb_conn.register_instances(load_balancer_name, [instance.id])
        
    else :
        print("Skipping association with Load Balancer ")
class BotoBalanceInterface(BalanceInterface):
    conn = None
    saveclcdata = False

    def __init__(self, clc_host, access_id, secret_key, token):
        #boto.set_stream_logger('foo')
        path='/services/elb'
        port=8773
        if clc_host[len(clc_host)-13:] == 'amazonaws.com':
            clc_host = clc_host.replace('ec2', 'elasticloadbalancing', 1)
            path = '/'
            reg = None
            port=443
        reg = RegionInfo(name='eucalyptus', endpoint=clc_host)
        self.conn = ELBConnection(access_id, secret_key, region=reg,
                                  port=port, path=path,
                                  is_secure=True, security_token=token, debug=0)
        self.conn.https_validate_certificates = False
        self.conn.http_connection_kwargs['timeout'] = 30

    def __save_json__(self, obj, name):
        f = open(name, 'w')
        json.dump(obj, f, cls=BotoJsonBalanceEncoder, indent=2)
        f.close()

    def create_load_balancer(self, name, zones, listeners, subnets=None,
                             security_groups=None, scheme='internet-facing'):
        return self.conn.create_load_balancer(name, zones, listeners, subnets, security_groups, scheme)
    
    def delete_load_balancer(self, name):
        return self.conn.delete_load_balancer(name)

    def get_all_load_balancers(self, load_balancer_names=None):
        return []
        obj = self.conn.get_all_load_balancers(load_balancer_names)
        if self.saveclcdata:
            self.__save_json__(obj, "mockdata/ELB_Balancers.json")
        return obj

    def deregister_instances(self, load_balancer_name, instances):
        return self.conn.deregister_instances(load_balancer_name, instances)

    def register_instances(self, load_balancer_name, instances):
        return self.conn.register_instances(load_balancer_name, instances)

    def create_load_balancer_listeners(self, name, listeners):
        return self.conn.create_load_balancer_listeners(name, listeners)

    def delete_load_balancer_listeners(self, name, ports):
        return self.conn.delete_load_balancer_listeners(name, ports)

    def configure_health_check(self, name, health_check):
        return self.conn.configure_health_check(name, health_check)

    def describe_instance_health(self, load_balancer_name, instances=None):
        obj = self.conn.describe_instance_health(load_balancer_name, instances)
        if self.saveclcdata:
            self.__save_json__(obj, "mockdata/ELB_Instances.json")
        return obj
class BotoBalanceInterface(BalanceInterface):
    conn = None
    saveclcdata = False

    def __init__(self, clc_host, access_id, secret_key, token):
        self.access_id = access_id
        self.secret_key = secret_key
        self.token = token
        self.set_endpoint(clc_host)

    def set_endpoint(self, endpoint):
        #boto.set_stream_logger('foo')
        reg = RegionInfo(name='eucalyptus', endpoint=endpoint)
        path = '/services/LoadBalancing'
        port = 8773
        if endpoint[len(endpoint)-13:] == 'amazonaws.com':
            endpoint = endpoint.replace('ec2', 'elasticloadbalancing', 1)
            path = '/'
            reg = RegionInfo(endpoint=endpoint)
            port = 443
        self.conn = ELBConnection(self.access_id, self.secret_key, region=reg,
                                  port=port, path=path,
                                  is_secure=True, security_token=self.token, debug=0)
        self.conn.https_validate_certificates = False
        self.conn.http_connection_kwargs['timeout'] = 30

    def __save_json__(self, obj, name):
        f = open(name, 'w')
        json.dump(obj, f, cls=BotoJsonBalanceEncoder, indent=2)
        f.close()

    def create_load_balancer(self, name, zones, listeners, subnets=None,
                             security_groups=None, scheme='internet-facing'):
        return self.conn.create_load_balancer(name, zones, listeners, subnets, security_groups, scheme)

    def delete_load_balancer(self, name):
        return self.conn.delete_load_balancer(name)

    def get_all_load_balancers(self, load_balancer_names=None):
        params = {}
        if load_balancer_names:
            self.build_list_params(params, load_balancer_names,
                                   'LoadBalancerNames.member.%d')
        http_request = self.conn.build_base_http_request('GET', '/', None,
                                                         params, {}, '',
                                                         self.conn.server_name())
        http_request.params['Action'] = 'DescribeLoadBalancers'
        http_request.params['Version'] = self.conn.APIVersion
        response = self.conn._mexe(http_request, override_num_retries=2)
        body = response.read()
        boto.log.debug(body)
        if not body:
            boto.log.error('Null body %s' % body)
            raise self.conn.ResponseError(response.status, response.reason, body)
        elif response.status == 200:
            obj = boto.resultset.ResultSet([('member', boto.ec2.elb.loadbalancer.LoadBalancer)])
            h = boto.handler.XmlHandler(obj, self.conn)
            import xml.sax;

            xml.sax.parseString(body, h)
            if self.saveclcdata:
                self.__save_json__(obj, "mockdata/ELB_Balancers.json")
            return obj
        else:
            boto.log.error('%s %s' % (response.status, response.reason))
            boto.log.error('%s' % body)
            raise self.conn.ResponseError(response.status, response.reason, body)


    def deregister_instances(self, load_balancer_name, instances):
        return self.conn.deregister_instances(load_balancer_name, instances)

    def register_instances(self, load_balancer_name, instances):
        return self.conn.register_instances(load_balancer_name, instances)

    def create_load_balancer_listeners(self, name, listeners):
        return self.conn.create_load_balancer_listeners(name, listeners)

    def delete_load_balancer_listeners(self, name, ports):
        return self.conn.delete_load_balancer_listeners(name, ports)

    def configure_health_check(self, name, health_check):
        return self.conn.configure_health_check(name, health_check)

    def describe_instance_health(self, load_balancer_name, instances=None):
        obj = self.conn.describe_instance_health(load_balancer_name, instances)
        if self.saveclcdata:
            self.__save_json__(obj, "mockdata/ELB_Instances.json")
        return obj
Exemple #4
0
class AutoScale:
    def __init__(self, args):
        """
        Initializing basic variables needed for auto scaling
        """
        self.configs = ConfigParser.RawConfigParser()
        self.args = args
        self.test_props = {}
        self.props = {}
        self.ec2_connection = EC2Connection(self.args.access_key,
                                            self.args.secret_key)
        self.autoscale_connection = AutoScaleConnection(
            self.args.access_key, self.args.secret_key)
        self.elb_connection = ELBConnection(self.args.access_key,
                                            self.args.secret_key)
        self.cw_connection = CloudWatchConnection(self.args.access_key,
                                                  self.args.secret_key)
        self.firstInstance = None
        self.launchConfiguration = None
        self.healthCheck = None

    def loadConfigs(self):
        """
        FIX ME: Currently doesnt do anything
        This method will load the configurations from boto config file if present else will 
        accept parameters passed by user.
        """
        if os.path.isfile("/etc/boto.cfg"):
            self.configs.read("/etc/boto.cfg")
            conf = self.configs.sections()
            self.populateConfigs(conf)
        if os.path.isfile("~/.boto"):
            self.configs.read("~/.boto")
            conf = self.configs.sections()
            self.populateConfigs(conf)

        print ">>> Loaded configs"

    def populateConfigs(self, sections):
        for section in sections:
            self.boto_props[section] = self.configs.items(section)
            for item in self.boto_props[section]:
                key, value = item
                if not self.props.has_key(key):
                    self.props[key] = value

    def createLaunchConfiguration(self, lc_name, ami_id, key_name):
        """
        Creates launch configuration for the auto scaling cluster
        """
        self.launchConfiguration = LaunchConfiguration(name=lc_name,
                                                       image_id=ami_id,
                                                       key_name=key_name)
        self.autoscale_connection.create_launch_configuration(
            self.launchConfiguration)
        print ">>> Created launch configuration: " + lc_name

    def createAutoScaleGroup(self, asg_name):
        """
        Create a Auto scaling group for the auto scaling cluster
        """
        autoScalingGroup = AutoScalingGroup(
            group_name=asg_name,
            load_balancers=[self.args.lb_name],
            launch_config=self.launchConfiguration,
            min_size=self.args.min_size,
            max_size=self.args.max_size,
            availability_zones=['us-east-1a'])
        self.autoscale_connection.create_auto_scaling_group(autoScalingGroup)
        print ">>> Created auto scaling group: " + asg_name

    def createTrigger(self, trigger_name, measure, asg_name):
        """
        Trigger to spawn new instances as per specific metrics
        """
        alarm_actions = []
        dimensions = {"AutoScalingGroupName": asg_name}
        policies = self.autoscale_connection.get_all_policies(
            as_group=self.args.asg_name, policy_names=[self.args.asp_name])
        for policy in policies:
            alarm_actions.append(policy.policy_arn)
        alarm = MetricAlarm(name=trigger_name,
                            namespace="AWS/EC2",
                            metric=measure,
                            statistic="Average",
                            comparison=">=",
                            threshold=50,
                            period=60,
                            unit="Percent",
                            evaluation_periods=2,
                            alarm_actions=alarm_actions,
                            dimensions=dimensions)

        self.cw_connection.create_alarm(alarm)
        print ">>> Created trigger: " + self.args.trigger

    def createAutoScalePolicy(self, asp_name):
        """
        Creates a Auto scaling policy to Add/Remove a instance from auto scaling cluster
        """
        self.autoScalingUpPolicy = ScalingPolicy(
            name=asp_name + '-up',
            adjustment_type="ChangeInCapacity",
            as_name=self.args.asg_name,
            scaling_adjustment=1,
            cooldown=180)
        self.autoScalingDownPolicy = ScalingPolicy(
            name=asp_name + '-down',
            adjustment_type="ChangeInCapacity",
            as_name=self.args.asg_name,
            scaling_adjustment=-1,
            cooldown=180)

        self.autoscale_connection.create_scaling_policy(
            self.autoScalingUpPolicy)
        self.autoscale_connection.create_scaling_policy(
            self.autoScalingDownPolicy)

        print ">>> Created auto scaling policy: " + asp_name

    def configureHealthCheck(self, target):
        """
        Configures health check for the cluster
        """
        self.healthCheck = HealthCheck(target=target, timeout=5)
        print ">>> Configured health check for: " + target

    def createLoadBalancer(self, lb_name, region, lb_port, instance_port,
                           protocol):
        """
        Creates a load balancer for cluster
        """
        listener = (int(lb_port), int(instance_port), protocol)
        tuple_list = []
        tuple_list.append(listener)
        lbs = self.elb_connection.get_all_load_balancers()
        for lb in lbs:
            if lb.name != lb_name:
                self.elb_connection.create_load_balancer(
                    lb_name, [region], tuple_list)
                self.elb_connection.configure_health_check(
                    name=lb_name, health_check=self.healthCheck)
                print ">>> Created load balancer: " + lb_name
            else:
                print "Load balancer with name '" + lb_name + "' already exists"

    def startInstance(self, image_id, key_name, region, instance_type):
        """
        Starts the first instance which will be serving requests irrespective of auto scaling 
        instances.
        """
        reservation = self.ec2_connection.run_instances(
            image_id=image_id,
            min_count=1,
            max_count=1,
            placement=region,
            key_name=key_name,
            instance_type=instance_type)
        #        for instance in reservation.instances:
        #            instance.add_tag('node', '0')
        #            break

        self.firstInstance = reservation.instances[0].id.split('\'')[0]
        print ">>> Started instance: ", self.firstInstance

    def registerInstanceToELB(self, lb_name):
        """
        Register the first instance started to the Elastic Load Balancer.
        """
        self.elb_connection.register_instances(load_balancer_name=lb_name,
                                               instances=[self.firstInstance])
        print ">>> Registered instance '", self.firstInstance, "' to load balancer '" + lb_name + "'"

    def setUp(self):
        """
        Set's up the auto scaling for the application
        """
        # STEP 1: Load the configurations
        self.loadConfigs()
        # STEP 2: Configure the health check for the instances
        self.configureHealthCheck(self.args.lb_target)
        # STEP 3: Create a load balancer
        self.createLoadBalancer(self.args.lb_name, self.args.region,
                                self.args.lb_port, self.args.instance_port,
                                self.args.protocol)
        # STEP 4: Start the first instance
        self.startInstance(self.args.ami_id, self.args.key_name,
                           self.args.region, self.args.instance_type)
        # STEP 5: Register the instance to the load balancer created in STEP 4
        self.registerInstanceToELB(self.args.lb_name)
        # STEP 6: Create launch configuration to launch instances by auto scale
        self.createLaunchConfiguration(self.args.lc_name, self.args.ami_id,
                                       self.args.key_name)
        # STEP 7: Create a auto scale group which will manage the instances started by auto scaling
        self.createAutoScaleGroup(self.args.asg_name)
        # STEP 8: Create a auto scaling policy to say add/remove a node
        self.createAutoScalePolicy(self.args.asp_name)
        # STEP 9: Create a trigger, so that auto scaling can trigger it to start
        # or remove a instance from auto scaling group
        self.createTrigger(self.args.trigger, self.args.measure,
                           self.args.asg_name)
Exemple #5
0
class BotoBalanceInterface(BalanceInterface):
    conn = None
    saveclcdata = False

    def __init__(self, clc_host, access_id, secret_key, token):
        #boto.set_stream_logger('foo')
        path = '/services/LoadBalancing'
        port = 8773
        if clc_host[len(clc_host) - 13:] == 'amazonaws.com':
            clc_host = clc_host.replace('ec2', 'elasticloadbalancing', 1)
            path = '/'
            reg = None
            port = 443
        reg = RegionInfo(name='eucalyptus', endpoint=clc_host)
        self.conn = ELBConnection(access_id,
                                  secret_key,
                                  region=reg,
                                  port=port,
                                  path=path,
                                  is_secure=True,
                                  security_token=token,
                                  debug=0)
        self.conn.https_validate_certificates = False
        self.conn.http_connection_kwargs['timeout'] = 30

    def __save_json__(self, obj, name):
        f = open(name, 'w')
        json.dump(obj, f, cls=BotoJsonBalanceEncoder, indent=2)
        f.close()

    def create_load_balancer(self,
                             name,
                             zones,
                             listeners,
                             subnets=None,
                             security_groups=None,
                             scheme='internet-facing'):
        return self.conn.create_load_balancer(name, zones, listeners, subnets,
                                              security_groups, scheme)

    def delete_load_balancer(self, name):
        return self.conn.delete_load_balancer(name)

    def get_all_load_balancers(self, load_balancer_names=None):
        obj = self.conn.get_all_load_balancers(load_balancer_names)
        if self.saveclcdata:
            self.__save_json__(obj, "mockdata/ELB_Balancers.json")
        return obj

    def deregister_instances(self, load_balancer_name, instances):
        return self.conn.deregister_instances(load_balancer_name, instances)

    def register_instances(self, load_balancer_name, instances):
        return self.conn.register_instances(load_balancer_name, instances)

    def create_load_balancer_listeners(self, name, listeners):
        return self.conn.create_load_balancer_listeners(name, listeners)

    def delete_load_balancer_listeners(self, name, ports):
        return self.conn.delete_load_balancer_listeners(name, ports)

    def configure_health_check(self, name, health_check):
        return self.conn.configure_health_check(name, health_check)

    def describe_instance_health(self, load_balancer_name, instances=None):
        obj = self.conn.describe_instance_health(load_balancer_name, instances)
        if self.saveclcdata:
            self.__save_json__(obj, "mockdata/ELB_Instances.json")
        return obj
class BotoBalanceInterface(BalanceInterface):
    conn = None
    saveclcdata = False

    def __init__(self, clc_host, access_id, secret_key, token):
        #boto.set_stream_logger('foo')
        path = '/services/LoadBalancing'
        port = 8773
        if clc_host[len(clc_host) - 13:] == 'amazonaws.com':
            clc_host = clc_host.replace('ec2', 'elasticloadbalancing', 1)
            path = '/'
            reg = None
            port = 443
        reg = RegionInfo(name='eucalyptus', endpoint=clc_host)
        self.conn = ELBConnection(access_id,
                                  secret_key,
                                  region=reg,
                                  port=port,
                                  path=path,
                                  is_secure=True,
                                  security_token=token,
                                  debug=0)
        self.conn.https_validate_certificates = False
        self.conn.http_connection_kwargs['timeout'] = 30

    def __save_json__(self, obj, name):
        f = open(name, 'w')
        json.dump(obj, f, cls=BotoJsonBalanceEncoder, indent=2)
        f.close()

    def create_load_balancer(self,
                             name,
                             zones,
                             listeners,
                             subnets=None,
                             security_groups=None,
                             scheme='internet-facing'):
        return self.conn.create_load_balancer(name, zones, listeners, subnets,
                                              security_groups, scheme)

    def delete_load_balancer(self, name):
        return self.conn.delete_load_balancer(name)

    def get_all_load_balancers(self, load_balancer_names=None):
        params = {}
        if load_balancer_names:
            self.build_list_params(params, load_balancer_names,
                                   'LoadBalancerNames.member.%d')
        http_request = self.conn.build_base_http_request(
            'GET', '/', None, params, {}, '', self.conn.server_name())
        http_request.params['Action'] = 'DescribeLoadBalancers'
        http_request.params['Version'] = self.conn.APIVersion
        response = self.conn._mexe(http_request, override_num_retries=2)
        body = response.read()
        boto.log.debug(body)
        if not body:
            boto.log.error('Null body %s' % body)
            raise self.conn.ResponseError(response.status, response.reason,
                                          body)
        elif response.status == 200:
            obj = boto.resultset.ResultSet([
                ('member', boto.ec2.elb.loadbalancer.LoadBalancer)
            ])
            h = boto.handler.XmlHandler(obj, self.conn)
            import xml.sax
            xml.sax.parseString(body, h)
            if self.saveclcdata:
                self.__save_json__(obj, "mockdata/ELB_Balancers.json")
            return obj
        else:
            boto.log.error('%s %s' % (response.status, response.reason))
            boto.log.error('%s' % body)
            raise self.conn.ResponseError(response.status, response.reason,
                                          body)

    def deregister_instances(self, load_balancer_name, instances):
        return self.conn.deregister_instances(load_balancer_name, instances)

    def register_instances(self, load_balancer_name, instances):
        return self.conn.register_instances(load_balancer_name, instances)

    def create_load_balancer_listeners(self, name, listeners):
        return self.conn.create_load_balancer_listeners(name, listeners)

    def delete_load_balancer_listeners(self, name, ports):
        return self.conn.delete_load_balancer_listeners(name, ports)

    def configure_health_check(self, name, health_check):
        return self.conn.configure_health_check(name, health_check)

    def describe_instance_health(self, load_balancer_name, instances=None):
        obj = self.conn.describe_instance_health(load_balancer_name, instances)
        if self.saveclcdata:
            self.__save_json__(obj, "mockdata/ELB_Instances.json")
        return obj
Exemple #7
0
class LoadBalancer(BaseLoadBalancer):
    """The classic load balancer for ELB.

    This is used to interface with the classic Elastic Load Balancer, which
    can be used in VPC or in EC2-Classic.
    """

    def __init__(self, name):
        """Initialize the instance.

        Args:
            name (unicode):
                The name of the load balancer.
        """
        self.name = name
        self._cnx = ELBConnection()

    def register_instance(self, instance):
        """Register an instance on the load balancer.

        Args:
            instance (fabazon.ec2.EC2Instance):
                The instance to register.
        """
        self._cnx.register_instances(self.name, [instance.id])

    def unregister_instance(self, instance):
        """Unregister an instance from the load balancer.

        Args:
            instance (fabazon.ec2.EC2Instance):
                The instance to unregister.
        """
        self._cnx.deregister_instances(self.name, [instance.id])

    def is_instance_registered(self, instance):
        """Return whether an instance is registered.

        Args:
            instance (fabazon.ec2.EC2Instance):
                The instance to check.

        Returns:
            bool:
            ``True`` if the instance is registered on the load balancer.
            ``False`` if it's not registered.
        """
        health_info = self._get_instance_health_info(instance)

        return (health_info.description ==
                'Instance is not currently registered with the LoadBalancer.')

    def is_instance_healthy(self, instance):
        """Return whether an instance is healthy.

        Args:
            instance (fabazon.ec2.EC2Instance):
                The instance to check.

        Returns:
            bool:
            ``True`` if the instance is healthy.
            ``False`` if it's not healthy.
        """
        health_info = self._get_instance_health_info(instance)

        return health_info.state == 'InService'

    def _get_instance_health_info(self, instance):
        """Return health information for an instance.

        Args:
            instance (fabazon.ec2.EC2Instance):
                The instance to check.

        Returns:
            dict:
            Information on the instance's health.
        """
        health_info = self._cnx.describe_instance_health(self.name,
                                                         [instance.id])

        assert len(health_info) == 1
        assert health_info[0].instance_id == instance.id

        return health_info[0]
Exemple #8
0
class aws:
    def __init__(self,PREFIX='tfound-',ENV='dev',AMI='',TYPE='',SIZE='',
                 DOMAIN='tfound',SSHKEY='myprivatekey',AWSKEY='',AWSSECRET='',AVAIL_ZONES=["us-east-1a","us-east-1b","us-east-1c","us-east-1d"]):
        '''
        Shows examples
        Create load balancer group 'tfound-dev-web-lb' for web servers, in dev group for tfound:
            python control-lb-and-groups.py --createlb --env dev --aws SC --type web
        Add an instance to the load balancer group:
            python control-lb-and-groups.py --addtolb=true --env dev --aws SC --type web --instance=i-999999
        Create launch config using ami ami-fa6b8393 (default), medium sized instance, and Autoscale Group 'tfound-dev-web-group' with a min of 2 instances, max 5, with health check on port 80:
            python control-lb-and-groups.py  --createlc --ami ami-fa6b8393 --size c1.medium --env dev --aws SC --type web --createag --min 2 --max 5
        Triggers/Health checks are hard coded to spawn new instances when total cpu reaches 60 percent or health check fails.
        '''
        self.PREFIX=PREFIX+DOMAIN+'-'+ENV+'-'+TYPE
        self.ENV=ENV
        self.AMI=AMI
        self.TYPE=TYPE
        self.DOMAIN=DOMAIN
        self.SIZE=SIZE
        self.MIN=MIN
        self.MAX=MAX
        self.SSHKEY=SSHKEY
        self.AWSKEY=AWSKEY
        self.AWSSECRET=AWSSECRET
        self.AVAIL_ZONES=AVAIL_ZONES
        self.LBNAME=self.PREFIX+'-lb'
        self.AGNAME=self.PREFIX+'-group'
        self.TRNAME=self.PREFIX+'-trigger'
        self.LCNAME=self.PREFIX+'-launch_config'
        self.asconn=AutoScaleConnection(self.AWSKEY, self.AWSSECRET)
        self.elbconn = ELBConnection(aws_access_key_id=AWSKEY,aws_secret_access_key=AWSSECRET)
        self.lc = self._buildLaunchConfig()
        self.ag = self._buildAutoscaleGroup()
        
    
    def _buildLaunchConfig(self):
        return LaunchConfiguration(name=self.LCNAME, 
                                   image_id=self.AMI,
                                   key_name=self.SSHKEY,
                                   security_groups=[self.ENV+'.'+self.TYPE],
                                   user_data='LAUNCHTAGS="'+self.ENV+' '
                                   +self.TYPE+' '+self.DOMAIN+'";',
                                   instance_type=self.SIZE)

    def _buildAutoscaleGroup(self):
        return AutoScalingGroup(group_name=self.AGNAME,
                              load_balancers=[self.LBNAME],
                              availability_zones=self.AVAIL_ZONES,
                              launch_config=self.lc, 
                              min_size=self.MIN,
                              max_size=self.MAX)

    def getGroups(self):
        '''get existing lb groups'''
        # conn = AutoScaleConnection(AWSKEY, AWSSECRET)
        #conn = AutoScaleConnection()
        return self.asconn.get_all_groups()

    def getActivities(self,AUTOSCALE_GROUP=None):
        return self.asconn.get_all_activities(AUTOSCALE_GROUP)
                        
    def createLaunchConfig(self):
        '''create Launch Configuration to define initial startup params
        '''
        #conn = AutoScaleConnection(AWSKEY, AWSSECRET)
        #lc = self.buildLaunchConfig()
        return self.asconn.create_launch_configuration(self.lc)
    

        
    def createAutoscaleGroup(self):
        '''We now have created a launch configuration called tfound...launch-config.
        We are now ready to associate it with our new autoscale group.
        returns autoscale object
        '''
        #conn = AutoScaleConnection(AWSKEY, AWSSECRET) 
        #lc = self.buildLaunchConfig()
        
        return self.asconn.create_auto_scaling_group(self.ag)
        #conn.get_all_activities(ag)
        
    def createTrigger(self,AUTOSCALE_GROUP=None):
        ''' 
        you create a trigger on a group, pass in a group object
        this creates a trigger that scales up to MAX instances if average cpu utilitzation goes over 60, 
        scales down to MIN instances if under 40 avg cpu
        '''
        #conn = AutoScaleConnection(AWSKEY, AWSSECRET)
        tr = Trigger(name=self.TRNAME, 
                     autoscale_group=AUTOSCALE_GROUP,
                     measure_name='CPUUtilization', statistic='Average',
                     unit='Percent',
                     dimensions=[('AutoScalingGroupName', AUTOSCALE_GROUP.name),
                                 ('Namespace','AWS/EC2')],
                                 period=120, lower_threshold=10,
                                 lower_breach_scale_increment='-1',
                                 upper_threshold=30,
                                 upper_breach_scale_increment='1',
                                 breach_duration=360)
        return self.asconn.create_trigger(tr)
    
    def createHealthCheck(self):
        return HealthCheck('instance_health', 
                           interval=20, 
                           target='TCP:8080', 
                           timeout='5')
    
    def createLoadbalancer(self):
        #elbconn = ELBConnection(aws_access_key_id=AWSKEY,aws_secret_access_key=AWSSECRET)
        #conn = ELBConnection(aws_access_key_id=AWSKEY,aws_secret_access_key=AWSSECRET,
        #  host='us-east-1a.elasticloadbalancing.amazonaws.com')
        #  hc = HealthCheck('instance_health', interval=20, target='HTTP:80/index.php', timeout='5')
        #  lb = conn.create_load_balancer('tfound-'+options.ENV+'-'+options.TYPE+'-lb', [options.ZONE],
        #                                   [(80, 80, 'http'),(8000,8000, 'tcp')])
        ##  lb.delete()
        hc = self.createHealthCheck()
        lb = self.elbconn.create_load_balancer(self.LBNAME, 
                                               [self.ZONE],
                                               [(8080,8080, 'tcp')])

        lb.configure_health_check(hc)
        return lb.dns_name
    
    def addToLoadbalancer(self,INSTANCE=None):
        #from boto.ec2.elb import ELBConnection
        #from boto.ec2.elb import HealthCheck
        #conn = ELBConnection(aws_access_key_id=AWSKEY,aws_secret_access_key=AWSSECRET)
        #  conn = ELBConnection(aws_access_key_id=AWSKEY,aws_secret_access_key=AWSSECRET,
        #  host='us-east-1a.elasticloadbalancing.amazonaws.com')
        if INSTANCE == None:
            sys.stderr.write("Please provide instance id to add. not acceptble: %s\n" % options.INSTANCE )
            raise SystemExit(1)
        lb = self.elbconn.register_instances(self.LBNAME, 
                                             INSTANCE)
        #lbgroup = 'tfound-'+options.ENV+'-'+options.TYPE+'-lb'
        print "Added instance %s to %s\n" % (INSTANCE, self.LBNAME)

    def getLoadbalancers(self):
        return self.elbconn.get_all_load_balancers()

    def startInstances(self,TYPE='',NUM='',SIZE=''):
        return
Exemple #9
0
class AutoScale:

    def __init__(self, args):
        """
        Initializing basic variables needed for auto scaling
        """
        self.configs                = ConfigParser.RawConfigParser()
        self.args                   = args
        self.test_props             = {}
        self.props                  = {}
        self.ec2_connection         = EC2Connection(self.args.access_key, self.args.secret_key)
        self.autoscale_connection   = AutoScaleConnection(self.args.access_key, self.args.secret_key)
        self.elb_connection         = ELBConnection(self.args.access_key, self.args.secret_key)
        self.cw_connection          = CloudWatchConnection(self.args.access_key, self.args.secret_key)
        self.firstInstance          = None
        self.launchConfiguration    = None
        self.healthCheck            = None

    def loadConfigs(self):
        """
        FIX ME: Currently doesnt do anything
        This method will load the configurations from boto config file if present else will 
        accept parameters passed by user.
        """
        if os.path.isfile("/etc/boto.cfg"):
            self.configs.read("/etc/boto.cfg")
            conf = self.configs.sections()
            self.populateConfigs(conf)
        if os.path.isfile("~/.boto"):
            self.configs.read("~/.boto")
            conf = self.configs.sections()
            self.populateConfigs(conf)
            
        print ">>> Loaded configs"
            
    def populateConfigs(self, sections):
        for section in sections:
            self.boto_props[section] = self.configs.items(section)
            for item in self.boto_props[section]:
                key, value = item
                if not self.props.has_key(key):
                    self.props[key] = value

    def createLaunchConfiguration(self, lc_name, ami_id, key_name):
        """
        Creates launch configuration for the auto scaling cluster
        """
        self.launchConfiguration = LaunchConfiguration(name     = lc_name, 
                                                       image_id = ami_id, 
                                                       key_name = key_name)
        self.autoscale_connection.create_launch_configuration(self.launchConfiguration)
        print ">>> Created launch configuration: " + lc_name

    def createAutoScaleGroup(self, asg_name):
        """
        Create a Auto scaling group for the auto scaling cluster
        """
        autoScalingGroup = AutoScalingGroup(group_name         = asg_name, 
                                            load_balancers     = [self.args.lb_name], 
                                            launch_config      = self.launchConfiguration, 
                                            min_size           = self.args.min_size, 
                                            max_size           = self.args.max_size, 
                                            availability_zones = ['us-east-1a'])
        self.autoscale_connection.create_auto_scaling_group(autoScalingGroup)
        print ">>> Created auto scaling group: " + asg_name

    def createTrigger(self, trigger_name, measure, asg_name):
        """
        Trigger to spawn new instances as per specific metrics
        """
        alarm_actions = []
        dimensions = {"AutoScalingGroupName" : asg_name}
        policies = self.autoscale_connection.get_all_policies(as_group=self.args.asg_name, policy_names=[self.args.asp_name])
        for policy in policies:
            alarm_actions.append(policy.policy_arn)
        alarm = MetricAlarm(name                = trigger_name, 
                            namespace           = "AWS/EC2", 
                            metric              = measure, 
                            statistic           = "Average", 
                            comparison          = ">=", 
                            threshold           = 50, 
                            period              = 60, 
                            unit                = "Percent",
                            evaluation_periods  = 2,  
                            alarm_actions       = alarm_actions, 
                            dimensions          = dimensions)
        
        self.cw_connection.create_alarm(alarm)
        print ">>> Created trigger: "+self.args.trigger

    def createAutoScalePolicy(self, asp_name):
        """
        Creates a Auto scaling policy to Add/Remove a instance from auto scaling cluster
        """
        self.autoScalingUpPolicy = ScalingPolicy(name                 = asp_name+'-up',
                                                 adjustment_type      = "ChangeInCapacity", 
                                                 as_name              = self.args.asg_name, 
                                                 scaling_adjustment   = 1, 
                                                 cooldown             = 180)
        self.autoScalingDownPolicy = ScalingPolicy(name                 = asp_name+'-down',
                                                   adjustment_type      = "ChangeInCapacity", 
                                                   as_name              = self.args.asg_name, 
                                                   scaling_adjustment   = -1, 
                                                   cooldown             = 180)

        self.autoscale_connection.create_scaling_policy(self.autoScalingUpPolicy)
        self.autoscale_connection.create_scaling_policy(self.autoScalingDownPolicy)
        
        print ">>> Created auto scaling policy: " + asp_name
    
    def configureHealthCheck(self, target):
        """
        Configures health check for the cluster
        """
        self.healthCheck = HealthCheck(target   = target, 
                                       timeout  = 5)
        print ">>> Configured health check for: " + target
        
    def createLoadBalancer(self, lb_name, region, lb_port, instance_port, protocol):
        """
        Creates a load balancer for cluster
        """
        listener = (int(lb_port), int(instance_port), protocol)
        tuple_list =[]
        tuple_list.append(listener)
        lbs = self.elb_connection.get_all_load_balancers()
        for lb in lbs:
            if lb.name != lb_name:
                self.elb_connection.create_load_balancer(lb_name, [region], tuple_list)
                self.elb_connection.configure_health_check(name         = lb_name, 
                                                           health_check = self.healthCheck)
                print ">>> Created load balancer: " + lb_name
            else:
                print "Load balancer with name '"+lb_name+"' already exists"
        
    def startInstance(self, image_id, key_name, region, instance_type):
        """
        Starts the first instance which will be serving requests irrespective of auto scaling 
        instances.
        """
        reservation = self.ec2_connection.run_instances(image_id=image_id, min_count=1, max_count=1, placement=region, key_name=key_name, instance_type=instance_type)
#        for instance in reservation.instances:
#            instance.add_tag('node', '0')
#            break

        self.firstInstance = reservation.instances[0].id.split('\'')[0]
        print ">>> Started instance: ", self.firstInstance
    
    def registerInstanceToELB(self, lb_name):
        """
        Register the first instance started to the Elastic Load Balancer.
        """
        self.elb_connection.register_instances(load_balancer_name = lb_name, 
                                               instances          = [self.firstInstance])
        print ">>> Registered instance '",self.firstInstance,"' to load balancer '"+lb_name+"'"
    
    def setUp(self):
        """
        Set's up the auto scaling for the application
        """
        # STEP 1: Load the configurations
        self.loadConfigs()
        # STEP 2: Configure the health check for the instances
        self.configureHealthCheck(self.args.lb_target)
        # STEP 3: Create a load balancer
        self.createLoadBalancer(self.args.lb_name, self.args.region, self.args.lb_port, self.args.instance_port, self.args.protocol)
        # STEP 4: Start the first instance
        self.startInstance(self.args.ami_id, self.args.key_name, self.args.region, self.args.instance_type)
        # STEP 5: Register the instance to the load balancer created in STEP 4
        self.registerInstanceToELB(self.args.lb_name)
        # STEP 6: Create launch configuration to launch instances by auto scale
        self.createLaunchConfiguration(self.args.lc_name, self.args.ami_id, self.args.key_name)
        # STEP 7: Create a auto scale group which will manage the instances started by auto scaling
        self.createAutoScaleGroup(self.args.asg_name)
        # STEP 8: Create a auto scaling policy to say add/remove a node
        self.createAutoScalePolicy(self.args.asp_name)
        # STEP 9: Create a trigger, so that auto scaling can trigger it to start 
        # or remove a instance from auto scaling group 
        self.createTrigger(self.args.trigger, self.args.measure, self.args.asg_name)
#the copy and copytree methods can help you move stuff out of your expanded package to various places on the server.
#subprocess.call(["rm /var/www/html/test.py",""], shell=True)
#subprocess.call(["rmdr /var/www/html",""], shell=True)
#subprocess.call(["apachectl -k stop",""], shell=True)
move("/home/root/project-code/AppServer/httpd.conf", "/etc/httpd/conf")
subprocess.call(["mkdir /var/www/styles",""], shell=True)
#subprocess.call(["apachectl -k start",""], shell=True)
copytree("/home/root/project-code/AppServer", "/var/www/python")
subprocess.call(["mkdir	/var/www/python/files",""], shell=True)
subprocess.call(["chmod 777 /var/www/python/files",""], shell=True)

subprocess.call(["yum install -y python-json",""], shell=True)
subprocess.call(["yum install -y python-imaging",""], shell=True)

#executing commandline calls can be done with the subprocess module
subprocess.call(["apachectl -k start",""], shell=True)

#Register with load balancer
from subprocess import Popen, PIPE
cmd = 'curl -s http://169.254.169.254/latest/meta-data/instance-id'
arglist = cmd.split()
instance_id = Popen(arglist, stdout=PIPE).communicate()[0] 
from boto.ec2.elb import ELBConnection
conn = ELBConnection('AKIAJHJXHTMTVQYVZJOA','2YVZfFXQ7mhdFeUnMjcMOJ8uc5GBjz5LXhmh8LiM')
lbs = conn.get_all_load_balancers()
conn.register_instances('appserver-lb', [instance_id])
 
#make sure to start any services required for this server.
 
print "Configure Server Complete"