Exemple #1
0
 def save_stream(self, **kwargs):
     amp_api = ApiService(kwargs['api_host'], kwargs['api_id'],
                          kwargs['api_key'])
     storage = AmpStorageWrapper(self.__metadata(kwargs.get('name')))
     stream = storage.find_stream()
     if stream is None:
         logger.info('Controller - Creating the stream at API')
         response = amp_api.create(kwargs)
         logger.info('Controller - Created the stream at API: {}'.format(
             kwargs.get('name')))
         storage.save_stream_with_data(
             StreamDictManager(response['data']).merged_with(kwargs))
     else:
         dict_manager = StreamDictManager(stream)
         diff = dict_manager.diff_fields_from(kwargs)
         if len(diff) > 0:
             logger.info(
                 'Controller - Updating the stream at API {}'.format(
                     stream.get('name')))
             amp_api.update(stream['id'], diff)
             storage.save_stream_with_data(dict_manager.merged_with(kwargs))
             logger.info('Controller - Updated the stream at API')
     output = jsonresponse.JsonResponse()
     output.success = True
     return self.render_json(output)
Exemple #2
0
 def save_api_key(self, **kwargs):
     session_key = cherrypy.session.get('sessionKey')
     service = client.connect(token=session_key)
     service.storage_passwords.create(kwargs['api_key'], kwargs['api_id'])
     output = jsonresponse.JsonResponse()
     output.success = True
     return self.render_json(output)
Exemple #3
0
 def delete_event_stream(self, **kwargs):
     amp_api = ApiService(kwargs['api_host'], kwargs['api_id'],
                          kwargs['api_key'])
     self.__try_destroy_stream(amp_api, kwargs['id'])
     output = jsonresponse.JsonResponse()
     output.success = True
     return self.render_json(output)
 def build_response(self, entities, selectionMode=None):
     output = jsonresponse.JsonResponse()
     output.count = entities.itemsPerPage
     output.offset = entities.offset
     output.total = entities.totalResults
     output.data = []
     
     if entities:
         if len(entities) == 1 and not entities.values()[0].get('name'):
             # empty node
             return output
         
         blocks = []
         for ent in entities.values():
             hasChildren = util.normalizeBoolean(ent.get('hasSubNodes', True))
             block = {'text': ent.get('name', ent.name), 
                      'fileSize': ent.get('fileSize'), 
                      'id': ent.name, 
                      'hasChildren': hasChildren, 
                      'classes': 'nonleaf' if hasChildren else 'leaf',
                      'selectable': self.is_selectable(ent, selectionMode)
                     }
             blocks.append(block)
         output.data = sorted(blocks, key=lambda block: block['text'].lower())
         
     return output
Exemple #5
0
    def getPanel(self, namespace, view_id, panel_type, panel_sequence,
                 **unused):
        '''
        Returns a dashboard panel config
        
        GET /<namespace>/<view_id>/panel/<panel_sequence>
            --> panel config for panel at <panel_sequence>
            
            ==> returns a JSON response
        '''

        output = jsonresponse.JsonResponse()

        try:
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS,
                                       view_id,
                                       namespace=namespace,
                                       owner=username)
            dashObject = Dashboard.get(dash_id)
            output.data = dashObject.get_panel(panel_sequence)

        except IndexError, e:
            cherrypy.response.status = 404
            output.success = False
            output.addError(
                _('Requested panel %s does not exist') % panel_sequence)
