Add opsworks app mocks (#1481)

* Add implementation for OpsWorks create_app and describe_apps

* Fix the name of the test

* Add some more exception tests
This commit is contained in:
Loukas Leontopoulos 2018-03-21 18:05:57 +02:00 committed by Jack Danger
parent fceeb5d55f
commit b7ae704ad2
3 changed files with 227 additions and 0 deletions

View File

@ -398,11 +398,82 @@ class Stack(BaseModel):
return response
class App(BaseModel):
def __init__(self, stack_id, name, type,
shortname=None,
description=None,
datasources=None,
app_source=None,
domains=None,
enable_ssl=False,
ssl_configuration=None,
attributes=None,
environment=None):
self.stack_id = stack_id
self.name = name
self.type = type
self.shortname = shortname
self.description = description
self.datasources = datasources
if datasources is None:
self.datasources = []
self.app_source = app_source
if app_source is None:
self.app_source = {}
self.domains = domains
if domains is None:
self.domains = []
self.enable_ssl = enable_ssl
self.ssl_configuration = ssl_configuration
if ssl_configuration is None:
self.ssl_configuration = {}
self.attributes = attributes
if attributes is None:
self.attributes = {}
self.environment = environment
if environment is None:
self.environment = {}
self.id = "{0}".format(uuid.uuid4())
self.created_at = datetime.datetime.utcnow()
def __eq__(self, other):
return self.id == other.id
def to_dict(self):
d = {
"AppId": self.id,
"AppSource": self.app_source,
"Attributes": self.attributes,
"CreatedAt": self.created_at.isoformat(),
"Datasources": self.datasources,
"Description": self.description,
"Domains": self.domains,
"EnableSsl": self.enable_ssl,
"Environment": self.environment,
"Name": self.name,
"Shortname": self.shortname,
"SslConfiguration": self.ssl_configuration,
"StackId": self.stack_id,
"Type": self.type
}
return d
class OpsWorksBackend(BaseBackend):
def __init__(self, ec2_backend):
self.stacks = {}
self.layers = {}
self.apps = {}
self.instances = {}
self.ec2_backend = ec2_backend
@ -435,6 +506,20 @@ class OpsWorksBackend(BaseBackend):
self.stacks[stackid].layers.append(layer)
return layer
def create_app(self, **kwargs):
name = kwargs['name']
stackid = kwargs['stack_id']
if stackid not in self.stacks:
raise ResourceNotFoundException(stackid)
if name in [a.name for a in self.stacks[stackid].apps]:
raise ValidationException(
'There is already an app named "{0}" '
'for this stack'.format(name))
app = App(**kwargs)
self.apps[app.id] = app
self.stacks[stackid].apps.append(app)
return app
def create_instance(self, **kwargs):
stack_id = kwargs['stack_id']
layer_ids = kwargs['layer_ids']
@ -502,6 +587,22 @@ class OpsWorksBackend(BaseBackend):
raise ResourceNotFoundException(", ".join(unknown_layers))
return [self.layers[id].to_dict() for id in layer_ids]
def describe_apps(self, stack_id, app_ids):
if stack_id is not None and app_ids is not None:
raise ValidationException(
"Please provide one or more app IDs or a stack ID"
)
if stack_id is not None:
if stack_id not in self.stacks:
raise ResourceNotFoundException(
"Unable to find stack with ID {0}".format(stack_id))
return [app.to_dict() for app in self.stacks[stack_id].apps]
unknown_apps = set(app_ids) - set(self.apps.keys())
if unknown_apps:
raise ResourceNotFoundException(", ".join(unknown_apps))
return [self.apps[id].to_dict() for id in app_ids]
def describe_instances(self, instance_ids, layer_id, stack_id):
if len(list(filter(None, (instance_ids, layer_id, stack_id)))) != 1:
raise ValidationException("Please provide either one or more "

View File

@ -75,6 +75,24 @@ class OpsWorksResponse(BaseResponse):
layer = self.opsworks_backend.create_layer(**kwargs)
return json.dumps({"LayerId": layer.id}, indent=1)
def create_app(self):
kwargs = dict(
stack_id=self.parameters.get('StackId'),
name=self.parameters.get('Name'),
type=self.parameters.get('Type'),
shortname=self.parameters.get('Shortname'),
description=self.parameters.get('Description'),
datasources=self.parameters.get('DataSources'),
app_source=self.parameters.get('AppSource'),
domains=self.parameters.get('Domains'),
enable_ssl=self.parameters.get('EnableSsl'),
ssl_configuration=self.parameters.get('SslConfiguration'),
attributes=self.parameters.get('Attributes'),
environment=self.parameters.get('Environment')
)
app = self.opsworks_backend.create_app(**kwargs)
return json.dumps({"AppId": app.id}, indent=1)
def create_instance(self):
kwargs = dict(
stack_id=self.parameters.get("StackId"),
@ -110,6 +128,12 @@ class OpsWorksResponse(BaseResponse):
layers = self.opsworks_backend.describe_layers(stack_id, layer_ids)
return json.dumps({"Layers": layers}, indent=1)
def describe_apps(self):
stack_id = self.parameters.get("StackId")
app_ids = self.parameters.get("AppIds")
apps = self.opsworks_backend.describe_apps(stack_id, app_ids)
return json.dumps({"Apps": apps}, indent=1)
def describe_instances(self):
instance_ids = self.parameters.get("InstanceIds")
layer_id = self.parameters.get("LayerId")

View File

@ -0,0 +1,102 @@
from __future__ import unicode_literals
import boto3
from freezegun import freeze_time
import sure # noqa
import re
from moto import mock_opsworks
@freeze_time("2015-01-01")
@mock_opsworks
def test_create_app_response():
client = boto3.client('opsworks', region_name='us-east-1')
stack_id = client.create_stack(
Name="test_stack_1",
Region="us-east-1",
ServiceRoleArn="service_arn",
DefaultInstanceProfileArn="profile_arn"
)['StackId']
response = client.create_app(
StackId=stack_id,
Type="other",
Name="TestApp"
)
response.should.contain("AppId")
second_stack_id = client.create_stack(
Name="test_stack_2",
Region="us-east-1",
ServiceRoleArn="service_arn",
DefaultInstanceProfileArn="profile_arn"
)['StackId']
response = client.create_app(
StackId=second_stack_id,
Type="other",
Name="TestApp"
)
response.should.contain("AppId")
# ClientError
client.create_app.when.called_with(
StackId=stack_id,
Type="other",
Name="TestApp"
).should.throw(
Exception, re.compile(r'already an app named "TestApp"')
)
# ClientError
client.create_app.when.called_with(
StackId="nothere",
Type="other",
Name="TestApp"
).should.throw(
Exception, "nothere"
)
@freeze_time("2015-01-01")
@mock_opsworks
def test_describe_apps():
client = boto3.client('opsworks', region_name='us-east-1')
stack_id = client.create_stack(
Name="test_stack_1",
Region="us-east-1",
ServiceRoleArn="service_arn",
DefaultInstanceProfileArn="profile_arn"
)['StackId']
app_id = client.create_app(
StackId=stack_id,
Type="other",
Name="TestApp"
)['AppId']
rv1 = client.describe_apps(StackId=stack_id)
rv2 = client.describe_apps(AppIds=[app_id])
rv1['Apps'].should.equal(rv2['Apps'])
rv1['Apps'][0]['Name'].should.equal("TestApp")
# ClientError
client.describe_apps.when.called_with(
StackId=stack_id,
AppIds=[app_id]
).should.throw(
Exception, "Please provide one or more app IDs or a stack ID"
)
# ClientError
client.describe_apps.when.called_with(
StackId="nothere"
).should.throw(
Exception, "Unable to find stack with ID nothere"
)
# ClientError
client.describe_apps.when.called_with(
AppIds=["nothere"]
).should.throw(
Exception, "nothere"
)