Example #1
0
    def setUp(self):
        ec2.credentials.ACCESS_KEY_ID = 'abc'
        ec2.credentials.SECRET_ACCESS_KEY = 'xyz'

        # Build up two reservations, with two instances each, totalling 4 instances
        # Two running, two stopped
        reservations = []
        instance_count = 0
        for i in xrange(2):
            i1 = Instance()
            i1.id = 'i-abc%d' % instance_count
            i1._state = RUNNING_STATE
            i1.tags = {'Name': 'instance-%d' % instance_count}
            instance_count += 1
            i2 = Instance()
            i2.id = 'i-abc%d' % instance_count
            i2._state = STOPPED_STATE
            i2.tags = {'Name': 'instance-%d' % instance_count}
            instance_count += 1
            reservation = MagicMock()
            reservation.instances.__iter__ = MagicMock(return_value=iter([i1, i2]))
            reservations.append(reservation)

        security_groups = []
        for i in xrange(2):
            sg = SecurityGroup()
            sg.id = 'sg-abc%d' % i
            sg.name = 'group-%d' % i
            sg.description = 'Group %d' % i
            security_groups.append(sg)

        self.connection = MagicMock()
        self.connection.get_all_instances = MagicMock(return_value=reservations)
        self.connection.get_all_security_groups = MagicMock(return_value=security_groups)
    def test_create_db_instance_vpc_sg_obj(self):
        self.set_http_response(status_code=200)

        sg1 = SecurityGroup(name='sg-1')
        sg2 = SecurityGroup(name='sg-2')

        vpc_security_groups = [
            VPCSecurityGroupMembership(self.service_connection, 'active', sg1.name),
            VPCSecurityGroupMembership(self.service_connection, None, sg2.name)]

        db = self.service_connection.create_dbinstance(
            'SimCoProd01',
            10,
            'db.m1.large',
            'main',
            'Password01',
            param_group='default.mysql5.1',
            db_subnet_group_name='dbSubnetgroup01',
            vpc_security_groups=vpc_security_groups)

        self.assert_request_parameters({
            'Action': 'CreateDBInstance',
            'AllocatedStorage': 10,
            'AutoMinorVersionUpgrade': 'true',
            'DBInstanceClass': 'db.m1.large',
            'DBInstanceIdentifier': 'SimCoProd01',
            'DBParameterGroupName': 'default.mysql5.1',
            'DBSubnetGroupName': 'dbSubnetgroup01',
            'Engine': 'MySQL5.1',
            'MainUsername': '******',
            'MainUserPassword': '******',
            'Port': 3306,
            'VpcSecurityGroupIds.member.1': 'sg-1',
            'VpcSecurityGroupIds.member.2': 'sg-2'
        }, ignore_params_values=['Version'])
Example #3
0
    def test_attach_classic_link_instance_object_groups(self):
        sec_group_1 = SecurityGroup()
        sec_group_1.id = 'sg-foo'

        sec_group_2 = SecurityGroup()
        sec_group_2.id = 'sg-bar'

        groups = [sec_group_1, sec_group_2]

        self.set_http_response(status_code=200)
        response = self.vpc.attach_classic_instance(
            instance_id='my_instance_id',
            groups=groups,
            dry_run=True
        )
        self.assertTrue(response)
        self.assert_request_parameters({
            'Action': 'AttachClassicLinkVpc',
            'VpcId': self.vpc_id,
            'InstanceId': 'my_instance_id',
            'SecurityGroupId.1': 'sg-foo',
            'SecurityGroupId.2': 'sg-bar',
            'DryRun': 'true'},
            ignore_params_values=['AWSAccessKeyId', 'SignatureMethod',
                                  'SignatureVersion', 'Timestamp', 'Version'])
def get_running_instances(access_key=None, secret_key=None, security_group=None):
    '''
    Get all running instances. Only within a security group if specified.
    '''
    logging.debug('get_running_instances()')

    instances_all_regions_list = []
    conn = EC2Connection(aws_access_key_id=access_key,
                         aws_secret_access_key=secret_key)
    ec2_region_list = conn.get_all_regions()

    if security_group:
        for index, region in enumerate(ec2_region_list):
            conn = EC2Connection(aws_access_key_id=access_key,
                                 aws_secret_access_key=secret_key,
                                 region=ec2_region_list[index])
            sg = SecurityGroup(connection=conn, name=security_group)
            running_instances = [i for i in sg.instances() if i.state == 'running']
            if running_instances:
                for instance in running_instances:
                    instances_all_regions_list.append(instance)
    else:
        for index, region in enumerate(ec2_region_list):
            conn = EC2Connection(aws_access_key_id=access_key,
                                 aws_secret_access_key=secret_key,
                                 region=ec2_region_list[index])
            reserved_instances = conn.get_all_instances()
            if reserved_instances:
                for reservation in reserved_instances:
                    for instance in reservation.instances:
                        if instance.stat == 'running':
                            instances_all_regions_list.append(instance)
    return instances_all_regions_list
