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'])
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
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
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
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
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())
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 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)
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())
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())
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
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
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
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())
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())
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())
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)
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.')
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)