Esempio n. 1
0
 def run(self, machine, *args, **kwargs):
     assert isinstance(machine, Machine)
     assert machine.owner == self._instance.owner
     getattr(machine.ctl, self.action)()
     if self.action == 'destroy':  # If destroy, disable monitoring, too.
         # FIXME Imported here due to circular dependency issues.
         from mist.api.monitoring.methods import disable_monitoring
         # TODO Move this into machine.ctl.destroy method and
         # deprecate mist.api.machines.methods:destroy_machine.
         # Could also be implemented as new method inside the
         # MachineController.
         disable_monitoring(machine.owner,
                            machine.cloud.id,
                            machine.machine_id,
                            no_ssh=True)
Esempio n. 2
0
 def run(self, machine, value, triggered, timestamp, incident_id, **kwargs):
     if timestamp + 60 * 60 * 24 < time.time():
         # FIXME Imported here due to circular dependency issues.
         from mist.api.monitoring.methods import disable_monitoring
         # If NoData alerts are being triggered for over 24h, disable
         # monitoring and log the action to close any open incidents.
         disable_monitoring(machine.owner,
                            machine.cloud.id,
                            machine.machine_id,
                            no_ssh=True)
         log_event(machine.owner.id,
                   'incident',
                   'disable_monitoring',
                   cloud_id=machine.cloud.id,
                   machine_id=machine.id,
                   external_id=machine.machine_id,
                   incident_id=incident_id)
         action = 'Disable Monitoring'
     else:
         action = 'Alert'
     super(NoDataAction, self).run(machine, value, triggered, timestamp,
                                   incident_id, action)
