示例#1
0
 def handle_POST(self):
     self.verifyAllowRemote()
     try:
         post_args = urlencode(self.request["form"])
         if sys.version_info >= (3, 0): post_args = post_args.encode()
         logger.debug("Logging into %s" % self._login)
         bundle_paths.BundleInstaller().validate_server_cert(
             self._login, self._sslpol)
         # Forward post arguments, including username and password.
         with closing(urlopen(self._login, post_args,
                              URLOPEN_TIMEOUT)) as f:
             root = safe_lxml.parse(f).getroot()
             token = root.xpath("a:id", namespaces=NSMAP)[0].text
             if self.request["output_mode"] == "json":
                 self.response.setHeader('content-type', 'application/json')
                 sessDict = {"response": {"sessionKey": token}}
                 self.response.write(json.dumps(sessDict))
             else:
                 # Generate response.
                 response = etree.Element("response")
                 sessionKey = etree.SubElement(response, "sessionKey")
                 sessionKey.text = token
                 self.response.setHeader('content-type', 'text/xml')
                 self.response.write(
                     etree.tostring(response, pretty_print=True))
             logger.debug("Login successful")
     except HTTPError as e:
         if e.code in [401, 405]:
             # Returning 401 logs off current session
             # Splunkbase retuns 405 when only password is submitted
             raise splunk.RESTException(400, e.msg)
         raise splunk.RESTException(e.code, e.msg)
     except Exception as e:
         logger.exception(e)
         raise splunk.AuthenticationFailed
 def handle_POST(self):
     """
     Install a remote application in response to an HTTP POST.
     """
     self.verifyAllowRemote()
     parts = len(self.pathParts)
     if parts == self.BASE_DEPTH + 2:
         default_version = True
     elif parts == self.BASE_DEPTH + 3:
         default_version = False
     else:
         raise splunk.BadRequest
     if not self.args.has_key(HTTP_AUTH_TOKEN):
         raise splunk.BadRequest("Missing argument: %s" % HTTP_AUTH_TOKEN)
     if not self.args.has_key(HTTP_ACTION):
         raise splunk.BadRequest("Missing argument: %s" % HTTP_ACTION)
     if self.args[HTTP_ACTION] != HTTP_ACTION_INSTALL:
         raise splunk.BadRequest("Invalid value '%s' for argument '%s'" %
                                 (self.args[HTTP_ACTION], HTTP_ACTION))
     url = self._native_to_foreign_url()
     root = self._get_feed_root(url)
     if default_version:
         root = self._get_latest_version(root)
     href = self._parse_link(root)
     try:
         # Package up a Request with auth information.
         req = urllib2.Request(href)
         # XXX: Converting the auth token from a POST arg to a header
         # requires us to unquote() it. If the client did not correctly
         # quote() the token, login will fail.
         req.add_header(HTTP_AUTH_HEADER,
                        urllib.unquote(self.args[HTTP_AUTH_TOKEN]))
         # Install using this Request object.
         installer = bundle_paths.BundleInstaller()
         b, status = installer.install_from_url(req)
         self.response.setStatus(status)
         if ((status == bundle_paths.BundleInstaller.STATUS_INSTALLED) or
             (status == bundle_paths.BundleInstaller.STATUS_UPGRADED)):
             # Migrate old-style bundles.
             logger.debug("Configuring application contents")
             try:
                 b.migrate()
             except Exception, e:
                 logger.exception(e)
                 self.addMessage("WARN",
                                 "Error during configuration: %s" % e)
             # Redirect to local application.
             self.response.setHeader("Location", self._redirect_to_local(b))
             # Let splunkd know about newly-installed app.
             logger.debug("Notifying splunkd that app has been installed")
             splunk.rest.simpleRequest('apps/local/_reload',
                                       sessionKey=self.sessionKey)
         if status == bundle_paths.BundleInstaller.STATUS_INSTALLED:
             self.addMessage("INFO", "Installed application: %s" % b.name())
         elif status == bundle_paths.BundleInstaller.STATUS_UPGRADED:
             self.addMessage("INFO", "Upgraded application: %s" % b.name())
         else:
             self.addMessage("WARN",
                             "Could not install application: %s" % b.name())
示例#3
0
def installApp(location, force=False):
    installer = bundle_paths.BundleInstaller()
    location = location.strip()

    try:
        if location.startswith('http'):
            req = urllib2.Request(url=location)
            return installer.install_from_url(req, force)
        else:
            return installer.install_from_tar(location, force)
    except splunk.ResourceNotFound, e:
        raise admin.ArgValidationException(e.msg)
示例#4
0
    def _get_feed_root(self, url, extra_get_args={}):
        """
        Get an Atom feed of application information from the remote provider.
        """
        try:
            target_url = url
            # Forward GET arguments, and add user-agent.
            args_dict = {}
            headers = {}

            args_dict.update(self.request["query"])
            if (len(extra_get_args) > 0):
                args_dict.update(extra_get_args)
            if self._platformInfo:
                args_dict.update(self._platformInfo)
            args = urlencode(args_dict)
            if args != "":
                target_url += ("?" + args)
            logger.debug("Getting feed from: %s" % target_url)

            if self._agent:
                headers["User-Agent"] = self._agent

            bundle_paths.BundleInstaller().validate_server_cert(
                target_url, self._sslpol)
            req = Request(target_url, None, headers)
            f = urlopen(req, None, URLOPEN_TIMEOUT)
        except HTTPError as e:
            raise splunk.RESTException(e.code, e.msg)
        except URLError as e:
            logger.exception(e)
            raise splunk.RESTException(
                503,
                "Splunk is unable to connect to the Internet to find more apps."
            )
        except Exception as e:
            logger.exception(e)
            raise splunk.RESTException(404, "Resource not found")
        try:
            root = safe_lxml.parse(f).getroot()
            f.close()
            return root
        except Exception as e:
            raise splunk.InternalServerError(e)
