"Fossies" - the Fresh Open Source Software Archive 
Member "salt-3002.2/salt/runners/asam.py" (18 Nov 2020, 10918 Bytes) of package /linux/misc/salt-3002.2.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style:
standard) with prefixed line numbers.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "asam.py" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
3002.1_vs_3002.2.
1 """
2 Novell ASAM Runner
3 ==================
4
5 .. versionadded:: Beryllium
6
7 Runner to interact with Novell ASAM Fan-Out Driver
8
9 :codeauthor: Nitin Madhok <nmadhok@clemson.edu>
10
11 To use this runner, set up the Novell Fan-Out Driver URL, username and password in the
12 master configuration at ``/etc/salt/master`` or ``/etc/salt/master.d/asam.conf``:
13
14 .. code-block:: yaml
15
16 asam:
17 prov1.domain.com
18 username: "testuser"
19 password: "verybadpass"
20 prov2.domain.com
21 username: "testuser"
22 password: "verybadpass"
23
24 .. note::
25
26 Optionally, ``protocol`` and ``port`` can be specified if the Fan-Out Driver server
27 is not using the defaults. Default is ``protocol: https`` and ``port: 3451``.
28
29 """
30
31 import logging
32
33 HAS_LIBS = False
34 try:
35 import requests
36 from salt.ext.six.moves.html_parser import HTMLParser # pylint: disable=E0611
37
38 HAS_LIBS = True
39
40 class ASAMHTMLParser(HTMLParser): # fix issue #30477
41 def __init__(self):
42 HTMLParser.__init__(self)
43 self.data = []
44
45 def handle_starttag(self, tag, attrs):
46 if tag != "a":
47 return
48 for attr in attrs:
49 if attr[0] != "href":
50 return
51 self.data.append(attr[1])
52
53
54 except ImportError:
55 pass
56
57 log = logging.getLogger(__name__)
58
59
60 def __virtual__():
61 """
62 Check for ASAM Fan-Out driver configuration in master config file
63 or directory and load runner only if it is specified
64 """
65 if not HAS_LIBS:
66 return False
67
68 if _get_asam_configuration() is False:
69 return False
70 return True
71
72
73 def _get_asam_configuration(driver_url=""):
74 """
75 Return the configuration read from the master configuration
76 file or directory
77 """
78 asam_config = __opts__["asam"] if "asam" in __opts__ else None
79
80 if asam_config:
81 try:
82 for asam_server, service_config in asam_config.items():
83 username = service_config.get("username", None)
84 password = service_config.get("password", None)
85 protocol = service_config.get("protocol", "https")
86 port = service_config.get("port", 3451)
87
88 if not username or not password:
89 log.error(
90 "Username or Password has not been specified in the "
91 "master configuration for %s",
92 asam_server,
93 )
94 return False
95
96 ret = {
97 "platform_edit_url": "{}://{}:{}/config/PlatformEdit.html".format(
98 protocol, asam_server, port
99 ),
100 "platform_config_url": "{}://{}:{}/config/PlatformConfig.html".format(
101 protocol, asam_server, port
102 ),
103 "platformset_edit_url": "{}://{}:{}/config/PlatformSetEdit.html".format(
104 protocol, asam_server, port
105 ),
106 "platformset_config_url": "{}://{}:{}/config/PlatformSetConfig.html".format(
107 protocol, asam_server, port
108 ),
109 "username": username,
110 "password": password,
111 }
112
113 if (not driver_url) or (driver_url == asam_server):
114 return ret
115 except Exception as exc: # pylint: disable=broad-except
116 log.error("Exception encountered: %s", exc)
117 return False
118
119 if driver_url:
120 log.error(
121 "Configuration for %s has not been specified in the master "
122 "configuration",
123 driver_url,
124 )
125 return False
126
127 return False
128
129
130 def _make_post_request(url, data, auth, verify=True):
131 r = requests.post(url, data=data, auth=auth, verify=verify)
132 if r.status_code != requests.codes.ok:
133 r.raise_for_status()
134 else:
135 return r.text.split("\n")
136
137
138 def _parse_html_content(html_content):
139 parser = ASAMHTMLParser()
140 for line in html_content:
141 if line.startswith("<META"):
142 html_content.remove(line)
143 else:
144 parser.feed(line)
145
146 return parser
147
148
149 def _get_platformset_name(data, platform_name):
150 for item in data:
151 if platform_name in item and item.startswith("PlatformEdit.html?"):
152 parameter_list = item.split("&")
153 for parameter in parameter_list:
154 if parameter.startswith("platformSetName"):
155 return parameter.split("=")[1]
156
157 return None
158
159
160 def _get_platforms(data):
161 platform_list = []
162 for item in data:
163 if item.startswith("PlatformEdit.html?"):
164 parameter_list = item.split("PlatformEdit.html?", 1)[1].split("&")
165 for parameter in parameter_list:
166 if parameter.startswith("platformName"):
167 platform_list.append(parameter.split("=")[1])
168
169 return platform_list
170
171
172 def _get_platform_sets(data):
173 platform_set_list = []
174 for item in data:
175 if item.startswith("PlatformSetEdit.html?"):
176 parameter_list = item.split("PlatformSetEdit.html?", 1)[1].split("&")
177 for parameter in parameter_list:
178 if parameter.startswith("platformSetName"):
179 platform_set_list.append(
180 parameter.split("=")[1].replace("%20", " ")
181 )
182
183 return platform_set_list
184
185
186 def remove_platform(name, server_url):
187 """
188 To remove specified ASAM platform from the Novell Fan-Out Driver
189
190 CLI Example:
191
192 .. code-block:: bash
193
194 salt-run asam.remove_platform my-test-vm prov1.domain.com
195 """
196 config = _get_asam_configuration(server_url)
197 if not config:
198 return False
199
200 url = config["platform_config_url"]
201
202 data = {
203 "manual": "false",
204 }
205
206 auth = (config["username"], config["password"])
207
208 try:
209 html_content = _make_post_request(url, data, auth, verify=False)
210 except Exception as exc: # pylint: disable=broad-except
211 err_msg = "Failed to look up existing platforms on {}".format(server_url)
212 log.error("%s:\n%s", err_msg, exc)
213 return {name: err_msg}
214
215 parser = _parse_html_content(html_content)
216 platformset_name = _get_platformset_name(parser.data, name)
217
218 if platformset_name:
219 log.debug(platformset_name)
220 data["platformName"] = name
221 data["platformSetName"] = str(platformset_name)
222 data["postType"] = "platformRemove"
223 data["Submit"] = "Yes"
224 try:
225 html_content = _make_post_request(url, data, auth, verify=False)
226 except Exception as exc: # pylint: disable=broad-except
227 err_msg = "Failed to delete platform from {}".format(server_url)
228 log.error("%s:\n%s", err_msg, exc)
229 return {name: err_msg}
230
231 parser = _parse_html_content(html_content)
232 platformset_name = _get_platformset_name(parser.data, name)
233 if platformset_name:
234 return {name: "Failed to delete platform from {}".format(server_url)}
235 else:
236 return {name: "Successfully deleted platform from {}".format(server_url)}
237 else:
238 return {name: "Specified platform name does not exist on {}".format(server_url)}
239
240
241 def list_platforms(server_url):
242 """
243 To list all ASAM platforms present on the Novell Fan-Out Driver
244
245 CLI Example:
246
247 .. code-block:: bash
248
249 salt-run asam.list_platforms prov1.domain.com
250 """
251 config = _get_asam_configuration(server_url)
252 if not config:
253 return False
254
255 url = config["platform_config_url"]
256
257 data = {
258 "manual": "false",
259 }
260
261 auth = (config["username"], config["password"])
262
263 try:
264 html_content = _make_post_request(url, data, auth, verify=False)
265 except Exception as exc: # pylint: disable=broad-except
266 err_msg = "Failed to look up existing platforms"
267 log.error("%s:\n%s", err_msg, exc)
268 return {server_url: err_msg}
269
270 parser = _parse_html_content(html_content)
271 platform_list = _get_platforms(parser.data)
272
273 if platform_list:
274 return {server_url: platform_list}
275 else:
276 return {server_url: "No existing platforms found"}
277
278
279 def list_platform_sets(server_url):
280 """
281 To list all ASAM platform sets present on the Novell Fan-Out Driver
282
283 CLI Example:
284
285 .. code-block:: bash
286
287 salt-run asam.list_platform_sets prov1.domain.com
288 """
289 config = _get_asam_configuration(server_url)
290 if not config:
291 return False
292
293 url = config["platformset_config_url"]
294
295 data = {
296 "manual": "false",
297 }
298
299 auth = (config["username"], config["password"])
300
301 try:
302 html_content = _make_post_request(url, data, auth, verify=False)
303 except Exception as exc: # pylint: disable=broad-except
304 err_msg = "Failed to look up existing platform sets"
305 log.error("%s:\n%s", err_msg, exc)
306 return {server_url: err_msg}
307
308 parser = _parse_html_content(html_content)
309 platform_set_list = _get_platform_sets(parser.data)
310
311 if platform_set_list:
312 return {server_url: platform_set_list}
313 else:
314 return {server_url: "No existing platform sets found"}
315
316
317 def add_platform(name, platform_set, server_url):
318 """
319 To add an ASAM platform using the specified ASAM platform set on the Novell
320 Fan-Out Driver
321
322 CLI Example:
323
324 .. code-block:: bash
325
326 salt-run asam.add_platform my-test-vm test-platform-set prov1.domain.com
327 """
328 config = _get_asam_configuration(server_url)
329 if not config:
330 return False
331
332 platforms = list_platforms(server_url)
333 if name in platforms[server_url]:
334 return {name: "Specified platform already exists on {}".format(server_url)}
335
336 platform_sets = list_platform_sets(server_url)
337 if platform_set not in platform_sets[server_url]:
338 return {name: "Specified platform set does not exist on {}".format(server_url)}
339
340 url = config["platform_edit_url"]
341
342 data = {
343 "platformName": name,
344 "platformSetName": platform_set,
345 "manual": "false",
346 "previousURL": "/config/platformAdd.html",
347 "postType": "PlatformAdd",
348 "Submit": "Apply",
349 }
350
351 auth = (config["username"], config["password"])
352
353 try:
354 html_content = _make_post_request(url, data, auth, verify=False)
355 except Exception as exc: # pylint: disable=broad-except
356 err_msg = "Failed to add platform on {}".format(server_url)
357 log.error("%s:\n%s", err_msg, exc)
358 return {name: err_msg}
359
360 platforms = list_platforms(server_url)
361 if name in platforms[server_url]:
362 return {name: "Successfully added platform on {}".format(server_url)}
363 else:
364 return {name: "Failed to add platform on {}".format(server_url)}