From 25b048811479e4d7ddc4baa626fb9b51ba56ed71 Mon Sep 17 00:00:00 2001 From: Daniel Wallace Date: Fri, 11 Nov 2016 13:29:40 -0600 Subject: [PATCH] Add grains for the cloud metadata server My understanding is that this should always appear at 169.254.169.254. This is specifically used with ec2 and openstack, and possible some other cloud providers, but this format should work for the two I know of. Closes #37436 --- salt/grains/metadata.py | 51 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 salt/grains/metadata.py diff --git a/salt/grains/metadata.py b/salt/grains/metadata.py new file mode 100644 index 0000000000..13b8542bb6 --- /dev/null +++ b/salt/grains/metadata.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +''' +Grains from cloud metadata servers at 169.254.169.254 + +.. versionadded:: Nitrogen + +:depends: requests +''' +from __future__ import absolute_import + +# Import python libs +import os +import socket + +# Import salt libs +import salt.utils.http as http + + +# metadata server information +IP = '169.254.169.254' +HOST = 'http://{0}/'.format(IP) + + +def __virtual__(): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + result = sock.connect_ex((IP, 80)) + if result != 0: + return False + if http.query(os.path.join(HOST, 'latest/'), status=True).get('status') != 200: + return False + return True + + +def _search(prefix="latest/"): + ''' + Recursively look up all grains in the metadata server + ''' + ret = {} + for line in http.query(os.path.join(HOST, prefix))['body'].split('\n'): + if line.endswith('/'): + ret[line[:-1]] = _search(prefix=os.path.join(prefix, line)) + elif '=' in line: + key, value = line.split('=') + ret[value] = _search(prefix=os.path.join(prefix, key)) + else: + ret[line] = http.query(os.path.join(HOST, prefix, line))['body'] + return ret + + +def metadata(): + return _search()