Пример #1
0
    def test_modify_variables(self):
        prepare_variables(self.variable_dao)

        # use test variable in 'new_app' to check
        new_app_variable = SAMPLE_VARIABLE.copy()
        new_app_variable.app = 'new_app'
        new_app_variable.name = 'var1'

        # first check
        url = "/default/variable_models?app=new_app"
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(len(res['values']), 1)
        get_variable = VariableModel.from_dict(res['values'][0])
        self.assertEqual(new_app_variable, get_variable)

        # 1. modify variable and test
        # 1.1 modify test variable, so it is doesn't equal now
        new_app_variable.remark = 'new_remark'
        self.assertNotEquals(new_app_variable, get_variable)

        # 1.2 post the modified variable
        url = "/default/variable_models"
        response = self.fetch(url, method='POST', body='[%s]' % new_app_variable.get_json())
        res = json.loads(response.body)
        self.assertEqual(res['status'], 0)
        self.assertEqual(res['msg'], 'ok')

        # 1.3 verify again
        url = "/default/variable_models?app=new_app"
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(len(res['values']), 1)
        get_variable = VariableModel.from_dict(res['values'][0])
        # now equal again
        self.assertEqual(new_app_variable, get_variable)

        # 2. add an variable with post
        # 2.1 now there are 4 variables
        url = "/default/variable_models"
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(len(res['values']), 4)

        # 2.2 add one
        added_variable = SAMPLE_VARIABLE.copy()
        added_variable.name = 'added_variable'
        response = self.fetch(url, method='POST', body='[%s]' % added_variable.get_json())
        res = json.loads(response.body)
        self.assertEqual(res['status'], 0)
        self.assertEqual(res['msg'], 'ok')

        # 2.3 now there are 5
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(len(res['values']), 5)
Пример #2
0
    def tests_modify_variable(self):
        prepare_variables(self.cust_dao)
        url = "/platform/variable_models/variable/{}/{}".format(SAMPLE_VARIABLE.app, SAMPLE_VARIABLE.name)
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(res['status'], 0)
        self.assertEqual(res['msg'], 'ok')
        self.assertEqual(len(res['values']), 1)
        get_variable = VariableModel.from_dict(res['values'][0])
        self.assertEqual(get_variable, SAMPLE_VARIABLE)

        # 1. modify SAMPLE_VARIABLE
        # 1.1 first not equal
        new_sample = SAMPLE_VARIABLE.copy()
        new_sample.remark = 'modified'
        self.assertNotEquals(get_variable, new_sample)

        # 1.2 second modify
        response = self.fetch(url, method='POST', body=new_sample.get_json())
        res = json.loads(response.body)
        self.assertEqual(res['status'], 0)
        self.assertEqual(res['msg'], 'ok')

        # 1.3 third  check
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(res['status'], 0)
        self.assertEqual(res['msg'], 'ok')
        self.assertEqual(len(res['values']), 1)
        get_variable = VariableModel.from_dict(res['values'][0])
        self.assertEqual(get_variable, new_sample)

        # 2. add a new one
        # 2.1 get 404
        url = "/platform/variable_models/variable/{}/{}".format(SAMPLE_VARIABLE.app, 'variable_to_be_add')
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(res['status'], 404)

        # 2.2 add one
        variable_to_be_add = SAMPLE_VARIABLE.copy()
        variable_to_be_add.name = 'variable_to_be_add'
        response = self.fetch(url, method='POST', body=variable_to_be_add.get_json())
        res = json.loads(response.body)
        self.assertEqual(res['status'], 0)
        self.assertEqual(res['msg'], 'ok')

        # 2.3 check
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(res['status'], 0)
        self.assertEqual(res['msg'], 'ok')
        self.assertEqual(len(res['values']), 1)
        get_variable = VariableModel.from_dict(res['values'][0])
        self.assertEqual(get_variable, variable_to_be_add)
