Exemple #1
0
def modify_user_limits():
    uid, err = get_oemid(request=request)
    if err is not None:
        return jsonify(UNAUTH_RESULT)

    is_admin = True if request.headers.get('admin') == 'true' else False

    if not is_admin:
        return jsonify({
            'statis': 'fail',
            'message': 'Only administrator can access this.'
        })

    check_json(request)
    username = get_json(request).get('username')
    limit_type_id = get_json(request).get('limit_type_id')
    max_limits = get_json(request).get('max_limit')
    max_second = get_json(request).get('max_seconds')

    if not max_limits:
        return jsonify({
            'status': 'fail',
            'message': 'The "max_limits" cannot be empty.'
        })

    is_user_exist, user_id = user_exist(request.cursor, username)
    if not is_user_exist:
        return jsonify({
            'status': 'fail',
            'message': 'Incorrect username, user not exist'
        })

    limit_type = query_limit_type(request.cursor, limit_type_id)

    if limit_type.default_max_sec is None:
        if max_second:
            return jsonify({
                'status':
                'fail',
                'message':
                'Max seconds must be empty for this limit type.'
            })
        else:
            max_second = None
    else:
        if not max_second:
            return jsonify({
                'status':
                'fail',
                'message':
                'Max seconds cannot be empty for this limit type.'
            })

    try:
        request.cursor.execute(
            update_user_limit_sql,
            (max_limits, max_second, user_id, limit_type_id))
        request.conn.commit()
    except Exception:
        raise DCCAException('Fail to update limit data')

    return jsonify({
        'status': 'success',
        'message': 'Success to update the max limit data for user'
    })
Exemple #2
0
def query_models():
    uid, err = get_oemid(request=request)
    if err is not None:
        return jsonify(UNAUTH_RESULT)

    my_model = request.args.get('my_model') or ""
    limit = request.args.get('limit') or 20
    offset = request.args.get('offset') or 0

    model = request.args.get('model')
    _type = request.args.get('type')
    platform = request.args.get('platform')
    vendor = request.args.get('vendor')

    public_model = "  is_public IS TRUE"
    all_my_model = " owner_id={uid}"
    no_filt_model = " (is_public IS TRUE OR owner_id={uid})"
    split_page = " ORDER BY id DESC LIMIT {limit} OFFSET {offset};".format(limit=limit, offset=offset)

    filt = ""
    if model:
        filt = " AND model = '{}'".format(model)
    if _type:
        if filt:
            filt = filt + " AND type = '{}'".format(_type)
        else:
            filt = " AND type = '{}'".format(_type)
    if platform:
        if filt:
            filt = filt + " AND platform = '{}'".format(platform)
        else:
            filt = " AND platform = '{}'".format(platform)
    if vendor:
        if filt:
            filt = filt + " AND vendor = '{}'".format(vendor)
        else:
            filt = " AND vendor = '{}'".format(vendor)

    if not my_model:
        query_models_cmd = query_models_sql + no_filt_model.format(uid=uid) + filt + split_page
        query_total_models_cmd = query_total_models_sql + no_filt_model.format(uid=uid) + filt
    elif my_model == 'false':
        query_models_cmd = query_models_sql + public_model + filt + split_page
        query_total_models_cmd = query_total_models_sql + public_model + filt
    else:
        query_models_cmd = query_models_sql + all_my_model.format(uid=uid) + filt + split_page
        query_total_models_cmd = query_total_models_sql + all_my_model.format(uid=uid) + filt
    request.cursor.execute(query_models_cmd)
    models = request.cursor.fetchall()

    request.cursor.execute(query_total_models_cmd)
    total = request.cursor.fetchone()[0]

    results = OrderedDict()
    results['total'] = total
    results['limit'] = limit
    results['offset'] = offset

    results['models'] = []
    for model in models:
        model = ModelInfo._make(model)._asdict()
        if model['owner_id'] == int(uid):
            model['is_owner'] = True
        else:
            model['is_owner'] = False
        del model['owner_id']
        results['models'].append(model)

    return jsonify(results)
