From 57056954954ddea47e82d7443f3f401c41c2476f Mon Sep 17 00:00:00 2001 From: Brent Driskill Date: Sun, 8 Mar 2020 20:32:01 -0400 Subject: [PATCH 1/2] SSM: Added support for label_parameter_version and getting labels on get_parameter_history --- moto/ssm/exceptions.py | 17 ++ moto/ssm/models.py | 66 ++++++- moto/ssm/responses.py | 13 +- tests/test_ssm/test_ssm_boto3.py | 303 +++++++++++++++++++++++++++++++ 4 files changed, 396 insertions(+), 3 deletions(-) diff --git a/moto/ssm/exceptions.py b/moto/ssm/exceptions.py index 3458fe7d3..1c7c26ed9 100644 --- a/moto/ssm/exceptions.py +++ b/moto/ssm/exceptions.py @@ -22,6 +22,23 @@ class InvalidFilterValue(JsonRESTError): def __init__(self, message): super(InvalidFilterValue, self).__init__("InvalidFilterValue", message) +class ParameterNotFound(JsonRESTError): + code = 400 + + def __init__(self, message): + super(ParameterNotFound, self).__init__("ParameterNotFound", message) + +class ParameterVersionNotFound(JsonRESTError): + code = 400 + + def __init__(self, message): + super(ParameterVersionNotFound, self).__init__("ParameterVersionNotFound", message) + +class ParameterVersionLabelLimitExceeded(JsonRESTError): + code = 400 + + def __init__(self, message): + super(ParameterVersionLabelLimitExceeded, self).__init__("ParameterVersionLabelLimitExceeded", message) class ValidationException(JsonRESTError): code = 400 diff --git a/moto/ssm/models.py b/moto/ssm/models.py index a7518d405..2806a0fe0 100644 --- a/moto/ssm/models.py +++ b/moto/ssm/models.py @@ -19,6 +19,9 @@ from .exceptions import ( InvalidFilterValue, InvalidFilterOption, InvalidFilterKey, + ParameterVersionLabelLimitExceeded, + ParameterVersionNotFound, + ParameterNotFound ) @@ -32,7 +35,7 @@ class Parameter(BaseModel): allowed_pattern, keyid, last_modified_date, - version, + version ): self.name = name self.type = type @@ -41,6 +44,7 @@ class Parameter(BaseModel): self.keyid = keyid self.last_modified_date = last_modified_date self.version = version + self.labels = [] if self.type == "SecureString": if not self.keyid: @@ -75,7 +79,7 @@ class Parameter(BaseModel): return r - def describe_response_object(self, decrypt=False): + def describe_response_object(self, decrypt=False, include_labels=False): r = self.response_object(decrypt) r["LastModifiedDate"] = round(self.last_modified_date, 3) r["LastModifiedUser"] = "N/A" @@ -89,6 +93,9 @@ class Parameter(BaseModel): if self.allowed_pattern: r["AllowedPattern"] = self.allowed_pattern + if include_labels: + r["Labels"] = self.labels + return r @@ -614,6 +621,61 @@ class SimpleSystemManagerBackend(BaseBackend): return self._parameters[name][-1] return None + def label_parameter_version(self, name, version, labels): + previous_parameter_versions = self._parameters[name] + if not previous_parameter_versions: + raise ParameterNotFound( + "Parameter %s not found." % name + ) + found_parameter = None + labels_needing_removal = [] + if not version: + version = 1 + for parameter in previous_parameter_versions: + if parameter.version >= version: + version = parameter.version + for parameter in previous_parameter_versions: + if parameter.version == version: + found_parameter = parameter + else: + for label in labels: + if label in parameter.labels: + labels_needing_removal.append(label) + if not found_parameter: + raise ParameterVersionNotFound( + "Systems Manager could not find version %s of %s. " + "Verify the version and try again." % (version, name) + ) + labels_to_append = [] + invalid_labels = [] + for label in labels: + if label.startswith("aws") or label.startswith("ssm") or label[:1].isdigit() or not re.match("^[a-zA-z0-9_\.\-]*$", label): + invalid_labels.append(label) + continue + if len(label) > 100: + raise ValidationException( + "1 validation error detected: " + "Value '[%s]' at 'labels' failed to satisfy constraint: " + "Member must satisfy constraint: " + "[Member must have length less than or equal to 100, Member must have length greater than or equal to 1]" % label + ) + continue + if label not in found_parameter.labels: + labels_to_append.append(label) + if (len(found_parameter.labels) + len(labels_to_append)) > 10: + raise ParameterVersionLabelLimitExceeded( + "An error occurred (ParameterVersionLabelLimitExceeded) when calling the LabelParameterVersion operation: " + "A parameter version can have maximum 10 labels." + "Move one or more labels to another version and try again." + ) + found_parameter.labels = found_parameter.labels + labels_to_append + for parameter in previous_parameter_versions: + if parameter.version != version: + for label in parameter.labels[:]: + if label in labels_needing_removal: + parameter.labels.remove(label) + return [invalid_labels, version] + def put_parameter( self, name, description, value, type, allowed_pattern, keyid, overwrite ): diff --git a/moto/ssm/responses.py b/moto/ssm/responses.py index 831737848..f453518ab 100644 --- a/moto/ssm/responses.py +++ b/moto/ssm/responses.py @@ -168,12 +168,23 @@ class SimpleSystemManagerResponse(BaseResponse): response = {"Parameters": []} for parameter_version in result: param_data = parameter_version.describe_response_object( - decrypt=with_decryption + decrypt=with_decryption, + include_labels=True ) response["Parameters"].append(param_data) return json.dumps(response) + def label_parameter_version(self): + name = self._get_param("Name") + version = self._get_param("ParameterVersion") + labels = self._get_param("Labels") + + invalid_labels, version = self.ssm_backend.label_parameter_version(name, version, labels) + + response = {"InvalidLabels": invalid_labels, "ParameterVersion": version} + return json.dumps(response) + def add_tags_to_resource(self): resource_id = self._get_param("ResourceId") resource_type = self._get_param("ResourceType") diff --git a/tests/test_ssm/test_ssm_boto3.py b/tests/test_ssm/test_ssm_boto3.py index bb674fb65..c2813772d 100644 --- a/tests/test_ssm/test_ssm_boto3.py +++ b/tests/test_ssm/test_ssm_boto3.py @@ -897,6 +897,7 @@ def test_get_parameter_history(): param["Value"].should.equal("value-%d" % index) param["Version"].should.equal(index + 1) param["Description"].should.equal("A test parameter version %d" % index) + param["Labels"].should.equal([]) len(parameters_response).should.equal(3) @@ -937,6 +938,308 @@ def test_get_parameter_history_with_secure_string(): len(parameters_response).should.equal(3) +@mock_ssm +def test_label_parameter_version(): + client = boto3.client("ssm", region_name="us-east-1") + + test_parameter_name = "test" + client.put_parameter(Name=test_parameter_name, Description="A test parameter", Value="value", Type="String") + + response = client.label_parameter_version(Name=test_parameter_name, Labels=["test-label"]) + response["InvalidLabels"].should.equal([]) + response["ParameterVersion"].should.equal(1) + +@mock_ssm +def test_label_parameter_version_with_specific_version(): + client = boto3.client("ssm", region_name="us-east-1") + + test_parameter_name = "test" + client.put_parameter(Name=test_parameter_name, Description="A test parameter", Value="value", Type="String") + + response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=["test-label"]) + response["InvalidLabels"].should.equal([]) + response["ParameterVersion"].should.equal(1) + +@mock_ssm +def test_label_parameter_version_twice(): + client = boto3.client("ssm", region_name="us-east-1") + + test_parameter_name = "test" + test_labels = ["test-label"] + client.put_parameter(Name=test_parameter_name, Description="A test parameter", Value="value", Type="String") + + response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=test_labels) + response["InvalidLabels"].should.equal([]) + response["ParameterVersion"].should.equal(1) + response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=test_labels) + response["InvalidLabels"].should.equal([]) + response["ParameterVersion"].should.equal(1) + + response = client.get_parameter_history(Name=test_parameter_name) + len(response["Parameters"]).should.equal(1) + response["Parameters"][0]["Labels"].should.equal(test_labels) + +@mock_ssm +def test_label_parameter_moving_versions(): + client = boto3.client("ssm", region_name="us-east-1") + + test_parameter_name = "test" + test_labels = ["test-label"] + + for i in range(3): + client.put_parameter( + Name=test_parameter_name, + Description="A test parameter version %d" % i, + Value="value-%d" % i, + Type="String", + Overwrite=True + ) + + response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=test_labels) + response["InvalidLabels"].should.equal([]) + response["ParameterVersion"].should.equal(1) + response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=2, Labels=test_labels) + response["InvalidLabels"].should.equal([]) + response["ParameterVersion"].should.equal(2) + + response = client.get_parameter_history(Name=test_parameter_name) + parameters_response = response["Parameters"] + + for index, param in enumerate(parameters_response): + param["Name"].should.equal(test_parameter_name) + param["Type"].should.equal("String") + param["Value"].should.equal("value-%d" % index) + param["Version"].should.equal(index + 1) + param["Description"].should.equal("A test parameter version %d" % index) + labels = test_labels if param["Version"] == 2 else [] + param["Labels"].should.equal(labels) + + len(parameters_response).should.equal(3) + +@mock_ssm +def test_label_parameter_moving_versions_complex(): + client = boto3.client("ssm", region_name="us-east-1") + + test_parameter_name = "test" + + for i in range(3): + client.put_parameter( + Name=test_parameter_name, + Description="A test parameter version %d" % i, + Value="value-%d" % i, + Type="String", + Overwrite=True + ) + + response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=["test-label1", "test-label2", "test-label3"]) + response["InvalidLabels"].should.equal([]) + response["ParameterVersion"].should.equal(1) + response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=2, Labels=["test-label2", "test-label3"]) + response["InvalidLabels"].should.equal([]) + response["ParameterVersion"].should.equal(2) + + response = client.get_parameter_history(Name=test_parameter_name) + parameters_response = response["Parameters"] + + for index, param in enumerate(parameters_response): + param["Name"].should.equal(test_parameter_name) + param["Type"].should.equal("String") + param["Value"].should.equal("value-%d" % index) + param["Version"].should.equal(index + 1) + param["Description"].should.equal("A test parameter version %d" % index) + labels = ["test-label2", "test-label3"] if param["Version"] == 2 else (["test-label1"] if param["Version"] == 1 else []) + param["Labels"].should.equal(labels) + + len(parameters_response).should.equal(3) + +@mock_ssm +def test_label_parameter_version_exception_ten_labels_at_once(): + client = boto3.client("ssm", region_name="us-east-1") + + test_parameter_name = "test" + test_labels = ["test-label1", "test-label2", "test-label3", "test-label4", "test-label5", "test-label6", "test-label7", "test-label8", "test-label9", "test-label10", "test-label11"] + + client.put_parameter(Name=test_parameter_name, Description="A test parameter", Value="value", Type="String") + client.label_parameter_version.when.called_with( + Name="test", ParameterVersion=1, Labels=test_labels + ).should.throw( + ClientError, + "An error occurred (ParameterVersionLabelLimitExceeded) when calling the LabelParameterVersion operation: " + "A parameter version can have maximum 10 labels." + "Move one or more labels to another version and try again." + ) + +@mock_ssm +def test_label_parameter_version_exception_ten_labels_over_multiple_calls(): + client = boto3.client("ssm", region_name="us-east-1") + + test_parameter_name = "test" + + client.put_parameter(Name=test_parameter_name, Description="A test parameter", Value="value", Type="String") + client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=["test-label1", "test-label2", "test-label3", "test-label4", "test-label5"]) + client.label_parameter_version.when.called_with( + Name="test", ParameterVersion=1, Labels=["test-label6", "test-label7", "test-label8", "test-label9", "test-label10", "test-label11"] + ).should.throw( + ClientError, + "An error occurred (ParameterVersionLabelLimitExceeded) when calling the LabelParameterVersion operation: " + "A parameter version can have maximum 10 labels." + "Move one or more labels to another version and try again." + ) + +@mock_ssm +def test_label_parameter_version_invalid_name(): + client = boto3.client("ssm", region_name="us-east-1") + + test_parameter_name = "test" + + response = client.label_parameter_version.when.called_with( + Name=test_parameter_name, Labels=["test-label"] + ).should.throw( + ClientError, + "An error occurred (ParameterNotFound) when calling the LabelParameterVersion operation: " + "Parameter test not found." + ) + +@mock_ssm +def test_label_parameter_version_invalid_parameter_version(): + client = boto3.client("ssm", region_name="us-east-1") + + test_parameter_name = "test" + client.put_parameter(Name=test_parameter_name, Description="A test parameter", Value="value", Type="String") + + response = client.label_parameter_version.when.called_with( + Name=test_parameter_name, Labels=["test-label"], ParameterVersion=5 + ).should.throw( + ClientError, + "An error occurred (ParameterVersionNotFound) when calling the LabelParameterVersion operation: " + "Systems Manager could not find version 5 of test. " + "Verify the version and try again." + ) + +@mock_ssm +def test_label_parameter_version_invalid_label(): + client = boto3.client("ssm", region_name="us-east-1") + + test_parameter_name = "test" + client.put_parameter(Name=test_parameter_name, Description="A test parameter", Value="value", Type="String") + response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=["awsabc"]) + response["InvalidLabels"].should.equal(["awsabc"]) + + response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=["ssmabc"]) + response["InvalidLabels"].should.equal(["ssmabc"]) + + response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=["9abc"]) + response["InvalidLabels"].should.equal(["9abc"]) + + response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=["abc/123"]) + response["InvalidLabels"].should.equal(["abc/123"]) + + client.label_parameter_version.when.called_with( + Name=test_parameter_name, ParameterVersion=1, Labels=["a"*101] + ).should.throw( + ClientError, + "1 validation error detected: " + "Value '[%s]' at 'labels' failed to satisfy constraint: " + "Member must satisfy constraint: " + "[Member must have length less than or equal to 100, Member must have length greater than or equal to 1]" % ("a"*101) + ) + + +@mock_ssm +def test_get_parameter_history_with_label(): + client = boto3.client("ssm", region_name="us-east-1") + + test_parameter_name = "test" + test_labels = ["test-label"] + + for i in range(3): + client.put_parameter( + Name=test_parameter_name, + Description="A test parameter version %d" % i, + Value="value-%d" % i, + Type="String", + Overwrite=True, + ) + + client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=test_labels) + + response = client.get_parameter_history(Name=test_parameter_name) + parameters_response = response["Parameters"] + + for index, param in enumerate(parameters_response): + param["Name"].should.equal(test_parameter_name) + param["Type"].should.equal("String") + param["Value"].should.equal("value-%d" % index) + param["Version"].should.equal(index + 1) + param["Description"].should.equal("A test parameter version %d" % index) + labels = test_labels if param["Version"] == 1 else [] + param["Labels"].should.equal(labels) + + len(parameters_response).should.equal(3) + +@mock_ssm +def test_get_parameter_history_with_label_non_latest(): + client = boto3.client("ssm", region_name="us-east-1") + + test_parameter_name = "test" + test_labels = ["test-label"] + + for i in range(3): + client.put_parameter( + Name=test_parameter_name, + Description="A test parameter version %d" % i, + Value="value-%d" % i, + Type="String", + Overwrite=True, + ) + + client.label_parameter_version(Name=test_parameter_name, ParameterVersion=2, Labels=test_labels) + + response = client.get_parameter_history(Name=test_parameter_name) + parameters_response = response["Parameters"] + + for index, param in enumerate(parameters_response): + param["Name"].should.equal(test_parameter_name) + param["Type"].should.equal("String") + param["Value"].should.equal("value-%d" % index) + param["Version"].should.equal(index + 1) + param["Description"].should.equal("A test parameter version %d" % index) + labels = test_labels if param["Version"] == 2 else [] + param["Labels"].should.equal(labels) + + len(parameters_response).should.equal(3) + +@mock_ssm +def test_get_parameter_history_with_label_latest_assumed(): + client = boto3.client("ssm", region_name="us-east-1") + + test_parameter_name = "test" + test_labels = ["test-label"] + + for i in range(3): + client.put_parameter( + Name=test_parameter_name, + Description="A test parameter version %d" % i, + Value="value-%d" % i, + Type="String", + Overwrite=True, + ) + + client.label_parameter_version(Name=test_parameter_name, Labels=test_labels) + + response = client.get_parameter_history(Name=test_parameter_name) + parameters_response = response["Parameters"] + + for index, param in enumerate(parameters_response): + param["Name"].should.equal(test_parameter_name) + param["Type"].should.equal("String") + param["Value"].should.equal("value-%d" % index) + param["Version"].should.equal(index + 1) + param["Description"].should.equal("A test parameter version %d" % index) + labels = test_labels if param["Version"] == 3 else [] + param["Labels"].should.equal(labels) + + len(parameters_response).should.equal(3) @mock_ssm def test_get_parameter_history_missing_parameter(): From e3e4b741d8aae3acc7408bdb48f733c66fa59d39 Mon Sep 17 00:00:00 2001 From: Brent Driskill Date: Wed, 11 Mar 2020 11:57:04 -0400 Subject: [PATCH 2/2] SSM: Fix the formatting associated with label_parameter_version/get_parameter_history updates --- moto/ssm/exceptions.py | 12 +- moto/ssm/models.py | 20 ++-- moto/ssm/responses.py | 7 +- tests/test_ssm/test_ssm_boto3.py | 184 +++++++++++++++++++++++++------ 4 files changed, 176 insertions(+), 47 deletions(-) diff --git a/moto/ssm/exceptions.py b/moto/ssm/exceptions.py index 1c7c26ed9..83ae26b6c 100644 --- a/moto/ssm/exceptions.py +++ b/moto/ssm/exceptions.py @@ -22,23 +22,31 @@ class InvalidFilterValue(JsonRESTError): def __init__(self, message): super(InvalidFilterValue, self).__init__("InvalidFilterValue", message) + class ParameterNotFound(JsonRESTError): code = 400 def __init__(self, message): super(ParameterNotFound, self).__init__("ParameterNotFound", message) + class ParameterVersionNotFound(JsonRESTError): code = 400 def __init__(self, message): - super(ParameterVersionNotFound, self).__init__("ParameterVersionNotFound", message) + super(ParameterVersionNotFound, self).__init__( + "ParameterVersionNotFound", message + ) + class ParameterVersionLabelLimitExceeded(JsonRESTError): code = 400 def __init__(self, message): - super(ParameterVersionLabelLimitExceeded, self).__init__("ParameterVersionLabelLimitExceeded", message) + super(ParameterVersionLabelLimitExceeded, self).__init__( + "ParameterVersionLabelLimitExceeded", message + ) + class ValidationException(JsonRESTError): code = 400 diff --git a/moto/ssm/models.py b/moto/ssm/models.py index 2806a0fe0..201f43c5a 100644 --- a/moto/ssm/models.py +++ b/moto/ssm/models.py @@ -21,7 +21,7 @@ from .exceptions import ( InvalidFilterKey, ParameterVersionLabelLimitExceeded, ParameterVersionNotFound, - ParameterNotFound + ParameterNotFound, ) @@ -35,7 +35,7 @@ class Parameter(BaseModel): allowed_pattern, keyid, last_modified_date, - version + version, ): self.name = name self.type = type @@ -624,9 +624,7 @@ class SimpleSystemManagerBackend(BaseBackend): def label_parameter_version(self, name, version, labels): previous_parameter_versions = self._parameters[name] if not previous_parameter_versions: - raise ParameterNotFound( - "Parameter %s not found." % name - ) + raise ParameterNotFound("Parameter %s not found." % name) found_parameter = None labels_needing_removal = [] if not version: @@ -645,11 +643,16 @@ class SimpleSystemManagerBackend(BaseBackend): raise ParameterVersionNotFound( "Systems Manager could not find version %s of %s. " "Verify the version and try again." % (version, name) - ) + ) labels_to_append = [] invalid_labels = [] for label in labels: - if label.startswith("aws") or label.startswith("ssm") or label[:1].isdigit() or not re.match("^[a-zA-z0-9_\.\-]*$", label): + if ( + label.startswith("aws") + or label.startswith("ssm") + or label[:1].isdigit() + or not re.match("^[a-zA-z0-9_\.\-]*$", label) + ): invalid_labels.append(label) continue if len(label) > 100: @@ -657,7 +660,8 @@ class SimpleSystemManagerBackend(BaseBackend): "1 validation error detected: " "Value '[%s]' at 'labels' failed to satisfy constraint: " "Member must satisfy constraint: " - "[Member must have length less than or equal to 100, Member must have length greater than or equal to 1]" % label + "[Member must have length less than or equal to 100, Member must have length greater than or equal to 1]" + % label ) continue if label not in found_parameter.labels: diff --git a/moto/ssm/responses.py b/moto/ssm/responses.py index f453518ab..45d2dec0a 100644 --- a/moto/ssm/responses.py +++ b/moto/ssm/responses.py @@ -168,8 +168,7 @@ class SimpleSystemManagerResponse(BaseResponse): response = {"Parameters": []} for parameter_version in result: param_data = parameter_version.describe_response_object( - decrypt=with_decryption, - include_labels=True + decrypt=with_decryption, include_labels=True ) response["Parameters"].append(param_data) @@ -180,7 +179,9 @@ class SimpleSystemManagerResponse(BaseResponse): version = self._get_param("ParameterVersion") labels = self._get_param("Labels") - invalid_labels, version = self.ssm_backend.label_parameter_version(name, version, labels) + invalid_labels, version = self.ssm_backend.label_parameter_version( + name, version, labels + ) response = {"InvalidLabels": invalid_labels, "ParameterVersion": version} return json.dumps(response) diff --git a/tests/test_ssm/test_ssm_boto3.py b/tests/test_ssm/test_ssm_boto3.py index c2813772d..170cd8a3e 100644 --- a/tests/test_ssm/test_ssm_boto3.py +++ b/tests/test_ssm/test_ssm_boto3.py @@ -938,40 +938,66 @@ def test_get_parameter_history_with_secure_string(): len(parameters_response).should.equal(3) + @mock_ssm def test_label_parameter_version(): client = boto3.client("ssm", region_name="us-east-1") test_parameter_name = "test" - client.put_parameter(Name=test_parameter_name, Description="A test parameter", Value="value", Type="String") + client.put_parameter( + Name=test_parameter_name, + Description="A test parameter", + Value="value", + Type="String", + ) - response = client.label_parameter_version(Name=test_parameter_name, Labels=["test-label"]) + response = client.label_parameter_version( + Name=test_parameter_name, Labels=["test-label"] + ) response["InvalidLabels"].should.equal([]) response["ParameterVersion"].should.equal(1) + @mock_ssm def test_label_parameter_version_with_specific_version(): client = boto3.client("ssm", region_name="us-east-1") test_parameter_name = "test" - client.put_parameter(Name=test_parameter_name, Description="A test parameter", Value="value", Type="String") + client.put_parameter( + Name=test_parameter_name, + Description="A test parameter", + Value="value", + Type="String", + ) - response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=["test-label"]) + response = client.label_parameter_version( + Name=test_parameter_name, ParameterVersion=1, Labels=["test-label"] + ) response["InvalidLabels"].should.equal([]) response["ParameterVersion"].should.equal(1) + @mock_ssm def test_label_parameter_version_twice(): client = boto3.client("ssm", region_name="us-east-1") test_parameter_name = "test" test_labels = ["test-label"] - client.put_parameter(Name=test_parameter_name, Description="A test parameter", Value="value", Type="String") + client.put_parameter( + Name=test_parameter_name, + Description="A test parameter", + Value="value", + Type="String", + ) - response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=test_labels) + response = client.label_parameter_version( + Name=test_parameter_name, ParameterVersion=1, Labels=test_labels + ) response["InvalidLabels"].should.equal([]) response["ParameterVersion"].should.equal(1) - response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=test_labels) + response = client.label_parameter_version( + Name=test_parameter_name, ParameterVersion=1, Labels=test_labels + ) response["InvalidLabels"].should.equal([]) response["ParameterVersion"].should.equal(1) @@ -979,6 +1005,7 @@ def test_label_parameter_version_twice(): len(response["Parameters"]).should.equal(1) response["Parameters"][0]["Labels"].should.equal(test_labels) + @mock_ssm def test_label_parameter_moving_versions(): client = boto3.client("ssm", region_name="us-east-1") @@ -992,13 +1019,17 @@ def test_label_parameter_moving_versions(): Description="A test parameter version %d" % i, Value="value-%d" % i, Type="String", - Overwrite=True + Overwrite=True, ) - response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=test_labels) + response = client.label_parameter_version( + Name=test_parameter_name, ParameterVersion=1, Labels=test_labels + ) response["InvalidLabels"].should.equal([]) response["ParameterVersion"].should.equal(1) - response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=2, Labels=test_labels) + response = client.label_parameter_version( + Name=test_parameter_name, ParameterVersion=2, Labels=test_labels + ) response["InvalidLabels"].should.equal([]) response["ParameterVersion"].should.equal(2) @@ -1016,6 +1047,7 @@ def test_label_parameter_moving_versions(): len(parameters_response).should.equal(3) + @mock_ssm def test_label_parameter_moving_versions_complex(): client = boto3.client("ssm", region_name="us-east-1") @@ -1028,13 +1060,21 @@ def test_label_parameter_moving_versions_complex(): Description="A test parameter version %d" % i, Value="value-%d" % i, Type="String", - Overwrite=True + Overwrite=True, ) - response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=["test-label1", "test-label2", "test-label3"]) + response = client.label_parameter_version( + Name=test_parameter_name, + ParameterVersion=1, + Labels=["test-label1", "test-label2", "test-label3"], + ) response["InvalidLabels"].should.equal([]) response["ParameterVersion"].should.equal(1) - response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=2, Labels=["test-label2", "test-label3"]) + response = client.label_parameter_version( + Name=test_parameter_name, + ParameterVersion=2, + Labels=["test-label2", "test-label3"], + ) response["InvalidLabels"].should.equal([]) response["ParameterVersion"].should.equal(2) @@ -1047,45 +1087,93 @@ def test_label_parameter_moving_versions_complex(): param["Value"].should.equal("value-%d" % index) param["Version"].should.equal(index + 1) param["Description"].should.equal("A test parameter version %d" % index) - labels = ["test-label2", "test-label3"] if param["Version"] == 2 else (["test-label1"] if param["Version"] == 1 else []) + labels = ( + ["test-label2", "test-label3"] + if param["Version"] == 2 + else (["test-label1"] if param["Version"] == 1 else []) + ) param["Labels"].should.equal(labels) len(parameters_response).should.equal(3) + @mock_ssm def test_label_parameter_version_exception_ten_labels_at_once(): client = boto3.client("ssm", region_name="us-east-1") test_parameter_name = "test" - test_labels = ["test-label1", "test-label2", "test-label3", "test-label4", "test-label5", "test-label6", "test-label7", "test-label8", "test-label9", "test-label10", "test-label11"] + test_labels = [ + "test-label1", + "test-label2", + "test-label3", + "test-label4", + "test-label5", + "test-label6", + "test-label7", + "test-label8", + "test-label9", + "test-label10", + "test-label11", + ] - client.put_parameter(Name=test_parameter_name, Description="A test parameter", Value="value", Type="String") + client.put_parameter( + Name=test_parameter_name, + Description="A test parameter", + Value="value", + Type="String", + ) client.label_parameter_version.when.called_with( Name="test", ParameterVersion=1, Labels=test_labels ).should.throw( ClientError, "An error occurred (ParameterVersionLabelLimitExceeded) when calling the LabelParameterVersion operation: " "A parameter version can have maximum 10 labels." - "Move one or more labels to another version and try again." + "Move one or more labels to another version and try again.", ) + @mock_ssm def test_label_parameter_version_exception_ten_labels_over_multiple_calls(): client = boto3.client("ssm", region_name="us-east-1") test_parameter_name = "test" - client.put_parameter(Name=test_parameter_name, Description="A test parameter", Value="value", Type="String") - client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=["test-label1", "test-label2", "test-label3", "test-label4", "test-label5"]) + client.put_parameter( + Name=test_parameter_name, + Description="A test parameter", + Value="value", + Type="String", + ) + client.label_parameter_version( + Name=test_parameter_name, + ParameterVersion=1, + Labels=[ + "test-label1", + "test-label2", + "test-label3", + "test-label4", + "test-label5", + ], + ) client.label_parameter_version.when.called_with( - Name="test", ParameterVersion=1, Labels=["test-label6", "test-label7", "test-label8", "test-label9", "test-label10", "test-label11"] + Name="test", + ParameterVersion=1, + Labels=[ + "test-label6", + "test-label7", + "test-label8", + "test-label9", + "test-label10", + "test-label11", + ], ).should.throw( ClientError, "An error occurred (ParameterVersionLabelLimitExceeded) when calling the LabelParameterVersion operation: " "A parameter version can have maximum 10 labels." - "Move one or more labels to another version and try again." + "Move one or more labels to another version and try again.", ) + @mock_ssm def test_label_parameter_version_invalid_name(): client = boto3.client("ssm", region_name="us-east-1") @@ -1097,15 +1185,21 @@ def test_label_parameter_version_invalid_name(): ).should.throw( ClientError, "An error occurred (ParameterNotFound) when calling the LabelParameterVersion operation: " - "Parameter test not found." + "Parameter test not found.", ) + @mock_ssm def test_label_parameter_version_invalid_parameter_version(): client = boto3.client("ssm", region_name="us-east-1") test_parameter_name = "test" - client.put_parameter(Name=test_parameter_name, Description="A test parameter", Value="value", Type="String") + client.put_parameter( + Name=test_parameter_name, + Description="A test parameter", + Value="value", + Type="String", + ) response = client.label_parameter_version.when.called_with( Name=test_parameter_name, Labels=["test-label"], ParameterVersion=5 @@ -1113,37 +1207,52 @@ def test_label_parameter_version_invalid_parameter_version(): ClientError, "An error occurred (ParameterVersionNotFound) when calling the LabelParameterVersion operation: " "Systems Manager could not find version 5 of test. " - "Verify the version and try again." + "Verify the version and try again.", ) + @mock_ssm def test_label_parameter_version_invalid_label(): client = boto3.client("ssm", region_name="us-east-1") test_parameter_name = "test" - client.put_parameter(Name=test_parameter_name, Description="A test parameter", Value="value", Type="String") - response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=["awsabc"]) + client.put_parameter( + Name=test_parameter_name, + Description="A test parameter", + Value="value", + Type="String", + ) + response = client.label_parameter_version( + Name=test_parameter_name, ParameterVersion=1, Labels=["awsabc"] + ) response["InvalidLabels"].should.equal(["awsabc"]) - response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=["ssmabc"]) + response = client.label_parameter_version( + Name=test_parameter_name, ParameterVersion=1, Labels=["ssmabc"] + ) response["InvalidLabels"].should.equal(["ssmabc"]) - response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=["9abc"]) + response = client.label_parameter_version( + Name=test_parameter_name, ParameterVersion=1, Labels=["9abc"] + ) response["InvalidLabels"].should.equal(["9abc"]) - response = client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=["abc/123"]) + response = client.label_parameter_version( + Name=test_parameter_name, ParameterVersion=1, Labels=["abc/123"] + ) response["InvalidLabels"].should.equal(["abc/123"]) client.label_parameter_version.when.called_with( - Name=test_parameter_name, ParameterVersion=1, Labels=["a"*101] + Name=test_parameter_name, ParameterVersion=1, Labels=["a" * 101] ).should.throw( ClientError, "1 validation error detected: " "Value '[%s]' at 'labels' failed to satisfy constraint: " "Member must satisfy constraint: " - "[Member must have length less than or equal to 100, Member must have length greater than or equal to 1]" % ("a"*101) + "[Member must have length less than or equal to 100, Member must have length greater than or equal to 1]" + % ("a" * 101), ) - + @mock_ssm def test_get_parameter_history_with_label(): @@ -1161,7 +1270,9 @@ def test_get_parameter_history_with_label(): Overwrite=True, ) - client.label_parameter_version(Name=test_parameter_name, ParameterVersion=1, Labels=test_labels) + client.label_parameter_version( + Name=test_parameter_name, ParameterVersion=1, Labels=test_labels + ) response = client.get_parameter_history(Name=test_parameter_name) parameters_response = response["Parameters"] @@ -1177,6 +1288,7 @@ def test_get_parameter_history_with_label(): len(parameters_response).should.equal(3) + @mock_ssm def test_get_parameter_history_with_label_non_latest(): client = boto3.client("ssm", region_name="us-east-1") @@ -1193,7 +1305,9 @@ def test_get_parameter_history_with_label_non_latest(): Overwrite=True, ) - client.label_parameter_version(Name=test_parameter_name, ParameterVersion=2, Labels=test_labels) + client.label_parameter_version( + Name=test_parameter_name, ParameterVersion=2, Labels=test_labels + ) response = client.get_parameter_history(Name=test_parameter_name) parameters_response = response["Parameters"] @@ -1209,6 +1323,7 @@ def test_get_parameter_history_with_label_non_latest(): len(parameters_response).should.equal(3) + @mock_ssm def test_get_parameter_history_with_label_latest_assumed(): client = boto3.client("ssm", region_name="us-east-1") @@ -1241,6 +1356,7 @@ def test_get_parameter_history_with_label_latest_assumed(): len(parameters_response).should.equal(3) + @mock_ssm def test_get_parameter_history_missing_parameter(): client = boto3.client("ssm", region_name="us-east-1")