From 3740db80598fd4fb96a681bae0232f2c6afdda63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20Xia=28=E5=A4=8F=E6=81=BA=29?= Date: Mon, 6 Nov 2017 20:44:54 +1100 Subject: [PATCH] Added support for SSM get_parameters_by_path. (#1299) * Added support for SSM get_parameters_by_path. Signed-off-by: Kai Xia * add logic to handle trailing '/'. Also, fix pep8. Signed-off-by: Kai Xia * add tests for parameter value in response. Signed-off-by: Kai Xia --- moto/ssm/models.py | 15 +++++++++++ moto/ssm/responses.py | 19 ++++++++++++++ tests/test_ssm/test_ssm_boto3.py | 45 ++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/moto/ssm/models.py b/moto/ssm/models.py index a0e4a2155..c8c428b64 100644 --- a/moto/ssm/models.py +++ b/moto/ssm/models.py @@ -75,6 +75,21 @@ class SimpleSystemManagerBackend(BaseBackend): result.append(self._parameters[name]) return result + def get_parameters_by_path(self, path, with_decryption, recursive): + """Implement the get-parameters-by-path-API in the backend.""" + result = [] + # path could be with or without a trailing /. we handle this + # difference here. + path = path.rstrip('/') + '/' + for param in self._parameters: + if not param.startswith(path): + continue + if '/' in param[len(path) + 1:] and not recursive: + continue + result.append(self._parameters[param]) + + return result + def get_parameter(self, name, with_decryption): if name in self._parameters: return self._parameters[name] diff --git a/moto/ssm/responses.py b/moto/ssm/responses.py index 3b75ada09..3227839b9 100644 --- a/moto/ssm/responses.py +++ b/moto/ssm/responses.py @@ -81,6 +81,25 @@ class SimpleSystemManagerResponse(BaseResponse): response['InvalidParameters'].append(name) return json.dumps(response) + def get_parameters_by_path(self): + path = self._get_param('Path') + with_decryption = self._get_param('WithDecryption') + recursive = self._get_param('Recursive', False) + + result = self.ssm_backend.get_parameters_by_path( + path, with_decryption, recursive + ) + + response = { + 'Parameters': [], + } + + for parameter in result: + param_data = parameter.response_object(with_decryption) + response['Parameters'].append(param_data) + + return json.dumps(response) + def describe_parameters(self): page_size = 10 filters = self._get_param('Filters') diff --git a/tests/test_ssm/test_ssm_boto3.py b/tests/test_ssm/test_ssm_boto3.py index 7f4aca533..781727c26 100644 --- a/tests/test_ssm/test_ssm_boto3.py +++ b/tests/test_ssm/test_ssm_boto3.py @@ -47,6 +47,51 @@ def test_delete_parameters(): len(response['Parameters']).should.equal(0) +@mock_ssm +def test_get_parameters_by_path(): + client = boto3.client('ssm', region_name='us-east-1') + + client.put_parameter( + Name='/foo/name1', + Description='A test parameter', + Value='value1', + Type='String') + + client.put_parameter( + Name='/foo/name2', + Description='A test parameter', + Value='value2', + Type='String') + + client.put_parameter( + Name='/bar/name3', + Description='A test parameter', + Value='value3', + Type='String') + + client.put_parameter( + Name='/bar/name3/name4', + Description='A test parameter', + Value='value4', + Type='String') + + response = client.get_parameters_by_path(Path='/foo') + len(response['Parameters']).should.equal(2) + {p['Value'] for p in response['Parameters']}.should.equal( + set(['value1', 'value2']) + ) + + response = client.get_parameters_by_path(Path='/bar', Recursive=False) + len(response['Parameters']).should.equal(1) + response['Parameters'][0]['Value'].should.equal('value3') + + response = client.get_parameters_by_path(Path='/bar', Recursive=True) + len(response['Parameters']).should.equal(2) + {p['Value'] for p in response['Parameters']}.should.equal( + set(['value3', 'value4']) + ) + + @mock_ssm def test_put_parameter(): client = boto3.client('ssm', region_name='us-east-1')