def handle(plugin): """main funcion which will be routed to the plugin's endpoint""" logger = make_logger("mast.plugin_functions") import urllib if flask.request.method == 'GET': logger.info("GET Request received") name = flask.request.args.get('callable') logger.debug("name: {}".format(name)) appliances = flask.request.args.getlist('appliances[]') logger.debug("appliances: {}".format(str(appliances))) credentials = [xordecode(urllib.unquote(_), key=xorencode( flask.request.cookies["9x4h/mmek/j.ahba.ckhafn"])) for _ in flask.request.args.getlist('credentials[]')] logger.debug("getting form") try: form = get_form(plugin.replace("mast.", ""), name, appliances, credentials) except: logger.exception("An unhandled exception occurred during execution.") raise logger.debug("Got form") return form elif flask.request.method == 'POST': logger.info("Received POST request for {}".format(plugin)) try: return flask.Markup(str(call_method(plugin, flask.request.form))) except: logger.exception("An unhandled exception occurred during processing of request.") raise
def ssh(self): """Handle requests comming from the ssh tab in the MAST web GUI.""" global _appliances # Get the unique session_id from the form (this is different # even across tabs in the same browser) session_id = flask.request.form.get("ssh_session") if session_id not in _appliances.keys(): # This is the first request from session_id _appliances[session_id] = [] # _appliances holds the DataPower objects which in turn # are holding references to the ssh session. appliances = _appliances[session_id] command = flask.request.form.get("command") hostnames = flask.request.form.getlist("appliances[]") credentials = [xordecode(_, key=xorencode( flask.request.cookies["9x4h/mmek/j.ahba.ckhafn"])) for _ in flask.request.form.getlist('credentials[]')] # Check for appliances the user may have added for index, hostname in enumerate(hostnames): if not _check_for_appliance(hostname, appliances): # User added hostname to the list of appliances at the # top of the Web GUI. appliances.append( datapower.DataPower( hostname, credentials[index], check_hostname=False)) # Check for appliances the user may have removed for appliance in list(appliances): if appliance.hostname not in hostnames: # User removed hostname from the list of appliances at the # top of the Web GUI appliance.ssh_disconnect() appliances.remove(appliance) responses = {} # Loop through appliances, check for connectivity and issue command for appliance in appliances: if not appliance.ssh_is_connected(): appliance.ssh_connect() responses[appliance.hostname] = appliance.ssh_issue_command( command) # Return JSON object containing hostnames (keys) mapped # to responses (values) return flask.jsonify(responses)
def status(self): logger = make_logger("mast.datapower.status") t = Timestamp() check_hostname = "true" in flask.request.form.get( 'check_hostname').lower() appliances = flask.request.form.getlist('appliances[]') credentials = [xordecode( _, key=xorencode( flask.request.cookies["9x4h/mmek/j.ahba.ckhafn"])) for _ in flask.request.form.getlist('credentials[]')] if not appliances: return flask.abort(404) env = datapower.Environment( appliances, credentials, check_hostname=check_hostname) providers = flask.request.form.getlist("providers[]") resp = { "appliances": appliances, "time": t.short} for provider in providers: _provider = provider.split(".")[0] resp[provider] = [] for appliance in env.appliances: try: _status = appliance.get_status(_provider) except datapower.AuthenticationFailure: # This is to handle an intermittent authentication failure # sometimes issued by the DataPower. We will sleep 2 # seconds and try again sleep(2) try: return self.status() except: logger.exception( "An unhandled exception occurred during execution") raise except: logger.exception( "An unhandled exception occurred during execution") raise metric = _status.xml.find(PROVIDER_MAP[provider]).text resp[provider].append(metric) return flask.jsonify(resp)
def status(self): logger = make_logger("mast.datapower.status") t = Timestamp() check_hostname = "true" in flask.request.form.get( 'check_hostname').lower() appliances = flask.request.form.getlist('appliances[]') credentials = [ xordecode(_, key=xorencode( flask.request.cookies["9x4h/mmek/j.ahba.ckhafn"])) for _ in flask.request.form.getlist('credentials[]') ] if not appliances: return flask.abort(404) env = datapower.Environment(appliances, credentials, check_hostname=check_hostname) providers = flask.request.form.getlist("providers[]") resp = {"appliances": appliances, "time": t.short} for provider in providers: _provider = provider.split(".")[0] resp[provider] = [] for appliance in env.appliances: try: _status = appliance.get_status(_provider) except datapower.AuthenticationFailure: # This is to handle an intermittent authentication failure # sometimes issued by the DataPower. We will sleep 2 # seconds and try again sleep(2) try: return self.status() except: logger.exception( "An unhandled exception occurred during execution") raise except: logger.exception( "An unhandled exception occurred during execution") raise metric = _status.xml.find(PROVIDER_MAP[provider]).text resp[provider].append(metric) return flask.jsonify(resp)
def check_connectivity(hostname): """ _function_: `mast.datapower.web.check_connectivity(hostname)` This function will return a JSON response to a GET request containing the hostname and credentials (encrypted). The response will be a mapping of hostname to boolean value indicating whether or not we were able to reach the appliance using the hostname and credentials. Exposed at: `/test/connectivity` via GET Parameters: * `hostname`: The hostname of the appliance to connect to. """ resp = {} credentials = flask.request.args.get("credentials") credentials = xordecode( credentials, key=xorencode(flask.request.cookies["9x4h/mmek/j.ahba.ckhafn"])) check_hostname = flask.request.args.get("check_hostname", True) check_hostname = False if "false" in check_hostname else check_hostname appl = datapower.DataPower( hostname, credentials, check_hostname=check_hostname) resp["soma"] = appl.is_reachable() if "Authentication failure" in appl.last_response: resp["soma"] = False try: _resp = appl.ssh_connect(port=appl.ssh_port) appl.ssh_disconnect() resp["ssh"] = 'DataPower' in _resp except: resp["ssh"] = False return flask.jsonify(resp)
def handle(plugin): """main funcion which will be routed to the plugin's endpoint""" logger = make_logger("mast.plugin_functions") import urllib if flask.request.method == 'GET': logger.info("GET Request received") name = flask.request.args.get('callable') logger.debug("name: {}".format(name)) appliances = flask.request.args.getlist('appliances[]') logger.debug("appliances: {}".format(str(appliances))) credentials = [ xordecode(urllib.unquote(_), key=xorencode( flask.request.cookies["9x4h/mmek/j.ahba.ckhafn"])) for _ in flask.request.args.getlist('credentials[]') ] logger.debug("getting form") try: form = get_form(plugin.replace("mast.", ""), name, appliances, credentials) except: logger.exception( "An unhandled exception occurred during execution.") raise logger.debug("Got form") return form elif flask.request.method == 'POST': logger.info("Received POST request for {}".format(plugin)) try: return flask.Markup(str(call_method(plugin, flask.request.form))) except: logger.exception( "An unhandled exception occurred during processing of request." ) raise
def check_connectivity(hostname): """ _function_: `mast.datapower.web.check_connectivity(hostname)` This function will return a JSON response to a GET request containing the hostname and credentials (encrypted). The response will be a mapping of hostname to boolean value indicating whether or not we were able to reach the appliance using the hostname and credentials. Exposed at: `/test/connectivity` via GET Parameters: * `hostname`: The hostname of the appliance to connect to. """ resp = {} credentials = flask.request.args.get("credentials") credentials = xordecode( credentials, key=xorencode(flask.request.cookies["9x4h/mmek/j.ahba.ckhafn"])) check_hostname = flask.request.args.get("check_hostname", True) check_hostname = False if "false" in check_hostname else check_hostname appl = datapower.DataPower(hostname, credentials, check_hostname=check_hostname) resp["soma"] = appl.is_reachable() if "Authentication failure" in appl.last_response: resp["soma"] = False try: _resp = appl.ssh_connect(port=appl.ssh_port) appl.ssh_disconnect() resp["ssh"] = 'DataPower' in _resp except: resp["ssh"] = False return flask.jsonify(resp)
def call_method(plugin, form): """Gather the arguments and function name from form then invoke _call_method. Wrap the results in html and return them.""" t = Timestamp() name = form.get("callable") arguments, func = _get_arguments(plugin, name) kwargs = {} for arg, default in arguments: if isinstance(default, bool): if arg == "web": kwargs[arg] = True continue value = form.get(arg) if value == 'true': kwargs[arg] = True else: kwargs[arg] = False elif isinstance(default, list): # TODO: This needs to implement a selection feature if arg == 'appliances': kwargs[arg] = form.getlist(arg + '[]') elif arg == 'credentials': kwargs[arg] = [ xordecode( _, key=xorencode( flask.request.cookies["9x4h/mmek/j.ahba.ckhafn"])) for _ in form.getlist(arg + '[]') ] else: kwargs[arg] = form.getlist(arg + '[]') elif isinstance(default, basestring): if arg == 'out_dir': kwargs[arg] = os.path.join('tmp', 'web', name, t.timestamp) elif arg == 'out_file' and default is not None: kwargs[arg] = os.path.join( "tmp", "web", name, "{}-{}{}".format(t.timestamp, name, os.path.splitext(default)[1])).replace( os.path.sep, "/") else: kwargs[arg] = form.get(arg) or default elif isinstance(default, int): kwargs[arg] = int(form.get(arg)) or default elif default is None: kwargs[arg] = form.get(arg) or default out, history_id = _call_method(func, kwargs) link = "" if 'out_dir' in kwargs: config = get_config("server.conf") static_dir = config.get('dirs', 'static') fname = "" for appliance in kwargs['appliances']: fname = "{}-{}".format(fname, appliance) fname = "{}-{}{}.zip".format(t.timestamp, name, fname) zip_filename = os.path.join(static_dir, 'tmp', fname) zip_file = zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) _zipdir(kwargs['out_dir'], zip_file) zip_file.close() #filename = '%s-%s.zip' % (t.timestamp, name) link = flask.Markup(flask.render_template('link.html', filename=fname)) if 'out_file' in kwargs and kwargs["out_file"] is not None: import shutil config = get_config("server.conf") static_dir = config.get('dirs', 'static') dst = os.path.join(static_dir, "tmp", os.path.basename(kwargs["out_file"])) shutil.copyfile(kwargs["out_file"], dst) link = flask.Markup( flask.render_template('link.html', filename=os.path.basename( kwargs["out_file"]))) out = flask.render_template('output.html', output=out, callable=name, timestamp=str(t), history_id=history_id, link=link) if 'out_dir' in kwargs: out = out return out
def call_method(plugin, form): """Gather the arguments and function name from form then invoke _call_method. Wrap the results in html and return them.""" t = Timestamp() name = form.get("callable") arguments, func = _get_arguments(plugin, name) kwargs = {} for arg, default in arguments: if isinstance(default, bool): if arg == "web": kwargs[arg] = True continue value = form.get(arg) if value == 'true': kwargs[arg] = True else: kwargs[arg] = False elif isinstance(default, list): # TODO: This needs to implement a selection feature if arg == 'appliances': kwargs[arg] = form.getlist(arg + '[]') elif arg == 'credentials': kwargs[arg] = [ xordecode( _, key=xorencode( flask.request.cookies["9x4h/mmek/j.ahba.ckhafn"])) for _ in form.getlist(arg + '[]')] else: kwargs[arg] = form.getlist(arg + '[]') elif isinstance(default, basestring): if arg == 'out_dir': kwargs[arg] = os.path.join('tmp', 'web', name, t.timestamp) elif arg == 'out_file' and default is not None: kwargs[arg] = os.path.join("tmp", "web", name, "{}-{}{}".format(t.timestamp, name, os.path.splitext(default)[1]) ).replace(os.path.sep, "/") else: kwargs[arg] = form.get(arg) or default elif isinstance(default, int): kwargs[arg] = int(form.get(arg)) or default elif default is None: kwargs[arg] = form.get(arg) or default out, history_id = _call_method(func, kwargs) link = "" if 'out_dir' in kwargs: config = get_config("server.conf") static_dir = config.get('dirs', 'static') fname = "" for appliance in kwargs['appliances']: fname = "{}-{}".format(fname, appliance) fname = "{}-{}{}.zip".format(t.timestamp, name, fname) zip_filename = os.path.join( static_dir, 'tmp', fname) zip_file = zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) _zipdir(kwargs['out_dir'], zip_file) zip_file.close() #filename = '%s-%s.zip' % (t.timestamp, name) link = flask.Markup(flask.render_template('link.html', filename=fname)) if 'out_file' in kwargs and kwargs["out_file"] is not None: import shutil config = get_config("server.conf") static_dir = config.get('dirs', 'static') dst = os.path.join(static_dir, "tmp", os.path.basename(kwargs["out_file"])) shutil.copyfile(kwargs["out_file"], dst) link = flask.Markup(flask.render_template('link.html', filename=os.path.basename(kwargs["out_file"]))) out = flask.render_template( 'output.html', output=out, callable=name, timestamp=str(t), history_id=history_id, link=link) if 'out_dir' in kwargs: out = out return out