Exemple #1
0
async def adapt_cluster(request):
    user = request["user"]
    cluster_name = request.match_info["cluster_name"]
    backend = request.app["backend"]
    cluster = await backend.get_cluster(cluster_name)
    if cluster is None:
        raise web.HTTPNotFound(reason=f"Cluster {cluster_name} not found")
    if not user.has_permissions(cluster):
        raise web.HTTPForbidden(
            reason=
            f"User {user.name} lacks permissions to view cluster {cluster_name}"
        )

    msg = await request.json()
    minimum = msg.get("minimum", None)
    maximum = msg.get("maximum", None)
    active = msg.get("active", True)

    max_workers = cluster.config.get("cluster_max_workers")
    resp_msg = None
    if max_workers is not None:
        if maximum is None:
            maximum = max_workers
        if minimum is None:
            minimum = 0
        if maximum > max_workers or minimum > max_workers:
            orig_max = maximum
            orig_min = minimum
            maximum = min(max_workers, maximum)
            minimum = min(max_workers, minimum)
            resp_msg = (
                f"Adapt with `maximum={orig_max}, minimum={orig_min}` workers "
                f"would exceed resource limit of {max_workers} workers. Using "
                f"`maximum={maximum}, minimum={minimum}` instead.")

    try:
        await backend.forward_message_to_scheduler(
            cluster,
            {
                "op": "adapt",
                "minimum": minimum,
                "maximum": maximum,
                "active": active
            },
        )
    except PublicException as exc:
        raise web.HTTPConflict(reason=str(exc))

    return web.json_response({"ok": not resp_msg, "msg": resp_msg})
Exemple #2
0
 async def create(cls, identity, age=None):
     if await cls._exists(identity):
         # Anti brute force must be employed to disable this exploitation
         raise web.HTTPConflict(
             text='Identity conflicts, please try again!')
     if False:
         raise web.HTTPInsufficientStorage(
             text='Disk is full, please contact the admin! Thanks.')
     folder = Folder(identity, age)
     folder_key, msg_key = cls._keys(identity)
     # we might save a Folder object as a hashmap (i.e., a dict)
     # but all field values are strings
     # save as a json object is more convenient
     await redis.set(folder_key, folder.serialize())
     log.info('Create a new folder {}'.format(identity))
     return True
Exemple #3
0
async def upload_resource(request: web.Request) -> web.Response:
    """Upload resource chunk.

    Read resource metadata and save another chunk to the resource. If this is a final
    chunk, move resource to original file name and remove resource metadata.
    """
    # Ensure resource metadata is readable and resource file exists as well
    resource = get_resource_or_410(request)

    # Ensure resource offset equals to expected upload offset
    upload_offset = int(
        request.headers.get(constants.HEADER_UPLOAD_OFFSET) or 0)
    if upload_offset != resource.offset:
        raise web.HTTPConflict(headers=constants.BASE_HEADERS)

    # Save current chunk to the resource
    config = get_config(request)
    match_info = request.match_info
    resource.save(config=config,
                  match_info=match_info,
                  chunk=await request.read())

    # If this is a final chunk - complete upload
    chunk_size = int(request.headers.get(constants.HEADER_CONTENT_LENGTH) or 0)
    next_offset = resource.offset + chunk_size
    if next_offset == resource.file_size:
        file_path = resource.complete(config=config, match_info=match_info)
        await on_upload_done(request=request,
                             config=config,
                             resource=resource,
                             file_path=file_path)
    # But if it is not - store new metadata
    else:
        next_resource = attr.evolve(resource, offset=next_offset)
        next_resource.save_metadata(config=config, match_info=match_info)

    # Return upload headers
    return web.Response(
        status=204,
        headers={
            **constants.BASE_HEADERS,
            constants.HEADER_TUS_TEMP_FILENAME:
            resource.uid,
            constants.HEADER_UPLOAD_OFFSET:
            str(next_offset),
        },
    )