Пример #3
0
def load_config():
    print("loading config")
    for _ in get_file_json_content('data/event_model_default.json'):
        add_event_to_registry(EventModel.from_dict(_))

    for _ in get_file_json_content('data/common_variable_default.json'):
        add_variable_to_registry(VariableModel.from_dict(_))
    for _ in get_file_json_content('data/realtime_variable_default.json'):
        add_variable_to_registry(VariableModel.from_dict(_))
    for _ in get_file_json_content('data/profile_variable_default.json'):
        add_variable_to_registry(VariableModel.from_dict(_))
Пример #4
0
    def post(self):
        """
        美化一组variable

        @API
        summary: 美化一组variable
        notes: 美化一组variable
        tags:
          - platform
        parameters:
          -
            name: variable
            in: body
            required: true
            type: json
            description: 一组variable的json表示
        produces:
          - application/json
        """

        self.set_header('content-type', 'application/json')
        body = self.request.body
        try:
            variables = list()
            for _ in json.loads(body):
                variable = VariableModel.from_dict(_)
                variables.append(variable)
            variables = [_.get_simplified_ordered_dict() for _ in variables]
            self.finish(json_dumps({"status": 0, "msg": "ok", "values": variables}))
        except Exception as err:
            print_exc()
            return self.process_error(400, str(err))
Пример #5
0
    def test_delete_variable(self):
        prepare_variables(self.cust_dao)
        url = "/platform/variable_models/variable/{}/{}".format(SAMPLE_VARIABLE.app, SAMPLE_VARIABLE.name)
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(res['status'], 0)
        self.assertEqual(res['msg'], 'ok')
        self.assertEqual(len(res['values']), 1)
        self.assertEqual(VariableModel.from_dict(res['values'][0]), SAMPLE_VARIABLE)

        # delete
        url = "/platform/variable_models/variable/{}/{}".format(SAMPLE_VARIABLE.app, SAMPLE_VARIABLE.name)
        response = self.fetch(url, method='DELETE')
        res = json.loads(response.body)
        self.assertEqual(res['status'], 0)
        self.assertEqual(res['msg'], 'ok')

        # check
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(res['status'], 404)

        # can not delete default
        clear_variables(self.cust_dao)
        prepare_variables(self.default_dao)
        url = "/platform/variable_models/variable/{}/{}".format(SAMPLE_VARIABLE.app, SAMPLE_VARIABLE.name)
        response = self.fetch(url, method='DELETE')
        res = json.loads(response.body)
        self.assertEqual(res['status'], 0)
        self.assertEqual(res['msg'], 'ok')
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(res['status'], 0)
Пример #6
0
    def test_get_variables(self):
        prepare_variables(self.cust_dao)

        # default 0, cust 3
        url = "/default/variable_models"
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(self.default_dao.count(), 0)
        self.assertEqual(res['status'], 0)
        self.assertEqual(res['msg'], 'ok')
        self.assertEqual(len(res['values']), 0)

        url = '/platform/variable_models'
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(self.cust_dao.count(), 4)
        self.assertEqual(res['status'], 0)
        self.assertEqual(res['msg'], 'ok')
        self.assertEqual(len(res['values']), 4)
        return_variables = res['values']
        return_variable = [_ for _ in return_variables if _['name'] == SAMPLE_VARIABLE.name][0]
        self.assertEqual(VariableModel.from_dict(return_variable), SAMPLE_VARIABLE)

        # check get by app
        response = self.fetch(url + '?app=new_app')
        res = json.loads(response.body)
        self.assertEqual(len(res['values']), 1)

        # check get by type
        response = self.fetch(url + '?type=new_type')
        res = json.loads(response.body)
        self.assertEqual(len(res['values']), 1)
