def create_job(self, *args, **kwargs):        
        output = ODataEntity()
        responseCode = 500

        try:
            serverStatus, serverResponse = self.forward_request()
            responseCode = serverStatus.status

            root = et.fromstring(serverResponse)
            if root.findtext('sid'):
                output.data = {
                    'sid': root.findtext('sid')
                }
            elif self.request["form"].get("exec_mode", "").lower() == "oneshot":
                output.data = self._parseResultData(root, format=ResultFormat.ROW)
                
            # service may return messages in the body; try to parse them
            try:
                msg = splunk.rest.extractMessages(root)
                if msg:
                    output.messages.extend(msg)
            except:
                pass
        except splunk.RESTException, e:
            responseCode = e.statusCode
            output.messages.append({
                'type': 'HTTP',
                'text': '%s %s' % (e.statusCode, e.msg)
            })
            if e.extendedMessages:
                output.messages.extend(e.extendedMessages)
Beispiel #2
0
    def dispatch_job(self, owner, namespace, kwargs):

        output = ODataEntity()
        responseCode = 500

        uri = splunk.entity.buildEndpoint('search',
                                          'jobs',
                                          owner=owner,
                                          namespace=namespace)

        try:
            serverStatus, serverResponse = self.simpleRequest(
                uri, postargs=kwargs, method='POST', raiseAllErrors=True)
            responseCode = serverStatus.status

            root = et.fromstring(serverResponse)
            if root.findtext('sid'):
                output.data = {'sid': root.findtext('sid')}

            # service may return messages in the body; try to parse them
            try:
                msg = splunk.rest.extractMessages(root)
                if msg:
                    output.messages.extend(msg)
            except:
                pass
        except splunk.RESTException, e:
            responseCode = e.statusCode
            output.messages.append({
                'type': 'HTTP',
                'text': '%s %s' % (e.statusCode, e.msg)
            })
            if e.extendedMessages:
                output.messages.extend(e.extendedMessages)
    def create_job(self, *args, **kwargs):
        output = ODataEntity()
        responseCode = 500

        try:
            serverStatus, serverResponse = self.forward_request()
            responseCode = serverStatus.status

            root = et.fromstring(serverResponse)
            if root.findtext('sid'):
                output.data = {'sid': root.findtext('sid')}
            elif self.request["form"].get("exec_mode",
                                          "").lower() == "oneshot":
                output.data = self._parseResultData(root,
                                                    format=ResultFormat.ROW)

            # service may return messages in the body; try to parse them
            try:
                msg = splunk.rest.extractMessages(root)
                if msg:
                    output.messages.extend(msg)
            except:
                pass
        except splunk.RESTException, e:
            responseCode = e.statusCode
            output.messages.append({
                'type': 'HTTP',
                'text': '%s %s' % (e.statusCode, e.msg)
            })
            if e.extendedMessages:
                output.messages.extend(e.extendedMessages)