Exemple #4
0
    def IDputClasslist(self, data, request):
        """Accept classlist upload.

        Only "manager" can perform this action.

        The classlist should be provided as a ordered list of (str, str)
        pairs where each pair is (student ID, student name).

        Side effects on the server test spec file:
          * If numberToName and/or numberToProduce are -1, values are
            set based on this classlist (spec is permanently altered)/
          * If numberToName < 0 but numberToProduce is too small for the
            result, respond with HTTPNotAcceptable.

        Returns:
            aiohttp.web_response.Response: Success or failure.  Can be:
                200: success
                400: authentication problem.
                HTTPBadRequest: not manager, or malformed request.
                HTTPConflict: we already have a classlist.
                    TODO: would be nice to be able to "try again".
                HTTPNotAcceptable: classlist too short (see above).
        """
        if not data["user"] == "manager":
            raise web.HTTPBadRequest(reason="Not manager")
        if os.path.isfile(Path(specdir) / "classlist.csv"):
            raise web.HTTPConflict(reason="we already have a classlist")
        classlist = data["classlist"]
        # TODO should we make copy until sure it passes verification?
        spec = self.server.testSpec
        if spec.numberToName < 0 or spec.numberToProduce < 0:
            if spec.number_to_name < 0:
                spec.set_number_papers_to_name(len(classlist))
            if spec.number_to_produce < 0:
                spec.set_number_papers_add_spares(len(classlist))
            try:
                spec.verifySpec(verbose="log")
            except ValueError as e:
                raise web.HTTPNotAcceptable(reason=str(e))
            spec.saveVerifiedSpec()
        with open(Path(specdir) / "classlist.csv", "w") as csvfile:
            writer = csv.writer(csvfile)
            writer.writerow(["id", "studentName"])
            writer.writerows(classlist)
        return web.Response()
Exemple #5
0
async def delete_certificate(request):
    """ Delete a certificate

    :Example:
          curl -X DELETE http://localhost:8081/foglamp/certificate/foglamp
    """
    cert_name = request.match_info.get('name', None)

    certs_dir = _get_certs_dir()
    cert_file = certs_dir + '/{}.cert'.format(cert_name)
    key_file = certs_dir + '/{}.key'.format(cert_name)

    if not os.path.isfile(cert_file) and not os.path.isfile(key_file):
        raise web.HTTPNotFound(
            reason='Certificate with name {} does not exist'.format(cert_name))

    # read config
    # if cert_name is currently set for 'certificateName' in config for 'rest_api'
    cf_mgr = ConfigurationManager(connect.get_storage_async())
    result = await cf_mgr.get_category_item(category_name='rest_api',
                                            item_name='certificateName')
    if cert_name == result['value']:
        raise web.HTTPConflict(
            reason=
            'Certificate with name {} is already in use, you can not delete'.
            format(cert_name))

    msg = ''
    cert_file_found_and_removed = False
    if os.path.isfile(cert_file):
        os.remove(cert_file)
        msg = "{}.cert has been deleted successfully".format(cert_name)
        cert_file_found_and_removed = True

    key_file_found_and_removed = False
    if os.path.isfile(key_file):
        os.remove(key_file)
        msg = "{}.key has been deleted successfully".format(cert_name)
        key_file_found_and_removed = True

    if key_file_found_and_removed and cert_file_found_and_removed:
        msg = "{}.key, {}.cert have been deleted successfully".format(
            cert_name, cert_name)

    return web.json_response({'result': msg})
Exemple #6
0
    async def post(self):
        user = self.request.get("user")
        if user:
            data = await self.request.post()

            c = models.Chat()
            chat, err = c.Create(creator=user,
                                 name=data.get('name', ''),
                                 raw_members=data.getall('members', []))
            if err == None:
                response = await chat.to_json()
                return web.json_response(response, status=201)
            else:
                if err == exceptions.ChatWithMembersAlreadyExists:
                    return web.HTTPConflict()
                else:
                    return web.Response(text="422: %s" % str(err), status=422)
        return web.HTTPUnauthorized()