Example #5
0
 def create_security_group(self, name, description, vpc_id=None):
     if self.create_security_group_callback:
         self.create_security_group_callback(vpc_id)
     sg = SecurityGroup()
     sg.id = 'sg-%s' % new_id()
     sg.vpc_id = vpc_id or self.default_vpc.id
     self.security_groups[sg.id] = sg
     return sg
Example #6
0
    def setUp(self):
        ec2.credentials.ACCESS_KEY_ID = 'abc'
        ec2.credentials.SECRET_ACCESS_KEY = 'xyz'

        # Build up two reservations, with two instances each, totalling 4 instances
        # Two running, two stopped
        reservations = []
        instance_count = 0
        for i in xrange(2):
            i1 = Instance()
            i1.id = 'i-abc%d' % instance_count
            i1._state = RUNNING_STATE
            i1.tags = {'Name': 'instance-%d' % instance_count}
            instance_count += 1
            i2 = Instance()
            i2.id = 'i-abc%d' % instance_count
            i2._state = STOPPED_STATE
            i2.tags = {'Name': 'instance-%d' % instance_count}
            instance_count += 1
            reservation = MagicMock()
            reservation.instances.__iter__ = MagicMock(return_value=iter([i1, i2]))
            reservations.append(reservation)

        security_groups = []
        for i in xrange(2):
            sg = SecurityGroup()
            sg.id = 'sg-abc%d' % i
            sg.name = 'group-%d' % i
            sg.description = 'Group %d' % i
            security_groups.append(sg)

        vpcs = []
        for i in xrange(2):
            vpc = VPC()
            vpc.id = 'vpc-abc%d' % i
            if i % 2:
                vpc.state = 'pending'
                vpc.is_default = False
                vpc.instance_tenancy = 'default'
            else:
                vpc.state = 'available'
                vpc.is_default = True
                vpc.instance_tenancy = 'dedicated'
            vpc.cidr_block = '10.%d.0.0/16' % i
            vpc.dhcp_options_id = 'dopt-abc%d' % i
            vpcs.append(vpc)

        self.connection = MagicMock()
        self.connection.get_all_instances = MagicMock(return_value=reservations)
        self.connection.get_all_security_groups = MagicMock(return_value=security_groups)

        self.vpc_connection = MagicMock()
        self.vpc_connection.get_all_vpcs = MagicMock(return_value=vpcs)
def get_running_instances_in_security_group(access_key=None, secret_key=None, security_group=None, region='us-east-1'):
    '''
    Get all running instances. Only within a security group if specified.
    '''
    logging.debug('get_running_instances_in_security_group()')
    conn = EC2Connection(aws_access_key_id=access_key,
                         aws_secret_access_key=secret_key,region=boto.ec2.get_region(region))

    if security_group:
        sg = SecurityGroup(connection=conn, name=security_group)
        instances = [i for i in sg.instances() if i.state == 'running']
	print(instances)
        return instances
Example #8
0
    def test_add_rule(self):
        sg = SecurityGroup()
        self.assertEqual(len(sg.rules), 0)

        # Regression: ``dry_run`` was being passed (but unhandled) before.
        sg.add_rule(ip_protocol='http',
                    from_port='80',
                    to_port='8080',
                    src_group_name='groupy',
                    src_group_owner_id='12345',
                    cidr_ip='10.0.0.1',
                    src_group_group_id='54321',
                    dry_run=False)
        self.assertEqual(len(sg.rules), 1)
def get_running_instances(access_key=None, secret_key=None, security_group=None):
    """
    Get all running instances. Only within a security group if specified.
    """
    logging.debug("get_running_instances()")
    conn = EC2Connection(aws_access_key_id=access_key, aws_secret_access_key=secret_key)

    if security_group:
        sg = SecurityGroup(connection=conn, name=security_group)
        instances = [i for i in sg.instances() if i.state == "running"]
        return instances
    else:
        instances = conn.get_all_instances()
        return instances
Example #10
0
    def setUp(self):
        self.fake_ec2 = flexmock(name='self.fake_ec2')
        self.fake_ec2.should_receive('get_key_pair')
        self.fake_ec2.should_receive('create_key_pair').with_args('bookeyname') \
          .and_return(KeyPair())
        self.fake_ec2.should_receive('get_all_security_groups').and_return([])
        self.fake_ec2.should_receive('create_security_group') \
          .with_args('boogroup', 'AppScale security group') \
          .and_return(SecurityGroup())
        self.fake_ec2.should_receive('authorize_security_group')

        instance = flexmock(name='instance',
                            private_dns_name='private-ip',
                            public_dns_name='public-ip',
                            id='i-id',
                            state='running',
                            key_name='bookeyname')

        self.fake_ec2.should_receive('terminate_instances').and_return(
            [instance])
        self.fake_ec2.should_receive('run_instances')

        flexmock(boto.ec2)
        boto.ec2.should_receive('connect_to_region').and_return(self.fake_ec2)

        (flexmock(utils).should_receive('get_secret').and_return('secret'))
        (flexmock(utils).should_receive('sleep').and_return())
        (flexmock(utils).should_receive('get_random_alphanumeric').and_return(
            '0000000000'))
        (flexmock(utils).should_receive('write_key_file').and_return())
Example #11
0
    def test_add_rule(self):
        sg = SecurityGroup()
        self.assertEqual(len(sg.rules), 0)

        # Regression: ``dry_run`` was being passed (but unhandled) before.
        sg.add_rule(
            ip_protocol='http',
            from_port='80',
            to_port='8080',
            src_group_name='groupy',
            src_group_owner_id='12345',
            cidr_ip='10.0.0.1',
            src_group_group_id='54321',
            dry_run=False
        )
        self.assertEqual(len(sg.rules), 1)
Example #12
0
    def setUp(self):
        self.factory = InfrastructureAgentFactory()

        self.fake_ec2 = flexmock(name='self.fake_ec2')
        self.fake_ec2.should_receive('get_key_pair')
        self.fake_ec2.should_receive('create_key_pair').with_args('bookeyname') \
            .and_return(KeyPair())
        self.fake_ec2.should_receive('get_all_security_groups').and_return([])
        self.fake_ec2.should_receive('create_security_group') \
            .with_args('boogroup', 'AppScale security group') \
            .and_return(SecurityGroup())
        self.fake_ec2.should_receive('authorize_security_group')

        instance = flexmock(name='instance',
                            private_dns_name='private-ip',
                            public_dns_name='public-ip',
                            id='i-id',
                            state='running',
                            key_name='bookeyname')

        self.fake_ec2.should_receive('terminate_instances').and_return(
            [instance])
        self.fake_ec2.should_receive('run_instances')

        flexmock(boto.ec2)
        boto.ec2.should_receive('connect_to_region').and_return(self.fake_ec2)
Example #13
0
    def setUp(self):
        (flexmock(EC2Connection).should_receive('get_key_pair').and_return(
            None))
        (flexmock(EC2Connection).should_receive('create_key_pair').with_args(
            'bookeyname').and_return(KeyPair()))
        (flexmock(EC2Connection).should_receive(
            'get_all_security_groups').and_return([]))
        (flexmock(
            EC2Connection).should_receive('create_security_group').with_args(
                'boogroup',
                'AppScale security group').and_return(SecurityGroup()))
        (flexmock(EC2Connection).should_receive(
            'authorize_security_group').and_return())
        reservation = Reservation()
        instance = Instance()
        instance.private_dns_name = 'private-ip'
        instance.public_dns_name = 'public-ip'
        instance.id = 'i-id'
        instance._state.name = 'running'
        instance.key_name = 'bookeyname'
        reservation.instances = [instance]
        (flexmock(EC2Connection).should_receive(
            'get_all_instances').and_return([]).and_return([reservation]))
        (flexmock(EC2Connection).should_receive(
            'terminate_instances').and_return([instance]))
        (flexmock(EC2Connection).should_receive('run_instances').and_return())

        (flexmock(utils).should_receive('get_secret').and_return('secret'))
        (flexmock(utils).should_receive('sleep').and_return())
        (flexmock(utils).should_receive('get_random_alphanumeric').and_return(
            '0000000000'))
        (flexmock(utils).should_receive('write_key_file').and_return())
