Skip to content
This repository has been archived by the owner. It is now read-only.

Commit

Permalink
Merge pull request #114 from zalando-stups/ignore-missing-ami
Browse files Browse the repository at this point in the history
Ignore missing AMI for new regions
  • Loading branch information
mikkeloscar authored Oct 25, 2021
2 parents 57fb3c0 + becb7bc commit 7463a3c
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 115 deletions.
6 changes: 4 additions & 2 deletions delivery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ version: "2017-09-20"
pipeline:
- id: build
type: script
overlay: ci/python
overlay: guild-python/latest
env:
PYENV_VERSION: "3.9"
commands:
- desc: "Install dependencies"
cmd: |
Expand All @@ -11,7 +13,7 @@ pipeline:
- desc: "Run Tests"
cmd: python3 setup.py test
- desc: "Check code style"
cmd: python3 setup.py flake8
cmd: flake8
- desc: "Build docker image that will upload package"
cmd: |
VERSION=$(./next-version)
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ PyYAML
PyJWT>=2.0, <3.0
stups-zign>=1.1.26
setuptools>=30
flake8
3 changes: 3 additions & 0 deletions sevenseconds/config/bastion.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ def configure_bastion_host(account: AccountData, vpc: object, region: str, base_
enable_bastion = account.config.get("enable_odd", False)
re_deploy = account.config['bastion'].get('re_deploy', account.options.get('redeploy_odd_host'))

if not base_ami_id:
enable_bastion = False

bastion_version = None
if account.config['bastion'].get('version_url'):
with ActionOnExit('Get last Tag for Bastion Image...') as act:
Expand Down
13 changes: 7 additions & 6 deletions sevenseconds/config/vpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,13 @@ def configure_vpc(account: AccountData, region, base_ami_id):
{'Key': 'LastUpdate', 'Value': time.strftime('%Y-%m-%dT%H:%M:%S%z')}
]
for key, val in account.config.get('vpc', {}).get('tags', {}).items():
tags.append({
'Key': key,
'Value': val.replace('{{ami_id}}', base_ami_id).replace(
'{{base_ami_config}}',
json.dumps(account.config.get('base_ami'), sort_keys=True))
})
if base_ami_id:
tags.append({
'Key': key,
'Value': val.replace('{{ami_id}}', base_ami_id).replace(
'{{base_ami_config}}',
json.dumps(account.config.get('base_ami'), sort_keys=True))
})
vpc.create_tags(Tags=tags)
vpc.modify_attribute(EnableDnsSupport={'Value': True})
vpc.modify_attribute(EnableDnsHostnames={'Value': True})
Expand Down
173 changes: 85 additions & 88 deletions tests/test_aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,164 +3,161 @@
from sevenseconds.helper.aws import get_account_id, get_az_names
from sevenseconds.config.cloudtrail import configure_cloudtrail
from sevenseconds.config.s3 import configure_s3_buckets
from datetime import datetime
import botocore.exceptions


def test_get_account_id(monkeypatch):
sts = MagicMock(get_caller_identity=lambda: {'Account': '01234567',
'Arn': 'arn:aws:iam::01234567:assumed-role/Administrator/sevenseconds',
'UserId': 'ABCDEFGHIJKLMNOPQ:sevenseconds'})
sts = MagicMock(
get_caller_identity=lambda: {
"Account": "01234567",
"Arn": "arn:aws:iam::01234567:assumed-role/Administrator/sevenseconds",
"UserId": "ABCDEFGHIJKLMNOPQ:sevenseconds",
}
)
session = MagicMock(client=MagicMock(return_value=sts))
id = get_account_id(session)
assert id == '01234567', 'ID from current User'
assert id == "01234567", "ID from current User"


def test_get_az_names(monkeypatch):
conn = MagicMock(describe_availability_zones=lambda **kargs: {
'AvailabilityZones': [
{
'ZoneName': 'eu-west-1a',
'RegionName': 'eu-west-1',
'State': 'available',
'Messages': []
}, {
'ZoneName': 'eu-west-1b',
'RegionName': 'eu-west-1',
'State': 'available',
'Messages': []
}, {
'ZoneName': 'eu-west-1c',
'RegionName': 'eu-west-1',
'State': 'available',
'Messages': []
}]})
conn = MagicMock(
describe_availability_zones=lambda **kargs: {
"AvailabilityZones": [
{"ZoneName": "eu-west-1a", "RegionName": "eu-west-1", "State": "available", "Messages": []},
{"ZoneName": "eu-west-1b", "RegionName": "eu-west-1", "State": "available", "Messages": []},
{"ZoneName": "eu-west-1c", "RegionName": "eu-west-1", "State": "available", "Messages": []},
]
}
)
session = MagicMock(client=MagicMock(return_value=conn))
names = get_az_names(session, 'eu-west-1')
assert 'eu-west-1b' in names, 'AZ found'
names = get_az_names(session, "eu-west-1")
assert "eu-west-1b" in names, "AZ found"