Exemple #7
0
    async def post(self) -> web.Response:
        LOG.info('Creating new user')
        try:
            new_user = user.User.parse_obj(await self.request.json())
            await user.save(
                db_pool=self.request.config_dict['db_pool'],
                name=new_user.name,
                password=new_user.password,
                role=new_user.role,
            )
        except pd.ValidationError:
            LOG.exception('Invalid new user request body')
            raise web.HTTPBadRequest(text='Invalid new user')
        except asyncpg.exceptions.UniqueViolationError:
            LOG.exception(f'Attempted to duplicate user {new_user.name}')
            raise web.HTTPConflict(text=f'User {new_user.name} already exists')

        return web.json_response(status=201, data=new_user.dict())
Exemple #8
0
 async def get(self: web.View) -> Response:
     await check_permission(self.request, Permissions.READ)
     source_id = int(self.request.match_info["id"])
     async with db.transaction():
         source = await Source.get(source_id)
     source_model = self.schema.from_orm(source)
     source_config = json.loads(source_model.config_json)
     table_fullname = source_config["table_name"]
     if not table_fullname:
         raise web.HTTPConflict(
             text="table_name not defined in source config")
     source_executor: AbstractSource = LIVE_SOURCES[source_model.typename]
     availability_intervals = await source_executor.list_availability_intervals(
         interval=3600, table_fullname=table_fullname)
     source_model.available_intervals = []
     for res in availability_intervals:
         source_model.available_intervals.append([res[0], res[1]])
     return web.json_response(body=source_model.json())
Exemple #9
0
 async def get(self: web.View) -> Response:
     await check_permission(self.request, Permissions.READ)
     source_id = int(self.request.match_info["id"])
     async with db.transaction():
         source = await Source.get(source_id)
     source_model = self.schema.from_orm(source)
     source_config = json.loads(source_model.config_json)
     table_fullname = source_config["table_name"]
     if not table_fullname:
         raise web.HTTPConflict(
             text="table_name not defined in source config")
     source_executor: AbstractSource = LIVE_SOURCES[source_model.typename]
     res = await source_executor.list_data_in_interval(
         table_fullname=table_fullname,
         start=self.request.query.get("start"),
         end=self.request.query.get("end"),
     )
     source_model.data = res
     return web.json_response(body=source_model.json())
def begin_job(jobdesc):
    global updater_process
    if updater_process is not None:
        if updater_process.poll() is not None:
            # Update complete
            updater_process = None
        else:
            error_body = {
                "error": "update_already_running",
                "pid": updater_process.pid
            }
            raise web.HTTPConflict(body=error_body)
    job_id = str(uuid.uuid1())
    (fwfd, fwfilepath) = mkstemp()
    if not os.path.exists(UPDATE_JOB_DIR):
        os.makedirs(UPDATE_JOB_DIR)
    statusfilepath = os.path.join(UPDATE_JOB_DIR, str(job_id) + ".json")
    status = {"pid": 0, "state": "fetching"}
    with open(statusfilepath, "wb") as sfh:
        sfh.write(json.dumps(status))
    try:
        fwdata = urllib.request.urlopen(jobdesc["fw_url"])
        with os.fdopen(fwfd, "wb") as fwfile:
            fwfile.write(fwdata.read())
            fwfile.flush()
    except:
        os.remove(statusfilepath)
        raise

    updater = UPDATERS[jobdesc.get("updater", "delta")]
    updater_process = Popen([
        updater,
        "--addr",
        str(jobdesc["address"]),
        "--statusfile",
        statusfilepath,
        "--rmfwfile",
        fwfilepath,
    ])
    status = {"pid": updater_process.pid, "state": "starting"}
    with open(statusfilepath, "wb") as sfh:
        sfh.write(json.dumps(status))
    return {"job_id": job_id, "pid": updater_process.pid}