Пример #7
0
def gen_ip_trigger_variable_from_strategy(strategy,
                                          trigger_variable_name,
                                          is_delay=False):
    """
    产生ip维度的trigger变量
    new mode

    :return:
    """

    if not strategy:
        return

    conditions = []
    trigger_event = get_trigger_event(strategy, is_delay)

    for t in strategy.terms:
        left = t.left
        if left.type == 'event':
            c = gen_filter_from_event_exp(left, t.op, t.right)
            if c:
                conditions.append(c)

    # location condition has lower priority
    for t in strategy.terms:
        left = t.left
        if left.type == 'func' and left.subtype == 'getlocation':
            c = gen_filter_from_location_exp(left, trigger_event)
            if c:
                conditions.append(c)

    total_filter = {}
    if is_delay:
        total_filter = gen_ordinary_filter(trigger_event[1], 'delay_strategy',
                                           '==', strategy.name).get_dict()
    else:
        if conditions:
            conditions = [_.get_dict() for _ in conditions]
            total_filter = Filter('', '', '', '', '', '', 'and', '',
                                  conditions).get_dict()
    remark = 'ip trigger for strategy {}'.format(utf8(strategy.name))
    variable = VariableModel('realtime', 'nebula', trigger_variable_name,
                             remark, remark, '', 'enable', 'filter', '', '',
                             '', [{
                                 'app': trigger_event[0],
                                 'name': trigger_event[1]
                             }], total_filter, {}, {}, ['c_ip'])
    add_variable_to_registry(variable)

    return variable
Пример #8
0
    def test_get_variable(self):
        prepare_variables(self.variable_dao)
        url = "/default/variable_models/variable/{}/{}".format(SAMPLE_VARIABLE.app, SAMPLE_VARIABLE.name)
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(res['status'], 0)
        self.assertEqual(res['msg'], 'ok')
        self.assertEqual(len(res['values']), 1)
        self.assertEqual(VariableModel.from_dict(res['values'][0]), SAMPLE_VARIABLE)

        # get not exist
        url = "/default/variable_models/variable/{}/{}".format(SAMPLE_VARIABLE.app, 'not_exist')
        response = self.fetch(url)
        res = json.loads(response.body)
        self.assertEqual(res['status'], 404)
Пример #9
0
def gen_dimension_trigger_variable_from_strategy(strategy,
                                                 trigger_variable_name,
                                                 dimension,
                                                 is_delay=False):
    """
    产生uid/did维度的trigger变量
    new mode

    :return:
    """

    trigger_event = get_trigger_event(strategy, is_delay)

    # mappings, getvariable和count的触发字段必须包含在trigger event,这样在collect variable才能获取
    dimension_count = 0
    for t in strategy.terms:
        left = t.left

        # only care realtime vars
        if t.scope != 'realtime':
            continue

        # only dimension related
        if left.subtype in {'getvariable', 'count'}:
            if get_dimension_from_trigger_keys(
                    left.trigger_fields) != dimension:
                continue
            else:
                dimension_count += 1

    if not dimension_count:
        return None

    dimension_field = get_field_from_dimension(dimension)
    filter_dict = gen_ordinary_filter(trigger_event[1], dimension_field, '!=',
                                      '').get_dict()

    remark = '{} trigger for strategy {}'.format(dimension,
                                                 utf8(strategy.name))
    variable = VariableModel('realtime', 'nebula', trigger_variable_name,
                             remark, remark, '', 'enable', 'filter', '', '',
                             '', [{
                                 'app': trigger_event[0],
                                 'name': trigger_event[1]
                             }], filter_dict, {}, {}, [dimension_field])
    add_variable_to_registry(variable)
    return variable
Пример #10
0
    def post(self, app, name):
        """
        增加/修改一个变量

        @API
        summary: 增加/修改一个变量
        notes: 增加/修改一个变量
        tags:
          - platform
        parameters:
          -
            name: app
            in: path
            required: true
            type: string
            description: 变量的app
          -
            name: name
            in: path
            required: true
            type: string
            description: 变量的名称
          -
            name: variable
            in: body
            required: true
            type: json
            description: 变量的json表示
        produces:
          - application/json
        """

        self.set_header('content-type', 'application/json')
        body = self.request.body
        try:
            new_model = VariableModel.from_json(body)
        except Exception as err:
            return self.process_error(400, str(err))

        try:
            VariableModelCustDao().add_model(new_model)
            self.finish(json_dumps({"status": 0, "msg": "ok", "values": []}))
        except Exception as err:
            logger.error(err)
            self.process_error(500, str(err))