Example #14
0
  def setUp(self):
    (flexmock(EC2Connection)
      .should_receive('get_key_pair')
      .and_return(None))
    (flexmock(EC2Connection)
      .should_receive('create_key_pair')
      .with_args('bookeyname')
      .and_return(KeyPair()))
    (flexmock(EC2Connection)
      .should_receive('get_all_security_groups')
      .and_return([]))
    (flexmock(EC2Connection)
      .should_receive('create_security_group')
      .with_args('boogroup', 'AppScale security group')
      .and_return(SecurityGroup()))
    (flexmock(EC2Connection)
      .should_receive('authorize_security_group')
      .and_return())
    reservation = Reservation()

    # the old implementation had a regression where public and private IPs
    # were getting sorted, and thus public ip1 would point to private ip 2.
    # to prevent this regression from resurfacing, set up the dns names so
    # that a sort would mess them up again.
    instance1 = Instance()
    instance1.public_dns_name = 'ABC-public-ip1'
    instance1.private_dns_name = 'DEF-private-ip1'
    instance1.id = 'i-id1'
    instance1._state.name = 'running'
    instance1.key_name = 'bookeyname'

    instance2 = Instance()
    instance2.public_dns_name = 'DEF-public-ip2'
    instance2.private_dns_name = 'ABC-private-ip2'
    instance2.id = 'i-id2'
    instance2._state.name = 'running'
    instance2.key_name = 'bookeyname'

    reservation.instances = [instance1, instance2]
    (flexmock(EC2Connection)
      .should_receive('get_all_instances')
      .and_return([])
      .and_return([reservation]))
    (flexmock(EC2Connection)
     .should_receive('run_instances')
     .and_return())

    (flexmock(utils)
      .should_receive('get_secret')
      .and_return('secret'))
    (flexmock(utils)
      .should_receive('sleep')
      .and_return())
    (flexmock(utils)
      .should_receive('get_random_alphanumeric')
      .and_return('0000000000'))
    (flexmock(utils)
      .should_receive('write_key_file')
      .and_return())
Example #15
0
def get_running_instances(access_key=None,
                          secret_key=None,
                          security_group=None):
    '''
    Get all running instances. Only within a security group if specified.
    '''
    logging.debug('get_running_instances()')
    conn = EC2Connection(aws_access_key_id=access_key,
                         aws_secret_access_key=secret_key)

    if security_group:
        sg = SecurityGroup(connection=conn, name=security_group)
        instances = [i for i in sg.instances() if i.state == 'running']
        return instances
    else:
        instances = conn.get_all_instances()
        return instances
Example #16
0
def get_target_from_rule(module, ec2, rule, name, group, groups, vpc_id):
    """
    Returns tuple of (group_id, ip) after validating rule params.

    rule: Dict describing a rule.
    name: Name of the security group being managed.
    groups: Dict of all available security groups.

    AWS accepts an ip range or a security group as target of a rule. This
    function validate the rule specification and return either a non-None
    group_id or a non-None ip range.
    """

    FOREIGN_SECURITY_GROUP_REGEX = '^(\S+)/(sg-\S+)/(\S+)'
    group_id = None
    group_name = None
    ip = None
    target_group_created = False
    if 'group_id' in rule and 'cidr_ip' in rule:
        module.fail_json(msg="Specify group_id OR cidr_ip, not both")
    elif 'group_name' in rule and 'cidr_ip' in rule:
        module.fail_json(msg="Specify group_name OR cidr_ip, not both")
    elif 'group_id' in rule and 'group_name' in rule:
        module.fail_json(msg="Specify group_id OR group_name, not both")
    elif 'group_id' in rule and re.match(FOREIGN_SECURITY_GROUP_REGEX, rule['group_id']):
        # this is a foreign Security Group. Since you can't fetch it you must create an instance of it
        owner_id, group_id, group_name = re.match(FOREIGN_SECURITY_GROUP_REGEX, rule['group_id']).groups()
        group_instance = SecurityGroup(owner_id=owner_id, name=group_name, id=group_id)
        groups[group_id] = group_instance
        groups[group_name] = group_instance
    elif 'group_id' in rule:
        group_id = rule['group_id']
    elif 'group_name' in rule:
        group_name = rule['group_name']
        if group_name == name:
            group_id = group.id
            groups[group_id] = group
            groups[group_name] = group
        elif group_name in groups:
            group_id = groups[group_name].id
        else:
            if not rule.get('group_desc', '').strip():
                module.fail_json(msg="group %s will be automatically created by rule %s and no description was provided" % (group_name, rule))
            if not module.check_mode:
                auto_group = ec2.create_security_group(group_name, rule['group_desc'], vpc_id=vpc_id)
                group_id = auto_group.id
                groups[group_id] = auto_group
                groups[group_name] = auto_group
            target_group_created = True
    elif 'cidr_ip' in rule:
        ip = rule['cidr_ip']

    return group_id, ip, target_group_created