Beispiel #4
0
    def dispatch_job(self, owner, namespace, kwargs):

        output = ODataEntity()
        responseCode = 500

        uri = splunk.entity.buildEndpoint("search", "jobs", owner=owner, namespace=namespace)

        try:
            serverStatus, serverResponse = self.simpleRequest(uri, postargs=kwargs, method="POST", raiseAllErrors=True)
            responseCode = serverStatus.status

            root = et.fromstring(serverResponse)
            if root.findtext("sid"):
                output.data = {"sid": root.findtext("sid")}

            # service may return messages in the body; try to parse them
            try:
                msg = splunk.rest.extractMessages(root)
                if msg:
                    output.messages.extend(msg)
            except:
                pass
        except splunk.RESTException, e:
            responseCode = e.statusCode
            output.messages.append({"type": "HTTP", "text": "%s %s" % (e.statusCode, e.msg)})
            if e.extendedMessages:
                output.messages.extend(e.extendedMessages)
    def http_simple_input(self, *args, **kwargs):
        # init
        output = ODataEntity()
        responseCode = 500
        serverResponse = None
        messages = []

        # Unfortunately, we can't use the Splunk API for this, so we just do it
        # ourselves
        base_url = "https://" + self.request['headers']['host'] + "/"
        path = self.request['path'].replace("/services/json/v1/", "")
        query = self.request["query"]
        query_string = ""
        if len(query):
            query_string = "?" + urllib.urlencode(query)
        uri = base_url + path + query_string

        # fetch data

        # Construct httplib2 such that it works with the version of httplib2 that requires SSL disabling
        h = None
        try:
            h = httplib2.Http(timeout=splunk.rest.SPLUNKD_CONNECTION_TIMEOUT,
                              disable_ssl_certificate_validation=True)
        except:
            h = httplib2.Http(timeout=splunk.rest.SPLUNKD_CONNECTION_TIMEOUT)

        serverStatus, serverResponse = h.request(
            uri,
            self.method,
            headers=self.request["headers"],
            body=self.request["payload"])
        responseCode = serverStatus.status

        # convert XML to struct
        if serverResponse:
            root = et.fromstring(serverResponse)
            result = {}

            for field in root.findall("results/result/field"):
                result[field.get("k")] = field.findtext("value/text")

            output.data = result

            # service may return messages in the body; try to parse them
            try:
                msg = splunk.rest.extractMessages(root)
                if msg:
                    messages.append(msg)
            except:
                raise

        # package and return
        output.messages = messages
        return responseCode, self.render_odata(output)
    def http_simple_input(self, *args, **kwargs):
        # init
        output = ODataEntity()
        responseCode = 500
        serverResponse = None
        messages = []
        
        # Unfortunately, we can't use the Splunk API for this, so we just do it
        # ourselves
        base_url = "https://" + self.request['headers']['host'] + "/"
        path = self.request['path'].replace("/services/json/v1/", "")
        query = self.request["query"] 
        query_string = ""
        if len(query): 
            query_string = "?" + urllib.urlencode(query)
        uri = base_url + path + query_string
        
        # fetch data
        
        # Construct httplib2 such that it works with the version of httplib2 that requires SSL disabling
        h = None
        try:
            h = httplib2.Http(timeout=splunk.rest.SPLUNKD_CONNECTION_TIMEOUT, disable_ssl_certificate_validation=True)
        except:
            h = httplib2.Http(timeout=splunk.rest.SPLUNKD_CONNECTION_TIMEOUT) 
            
        serverStatus, serverResponse = h.request(
            uri, 
            self.method, 
            headers=self.request["headers"], 
            body=self.request["payload"]
        )
        responseCode = serverStatus.status
        
        # convert XML to struct
        if serverResponse:
            root = et.fromstring(serverResponse)
            result = {}
            
            for field in root.findall("results/result/field"):
                result[field.get("k")] = field.findtext("value/text")
                
            output.data = result

            # service may return messages in the body; try to parse them
            try:
                msg = splunk.rest.extractMessages(root)
                if msg:
                    messages.append(msg)
            except:
                raise
                
        # package and return
        output.messages = messages
        return responseCode, self.render_odata(output) 
Beispiel #7
0
    def job_data(self, owner, namespace, sid, data_source, **kwargs):

        # redirect on control
        if data_source == 'control':
            return self.job_control(owner, namespace, sid, **kwargs)

        # init
        output = ODataEntity()
        responseCode = 500
        serverResponse = None
        messages = []

        # create API uri
        uri = splunk.entity.buildEndpoint('search/jobs/%s' % sid,
                                          data_source,
                                          owner=owner,
                                          namespace=namespace)
        kwargs['output_mode'] = 'xml'
        if data_source == 'summary':
            kwargs['output_time_format'] = '%s'

        # fetch data
        try:
            serverStatus, serverResponse = self.simpleRequest(
                uri, getargs=kwargs, raiseAllErrors=True)
            responseCode = serverStatus.status
        except splunk.RESTException, e:
            responseCode = e.statusCode
            messages.append({
                'type': 'HTTP',
                'text': '%s %s' % (e.statusCode, e.msg)
            })
            if e.extendedMessages:
                logger.error('ERROR: %s' % e.extendedMessages)
                messages.extend(e.extendedMessages)
Beispiel #8
0
    def response2odata(self, response_node, entity_class):
        """
        A handful of Splunk endpoints will not return a full Atom feed, but
        rather a short message block like:

        <response>
            <messages>
                <msg type="INFO">this is a message</msg>
                <msg type="ERROR">this is a message</msg>
            </messages>
        </response>
        """

        output = ODataEntity()
        output.entity_class = entity_class
        output.messages = splunk.rest.extractMessages(response_node)
        return output
    def auth(self):
        sessionKey = None
        try:
            username = self.request["form"]["username"]
            password = self.request["form"]["password"]
            sessionKey = splunk.auth.getSessionKey(username, password)
        except splunk.AuthenticationFailed:
            pass

        result = ODataEntity()
        result.data['sessionKey'] = sessionKey
        status = 200
        if not sessionKey:
            result.messages.append({'type': 'ERROR', 'text': 'login failed'})
            status = 401

        return status, self.render_odata(result)
