%PDF- %PDF-
Direktori : /proc/thread-self/root/lib/python2.7/site-packages/salt/runners/ |
Current File : //proc/thread-self/root/lib/python2.7/site-packages/salt/runners/asam.py |
# -*- coding: utf-8 -*- ''' Novell ASAM Runner ================== .. versionadded:: Beryllium Runner to interact with Novell ASAM Fan-Out Driver :codeauthor: Nitin Madhok <nmadhok@clemson.edu> To use this runner, set up the Novell Fan-Out Driver URL, username and password in the master configuration at ``/etc/salt/master`` or ``/etc/salt/master.d/asam.conf``: .. code-block:: yaml asam: prov1.domain.com username: "testuser" password: "verybadpass" prov2.domain.com username: "testuser" password: "verybadpass" .. note:: Optionally, ``protocol`` and ``port`` can be specified if the Fan-Out Driver server is not using the defaults. Default is ``protocol: https`` and ``port: 3451``. ''' from __future__ import absolute_import, print_function, unicode_literals # Import Python libs import logging # Import 3rd-party libs import salt.ext.six as six HAS_LIBS = False try: import requests from salt.ext.six.moves.html_parser import HTMLParser # pylint: disable=E0611 HAS_LIBS = True class ASAMHTMLParser(HTMLParser): # fix issue #30477 def __init__(self): HTMLParser.__init__(self) self.data = [] def handle_starttag(self, tag, attrs): if tag != "a": return for attr in attrs: if attr[0] != "href": return self.data.append(attr[1]) except ImportError: pass log = logging.getLogger(__name__) def __virtual__(): ''' Check for ASAM Fan-Out driver configuration in master config file or directory and load runner only if it is specified ''' if not HAS_LIBS: return False if _get_asam_configuration() is False: return False return True def _get_asam_configuration(driver_url=''): ''' Return the configuration read from the master configuration file or directory ''' asam_config = __opts__['asam'] if 'asam' in __opts__ else None if asam_config: try: for asam_server, service_config in six.iteritems(asam_config): username = service_config.get('username', None) password = service_config.get('password', None) protocol = service_config.get('protocol', 'https') port = service_config.get('port', 3451) if not username or not password: log.error( 'Username or Password has not been specified in the ' 'master configuration for %s', asam_server ) return False ret = { 'platform_edit_url': "{0}://{1}:{2}/config/PlatformEdit.html".format(protocol, asam_server, port), 'platform_config_url': "{0}://{1}:{2}/config/PlatformConfig.html".format(protocol, asam_server, port), 'platformset_edit_url': "{0}://{1}:{2}/config/PlatformSetEdit.html".format(protocol, asam_server, port), 'platformset_config_url': "{0}://{1}:{2}/config/PlatformSetConfig.html".format(protocol, asam_server, port), 'username': username, 'password': password } if (not driver_url) or (driver_url == asam_server): return ret except Exception as exc: log.error('Exception encountered: %s', exc) return False if driver_url: log.error( 'Configuration for %s has not been specified in the master ' 'configuration', driver_url ) return False return False def _make_post_request(url, data, auth, verify=True): r = requests.post(url, data=data, auth=auth, verify=verify) if r.status_code != requests.codes.ok: r.raise_for_status() else: return r.text.split('\n') def _parse_html_content(html_content): parser = ASAMHTMLParser() for line in html_content: if line.startswith("<META"): html_content.remove(line) else: parser.feed(line) return parser def _get_platformset_name(data, platform_name): for item in data: if platform_name in item and item.startswith('PlatformEdit.html?'): parameter_list = item.split('&') for parameter in parameter_list: if parameter.startswith("platformSetName"): return parameter.split('=')[1] return None def _get_platforms(data): platform_list = [] for item in data: if item.startswith('PlatformEdit.html?'): parameter_list = item.split('PlatformEdit.html?', 1)[1].split('&') for parameter in parameter_list: if parameter.startswith("platformName"): platform_list.append(parameter.split('=')[1]) return platform_list def _get_platform_sets(data): platform_set_list = [] for item in data: if item.startswith('PlatformSetEdit.html?'): parameter_list = item.split('PlatformSetEdit.html?', 1)[1].split('&') for parameter in parameter_list: if parameter.startswith("platformSetName"): platform_set_list.append(parameter.split('=')[1].replace('%20', ' ')) return platform_set_list def remove_platform(name, server_url): ''' To remove specified ASAM platform from the Novell Fan-Out Driver CLI Example: .. code-block:: bash salt-run asam.remove_platform my-test-vm prov1.domain.com ''' config = _get_asam_configuration(server_url) if not config: return False url = config['platform_config_url'] data = { 'manual': 'false', } auth = ( config['username'], config['password'] ) try: html_content = _make_post_request(url, data, auth, verify=False) except Exception as exc: err_msg = "Failed to look up existing platforms on {0}".format(server_url) log.error('%s:\n%s', err_msg, exc) return {name: err_msg} parser = _parse_html_content(html_content) platformset_name = _get_platformset_name(parser.data, name) if platformset_name: log.debug(platformset_name) data['platformName'] = name data['platformSetName'] = six.text_type(platformset_name) data['postType'] = 'platformRemove' data['Submit'] = 'Yes' try: html_content = _make_post_request(url, data, auth, verify=False) except Exception as exc: err_msg = "Failed to delete platform from {1}".format(server_url) log.error('%s:\n%s', err_msg, exc) return {name: err_msg} parser = _parse_html_content(html_content) platformset_name = _get_platformset_name(parser.data, name) if platformset_name: return {name: "Failed to delete platform from {0}".format(server_url)} else: return {name: "Successfully deleted platform from {0}".format(server_url)} else: return {name: "Specified platform name does not exist on {0}".format(server_url)} def list_platforms(server_url): ''' To list all ASAM platforms present on the Novell Fan-Out Driver CLI Example: .. code-block:: bash salt-run asam.list_platforms prov1.domain.com ''' config = _get_asam_configuration(server_url) if not config: return False url = config['platform_config_url'] data = { 'manual': 'false', } auth = ( config['username'], config['password'] ) try: html_content = _make_post_request(url, data, auth, verify=False) except Exception as exc: err_msg = "Failed to look up existing platforms" log.error('%s:\n%s', err_msg, exc) return {server_url: err_msg} parser = _parse_html_content(html_content) platform_list = _get_platforms(parser.data) if platform_list: return {server_url: platform_list} else: return {server_url: "No existing platforms found"} def list_platform_sets(server_url): ''' To list all ASAM platform sets present on the Novell Fan-Out Driver CLI Example: .. code-block:: bash salt-run asam.list_platform_sets prov1.domain.com ''' config = _get_asam_configuration(server_url) if not config: return False url = config['platformset_config_url'] data = { 'manual': 'false', } auth = ( config['username'], config['password'] ) try: html_content = _make_post_request(url, data, auth, verify=False) except Exception as exc: err_msg = "Failed to look up existing platform sets" log.error('%s:\n%s', err_msg, exc) return {server_url: err_msg} parser = _parse_html_content(html_content) platform_set_list = _get_platform_sets(parser.data) if platform_set_list: return {server_url: platform_set_list} else: return {server_url: "No existing platform sets found"} def add_platform(name, platform_set, server_url): ''' To add an ASAM platform using the specified ASAM platform set on the Novell Fan-Out Driver CLI Example: .. code-block:: bash salt-run asam.add_platform my-test-vm test-platform-set prov1.domain.com ''' config = _get_asam_configuration(server_url) if not config: return False platforms = list_platforms(server_url) if name in platforms[server_url]: return {name: "Specified platform already exists on {0}".format(server_url)} platform_sets = list_platform_sets(server_url) if platform_set not in platform_sets[server_url]: return {name: "Specified platform set does not exist on {0}".format(server_url)} url = config['platform_edit_url'] data = { 'platformName': name, 'platformSetName': platform_set, 'manual': 'false', 'previousURL': '/config/platformAdd.html', 'postType': 'PlatformAdd', 'Submit': 'Apply' } auth = ( config['username'], config['password'] ) try: html_content = _make_post_request(url, data, auth, verify=False) except Exception as exc: err_msg = "Failed to add platform on {0}".format(server_url) log.error('%s:\n%s', err_msg, exc) return {name: err_msg} platforms = list_platforms(server_url) if name in platforms[server_url]: return {name: "Successfully added platform on {0}".format(server_url)} else: return {name: "Failed to add platform on {0}".format(server_url)}