Example #17
0
    def test_attach_classic_link_instance_object_groups(self):
        sec_group_1 = SecurityGroup()
        sec_group_1.id = 'sg-foo'

        sec_group_2 = SecurityGroup()
        sec_group_2.id = 'sg-bar'

        groups = [sec_group_1, sec_group_2]

        self.set_http_response(status_code=200)
        response = self.vpc.attach_classic_instance(
            instance_id='my_instance_id', groups=groups, dry_run=True)
        self.assertTrue(response)
        self.assert_request_parameters(
            {
                'Action': 'AttachClassicLinkVpc',
                'VpcId': self.vpc_id,
                'InstanceId': 'my_instance_id',
                'SecurityGroupId.1': 'sg-foo',
                'SecurityGroupId.2': 'sg-bar',
                'DryRun': 'true'
            },
            ignore_params_values=[
                'AWSAccessKeyId', 'SignatureMethod', 'SignatureVersion',
                'Timestamp', 'Version'
            ])
def get_running_instances(access_key=None,
                          secret_key=None,
                          security_group=None):
    '''
    Get all running instances. Only within a security group if specified.
    '''
    logging.debug('get_running_instances()')

    instances_all_regions_list = []
    conn = EC2Connection(aws_access_key_id=access_key,
                         aws_secret_access_key=secret_key)
    ec2_region_list = conn.get_all_regions()

    if security_group:
        for index, region in enumerate(ec2_region_list):
            conn = EC2Connection(aws_access_key_id=access_key,
                                 aws_secret_access_key=secret_key,
                                 region=ec2_region_list[index])
            sg = SecurityGroup(connection=conn, name=security_group)
            running_instances = [
                i for i in sg.instances() if i.state == 'running'
            ]
            if running_instances:
                for instance in running_instances:
                    instances_all_regions_list.append(instance)
    else:
        for index, region in enumerate(ec2_region_list):
            conn = EC2Connection(aws_access_key_id=access_key,
                                 aws_secret_access_key=secret_key,
                                 region=ec2_region_list[index])
            reserved_instances = conn.get_all_instances()
            if reserved_instances:
                for reservation in reserved_instances:
                    for instance in reservation.instances:
                        if instance.stat == 'running':
                            instances_all_regions_list.append(instance)
    return instances_all_regions_list
Example #19
0
    def setUp(self):
        self.factory = InfrastructureAgentFactory()

        (flexmock(EC2Connection).should_receive('get_key_pair').and_return(
            None))
        (flexmock(EC2Connection).should_receive('create_key_pair').with_args(
            'bookeyname').and_return(KeyPair()))
        (flexmock(EC2Connection).should_receive(
            'get_all_security_groups').and_return([]))
        (flexmock(
            EC2Connection).should_receive('create_security_group').with_args(
                'boogroup',
                'AppScale security group').and_return(SecurityGroup()))
        (flexmock(EC2Connection).should_receive(
            'authorize_security_group').and_return())
        (flexmock(EC2Connection).should_receive('run_instances').and_return())
Example #20
0
    def setUp(self):
        fake_ec2 = flexmock(name='fake_ec2')
        fake_ec2.should_receive('get_key_pair')
        fake_ec2.should_receive('create_key_pair').with_args('bookeyname') \
          .and_return(KeyPair())
        fake_ec2.should_receive('get_all_security_groups').and_return([])
        fake_ec2.should_receive('create_security_group') \
          .with_args('boogroup', 'AppScale security group') \
          .and_return(SecurityGroup())
        fake_ec2.should_receive('authorize_security_group')

        reservation = Reservation()
        instance = flexmock(name='instance',
                            private_dns_name='private-ip',
                            public_dns_name='public-ip',
                            id='i-id',
                            state='running',
                            key_name='bookeyname',
                            ip_address='public-ip',
                            private_ip_address='private-ip')
        new_instance = flexmock(name='new-instance',
                                private_dns_name='new-private-ip',
                                public_dns_name='new-public-ip',
                                id='new-i-id',
                                state='running',
                                key_name='bookeyname',
                                ip_address='new-public-ip',
                                private_ip_address='new-private-ip')
        reservation.instances = [instance]
        new_reservation = Reservation()
        new_reservation.instances = [instance, new_instance]
        fake_ec2.should_receive('get_all_instances').and_return([]) \
          .and_return([reservation]).and_return([reservation]) \
          .and_return([new_reservation]).and_return([new_reservation])

        fake_ec2.should_receive('terminate_instances').and_return([instance])
        fake_ec2.should_receive('request_spot_instances')

        flexmock(boto.ec2)
        boto.ec2.should_receive('connect_to_region').and_return(fake_ec2)

        (flexmock(utils).should_receive('get_secret').and_return('secret'))
        (flexmock(utils).should_receive('sleep').and_return())
        (flexmock(utils).should_receive('get_random_alphanumeric').and_return(
            '0000000000'))
        (flexmock(utils).should_receive('write_key_file').and_return())
