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

Commit 7463a3c

Browse files
authored
Merge pull request #114 from zalando-stups/ignore-missing-ami
Ignore missing AMI for new regions
2 parents 57fb3c0 + becb7bc commit 7463a3c

File tree

6 files changed

+115
-115
lines changed

6 files changed

+115
-115
lines changed

delivery.yaml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ version: "2017-09-20"
22
pipeline:
33
- id: build
44
type: script
5-
overlay: ci/python
5+
overlay: guild-python/latest
6+
env:
7+
PYENV_VERSION: "3.9"
68
commands:
79
- desc: "Install dependencies"
810
cmd: |
@@ -11,7 +13,7 @@ pipeline:
1113
- desc: "Run Tests"
1214
cmd: python3 setup.py test
1315
- desc: "Check code style"
14-
cmd: python3 setup.py flake8
16+
cmd: flake8
1517
- desc: "Build docker image that will upload package"
1618
cmd: |
1719
VERSION=$(./next-version)

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ PyYAML
1111
PyJWT>=2.0, <3.0
1212
stups-zign>=1.1.26
1313
setuptools>=30
14+
flake8

sevenseconds/config/bastion.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ def configure_bastion_host(account: AccountData, vpc: object, region: str, base_
2222
enable_bastion = account.config.get("enable_odd", False)
2323
re_deploy = account.config['bastion'].get('re_deploy', account.options.get('redeploy_odd_host'))
2424

25+
if not base_ami_id:
26+
enable_bastion = False
27+
2528
bastion_version = None
2629
if account.config['bastion'].get('version_url'):
2730
with ActionOnExit('Get last Tag for Bastion Image...') as act:

sevenseconds/config/vpc.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,13 @@ def configure_vpc(account: AccountData, region, base_ami_id):
5656
{'Key': 'LastUpdate', 'Value': time.strftime('%Y-%m-%dT%H:%M:%S%z')}
5757
]
5858
for key, val in account.config.get('vpc', {}).get('tags', {}).items():
59-
tags.append({
60-
'Key': key,
61-
'Value': val.replace('{{ami_id}}', base_ami_id).replace(
62-
'{{base_ami_config}}',
63-
json.dumps(account.config.get('base_ami'), sort_keys=True))
64-
})
59+
if base_ami_id:
60+
tags.append({
61+
'Key': key,
62+
'Value': val.replace('{{ami_id}}', base_ami_id).replace(
63+
'{{base_ami_config}}',
64+
json.dumps(account.config.get('base_ami'), sort_keys=True))
65+
})
6566
vpc.create_tags(Tags=tags)
6667
vpc.modify_attribute(EnableDnsSupport={'Value': True})
6768
vpc.modify_attribute(EnableDnsHostnames={'Value': True})

tests/test_aws.py

Lines changed: 85 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -3,164 +3,161 @@
33
from sevenseconds.helper.aws import get_account_id, get_az_names
44
from sevenseconds.config.cloudtrail import configure_cloudtrail
55
from sevenseconds.config.s3 import configure_s3_buckets
6-
from datetime import datetime
7-
import botocore.exceptions
86

97

108
def test_get_account_id(monkeypatch):
11-
sts = MagicMock(get_caller_identity=lambda: {'Account': '01234567',
12-
'Arn': 'arn:aws:iam::01234567:assumed-role/Administrator/sevenseconds',
13-
'UserId': 'ABCDEFGHIJKLMNOPQ:sevenseconds'})
9+
sts = MagicMock(
10+
get_caller_identity=lambda: {
11+
"Account": "01234567",
12+
"Arn": "arn:aws:iam::01234567:assumed-role/Administrator/sevenseconds",
13+
"UserId": "ABCDEFGHIJKLMNOPQ:sevenseconds",
14+
}
15+
)
1416
session = MagicMock(client=MagicMock(return_value=sts))
1517
id = get_account_id(session)
16-
assert id == '01234567', 'ID from current User'
18+
assert id == "01234567", "ID from current User"
1719

1820