Пример #11
0
 def to_variablemodel(self):
     try:
         result = VariableModel(self.module, self.app, self.name,
                                self.remark, self.visible_name,
                                self.dimension, self.status, self.type,
                                self.value_type,
                                self.value_subtype, self.value_category,
                                json.loads(self.source),
                                json.loads(self.filter),
                                json.loads(self.period),
                                json.loads(self.function),
                                json.loads(self.groupbykeys),
                                json.loads(self.hint))
         add_variable_to_registry(result)
         return result
     except Exception as err:
         logger.error('variable model default error...')
         return None
Пример #12
0
def gen_counter_from_interval_count_exp(count_exp, counter_name):
    """ 为interval生成新的counter.

    新模式

    :param count_exp:
    :param counter_name:
    :return:
    """

    # 统计的事件
    source_event_id = count_exp.source_event
    counter_function = Function('last', '', 'timestamp', '', '', '')

    sub_filters = []
    for c in count_exp.condition:
        left = c['left']
        op = c['op']
        right = c['right']
        if op == '=':
            # 等于变量,在counter fix的时候被自动修正
            continue

        sub_filters.append(
            gen_ordinary_filter(source_event_id[1], left, op,
                                right).get_dict())

    counter_filter = Filter('', '', '', '', '', '', 'and', '', sub_filters)

    remark = 'first temp variable from interval counter'

    counter_variable = VariableModel('realtime', 'nebula', counter_name,
                                     remark, remark, '', 'enable', 'aggregate',
                                     '', '', '', [{
                                         'app': source_event_id[0],
                                         'name': source_event_id[1]
                                     }], counter_filter.get_dict(), {
                                         'type': 'ever',
                                         'value': ''
                                     }, counter_function.get_dict(),
                                     count_exp.groupby)
    add_variable_to_registry(counter_variable)
    return counter_variable
Пример #13
0
    def post(self):
        """
        增加一组变量

        @API
        summary: 增加一组变量
        notes: 增加一组变量,如果变量已存在,则修改
        tags:
          - platform
        parameters:
          -
            name: variables
            in: body
            required: true
            type: json
            description: 变量的json表示,list结构
        produces:
          - application/json   
        """

        self.set_header('content-type', 'application/json')
        body = self.request.body
        try:
            variables = list()
            for _ in json.loads(body):
                v = VariableModel.from_dict(_)
                add_variable_to_registry(v)
                variables.append(v)
        except Exception as err:
            print_exc()
            return self.process_error(400, str(err))

        try:
            dao = VariableModelCustDao()
            for v in variables:
                dao.add_model(v)
            self.finish(json_dumps({"status": 0, "msg": "ok", "values": []}))
        except Exception as err:
            print_exc()
            return self.process_error(500, str(err))
Пример #14
0
    def sync_to_base_events(self, body):
        """
        第二步:新增基础事件到基础事件记录表
        参数:依赖/platform/event_models中post的参数
        :param body:
        :return:
        """
        try:
            events = list()
            base_event = dict()
            for _ in json.loads(body):
                # 自动设置一些默认值,无需前端重复传递
                base_event["status"] = "enable"
                base_event["type"] = "event"
                base_event["source"] = [{
                    "app": _.get("app"),
                    "name": _.get("name")
                }]

                # 获取body中我们需要的值
                base_event["app"] = _.get("app")
                base_event["name"] = _.get("name")
                base_event["visible_name"] = _.get("visible_name")
                base_event["remark"] = _.get("remark")
                base_event["module"] = _.get("type")
                event = VariableModel.from_dict(base_event)
                events.append(event)
        except:
            logger.error(traceback.format_exc())
            return False
        try:
            dao = VariableModelCustDao()
            for event in events:
                dao.add_model(event)
            return True
        except:
            logger.error(traceback.format_exc())
            return False