Example #21
0
    def setUp(self):
        (flexmock(EC2Connection).should_receive('get_key_pair').and_return(
            None))
        (flexmock(EC2Connection).should_receive('create_key_pair').with_args(
            'bookeyname').and_return(KeyPair()))
        (flexmock(EC2Connection).should_receive(
            'get_all_security_groups').and_return([]))
        (flexmock(
            EC2Connection).should_receive('create_security_group').with_args(
                'boogroup',
                'AppScale security group').and_return(SecurityGroup()))
        (flexmock(EC2Connection).should_receive(
            'authorize_security_group').and_return())
        (flexmock(EC2Connection).should_receive('run_instances').and_return())

        (flexmock(utils).should_receive('get_secret').and_return('secret'))
        (flexmock(utils).should_receive('sleep').and_return())
        (flexmock(utils).should_receive('get_random_alphanumeric').and_return(
            '0000000000'))
        (flexmock(utils).should_receive('write_key_file').and_return())
Example #22
0
                        grantGroup = None
                        if group_id:
                            grantGroup = groups[group_id]

                        if not module.check_mode:
                            group.authorize(rule['proto'], rule['from_port'], rule['to_port'], thisip, grantGroup)
                        changed = True

        # Finally, remove anything left in the groupRules -- these will be defunct rules
        if purge_rules:
            for (rule, grant) in groupRules.itervalues() :
                grantGroup = None
                if grant.group_id:
                    if grant.owner_id != group.owner_id:
                        # this is a foreign Security Group. Since you can't fetch it you must create an instance of it
                        group_instance = SecurityGroup(owner_id=grant.owner_id, name=grant.name, id=grant.group_id)
                        groups[grant.group_id] = group_instance
                        groups[grant.name] = group_instance
                    grantGroup = groups[grant.group_id]
                if not module.check_mode:
                    group.revoke(rule.ip_protocol, rule.from_port, rule.to_port, grant.cidr_ip, grantGroup)
                changed = True

        # Manage egress rules
        groupRules = {}
        addRulesToLookup(group.rules_egress, 'out', groupRules)

        # Now, go through all provided rules and ensure they are there.
        if rules_egress is not None:
            for rule in rules_egress:
                validate_rule(module, rule)