1921
def test_get_az_names(monkeypatch):
20-
conn = MagicMock(describe_availability_zones=lambda **kargs: {
21-
'AvailabilityZones': [
22-
{
23-
'ZoneName': 'eu-west-1a',
24-
'RegionName': 'eu-west-1',
25-
'State': 'available',
26-
'Messages': []
27-
}, {
28-
'ZoneName': 'eu-west-1b',
29-
'RegionName': 'eu-west-1',
30-
'State': 'available',
31-
'Messages': []
32-
}, {
33-
'ZoneName': 'eu-west-1c',
34-
'RegionName': 'eu-west-1',
35-
'State': 'available',
36-
'Messages': []
37-
}]})
22+
conn = MagicMock(
23+
describe_availability_zones=lambda **kargs: {
24+
"AvailabilityZones": [
25+
{"ZoneName": "eu-west-1a", "RegionName": "eu-west-1", "State": "available", "Messages": []},
26+
{"ZoneName": "eu-west-1b", "RegionName": "eu-west-1", "State": "available", "Messages": []},
27+
{"ZoneName": "eu-west-1c", "RegionName": "eu-west-1", "State": "available", "Messages": []},
28+
]
29+
}
30+
)
3831
session = MagicMock(client=MagicMock(return_value=conn))
39-
names = get_az_names(session, 'eu-west-1')
40-
assert 'eu-west-1b' in names, 'AZ found'
32+
names = get_az_names(session, "eu-west-1")
33+
assert "eu-west-1b" in names, "AZ found"
4134

42-
conn = MagicMock(describe_availability_zones=lambda **kargs: {
43-
'AvailabilityZones': []})
35+
conn = MagicMock(describe_availability_zones=lambda **kargs: {"AvailabilityZones": []})
4436
session = MagicMock(client=MagicMock(return_value=conn))
45-
names = get_az_names(session, 'eu-west-1')
46-
assert 'eu-west-1b' in names, 'AZ found from Cache'
37+
names = get_az_names(session, "eu-west-1")
38+
assert "eu-west-1b" in names, "AZ found from Cache"
4739

4840

4941
def test_configure_cloudtrail(monkeypatch):
5042
def myinfo(text):
51-
assert 'Found no Cloudtrail Section in Configfile.' in text
43+
assert "Found no Cloudtrail Section in Configfile." in text
5244

53-
monkeypatch.setattr('clickclick.info', myinfo)
54-
account = MagicMock(name='name',
55-
config={})
45+
monkeypatch.setattr("clickclick.info", myinfo)
46+
account = MagicMock(name="name", config={})
5647
configure_cloudtrail(account)
5748

5849
class _test:
5950
def _only_kwargs(f):
6051
def _filter(*args, **kwargs):
6152
if args or len(kwargs) == 0:
62-
raise TypeError('{} only accepts keyword arguments.'.format(f.__name__))
53+
raise TypeError("{} only accepts keyword arguments.".format(f.__name__))
6354
return f(**kwargs)
55+
6456
return _filter
6557

6658
def describe_trails():
6759
return {
68-
'trailList': [
60+
"trailList": [
6961
{
70-
'IncludeGlobalServiceEvents': True,
71-
'Name': 'Default',
72-
'S3BucketName': 'bucketname',
73-
'S3KeyPrefix': ''
74-
}]}
62+
"IncludeGlobalServiceEvents": True,
63+
"Name": "Default",
64+
"S3BucketName": "bucketname",
65+
"S3KeyPrefix": "",
66+
}
67+
]
68+
}
7569

7670
@_only_kwargs
7771
def update_trail(Name, S3KeyPrefix, S3BucketName, IncludeGlobalServiceEvents, **kwargs):
78-
assert Name == 'Default', 'update Default'
79-
assert S3BucketName == 'bucketname', 'set bucketname'
80-
assert S3KeyPrefix == '', 'set directory prefix'
81-
assert IncludeGlobalServiceEvents is True, 'Include global'
72+
assert Name == "Default", "update Default"
73+
assert S3BucketName == "bucketname", "set bucketname"
74+
assert S3KeyPrefix == "", "set directory prefix"
75+
assert IncludeGlobalServiceEvents is True, "Include global"
8276

8377
@_only_kwargs
8478
def create_trail(Name, S3KeyPrefix, S3BucketName, IncludeGlobalServiceEvents, **kwargs):
85-
assert Name == 'Default', 'update Default'
86-
assert S3BucketName == 'bucketname', 'set bucketname'
87-
assert S3KeyPrefix == '', 'set directory prefix'
88-
assert IncludeGlobalServiceEvents is True, 'Include global'
79+
assert Name == "Default", "update Default"
80+
assert S3BucketName == "bucketname", "set bucketname"
81+
assert S3KeyPrefix == "", "set directory prefix"
82+
assert IncludeGlobalServiceEvents is True, "Include global"
8983