def create_task():
    """
    Create a task with payload
    """
    uid, err = get_oemid(request=request)
    if err is not None:
        return jsonify(UNAUTH_RESULT)

    ctx.current_user = DccaUser.get_by_id(uid)

    check_json(request)
    task_info = get_json(request).get("task", {})
    device_ids = task_info.get('device_ids')
    task_type = task_info.get('type')
    payloads = task_info.get('payload')

    devices = Host.query_in(device_ids)
    if len(devices) != len(device_ids):
        return jsonify({
            'status':
            'fail',
            'message':
            'Not authorized devices exist. Device not exist or cannot access',
            'not_authorized_devices':
            list(set(device_ids) - set([d.id for d in devices]))
        })

    try:
        inst_list = []
        if task_type == TASK_TYPE_NAMES[TASK_TYPE_APP]:
            unauthoried = EsTask.check_da_payload(payloads)
            if unauthoried:
                return jsonify({
                    'status': 'fail',
                    'message':
                    'Unauthorized application exists, not exist or cannot access. Do you have "version" in payload?',
                    'unauthorized': unauthoried
                })

            task = EsTask.create_da_task(payloads)
            task.started_at = datetime.utcnow()
            session.add(task)
            session.flush()
            for pl in payloads:
                softapp = DccaSoftapp.get(pl['softapp_id'])
                del pl['softapp_id']
                for device in devices:
                    inst = task.da_inst(device, softapp, pl)
                    session.add(inst)
                    inst_list.append(inst)

        elif task_type == TASK_TYPE_NAMES[TASK_TYPE_SOLUTION]:
            authed, solution = EsTask.check_ota_payload(payloads)
            if not authed:
                return jsonify({
                    'status':
                    'fail',
                    'message':
                    'Solution not exist or cannot access.'
                })

            task = EsTask.create_ota_task(payloads)
            task.started_at = datetime.utcnow()
            session.add(task)
            session.flush()
            for device in devices:
                inst = task.ota_inst(device, solution)
                session.add(inst)
                inst_list.append(inst)
        else:
            if not payloads:
                return jsonify({
                    'status': 'fail',
                    'message': 'payload is null.'
                })
            if not isinstance(payloads, dict):
                return jsonify({
                    'status': 'fail',
                    'message': 'payload is not dict.'
                })

            p = payloads.copy()
            p['device_ids'] = device_ids

            task = EsTask.create_common_task(TASK_TYPE_COMMON, p)
            task.started_at = datetime.utcnow()
            session.add(task)
            session.flush()
            for device in devices:
                inst = task.common_inst(device, payloads)
                session.add(inst)
                inst_list.append(inst)

            session.commit()

            data = []
            for inst in inst_list:
                data.append(
                    dict(
                        {
                            'mid': inst.id,
                            'device': inst.device.name,
                            'issync': True,
                        }, **payloads))
            params = None

            deploy_url = RESOURCE_POST_TASK.format(dns=APPSERVER_HOST,
                                                   port=APPSERVER_PORT,
                                                   uid=uid)
            task.start(deploy_url, params, data=json.dumps(data))
        session.commit()

        for inst in inst_list:
            if inst.task.type == TASK_TYPE_APP:
                print('Start da task')
                try:
                    inst.start(APPSERVER_HOST, APPSERVER_PORT)
                    session.add(inst)
                except Exception:
                    session.rollback()
                else:
                    session.commit()
            elif inst.task.type == TASK_TYPE_SOLUTION:
                print('Start ota task')
                try:
                    inst.start(MQTT_HOST)
                    session.add(inst)
                except Exception:
                    session.rollback()
                else:
                    session.commit()

        results = OrderedDict()
        results['status'] = 'success'
        results['message'] = 'Success to create the task'
        results['task'] = task.as_dict(schema=TaskSchema)
        return jsonify(results)
    except Exception as e:
        raise DCCAException(str(e))
