Exemplo n.º 1
0
    def deploy(self, machine, username=None, port=22):
        """"""
        # try to actually deploy
        log.info("Deploying key to host %s", machine.hostname)
        filename = '~/.ssh/authorized_keys'
        grep_output = '`grep \'%s\' %s`' % (self.key.public, filename)
        new_line_check_cmd = (
            'if [ "$(tail -c1 %(file)s; echo x)" != "\\nx" ];'
            ' then echo "" >> %(file)s; fi' % {
                'file': filename
            })
        append_cmd = ('if [ -z "%s" ]; then echo "%s" >> %s; fi' %
                      (grep_output, self.key.public, filename))
        command = new_line_check_cmd + " ; " + append_cmd
        log.debug("command = %s", command)

        # FIXME
        from mist.api.methods import ssh_command

        deploy_error = False

        try:
            # Deploy key.
            ssh_command(self.key.owner,
                        machine.cloud.id,
                        machine.machine_id,
                        machine.hostname,
                        command,
                        username=username,
                        port=port)
            log.info("Key associated and deployed successfully.")
        except MachineUnauthorizedError:
            # Couldn't deploy key, maybe key was already deployed?
            deploy_error = True
        try:
            ssh_command(self.key.owner,
                        machine.cloud.id,
                        machine.machine_id,
                        machine.hostname,
                        'uptime',
                        key_id=self.key.id,
                        username=username,
                        port=port)
        except MachineUnauthorizedError:
            if deploy_error:
                super(SSHKeyController, self).disassociate(machine)
                raise MachineUnauthorizedError("Couldn't connect to "
                                               "deploy new SSH key.")
            raise
Exemplo n.º 2
0
 def undeploy(self, machine):
     log.info("Trying to actually remove key from authorized_keys.")
     command = \
         'grep -v "' + self.key.public + \
         '" ~/.ssh/authorized_keys ' + \
         '> ~/.ssh/authorized_keys.tmp ; ' + \
         'mv ~/.ssh/authorized_keys.tmp ~/.ssh/authorized_keys ' + \
         '&& chmod go-w ~/.ssh/authorized_keys'
     try:
         # FIXME
         from mist.api.methods import ssh_command
         ssh_command(self.key.owner, machine.cloud.id,
                     machine.machine_id, machine.hostname, command)
     except Exception as exc:
         log.info("Undeploying key %s failed: %s", self.key.id, str(exc))
Exemplo n.º 3
0
 def run(self, machine, *args, **kwargs):
     # FIXME Imported here due to circular dependency issues.
     from mist.api.methods import ssh_command
     assert isinstance(machine, Machine)
     assert machine.owner == self._instance.owner
     return ssh_command(machine.owner, machine.cloud.id, machine.machine_id,
                        machine.hostname, self.command)
Exemplo n.º 4
0
 def reboot_machine_ssh(self, machine):
     """Reboot machine by running command over SSH"""
     assert self.cloud == machine.cloud
     log.debug("Rebooting (SSH) machine %s", machine)
     try:
         if machine.public_ips:
             hostname = machine.public_ips[0]
         else:
             hostname = machine.private_ips[0]
         command = '$(command -v sudo) shutdown -r now'
         # TODO move it up
         from mist.api.methods import ssh_command
         ssh_command(self.cloud.owner, self.cloud.id,
                     machine.machine_id, hostname, command)
     except MistError as exc:
         log.error("Could not reboot machine %s", machine)
         raise
     except Exception as exc:
         log.exception(exc)
         raise InternalServerError(exc=exc)
Exemplo n.º 5
0
 def _reboot_machine(self, machine, machine_libcloud):
     hypervisor = machine_libcloud.extra.get('tags', {}).get('type', None)
     if hypervisor == 'hypervisor':
         # issue an ssh command for the libvirt hypervisor
         try:
             hostname = machine_libcloud.public_ips[0] if \
                 machine_libcloud.public_ips else \
                 machine_libcloud.private_ips[0]
             command = '$(command -v sudo) shutdown -r now'
             # todo move it up
             from mist.api.methods import ssh_command
             ssh_command(self.cloud.owner, self.cloud.id,
                         machine_libcloud.id, hostname, command)
             return True
         except MistError as exc:
             log.error("Could not ssh machine %s", machine.name)
             raise
         except Exception as exc:
             log.exception(exc)
             raise InternalServerError(exc=exc)
     else:
         machine_libcloud.reboot()
Exemplo n.º 6
0
    def add_machine(self, name, host='',
                    ssh_user='******', ssh_port=22, ssh_key=None,
                    os_type='unix', rdp_port=3389, fail_on_error=True):
        """Add machine to this dummy Cloud

        This is a special method that exists only on this Cloud subclass.
        """

        old_machines = [m.as_dict() for m in
                        self.cloud.ctl.compute.list_cached_machines()]

        # FIXME: Move ssh command to Machine controller once it is migrated.
        from mist.api.methods import ssh_command

        try:
            ssh_port = int(ssh_port)
        except (ValueError, TypeError):
            ssh_port = 22
        try:
            rdp_port = int(rdp_port)
        except (ValueError, TypeError):
            rdp_port = 3389
        if ssh_key:
            ssh_key = Key.objects.get(owner=self.cloud.owner, id=ssh_key,
                                      deleted=None)

        from mist.api.machines.models import Machine
        # Create and save machine entry to database.
        machine = Machine(
            cloud=self.cloud,
            name=name,
            machine_id=uuid.uuid4().hex,
            os_type=os_type,
            ssh_port=ssh_port,
            rdp_port=rdp_port,
            last_seen=datetime.datetime.utcnow()
        )
        if host:
            # Sanitize inputs.
            host = sanitize_host(host)
            check_host(host)
            machine.hostname = host

            if is_private_subnet(socket.gethostbyname(host)):
                machine.private_ips = [host]
            else:
                machine.public_ips = [host]
        machine.save(write_concern={'w': 1, 'fsync': True})

        # Attempt to connect.
        if os_type == 'unix' and ssh_key:
            if not ssh_user:
                ssh_user = '******'
            # Try to connect. If it works, it will create the association.
            try:
                if not host:
                    raise BadRequestError("You have specified an SSH key but "
                                          "machine hostname is empty.")
                to_tunnel(self.cloud.owner, host)  # May raise VPNTunnelError
                ssh_command(
                    self.cloud.owner, self.cloud.id, machine.id, host,
                    'uptime', key_id=ssh_key.id, username=ssh_user,
                    port=ssh_port
                )
            except MachineUnauthorizedError as exc:
                if fail_on_error:
                    machine.delete()
                raise CloudUnauthorizedError(exc)
            except ServiceUnavailableError as exc:
                if fail_on_error:
                    machine.delete()
                raise MistError("Couldn't connect to host '%s'." % host)
            except:
                if fail_on_error:
                    machine.delete()
                raise

        if amqp_owner_listening(self.cloud.owner.id):
            new_machines = self.cloud.ctl.compute.list_cached_machines()
            self.cloud.ctl.compute.produce_and_publish_patch(
                old_machines, new_machines)

        return machine