async def create_user(request: web.Request, body) -> web.Response:
    user_table = get_model_by_name('user')
    login = body['login']
    exist = await request.app['pg'].fetchval(
        select([exists().where(user_table.c.login == login)]))

    if exist:
        return web.HTTPConflict(body=json.dumps(
            {'error': f'User with login "{login}" already exist'}),
                                content_type='application/json')

    data = await request.app['pg'].fetchrow(
        user_table.insert().values(**body).returning(literal_column('*')))
    body['user_id'] = data['user_id']
    del body['password']

    return web.Response(status=201,
                        content_type='application/json',
                        body=json.dumps(body))
Exemple #12
0
async def _update(session, **kwargs):
    if "downloadRateLimit" in kwargs:
        download_rate_limit = int(kwargs["downloadRateLimit"])
        session.set_download_rate_limit(download_rate_limit)
    if "uploadRateLimit" in kwargs:
        upload_rate_limit = int(kwargs["uploadRateLimit"])
        session.set_upload_rate_limit(upload_rate_limit)
    if "connectionsLimit" in kwargs:
        connections_limit = int(kwargs["connectionsLimit"])
        session.set_connections_limit(connections_limit)
    if "paused" in kwargs:
        paused = bool(kwargs["paused"])
        if paused and not session.paused:
            await session.pause()
        elif not paused and session.paused:
            await session.resume()
        else:
            raise web.HTTPConflict()
    return _to_dict(session)
Exemple #13
0
    async def post(self):
        # get the payload
        payload = await self.payload
        with suppress(AttributeError):
            # allow custom schema method to modify the payload before validation
            payload = await self.schema.procure_payload(self.request, payload)

        cleaned_payload = await self._validate_singular_payload(payload=payload
                                                                )
        cleaned_payload = self._clean_write_payload(cleaned_payload)

        if hasattr(self.schema, 'before_post'):
            cleaned_payload = await self.schema.before_post(
                weakref.proxy(self), self.request,
                cleaned_payload) or cleaned_payload

        insert_query = self._render_insert_query(cleaned_payload)

        async with self.request.app.db_pool.acquire() as conn:
            async with conn.cursor() as cur:
                await self.request.app.commons.execute(cur, insert_query,
                                                       cleaned_payload)
                res = await cur.fetchone()
                if res is None:
                    if self.request.session:
                        # Most likely a cross workspace insert or non-existent FK
                        raise web.HTTPConflict(
                            reason=
                            'Illegal cross workspace insert or non-existent FK supplied'
                        )

                    self.request.app.access_logger = self.request.app.access_logger.bind(
                        msg_context={'query': cur.query.decode()})
                    raise post_exceptions.CreateFailed()

        if hasattr(self.schema, 'after_post'):
            await spawn(
                self.request,
                self.schema.after_post(self.request, cleaned_payload, res[0]))

        return json_response({self.pk_column_name: res[0]})
Exemple #14
0
async def get_mediation_record_by_connection_id(
    backchannel: "AcaPyAgentBackchannel", connection_id: str
):
    (_, resp_text) = await backchannel.admin_GET(
        "/mediation/requests", params={"conn_id": connection_id}
    )

    resp_json = json.loads(resp_text)

    if len(resp_json["results"]) == 0:
        raise web.HTTPNotFound(
            reason=f"No mediation record found for connection with id {connection_id}"
        )

    # Should not be possible. ACA-Py only allows one mediation record set-up per connection
    if len(resp_json["results"]) > 1:
        raise web.HTTPConflict(
            reason=f"Multiple mediation records found for connection with id {connection_id}"
        )

    return resp_json["results"][0]
