blob: a48c753f31fc62ba590ca954849f01ce20309e50 [file] [log] [blame]
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +03001#!/usr/bin/python
2# -*- coding: utf-8 -*-
3
4import hashlib
5import os
6import re
7import tarfile
8
9import urllib2
10import yaml
11
12from reclass_tools.helpers import ssh_client
13
14
15def walkfiles(topdir, identity_files=None, verbose=False):
16 if ":" in topdir:
17 host, path = topdir.split(":")
18 private_keys = ssh_client.get_private_keys(os.environ.get("HOME"), identity_files)
19 if "@" in host:
20 username, host = host.split("@")
21 else:
22 username = os.environ.get("USER")
23 remote = ssh_client.SSHClient(
24 host, username=username, private_keys=private_keys)
25
26 walker = remote.walk(path)
27 opener = remote.open
28 prefix = remote.host + ":"
29 isdir = remote.isdir(path, follow_symlink=True)
30 else:
31 walker = os.walk(topdir)
32 opener = open
33 prefix = ''
34 isdir = os.path.isdir(topdir)
35
36 if isdir:
37 for dirName, subdirList, fileList in walker:
38 for filename in fileList:
39 filepath = os.path.join(dirName,filename)
40 if verbose:
41 print (prefix + filepath)
42 with OpenFile(filepath, opener) as log:
43 yield (log)
44 else:
45 if verbose:
46 print (topdir)
47 with OpenFile(topdir, opener) as log:
48 yield (log)
49
50
51def yaml_read(yaml_file):
52 if os.path.isfile(yaml_file):
53 with open(yaml_file, 'r') as f:
54 return yaml.load(f)
55 else:
56 print("\'{}\' is not a file!".format(yaml_file))
57
58
59class OpenFile(object):
60
61 fname = None
62 opener = None
63 readlines = None
64 fobj = None
65
66 def __init__(self, fname, opener):
67 self.fname = fname
68 self.opener = opener
69
70 def get_parser(self):
71 parsers = {'/lastlog': self.fake_parser,
72 '/wtmp': self.fake_parser,
73 '/btmp': self.fake_parser,
74 '/atop.log': self.fake_parser,
75 '/atop_': self.fake_parser,
76 '/atop_current': self.fake_parser,
77 '/supervisord.log': self.docker_parser,
78 '.gz': self.gz_parser,
79 '.bz2': self.gz_parser,
80 }
81 for w in parsers.keys():
82 if w in self.fname:
83 self.readlines = parsers[w]
84 return
85 try:
86 self.fobj = self.opener(self.fname, 'r')
87 self.readlines = self.plaintext_parser
88 except IOError as e:
89 print("Error opening file {0}: {1}".format(self.fname, e))
90 if self.fobj:
91 self.fobj.close()
92 self.fobj = None
93 self.readlines = self.fake_parser
94
95 def plaintext_parser(self):
96 try:
97 for s in self.fobj.readlines():
98 yield s
99 except IOError as e:
100 print("Error reading file {0}: {1}".format(self.fname, e))
101
102 def fake_parser(self):
103 yield ''
104
105 def docker_parser(self):
106 yield ''
107
108 def gz_parser(self):
109 yield ''
110
111 def bz2_parser(self):
112 yield ''
113
114 def __enter__(self):
115 self.get_parser()
116 return self
117
118 def __exit__(self, x, y, z):
119 if self.fobj:
120 self.fobj.close()
121
122
123def get_nested_key(data, path=None):
124 if type(path) is not list:
125 raise("Use 'list' object with key names for 'path'")
126 for key in path:
127 value = data.get(key, None)
128 if value:
129 data = value
130 else:
131 return None
132 return data
133
134def remove_nested_key(data, path=None):
135 if type(path) is not list:
136 raise("Use 'list' object with key names for 'path'")
137
138 # Remove the value from the specified key
139 val = get_nested_key(data, path[:-1])
140 val[path[-1]] = None
141
142 # Clear parent keys if empty
143 while path:
144 val = get_nested_key(data, path)
145 if val:
146 # Non-empty value, nothing to do
147 return
148 else:
149 get_nested_key(data, path[:-1]).pop(path[-1])
150 path = path[:-1]
151
152
Dennis Dmitriev7d91b582017-06-16 02:01:39 +0300153def get_all_reclass_params(paths, identity_files=None, verbose=False):
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +0300154 """Return dict with all used values for each param"""
155 #path = '/srv/salt/reclass/classes'
156 _params = dict()
157 for path in paths:
Dennis Dmitriev7d91b582017-06-16 02:01:39 +0300158 for log in walkfiles(path, identity_files, verbose):
Dennis Dmitrieve56c8b92017-06-16 01:53:16 +0300159 if log.fname.endswith('.yml'):
160 model = yaml_read(log.fname)
161 if model is not None:
162 # Collect all params from the models
163 _param = get_nested_key(model, ['parameters', '_param'])
164 if _param:
165 for key, val in _param.items():
166 if key in _params:
167 _params[key].append(val)
168 else:
169 _params[key] = [val]
170
171 return _params
172 #print(yaml.dump(_params))
173
174
175def remove_reclass_parameter(path, parameter, verbose=False):
176 """Removes specified key from parameters from all reclass models"""
177 #path = '/srv/salt/reclass/classes'
178 _params = dict()
179 for log in walkfiles(path, verbose=verbose):
180 if log.fname.endswith('.yml'):
181 model = yaml_read(log.fname)
182 if model is not None:
183
184 # Clear linux.network.interfaces
185 interfaces = get_nested_key(model, ['parameters', 'linux', 'network', 'interface'])
186 if interfaces:
187 print(log.fname)
188 print(interfaces.keys())
189
190 remove_nested_key(model, ['parameters', 'linux', 'network', 'interface'])
191
192 print(model)
193 with open(log.fname, 'w') as f:
194 f.write(
195 yaml.dump(
196 model, default_flow_style=False
197 )
198 )
199
200# #print(yaml.dump(interfaces, default_flow_style=False))
201
202# lvm = get_nested_key(model, ['parameters', 'linux', 'storage', 'lvm'])
203# if lvm:
204# print(log.fname)
205# print(lvm.keys())
206# #print(yaml.dump(lvm, default_flow_style=False))
207
208# mount = get_nested_key(model, ['parameters', 'linux', 'storage', 'mount'])
209# if mount:
210# print(log.fname)
211# print(mount.keys())
212# #print(yaml.dump(mount, default_flow_style=False))
213
214# swap = get_nested_key(model, ['parameters', 'linux', 'storage', 'swap'])
215# if swap:
216# print(log.fname)
217# print(swap.keys())
218# #print(yaml.dump(swap, default_flow_style=False))