def create_solution_view():
    uid, err = get_oemid(request=request)
    if err is not None:
        return jsonify(UNAUTH_RESULT)

    ctx.current_user = DccaUser.get_by_id(uid)

    check_json(request)
    solution_name = get_json(request).get('solution')
    model_id = get_json(request).get('model_id')
    version = get_json(request).get('version')
    image = get_json(request).get('image')
    url = get_json(request).get('url')
    is_signed = bool_helper(get_json(request).get('is_signed'))
    is_default = bool_helper(get_json(request).get('is_default'))
    have_installer = bool_helper(get_json(request).get('have_installer'))

    exceed_flag, max_limit_size = DccaAssSolutionImage.check_solution_limit()
    if exceed_flag:
        return jsonify({
            'status':
            'fail',
            'message':
            'Up to max limit({}) you can create.'.format(max_limit_size)
        })

    if url:
        in_s3 = False
        image = url.split('/')[-1]
        if not image:
            return jsonify({'status': 'fail', 'message': 'Bad URL format'})
    else:
        in_s3 = True
        s3_url = STORAGE_PREFIX + BUCKET
        url = '/'.join([
            s3_url, ctx.current_user.username, solution_name,
            str(model_id),
            image.split('.')[0], version, image
        ])

    if is_default:
        if not DccaModel.check_model_owner(model_id):
            return jsonify({
                'status': 'fail',
                'message': 'Not the model owner, cannot set default'
            })

        if DccaModel.check_model_permission(model_id):
            return jsonify({
                'status':
                "fail",
                'message':
                "Can't set private solution as default solution of public model"
            })

    solution = DccaAssSolutionImage(solution_name, model_id, image, version,
                                    url, uid, in_s3, is_signed, have_installer)
    try:
        session.add(solution)
        session.commit()
    except Exception as e:
        err_msg = "Fail to create solution. {}".format(str(e))
        raise DCCAException(err_msg)

    solution_id = solution.id
    if is_default:
        solution.model.default_solution_id = solution_id
        try:
            session.commit()
        except Exception as e:
            err_msg = "Fail to set default solution. {}".format(str(e))
            raise DCCAException(err_msg)

    return jsonify({
        'id': solution_id,
        'status': 'success',
        'message': 'Success to create solution'
    })
def query_all_tasks():
    """
    Query tasks of all
    """
    uid, err = get_oemid(request=request)
    if err is not None:
        return jsonify(UNAUTH_RESULT)

    ctx.current_user = DccaUser.get_by_id(uid)

    limit = request.args.get('limit') if request.args.get('limit') else 20
    offset = request.args.get('offset') if request.args.get('offset') else 0
    status = request.args.get('status')
    order_by = request.args.get('order_by') if request.args.get(
        'order_by') else 'created_at'
    device_id = request.args.get('device_id')
    reverse = request.args.get('reverse')
    if reverse == "true":
        reverse = True
    elif reverse == "false":
        reverse = False
    else:
        reverse = True

    if order_by not in ['id', 'created_at']:
        return jsonify({
            'status': 'fail',
            'message': 'Invalid value of "order_by"'
        })

    if order_by not in ['id', 'created_at']:
        return jsonify({
            'status': 'fail',
            'message': 'Invalid value of "order_by"'
        })

    if status:
        status = status.lower().capitalize()
        if status not in TASK_STATUS_FILTER:
            return jsonify({
                'status':
                'fail',
                'message':
                "Invalid status value, should be one of \"{0}\"".format(
                    ', '.join(map(str, list(TASK_STATUS_FILTER.keys()))))
            })

        _status = TASK_STATUS_FILTER[status]
    else:
        _status = None

    tasks, total = EsTask.query_all(
        status=_status,
        device_id=device_id,
        order_by=order_by,
        reverse=reverse,
        limit=limit,
        offset=offset,
    )

    results = OrderedDict()
    results['limit'] = limit
    results['offset'] = offset
    results['total'] = total
    results['items'] = []
    for task in tasks:
        results['items'].append(task.as_dict(schema=TaskSchema))

    return jsonify(results)