async def register_service(request, db_pool):
    """Register a new service at host."""
    LOG.debug('Register new service.')
    # Get POST request body JSON as python dict
    service = await request.json()

    # Parse query params from path, `_` denotes service_id from path param /services/{service_id}, which is not used here
    _, params = await query_params(request)

    # Response object
    response = {'message': '', 'beaconServiceKey': ''}

    if 'remote' in params:
        # This option is used at Aggregators when they do a remote registration at a Registry
        LOG.debug(f'Remote registration request to {params["remote"]}.')
        # Register self (aggregator) at remote service (registry) via self, not manually
        service_key = await remote_registration(db_pool, request,
                                                params['remote'])
        response = {
            'message':
            f'Service has been registered remotely at {params["remote"]}. Service key for updating and deleting registration included in this response, keep it safe.',
            'beaconServiceKey': service_key
        }
    else:
        LOG.debug('Local registration at host.')
        # Take connection from database pool, re-use connection for all tasks
        async with db_pool.acquire() as connection:
            # Check that the chosen service ID is not taken
            id_taken = await db_check_service_id(connection, service['id'])
            if id_taken:
                raise web.HTTPConflict(text='Service ID is taken.')
            # Register service to host
            service_key = await db_register_service(connection, service)
            response = {
                'message':
                'Service has been registered. Service key for updating and deleting registration included in this response, keep it safe.',
                'beaconServiceKey': service_key
            }

    return response
Exemple #16
0
async def python_eval(
        req: web.Request) -> Union[Dict[str, Any], web.StreamResponse]:
    if not req.config_dict["args"].with_eval:
        raise web.HTTPForbidden(reason="Python eval page not ebabled")

    if req.app.get("eval-session", None) is not None:
        raise web.HTTPConflict(reason="Eval session already launched")

    ws_current = web.WebSocketResponse()
    ws_ready = ws_current.can_prepare(req)
    if not ws_ready.ok:
        return {}

    await ws_current.prepare(req)

    req.app["eval-session"] = ws_current

    async for msg in ws_current:
        if msg.type == aiohttp.WSMsgType.text:
            server_log.warn(
                f"Evaluating code from python eval page: {msg.data}")
            try:
                stdout, tb, returned = await eval_code(msg.data, req)
            except CompilationError as e:
                await ws_current.send_json({
                    "action": "eval_compilation_error",
                    "text": str(e)
                })
                continue

            await ws_current.send_json({
                "action": "eval_result",
                "stdout": stdout,
                "traceback": tb,
                "returned": str(returned),
            })

    req.app["eval-session"] = None

    return ws_current
Exemple #17
0
    def IDputClasslist(self, data, request):
        """Accept classlist upload.

        Only "manager" can perform this action.
        Responds with status success, HTTPBadRequest or HTTPConflict.

        The classlist should be provided as a ordered list of (str, str)
        pairs where each pair is (student ID, student name).

        Returns:
            aiohttp.web_response.Response: A response indicating whether the operation was a failure or a success.
        """
        if not data["user"] == "manager":
            raise web.HTTPBadRequest(reason="Not manager")
        classlist = data["classlist"]
        if os.path.isfile(Path(specdir) / "classlist.csv"):
            raise web.HTTPConflict(reason="we already have a classlist")
        with open(Path(specdir) / "classlist.csv", "w") as csvfile:
            writer = csv.writer(csvfile)
            writer.writerow(["id", "studentName"])
            writer.writerows(classlist)
        return web.Response()