Beispiel #10
0
    def response2odata(self, response_node, entity_class):
        '''
        A handful of Splunk endpoints will not return a full Atom feed, but
        rather a short message block like:

        <response>
            <messages>
                <msg type="INFO">this is a message</msg>
                <msg type="ERROR">this is a message</msg>
            </messages>
        </response>
        '''

        output = ODataEntity()
        output.entity_class = entity_class
        output.messages = splunk.rest.extractMessages(response_node)
        return output
Beispiel #11
0
    def entry2odata(self, entry_node, entity_class):
        '''
        parses lxml <entry> node to odata struct
        '''

        node = entry_node

        tmpEntity = ODataEntity()
        tmpEntity.entity_class = entity_class

        content_nodes = node.xpath('a:content', namespaces={'a': ATOM_NS})
        if len(content_nodes):
            content_node = content_nodes[0]
            if content_node.get('type') == 'text/xml':
                tmpEntity.data = splunk.rest.format.nodeToPrimitive(
                    content_node[0])
            else:
                tmpEntity.data = {'__text': content_node.text}

        # move the metadata around
        if isinstance(tmpEntity.data, dict):
            to_delete = []
            for k in tmpEntity.data:

                if k.startswith('eai:') and k != 'eai:data':
                    to_delete.append(k)
                    if hasattr(tmpEntity.metadata, k[4:]):
                        setattr(tmpEntity.metadata, k[4:], tmpEntity.data[k])
                    else:
                        logger.warn('encountered unknown EAI attribute: %s' %
                                    k)

            # the one exception
            if 'eai:data' in tmpEntity.data:
                tmpEntity.data['rawdata'] = tmpEntity.data['eai:data']
                to_delete.append('eai:data')

            for k in to_delete:
                del tmpEntity.data[k]

        # pull in all the links
        for link in node.xpath('a:link', namespaces={'a': ATOM_NS}):
            tmpEntity.metadata.links.append({
                'href': link.get('href'),
                'rel': link.get('rel')
            })

        # set other randoms
        tmpEntity.id = node.xpath('a:id', namespaces={'a': ATOM_NS})[0].text
        tmpEntity.name = node.xpath('a:title', namespaces={'a':
                                                           ATOM_NS})[0].text

        return tmpEntity
 def auth(self):
     sessionKey = None
     try:
         username = self.request["form"]["username"]
         password = self.request["form"]["password"]
         sessionKey = splunk.auth.getSessionKey(username, password)
     except splunk.AuthenticationFailed:
         pass
     
     result = ODataEntity()
     result.data['sessionKey'] = sessionKey
     status = 200
     if not sessionKey:
         result.messages.append({
             'type': 'ERROR',
             'text': 'login failed'
         })
         status = 401
         
     return status, self.render_odata(result)
    def get_origin_error(self):
        output = ODataEntity()
        output.messages.append({
            "type":
            "HTTP",
            "text":
            "Origin '%s' is not allowed. Please check json.conf" %
            self.remote_origin
        })

        return 403, self.render_odata(output)
    def properties_stanza(self, file, stanza, *args, **kwargs):
        output = ODataEntity()
        responseCode = 500
        serverResponse = None
        messages = []

        # fetch data
        try:
            serverStatus, serverResponse = self.forward_request()
            responseCode = serverStatus.status
        except splunk.RESTException, e:
            responseCode = e.statusCode
            messages.append({
                'type': 'HTTP',
                'text': '%s %s' % (e.statusCode, e.msg)
            })
            if e.extendedMessages:
                messages.extend(e.extendedMessages)
