Greengrass Implement group and role associate APIs (#5278)
This commit is contained in:
parent
6282e5124d
commit
01d0141da8
@ -361,10 +361,25 @@ class FakeGroupVersion(BaseModel):
|
||||
return obj
|
||||
|
||||
|
||||
class FakeAssociatedRole(BaseModel):
|
||||
def __init__(self, role_arn):
|
||||
self.role_arn = role_arn
|
||||
self.associated_at = datetime.utcnow()
|
||||
|
||||
def to_dict(self, include_detail=False):
|
||||
|
||||
obj = {"AssociatedAt": iso_8601_datetime_with_milliseconds(self.associated_at)}
|
||||
if include_detail:
|
||||
obj["RoleArn"] = self.role_arn
|
||||
|
||||
return obj
|
||||
|
||||
|
||||
class GreengrassBackend(BaseBackend):
|
||||
def __init__(self, region_name, account_id):
|
||||
super().__init__(region_name, account_id)
|
||||
self.groups = OrderedDict()
|
||||
self.group_role_associations = OrderedDict()
|
||||
self.group_versions = OrderedDict()
|
||||
self.core_definitions = OrderedDict()
|
||||
self.core_definition_versions = OrderedDict()
|
||||
@ -1066,5 +1081,28 @@ class GreengrassBackend(BaseBackend):
|
||||
|
||||
return self.group_versions[group_id][group_version_id]
|
||||
|
||||
def associate_role_to_group(self, group_id, role_arn):
|
||||
|
||||
# I don't know why, AssociateRoleToGroup does not check specified group is exists
|
||||
# So, this API allows any group id such as "a"
|
||||
|
||||
associated_role = FakeAssociatedRole(role_arn)
|
||||
self.group_role_associations[group_id] = associated_role
|
||||
return associated_role
|
||||
|
||||
def get_associated_role(self, group_id):
|
||||
|
||||
if group_id not in self.group_role_associations:
|
||||
raise GreengrassClientError(
|
||||
"404", "You need to attach an IAM role to this deployment group."
|
||||
)
|
||||
|
||||
return self.group_role_associations[group_id]
|
||||
|
||||
def disassociate_role_from_group(self, group_id):
|
||||
if group_id not in self.group_role_associations:
|
||||
return
|
||||
del self.group_role_associations[group_id]
|
||||
|
||||
|
||||
greengrass_backends = BackendDict(GreengrassBackend, "greengrass")
|
||||
|
@ -1,5 +1,7 @@
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
from moto.core.utils import iso_8601_datetime_with_milliseconds
|
||||
from moto.core.responses import BaseResponse
|
||||
from .models import greengrass_backends
|
||||
|
||||
@ -677,3 +679,50 @@ class GreengrassResponse(BaseResponse):
|
||||
group_version_id=group_version_id,
|
||||
)
|
||||
return 200, {"status": 200}, json.dumps(res.to_dict(include_detail=True))
|
||||
|
||||
def role(self, request, full_url, headers):
|
||||
self.setup_class(request, full_url, headers)
|
||||
|
||||
if self.method == "PUT":
|
||||
return self.associate_role_to_group()
|
||||
|
||||
if self.method == "GET":
|
||||
return self.get_associated_role()
|
||||
|
||||
if self.method == "DELETE":
|
||||
return self.disassociate_role_from_group()
|
||||
|
||||
def associate_role_to_group(self):
|
||||
|
||||
group_id = self.path.split("/")[-2]
|
||||
role_arn = self._get_param("RoleArn")
|
||||
res = self.greengrass_backend.associate_role_to_group(
|
||||
group_id=group_id,
|
||||
role_arn=role_arn,
|
||||
)
|
||||
return 200, {"status": 200}, json.dumps(res.to_dict())
|
||||
|
||||
def get_associated_role(self):
|
||||
|
||||
group_id = self.path.split("/")[-2]
|
||||
res = self.greengrass_backend.get_associated_role(
|
||||
group_id=group_id,
|
||||
)
|
||||
return 200, {"status": 200}, json.dumps(res.to_dict(include_detail=True))
|
||||
|
||||
def disassociate_role_from_group(self):
|
||||
group_id = self.path.split("/")[-2]
|
||||
self.greengrass_backend.disassociate_role_from_group(
|
||||
group_id=group_id,
|
||||
)
|
||||
return (
|
||||
200,
|
||||
{"status": 200},
|
||||
json.dumps(
|
||||
{
|
||||
"DisassociatedAt": iso_8601_datetime_with_milliseconds(
|
||||
datetime.utcnow()
|
||||
)
|
||||
}
|
||||
),
|
||||
)
|
||||
|
@ -31,6 +31,7 @@ url_paths = {
|
||||
"{0}/greengrass/definition/resources/(?P<definition_id>[^/]+)/versions/(?P<definition_version_id>[^/]+)/?$": response.resource_definition_version,
|
||||
"{0}/greengrass/groups$": response.groups,
|
||||
"{0}/greengrass/groups/(?P<group_id>[^/]+)/?$": response.group,
|
||||
"{0}/greengrass/groups/(?P<group_id>[^/]+)/role$": response.role,
|
||||
"{0}/greengrass/groups/(?P<group_id>[^/]+)/versions$": response.group_versions,
|
||||
"{0}/greengrass/groups/(?P<group_id>[^/]+)/versions/(?P<group_version_id>[^/]+)/?$": response.group_version,
|
||||
}
|
||||
|
@ -473,3 +473,88 @@ def test_get_group_version_with_invalid_version_id():
|
||||
f"Version {invalid_group_ver_id} of Group Definition {group_id} does not exist."
|
||||
)
|
||||
ex.value.response["Error"]["Code"].should.equal("VersionNotFoundException")
|
||||
|
||||
|
||||
@freezegun.freeze_time("2022-06-01 12:00:00")
|
||||
@mock_greengrass
|
||||
def test_associate_role_to_group():
|
||||
|
||||
client = boto3.client("greengrass", region_name="ap-northeast-1")
|
||||
res = client.associate_role_to_group(
|
||||
GroupId="abc002c8-1093-485e-9324-3baadf38e582",
|
||||
RoleArn=f"arn:aws:iam::{ACCOUNT_ID}:role/greengrass-role",
|
||||
)
|
||||
|
||||
res.should.have.key("AssociatedAt")
|
||||
res["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||
|
||||
|
||||
@freezegun.freeze_time("2022-06-01 12:00:00")
|
||||
@mock_greengrass
|
||||
def test_get_associated_role():
|
||||
|
||||
client = boto3.client("greengrass", region_name="ap-northeast-1")
|
||||
group_id = "abc002c8-1093-485e-9324-3baadf38e582"
|
||||
role_arn = f"arn:aws:iam::{ACCOUNT_ID}:role/greengrass-role"
|
||||
client.associate_role_to_group(GroupId=group_id, RoleArn=role_arn)
|
||||
|
||||
res = client.get_associated_role(GroupId=group_id)
|
||||
res.should.have.key("AssociatedAt")
|
||||
res.should.have.key("RoleArn").should.equal(role_arn)
|
||||
res["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||
|
||||
if not TEST_SERVER_MODE:
|
||||
res["AssociatedAt"].should.equal("2022-06-01T12:00:00.000Z")
|
||||
|
||||
|
||||
@mock_greengrass
|
||||
def test_get_associated_role_with_invalid_id():
|
||||
|
||||
client = boto3.client("greengrass", region_name="ap-northeast-1")
|
||||
with pytest.raises(ClientError) as ex:
|
||||
client.get_associated_role(GroupId="abc002c8-1093-485e-9324-3baadf38e582")
|
||||
|
||||
ex.value.response["Error"]["Message"].should.equal(
|
||||
"You need to attach an IAM role to this deployment group."
|
||||
)
|
||||
ex.value.response["Error"]["Code"].should.equal("404")
|
||||
|
||||
|
||||
@freezegun.freeze_time("2022-06-01 12:00:00")
|
||||
@mock_greengrass
|
||||
def test_disassociate_role_from_group():
|
||||
|
||||
client = boto3.client("greengrass", region_name="ap-northeast-1")
|
||||
group_id = "abc002c8-1093-485e-9324-3baadf38e582"
|
||||
role_arn = f"arn:aws:iam::{ACCOUNT_ID}:role/greengrass-role"
|
||||
client.associate_role_to_group(GroupId=group_id, RoleArn=role_arn)
|
||||
client.get_associated_role(GroupId=group_id)
|
||||
|
||||
res = client.disassociate_role_from_group(GroupId=group_id)
|
||||
res.should.have.key("DisassociatedAt")
|
||||
res["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||
|
||||
if not TEST_SERVER_MODE:
|
||||
res["DisassociatedAt"].should.equal("2022-06-01T12:00:00.000Z")
|
||||
|
||||
with pytest.raises(ClientError) as ex:
|
||||
client.get_associated_role(GroupId=group_id)
|
||||
|
||||
ex.value.response["Error"]["Message"].should.equal(
|
||||
"You need to attach an IAM role to this deployment group."
|
||||
)
|
||||
ex.value.response["Error"]["Code"].should.equal("404")
|
||||
|
||||
|
||||
@freezegun.freeze_time("2022-06-01 12:00:00")
|
||||
@mock_greengrass
|
||||
def test_disassociate_role_from_group_with_none_exists_group_id():
|
||||
|
||||
client = boto3.client("greengrass", region_name="ap-northeast-1")
|
||||
group_id = "abc002c8-1093-485e-9324-3baadf38e582"
|
||||
res = client.disassociate_role_from_group(GroupId=group_id)
|
||||
res.should.have.key("DisassociatedAt")
|
||||
res["ResponseMetadata"]["HTTPStatusCode"].should.equal(200)
|
||||
|
||||
if not TEST_SERVER_MODE:
|
||||
res["DisassociatedAt"].should.equal("2022-06-01T12:00:00.000Z")
|
||||
|
Loading…
Reference in New Issue
Block a user