2017-04-18 17:09:10 +00:00
|
|
|
from __future__ import unicode_literals
|
|
|
|
|
|
|
|
import boto3
|
2017-09-18 20:27:56 +00:00
|
|
|
import botocore.exceptions
|
2017-04-18 17:09:10 +00:00
|
|
|
import sure # noqa
|
2017-11-17 08:57:11 +00:00
|
|
|
import datetime
|
2018-04-25 20:27:07 +00:00
|
|
|
import uuid
|
2018-07-25 18:24:01 +00:00
|
|
|
import json
|
2018-04-25 20:27:07 +00:00
|
|
|
|
|
|
|
from botocore.exceptions import ClientError
|
|
|
|
from nose.tools import assert_raises
|
2017-04-18 17:09:10 +00:00
|
|
|
|
2018-07-25 18:24:01 +00:00
|
|
|
from moto import mock_ssm, mock_cloudformation
|
2017-04-18 17:09:10 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ssm
|
|
|
|
def test_delete_parameter():
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
|
|
|
client.put_parameter(
|
|
|
|
Name='test',
|
|
|
|
Description='A test parameter',
|
|
|
|
Value='value',
|
|
|
|
Type='String')
|
|
|
|
|
|
|
|
response = client.get_parameters(Names=['test'])
|
|
|
|
len(response['Parameters']).should.equal(1)
|
|
|
|
|
|
|
|
client.delete_parameter(Name='test')
|
|
|
|
|
|
|
|
response = client.get_parameters(Names=['test'])
|
|
|
|
len(response['Parameters']).should.equal(0)
|
|
|
|
|
2017-09-18 20:46:07 +00:00
|
|
|
|
2017-08-11 13:19:36 +00:00
|
|
|
@mock_ssm
|
|
|
|
def test_delete_parameters():
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
|
|
|
client.put_parameter(
|
|
|
|
Name='test',
|
|
|
|
Description='A test parameter',
|
|
|
|
Value='value',
|
|
|
|
Type='String')
|
|
|
|
|
|
|
|
response = client.get_parameters(Names=['test'])
|
|
|
|
len(response['Parameters']).should.equal(1)
|
|
|
|
|
|
|
|
result = client.delete_parameters(Names=['test', 'invalid'])
|
|
|
|
len(result['DeletedParameters']).should.equal(1)
|
|
|
|
len(result['InvalidParameters']).should.equal(1)
|
|
|
|
|
|
|
|
response = client.get_parameters(Names=['test'])
|
|
|
|
len(response['Parameters']).should.equal(0)
|
2017-04-18 17:09:10 +00:00
|
|
|
|
2017-09-18 20:46:07 +00:00
|
|
|
|
2017-11-06 09:44:54 +00:00
|
|
|
@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')
|
|
|
|
|
2018-04-30 18:02:47 +00:00
|
|
|
client.put_parameter(
|
|
|
|
Name='/baz/name1',
|
|
|
|
Description='A test parameter (list)',
|
|
|
|
Value='value1,value2,value3',
|
|
|
|
Type='StringList')
|
|
|
|
|
|
|
|
client.put_parameter(
|
|
|
|
Name='/baz/name2',
|
|
|
|
Description='A test parameter',
|
|
|
|
Value='value1',
|
|
|
|
Type='String')
|
|
|
|
|
|
|
|
client.put_parameter(
|
|
|
|
Name='/baz/pwd',
|
|
|
|
Description='A secure test parameter',
|
|
|
|
Value='my_secret',
|
|
|
|
Type='SecureString',
|
|
|
|
KeyId='alias/aws/ssm')
|
|
|
|
|
2018-07-13 09:24:11 +00:00
|
|
|
client.put_parameter(
|
|
|
|
Name='foo',
|
|
|
|
Description='A test parameter',
|
|
|
|
Value='bar',
|
|
|
|
Type='String')
|
|
|
|
|
|
|
|
client.put_parameter(
|
|
|
|
Name='baz',
|
|
|
|
Description='A test parameter',
|
|
|
|
Value='qux',
|
|
|
|
Type='String')
|
|
|
|
|
|
|
|
response = client.get_parameters_by_path(Path='/', Recursive=False)
|
|
|
|
len(response['Parameters']).should.equal(2)
|
|
|
|
{p['Value'] for p in response['Parameters']}.should.equal(
|
|
|
|
set(['bar', 'qux'])
|
|
|
|
)
|
|
|
|
|
|
|
|
response = client.get_parameters_by_path(Path='/', Recursive=True)
|
|
|
|
len(response['Parameters']).should.equal(9)
|
|
|
|
|
2017-11-06 09:44:54 +00:00
|
|
|
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'])
|
|
|
|
)
|
|
|
|
|
2018-04-30 18:02:47 +00:00
|
|
|
response = client.get_parameters_by_path(Path='/baz')
|
|
|
|
len(response['Parameters']).should.equal(3)
|
|
|
|
|
|
|
|
filters = [{
|
|
|
|
'Key': 'Type',
|
|
|
|
'Option': 'Equals',
|
|
|
|
'Values': ['StringList'],
|
|
|
|
}]
|
|
|
|
response = client.get_parameters_by_path(Path='/baz', ParameterFilters=filters)
|
|
|
|
len(response['Parameters']).should.equal(1)
|
|
|
|
{p['Name'] for p in response['Parameters']}.should.equal(
|
|
|
|
set(['/baz/name1'])
|
|
|
|
)
|
|
|
|
|
|
|
|
# note: 'Option' is optional (default: 'Equals')
|
|
|
|
filters = [{
|
|
|
|
'Key': 'Type',
|
|
|
|
'Values': ['StringList'],
|
|
|
|
}]
|
|
|
|
response = client.get_parameters_by_path(Path='/baz', ParameterFilters=filters)
|
|
|
|
len(response['Parameters']).should.equal(1)
|
|
|
|
{p['Name'] for p in response['Parameters']}.should.equal(
|
|
|
|
set(['/baz/name1'])
|
|
|
|
)
|
|
|
|
|
|
|
|
filters = [{
|
|
|
|
'Key': 'Type',
|
|
|
|
'Option': 'Equals',
|
|
|
|
'Values': ['String'],
|
|
|
|
}]
|
|
|
|
response = client.get_parameters_by_path(Path='/baz', ParameterFilters=filters)
|
|
|
|
len(response['Parameters']).should.equal(1)
|
|
|
|
{p['Name'] for p in response['Parameters']}.should.equal(
|
|
|
|
set(['/baz/name2'])
|
|
|
|
)
|
|
|
|
|
|
|
|
filters = [{
|
|
|
|
'Key': 'Type',
|
|
|
|
'Option': 'Equals',
|
|
|
|
'Values': ['String', 'SecureString'],
|
|
|
|
}]
|
|
|
|
response = client.get_parameters_by_path(Path='/baz', ParameterFilters=filters)
|
|
|
|
len(response['Parameters']).should.equal(2)
|
|
|
|
{p['Name'] for p in response['Parameters']}.should.equal(
|
|
|
|
set(['/baz/name2', '/baz/pwd'])
|
|
|
|
)
|
|
|
|
|
|
|
|
filters = [{
|
|
|
|
'Key': 'Type',
|
|
|
|
'Option': 'BeginsWith',
|
|
|
|
'Values': ['String'],
|
|
|
|
}]
|
|
|
|
response = client.get_parameters_by_path(Path='/baz', ParameterFilters=filters)
|
|
|
|
len(response['Parameters']).should.equal(2)
|
|
|
|
{p['Name'] for p in response['Parameters']}.should.equal(
|
|
|
|
set(['/baz/name1', '/baz/name2'])
|
|
|
|
)
|
|
|
|
|
|
|
|
filters = [{
|
|
|
|
'Key': 'KeyId',
|
|
|
|
'Option': 'Equals',
|
|
|
|
'Values': ['alias/aws/ssm'],
|
|
|
|
}]
|
|
|
|
response = client.get_parameters_by_path(Path='/baz', ParameterFilters=filters)
|
|
|
|
len(response['Parameters']).should.equal(1)
|
|
|
|
{p['Name'] for p in response['Parameters']}.should.equal(
|
|
|
|
set(['/baz/pwd'])
|
|
|
|
)
|
|
|
|
|
2017-11-06 09:44:54 +00:00
|
|
|
|
2017-04-18 17:09:10 +00:00
|
|
|
@mock_ssm
|
|
|
|
def test_put_parameter():
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
2018-03-21 15:56:57 +00:00
|
|
|
response = client.put_parameter(
|
2017-04-18 17:09:10 +00:00
|
|
|
Name='test',
|
|
|
|
Description='A test parameter',
|
|
|
|
Value='value',
|
|
|
|
Type='String')
|
|
|
|
|
2018-03-21 15:56:57 +00:00
|
|
|
response['Version'].should.equal(1)
|
|
|
|
|
2017-04-18 17:09:10 +00:00
|
|
|
response = client.get_parameters(
|
|
|
|
Names=[
|
|
|
|
'test'
|
|
|
|
],
|
|
|
|
WithDecryption=False)
|
|
|
|
|
|
|
|
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')
|
2017-11-17 08:57:11 +00:00
|
|
|
response['Parameters'][0]['Version'].should.equal(1)
|
|
|
|
|
2018-03-21 15:56:57 +00:00
|
|
|
try:
|
|
|
|
client.put_parameter(
|
|
|
|
Name='test',
|
|
|
|
Description='desc 2',
|
|
|
|
Value='value 2',
|
|
|
|
Type='String')
|
|
|
|
raise RuntimeError('Should fail')
|
|
|
|
except botocore.exceptions.ClientError as err:
|
|
|
|
err.operation_name.should.equal('PutParameter')
|
|
|
|
err.response['Error']['Message'].should.equal('Parameter test already exists.')
|
2017-11-17 08:57:11 +00:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2018-03-21 15:56:57 +00:00
|
|
|
response = client.put_parameter(
|
2017-11-17 08:57:11 +00:00
|
|
|
Name='test',
|
|
|
|
Description='desc 3',
|
|
|
|
Value='value 3',
|
|
|
|
Type='String',
|
|
|
|
Overwrite=True)
|
|
|
|
|
2018-03-21 15:56:57 +00:00
|
|
|
response['Version'].should.equal(2)
|
|
|
|
|
2017-11-17 08:57:11 +00:00
|
|
|
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)
|
2017-09-18 13:13:02 +00:00
|
|
|
|
|
|
|
|
|
|
|
@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')
|
|
|
|
|
|
|
|
response = client.get_parameter(
|
|
|
|
Name='test',
|
|
|
|
WithDecryption=False)
|
|
|
|
|
|
|
|
response['Parameter']['Name'].should.equal('test')
|
|
|
|
response['Parameter']['Value'].should.equal('value')
|
|
|
|
response['Parameter']['Type'].should.equal('String')
|
2017-04-18 17:09:10 +00:00
|
|
|
|
|
|
|
|
2017-09-18 20:27:56 +00:00
|
|
|
@mock_ssm
|
|
|
|
def test_get_nonexistant_parameter():
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
|
|
|
try:
|
|
|
|
client.get_parameter(
|
|
|
|
Name='test_noexist',
|
|
|
|
WithDecryption=False)
|
|
|
|
raise RuntimeError('Should of failed')
|
|
|
|
except botocore.exceptions.ClientError as err:
|
|
|
|
err.operation_name.should.equal('GetParameter')
|
|
|
|
err.response['Error']['Message'].should.equal('Parameter test_noexist not found.')
|
|
|
|
|
|
|
|
|
2017-06-20 18:47:53 +00:00
|
|
|
@mock_ssm
|
|
|
|
def test_describe_parameters():
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
|
|
|
client.put_parameter(
|
|
|
|
Name='test',
|
|
|
|
Description='A test parameter',
|
|
|
|
Value='value',
|
|
|
|
Type='String')
|
|
|
|
|
|
|
|
response = client.describe_parameters()
|
|
|
|
|
|
|
|
len(response['Parameters']).should.equal(1)
|
|
|
|
response['Parameters'][0]['Name'].should.equal('test')
|
|
|
|
response['Parameters'][0]['Type'].should.equal('String')
|
|
|
|
|
|
|
|
|
|
|
|
@mock_ssm
|
|
|
|
def test_describe_parameters_paging():
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
|
|
|
for i in range(50):
|
|
|
|
client.put_parameter(
|
|
|
|
Name="param-%d" % i,
|
|
|
|
Value="value-%d" % i,
|
|
|
|
Type="String"
|
|
|
|
)
|
|
|
|
|
|
|
|
response = client.describe_parameters()
|
|
|
|
len(response['Parameters']).should.equal(10)
|
|
|
|
response['NextToken'].should.equal('10')
|
|
|
|
|
|
|
|
response = client.describe_parameters(NextToken=response['NextToken'])
|
|
|
|
len(response['Parameters']).should.equal(10)
|
|
|
|
response['NextToken'].should.equal('20')
|
|
|
|
|
|
|
|
response = client.describe_parameters(NextToken=response['NextToken'])
|
|
|
|
len(response['Parameters']).should.equal(10)
|
|
|
|
response['NextToken'].should.equal('30')
|
|
|
|
|
|
|
|
response = client.describe_parameters(NextToken=response['NextToken'])
|
|
|
|
len(response['Parameters']).should.equal(10)
|
|
|
|
response['NextToken'].should.equal('40')
|
|
|
|
|
|
|
|
response = client.describe_parameters(NextToken=response['NextToken'])
|
|
|
|
len(response['Parameters']).should.equal(10)
|
|
|
|
response['NextToken'].should.equal('50')
|
|
|
|
|
|
|
|
response = client.describe_parameters(NextToken=response['NextToken'])
|
|
|
|
len(response['Parameters']).should.equal(0)
|
|
|
|
''.should.equal(response.get('NextToken', ''))
|
|
|
|
|
2017-06-26 18:20:56 +00:00
|
|
|
|
2017-06-20 18:47:53 +00:00
|
|
|
@mock_ssm
|
|
|
|
def test_describe_parameters_filter_names():
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
|
|
|
for i in range(50):
|
|
|
|
p = {
|
|
|
|
'Name': "param-%d" % i,
|
|
|
|
'Value': "value-%d" % i,
|
|
|
|
'Type': "String"
|
|
|
|
}
|
|
|
|
if i % 5 == 0:
|
|
|
|
p['Type'] = 'SecureString'
|
|
|
|
p['KeyId'] = 'a key'
|
|
|
|
client.put_parameter(**p)
|
|
|
|
|
|
|
|
response = client.describe_parameters(Filters=[
|
|
|
|
{
|
|
|
|
'Key': 'Name',
|
2017-06-26 18:17:36 +00:00
|
|
|
'Values': ['param-22']
|
2017-06-20 18:47:53 +00:00
|
|
|
},
|
|
|
|
])
|
2017-06-26 18:17:36 +00:00
|
|
|
len(response['Parameters']).should.equal(1)
|
2017-06-20 18:47:53 +00:00
|
|
|
response['Parameters'][0]['Name'].should.equal('param-22')
|
|
|
|
response['Parameters'][0]['Type'].should.equal('String')
|
|
|
|
''.should.equal(response.get('NextToken', ''))
|
|
|
|
|
2017-06-26 18:20:56 +00:00
|
|
|
|
2017-06-20 18:47:53 +00:00
|
|
|
@mock_ssm
|
|
|
|
def test_describe_parameters_filter_type():
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
|
|
|
for i in range(50):
|
|
|
|
p = {
|
|
|
|
'Name': "param-%d" % i,
|
|
|
|
'Value': "value-%d" % i,
|
|
|
|
'Type': "String"
|
|
|
|
}
|
|
|
|
if i % 5 == 0:
|
|
|
|
p['Type'] = 'SecureString'
|
|
|
|
p['KeyId'] = 'a key'
|
|
|
|
client.put_parameter(**p)
|
|
|
|
|
|
|
|
response = client.describe_parameters(Filters=[
|
|
|
|
{
|
|
|
|
'Key': 'Type',
|
|
|
|
'Values': ['SecureString']
|
|
|
|
},
|
|
|
|
])
|
|
|
|
len(response['Parameters']).should.equal(10)
|
|
|
|
response['Parameters'][0]['Type'].should.equal('SecureString')
|
|
|
|
'10'.should.equal(response.get('NextToken', ''))
|
|
|
|
|
2017-06-26 18:20:56 +00:00
|
|
|
|
2017-06-20 18:47:53 +00:00
|
|
|
@mock_ssm
|
|
|
|
def test_describe_parameters_filter_keyid():
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
|
|
|
for i in range(50):
|
|
|
|
p = {
|
|
|
|
'Name': "param-%d" % i,
|
|
|
|
'Value': "value-%d" % i,
|
|
|
|
'Type': "String"
|
|
|
|
}
|
|
|
|
if i % 5 == 0:
|
|
|
|
p['Type'] = 'SecureString'
|
|
|
|
p['KeyId'] = "key:%d" % i
|
|
|
|
client.put_parameter(**p)
|
|
|
|
|
|
|
|
response = client.describe_parameters(Filters=[
|
|
|
|
{
|
|
|
|
'Key': 'KeyId',
|
2017-06-26 18:17:36 +00:00
|
|
|
'Values': ['key:10']
|
2017-06-20 18:47:53 +00:00
|
|
|
},
|
|
|
|
])
|
2017-06-26 18:17:36 +00:00
|
|
|
len(response['Parameters']).should.equal(1)
|
2017-06-20 18:47:53 +00:00
|
|
|
response['Parameters'][0]['Name'].should.equal('param-10')
|
|
|
|
response['Parameters'][0]['Type'].should.equal('SecureString')
|
|
|
|
''.should.equal(response.get('NextToken', ''))
|
|
|
|
|
2018-07-13 09:24:11 +00:00
|
|
|
|
2017-11-17 08:57:11 +00:00
|
|
|
@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)
|
2017-06-26 18:20:56 +00:00
|
|
|
|
2018-07-13 09:24:11 +00:00
|
|
|
|
2017-08-16 10:49:03 +00:00
|
|
|
@mock_ssm
|
|
|
|
def test_get_parameter_invalid():
|
|
|
|
client = client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
response = client.get_parameters(
|
|
|
|
Names=[
|
|
|
|
'invalid'
|
|
|
|
],
|
|
|
|
WithDecryption=False)
|
|
|
|
|
|
|
|
len(response['Parameters']).should.equal(0)
|
|
|
|
len(response['InvalidParameters']).should.equal(1)
|
|
|
|
response['InvalidParameters'][0].should.equal('invalid')
|
|
|
|
|
|
|
|
|
2017-04-18 17:09:10 +00:00
|
|
|
@mock_ssm
|
|
|
|
def test_put_parameter_secure_default_kms():
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
|
|
|
client.put_parameter(
|
|
|
|
Name='test',
|
|
|
|
Description='A test parameter',
|
|
|
|
Value='value',
|
|
|
|
Type='SecureString')
|
|
|
|
|
|
|
|
response = client.get_parameters(
|
|
|
|
Names=[
|
|
|
|
'test'
|
|
|
|
],
|
|
|
|
WithDecryption=False)
|
|
|
|
|
|
|
|
len(response['Parameters']).should.equal(1)
|
|
|
|
response['Parameters'][0]['Name'].should.equal('test')
|
|
|
|
response['Parameters'][0]['Value'].should.equal('kms:default:value')
|
|
|
|
response['Parameters'][0]['Type'].should.equal('SecureString')
|
|
|
|
|
|
|
|
response = client.get_parameters(
|
|
|
|
Names=[
|
|
|
|
'test'
|
|
|
|
],
|
|
|
|
WithDecryption=True)
|
|
|
|
|
|
|
|
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('SecureString')
|
|
|
|
|
|
|
|
|
|
|
|
@mock_ssm
|
|
|
|
def test_put_parameter_secure_custom_kms():
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
|
|
|
client.put_parameter(
|
|
|
|
Name='test',
|
|
|
|
Description='A test parameter',
|
|
|
|
Value='value',
|
|
|
|
Type='SecureString',
|
|
|
|
KeyId='foo')
|
|
|
|
|
|
|
|
response = client.get_parameters(
|
|
|
|
Names=[
|
|
|
|
'test'
|
|
|
|
],
|
|
|
|
WithDecryption=False)
|
|
|
|
|
|
|
|
len(response['Parameters']).should.equal(1)
|
|
|
|
response['Parameters'][0]['Name'].should.equal('test')
|
|
|
|
response['Parameters'][0]['Value'].should.equal('kms:foo:value')
|
|
|
|
response['Parameters'][0]['Type'].should.equal('SecureString')
|
|
|
|
|
|
|
|
response = client.get_parameters(
|
|
|
|
Names=[
|
|
|
|
'test'
|
|
|
|
],
|
|
|
|
WithDecryption=True)
|
|
|
|
|
|
|
|
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('SecureString')
|
2017-07-26 11:38:12 +00:00
|
|
|
|
2017-09-18 20:46:07 +00:00
|
|
|
|
2017-07-26 11:38:12 +00:00
|
|
|
@mock_ssm
|
|
|
|
def test_add_remove_list_tags_for_resource():
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
|
|
|
client.add_tags_to_resource(
|
|
|
|
ResourceId='test',
|
|
|
|
ResourceType='Parameter',
|
|
|
|
Tags=[{'Key': 'test-key', 'Value': 'test-value'}]
|
|
|
|
)
|
|
|
|
|
|
|
|
response = client.list_tags_for_resource(
|
|
|
|
ResourceId='test',
|
|
|
|
ResourceType='Parameter'
|
|
|
|
)
|
|
|
|
len(response['TagList']).should.equal(1)
|
|
|
|
response['TagList'][0]['Key'].should.equal('test-key')
|
|
|
|
response['TagList'][0]['Value'].should.equal('test-value')
|
|
|
|
|
|
|
|
client.remove_tags_from_resource(
|
|
|
|
ResourceId='test',
|
|
|
|
ResourceType='Parameter',
|
|
|
|
TagKeys=['test-key']
|
|
|
|
)
|
|
|
|
|
|
|
|
response = client.list_tags_for_resource(
|
|
|
|
ResourceId='test',
|
|
|
|
ResourceType='Parameter'
|
|
|
|
)
|
|
|
|
len(response['TagList']).should.equal(0)
|
2018-02-19 15:10:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
@mock_ssm
|
|
|
|
def test_send_command():
|
|
|
|
ssm_document = 'AWS-RunShellScript'
|
2018-02-19 15:58:46 +00:00
|
|
|
params = {'commands': ['#!/bin/bash\necho \'hello world\'']}
|
2018-02-19 15:10:52 +00:00
|
|
|
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
2018-02-19 15:59:52 +00:00
|
|
|
# note the timeout is determined server side, so this is a simpler check.
|
2018-02-19 15:58:46 +00:00
|
|
|
before = datetime.datetime.now()
|
2018-02-19 15:59:52 +00:00
|
|
|
|
2018-02-19 15:10:52 +00:00
|
|
|
response = client.send_command(
|
|
|
|
InstanceIds=['i-123456'],
|
|
|
|
DocumentName=ssm_document,
|
2018-02-19 15:58:46 +00:00
|
|
|
Parameters=params,
|
|
|
|
OutputS3Region='us-east-2',
|
|
|
|
OutputS3BucketName='the-bucket',
|
|
|
|
OutputS3KeyPrefix='pref'
|
2018-02-19 15:10:52 +00:00
|
|
|
)
|
2018-02-19 15:58:46 +00:00
|
|
|
cmd = response['Command']
|
2018-02-19 15:10:52 +00:00
|
|
|
|
2018-02-19 15:58:46 +00:00
|
|
|
cmd['CommandId'].should_not.be(None)
|
|
|
|
cmd['DocumentName'].should.equal(ssm_document)
|
|
|
|
cmd['Parameters'].should.equal(params)
|
|
|
|
|
|
|
|
cmd['OutputS3Region'].should.equal('us-east-2')
|
|
|
|
cmd['OutputS3BucketName'].should.equal('the-bucket')
|
|
|
|
cmd['OutputS3KeyPrefix'].should.equal('pref')
|
|
|
|
|
|
|
|
cmd['ExpiresAfter'].should.be.greater_than(before)
|
2018-04-25 20:27:07 +00:00
|
|
|
|
|
|
|
# test sending a command without any optional parameters
|
|
|
|
response = client.send_command(
|
|
|
|
DocumentName=ssm_document)
|
|
|
|
|
|
|
|
cmd = response['Command']
|
|
|
|
|
|
|
|
cmd['CommandId'].should_not.be(None)
|
|
|
|
cmd['DocumentName'].should.equal(ssm_document)
|
|
|
|
|
|
|
|
|
|
|
|
@mock_ssm
|
|
|
|
def test_list_commands():
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
|
|
|
ssm_document = 'AWS-RunShellScript'
|
|
|
|
params = {'commands': ['#!/bin/bash\necho \'hello world\'']}
|
|
|
|
|
|
|
|
response = client.send_command(
|
|
|
|
InstanceIds=['i-123456'],
|
|
|
|
DocumentName=ssm_document,
|
|
|
|
Parameters=params,
|
|
|
|
OutputS3Region='us-east-2',
|
|
|
|
OutputS3BucketName='the-bucket',
|
|
|
|
OutputS3KeyPrefix='pref')
|
|
|
|
|
|
|
|
cmd = response['Command']
|
|
|
|
cmd_id = cmd['CommandId']
|
|
|
|
|
|
|
|
# get the command by id
|
|
|
|
response = client.list_commands(
|
|
|
|
CommandId=cmd_id)
|
|
|
|
|
|
|
|
cmds = response['Commands']
|
|
|
|
len(cmds).should.equal(1)
|
|
|
|
cmds[0]['CommandId'].should.equal(cmd_id)
|
|
|
|
|
|
|
|
# add another command with the same instance id to test listing by
|
|
|
|
# instance id
|
|
|
|
client.send_command(
|
|
|
|
InstanceIds=['i-123456'],
|
|
|
|
DocumentName=ssm_document)
|
|
|
|
|
|
|
|
response = client.list_commands(
|
|
|
|
InstanceId='i-123456')
|
|
|
|
|
|
|
|
cmds = response['Commands']
|
|
|
|
len(cmds).should.equal(2)
|
|
|
|
|
|
|
|
for cmd in cmds:
|
|
|
|
cmd['InstanceIds'].should.contain('i-123456')
|
|
|
|
|
|
|
|
# test the error case for an invalid command id
|
|
|
|
with assert_raises(ClientError):
|
|
|
|
response = client.list_commands(
|
|
|
|
CommandId=str(uuid.uuid4()))
|
2018-07-24 20:15:53 +00:00
|
|
|
|
|
|
|
@mock_ssm
|
|
|
|
def test_get_command_invocation():
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
|
|
|
ssm_document = 'AWS-RunShellScript'
|
|
|
|
params = {'commands': ['#!/bin/bash\necho \'hello world\'']}
|
|
|
|
|
|
|
|
response = client.send_command(
|
|
|
|
InstanceIds=['i-123456', 'i-234567', 'i-345678'],
|
|
|
|
DocumentName=ssm_document,
|
|
|
|
Parameters=params,
|
|
|
|
OutputS3Region='us-east-2',
|
|
|
|
OutputS3BucketName='the-bucket',
|
|
|
|
OutputS3KeyPrefix='pref')
|
|
|
|
|
|
|
|
cmd = response['Command']
|
|
|
|
cmd_id = cmd['CommandId']
|
|
|
|
|
|
|
|
instance_id = 'i-345678'
|
|
|
|
invocation_response = client.get_command_invocation(
|
|
|
|
CommandId=cmd_id,
|
|
|
|
InstanceId=instance_id,
|
|
|
|
PluginName='aws:runShellScript')
|
|
|
|
|
|
|
|
invocation_response['CommandId'].should.equal(cmd_id)
|
|
|
|
invocation_response['InstanceId'].should.equal(instance_id)
|
|
|
|
|
|
|
|
# test the error case for an invalid instance id
|
|
|
|
with assert_raises(ClientError):
|
|
|
|
invocation_response = client.get_command_invocation(
|
|
|
|
CommandId=cmd_id,
|
|
|
|
InstanceId='i-FAKE')
|
|
|
|
|
|
|
|
# test the error case for an invalid plugin name
|
|
|
|
with assert_raises(ClientError):
|
|
|
|
invocation_response = client.get_command_invocation(
|
|
|
|
CommandId=cmd_id,
|
|
|
|
InstanceId=instance_id,
|
|
|
|
PluginName='FAKE')
|
2018-07-25 18:24:01 +00:00
|
|
|
|
|
|
|
@mock_ssm
|
|
|
|
@mock_cloudformation
|
|
|
|
def test_get_command_invocations_from_stack():
|
|
|
|
stack_template = {
|
|
|
|
"AWSTemplateFormatVersion": "2010-09-09",
|
|
|
|
"Description": "Test Stack",
|
|
|
|
"Resources": {
|
|
|
|
"EC2Instance1": {
|
|
|
|
"Type": "AWS::EC2::Instance",
|
|
|
|
"Properties": {
|
|
|
|
"ImageId": "ami-test-image-id",
|
|
|
|
"KeyName": "test",
|
|
|
|
"InstanceType": "t2.micro",
|
|
|
|
"Tags": [
|
|
|
|
{
|
|
|
|
"Key": "Test Description",
|
|
|
|
"Value": "Test tag"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"Key": "Test Name",
|
|
|
|
"Value": "Name tag for tests"
|
|
|
|
}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"Outputs": {
|
|
|
|
"test": {
|
|
|
|
"Description": "Test Output",
|
|
|
|
"Value": "Test output value",
|
|
|
|
"Export": {
|
|
|
|
"Name": "Test value to export"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"PublicIP": {
|
|
|
|
"Value": "Test public ip"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cloudformation_client = boto3.client(
|
|
|
|
'cloudformation',
|
|
|
|
region_name='us-east-1')
|
|
|
|
|
|
|
|
stack_template_str = json.dumps(stack_template)
|
|
|
|
|
|
|
|
response = cloudformation_client.create_stack(
|
|
|
|
StackName='test_stack',
|
|
|
|
TemplateBody=stack_template_str,
|
|
|
|
Capabilities=('CAPABILITY_IAM', ))
|
|
|
|
|
|
|
|
client = boto3.client('ssm', region_name='us-east-1')
|
|
|
|
|
|
|
|
ssm_document = 'AWS-RunShellScript'
|
|
|
|
params = {'commands': ['#!/bin/bash\necho \'hello world\'']}
|
|
|
|
|
|
|
|
response = client.send_command(
|
|
|
|
Targets=[{
|
|
|
|
'Key': 'tag:aws:cloudformation:stack-name',
|
|
|
|
'Values': ('test_stack', )}],
|
|
|
|
DocumentName=ssm_document,
|
|
|
|
Parameters=params,
|
|
|
|
OutputS3Region='us-east-2',
|
|
|
|
OutputS3BucketName='the-bucket',
|
|
|
|
OutputS3KeyPrefix='pref')
|
|
|
|
|
|
|
|
cmd = response['Command']
|
|
|
|
cmd_id = cmd['CommandId']
|
|
|
|
instance_ids = cmd['InstanceIds']
|
|
|
|
|
|
|
|
invocation_response = client.get_command_invocation(
|
|
|
|
CommandId=cmd_id,
|
|
|
|
InstanceId=instance_ids[0],
|
|
|
|
PluginName='aws:runShellScript')
|