Esempio n. 1
0
    def _transform_request_options(self, rest_options, url_parts, request):
        """
        - Overridden from SplunkRestEndpointProxy
        - Handling experiment specific modification/handling of the request before
        sending the request to kvstore
        - See RestProxy.make_rest_call() for a list of available items for `rest_options`

        Args:
            rest_options (dict): default rest_options constructed by the request method (get, post, delete)
            url_parts (list): a list of url parts without /mltk/experiments
            request (dict): the original request from the rest call to /mltk/experiments/*

        Raises:
            SplunkRestProxyException: some error occurred during this process

        Returns:
            options (tuple) : a two element tuple.  the first element is a dictionary that stores parameters needed by
            RestProxy.make_rest_call(), and the second element stores parameters for _handle_reply, if any.
        """

        if url_parts > 0:
            experiment_id = url_parts[0]
        else:
            raise SplunkRestProxyException('No experiment id specified',
                                           logging.ERROR, httplib.BAD_REQUEST)

        if rest_options['method'] == 'GET' or rest_options[
                'method'] == 'DELETE':
            rest_options['getargs'] = dict(
                rest_options.get('getargs', []) +
                [("query", json.dumps({'experimentId': experiment_id}))])

        if rest_options['method'] == 'POST':
            experiment_history = json.loads(request.get('payload', '{}'))

            experiment_history["experimentId"] = experiment_id

            try:
                validate_experiment_history_json(experiment_history)

                # these are intentionally added after validation, since we don't want to allow the user to submit them
                searchinfo = searchinfo_from_request(request)
                experiment_history["_time"] = time.time()
                experiment_history["user"] = searchinfo["username"]
                experiment_history["app"] = searchinfo["app"]
            except Exception as e:
                logger.error(str(e))
                raise SplunkRestProxyException(
                    'Can not validate experiment history', logging.ERROR,
                    httplib.BAD_REQUEST)
            rest_options['jsonargs'] = json.dumps(experiment_history)

        return rest_options, {}
    def _handle_reply(self, reply, reply_options, request, url_parts, method):
        """
        - Overridden from SplunkRestEndpointProxy
        - Replace '/configs/conf-experiments' in the reply with '/mltk/experiments'

        Args:
            reply (dict): the reply we got from '/configs/conf-experiments'
            reply_options (dict): the reply options from '_transform_request_options'
            url_parts (list): a list of url parts without /mltk/experiments
            method (string): original request's method

        Returns:
            reply: reply from input after the filtering
        """
        def deproxy(string):
            # replace '/configs/conf-experiments' with '/mltk/experiments'
            return string.replace('/%s' % '/'.join(self.URL_PARTS_PREFIX),
                                  '/mltk/experiments')

        content = json.loads(reply.get('content'))

        if content.get('origin'):
            content['origin'] = deproxy(content['origin'])

        if content.get('links'):
            for key, value in content['links'].iteritems():
                content['links'][key] = deproxy(value)

        if content.get('entry'):
            entry = content['entry']
            for item in entry:
                item['id'] = deproxy(item['id'])
                for key, value in item['links'].iteritems():
                    item['links'][key] = deproxy(value)

        # promote the draft model to production.
        if reply_options.get(
                'promote_model') and method == 'POST' and reply.get(
                    'status') == httplib.OK:
            searchinfo = searchinfo_from_request(request)

            promote_draft_model_callback = self._promote_draft_model_callback(
                searchinfo)
            self._handle_all_experiment_models(reply,
                                               promote_draft_model_callback)

        return {
            'status': reply.get('status', httplib.OK),
            'payload': json.dumps(content)
        }
 def _delete_models(request, url_parts):
     if len(url_parts) == 1:
         try:
             searchinfo = searchinfo_from_request(request)
             rest_proxy = rest_proxy_from_searchinfo(searchinfo)
             model_list = get_model_list_by_experiment(
                 rest_proxy, namespace='user', experiment_id=url_parts[0])
             for model_name in model_list:
                 url = rest_url_util.make_get_lookup_url(
                     rest_proxy, namespace='user', lookup_file=model_name)
                 reply = rest_proxy.make_rest_call('DELETE', url)
         except Exception as e:
             cexc.log_traceback()
             pass
Esempio n. 4
0
    def handle_get(cls, request, path_parts):
        """
        Handles GET requests

        Args:
            request: a dictionary providing information about the request
            path_parts: a list of strings describing the request path
        """
        searchinfo = searchinfo_from_request(request)

        models = listmodels.list_models(searchinfo, query_params=[tuple(r) for r in request['query']])

        return {
            'payload': models,
            'status': 200
        }
    def clone_experiment_models(self, experiment_fetch_reply, request,
                                url_parts):
        """
        the function performs the "clone models" operation for an experiment, the experiment info is from 'experiment_fetch_reply'
        Args:
            experiment_fetch_reply (dict) : the reply from a mltk/experiments/<guid> POST request
            request (dict) : the request object
            url_parts (list) : a subset of the url, here is a list of length 1 which contains experiment id.

        Returns:
            (dict) a dictionary of `status` and `payload`
        """
        target_info = json.loads(request.get('payload', {}))
        if target_info.viewkeys() == {'app', 'name'}:
            target_model_name = target_info.get('name')
            if not is_valid_identifier(target_model_name):
                raise SplunkRestProxyException(
                    'Invalid model name "%s"' % target_model_name,
                    logging.ERROR, httplib.BAD_REQUEST)

            source_searchinfo = searchinfo_from_request(request)
            target_searchinfo = copy.deepcopy(source_searchinfo)
            target_searchinfo['app'] = target_info.get('app')

            clone_experiment_model_callback = self._clone_experiment_model_callback(
                source_searchinfo,
                target_searchinfo,
                target_model_name,
                url_parts[0],
                reply_handler=self._add_model_name_to_reply)

            reply_list = self._handle_all_experiment_models(
                experiment_fetch_reply, clone_experiment_model_callback)

            formatted_reply = self._handle_clone_reply(reply_list)

            return self._handle_reply(formatted_reply, {}, request, url_parts,
                                      'POST')

        else:
            raise SplunkRestProxyException(
                'This handler only supports "app" and "name" as arguments',
                logging.ERROR, httplib.BAD_REQUEST)
Esempio n. 6
0
 def from_rest_request(request, with_admin_token=False):
     searchinfo = searchinfo_from_request(request, with_admin_token)
     return SplunkRestProxy.from_searchinfo(searchinfo, with_admin_token)