Last active
August 29, 2015 14:05
-
-
Save reywood/fc752efbdd85a87d5316 to your computer and use it in GitHub Desktop.
Salt state for fetching a file from an S3 bucket. Place s3_file.py in /srv/salt/[ENV]/_states/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import os.path | |
import salt.exceptions | |
from tempfile import mkstemp | |
def get(name, bucket, path, md5, access_key=None, secret_key=None): | |
ret = {'name': name, 'changes': {}, 'result': False, 'comment': ''} | |
if md5 is None or len(md5) != 32: | |
raise salt.exceptions.SaltInvocationError('Argument "md5" does not appear to be a valid hash') | |
current_md5 = _get_current_m5_or_none(name) | |
if os.path.exists(name) and current_md5 == md5: | |
ret['result'] = True | |
ret['comment'] = 'System already in the correct state' | |
return ret | |
ret['changes'] = { | |
'old': 'MD5: {0}'.format(current_md5), | |
'new': 'MD5: {0}'.format(md5), | |
} | |
if __opts__['test'] == True: | |
ret['comment'] = 'The state of "{0}" will be changed.'.format(name) | |
ret['result'] = None | |
return ret | |
_get_file_from_s3(bucket, path, name, access_key, secret_key, md5) | |
ret['comment'] = 'The state of "{0}" was changed!'.format(name) | |
ret['result'] = True | |
return ret | |
def _get_current_m5_or_none(file_path): | |
if os.path.exists(file_path): | |
return __salt__['file.get_hash'](file_path) | |
return None | |
def _get_file_from_s3(bucket, path, file_path, access_key, secret_key, md5): | |
temp_file_path = _get_temp_file_path() | |
s3_get_kwargs = { | |
'bucket': bucket, | |
'path': path, | |
'return_bin': True, | |
'local_file': temp_file_path | |
} | |
if access_key is not None and secret_key is not None: | |
s3_get_kwargs['keyid'] = access_key | |
s3_get_kwargs['key'] = secret_key | |
__salt__['s3.get'](**s3_get_kwargs) | |
_delete_and_raise_if_file_hash_does_not_match(temp_file_path, md5) | |
if os.path.exists(file_path): | |
os.unlink(file_path) | |
os.rename(temp_file_path, file_path) | |
def _get_temp_file_path(): | |
fd, path = mkstemp() | |
os.close(fd) | |
return path | |
def _delete_and_raise_if_file_hash_does_not_match(file_path, expected_md5): | |
actual_md5 = __salt__['file.get_hash'](file_path) | |
if actual_md5 != expected_md5: | |
os.unlink(file_path) | |
message = 'Hash for {0} did not match. expected: {1}, actual: {2}'.format(file_path, expected_md5, actual_md5) | |
raise salt.exceptions.SaltInvocationError(message) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
my_file: | |
s3_file.get: | |
- name: /path/to/file/destination/on/minion | |
- bucket: my-s3-bucket | |
- path: path/to/file/in/s3/bucket | |
- md5: 51e44977f4cb6c39beca301db66be0ea | |
- access_key: AKIAIHDN626R2Z7NFFWQ | |
- secret_key: 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uses salt.modules.s3.get to get the file. This means that you can omit the
access_key
andsecret_key
state params if your minion is an EC2 instance with an IAM role assigned to it. Just make sure the IAM role has access to the S3 file in question.