Beispiel #1
0
def GET(request):
    """Get this Rack's Machines."""

    # Make sure required parameters are there

    try:
        request.check_required_parameters(path={'tileId': 'int'})

    except exceptions.ParameterError as e:
        return Response(400, e.message)

    # Instantiate a Rack from the database

    rack = Rack.from_tile_id(request.params_path['tileId'])

    # Make sure this Rack exists

    if not rack.exists():
        return Response(404, '{} not found.'.format(rack))

    # Make sure this user is authorized to view this Rack's Machines

    if not rack.google_id_has_at_least(request.google_id, 'VIEW'):
        return Response(403, 'Forbidden from viewing {}.'.format(rack))

    # Get and return the Machines

    machines = Machine.query('rack_id', rack.id)

    for machine in machines:
        machine.read()

    return Response(200,
                    'Successfully retrieved Machines for {}.'.format(rack),
                    [x.to_JSON() for x in machines])
Beispiel #2
0
def PUT(request):
    """Update the Rack on this Tile."""

    # Make sure required parameters are there

    try:
        request.check_required_parameters(path={'tileId': 'int'},
                                          body={
                                              'rack': {
                                                  'name': 'string',
                                                  'capacity': 'int',
                                                  'powerCapacityW': 'int'
                                              }
                                          })

    except exceptions.ParameterError as e:
        return Response(400, e.message)

    # Instantiate a Tile from the database

    tile = Tile.from_primary_key((request.params_path['tileId'], ))

    # Make sure this Tile exists

    if not tile.exists():
        return Response(404, '{} not found.'.format(tile))

    # Make sure this user is authorized to edit this Tile

    if not tile.google_id_has_at_least(request.google_id, 'EDIT'):
        return Response(403, 'Forbidden from editing {}'.format(tile))

    # Instantiate a Rack from the database

    rack = Rack.from_primary_key((tile.object_id, ))

    # Make sure this Rack exists

    if not rack.exists():
        return Response(404, '{} not found'.format(rack))

    # Update this Rack

    rack.name = request.params_body['rack']['name']
    rack.capacity = request.params_body['rack']['capacity']

    rack.update()

    # Return this Rack

    rack.read()

    return Response(200, 'Successfully updated {}.'.format(rack),
                    rack.to_JSON())
Beispiel #3
0
def POST(request):
    """Add a Rack to this Tile if it is empty."""

    # Make sure required parameters are there

    try:
        request.check_required_parameters(path={'tileId': 'int'},
                                          body={
                                              'rack': {
                                                  'name': 'string',
                                                  'capacity': 'int',
                                                  'powerCapacityW': 'int'
                                              }
                                          })

    except exceptions.ParameterError as e:
        return Response(400, e.message)

    # Instantiate a Tile from the database

    tile = Tile.from_primary_key((request.params_path['tileId'], ))

    # Make sure this Tile exists

    if not tile.exists():
        return Response(404, '{} not found.'.format(tile))

    # Make sure this user is authorized to edit this Tile

    if not tile.google_id_has_at_least(request.google_id, 'EDIT'):
        return Response(403, 'Forbidden from editing {}'.format(tile))

    # Make sure this Tile isn't occupied

    if tile.object_id is not None:
        return Response(409, '{} occupied.'.format(tile))

    # Instantiate a Rack and insert it into the database

    rack = Rack.from_JSON(request.params_body['rack'])
    rack.insert()

    # Try to add this Rack to this Tile

    tile.object_id = rack.id
    tile.object_type = 'RACK'
    tile.update()

    # Return this Rack

    rack.read()

    return Response(200, 'Successfully added {}.'.format(rack), rack.to_JSON())
Beispiel #4
0
    def google_id_has_at_least(self, google_id, authorization_level):
        """Return True if the user has at least the given auth level over this Machine."""

        # Get the Rack

        try:
            rack = Rack.from_primary_key((self.rack_id, ))
        except exceptions.RowNotFoundError:
            return False

        # Check the Rack's Authorization

        return rack.google_id_has_at_least(google_id, authorization_level)