Example #23
0
def main():
    argument_spec = ec2_argument_spec()
    argument_spec.update(
        dict(
            name=dict(),
            group_id=dict(),
            description=dict(),
            vpc_id=dict(),
            rules=dict(type='list'),
            rules_egress=dict(type='list'),
            state=dict(default='present',
                       type='str',
                       choices=['present', 'absent']),
            purge_rules=dict(default=True, required=False, type='bool'),
            purge_rules_egress=dict(default=True, required=False, type='bool'),
        ))
    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        required_one_of=[['name', 'group_id']],
        required_if=[['state', 'present', ['name']]],
    )

    if not HAS_BOTO:
        module.fail_json(msg='boto required for this module')

    name = module.params['name']
    group_id = module.params['group_id']
    description = module.params['description']
    vpc_id = module.params['vpc_id']
    rules = deduplicate_rules_args(
        rules_expand_sources(rules_expand_ports(module.params['rules'])))
    rules_egress = deduplicate_rules_args(
        rules_expand_sources(rules_expand_ports(
            module.params['rules_egress'])))
    state = module.params.get('state')
    purge_rules = module.params['purge_rules']
    purge_rules_egress = module.params['purge_rules_egress']

    if state == 'present' and not description:
        module.fail_json(msg='Must provide description when state is present.')

    changed = False

    ec2 = ec2_connect(module)

    # find the group if present
    group = None
    groups = {}

    try:
        security_groups = ec2.get_all_security_groups()
    except BotoServerError as e:
        module.fail_json(msg="Error in get_all_security_groups: %s" %
                         e.message,
                         exception=traceback.format_exc())

    for curGroup in security_groups:
        groups[curGroup.id] = curGroup
        if curGroup.name in groups:
            # Prioritise groups from the current VPC
            if vpc_id is None or curGroup.vpc_id == vpc_id:
                groups[curGroup.name] = curGroup
        else:
            groups[curGroup.name] = curGroup

        if group_id:
            if curGroup.id == group_id:
                group = curGroup
        else:
            if curGroup.name == name and (vpc_id is None
                                          or curGroup.vpc_id == vpc_id):
                group = curGroup

    # Ensure requested group is absent
    if state == 'absent':
        if group:
            # found a match, delete it
            try:
                if not module.check_mode:
                    group.delete()
            except BotoServerError as e:
                module.fail_json(
                    msg="Unable to delete security group '%s' - %s" %
                    (group, e.message),
                    exception=traceback.format_exc())
            else:
                group = None
                changed = True
        else:
            # no match found, no changes required
            pass

    # Ensure requested group is present
    elif state == 'present':
        if group:
            # existing group
            if group.description != description:
                module.fail_json(
                    msg=
                    "Group description does not match existing group. ec2_group does not support this case."
                )

        # if the group doesn't exist, create it now
        else:
            # no match found, create it
            if not module.check_mode:
                group = ec2.create_security_group(name,
                                                  description,
                                                  vpc_id=vpc_id)

                # When a group is created, an egress_rule ALLOW ALL
                # to 0.0.0.0/0 is added automatically but it's not
                # reflected in the object returned by the AWS API
                # call. We re-read the group for getting an updated object
                # amazon sometimes takes a couple seconds to update the security group so wait till it exists
                while len(
                        ec2.get_all_security_groups(
                            filters={'group_id': group.id})) == 0:
                    time.sleep(0.1)

                group = ec2.get_all_security_groups(group_ids=(group.id, ))[0]
            changed = True
    else:
        module.fail_json(msg="Unsupported state requested: %s" % state)

    # create a lookup for all existing rules on the group
    if group:

        # Manage ingress rules
        groupRules = {}
        addRulesToLookup(group.rules, 'in', groupRules)

        # Now, go through all provided rules and ensure they are there.
        if rules is not None:
            for rule in rules:
                validate_rule(module, rule)

                group_id, ip, target_group_created = get_target_from_rule(
                    module, ec2, rule, name, group, groups, vpc_id)
                if target_group_created:
                    changed = True

                if rule['proto'] in ('all', '-1', -1):
                    rule['proto'] = -1
                    rule['from_port'] = None
                    rule['to_port'] = None

                # Convert ip to list we can iterate over
                if not isinstance(ip, list):
                    ip = [ip]

                # If rule already exists, don't later delete it
                for thisip in ip:
                    ruleId = make_rule_key('in', rule, group_id, thisip)
                    if ruleId not in groupRules:
                        grantGroup = None
                        if group_id:
                            grantGroup = groups[group_id]

                        if not module.check_mode:
                            group.authorize(rule['proto'], rule['from_port'],
                                            rule['to_port'], thisip,
                                            grantGroup)
                        changed = True
                    else:
                        del groupRules[ruleId]

        # Finally, remove anything left in the groupRules -- these will be defunct rules
        if purge_rules:
            for (rule, grant) in groupRules.values():
                grantGroup = None
                if grant.group_id:
                    if grant.owner_id != group.owner_id:
                        # this is a foreign Security Group. Since you can't fetch it you must create an instance of it
                        group_instance = SecurityGroup(owner_id=grant.owner_id,
                                                       name=grant.name,
                                                       id=grant.group_id)
                        groups[grant.group_id] = group_instance
                        groups[grant.name] = group_instance
                    grantGroup = groups[grant.group_id]
                if not module.check_mode:
                    group.revoke(rule.ip_protocol, rule.from_port,
                                 rule.to_port, grant.cidr_ip, grantGroup)
                changed = True

        # Manage egress rules
        groupRules = {}
        addRulesToLookup(group.rules_egress, 'out', groupRules)

        # Now, go through all provided rules and ensure they are there.
        if rules_egress is not None:
            for rule in rules_egress:
                validate_rule(module, rule)

                group_id, ip, target_group_created = get_target_from_rule(
                    module, ec2, rule, name, group, groups, vpc_id)
                if target_group_created:
                    changed = True

                if rule['proto'] in ('all', '-1', -1):
                    rule['proto'] = -1
                    rule['from_port'] = None
                    rule['to_port'] = None

                # Convert ip to list we can iterate over
                if not isinstance(ip, list):
                    ip = [ip]

                # If rule already exists, don't later delete it
                for thisip in ip:
                    ruleId = make_rule_key('out', rule, group_id, thisip)
                    if ruleId in groupRules:
                        del groupRules[ruleId]
                    # Otherwise, add new rule
                    else:
                        grantGroup = None
                        if group_id:
                            grantGroup = groups[group_id].id

                        if not module.check_mode:
                            ec2.authorize_security_group_egress(
                                group_id=group.id,
                                ip_protocol=rule['proto'],
                                from_port=rule['from_port'],
                                to_port=rule['to_port'],
                                src_group_id=grantGroup,
                                cidr_ip=thisip)
                        changed = True
        else:
            # when no egress rules are specified,
            # we add in a default allow all out rule, which was the
            # default behavior before egress rules were added
            default_egress_rule = 'out--1-None-None-None-0.0.0.0/0'
            if default_egress_rule not in groupRules:
                if not module.check_mode:
                    ec2.authorize_security_group_egress(group_id=group.id,
                                                        ip_protocol=-1,
                                                        from_port=None,
                                                        to_port=None,
                                                        src_group_id=None,
                                                        cidr_ip='0.0.0.0/0')
                changed = True
            else:
                # make sure the default egress rule is not removed
                del groupRules[default_egress_rule]

        # Finally, remove anything left in the groupRules -- these will be defunct rules
        if purge_rules_egress:
            for (rule, grant) in groupRules.values():
                grantGroup = None
                if grant.group_id:
                    grantGroup = groups[grant.group_id].id
                if not module.check_mode:
                    ec2.revoke_security_group_egress(
                        group_id=group.id,
                        ip_protocol=rule.ip_protocol,
                        from_port=rule.from_port,
                        to_port=rule.to_port,
                        src_group_id=grantGroup,
                        cidr_ip=grant.cidr_ip)
                changed = True

    if group:
        module.exit_json(changed=changed, group_id=group.id)
    else:
        module.exit_json(changed=changed, group_id=None)