Exemple #18
0
async def post(body: typing.Dict[str, typing.Any],
               db_pool: asyncpg.pool.Pool) -> web.Response:
    LOG.info('Received request to create new user')
    user_id = str(uuid.uuid4())
    async with db_pool.acquire() as conn:
        try:
            database_user = await conn.fetchrow(
                'SELECT id FROM users WHERE user_name = $1 ',
                body['user_name'])
            if database_user:
                raise web.HTTPConflict(
                    body=ujson.dumps({'message': 'User already exists'}))
            await conn.execute(
                'INSERT INTO users(id, user_name, first_name, last_name, email, address, postal_code)'
                'VALUES ($1, $2, $3, $4, $5, $6, $7)',
                user_id,
                body['user_name'],
                body['first_name'],
                body['last_name'],
                body['email'],
                body.get('address', ''),
                body.get('postal_code', ''),
            )
        except asyncpg.PostgresError:
            LOG.exception('Failed to add user')
            raise web.HTTPInternalServerError(
                body=ujson.dumps({'message': 'Failed to create new user'}))
    return web.json_response(
        data=user.User(
            id=user_id,
            userName=body['user_name'],
            firstName=body['first_name'],
            lastName=body['last_name'],
            email=body['email'],
            address=body.get('address'),
            postalCode=body.get('postal_code'),
        ),
        dumps=user.User.dumps,
    )
Exemple #19
0
async def worker_register(request: web.Request) -> web.Response:
    """For worker to register itself

    request headers:

    * X-DISTRIBUTED-WORKER-NAME: worker's name, worker should been registered
                                 already. required

    responses:

    * 200 OK: successful
    * 400 Bad Request: missing worker name header
    * 409 Conflict: worker has already registered
    """
    worker_name = _get_worker_name(request)

    master = request.app["master"]
    if not master.worker_register(worker_name):
        # already registered
        raise web.HTTPConflict(text="worker has already registered")

    return web.Response()
Exemple #20
0
async def post_users(request: web.Request) -> web.Response:
    """A client is asking to create a new user
    """
    data = await request.json()

    if not all(key in data.keys()
               for key in {"username", "email", "password"}):
        raise web.HTTPBadRequest(reason="Missing required input fields")

    logger.debug("Trying to create user %s", data["username"])

    if not is_email(data["email"]):
        raise web.HTTPBadRequest(reason="Email is not valid")

    try:
        await request.app["identity_backend"].register_user(
            data["username"], data["password"], data["email"])
    except UserAlreadyExist:
        raise web.HTTPConflict(reason="User already exist")

    location = f"/users/{data['username']}/"
    return web.Response(status=201, headers={"Location": location})
Exemple #21
0
    def IdentifyPaperTask(self, data, request):
        """Identify a paper based on a task.

        Returns:
            403: some other user owns this task.
            404: papernum not found, or other data errors.
            409: student number `data["sid"]` is already in use.
        """
        papernum = request.match_info["task"]
        r, what, msg = self.server.ID_id_paper(papernum, data["user"],
                                               data["sid"], data["sname"])
        if r:
            return web.Response(status=200)
        elif what == 409:
            raise web.HTTPConflict(reason=msg)
        elif what == 404:
            raise web.HTTPNotFound(reason=msg)
        elif what == 403:
            raise web.HTTPForbidden(reason=msg)
        else:
            # catch all that should not happen.
            raise web.HTTPInternalServerError(reason=msg)
def begin_job(jobdesc):
    global updater_process
    if updater_process is not None:
        if updater_process.poll() is not None:
            # Update complete
            updater_process = None
        else:
            error_body = {
                'error': 'update_already_running',
                'pid': updater_process.pid
            }
            raise web.HTTPConflict(body=error_body)
    job_id = str(uuid.uuid1())
    (fwfd, fwfilepath) = mkstemp()
    if not os.path.exists(UPDATE_JOB_DIR):
        os.makedirs(UPDATE_JOB_DIR)
    statusfilepath = os.path.join(UPDATE_JOB_DIR, str(job_id) + '.json')
    status = {'pid': 0, 'state': 'fetching'}
    with open(statusfilepath, 'wb') as sfh:
        sfh.write(json.dumps(status))
    try:
        fwdata = urllib.request.urlopen(jobdesc['fw_url'])
        with os.fdopen(fwfd, 'wb') as fwfile:
            fwfile.write(fwdata.read())
            fwfile.flush()
    except:
        os.remove(statusfilepath)
        raise

    updater = UPDATERS[jobdesc.get('updater', 'delta')]
    updater_process = Popen([
        updater, '--addr',
        str(jobdesc['address']), '--statusfile', statusfilepath, '--rmfwfile',
        fwfilepath
    ])
    status = {'pid': updater_process.pid, 'state': 'starting'}
    with open(statusfilepath, 'wb') as sfh:
        sfh.write(json.dumps(status))
    return {'job_id': job_id, 'pid': updater_process.pid}