Beispiel #5
0
def DELETE(request):
    """Delete this Tile's Rack."""

    # Make sure required parameters are there

    try:
        request.check_required_parameters(path={'tileId': 'int'}, )

    except exceptions.ParameterError as e:
        return Response(400, e.message)

    # Instantiate a Tile from the database

    tile = Tile.from_primary_key((request.params_path['tileId'], ))

    # Make sure this Tile exists

    if not tile.exists():
        return Response(404, '{} not found.'.format(tile))

    # Make sure this user is authorized to edit this Tile

    if not tile.google_id_has_at_least(request.google_id, 'EDIT'):
        return Response(403, 'Forbidden from editing {}'.format(tile))

    # Instantiate a Rack from the database

    rack = Rack.from_primary_key((tile.object_id, ))

    # Make sure this Rack exists

    if not rack.exists():
        return Response(404, '{} not found'.format(rack))

    # Remove this Rack from this Tile

    tile.object_id = None
    tile.object_type = None

    tile.update()

    # Delete this Rack

    rack.delete()

    # Return this Rack

    return Response(200, 'Successfully deleted {}.'.format(rack),
                    rack.to_JSON())
Beispiel #6
0
    def from_tile_id_and_rack_position(cls, tile_id, position):
        """Get a Rack from the ID of the tile its Rack is on, and its position in the Rack."""

        try:
            rack = Rack.from_tile_id(tile_id)
        except:
            return cls(id=-1)

        try:
            statement = 'SELECT id FROM machines WHERE rack_id = %s AND position = %s'
            machine_id = database.fetchone(statement, (rack.id, position))[0]
        except:
            return cls(id=-1)

        return cls.from_primary_key((machine_id, ))
Beispiel #7
0
def POST(request):
    """Create a new Path that branches off of this Path at the specified tick."""

    # Make sure required parameters are there

    try:
        request.check_required_parameters(
            path={'pathId': 'int'}, body={'section': {
                'startTick': 'int'
            }})

    except exceptions.ParameterError as e:
        return Response(400, e.message)

    # Instantiate the current Path from the database

    current_path = Path.from_primary_key((request.params_path['pathId'], ))

    # Make sure the current Path exists

    if not current_path.exists():
        return Response(404, '{} not found.'.format(current_path))

    # Make sure this user is authorized to branch off the current Path

    if not current_path.google_id_has_at_least(request.google_id, 'EDIT'):
        return Response(
            403, 'Forbidden from branching off {}.'.format(current_path))

    # Create the new Path

    new_path = Path(simulation_id=current_path.simulation_id,
                    datetime_created=database.datetime_to_string(
                        datetime.now()))

    new_path.insert()

    # Get the current Path's sections and add them to the new Path if they're before the branch

    current_sections = Section.query('path_id', current_path.id)
    last_section = None

    for current_section in current_sections:

        if current_section.start_tick < request.params_body['section'][
                'startTick'] or current_section.start_tick == 0:
            new_section = Section(path_id=new_path.id,
                                  datacenter_id=current_section.datacenter_id,
                                  start_tick=current_section.start_tick)

            new_section.insert()

            last_section = current_section

    # Make a deep copy of the last section's datacenter, its rooms, their tiles, etc.

    path_parameters = {'simulationId': new_path.simulation_id}

    # Copy the Datacenter

    old_datacenter = Datacenter.from_primary_key(
        (last_section.datacenter_id, ))

    message = old_datacenter.generate_api_call(path_parameters, request.token)
    response = Request(message).process()

    path_parameters['datacenterId'] = response.content['id']

    # Create the new last Section, with the IDs of the new Path and new Datacenter

    if last_section.start_tick != 0:
        new_section = Section(
            path_id=new_path.id,
            datacenter_id=path_parameters['datacenterId'],
            start_tick=request.params_body['section']['startTick'])

        new_section.insert()

    else:
        last_section.datacenter_id = path_parameters['datacenterId']
        last_section.update()

    # Copy the rest of the Datacenter, starting with the Rooms...

    old_rooms = Room.query('datacenter_id', old_datacenter.id)

    for old_room in old_rooms:

        old_room.datacenter_id = path_parameters['datacenterId']

        if old_room.topology_id is None:
            old_room.topology_id = old_room.id

        message = old_room.generate_api_call(path_parameters, request.token)
        response = Request(message).process()

        path_parameters['roomId'] = response.content['id']

        # ... then the Tiles, ...

        old_tiles = Tile.query('room_id', old_room.id)

        for old_tile in old_tiles:

            old_tile.room_id = path_parameters['roomId']

            if old_tile.topology_id is None:
                old_tile.topology_id = old_tile.id

            message = old_tile.generate_api_call(path_parameters,
                                                 request.token)
            response = Request(message).process()

            path_parameters['tileId'] = response.content['id']

            old_objects = Object.query('id', old_tile.object_id)

            # ... then the Tile's Rack, ...

            if len(old_objects) == 1 and old_objects[0].type == 'RACK':

                old_rack = Rack.query('id', old_objects[0].id)[0]

                if old_rack.topology_id is None:
                    old_rack.topology_id = old_rack.id

                message = old_rack.generate_api_call(path_parameters,
                                                     request.token)
                response = Request(message).process()

                path_parameters['rackId'] = response.content['id']

                # ... then the Rack's Machines ...

                old_machines = Machine.query('rack_id', old_rack.id)

                for old_machine in old_machines:
                    old_machine.read()
                    old_machine.rack_id = path_parameters['rackId']

                    if old_machine.topology_id is None:
                        old_machine.topology_id = old_machine.id

                    message = old_machine.generate_api_call(
                        path_parameters, request.token)
                    response = Request(message).process()

                    path_parameters['machineId'] = response.content['id']

    # Return the new Path

    return Response(200, 'Successfully created {}.'.format(new_path),
                    new_path.to_JSON())