conn = MagicMock(describe_availability_zones=lambda **kargs: {
'AvailabilityZones': []})
conn = MagicMock(describe_availability_zones=lambda **kargs: {"AvailabilityZones": []})
session = MagicMock(client=MagicMock(return_value=conn))
names = get_az_names(session, 'eu-west-1')
assert 'eu-west-1b' in names, 'AZ found from Cache'
names = get_az_names(session, "eu-west-1")
assert "eu-west-1b" in names, "AZ found from Cache"


def test_configure_cloudtrail(monkeypatch):
def myinfo(text):
assert 'Found no Cloudtrail Section in Configfile.' in text
assert "Found no Cloudtrail Section in Configfile." in text

monkeypatch.setattr('clickclick.info', myinfo)
account = MagicMock(name='name',
config={})
monkeypatch.setattr("clickclick.info", myinfo)
account = MagicMock(name="name", config={})
configure_cloudtrail(account)

class _test:
def _only_kwargs(f):
def _filter(*args, **kwargs):
if args or len(kwargs) == 0:
raise TypeError('{} only accepts keyword arguments.'.format(f.__name__))
raise TypeError("{} only accepts keyword arguments.".format(f.__name__))
return f(**kwargs)

return _filter

def describe_trails():
return {
'trailList': [
"trailList": [
{
'IncludeGlobalServiceEvents': True,
'Name': 'Default',
'S3BucketName': 'bucketname',
'S3KeyPrefix': ''
}]}
"IncludeGlobalServiceEvents": True,
"Name": "Default",
"S3BucketName": "bucketname",
"S3KeyPrefix": "",
}
]
}

@_only_kwargs
def update_trail(Name, S3KeyPrefix, S3BucketName, IncludeGlobalServiceEvents, **kwargs):
assert Name == 'Default', 'update Default'
assert S3BucketName == 'bucketname', 'set bucketname'
assert S3KeyPrefix == '', 'set directory prefix'
assert IncludeGlobalServiceEvents is True, 'Include global'
assert Name == "Default", "update Default"
assert S3BucketName == "bucketname", "set bucketname"
assert S3KeyPrefix == "", "set directory prefix"
assert IncludeGlobalServiceEvents is True, "Include global"

@_only_kwargs
def create_trail(Name, S3KeyPrefix, S3BucketName, IncludeGlobalServiceEvents, **kwargs):
assert Name == 'Default', 'update Default'
assert S3BucketName == 'bucketname', 'set bucketname'
assert S3KeyPrefix == '', 'set directory prefix'
assert IncludeGlobalServiceEvents is True, 'Include global'
assert Name == "Default", "update Default"
assert S3BucketName == "bucketname", "set bucketname"
assert S3KeyPrefix == "", "set directory prefix"
assert IncludeGlobalServiceEvents is True, "Include global"

@_only_kwargs
def start_logging(Name):
assert Name == 'Default', 'start logging for Default'
assert Name == "Default", "start logging for Default"

@_only_kwargs
def stop_logging(Name):
assert Name == 'wrongconfig', 'stop wrong configuration'
assert Name == "wrongconfig", "stop wrong configuration"

@_only_kwargs
def delete_trail(Name):
assert Name == 'wrongconfig', 'remove wrong configuration'
assert Name == "wrongconfig", "remove wrong configuration"

@_only_kwargs
def get_trail_status(Name):
return {'IsLogging': True}
return {"IsLogging": True}

account = MagicMock(name='name',
config={'cloudtrail': {'s3_bucket_name': 'bucketname', 's3_key_prefix': ''}},
client=MagicMock(return_value=_test))
account = MagicMock(
name="name",
config={"cloudtrail": {"s3_bucket_name": "bucketname", "s3_key_prefix": ""}},
client=MagicMock(return_value=_test),
)
configure_cloudtrail(account)
_test.get_trail_status = lambda Name: {'IsLogging': False}
_test.get_trail_status = lambda Name: {"IsLogging": False}
configure_cloudtrail(account)
_test.get_trail_status = lambda Name: {'IsLogging': True}
_test.get_trail_status = lambda Name: {"IsLogging": True}
_test.describe_trails = lambda: {
'trailList': [
"trailList": [
{
'IncludeGlobalServiceEvents': False,
'Name': 'Default',
'S3BucketName': 'oldbucketname',
'S3KeyPrefix': 'dummy'
}]}
"IncludeGlobalServiceEvents": False,
"Name": "Default",
"S3BucketName": "oldbucketname",
"S3KeyPrefix": "dummy",
}
]
}
configure_cloudtrail(account)
_test.describe_trails = lambda: {
'trailList': [
"trailList": [
{
'IncludeGlobalServiceEvents': False,
'Name': 'wrongconfig',
'S3BucketName': 'oldbucketname',
'S3KeyPrefix': 'dummy'
}]}
"IncludeGlobalServiceEvents": False,
"Name": "wrongconfig",
"S3BucketName": "oldbucketname",
"S3KeyPrefix": "dummy",
}
]
}
configure_cloudtrail(account)