def delete_registry():
    uid, err = get_oemid(request=request)
    if err is not None:
        return jsonify(UNAUTH_RESULT)

    check_json(request)
    registry_ids = get_json(request).get("ids")
    is_admin = True if request.headers.get('admin') == 'true' else False

    if not registry_ids:
        return jsonify({
            'status': 'fail',
            'message': 'The "registry_ids" can not be empty'
        })

    registry_ids = ",".join(str(r) for r in registry_ids)

    query_registry_cmd = query_registry_sql.format(registry_ids=registry_ids)
    request.cursor.execute(query_registry_cmd)
    registries = request.cursor.fetchall()
    if not registries:
        return jsonify({'status': 'fail', 'message': 'Registries not exist'})

    id_list = []
    for registry in registries:
        registry = RegistryFull._make(registry)
        if registry.owner_id != int(uid) and not registry.public:
            return jsonify({
                'status': 'fail',
                'message': 'Not authorized to this registry'
            })

        if registry.public and not is_admin:
            # TODO We should allow not only administrator but also authorized user to delete registry
            return jsonify({
                'status':
                'fail',
                'message':
                'Only administrator can delete public registry'
            })
        id_list.append(str(registry.id))
    ids = ",".join(id_list)
    remove_registry_cmd = remove_registry_sql.format(registry_ids=ids)
    remove_softapp_cmd = remove_softapp_sql.format(mirror_ids=ids)
    query_softapps_cmd = query_softapps_sql.format(mirror_ids=ids)
    request.cursor.execute(query_softapps_cmd)
    soft_app_ids = request.cursor.fetchall()

    try:
        for sid in soft_app_ids:
            remove_da_inst_cmd = remove_da_inst_sql.format(softapp_id=sid[0])
            request.cursor.execute(remove_da_inst_cmd)
        request.cursor.execute(remove_softapp_cmd)
        request.cursor.execute(remove_registry_cmd)
        request.conn.commit()
    except Exception:
        raise DCCAException('Fail to remove registries')

    return jsonify({
        'status': 'success',
        'message': 'Success to remove registries'
    })
def query_audit_view():
    uid, err = get_oemid(request=request)
    if err is not None:
        return jsonify(UNAUTH_RESULT)

    limit = request.args.get('limit') or 20
    offset = request.args.get('offset') or 0
    filter_text = request.args.get('filter_text') or ''
    filter_type = request.args.get('filter_type') or ''
    order_by = request.args.get('orderBy') or 'created_at'
    order_type = request.args.get('orderType') or 'desc'

    is_admin = True if request.headers.get('admin', False) == 'true' else False
    if not is_admin:
        return jsonify({
            'status':
            'fail',
            'message':
            'Unauthorized, administrator is assumed to access this.'
        })

    if order_type not in ['asc', 'desc']:
        return jsonify({'status': "fail", 'message': "Invalid order type"})

    if order_by not in ['created_at', 'status', '']:
        return jsonify({'status': "fail", 'message': "Invalid orderBy value"})

    try:
        split = "ORDER BY {order_by} {order_type} LIMIT {limit} OFFSET {offset};"
        if filter_text:
            if filter_type:
                query_audit_sql = query_audit + "WHERE username LIKE '%{filter_text}%' " \
                                                "AND approve_type='{filter_type}' " + split
                query_total_audit_sql = query_total_audit + "WHERE username LIKE '%{filter_text}%' " \
                                                            "AND approve_type='{filter_type}';"
            else:
                query_audit_sql = query_audit + "WHERE username LIKE '%{filter_text}%' " + split
                query_total_audit_sql = query_total_audit + "WHERE username LIKE '%{filter_text}%';"
        else:
            if filter_type:
                query_audit_sql = query_audit + "WHERE approve_type='{filter_type}' " + split
                query_total_audit_sql = query_total_audit + "WHERE approve_type='{filter_type}';"
            else:
                query_audit_sql = query_audit + split
                query_total_audit_sql = query_total_audit

        request.cursor.execute(
            query_audit_sql.format(filter_text=filter_text,
                                   filter_type=filter_type,
                                   order_by=order_by,
                                   order_type=order_type,
                                   limit=limit,
                                   offset=offset))
        audits = request.cursor.fetchall()
        request.cursor.execute(
            query_total_audit_sql.format(filter_text=filter_text,
                                         filter_type=filter_type))
        total = request.cursor.fetchone()[0]

        results = OrderedDict()
        results['orderType'] = order_type
        results['orderBy'] = order_by
        results['offset'] = offset
        results['limit'] = limit
        results['total'] = total
        results['results'] = []

        for a in audits:
            a = Audits._make(a)
            a = a._asdict()
            a["created_at"] = str(a["created_at"])
            results['results'].append(a)

    except Exception as e:
        return jsonify({"status": "fail", "error": str(e)})

    return jsonify(results)
