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)
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)
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)
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)