diff --git a/moto/ssm/models.py b/moto/ssm/models.py index c8c428b64..d8dc10a4b 100644 --- a/moto/ssm/models.py +++ b/moto/ssm/models.py @@ -5,13 +5,17 @@ from collections import defaultdict from moto.core import BaseBackend, BaseModel from moto.ec2 import ec2_backends +import time + class Parameter(BaseModel): - def __init__(self, name, value, type, description, keyid): + def __init__(self, name, value, type, description, keyid, last_modified_date, version): self.name = name self.type = type self.description = description self.keyid = keyid + self.last_modified_date = last_modified_date + self.version = version if self.type == 'SecureString': self.value = self.encrypt(value) @@ -33,8 +37,20 @@ class Parameter(BaseModel): r = { 'Name': self.name, 'Type': self.type, - 'Value': self.decrypt(self.value) if decrypt else self.value + 'Value': self.decrypt(self.value) if decrypt else self.value, + 'Version': self.version, } + + return r + + def describe_response_object(self, decrypt=False): + r = self.response_object(decrypt) + r['LastModifiedDate'] = int(self.last_modified_date) + r['LastModifiedUser'] = 'N/A' + + if self.description: + r['Description'] = self.description + if self.keyid: r['KeyId'] = self.keyid return r @@ -96,10 +112,18 @@ class SimpleSystemManagerBackend(BaseBackend): return None def put_parameter(self, name, description, value, type, keyid, overwrite): - if not overwrite and name in self._parameters: - return + previous_parameter = self._parameters.get(name) + version = 1 + + if previous_parameter: + version = previous_parameter.version + 1 + + if not overwrite: + return + + last_modified_date = time.time() self._parameters[name] = Parameter( - name, value, type, description, keyid) + name, value, type, description, keyid, last_modified_date, version) def add_tags_to_resource(self, resource_type, resource_id, tags): for key, value in tags.items(): diff --git a/moto/ssm/responses.py b/moto/ssm/responses.py index 3227839b9..0b4ca3b65 100644 --- a/moto/ssm/responses.py +++ b/moto/ssm/responses.py @@ -117,7 +117,7 @@ class SimpleSystemManagerResponse(BaseResponse): end = token + page_size for parameter in result[token:]: - param_data = parameter.response_object(False) + param_data = parameter.describe_response_object(False) add = False if filters: diff --git a/tests/test_ssm/test_ssm_boto3.py b/tests/test_ssm/test_ssm_boto3.py index 781727c26..ff8e5e8a4 100644 --- a/tests/test_ssm/test_ssm_boto3.py +++ b/tests/test_ssm/test_ssm_boto3.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import boto3 import botocore.exceptions import sure # noqa +import datetime from moto import mock_ssm @@ -112,6 +113,46 @@ def test_put_parameter(): response['Parameters'][0]['Name'].should.equal('test') response['Parameters'][0]['Value'].should.equal('value') response['Parameters'][0]['Type'].should.equal('String') + response['Parameters'][0]['Version'].should.equal(1) + + client.put_parameter( + Name='test', + Description='desc 2', + Value='value 2', + Type='String') + + response = client.get_parameters( + Names=[ + 'test' + ], + WithDecryption=False) + + # without overwrite nothing change + len(response['Parameters']).should.equal(1) + response['Parameters'][0]['Name'].should.equal('test') + response['Parameters'][0]['Value'].should.equal('value') + response['Parameters'][0]['Type'].should.equal('String') + response['Parameters'][0]['Version'].should.equal(1) + + client.put_parameter( + Name='test', + Description='desc 3', + Value='value 3', + Type='String', + Overwrite=True) + + response = client.get_parameters( + Names=[ + 'test' + ], + WithDecryption=False) + + # without overwrite nothing change + len(response['Parameters']).should.equal(1) + response['Parameters'][0]['Name'].should.equal('test') + response['Parameters'][0]['Value'].should.equal('value 3') + response['Parameters'][0]['Type'].should.equal('String') + response['Parameters'][0]['Version'].should.equal(2) @mock_ssm @@ -279,6 +320,33 @@ def test_describe_parameters_filter_keyid(): response['Parameters'][0]['Type'].should.equal('SecureString') ''.should.equal(response.get('NextToken', '')) +@mock_ssm +def test_describe_parameters_attributes(): + client = boto3.client('ssm', region_name='us-east-1') + + client.put_parameter( + Name='aa', + Value='11', + Type='String', + Description='my description' + ) + + client.put_parameter( + Name='bb', + Value='22', + Type='String' + ) + + response = client.describe_parameters() + len(response['Parameters']).should.equal(2) + + response['Parameters'][0]['Description'].should.equal('my description') + response['Parameters'][0]['Version'].should.equal(1) + response['Parameters'][0]['LastModifiedDate'].should.be.a(datetime.date) + response['Parameters'][0]['LastModifiedUser'].should.equal('N/A') + + response['Parameters'][1].get('Description').should.be.none + response['Parameters'][1]['Version'].should.equal(1) @mock_ssm def test_get_parameter_invalid():