Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

# Copyright (c) 2017 Ansible Project 

# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 

 

# Make coding more python3-ish 

from __future__ import (absolute_import, division, print_function) 

__metaclass__ = type 

 

import os 

import re 

 

from copy import deepcopy 

 

from ansible import constants as C 

from ansible.module_utils._text import to_text 

from ansible.module_utils.six import string_types 

from ansible.plugins.loader import connection_loader 

 

try: 

from __main__ import display 

except ImportError: 

from ansible.utils.display import Display 

display = Display() 

 

 

def strip_internal_keys(dirty, exceptions=None): 

''' 

All keys starting with _ansible_ are internal, so create a copy of the 'dirty' dict 

and remove them from the clean one before returning it 

''' 

 

if exceptions is None: 

exceptions = () 

clean = dirty.copy() 

for k in dirty.keys(): 

if isinstance(k, string_types) and k.startswith('_ansible_'): 

if k not in exceptions: 

del clean[k] 

elif isinstance(dirty[k], dict): 

clean[k] = strip_internal_keys(dirty[k]) 

return clean 

 

 

def remove_internal_keys(data): 

''' 

More nuanced version of strip_internal_keys 

''' 

for key in list(data.keys()): 

48 ↛ 49line 48 didn't jump to line 49, because the condition on line 48 was never true if (key.startswith('_ansible_') and key != '_ansible_parsed') or key in C.INTERNAL_RESULT_KEYS: 

display.warning("Removed unexpected internal key in module return: %s = %s" % (key, data[key])) 

del data[key] 

 

# remove bad/empty internal keys 

for key in ['warnings', 'deprecations']: 

if key in data and not data[key]: 

del data[key] 

 

 

def clean_facts(facts): 

''' remove facts that can override internal keys or otherwise deemed unsafe ''' 

data = deepcopy(facts) 

 

remove_keys = set() 

fact_keys = set(data.keys()) 

# first we add all of our magic variable names to the set of 

# keys we want to remove from facts 

for magic_var in C.MAGIC_VARIABLE_MAPPING: 

remove_keys.update(fact_keys.intersection(C.MAGIC_VARIABLE_MAPPING[magic_var])) 

# next we remove any connection plugin specific vars 

for conn_path in connection_loader.all(path_only=True): 

try: 

conn_name = os.path.splitext(os.path.basename(conn_path))[0] 

re_key = re.compile('^ansible_%s_' % conn_name) 

for fact_key in fact_keys: 

# most lightweight VM or container tech creates devices with this pattern, this avoids filtering them out 

75 ↛ 76line 75 didn't jump to line 76, because the condition on line 75 was never true if re_key.match(fact_key) and not fact_key.endswith(('_bridge', '_gwbridge')): 

remove_keys.add(fact_key) 

except AttributeError: 

pass 

 

# remove some KNOWN keys 

for hard in C.RESTRICTED_RESULT_KEYS + C.INTERNAL_RESULT_KEYS: 

82 ↛ 83line 82 didn't jump to line 83, because the condition on line 82 was never true if hard in fact_keys: 

remove_keys.add(hard) 

 

# finally, we search for interpreter keys to remove 

re_interp = re.compile('^ansible_.*_interpreter$') 

for fact_key in fact_keys: 

88 ↛ 89line 88 didn't jump to line 89, because the condition on line 88 was never true if re_interp.match(fact_key): 

remove_keys.add(fact_key) 

# then we remove them (except for ssh host keys) 

91 ↛ 92line 91 didn't jump to line 92, because the loop on line 91 never started for r_key in remove_keys: 

if not r_key.startswith('ansible_ssh_host_key_'): 

try: 

r_val = to_text(data[r_key]) 

if len(r_val) > 24: 

r_val = '%s ... %s' % (r_val[:13], r_val[-6:]) 

except Exception: 

r_val = ' <failed to convert value to a string> ' 

display.warning("Removed restricted key from module data: %s = %s" % (r_key, r_val)) 

del data[r_key] 

 

return strip_internal_keys(data) 

 

 

def namespace_facts(facts): 

''' return all facts inside 'ansible_facts' w/o an ansible_ prefix ''' 

deprefixed = {} 

for k in facts: 

109 ↛ 111line 109 didn't jump to line 111, because the condition on line 109 was never true if k in ('ansible_local'): 

# exceptions to 'deprefixing' 

deprefixed[k] = deepcopy(facts[k]) 

else: 

deprefixed[k.replace('ansible_', '', 1)] = deepcopy(facts[k]) 

 

return {'ansible_facts': deprefixed}