Exemple #6
0
    def insecurelogin(self, username=None, password=None, return_to=None):
        '''
        Provide insecure login endpoint for HTTP GET-based credential passing
        '''

        # Force a refresh of startup info so that we know to
        # redirect if license stuff has expired.
        startup.initVersionInfo(force=True)

        output = jsonresponse.JsonResponse()

        if not splunk.util.normalizeBoolean(
                cherrypy.config.get('enable_insecure_login')):
            cherrypy.response.status = 403
            output.success = False
            output.addError(
                'The insecure login endpoint is disabled. See web.conf for details.'
            )
            return self.render_json(output)

        if not username or not password:
            cherrypy.response.status = 400
            output.success = False
            output.addError('Missing credentials')
            return self.render_json(output)

        try:
            sessionKey = splunk.auth.getSessionKey(
                username, password, hostPath=self.splunkd_urlhost)
        except Exception, e:
            output.parseRESTException(e)
            output.success = False
            return self.render_json(output)
 def render_error_json(self, msg):
     output = jsonresponse.JsonResponse()
     output.data = []
     output.success = False
     output.addError(msg)
     cherrypy.response.status = 400
     return self.render_json(output, set_mime='text/plain')
Exemple #8
0
    def render_error_json(self, msg):
        """
        Render JSON that describes an error state.
        """

        output = jsonresponse.JsonResponse()
        output.data = []
        output.success = False
        output.addError(msg)
        return self.render_json(output, set_mime='text/plain')
Exemple #9
0
    def setPanel(self,
                 namespace,
                 view_id,
                 panel_type,
                 panel_sequence,
                 panel_class=None,
                 action='edit',
                 **panel_definition):
        '''
        Provides management for view panel objects
        
        The HTTP signature for this method expects standard form params to match
        the property names used in the panel objects.  All form params are
        inserted into a dict and passed into the panel object for processing
        
        POST /<namespace>/<view_id>/panel/<panel_sequence>
            &action=edit
            --> updates the existing panel at <panel_sequence>
            &action=delete
            --> deletes the panel at <panel_sequence>
            
            ==> returns JSON response
        '''

        output = jsonresponse.JsonResponse()

        self.collatePanelOptions(panel_definition)

        try:
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS,
                                       view_id,
                                       namespace=namespace,
                                       owner=username)
            dashObject = Dashboard.get(dash_id)

            if action == 'edit':
                dashObject.set_panel(panel_sequence, panel_class,
                                     **panel_definition)

            elif action == 'delete':
                dashObject.delete_panel(panel_sequence)

            else:
                raise ValueError, 'Unknown action requested: %s' % action

            dashObject.save()
            output.addInfo(_('Successfully updated %s' % view_id))

        except Exception, e:
            logger.exception(e)
            output.success = False
            output.addError(
                _('Unable to update panel at sequence %s: %s') %
                (panel_sequence, e))
 def delete_stream(self, **kwargs):
     amp_api = ApiService(kwargs['api_host'], kwargs['api_id'], kwargs['api_key'])
     storage = AmpStorageWrapper(self.__metadata(kwargs.get('name')))
     stream = storage.find_stream()
     if stream is not None:
         logger.info('Controller - Deleting the stream at API: {}'.format(stream.get('name')))
         self.__try_destroy_stream(amp_api, stream['id'])
         storage.delete_stream()
     output = jsonresponse.JsonResponse()
     output.success = True
     return self.render_json(output)
    def render_error_json(self, msg):
        """
        Render an error such that it can be returned to the client as JSON.

        Arguments:
        msg -- A message describing the problem (a string)
        """

        output = jsonresponse.JsonResponse()
        output.data = []
        output.success = False
        output.addError(msg)
        return self.render_json(output)
Exemple #12
0
 def fetch_api_key(self, **kwargs):
     session_key = cherrypy.session.get('sessionKey')
     service = client.connect(token=session_key)
     storage_passwords = service.storage_passwords
     api_key = None
     for storage_password in storage_passwords:
         if kwargs['api_id'] in storage_password.name:
             api_key = storage_password.clear_password
             break
     output = jsonresponse.JsonResponse()
     output.success = True
     output.api_key = api_key
     return self.render_json(output)
 def add_error(self, output, error):
     status = None
     if not error: return output
     
     if not output:
         output = jsonresponse.JsonResponse()
         output.data = []
     if isinstance(error, tuple):
         status = error[1]
         error = error[0]
         
     if status:
         cherrypy.response.status = status
     output.success = False
     output.addError(error)
     
     return output
