enhancement(SSM): Add DataType attribute to SSM Parameters (#4232)
This commit is contained in:
parent
dc49232734
commit
58da62cc71
@ -55,6 +55,7 @@ class Parameter(BaseModel):
|
||||
keyid,
|
||||
last_modified_date,
|
||||
version,
|
||||
data_type,
|
||||
tags=None,
|
||||
):
|
||||
self.name = name
|
||||
@ -64,6 +65,7 @@ class Parameter(BaseModel):
|
||||
self.keyid = keyid
|
||||
self.last_modified_date = last_modified_date
|
||||
self.version = version
|
||||
self.data_type = data_type
|
||||
self.tags = tags or []
|
||||
self.labels = []
|
||||
|
||||
@ -93,6 +95,7 @@ class Parameter(BaseModel):
|
||||
"Value": self.decrypt(self.value) if decrypt else self.value,
|
||||
"Version": self.version,
|
||||
"LastModifiedDate": round(self.last_modified_date, 3),
|
||||
"DataType": self.data_type,
|
||||
}
|
||||
|
||||
if region:
|
||||
@ -618,6 +621,14 @@ def _document_filter_match(filters, ssm_doc):
|
||||
return True
|
||||
|
||||
|
||||
def _valid_parameter_data_type(data_type):
|
||||
"""
|
||||
Parameter DataType field allows only `text` and `aws:ec2:image` values
|
||||
|
||||
"""
|
||||
return data_type in ("text", "aws:ec2:image")
|
||||
|
||||
|
||||
class SimpleSystemManagerBackend(BaseBackend):
|
||||
def __init__(self, region_name=None):
|
||||
super(SimpleSystemManagerBackend, self).__init__()
|
||||
@ -1480,7 +1491,16 @@ class SimpleSystemManagerBackend(BaseBackend):
|
||||
)
|
||||
|
||||
def put_parameter(
|
||||
self, name, description, value, type, allowed_pattern, keyid, overwrite, tags,
|
||||
self,
|
||||
name,
|
||||
description,
|
||||
value,
|
||||
type,
|
||||
allowed_pattern,
|
||||
keyid,
|
||||
overwrite,
|
||||
tags,
|
||||
data_type,
|
||||
):
|
||||
if not value:
|
||||
raise ValidationException(
|
||||
@ -1504,6 +1524,15 @@ class SimpleSystemManagerBackend(BaseBackend):
|
||||
"formed as a mix of letters, numbers and the following 3 symbols .-_"
|
||||
)
|
||||
raise ValidationException(invalid_prefix_error)
|
||||
|
||||
if not _valid_parameter_data_type(data_type):
|
||||
# The check of the existence of an AMI ID in the account for a parameter of DataType `aws:ec2:image`
|
||||
# is not supported. The parameter will be created.
|
||||
# https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-ec2-aliases.html
|
||||
raise ValidationException(
|
||||
f"The following data type is not supported: {data_type} (Data type names are all lowercase.)"
|
||||
)
|
||||
|
||||
previous_parameter_versions = self._parameters[name]
|
||||
if len(previous_parameter_versions) == 0:
|
||||
previous_parameter = None
|
||||
@ -1522,15 +1551,16 @@ class SimpleSystemManagerBackend(BaseBackend):
|
||||
last_modified_date = time.time()
|
||||
self._parameters[name].append(
|
||||
Parameter(
|
||||
name,
|
||||
value,
|
||||
type,
|
||||
description,
|
||||
allowed_pattern,
|
||||
keyid,
|
||||
last_modified_date,
|
||||
version,
|
||||
tags or [],
|
||||
name=name,
|
||||
value=value,
|
||||
type=type,
|
||||
description=description,
|
||||
allowed_pattern=allowed_pattern,
|
||||
keyid=keyid,
|
||||
last_modified_date=last_modified_date,
|
||||
version=version,
|
||||
tags=tags or [],
|
||||
data_type=data_type,
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -277,9 +277,18 @@ class SimpleSystemManagerResponse(BaseResponse):
|
||||
keyid = self._get_param("KeyId")
|
||||
overwrite = self._get_param("Overwrite", False)
|
||||
tags = self._get_param("Tags", [])
|
||||
data_type = self._get_param("DataType", "text")
|
||||
|
||||
result = self.ssm_backend.put_parameter(
|
||||
name, description, value, type_, allowed_pattern, keyid, overwrite, tags
|
||||
name,
|
||||
description,
|
||||
value,
|
||||
type_,
|
||||
allowed_pattern,
|
||||
keyid,
|
||||
overwrite,
|
||||
tags,
|
||||
data_type,
|
||||
)
|
||||
|
||||
if result is None:
|
||||
|
@ -232,9 +232,8 @@ def test_get_parameters_by_path():
|
||||
@mock_ssm
|
||||
def test_put_parameter(name):
|
||||
client = boto3.client("ssm", region_name="us-east-1")
|
||||
|
||||
response = client.put_parameter(
|
||||
Name=name, Description="A test parameter", Value="value", Type="String"
|
||||
Name=name, Description="A test parameter", Value="value", Type="String",
|
||||
)
|
||||
|
||||
response["Version"].should.equal(1)
|
||||
@ -246,6 +245,7 @@ def test_put_parameter(name):
|
||||
response["Parameters"][0]["Value"].should.equal("value")
|
||||
response["Parameters"][0]["Type"].should.equal("String")
|
||||
response["Parameters"][0]["Version"].should.equal(1)
|
||||
response["Parameters"][0]["DataType"].should.equal("text")
|
||||
response["Parameters"][0]["LastModifiedDate"].should.be.a(datetime.datetime)
|
||||
response["Parameters"][0]["ARN"].should.equal(
|
||||
"arn:aws:ssm:us-east-1:{}:parameter/{}".format(ACCOUNT_ID, name)
|
||||
@ -271,15 +271,21 @@ def test_put_parameter(name):
|
||||
response["Parameters"][0]["Value"].should.equal("value")
|
||||
response["Parameters"][0]["Type"].should.equal("String")
|
||||
response["Parameters"][0]["Version"].should.equal(1)
|
||||
response["Parameters"][0]["DataType"].should.equal("text")
|
||||
response["Parameters"][0]["LastModifiedDate"].should.equal(
|
||||
initial_modification_date
|
||||
)
|
||||
response["Parameters"][0]["ARN"].should.equal(
|
||||
"arn:aws:ssm:us-east-1:{}:parameter/{}".format(ACCOUNT_ID, name)
|
||||
)
|
||||
|
||||
new_data_type = "aws:ec2:image"
|
||||
response = client.put_parameter(
|
||||
Name=name, Description="desc 3", Value="value 3", Type="String", Overwrite=True,
|
||||
Name=name,
|
||||
Description="desc 3",
|
||||
Value="value 3",
|
||||
Type="String",
|
||||
Overwrite=True,
|
||||
DataType=new_data_type,
|
||||
)
|
||||
|
||||
response["Version"].should.equal(2)
|
||||
@ -292,6 +298,8 @@ def test_put_parameter(name):
|
||||
response["Parameters"][0]["Value"].should.equal("value 3")
|
||||
response["Parameters"][0]["Type"].should.equal("String")
|
||||
response["Parameters"][0]["Version"].should.equal(2)
|
||||
response["Parameters"][0]["DataType"].should_not.equal("text")
|
||||
response["Parameters"][0]["DataType"].should.equal(new_data_type)
|
||||
response["Parameters"][0]["LastModifiedDate"].should_not.equal(
|
||||
initial_modification_date
|
||||
)
|
||||
@ -394,12 +402,30 @@ def test_put_parameter_china():
|
||||
response["Version"].should.equal(1)
|
||||
|
||||
|
||||
@mock_ssm
|
||||
@pytest.mark.parametrize("bad_data_type", ["not_text", "not_ec2", "something weird"])
|
||||
def test_put_parameter_invalid_data_type(bad_data_type):
|
||||
client = boto3.client("ssm", region_name="us-east-1")
|
||||
with pytest.raises(ClientError) as e:
|
||||
client.put_parameter(
|
||||
Name="test_name", Value="some_value", Type="String", DataType=bad_data_type
|
||||
)
|
||||
ex = e.value
|
||||
ex.operation_name.should.equal("PutParameter")
|
||||
ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
|
||||
ex.response["Error"]["Code"].should.contain("ValidationException")
|
||||
ex.response["Error"]["Message"].should.equal(
|
||||
f"The following data type is not supported: {bad_data_type}"
|
||||
" (Data type names are all lowercase.)"
|
||||
)
|
||||
|
||||
|
||||
@mock_ssm
|
||||
def test_get_parameter():
|
||||
client = boto3.client("ssm", region_name="us-east-1")
|
||||
|
||||
client.put_parameter(
|
||||
Name="test", Description="A test parameter", Value="value", Type="String"
|
||||
Name="test", Description="A test parameter", Value="value", Type="String",
|
||||
)
|
||||
|
||||
response = client.get_parameter(Name="test", WithDecryption=False)
|
||||
@ -407,6 +433,7 @@ def test_get_parameter():
|
||||
response["Parameter"]["Name"].should.equal("test")
|
||||
response["Parameter"]["Value"].should.equal("value")
|
||||
response["Parameter"]["Type"].should.equal("String")
|
||||
response["Parameter"]["DataType"].should.equal("text")
|
||||
response["Parameter"]["LastModifiedDate"].should.be.a(datetime.datetime)
|
||||
response["Parameter"]["ARN"].should.equal(
|
||||
"arn:aws:ssm:us-east-1:{}:parameter/test".format(ACCOUNT_ID)
|
||||
@ -418,10 +445,10 @@ def test_get_parameter_with_version_and_labels():
|
||||
client = boto3.client("ssm", region_name="us-east-1")
|
||||
|
||||
client.put_parameter(
|
||||
Name="test-1", Description="A test parameter", Value="value", Type="String"
|
||||
Name="test-1", Description="A test parameter", Value="value", Type="String",
|
||||
)
|
||||
client.put_parameter(
|
||||
Name="test-2", Description="A test parameter", Value="value", Type="String"
|
||||
Name="test-2", Description="A test parameter", Value="value", Type="String",
|
||||
)
|
||||
|
||||
client.label_parameter_version(
|
||||
@ -433,6 +460,7 @@ def test_get_parameter_with_version_and_labels():
|
||||
response["Parameter"]["Name"].should.equal("test-1")
|
||||
response["Parameter"]["Value"].should.equal("value")
|
||||
response["Parameter"]["Type"].should.equal("String")
|
||||
response["Parameter"]["DataType"].should.equal("text")
|
||||
response["Parameter"]["LastModifiedDate"].should.be.a(datetime.datetime)
|
||||
response["Parameter"]["ARN"].should.equal(
|
||||
"arn:aws:ssm:us-east-1:{}:parameter/test-1".format(ACCOUNT_ID)
|
||||
@ -442,6 +470,7 @@ def test_get_parameter_with_version_and_labels():
|
||||
response["Parameter"]["Name"].should.equal("test-2")
|
||||
response["Parameter"]["Value"].should.equal("value")
|
||||
response["Parameter"]["Type"].should.equal("String")
|
||||
response["Parameter"]["DataType"].should.equal("text")
|
||||
response["Parameter"]["LastModifiedDate"].should.be.a(datetime.datetime)
|
||||
response["Parameter"]["ARN"].should.equal(
|
||||
"arn:aws:ssm:us-east-1:{}:parameter/test-2".format(ACCOUNT_ID)
|
||||
@ -451,6 +480,7 @@ def test_get_parameter_with_version_and_labels():
|
||||
response["Parameter"]["Name"].should.equal("test-2")
|
||||
response["Parameter"]["Value"].should.equal("value")
|
||||
response["Parameter"]["Type"].should.equal("String")
|
||||
response["Parameter"]["DataType"].should.equal("text")
|
||||
response["Parameter"]["LastModifiedDate"].should.be.a(datetime.datetime)
|
||||
response["Parameter"]["ARN"].should.equal(
|
||||
"arn:aws:ssm:us-east-1:{}:parameter/test-2".format(ACCOUNT_ID)
|
||||
@ -532,6 +562,7 @@ def test_describe_parameters():
|
||||
parameters.should.have.length_of(1)
|
||||
parameters[0]["Name"].should.equal("test")
|
||||
parameters[0]["Type"].should.equal("String")
|
||||
parameters[0]["DataType"].should.equal("text")
|
||||
parameters[0]["AllowedPattern"].should.equal(r".*")
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user