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

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

# Copyright 2017 RedHat, inc 

# 

# This file is part of Ansible 

# 

# Ansible is free software: you can redistribute it and/or modify 

# it under the terms of the GNU General Public License as published by 

# the Free Software Foundation, either version 3 of the License, or 

# (at your option) any later version. 

# 

# Ansible is distributed in the hope that it will be useful, 

# but WITHOUT ANY WARRANTY; without even the implied warranty of 

# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

# GNU General Public License for more details. 

# 

# You should have received a copy of the GNU General Public License 

# along with Ansible. If not, see <http://www.gnu.org/licenses/>. 

############################################# 

from __future__ import (absolute_import, division, print_function) 

__metaclass__ = type 

 

DOCUMENTATION = ''' 

vars: host_group_vars 

version_added: "2.4" 

short_description: In charge of loading group_vars and host_vars 

description: 

- Loads YAML vars into corresponding groups/hosts in group_vars/ and host_vars/ directories. 

- Files are restricted by extension to one of .yaml, .json, .yml or no extension. 

- Hidden (starting with '.') and backup (ending with '~') files and directories are ignored. 

- Only applies to inventory sources that are existing paths. 

notes: 

- It takes the place of the previously hardcoded group_vars/host_vars loading. 

options: 

_valid_extensions: 

default: [".yml", ".yaml", ".json"] 

description: 

- "Check all of these extensions when looking for 'variable' files which should be YAML or JSON or vaulted versions of these." 

- 'This affects vars_files, include_vars, inventory and vars plugins among others.' 

env: 

- name: ANSIBLE_YAML_FILENAME_EXT 

ini: 

- section: yaml_valid_extensions 

key: defaults 

type: list 

''' 

 

import os 

from ansible import constants as C 

from ansible.errors import AnsibleParserError 

from ansible.module_utils._text import to_bytes, to_native, to_text 

from ansible.plugins.vars import BaseVarsPlugin 

from ansible.inventory.host import Host 

from ansible.inventory.group import Group 

from ansible.utils.vars import combine_vars 

 

FOUND = {} 

 

 

class VarsModule(BaseVarsPlugin): 

 

def get_vars(self, loader, path, entities, cache=True): 

''' parses the inventory file ''' 

 

63 ↛ 64line 63 didn't jump to line 64, because the condition on line 63 was never true if not isinstance(entities, list): 

entities = [entities] 

 

super(VarsModule, self).get_vars(loader, path, entities) 

 

data = {} 

for entity in entities: 

if isinstance(entity, Host): 

subdir = 'host_vars' 

72 ↛ 75line 72 didn't jump to line 75, because the condition on line 72 was never false elif isinstance(entity, Group): 

subdir = 'group_vars' 

else: 

raise AnsibleParserError("Supplied entity must be Host or Group, got %s instead" % (type(entity))) 

 

# avoid 'chroot' type inventory hostnames /path/to/chroot 

78 ↛ 69line 78 didn't jump to line 69, because the condition on line 78 was never false if not entity.name.startswith(os.path.sep): 

try: 

found_files = [] 

# load vars 

opath = os.path.realpath(os.path.join(self._basedir, subdir)) 

key = '%s.%s' % (entity.name, opath) 

if cache and key in FOUND: 

found_files = FOUND[key] 

else: 

b_opath = to_bytes(opath) 

# no need to do much if path does not exist for basedir 

if os.path.exists(b_opath): 

90 ↛ 95line 90 didn't jump to line 95, because the condition on line 90 was never false if os.path.isdir(b_opath): 

self._display.debug("\tprocessing dir %s" % opath) 

found_files = self._find_vars_files(opath, entity.name) 

FOUND[key] = found_files 

else: 

self._display.warning("Found %s that is not a directory, skipping: %s" % (subdir, opath)) 

 

97 ↛ 98line 97 didn't jump to line 98, because the loop on line 97 never started for found in found_files: 

new_data = loader.load_from_file(found, cache=True, unsafe=True) 

if new_data: # ignore empty files 

data = combine_vars(data, new_data) 

 

except Exception as e: 

raise AnsibleParserError(to_native(e)) 

return data 

 

def _find_vars_files(self, path, name): 

""" Find {group,host}_vars files """ 

 

b_path = to_bytes(os.path.join(path, name)) 

found = [] 

 

# first look for w/o extensions 

113 ↛ 114line 113 didn't jump to line 114, because the condition on line 113 was never true if os.path.exists(b_path): 

if os.path.isdir(b_path): 

found.extend(self._get_dir_files(to_text(b_path))) 

else: 

found.append(b_path) 

else: 

# add valid extensions to name 

for ext in C.YAML_FILENAME_EXTENSIONS: 

 

122 ↛ 124line 122 didn't jump to line 124, because the condition on line 122 was never false if '.' in ext: 

full_path = b_path + to_bytes(ext) 

elif ext: 

full_path = b'.'.join([b_path, to_bytes(ext)]) 

else: 

full_path = b_path 

 

129 ↛ 130line 129 didn't jump to line 130, because the condition on line 129 was never true if os.path.exists(full_path) and os.path.isfile(full_path): 

found.append(full_path) 

break 

return found 

 

def _get_dir_files(self, path): 

 

found = [] 

for spath in sorted(os.listdir(path)): 

if not spath.startswith(u'.') and not spath.endswith(u'~'): # skip hidden and backups 

 

ext = os.path.splitext(spath)[-1] 

full_spath = os.path.join(path, spath) 

 

if os.path.isdir(full_spath) and not ext: # recursive search if dir 

found.extend(self._get_dir_files(full_spath)) 

elif os.path.isfile(full_spath) and (not ext or to_text(ext) in C.YAML_FILENAME_EXTENSIONS): 

# only consider files with valid extensions or no extension 

found.append(full_spath) 

 

return found