Exemple #14
0
    def createPanel(self, namespace, view_id, panel_type, panel_class,
                    **panel_definition):
        '''
        Create a new panel to add to an existing dashboard
        
        POST /<namespace>/<view_id>/<panel_type=panel>
            &panel_class={table | chart | html | event | list}
            &<panel_property>=<property_value>
                --> creates a new panel
                
            the <panel_property> is a direct map to the panel XML data
            
            ==> returns a JSON response
        '''

        output = jsonresponse.JsonResponse()

        try:

            if panel_type != 'panel':
                raise ValueError, 'Only panel type "panel" is currently supported'

            # support all options
            self.collatePanelOptions(panel_definition)

            # get dashboard and create panel
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS,
                                       view_id,
                                       namespace=namespace,
                                       owner=username)
            dashObject = Dashboard.get(dash_id)

            dashObject.create_panel(type=panel_class, **panel_definition)

            dashObject.save()

        except Exception, e:
            logger.exception(e)
            output.success = False
            output.addError(_('Unable to add panel: %s') % e)
    def insecurelogin(self, username=None, password=None, return_to=None):
        '''
        Provide insecure login endpoint for HTTP GET-based credential passing
        '''

        # Force a refresh of startup info so that we know to
        # redirect if license stuff has expired.
        startup.initVersionInfo(force=True)

        output = jsonresponse.JsonResponse()

        if not splunk.util.normalizeBoolean(
                cherrypy.config.get('enable_insecure_login')):
            cherrypy.response.status = 403
            output.success = False
            output.addError(
                'The insecure login endpoint is disabled. See web.conf for details.'
            )
            return self.render_json(output)

        if not username or not password:
            cherrypy.response.status = 400
            output.success = False
            output.addError('Missing credentials')
            return self.render_json(output)

        ua = cherrypy.request.headers.get('user-agent', 'unknown')
        ip = cherrypy.request.remote.ip
        try:
            sessionKey = splunk.auth.getSessionKey(
                username, password, hostPath=self.splunkd_urlhost)
        except Exception, e:
            logger.error('user=%s action=insecurelogin status=failure session=%s ' \
                'reason=user-initiated useragent="%s" clientip=%s'
                % (username, sessionKey, ua, ip))
            output.parseRESTException(e)
            output.success = False
            return self.render_json(output)
Exemple #16
0
    def setContainer(self, namespace, view_id, action, view_json=None):
        '''
        Provides support to modify dashboard configs
        
        POST /<namespace>/<view_id>
            &action=delete
                --> deletes the current view
            &action=edit
                --> updates the current view config (view JSON object)
                
            ==> returns a JSON response
        '''

        output = jsonresponse.JsonResponse()

        try:

            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS,
                                       view_id,
                                       namespace=namespace,
                                       owner=username)
            dashObject = Dashboard.get(dash_id)

            if action == 'delete':
                dashObject.delete()
                output.addInfo(_('Successfully deleted %s') % view_id)

            elif action == 'edit':

                # convert incoming JSON to native struct; clean strings,
                view_json = json.loads(view_json)

                if view_json.get('label'):
                    dashObject.label = view_json['label'].strip()
                if view_json.get('refresh'):
                    dashObject.refresh = int(view_json['refresh'].strip())

                # handle panel reordering; wrap number of columns to the max
                # column constraint
                newPanelDefinition = []
                for row in view_json['new_panel_sequence']:
                    newRow = []
                    for seq in row:
                        newRow.append(dashObject._obj.getPanelBySequence(seq))
                        if len(
                                newRow
                        ) >= splunk.models.dashboard.MAX_DASHBOARD_ROW_SIZE:
                            newPanelDefinition.append(newRow)
                            newRow = []
                    if len(row) > 0:
                        newPanelDefinition.append(newRow)
                dashObject._obj.rows = newPanelDefinition

                # ensure that the row grouping array is synced
                if len(dashObject._obj.rowGrouping) < len(
                        dashObject._obj.rows):
                    dashObject._obj.rowGrouping.extend(
                        [None] * (len(dashObject._obj.rows) -
                                  len(dashObject._obj.rowGrouping)))

                # commit
                dashObject.save()
                output.addInfo(_('Successfully updated %s') % view_id)

            else:
                output.success = False
                output.addError(
                    _('Unrecognized dashboard action: %s; cannot process') %
                    action)
                logger.error(
                    'Unrecognized dashboard action: %s; cannot process' %
                    action)

        except splunk.ResourceNotFound:
            cherrypy.response.status = 404
            output.addWarn(_('"%s" was not found; no action taken') % view_id)

        except Exception, e:
            output.success = False
            output.addError(_('Unable to update view %s: %s') % (view_id, e))
            logger.exception(e)