Exemple #23
0
async def db_update_service(connection, id, service):
    """Update service."""
    LOG.debug("Update service.")
    # Check if user wants to change service id
    if not id == service["id"]:
        # Check if desired service ID is taken
        service_id = await db_check_service_id(connection, service["id"])
        if service_id:
            # Chosen service ID is taken
            raise web.HTTPConflict(text="Service ID is taken.")

    # Apply updates
    try:
        await connection.execute(
            """UPDATE services SET id=$1, name=$2, type=$3, description=$4,
                                 url=$5, contact_url=$6, api_version=$7, service_version=$8,
                                 environment=$9, organization=$10, organization_url=$11, organization_logo=$12,
                                 updated_at=NOW()
                                 WHERE id=$13""",
            service["id"],
            service["name"],
            service["type"],
            service["description"],
            service["url"],
            service["contact_url"],
            service["api_version"],
            service["service_version"],
            service["environment"],
            service["organization"],
            service["organization_url"],
            service["organization_logo"],
            id,
        )
    except Exception as e:
        LOG.debug(f"DB error: {e}")
        raise web.HTTPInternalServerError(
            text=
            "Database error occurred while attempting to update service details."
        )
Exemple #24
0
async def register(request):
    username = await authorized_userid(request)
    if username:
        return web.HTTPOk()

    data = await request.json()
    username = data["username"]
    password = data["password"]
    if User.by_name(username):
        return web.HTTPConflict(reason="Username already taken")
    elif not username:
        return web.HTTPBadRequest(reason="Please provide a username")
    elif not password:
        return web.HTTPBadRequest(reason="Please provide a password")
    else:
        with db.atomic():
            u = User(name=username)
            u.set_password(password)
            u.save()
        response = web.HTTPOk()
        await remember(request, response, username)
        return response
Exemple #25
0
async def delete_schedule(request):
    """
    Delete a schedule from schedules table

    :Example:
             curl -X DELETE  http://localhost:8081/foglamp/schedule/dc9bfc01-066a-4cc0-b068-9c35486db87f
    """

    try:
        schedule_id = request.match_info.get('schedule_id', None)

        try:
            assert uuid.UUID(schedule_id)
        except ValueError as ex:
            raise web.HTTPNotFound(reason="Invalid Schedule ID {}".format(schedule_id))

        retval, message = await server.Server.scheduler.delete_schedule(uuid.UUID(schedule_id))

        return web.json_response({'message': message, 'id': schedule_id})
    except RuntimeWarning:
        raise web.HTTPConflict(reason="Enabled Schedule {} cannot be deleted.".format(schedule_id))
    except (ValueError, ScheduleNotFoundError, NotReadyError) as ex:
        raise web.HTTPNotFound(reason=str(ex))
async def websocketHandler(request):
    cid = request.match_info['cid']
    if cid in websockets:
        return web.HTTPConflict(text="Already have a connection here")

    ws = web.WebSocketResponse(max_msg_size=MSG_MAX, heartbeat=60.0)
    await ws.prepare(request)
    websockets[cid] = {"ws": ws, "recv": None}
    print(f'({len(websockets)}) {cid}: connection opened')
    try:
        msg = await ws.receive_str()
        if websockets[cid]["recv"] is not None:
            websockets[cid]["recv"].put_nowait(msg)
    except:
        # Clear the queue
        if websockets[cid]["recv"] is not None:
            try:
                websockets[cid]["recv"].put_nowait("")
            except:
                pass

    del websockets[cid]
    print(f'({len(websockets)}) {cid}: connection closed')