9084
@_only_kwargs
9185
def start_logging(Name):
92-
assert Name == 'Default', 'start logging for Default'
86+
assert Name == "Default", "start logging for Default"
9387

9488
@_only_kwargs
9589
def stop_logging(Name):
96-
assert Name == 'wrongconfig', 'stop wrong configuration'
90+
assert Name == "wrongconfig", "stop wrong configuration"
9791

9892
@_only_kwargs
9993
def delete_trail(Name):
100-
assert Name == 'wrongconfig', 'remove wrong configuration'
94+
assert Name == "wrongconfig", "remove wrong configuration"
10195

10296
@_only_kwargs
10397
def get_trail_status(Name):
104-
return {'IsLogging': True}
98+
return {"IsLogging": True}
10599

106-
account = MagicMock(name='name',
107-
config={'cloudtrail': {'s3_bucket_name': 'bucketname', 's3_key_prefix': ''}},
108-
client=MagicMock(return_value=_test))
100+
account = MagicMock(
101+
name="name",
102+
config={"cloudtrail": {"s3_bucket_name": "bucketname", "s3_key_prefix": ""}},
103+
client=MagicMock(return_value=_test),
104+
)
109105
configure_cloudtrail(account)
110-
_test.get_trail_status = lambda Name: {'IsLogging': False}
106+
_test.get_trail_status = lambda Name: {"IsLogging": False}
111107
configure_cloudtrail(account)
112-
_test.get_trail_status = lambda Name: {'IsLogging': True}
108+
_test.get_trail_status = lambda Name: {"IsLogging": True}
113109
_test.describe_trails = lambda: {
114-
'trailList': [
110+
"trailList": [
115111
{
116-
'IncludeGlobalServiceEvents': False,
117-
'Name': 'Default',
118-
'S3BucketName': 'oldbucketname',
119-
'S3KeyPrefix': 'dummy'
120-
}]}
112+
"IncludeGlobalServiceEvents": False,
113+
"Name": "Default",
114+
"S3BucketName": "oldbucketname",
115+
"S3KeyPrefix": "dummy",
116+
}
117+
]
118+
}
121119
configure_cloudtrail(account)
122120
_test.describe_trails = lambda: {
123-
'trailList': [
121+
"trailList": [
124122
{
125-
'IncludeGlobalServiceEvents': False,
126-
'Name': 'wrongconfig',
127-
'S3BucketName': 'oldbucketname',
128-
'S3KeyPrefix': 'dummy'
129-
}]}
123+
"IncludeGlobalServiceEvents": False,
124+
"Name": "wrongconfig",
125+
"S3BucketName": "oldbucketname",
126+
"S3KeyPrefix": "dummy",
127+
}
128+
]
129+
}
130130
configure_cloudtrail(account)
131131

132132

133133
def test_configure_s3_buckets():
134134
config = {
135-
's3_buckets': {
136-
'bucket-1': {
137-
'name': 'bucket-1',
138-
'regions': ['eu-central-1'],
139-
'lifecycle_configuration': {'Rules': [{'x': 'y'}]},
140-
'encryption_config': {'Rules': [{'a': 'b'}]},
141-
'tags': {'foo': 'bar', 'bee': 'baz'}
135+
"s3_buckets": {
136+
"bucket-1": {
137+
"name": "bucket-1",
138+
"regions": ["eu-central-1"],
139+
"lifecycle_configuration": {"Rules": [{"x": "y"}]},
140+
"encryption_config": {"Rules": [{"a": "b"}]},
141+
"tags": {"foo": "bar", "bee": "baz"},
142142
}
143143
}
144144
}
145145
account = MagicMock(config=config)
146-
s3 = account.session.resource('s3', 'eu-central-1')
147-
bucket = s3.Bucket('bucket-1')
146+
s3 = account.session.resource("s3", "eu-central-1")
147+
bucket = s3.Bucket("bucket-1")
148148
bucket.creation_date = None
149149

150150
configure_s3_buckets(account)
151151

152152
bucket.create.assert_called_once()
153-
s3.BucketLifecycle('bucket-1').put.assert_called_once_with(
154-
LifecycleConfiguration={'Rules': [{'x': 'y'}]})
153+
s3.BucketLifecycle("bucket-1").put.assert_called_once_with(LifecycleConfiguration={"Rules": [{"x": "y"}]})
155154
s3.meta.client.put_bucket_encryption.assert_called_once_with(
156-
Bucket='bucket-1',
157-
ServerSideEncryptionConfiguration={'Rules': [{'a': 'b'}]})
155+
Bucket="bucket-1", ServerSideEncryptionConfiguration={"Rules": [{"a": "b"}]}
156+
)
158157
bucket.Tagging().put.assert_called_once_with(
159-
Tagging={'TagSet': [
160-
{'Key': 'foo', 'Value': 'bar'},
161-
{'Key': 'bee', 'Value': 'baz'}
162-
]})
158+
Tagging={"TagSet": [{"Key": "foo", "Value": "bar"}, {"Key": "bee", "Value": "baz"}]}
159+
)
163160