Exemple #17
0
    def getContainer(self, namespace, view_id, mode='', **unused):
        '''
        Renders the dashboard edit page
        
        GET /<namespace>/<view_id>
            ==> HTML form page with dashboard edit form (labels, panels) and
                master panel edit form (hidden)
            
        GET /api/<namespace>/<view_id>
            ==> JSON structure of dashboard config (unused?)
        '''

        # serve data feed
        output = jsonresponse.JsonResponse()

        try:
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS,
                                       view_id,
                                       namespace=namespace,
                                       owner=username)
            dashObject = Dashboard.get(dash_id)
            output.data = dashObject._obj.toJsonable()

        except splunk.ResourceNotFound:
            cherrypy.response.status = 404
            output.success = False
            output.addError(_('View %s was not found') % view_id)
            return self.render_json(output)

        # serve template page
        if cherrypy.request.is_api:
            return self.render_json(output)
        else:
            cherrypy.response.headers['content-type'] = MIME_HTML

            # get supporting assets

            savedSearches = en.getEntities('saved/searches',
                                           namespace=namespace,
                                           count=-1,
                                           search="is_visible=1")

            for savedSearch in savedSearches:
                acl = savedSearches[savedSearch]['eai:acl']
                if dashObject.metadata.sharing == 'user':
                    continue
                if dashObject.metadata.sharing == 'app' and acl[
                        'sharing'] == 'user':
                    savedSearches[savedSearch]['dq'] = True
                    continue
                if dashObject.metadata.sharing == 'global' and acl[
                        'sharing'] != 'global':
                    savedSearches[savedSearch]['dq'] = True
                    continue
                if dashObject.metadata.perms['read'].count(
                        '*') > 0 and acl['perms']['read'].count('*') == 0:
                    savedSearches[savedSearch]['dq'] = True
                    continue

            #dashboardObject = splunk.entity.getEntity('data/ui/views', view_id, namespace=APP['id'], owner=cherrypy.session['user'].get('name'))
            #dashOwner = dashboardObject['eai:acl'].get('owner', 'nobody')

            editLink = self.make_url(
                ['manager', namespace, 'data/ui/views', view_id],
                _qs=dict(action='edit',
                         url=self.make_url(['app', namespace, view_id]),
                         redirect_override="/app/%s/%s" %
                         (namespace, view_id)))

            permissionsLink = self.make_url(
                [
                    'manager', 'permissions', namespace, 'data/ui/views',
                    view_id
                ],
                _qs=dict(
                    uri=en.buildEndpoint('data/ui/views',
                                         view_id,
                                         namespace=namespace,
                                         owner=dashObject.metadata.owner)))

            return self.render_template(
                'viewmaster/edit_dashboard.html', {
                    'namespace': namespace,
                    'view_id': view_id,
                    'view_object': dashObject._obj,
                    'APP': {
                        'id': namespace
                    },
                    'savedSearches': savedSearches,
                    'editLink': editLink,
                    'permissionsLink': permissionsLink,
                    'mode': mode,
                })