Exemple #27
0
    async def post_handler(self, request: web.Request) -> web.Response:
        """POST handler to create a resource"""
        try:
            request_data = await request.json()
        except Exception:
            raise web.HTTPBadRequest(
                text=json.dumps({"errors": ["The supplied JSON is invalid."]}))

        try:
            request_entity = self.adapter.to_entity(request_data)
        except aiokea.errors.ValidationError as e:
            raise web.HTTPUnprocessableEntity(text=json.dumps(
                {"errors": e.errors}),
                                              content_type="application/json")
        try:
            service_entity = await self.service.create(request_entity)
        except DuplicateResourceError as e:
            raise web.HTTPConflict(
                text=json.dumps({"errors": [e.msg]}),
                content_type="application/json",
            )
        response_data = self.adapter.from_entity(service_entity)
        return web.json_response({"data": response_data})
Exemple #28
0
    def populateExamDatabase(self, data, request):
        """Instruct the server to generate paper data in the database.

        TODO: maybe the api call should just be for one row of the database.

        TODO: or maybe we can pass the page-to-version mapping to this?
        """
        if not data["user"] == "manager":
            return web.Response(status=400)  # malformed request.

        from plom.db import buildExamDatabaseFromSpec

        # TODO this is not the design we have elsewhere, should call helper function
        try:
            r, summary = buildExamDatabaseFromSpec(self.server.testSpec,
                                                   self.server.DB)
        except ValueError:
            raise web.HTTPConflict(
                reason="Database already present: not overwriting") from None
        if r:
            return web.Response(text=summary, status=200)
        else:
            raise web.HTTPInternalServerError(text=summary)
Exemple #29
0
    async def remove_job(self, request):
        data = await request.post()

        self.logger.debug("received remove request {0}".format(data))

        if 'command' not in data or \
                'minute' not in data or \
                'hour' not in data or \
                'dom' not in data or \
                'month' not in data or \
                'dow' not in data:
            return web.Response(status=500,
                                text='not all mandatory fields submitted')

        cron_item = self.generate_cron_item(data, removable=True)

        if cron_item not in self.storage.cluster_jobs:
            raise web.HTTPConflict(text='job not found')

        self.logger.debug("broadcasting remove result")

        broadcast(self.udp_port, UdpSerializer.dump(cron_item, self.hash_key))

        raise web.HTTPAccepted()
Exemple #30
0
async def scale_cluster(request):
    user = request["user"]
    cluster_name = request.match_info["cluster_name"]
    backend = request.app["backend"]
    cluster = await backend.get_cluster(cluster_name)
    if cluster is None:
        raise web.HTTPNotFound(reason=f"Cluster {cluster_name} not found")
    if not user.has_permissions(cluster):
        raise web.HTTPForbidden(
            reason=
            f"User {user.name} lacks permissions to view cluster {cluster_name}"
        )

    msg = await request.json()
    count = msg.get("count", None)
    if not isinstance(count, int) or count < 0:
        raise web.HTTPUnprocessableEntity(
            reason=f"Scale expects a non-negative integer, got {count}")

    max_workers = cluster.config.get("cluster_max_workers")
    resp_msg = None
    if max_workers is not None and count > max_workers:
        resp_msg = (
            f"Scale request of {count} workers would exceed resource limit of "
            f"{max_workers} workers. Scaling to {max_workers} instead.")
        count = max_workers

    try:
        await backend.forward_message_to_scheduler(cluster, {
            "op": "scale",
            "count": count
        })
    except PublicException as exc:
        raise web.HTTPConflict(reason=str(exc))

    return web.json_response({"ok": not resp_msg, "msg": resp_msg})