Пример #15
0
def gen_counters_and_filters_from_count_exp(term, termid, name_pattern,
                                            trigger_variable_name):
    """
    从count函数配置中生成新的counter.

    返回: (all counters, collect counter, filters),这里有三块内容
    all counters: 所有生成的counter, 包括用来参与策略计算的counter和中间counter
    collect counter:最终参与策略计算的counter,这一个list就去掉了一些中间counter
    fitlers:collect counters关联的filters

    """

    # 统计的事件
    count_exp = term.left
    source_event_id = count_exp.source_event

    sub_filters = []
    for c in count_exp.condition:
        left = c['left']
        op = c['op']
        right = c['right']
        if op == '=':
            # 等于变量,在counter fix的时候被自动修正
            continue

        sub_filters.append(
            gen_ordinary_filter(source_event_id[1], left, op,
                                right).get_dict())

    # distinct string should be non empty
    if 'distinct' in count_exp.algorithm:
        for field in count_exp.operand:
            # noinspection PyBroadException
            try:
                sub_filters.append(
                    gen_ordinary_filter(source_event_id[1], field, '!=',
                                        '').get_dict())
            except:
                pass

    counter_filter = Filter('', '', '', '', '', '', 'and', '', sub_filters)

    if 'interval' == count_exp.algorithm:
        first_counter_name = name_pattern % '_1_'
        remark = 'interval 1st counter variable(last counter event) for term %s' % termid
        first_counter_function = Function('last', '', 'timestamp', '', '')
        first_variable = VariableModel('realtime', 'nebula',
                                       first_counter_name, remark, remark, '',
                                       'enable', 'aggregate', '', '', '',
                                       [{
                                           'app': source_event_id[0],
                                           'name': source_event_id[1]
                                       }], counter_filter.get_dict(), {
                                           'type': 'last_n_seconds',
                                           'value': count_exp.interval
                                       }, first_counter_function.get_dict(),
                                       count_exp.groupby)
        add_variable_to_registry(first_variable)

        second_counter_name = name_pattern % '_2_'
        remark = 'interval 2nd counter variable(last trigger event) for term %s' % termid
        second_source = [
            {
                'app': 'nebula',
                'name': trigger_variable_name
            },
        ]
        second_counter_function = Function('last', '', 'timestamp', '', '')
        second_variable = VariableModel('realtime', 'nebula',
                                        second_counter_name, remark, remark,
                                        '', 'enable', 'aggregate', '', '', '',
                                        second_source, {}, {
                                            'type': 'last_n_seconds',
                                            'value': count_exp.interval
                                        }, second_counter_function.get_dict(),
                                        count_exp.groupby)
        add_variable_to_registry(second_variable)

        third_counter_name = name_pattern % '_3_'
        remark = 'interval 3rd dual variable(-value) for term %s' % termid
        third_source = [
            {
                'app': 'nebula',
                'name': second_counter_name
            },
            {
                'app': 'nebula',
                'name': first_counter_name
            },
        ]
        third_counter_function = Function('-', '', 'value', '', '')
        third_variable = VariableModel('realtime', 'nebula',
                                       third_counter_name, remark, remark, '',
                                       'enable', 'dual', '', '', '',
                                       third_source, {}, {
                                           'type': 'last_n_seconds',
                                           'value': count_exp.interval
                                       }, third_counter_function.get_dict(),
                                       count_exp.groupby)
        add_variable_to_registry(third_variable)
        f = gen_ordinary_filter(third_counter_name, 'value', term.op,
                                term.right.value)
        additional_f = gen_ordinary_filter(third_counter_name, 'value', '>',
                                           '0')
        return [first_variable, second_variable,
                third_variable], third_variable, [f, additional_f]
    else:
        counter_function = gen_function(count_exp.algorithm,
                                        count_exp.operand[0])
        counter_name = name_pattern % ''
        remark = 'temp counter for term %s' % termid
        counter_variable = VariableModel('realtime', 'nebula', counter_name,
                                         remark, remark, '', 'enable',
                                         'aggregate', '', '', '',
                                         [{
                                             'app': source_event_id[0],
                                             'name': source_event_id[1]
                                         }], counter_filter.get_dict(), {
                                             'type': 'last_n_seconds',
                                             'value': count_exp.interval
                                         }, counter_function.get_dict(),
                                         count_exp.groupby)
        add_variable_to_registry(counter_variable)
        f = gen_ordinary_filter(counter_name, 'value', term.op,
                                term.right.value)
        return [counter_variable], counter_variable, [f]
