def install_from_url(self, req, force=False): try: fd, tmppath = tempfile.mkstemp() logger.debug("Using temporary fd %d at: %s" % (fd, tmppath)) logger.debug("Checking for application at: %s" % req.get_full_url()) with nested(closing(urllib2.urlopen(req)), os.fdopen(fd, "w+")) as (remote, local): logger.debug("Downloading application from: %s" % remote.geturl()) logger.debug("URL metadata:\n%s" % remote.info()) logger.debug("Downloading application to: %s" % tmppath) local.write(remote.read()) local.flush() logger.debug("Application download complete: %d bytes", os.path.getsize(tmppath)) result = self.install_from_tar(tmppath, force) safe_remove(tmppath) return result except urllib2.HTTPError, e: logger.exception(e) if (e.code == 403): raise splunk.AuthorizationFailed(e.msg) else: raise splunk.ResourceNotFound(e.msg)
def getAppDependencies(self, app, confInfo): app_location = make_splunkhome_path(['etc', 'apps', app]) if not os.path.isdir(app_location): raise splunk.ResourceNotFound('App %s does not exist.' % app) manifestFile = os.path.join(app_location, 'app.manifest') if not os.path.exists(str(manifestFile)): # not an error, app manifest is optional confInfo.addInfoMsg('Application manifest file is missing.') return # read app manifest chopping possible comments (that start with '#') manifest = ''.join([ line.split('#')[0] for line in open(manifestFile, 'r').readlines() ]) # parse manifest, possible errors will bubble to REST reply manifest = json.loads(manifest) dependencies = manifest.get('dependencies') if dependencies is None: confInfo.addInfoMsg( "Application manifest doesn't include dependencies.") return # construct reply reply = confInfo[app] for dependency, properties in dependencies.items(): # Convert properties to STR as it returns unicode reply[dependency] = str(properties.get("version"))
def _parse_link(self, xml): """ Given a feed of application files, get the URL of the installer. """ msg = "Could not find application download location" try: for entry in xml.xpath("//a:entry", namespaces=NSMAP): try: contents = self._convert_content(entry) if contents["fileclass"] in ["bundle", "other"]: return entry.xpath("a:link/@href", namespaces=NSMAP)[0] except: pass raise splunk.ResourceNotFound(msg) except Exception, e: logger.exception(e) raise splunk.ResourceNotFound(msg)
def handleCustom(self, confInfo): if self.customAction in ['acl']: return self.handleACL(confInfo) meth = self.get_method(self.customAction) if meth: ctx = self.getContext() meth(ctx) self.makeConfItem(self.callerArgs.id, ctx.entity, confInfo) else: raise splunk.ResourceNotFound()
def _get_latest_version(self, xml): """ Given a feed of version entries for an application, get the feed for the latest version. """ try: entry = self._get_latest_version_entry(xml) href = entry.xpath("a:link/@href", namespaces=NSMAP)[0] return self._get_feed_root(href) except Exception, e: logger.exception(e) msg = "Could not find latest version of application" raise splunk.ResourceNotFound(msg)
def install_from_tar(self, path, force=False): logger.debug("Examining application archive: %s" % path) if not os.path.exists(path) or os.path.isdir(path): raise splunk.ResourceNotFound('The package "%s" wasn\'t found' % path) tmpdir = None appname = get_app_name_from_tarball(path) existing = get_bundle(appname) if not force and existing: msg = 'App "%s" already exists; use the "-%s true" argument to install anyway' % ( appname, 'update') raise splunk.RESTException(409, msg) with closing(tarfile.open(path)) as tar: tmpdir = tempfile.mkdtemp() logger.debug("Extracting application to: %s" % tmpdir) tar.extractall(tmpdir, members=self._filter_tar(tar)) result = self.install_from_dir(tmpdir, appname) safe_remove(tmpdir) return result
raise splunk.LicenseRestriction elif serverResponse.status == 403: raise splunk.AuthorizationFailed(extendedMessages=uri) elif serverResponse.status == 404: # Some 404 reponses, such as those for expired jobs which were originally # run by the scheduler return extra data about the original resource. # In this case we add that additional info into the exception object # as the resourceInfo parameter so others might use it. try: body = et.fromstring(serverContent) resourceInfo = body.find('dict') if resourceInfo is not None: raise splunk.ResourceNotFound(uri, format.nodeToPrimitive(resourceInfo)) else: raise splunk.ResourceNotFound(uri, extendedMessages=extractMessages(body)) except et.XMLSyntaxError: pass raise splunk.ResourceNotFound, uri elif serverResponse.status == 201: try: body = et.fromstring(serverContent) serverResponse.messages = extractMessages(body) except et.XMLSyntaxError, e: # do nothing, just continue, no messages to extract if there is no xml pass except e: