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

1import os 

2import re 

3import subprocess 

4 

5from cfg_checker.common.const import all_roles_map, uknown_code 

6from cfg_checker.common.exception import ConfigException 

7 

8pkg_dir = os.path.dirname(__file__) 

9pkg_dir = os.path.join(pkg_dir, os.pardir, os.pardir) 

10pkg_dir = os.path.normpath(pkg_dir) 

11pkg_dir = os.path.abspath(pkg_dir) 

12 

13 

14def shell(command): 

15 _ps = subprocess.Popen( 

16 command.split(), 

17 stdout=subprocess.PIPE 

18 ).communicate()[0].decode() 

19 

20 return _ps 

21 

22 

23def merge_dict(source, destination): 

24 """ 

25 Dict merger, thanks to vincent 

26 http://stackoverflow.com/questions/20656135/python-deep-merge-dictionary-data 

27 

28 >>> a = { 'first' : { 'all_rows' : { 'pass' : 'dog', 'number' : '1' } } } 

29 >>> b = { 'first' : { 'all_rows' : { 'fail' : 'cat', 'number' : '5' } } } 

30 >>> merge(b, a) == { 

31 'first': { 

32 'all_rows': { 

33 'pass': 'dog', 

34 'fail': 'cat', 

35 'number': '5' 

36 } 

37 } 

38 } 

39 True 

40 """ 

41 for key, value in source.items(): 

42 if isinstance(value, dict): 

43 # get node or create one 

44 node = destination.setdefault(key, {}) 

45 merge_dict(value, node) 

46 else: 

47 destination[key] = value 

48 

49 return destination 

50 

51 

52class Utils(object): 

53 @staticmethod 

54 def validate_name(fqdn, message=False): 

55 """ 

56 Function that tries to validate node name. 

57 Checks if code contains letters, has '.' in it, 

58 roles map contains code's role 

59 

60 :param fqdn: node FQDN name to supply for the check 

61 :param message: True if validate should return error check message 

62 :return: False if checks failed, True if all checks passed 

63 """ 

64 _message = "# Validation passed" 

65 

66 def _result(): 

67 return (True, _message) if message else True 

68 

69 # node role code checks 

70 _code = re.findall(r"[a-zA-Z]+", fqdn.split('.')[0]) 

71 if len(_code) > 0: 

72 if _code[0] in all_roles_map: 

73 return _result() 

74 else: 

75 # log warning here 

76 _message = "# Node code is unknown, '{}'. " \ 

77 "# Please, update map".format(_code) 

78 else: 

79 # log warning here 

80 _message = "# Node name is invalid, '{}'".format(fqdn) 

81 

82 # put other checks here 

83 

84 # output result 

85 return _result() 

86 

87 @staticmethod 

88 def node_string_to_list(node_string): 

89 # supplied var should contain node list 

90 # if there is no ',' -> use space as a delimiter 

91 if node_string is not None: 

92 if node_string.find(',') < 0: 

93 return node_string.split(' ') 

94 else: 

95 return node_string.split(',') 

96 else: 

97 return [] 

98 

99 def get_node_code(self, fqdn): 

100 # validate 

101 _isvalid, _message = self.validate_name(fqdn, message=True) 

102 _code = re.findall( 

103 r"[a-zA-Z]+?(?=(?:[0-9]+$)|(?:\-+?)|(?:\_+?)|$)", 

104 fqdn.split('.')[0] 

105 ) 

106 # check if it is valid and raise if not 

107 if _isvalid: 

108 # try to match it with ones in map 

109 _c = _code[0] 

110 match = any([r in _c for r in all_roles_map.keys()]) 

111 if match: 

112 # no match, try to find it 

113 match = False 

114 for r in all_roles_map.keys(): 

115 _idx = _c.find(r) 

116 if _idx > -1: 

117 _c = _c[_idx:] 

118 match = True 

119 break 

120 if match: 

121 return _c 

122 else: 

123 return uknown_code 

124 else: 

125 return uknown_code 

126 else: 

127 raise ConfigException(_message) 

128 

129 def get_nodes_list(self, env, nodes_list): 

130 _list = [] 

131 if env is None: 

132 # nothing supplied, use the one in repo 

133 try: 

134 if not nodes_list: 

135 return [] 

136 with open(os.path.join(pkg_dir, nodes_list)) as _f: 

137 _list.extend(_f.read().splitlines()) 

138 except IOError as e: 

139 raise ConfigException("# Error while loading file, '{}': " 

140 "{}".format(e.filename, e.strerror)) 

141 else: 

142 _list.extend(self.node_string_to_list(env)) 

143 

144 # validate names 

145 _invalid = [] 

146 _valid = [] 

147 for idx in range(len(_list)): 

148 _name = _list[idx] 

149 if not self.validate_name(_name): 

150 _invalid.append(_name) 

151 else: 

152 _valid.append(_name) 

153 

154 return _valid 

155 

156 

157utils = Utils()