Beispiel #15
0
    def entry2odata(self, entry_node, entity_class):
        """
        parses lxml <entry> node to odata struct
        """

        node = entry_node

        tmpEntity = ODataEntity()
        tmpEntity.entity_class = entity_class

        content_nodes = node.xpath("a:content", namespaces={"a": ATOM_NS})
        if len(content_nodes):
            content_node = content_nodes[0]
            if content_node.get("type") == "text/xml":
                tmpEntity.data = splunk.rest.format.nodeToPrimitive(content_node[0])
            else:
                tmpEntity.data = {"__text": content_node.text}

        # move the metadata around
        if isinstance(tmpEntity.data, dict):
            to_delete = []
            for k in tmpEntity.data:

                if k.startswith("eai:") and k != "eai:data":
                    to_delete.append(k)
                    if hasattr(tmpEntity.metadata, k[4:]):
                        setattr(tmpEntity.metadata, k[4:], tmpEntity.data[k])
                    else:
                        logger.warn("encountered unknown EAI attribute: %s" % k)

            # the one exception
            if "eai:data" in tmpEntity.data:
                tmpEntity.data["rawdata"] = tmpEntity.data["eai:data"]
                to_delete.append("eai:data")

            for k in to_delete:
                del tmpEntity.data[k]

        # pull in all the links
        for link in node.xpath("a:link", namespaces={"a": ATOM_NS}):
            tmpEntity.metadata.links.append({"href": link.get("href"), "rel": link.get("rel")})

        # set other randoms
        tmpEntity.id = node.xpath("a:id", namespaces={"a": ATOM_NS})[0].text
        tmpEntity.name = node.xpath("a:title", namespaces={"a": ATOM_NS})[0].text

        return tmpEntity
    def parse_query(self, *args, **kwargs):
        output = ODataEntity()
        responseCode = 500
        serverResponse = None
        messages = []

        # Always get JSON, that way we don't need to do anything
        self.request["query"]["output_mode"] = "xml"

        # fetch data
        try:
            serverStatus, serverResponse = self.forward_request()
            responseCode = serverStatus.status
        except splunk.RESTException, e:
            responseCode = e.statusCode
            messages.append({
                'type': 'HTTP',
                'text': '%s %s' % (e.statusCode, e.msg)
            })
            if e.extendedMessages:
                messages.extend(e.extendedMessages)
    def delete_job(self, *args, **kwargs):
        output = ODataEntity()
        responseCode = 500

        try:
            serverStatus, serverResponse = self.forward_request()
            responseCode = serverStatus.status
            # service may return messages in the body; try to parse them
            try:
                msg = splunk.rest.extractMessages(
                    et.fromstring(serverResponse))
                if msg:
                    output.messages.extend(msg)
            except:
                pass
        except splunk.RESTException, e:
            responseCode = e.statusCode
            output.messages.append({
                'type': 'HTTP',
                'text': '%s %s' % (e.statusCode, e.msg)
            })
            if e.extendedMessages:
                output.messages.extend(e.extendedMessages)