Esempio n. 3
0
def machine_actions(request):
    """
    Tags: machines
    ---
    Calls a machine action on cloud that supports it.
    READ permission required on cloud.
    ACTION permission required on machine(ACTION can be START,
    STOP, DESTROY, REBOOT or RESIZE, RENAME for some providers).
    ---
    machine_uuid:
      in: path
      required: true
      type: string
    action:
      enum:
      - start
      - stop
      - reboot
      - destroy
      - resize
      - rename
      - create_snapshot
      - remove_snapshot
      - revert_to_snapshot
      required: true
      type: string
    name:
      description: The new name of the renamed machine
      type: string
    size:
      description: The size id of the plan to resize
      type: string
    snapshot_name:
      description: The name of the snapshot to create/remove/revert_to
    snapshot_description:
      description: The description of the snapshot to create
    snapshot_dump_memory:
      description: Dump the machine's memory in the snapshot
      default: false
    snapshot_quiesce:
      description: Enable guest file system quiescing
      default: false
    """
    cloud_id = request.matchdict.get('cloud')
    params = params_from_request(request)
    action = params.get('action', '')
    name = params.get('name', '')
    size_id = params.get('size', '')
    memory = params.get('memory', '')
    cpus = params.get('cpus', '')
    cpu_shares = params.get('cpu_shares', '')
    cpu_units = params.get('cpu_units', '')
    snapshot_name = params.get('snapshot_name')
    snapshot_description = params.get('snapshot_description')
    snapshot_dump_memory = params.get('snapshot_dump_memory')
    snapshot_quiesce = params.get('snapshot_quiesce')
    auth_context = auth_context_from_request(request)

    if cloud_id:
        machine_id = request.matchdict['machine']
        auth_context.check_perm("cloud", "read", cloud_id)
        try:
            machine = Machine.objects.get(cloud=cloud_id,
                                          machine_id=machine_id,
                                          state__ne='terminated')
            # used by logging_view_decorator
            request.environ['machine_uuid'] = machine.id
        except Machine.DoesNotExist:
            raise NotFoundError("Machine %s doesn't exist" % machine_id)
    else:
        machine_uuid = request.matchdict['machine_uuid']
        try:
            machine = Machine.objects.get(id=machine_uuid)
            # VMs in libvirt can be started no matter if they are terminated
            if machine.state == 'terminated' and not isinstance(
                    machine.cloud, LibvirtCloud):
                raise NotFoundError("Machine %s has been terminated" %
                                    machine_uuid)
            # used by logging_view_decorator
            request.environ['machine_id'] = machine.machine_id
            request.environ['cloud_id'] = machine.cloud.id
        except Machine.DoesNotExist:
            raise NotFoundError("Machine %s doesn't exist" % machine_uuid)

        cloud_id = machine.cloud.id
        auth_context.check_perm("cloud", "read", cloud_id)

    if machine.cloud.owner != auth_context.owner:
        raise NotFoundError("Machine %s doesn't exist" % machine.id)

    auth_context.check_perm("machine", action, machine.id)

    actions = ('start', 'stop', 'reboot', 'destroy', 'resize', 'rename',
               'undefine', 'suspend', 'resume', 'remove', 'list_snapshots',
               'create_snapshot', 'remove_snapshot', 'revert_to_snapshot',
               'clone')

    if action not in actions:
        raise BadRequestError("Action '%s' should be "
                              "one of %s" % (action, actions))

    if not methods.run_pre_action_hooks(machine, action, auth_context.user):
        return OK  # webhook requires stopping action propagation

    if action == 'destroy':
        result = methods.destroy_machine(auth_context.owner, cloud_id,
                                         machine.machine_id)
    elif action == 'remove':
        log.info('Removing machine %s in cloud %s' %
                 (machine.machine_id, cloud_id))

        # if machine has monitoring, disable it
        if machine.monitoring.hasmonitoring:
            try:
                disable_monitoring(auth_context.owner,
                                   cloud_id,
                                   machine_id,
                                   no_ssh=True)
            except Exception as exc:
                log.warning("Didn't manage to disable monitoring, maybe the "
                            "machine never had monitoring enabled. Error: %r" %
                            exc)
        result = machine.ctl.remove()
        # Schedule a UI update
        trigger_session_update(auth_context.owner, ['clouds'])
    elif action in ('start', 'stop', 'reboot', 'clone', 'undefine', 'suspend',
                    'resume'):
        result = getattr(machine.ctl, action)()
    elif action == 'rename':
        if not name:
            raise BadRequestError("You must give a name!")
        result = getattr(machine.ctl, action)(name)
    elif action == 'resize':
        _, constraints = auth_context.check_perm("machine", "resize",
                                                 machine.id)
        # check cost constraint
        cost_constraint = constraints.get('cost', {})
        if cost_constraint:
            try:
                from mist.rbac.methods import check_cost
                check_cost(auth_context.org, cost_constraint)
            except ImportError:
                pass
        kwargs = {}
        if memory:
            kwargs['memory'] = memory
        if cpus:
            kwargs['cpus'] = cpus
        if cpu_shares:
            kwargs['cpu_shares'] = cpu_shares
        if cpu_units:
            kwargs['cpu_units'] = cpu_units
        result = getattr(machine.ctl, action)(size_id, kwargs)
    elif action == 'list_snapshots':
        return machine.ctl.list_snapshots()
    elif action in ('create_snapshot', 'remove_snapshot',
                    'revert_to_snapshot'):
        kwargs = {}
        if snapshot_description:
            kwargs['description'] = snapshot_description
        if snapshot_dump_memory:
            kwargs['dump_memory'] = bool(snapshot_dump_memory)
        if snapshot_quiesce:
            kwargs['quiesce'] = bool(snapshot_quiesce)
        result = getattr(machine.ctl, action)(snapshot_name, **kwargs)

    methods.run_post_action_hooks(machine, action, auth_context.user, result)

    # TODO: We shouldn't return list_machines, just OK. Save the API!
    return methods.filter_list_machines(auth_context, cloud_id)
