"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)}