Пример #16
0
def gen_dimension_collector_variable_from_strategy(s,
                                                   collect_variable_name,
                                                   trigger_variable_name,
                                                   dimension,
                                                   before_sleep=True,
                                                   is_delay=False):
    """
    为IP/UID/DID产生collector变量
    :param s: 策略
    :param collect_variable_name: collector变量
    :param trigger_variable_name: trigger变量
    :param dimension: 维度,ip/uid/did
    :param before_sleep: 是否找sleep之前的条款
    :param is_delay: 是否生成delaycollector
    :return: 产生该维度的变量
    """

    sources = list()
    sources.append({'app': 'nebula', 'name': trigger_variable_name})

    variables, variables_conditions = gen_getvariables_filters_from_strategy(
        s, dimension, before_sleep)
    for v in variables:
        sources.append({'app': v[0], 'name': v[1]})

    counters, collect_counters, counter_conditions = gen_counters_and_filters_from_strategy(
        s, dimension, before_sleep, trigger_variable_name)
    for counter in collect_counters:
        sources.append({'app': 'nebula', 'name': counter.name})

    conditions = (variables_conditions or list()) + (counter_conditions
                                                     or list())

    remark = 'collector for strategy {}'.format(utf8(s.name))
    total_filter = {}
    if conditions:
        conditions = [_.get_dict() for _ in conditions]
        total_filter = Filter('', '', '', '', '', '', 'and', '',
                              conditions).get_dict()

    dimension_field = get_field_from_dimension(dimension)
    if is_delay:
        variable_type = 'delaycollector'
    else:
        variable_type = 'collector'

    collector_function = {
        'method': 'setblacklist',
        'param': s.name,
        'config': {
            'trigger': trigger_variable_name
        }
    }
    if is_delay:
        sleep_terms = [_ for _ in s.terms if _.left.subtype == 'sleep']
        if not sleep_terms:
            raise RuntimeError('sleep配置出错')
        duration = int(sleep_terms[0].left.duration)
        unit = sleep_terms[0].left.unit
        if unit == 'm':
            duration *= 60
        elif unit == 'h':
            duration *= 3600
        collector_function['config']['sleep'] = duration

    variable = VariableModel('realtime', 'nebula', collect_variable_name,
                             remark, remark, '', 'enable', variable_type, '',
                             '', '', sources, total_filter, {},
                             collector_function, [dimension_field])
    add_variable_to_registry(variable)
    return counters, variable
Пример #17
0
    SAMPLE_EVENTS = json.load(json_file)
    new_events = list()
    for _ in SAMPLE_EVENTS:
        new_event = EventModel.from_dict(_)
        add_event_to_registry(new_event)
        new_events.append(new_event)

    SAMPLE_EVENTS = new_events
    SAMPLE_EVENT = SAMPLE_EVENTS[0]


with open('nebula/tests/data/variable_model.json') as json_file:
    SAMPLE_VARIABLES = json.load(json_file)
    new_variables = list()
    for _ in SAMPLE_VARIABLES:
        new_variable = VariableModel.from_dict(_)
        add_variable_to_registry(new_variable)
        new_variables.append(new_variable)
    SAMPLE_VARIABLES = new_variables
    SAMPLE_VARIABLE = SAMPLE_VARIABLES[-1]  # did变量


def prepare_events(event_dao):
    for _ in SAMPLE_EVENTS:
        event_dao.add_model(_)


def prepare_variables(variable_dao):
    variable_dao.add_model(SAMPLE_VARIABLES[0])
    variable_dao.add_model(SAMPLE_VARIABLES[1])