Exemple #8
0
def create_service_view():
    uid, err = get_oemid(request=request)
    if err is not None:
        return jsonify(UNAUTH_RESULT)

    name = get_json(request).get('name')
    model_id = get_json(request).get('model_id')

    cloudConfig = get_json(request).get("cloudConfig", {})
    protocal = cloudConfig.get('protocal')
    cipher_suite = cloudConfig.get('cipherSuite')

    serverCertificate = cloudConfig.get('serverCertificate', {})
    server_certificate_format = serverCertificate.get('format')
    server_certificate_key = serverCertificate.get('key')

    connection_url = cloudConfig.get('connectionUrl', {}).get("url")
    config = cloudConfig.get('config')

    signingCertificate = get_json(request).get("signingCertificate", {})
    signing_certificate_format = signingCertificate.get('format')
    signing_certificate_key = signingCertificate.get('key')

    result = create_param_validate(
        cursor=request.cursor,
        name=name,
        protocal=protocal,
        cipher_suite=cipher_suite,
        connection_url=connection_url,
        config=config,
        server_certificate_format=server_certificate_format,
        server_certificate_key=server_certificate_key,
        signing_certificate_format=signing_certificate_format,
        signing_certificate_key=signing_certificate_key,
        model_id=model_id,
        uid=uid)

    if result['status'] == 'Invalid':
        return jsonify(result)

    try:
        request.cursor.execute(
            create_service_sql,
            (name, protocal, cipher_suite, server_certificate_format,
             server_certificate_key, connection_url, config,
             signing_certificate_format, signing_certificate_key, uid))
    except Exception:
        if IS_DEBUG:
            import traceback
            traceback.print_exc()
        raise DCCAException('Exception to create service')

    service_id = request.cursor.fetchone()[0]
    service_uid = uuid.uuid5(uuid.NAMESPACE_DNS, str(service_id)).hex

    try:
        request.cursor.execute(update_service_uid_sql,
                               (service_uid, service_id))
    except Exception:
        raise DCCAException('Exception to update service uid')

    try:
        request.cursor.execute(create_service_model_map_sql,
                               (model_id, service_id))
        request.conn.commit()
    except Exception:
        raise DCCAException('Exception to bind service to model')

    return jsonify({
        'status': 'success',
        'message': 'Success to create service',
        'id': service_uid
    })
Exemple #9
0
def update_specific_service(service_id):
    uid, err = get_oemid(request=request)
    if err is not None:
        return jsonify(UNAUTH_RESULT)

    name = get_json(request).get('name')
    cloudConfig = get_json(request).get("cloudConfig", {})
    protocal = cloudConfig.get('protocal')
    cipher_suite = cloudConfig.get('cipherSuite')

    serverCertificate = cloudConfig.get("serverCertificate", {})
    server_certificate_format = serverCertificate.get('format')
    server_certificate_key = serverCertificate.get('key')

    connection_url = cloudConfig.get('connectionUrl')
    config = cloudConfig.get('config')

    signingCertificate = get_json(request).get("signingCertificate", {})
    signing_certificate_format = signingCertificate.get('format')
    signing_certificate_key = signingCertificate.get('key')

    result = update_param_validate(
        cursor=request.cursor,
        name=name,
        protocal=protocal,
        cipher_suite=cipher_suite,
        connection_url=connection_url,
        config=config,
        server_certificate_format=server_certificate_format,
        server_certificate_key=server_certificate_key,
        signing_certificate_format=signing_certificate_format,
        signing_certificate_key=signing_certificate_key)

    if result['status'] == 'Invalid':
        return jsonify(result)

    _variables = {}
    if name:
        _variables['name'] = name

    if protocal:
        _variables['protocal'] = protocal

    if cipher_suite:
        _variables['cipher_suite'] = cipher_suite

    if server_certificate_format:
        _variables['server_certificate_format'] = server_certificate_format

    if server_certificate_key:
        _variables['server_certificate_key'] = server_certificate_key

    if connection_url:
        _variables['connection_url'] = connection_url

    if config:
        _variables['config'] = config

    if signing_certificate_format:
        _variables['signing_certificate_format'] = signing_certificate_format

    if signing_certificate_key:
        _variables['signing_certificate_key'] = signing_certificate_key

    update_sql = 'UPDATE dcca_services SET '
    index = 0
    var_size = len(_variables)
    var_values = []
    for k, v in list(_variables.items()):
        update_sql += '{key}=%s'.format(key=k)
        if index != var_size - 1:
            update_sql += ', '
        var_values.append(v)
        index += 1

    update_sql += ' WHERE uid=%s ;'
    var_values.append(service_id)

    try:
        request.cursor.execute(update_sql, tuple(var_values))
        request.conn.commit()
    except Exception:
        raise DCCAException('Fail to update service')

    return jsonify({
        'status': 'success',
        'message': 'Success to update service'
    })