示例#5
0
    def handle_POST(self):
        """
        Install a remote application in response to an HTTP POST.
        """
        self.verifyAllowRemote()
        parts = len(self.pathParts)
        if parts == self.BASE_DEPTH + 2:
            default_version = True
        elif parts == self.BASE_DEPTH + 3:
            default_version = False
        else:
            raise splunk.BadRequest
        if HTTP_AUTH_TOKEN not in self.args:
            raise splunk.BadRequest("Missing argument: %s" % HTTP_AUTH_TOKEN)
        if HTTP_ACTION not in self.args:
            raise splunk.BadRequest("Missing argument: %s" % HTTP_ACTION)
        if self.args[HTTP_ACTION] not in (HTTP_ACTION_INSTALL,
                                          HTTP_ACTION_DOWNLOAD):
            raise splunk.BadRequest("Invalid value '%s' for argument '%s'" %
                                    (self.args[HTTP_ACTION], HTTP_ACTION))
        # check if this is a cloud stack
        if isCloud(self.sessionKey):
            app_name = self.pathParts[self.BASE_DEPTH + 1]
            # Get all cloud apps and see if the app being installed is vetted for cloud
            # i.e install_method == simple
            # TODO: Change to just querying for the app in question when BASE-4074
            # is finished.
            getargs = {'offset': 0, 'limit': 100}
            vetted_apps = []
            while 1:
                serverResponse, serverContent = splunk.rest.simpleRequest(
                    VETTED_APPS_URI, self.sessionKey, getargs)
                if serverResponse.status != 200:
                    raise splunk.BadRequest(
                        'Error while querying Splunkbase. Splunkd returned %s'
                        % serverContent)
                vetted_app_data = json.loads(serverContent)
                if not vetted_app_data['results']:
                    break
                else:
                    getargs['offset'] += 100
                    vetted_apps.extend(vetted_app_data['results'])
            for app in vetted_apps:
                if app['appid'] == app_name and app[
                        'install_method'] == VETTED_APP_INSTALL_METHOD:
                    break
            else:
                raise splunk.BadRequest(
                    'App %s is not vetted for Splunk Cloud.' % app_name)

        url = self._native_to_foreign_url()
        root = self._get_feed_root(url)
        if default_version:
            root = self._get_latest_version(root)
        href = self._parse_link(root)

        try:
            # Package up a Request with auth information.
            req = Request(href)
            # XXX: Converting the auth token from a POST arg to a header
            # requires us to unquote() it. If the client did not correctly
            # quote() the token, login will fail.
            req.add_header(HTTP_AUTH_HEADER,
                           unquote(self.args[HTTP_AUTH_TOKEN]))
            # Install using this Request object.
            installer = bundle_paths.BundleInstaller()
            if self.args[HTTP_ACTION] == HTTP_ACTION_INSTALL:
                b, status = installer.install_from_url(req,
                                                       sslpol=self._sslpol)
                self.response.setStatus(status)
                if ((status == bundle_paths.BundleInstaller.STATUS_INSTALLED)
                        or
                    (status == bundle_paths.BundleInstaller.STATUS_UPGRADED)):
                    # Migrate old-style bundles.
                    logger.debug("Configuring application contents")
                    try:
                        b.migrate()
                    except Exception as e:
                        logger.exception(e)
                        self.addMessage("WARN",
                                        "Error during configuration: %s" % e)
                    # Redirect to local application.
                    self.response.setHeader("Location",
                                            self._redirect_to_local(b))
                    # Let splunkd know about newly-installed app.
                    logger.debug(
                        "Notifying splunkd that app has been installed")
                    splunk.rest.simpleRequest('apps/local/_reload',
                                              sessionKey=self.sessionKey)
                if status == bundle_paths.BundleInstaller.STATUS_INSTALLED:
                    self.addMessage("INFO",
                                    "Installed application: %s" % b.name())
                elif status == bundle_paths.BundleInstaller.STATUS_UPGRADED:
                    self.addMessage("INFO",
                                    "Upgraded application: %s" % b.name())
                else:
                    self.addMessage(
                        "WARN", "Could not install application: %s" % b.name())
            else:
                assert self.args[HTTP_ACTION] == HTTP_ACTION_DOWNLOAD
                downloaded = installer.download_from_url(req,
                                                         sslpol=self._sslpol)
                self.addMessage("INFO",
                                "Downloaded application file: %s" % downloaded)
                self.response.setHeader('content-type', 'application/json')
                response_json = {"downloaded": downloaded}
                self.response.write(json.dumps(response_json))

        except splunk.ResourceNotFound:
            raise
        except splunk.AuthorizationFailed:
            raise
        except splunk.InternalServerError:
            raise
        except Exception as e:
            logger.exception(e)
            raise splunk.InternalServerError(e)