def _transform_feed(self, xml):
     """
     Make an Atom feed from the remote provider look as though we generated
     it by rewriting certain URLs in the feed.
     """
     try:
         self._convert_remote_elements(xml)
         for entry in xml.xpath("//a:entry", namespaces=NSMAP):
             self._convert_remote_elements(entry)
     except Exception, e:
         logger.exception(e)
         raise splunk.InternalServerError(e)
Exemple #2
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)
Exemple #3
0
def _bundle_error(msg):
    tmp = lit("ERROR_APP_INSTALL__S") % msg
    logger.error(tmp)
    raise splunk.InternalServerError(tmp)
                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())
        except splunk.ResourceNotFound:
            raise
        except splunk.InternalServerError:
            raise
        except Exception, e:
            logger.exception(e)
            raise splunk.InternalServerError(e)

    def _native_to_foreign_url(self):
        """
        Convert this endpoint's URL into a remote-provider URL.
        """
        url = self._base
        for part in self.pathParts[self.BASE_DEPTH:]:
            url += "/" + part
        return url

    def _foreign_to_native_url(self, url):
        """
        Convert a remote-provider URL into a URL pointing to this endpoint.
        """
        if not url.startswith(self._base):
Exemple #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)