Skip to content

Commit

Permalink
Greengrass Implement create_resource_definition (getmoto#5221)
Browse files Browse the repository at this point in the history
  • Loading branch information
cm-iwata authored and sahilshah6196 committed Jul 1, 2022
1 parent 1b64b27 commit 0f8c4a8
Show file tree
Hide file tree
Showing 4 changed files with 424 additions and 0 deletions.
119 changes: 119 additions & 0 deletions moto/greengrass/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from moto.core import BaseBackend, BaseModel, get_account_id
from moto.core.utils import BackendDict, iso_8601_datetime_with_milliseconds
from .exceptions import (
GreengrassClientError,
IdNotFoundException,
InvalidContainerDefinitionException,
VersionNotFoundException,
Expand Down Expand Up @@ -117,6 +118,55 @@ def to_dict(self, include_detail=False):
return obj


class FakeResourceDefinition(BaseModel):
def __init__(self, region_name, name, initial_version):
self.region_name = region_name
self.id = str(uuid.uuid4())
self.arn = f"arn:aws:greengrass:{region_name}:{get_account_id()}:/greengrass/definition/resources/{self.id}"
self.created_at_datetime = datetime.utcnow()
self.update_at_datetime = datetime.utcnow()
self.latest_version = ""
self.latest_version_arn = ""
self.name = name
self.initial_version = initial_version

def to_dict(self):
return {
"Arn": self.arn,
"CreationTimestamp": iso_8601_datetime_with_milliseconds(
self.created_at_datetime
),
"Id": self.id,
"LastUpdatedTimestamp": iso_8601_datetime_with_milliseconds(
self.update_at_datetime
),
"LatestVersion": self.latest_version,
"LatestVersionArn": self.latest_version_arn,
"Name": self.name,
}


class FakeResourceDefinitionVersion(BaseModel):
def __init__(self, region_name, resource_definition_id, resources):
self.region_name = region_name
self.resource_definition_id = resource_definition_id
self.resources = resources
self.version = str(uuid.uuid4())
self.arn = f"arn:aws:greengrass:{region_name}:{get_account_id()}:/greengrass/definition/resources/{self.resource_definition_id}/versions/{self.version}"
self.created_at_datetime = datetime.utcnow()

def to_dict(self):
return {
"Arn": self.arn,
"CreationTimestamp": iso_8601_datetime_with_milliseconds(
self.created_at_datetime
),
"Definition": {"Resources": self.resources},
"Id": self.resource_definition_id,
"Version": self.version,
}


class GreengrassBackend(BaseBackend):
def __init__(self, region_name, account_id):
super().__init__(region_name, account_id)
Expand Down Expand Up @@ -291,5 +341,74 @@ def get_device_definition_version(
device_definition_version_id
]

def create_resource_definition(self, name, initial_version):

resources = initial_version.get("Resources", [])
GreengrassBackend._validate_resources(resources)

resource_def = FakeResourceDefinition(self.region_name, name, initial_version)
self.resource_definitions[resource_def.id] = resource_def
init_ver = resource_def.initial_version
resources = init_ver.get("Resources", {})
self.create_resource_definition_version(resource_def.id, resources)

return resource_def

def create_resource_definition_version(self, resource_definition_id, resources):

if resource_definition_id not in self.resource_definitions:
raise IdNotFoundException("That resource definition does not exist.")

GreengrassBackend._validate_resources(resources)

resource_def_ver = FakeResourceDefinitionVersion(
self.region_name, resource_definition_id, resources
)

resources_ver = self.resource_definition_versions.get(
resource_def_ver.resource_definition_id, {}
)
resources_ver[resource_def_ver.version] = resource_def_ver
self.resource_definition_versions[
resource_def_ver.resource_definition_id
] = resources_ver

self.resource_definitions[
resource_definition_id
].latest_version = resource_def_ver.version

self.resource_definitions[
resource_definition_id
].latest_version_arn = resource_def_ver.arn

return resource_def_ver

@staticmethod
def _validate_resources(resources):
for resource in resources:
volume_source_path = (
resource.get("ResourceDataContainer", {})
.get("LocalVolumeResourceData", {})
.get("SourcePath", "")
)
if volume_source_path == "/sys" or volume_source_path.startswith("/sys/"):
raise GreengrassClientError(
"400",
"The resources definition is invalid. (ErrorDetails: [Accessing /sys is prohibited])",
)

local_device_resource_data = resource.get("ResourceDataContainer", {}).get(
"LocalDeviceResourceData", {}
)
if local_device_resource_data:
device_source_path = local_device_resource_data["SourcePath"]
if not device_source_path.startswith("/dev"):
raise GreengrassClientError(
"400",
f"The resources definition is invalid. (ErrorDetails: [Device resource path should begin with "
"/dev"
f", but got: {device_source_path}])",
)


greengrass_backends = BackendDict(GreengrassBackend, "greengrass")
31 changes: 31 additions & 0 deletions moto/greengrass/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,3 +229,34 @@ def get_device_definition_version(self):
device_definition_version_id=device_definition_version_id,
)
return 200, {"status": 200}, json.dumps(res.to_dict(include_detail=True))

def resource_definitions(self, request, full_url, headers):
self.setup_class(request, full_url, headers)

if self.method == "POST":
return self.create_resource_definition()

def create_resource_definition(self):

initial_version = self._get_param("InitialVersion")
name = self._get_param("Name")
res = self.greengrass_backend.create_resource_definition(
name=name, initial_version=initial_version
)
return 201, {"status": 201}, json.dumps(res.to_dict())

def resource_definition_versions(self, request, full_url, headers):
self.setup_class(request, full_url, headers)

if self.method == "POST":
return self.create_resource_definition_version()

def create_resource_definition_version(self):

resource_definition_id = self.path.split("/")[-2]
resources = self._get_param("Resources")

res = self.greengrass_backend.create_resource_definition_version(
resource_definition_id=resource_definition_id, resources=resources
)
return 201, {"status": 201}, json.dumps(res.to_dict())
2 changes: 2 additions & 0 deletions moto/greengrass/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@
"{0}/greengrass/definition/devices/(?P<definition_id>[^/]+)/?$": response.device_definition,
"{0}/greengrass/definition/devices/(?P<definition_id>[^/]+)/versions$": response.device_definition_versions,
"{0}/greengrass/definition/devices/(?P<definition_id>[^/]+)/versions/(?P<definition_version_id>[^/]+)/?$": response.device_definition_version,
"{0}/greengrass/definition/resources$": response.resource_definitions,
"{0}/greengrass/definition/resources/(?P<definition_id>[^/]+)/versions$": response.resource_definition_versions,
}

0 comments on commit 0f8c4a8

Please sign in to comment.