def main():
    # Parse up the command line arguments.
    parser = argparse.ArgumentParser(description='Update haproxy to use all instances running in a security group.')
    parser.add_argument('--security-group', required=True)
    parser.add_argument('--access-key', required=True)
    parser.add_argument('--secret-key', required=True)
    parser.add_argument('--output', default='haproxy.cfg',
                        help='Defaults to haproxy.cfg if not specified.')
    parser.add_argument('--template', default='templates/haproxy.tpl')
    parser.add_argument('--haproxy', default='./haproxy',
                        help='The haproxy binary to call. Defaults to haproxy if not specified.')
    parser.add_argument('--pid', default='/var/run/haproxy.pid',
                        help='The pid file for haproxy. Defaults to /var/run/haproxy.pid.')
    args = parser.parse_args()

    # Wrap everytihg in a try block. Any exceptions and exit without changing
    # anything just to be safe.
    new_configuration = None
    try:
        # Create a connection to EC2.
        logging.debug('Connecting to EC2.')
        conn = EC2Connection(aws_access_key_id=args.access_key,
                             aws_secret_access_key=args.secret_key)
    
        # Get the security group.
        logging.debug('Fetching security group (%s).' % args.security_group)
        sg = SecurityGroup(connection=conn, name=args.security_group)
    
        # Fetch a list of all the instances in this security group.
        logging.debug('Getting instance.')
        instances = [i for i in sg.instances() if i.state == 'running']
    
        # Load in the existing config file contents.
        logging.debug('Locading existing configuration.')
        f = open(args.output, 'r')
        old_configuration = f.read()
        f.close()
    
        # Generate the new config from the template.
        logging.debug('Generating configuration for haproxy.')
        new_configuration = Template(filename=args.template).render(instances=instances)
    except:
        logging.error('Something went wrong! Exiting without making changes.')
        return False

    # See if this new config is different. If it is then restart using it.
    # Otherwise just delete the temporary file and do nothing.
    logging.debug('Comparing to existing configuration.')
    if old_configuration != new_configuration:
        logging.debug('Existing configuration is outdated.')

        # Overwite the real config file.
        logging.debug('Writing new configuration.')
        output = open(args.output, 'w')
        output.write(Template(filename=args.template).render(instances=instances))
        output.close()

        # Get PID if haproxy is already running.
        logging.debug('Fetching PID from %s.' % args.pid)
        pid = ''
        try:
            pidfile = open(args.pid, 'r')
            pid = pidfile.read()
            pidfile.close()
        except:
            logging.warn('Unable to read from %s. haproxy may not be running already.')

        # Restart haproxy.
        logging.debug('Restarting haproxy.')
        command = '''%s -p %s -f %s -sf %s''' % (args.haproxy, args.pid, args.output, pid)
        logging.debug('Executing: %s' % command)
        subprocess.call(command, shell=True)
    else:
        logging.debug('Existing configuration is up-to-date.')
Example #25
0
    def test_remove_rule_on_empty_group(self):
        # Remove a rule from a group with no rules
        sg = SecurityGroup()

        with self.assertRaises(ValueError):
            sg.remove_rule('ip', 80, 80, None, None, None, None, None)
Example #26
0
    def test_remove_rule_on_empty_group(self):
        # Remove a rule from a group with no rules
        sg = SecurityGroup()

        with self.assertRaises(ValueError):
            sg.remove_rule('ip', 80, 80, None, None, None, None, None)