comparison configmix/extras/aws.py @ 282:da1596034954

Implemented an "AWS" namespace to retrieve some AWS-specific metadata
author Franz Glasner <fzglas.hg@dom66.de>
date Mon, 07 Dec 2020 01:06:33 +0100
parents
children 503768f91a05
comparison
equal deleted inserted replaced
281:2ea0aa9fb402 282:da1596034954
1 # -*- coding: utf-8 -*-
2 # :-
3 # :Copyright: (c) 2015-2020, Franz Glasner. All rights reserved.
4 # :License: 3-clause BSD. See LICENSE.txt for details.
5 # :-
6 """AWS namespace implementation
7
8 """
9
10 from __future__ import division, absolute_import, print_function
11
12
13 __all__ = []
14
15
16 import requests
17 import requests.exceptions
18
19
20 _MARKER = object()
21
22
23 URL_META_INSTANCEID = "http://169.254.169.254/latest/meta-data/instance-id"
24 URL_META_REGION = "http://169.254.169.254/latest/meta-data/placement/region"
25 URL_META_AVAILABILITY_ZONE = "http://169.254.169.254/latest/meta-data/availability-zone"
26 URL_DYN_INSTANCE_IDENTITY_DOC = "http://169.254.169.254/latest/dynamic/instance-identity/document"
27 TIMEOUT = 10
28
29 _meta_instanceid = None
30 _meta_region = None
31 _meta_availability_zone = None
32 _dyn_instance_identity_doc = None
33
34
35 def _get_text_req(url):
36 with requests.Session() as sess:
37 try:
38 resp = sess.get(url, timeout=TIMEOUT)
39 resp.raise_for_status()
40 return resp.text
41 except requests.exceptions.RequestException:
42 return _MARKER
43
44
45 def _get_json_req(url):
46 with requests.Session() as sess:
47 try:
48 resp = sess.get(url, timeout=TIMEOUT)
49 resp.raise_for_status()
50 return resp.json()
51 except requests.exceptions.RequestException:
52 return _MARKER
53 except ValueError:
54 # JSON error
55 return _MARKER
56
57
58 def _get_meta_instanceid():
59 global _meta_instanceid
60 if _meta_instanceid is None:
61 _meta_instanceid = _get_text_req(URL_META_INSTANCEID)
62 return _meta_instanceid
63
64
65 def _get_meta_region():
66 global _meta_region
67 if _meta_region is None:
68 _meta_region = _get_text_req(URL_META_REGION)
69 return _meta_region
70
71
72 def _get_meta_avzone():
73 global _meta_availability_zone
74 if _meta_availability_zone is None:
75 _meta_availability_zone = _get_text_req(URL_META_AVAILABILITY_ZONE)
76 return _meta_availability_zone
77
78
79 def _get_dyn_instance_identity_doc():
80 global _dyn_instance_identity_doc
81 if _dyn_instance_identity_doc is None:
82 _dyn_instance_identity_doc = _get_json_req(
83 URL_DYN_INSTANCE_IDENTITY_DOC)
84 return _dyn_instance_identity_doc
85
86
87 def _awslookup(name, default=_MARKER):
88 if name == "metadata.instance-id":
89 v = _get_meta_instanceid()
90 elif name == "metadata.placement.region":
91 v = _get_meta_region()
92 elif name == "metadata.placement.availability-zone":
93 v = _get_meta_avzone()
94 elif name.startswith("dynamic.instance-identity."):
95 idoc = _get_dyn_instance_identity_doc()
96 if idoc is _MARKER:
97 v = _MARKER
98 else:
99 v = idoc.get(name[26:], _MARKER)
100 else:
101 v = _MARKER
102 if v is _MARKER:
103 if default is _MARKER:
104 raise KeyError("key %r not found in the AWS namespace" % name)
105 else:
106 return default
107 return v