164161

165-
if __name__ == '__main__':
162+
if __name__ == "__main__":
166163
pytest.main()

tests/test_iam.py

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,21 @@
44

55
SAMPLE_ROLES = {
66
"Shibboleth-Administrator": {
7-
"attached_policies": [
8-
"arn:aws:iam::aws:policy/AdminDefaultPolicy"
9-
],
7+
"attached_policies": ["arn:aws:iam::aws:policy/AdminDefaultPolicy"],
108
"policy": {
119
"Statement": [
1210
{"Effect": "Allow", "Resource": "Test", "Action": "foo:*"},
1311
{"Effect": "Deny", "Resource": "Test", "Action": "bar:*"},
1412
]
15-
}
13+
},
1614
},
1715
"Shibboleth-PowerUser": {
18-
"attached_policies": [
19-
"arn:aws:iam::aws:policy/PowerUserDefaultPolicy"
20-
],
16+
"attached_policies": ["arn:aws:iam::aws:policy/PowerUserDefaultPolicy"],
2117
"policy": {
22-
"Statement": [{"Effect": "Allow", "Resource": "Test", "Action": "baz:*"},]
23-
}
18+
"Statement": [
19+
{"Effect": "Allow", "Resource": "Test", "Action": "baz:*"},
20+
]
21+
},
2422
},
2523
}
2624

@@ -50,27 +48,25 @@ def test_effective_policies_merge():
5048
}
5149
expected = {
5250
"Shibboleth-Administrator": {
53-
"attached_policies": [
54-
"arn:aws:iam::aws:policy/AdminDefaultPolicy"
55-
],
51+
"attached_policies": ["arn:aws:iam::aws:policy/AdminDefaultPolicy"],
5652
"policy": {
5753
"Statement": [
5854
{"Effect": "Allow", "Resource": "Test", "Action": "foo:*"},
5955
{"Effect": "Deny", "Resource": "Test", "Action": "bar:*"},
6056
{"Effect": "Allow", "Resource": "Additional", "Action": "test:*"},
6157
{"Effect": "Deny", "Resource": "Additional", "Action": "abc:*"},
6258
]
63-
}
59+
},
6460
},
6561
"Shibboleth-PowerUser": {
6662
"attached_policies": [
67-
"arn:aws:iam::aws:policy/PowerUserDefaultPolicy",
63+
"arn:aws:iam::aws:policy/PowerUserDefaultPolicy",
6864
],
6965
"policy": {
7066
"Statement": [
7167
{"Effect": "Allow", "Resource": "Test", "Action": "baz:*"},
7268
]
73-
}
69+
},
7470
},
7571
}
7672

@@ -90,14 +86,14 @@ def test_effective_attached_policies_merge():
9086
"arn:aws:iam::aws:policy/AdminDefaultPolicy",
9187
],
9288
"Shibboleth-PowerUser": [
93-
"arn:aws:iam::aws:policy/PowerUserDefaultPolicy",
89+
"arn:aws:iam::aws:policy/PowerUserDefaultPolicy",
9490
"arn:aws:iam::aws:policy/PolicyA",
95-
"arn:aws:iam::aws:policy/PolicyB"
96-
]
91+
"arn:aws:iam::aws:policy/PolicyB",
92+
],
9793
}
9894

9995
for role_name, role_cfg in SAMPLE_ROLES.items():
100-
assert expected[role_name] == iam.effective_attached_policies(config, role_name,role_cfg)
96+
assert expected[role_name] == iam.effective_attached_policies(config, role_name, role_cfg)
10197

10298

10399
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)