Beispiel #18
0
    def job_control(self, owner, namespace, sid, action=None):
        '''
        provides individual job control
        '''

        output = ODataEntity()
        responseCode = 500

        if cherrypy.request.method != 'POST':
            raise cherrypy.HTTPError(405)

        uri = splunk.entity.buildEndpoint('search/jobs/%s' % sid,
                                          'control',
                                          owner=owner,
                                          namespace=namespace)
        args = {'action': action}

        try:
            serverStatus, serverResponse = self.simpleRequest(
                uri, postargs=args, raiseAllErrors=True)
            responseCode = serverStatus.status
            # service may return messages in the body; try to parse them
            try:
                msg = splunk.rest.extractMessages(
                    et.fromstring(serverResponse))
                if msg:
                    output.messages.extend(msg)
            except:
                pass
        except splunk.RESTException, e:
            responseCode = e.statusCode
            output.messages.append({
                'type': 'HTTP',
                'text': '%s %s' % (e.statusCode, e.msg)
            })
            if e.extendedMessages:
                output.messages.extend(e.extendedMessages)
    def handle(self):
        output = ODataEntity()
        status = 500

        try:
            self.extract_path()
            self.extract_origin()
            self.extract_sessionKey()
            self.extract_allowed_domains()

            # Get the appropriate handler
            handler, args, kwargs = self.router.match(self.scrubbed_path)

            # Check to see if we are in the list of allowed domains
            if not self.remote_origin in self.allowed_domains:
                status, content = self.get_origin_error()
            else:
                if isinstance(handler, dict):
                    if handler.has_key(self.method):
                        handler = handler[self.method]
                    else:
                        self.set_response(404, "")
                        return

                status, content = handler(*args, **kwargs)
        except splunk.RESTException, e:
            responseCode = e.statusCode
            output.messages.append({
                'type': 'HTTP',
                'text': '%s %s' % (e.statusCode, e.msg)
            })
            if hasattr(e, 'extendedMessages') and e.extendedMessages:
                for message in e.extendedMessages:
                    output.messages.append(message)

            content = self.render_odata(output)
    def job_data(self, data_source, *args, **kwargs):
        # init
        output = ODataEntity()
        responseCode = 500
        serverResponse = None
        messages = []

        # Modify the arguments
        self.request["query"]["output_mode"] = "xml"
        if data_source == 'summary':
            self.request["query"]["output_time_format"] = "%s"

        # fetch data
        try:
            serverStatus, serverResponse = self.forward_request()
            responseCode = serverStatus.status
        except splunk.RESTException, e:
            responseCode = e.statusCode
            messages.append({
                'type': 'HTTP',
                'text': '%s %s' % (e.statusCode, e.msg)
            })
            if e.extendedMessages:
                messages.extend(e.extendedMessages)
    def entry2odata(self, entry_node, entity_class):
        '''
        parses lxml <entry> node to odata struct
        '''
        
        node = entry_node
        
        tmpEntity = ODataEntity()
        tmpEntity.entity_class = entity_class
        
        tmpEntity.data = {}
        content_xpath = node.xpath('a:content', namespaces={'a': ATOM_NS})
        if (len(content_xpath) > 0):
            if (len(content_xpath[0]) > 0):
                content_node = content_xpath[0][0]
                tmpEntity.data = splunk.rest.format.nodeToPrimitive(content_node)
            else:
                tmpEntity.data = {"data": content_xpath[0].text}
    
        # move the metadata around
        if isinstance(tmpEntity.data, dict):
            to_delete = []
            for k in tmpEntity.data:

                if k.startswith('eai:') and k != 'eai:data':
                    to_delete.append(k)
                    if hasattr(tmpEntity.metadata, k[4:]):
                        setattr(tmpEntity.metadata, k[4:], tmpEntity.data[k])
                    else:
                        logger.warn('encountered unknown EAI attribute: %s' % k)

            # the one exception
            if 'eai:data' in tmpEntity.data:
                tmpEntity.data['rawdata'] = tmpEntity.data['eai:data']
                to_delete.append('eai:data')

            for k in to_delete:
                del tmpEntity.data[k]
            
        # pull in all the links
        for link in node.xpath('a:link', namespaces={'a': ATOM_NS}):
            tmpEntity.metadata.links.append({
                'href': link.get('href'),
                'rel': link.get('rel')
            })
        
        # set other randoms
        tmpEntity.id = node.xpath('a:id', namespaces={'a': ATOM_NS})[0].text
        tmpEntity.name = tmpEntity.data.get("name", node.xpath('a:title', namespaces={'a': ATOM_NS})[0].text)
        
        published_info = node.xpath('a:published', namespaces={'a': ATOM_NS})
        if published_info:
            tmpEntity.data["published"] = published_info[0].text
            
        updated_info = node.xpath('a:updated', namespaces={'a': ATOM_NS})
        if updated_info:
            tmpEntity.data["updated"] = updated_info[0].text
            
        author_info = node.xpath('a:author/a:name', namespaces={'a': ATOM_NS})
        if author_info:
            tmpEntity.data["author"] = author_info[0].text
        
        return tmpEntity
    def entry2odata(self, entry_node, entity_class):
        '''
        parses lxml <entry> node to odata struct
        '''

        node = entry_node

        tmpEntity = ODataEntity()
        tmpEntity.entity_class = entity_class

        tmpEntity.data = {}
        content_xpath = node.xpath('a:content', namespaces={'a': ATOM_NS})
        if (len(content_xpath) > 0):
            if (len(content_xpath[0]) > 0):
                content_node = content_xpath[0][0]
                tmpEntity.data = splunk.rest.format.nodeToPrimitive(
                    content_node)
            else:
                tmpEntity.data = {"data": content_xpath[0].text}

        # move the metadata around
        if isinstance(tmpEntity.data, dict):
            to_delete = []
            for k in tmpEntity.data:

                if k.startswith('eai:') and k != 'eai:data':
                    to_delete.append(k)
                    if hasattr(tmpEntity.metadata, k[4:]):
                        setattr(tmpEntity.metadata, k[4:], tmpEntity.data[k])
                    else:
                        logger.warn('encountered unknown EAI attribute: %s' %
                                    k)

            # the one exception
            if 'eai:data' in tmpEntity.data:
                tmpEntity.data['rawdata'] = tmpEntity.data['eai:data']
                to_delete.append('eai:data')

            for k in to_delete:
                del tmpEntity.data[k]

        # pull in all the links
        for link in node.xpath('a:link', namespaces={'a': ATOM_NS}):
            tmpEntity.metadata.links.append({
                'href': link.get('href'),
                'rel': link.get('rel')
            })

        # set other randoms
        tmpEntity.id = node.xpath('a:id', namespaces={'a': ATOM_NS})[0].text
        tmpEntity.name = tmpEntity.data.get(
            "name",
            node.xpath('a:title', namespaces={'a': ATOM_NS})[0].text)

        published_info = node.xpath('a:published', namespaces={'a': ATOM_NS})
        if published_info:
            tmpEntity.data["published"] = published_info[0].text

        updated_info = node.xpath('a:updated', namespaces={'a': ATOM_NS})
        if updated_info:
            tmpEntity.data["updated"] = updated_info[0].text

        author_info = node.xpath('a:author/a:name', namespaces={'a': ATOM_NS})
        if author_info:
            tmpEntity.data["author"] = author_info[0].text

        return tmpEntity