Beispiel #8
0
def PUT(request):
    """Update the Machine at this location in this Rack."""

    try:
        request.check_required_parameters(
            path={
                'tileId': 'int',
                'position': 'int'
            },
            body={
                'machine': {
                    'rackId': 'int',
                    'position': 'int',
                    'tags': 'list-string',
                    'cpuIds': 'list-int',
                    'gpuIds': 'list-int',
                    'memoryIds': 'list-int',
                    'storageIds': 'list-int'
                }
            }
        )

    except exceptions.ParameterError as e:
        return Response(400, e.message)

    # Instantiate a Machine from the database

    machine = Machine.from_tile_id_and_rack_position(request.params_path['tileId'], request.params_path['position'])

    # Make sure this Machine exists

    if not machine.exists():
        return Response(404, '{} not found.'.format(machine))

    # Make sure this Machine's rack ID is right

    rack = Rack.from_tile_id(request.params_path['tileId'])

    if not rack.exists() or rack.id != request.params_body['machine']['rackId']:
        return Response(400, 'Mismatch in Rack IDs.')

    # Make sure this user is authorized to edit this Machine

    if not machine.google_id_has_at_least(request.google_id, 'EDIT'):
        return Response(403, 'Forbidden from retrieving {}.'.format(machine))

    # Update this Machine

    machine.position = request.params_body['machine']['position']
    machine.tags = request.params_body['machine']['tags']
    machine.cpu_ids = request.params_body['machine']['cpuIds']
    machine.gpu_ids = request.params_body['machine']['gpuIds']
    machine.memory_ids = request.params_body['machine']['memoryIds']
    machine.storage_ids = request.params_body['machine']['storageIds']

    try:
        machine.update()

    except exceptions.ForeignKeyError:
        return Response(409, 'Rack position occupied.')

    except Exception as e:
        print e
        return Response(400, 'Invalid Machine.')

    # Return this Machine

    machine.read()

    return Response(
        200,
        'Successfully updated {}.'.format(machine),
        machine.to_JSON()
    )
Beispiel #9
0
def POST(request):
    """Add a Machine to this rack."""

    # Make sure required parameters are there

    try:
        request.check_required_parameters(path={'tileId': 'int'},
                                          body={
                                              'machine': {
                                                  'rackId': 'int',
                                                  'position': 'int',
                                                  'tags': 'list-string',
                                                  'cpuIds': 'list-int',
                                                  'gpuIds': 'list-int',
                                                  'memoryIds': 'list-int',
                                                  'storageIds': 'list-int'
                                              }
                                          })

    except exceptions.ParameterError as e:
        return Response(400, e.message)

    # Instantiate a Rack from the database

    rack = Rack.from_tile_id(request.params_path['tileId'])

    # Make sure this Rack exists

    if not rack.exists():
        return Response(404, '{} not found.'.format(rack))

    # Make sure this Rack's ID matches the given rack ID

    if rack.id != request.params_body['machine']['rackId']:
        return Response(400, 'Rack ID in `machine` and path do not match.')

    # Make sure this user is authorized to edit this Rack's Machines

    if not rack.google_id_has_at_least(request.google_id, 'VIEW'):
        return Response(403, 'Forbidden from viewing {}.'.format(rack))

    # Instantiate a Machine

    machine = Machine.from_JSON(request.params_body['machine'])

    # Try to insert this Machine

    try:
        machine.insert()

    except exceptions.ForeignKeyError:
        return Response(409, 'Rack position occupied.')

    except:
        return Response(400, 'Invalid Machine.')

    # Return this Machine

    machine.read()

    return Response(200, 'Successfully added {}.'.format(machine),
                    machine.to_JSON())