def test_configure_s3_buckets():
config = {
's3_buckets': {
'bucket-1': {
'name': 'bucket-1',
'regions': ['eu-central-1'],
'lifecycle_configuration': {'Rules': [{'x': 'y'}]},
'encryption_config': {'Rules': [{'a': 'b'}]},
'tags': {'foo': 'bar', 'bee': 'baz'}
"s3_buckets": {
"bucket-1": {
"name": "bucket-1",
"regions": ["eu-central-1"],
"lifecycle_configuration": {"Rules": [{"x": "y"}]},
"encryption_config": {"Rules": [{"a": "b"}]},
"tags": {"foo": "bar", "bee": "baz"},
}
}
}
account = MagicMock(config=config)
s3 = account.session.resource('s3', 'eu-central-1')
bucket = s3.Bucket('bucket-1')
s3 = account.session.resource("s3", "eu-central-1")
bucket = s3.Bucket("bucket-1")
bucket.creation_date = None

configure_s3_buckets(account)

bucket.create.assert_called_once()
s3.BucketLifecycle('bucket-1').put.assert_called_once_with(
LifecycleConfiguration={'Rules': [{'x': 'y'}]})
s3.BucketLifecycle("bucket-1").put.assert_called_once_with(LifecycleConfiguration={"Rules": [{"x": "y"}]})
s3.meta.client.put_bucket_encryption.assert_called_once_with(
Bucket='bucket-1',
ServerSideEncryptionConfiguration={'Rules': [{'a': 'b'}]})
Bucket="bucket-1", ServerSideEncryptionConfiguration={"Rules": [{"a": "b"}]}
)
bucket.Tagging().put.assert_called_once_with(
Tagging={'TagSet': [
{'Key': 'foo', 'Value': 'bar'},
{'Key': 'bee', 'Value': 'baz'}
]})
Tagging={"TagSet": [{"Key": "foo", "Value": "bar"}, {"Key": "bee", "Value": "baz"}]}
)


if __name__ == '__main__':
if __name__ == "__main__":
pytest.main()
34 changes: 15 additions & 19 deletions tests/test_iam.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,21 @@

SAMPLE_ROLES = {
"Shibboleth-Administrator": {
"attached_policies": [
"arn:aws:iam::aws:policy/AdminDefaultPolicy"
],
"attached_policies": ["arn:aws:iam::aws:policy/AdminDefaultPolicy"],
"policy": {
"Statement": [
{"Effect": "Allow", "Resource": "Test", "Action": "foo:*"},
{"Effect": "Deny", "Resource": "Test", "Action": "bar:*"},
]
}
},
},
"Shibboleth-PowerUser": {
"attached_policies": [
"arn:aws:iam::aws:policy/PowerUserDefaultPolicy"
],
"attached_policies": ["arn:aws:iam::aws:policy/PowerUserDefaultPolicy"],
"policy": {
"Statement": [{"Effect": "Allow", "Resource": "Test", "Action": "baz:*"},]
}
"Statement": [
{"Effect": "Allow", "Resource": "Test", "Action": "baz:*"},
]
},
},
}

Expand Down Expand Up @@ -50,27 +48,25 @@ def test_effective_policies_merge():
}
expected = {
"Shibboleth-Administrator": {
"attached_policies": [
"arn:aws:iam::aws:policy/AdminDefaultPolicy"
],
"attached_policies": ["arn:aws:iam::aws:policy/AdminDefaultPolicy"],
"policy": {
"Statement": [
{"Effect": "Allow", "Resource": "Test", "Action": "foo:*"},
{"Effect": "Deny", "Resource": "Test", "Action": "bar:*"},
{"Effect": "Allow", "Resource": "Additional", "Action": "test:*"},
{"Effect": "Deny", "Resource": "Additional", "Action": "abc:*"},
]
}
},
},
"Shibboleth-PowerUser": {
"attached_policies": [
"arn:aws:iam::aws:policy/PowerUserDefaultPolicy",
"arn:aws:iam::aws:policy/PowerUserDefaultPolicy",
],
"policy": {
"Statement": [
{"Effect": "Allow", "Resource": "Test", "Action": "baz:*"},
]
}
},
},
}

Expand All @@ -90,14 +86,14 @@ def test_effective_attached_policies_merge():
"arn:aws:iam::aws:policy/AdminDefaultPolicy",
],
"Shibboleth-PowerUser": [
"arn:aws:iam::aws:policy/PowerUserDefaultPolicy",
"arn:aws:iam::aws:policy/PowerUserDefaultPolicy",
"arn:aws:iam::aws:policy/PolicyA",
"arn:aws:iam::aws:policy/PolicyB"
]
"arn:aws:iam::aws:policy/PolicyB",
],
}

for role_name, role_cfg in SAMPLE_ROLES.items():
assert expected[role_name] == iam.effective_attached_policies(config, role_name,role_cfg)
assert expected[role_name] == iam.effective_attached_policies(config, role_name, role_cfg)


@pytest.mark.parametrize(
Expand Down

0 comments on commit 7463a3c

Please sign in to comment.