Esempio n. 4
0
def machine_actions(request):
    """
    Tags: machines
    ---
    Calls a machine action on cloud that supports it.
    READ permission required on cloud.
    ACTION permission required on machine(ACTION can be START,
    STOP, DESTROY, REBOOT or RESIZE, RENAME for some providers).
    ---
    machine_uuid:
      in: path
      required: true
      type: string
    action:
      enum:
      - start
      - stop
      - reboot
      - destroy
      - resize
      - rename
      required: true
      type: string
    name:
      description: The new name of the renamed machine
      type: string
    size:
      description: The size id of the plan to resize
      type: string
    """
    cloud_id = request.matchdict.get('cloud')
    params = params_from_request(request)
    action = params.get('action', '')
    size_id = params.get('size', params.get('plan_id', ''))
    memory = params.get('memory', '')
    cpus = params.get('cpus', '')
    cpu_shares = params.get('cpu_shares', '')
    cpu_units = params.get('cpu_units', '')
    name = params.get('name', '')
    auth_context = auth_context_from_request(request)

    if cloud_id:
        # this is depracated, keep it for backwards compatibility
        machine_id = request.matchdict['machine']
        auth_context.check_perm("cloud", "read", cloud_id)
        try:
            machine = Machine.objects.get(cloud=cloud_id,
                                          machine_id=machine_id,
                                          state__ne='terminated')
            # used by logging_view_decorator
            request.environ['machine_uuid'] = machine.id
        except Machine.DoesNotExist:
            raise NotFoundError("Machine %s doesn't exist" % machine_id)
    else:
        machine_uuid = request.matchdict['machine_uuid']
        try:
            machine = Machine.objects.get(id=machine_uuid)
            # VMs in libvirt can be started no matter if they are terminated
            if machine.state == 'terminated' and not isinstance(
                    machine.cloud, LibvirtCloud):
                raise NotFoundError("Machine %s has been terminated" %
                                    machine_uuid)
            # used by logging_view_decorator
            request.environ['machine_id'] = machine.machine_id
            request.environ['cloud_id'] = machine.cloud.id
        except Machine.DoesNotExist:
            raise NotFoundError("Machine %s doesn't exist" % machine_uuid)

        cloud_id = machine.cloud.id
        auth_context.check_perm("cloud", "read", cloud_id)

    if machine.cloud.owner != auth_context.owner:
        raise NotFoundError("Machine %s doesn't exist" % machine.id)

    auth_context.check_perm("machine", action, machine.id)

    actions = ('start', 'stop', 'reboot', 'destroy', 'resize', 'rename',
               'undefine', 'suspend', 'resume', 'remove')

    if action not in actions:
        raise BadRequestError("Action '%s' should be "
                              "one of %s" % (action, actions))
    if action == 'destroy':
        methods.destroy_machine(auth_context.owner, cloud_id,
                                machine.machine_id)
    elif action == 'remove':
        log.info('Removing machine %s in cloud %s' %
                 (machine.machine_id, cloud_id))

        if not machine.monitoring.hasmonitoring:
            machine.ctl.remove()
            # Schedule a UI update
            trigger_session_update(auth_context.owner, ['clouds'])
            return

        # if machine has monitoring, disable it. the way we disable depends on
        # whether this is a standalone io installation or not
        try:
            disable_monitoring(auth_context.owner,
                               cloud_id,
                               machine_id,
                               no_ssh=True)
        except Exception as exc:
            log.warning(
                "Didn't manage to disable monitoring, maybe the "
                "machine never had monitoring enabled. Error: %r", exc)

        machine.ctl.remove()

        # Schedule a UI update
        trigger_session_update(auth_context.owner, ['clouds'])

    elif action in ('start', 'stop', 'reboot', 'undefine', 'suspend',
                    'resume'):
        getattr(machine.ctl, action)()
    elif action == 'rename':
        if not name:
            raise BadRequestError("You must give a name!")
        getattr(machine.ctl, action)(name)
    elif action == 'resize':
        kwargs = {}
        if memory:
            kwargs['memory'] = memory
        if cpus:
            kwargs['cpus'] = cpus
        if cpu_shares:
            kwargs['cpu_shares'] = cpu_shares
        if cpu_units:
            kwargs['cpu_units'] = cpu_units
        getattr(machine.ctl, action)(size_id, kwargs)

    # TODO: We shouldn't return list_machines, just OK. Save the API!
    return methods.filter_list_machines(auth_context, cloud_id)