Exemple #18
0
    def createContainer(self,
                        namespace,
                        view_id='',
                        view_label='',
                        container_type='dashboard'):
        '''
        Handles dashboard creation
        
        GET /<namespace>
            ==> HTML template form to input create data
            
        POST /<namespace>
            ==> Saves the HTML input values from GET
            
            == returns JSON response
        '''

        #
        # serve template
        #

        if cherrypy.request.method == 'GET':
            return self.render_template('viewmaster/create_dashboard.html',
                                        {'namespace': namespace})

        #
        # handle create view
        #

        output = jsonresponse.JsonResponse()

        # clean inputs
        view_id = re.sub(r'[^\w]', '', view_id)
        view_label = view_label.strip() or view_id

        if view_id == '':
            output.success = False
            output.addError(_('Dashboard ID cannot be empty'))
            return self.render_json(output)

        # check that view doesn't already exist
        try:
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS,
                                       view_id,
                                       namespace=namespace,
                                       owner=username)
            Dashboard.get(dash_id)
            output.success = False
            output.addError(
                _('Cannot create new %(container_type)s: %(view_id)s already exists') \
                % {'container_type': container_type, 'view_id': view_id})
            return self.render_json(output)

        except splunk.ResourceNotFound:
            pass

        # generate new
        try:
            view = Dashboard(namespace, username, view_id)
            view.label = view_label
            view.save()

            output.data = {'view_id': view_id, 'view_label': view_label}
            output.addInfo(_('Successfully created new %(container_type)s: %(view_id)s') \
                % {'container_type': container_type, 'view_id': view_id})
            logger.info('Created new %s: namespace=%s id=%s label=%s' %
                        (container_type, namespace, view_id, view_label))

        except Exception, e:
            logger.exception(e)
            output.success = False
            output.addError(_('Unable to create dashboard: %s') % e)
Exemple #19
0
 def __json_error(self, payload):
     output = jsonresponse.JsonResponse()
     output.error = payload
     output.success = False
     return self.render_json(output)
    def dispatcher(self, service, action=None, **kwargs):
        '''
        This is the main dispatcher that provides compatibility with the
        Twitter API.  The URI structure of Twitter's API is not as clean as the
        routes system expects; we route everything through here first.
        '''

        # parse the URI
        serviceParts = service.split('.', 2)
        handler = serviceParts[0]
        actionParts = action.split('.', 2)
        action = actionParts[0]

        outputMode = 'html'
        if len(serviceParts) > 1:
            outputMode = serviceParts[-1]
        elif len(actionParts) > 1:
            outputMode = actionParts[-1]

        data = None

        if handler == 'statuses':

            if action == 'public_timeline':
                searchString = 'search index=twink | head 100'
                data = self.executeSearch(searchString)

            elif action == 'user_timeline':
                searchString = 'search index=twink source="%s" | head 100' % kwargs.get(
                    'screen_name', cherrypy.session['user'].get('name'))
                data = self.executeSearch(searchString)

            elif action == 'mentions':
                pass

            elif action == 'show':
                pass

            elif action == 'update':
                self.addTweet(kwargs['status'])
                raise cherrypy.HTTPRedirect('public_timeline')

            else:
                raise cherrypy.HTTPError(
                    404, 'statuses does not recognize action: %s' % action)

        elif handler == 'search':
            searchString = 'search index=twink | head 100'

        elif handler == 'saved_searches':
            if action == 'show':
                pass
            else:
                pass

        else:
            raise cherrypy.HTTPError(404, 'handler not found: %s' % handler)

        if outputMode == 'html':
            cherrypy.response.headers['content-type'] = MIME_HTML
            return self.render_template(
                '/twink:/templates/public_timeline.html', {'stream': data})

        elif outputMode == 'json':
            output = jsonresponse.JsonResponse()
            output.data = data
            return self.render_json(output)

        else:
            raise cherrypy.HTTPError(500, 'something is wrong')