Exemplo n.º 1
0
def toggle_backend(request):
    backend_id = request.matchdict['backend']
    new_state = request.json_body.get('new_state', '')
    if not new_state:
        raise RequiredParameterMissingError('new_state')

    if new_state != "1" and new_state != "0":
        raise BadRequestError('Invalid backend state')

    user = user_from_request(request)
    if backend_id not in user.backends:
        raise BackendNotFoundError()
    with user.lock_n_load():
        user.backends[backend_id].enabled = bool(int(new_state))
        user.save()
    trigger_session_update(user.email, ['backends'])
    return OK
Exemplo n.º 2
0
def toggle_backend(request):
    backend_id = request.matchdict['backend']
    new_state = request.json_body.get('new_state', '')
    if not new_state:
        raise RequiredParameterMissingError('new_state')

    if new_state != "1" and new_state != "0":
        raise BadRequestError('Invalid backend state')

    user = user_from_request(request)
    if backend_id not in user.backends:
        raise BackendNotFoundError()
    with user.lock_n_load():
        user.backends[backend_id].enabled = bool(int(new_state))
        user.save()
    trigger_session_update(user.email, ['backends'])
    return OK
Exemplo n.º 3
0
def delete_rule(request):
    """Deletes a rule.

    """
    user = user_from_request(request)
    try:
        ret = requests.delete(config.CORE_URI + request.path,
                              headers={'Authorization': get_auth_header(user)},
                              verify=config.SSL_VERIFY)
    except requests.exceptions.SSLError as exc:
        log.error("%r", exc)
        raise SSLError()
    if ret.status_code != 200:
        log.error("Error deleting rule %d:%s", ret.status_code, ret.text)
        raise ServiceUnavailableError()
    trigger_session_update(user.email, ['monitoring'])
    return OK
Exemplo n.º 4
0
def toggle_cloud(request):
    cloud_id = request.matchdict['cloud']
    params = params_from_request(request)
    new_state = params.get('new_state', '')
    if not new_state:
        raise RequiredParameterMissingError('new_state')

    if new_state != "1" and new_state != "0":
        raise BadRequestError('Invalid cloud state')

    user = user_from_request(request)
    if cloud_id not in user.clouds:
        raise CloudNotFoundError()
    with user.lock_n_load():
        user.clouds[cloud_id].enabled = bool(int(new_state))
        user.save()
    trigger_session_update(user.email, ['clouds'])
    return OK
Exemplo n.º 5
0
def toggle_cloud(request):
    cloud_id = request.matchdict['cloud']
    params = params_from_request(request)
    new_state = params.get('new_state', '')
    if not new_state:
        raise RequiredParameterMissingError('new_state')

    if new_state != "1" and new_state != "0":
        raise BadRequestError('Invalid cloud state')

    user = user_from_request(request)
    if cloud_id not in user.clouds:
        raise CloudNotFoundError()
    with user.lock_n_load():
        user.clouds[cloud_id].enabled = bool(int(new_state))
        user.save()
    trigger_session_update(user.email, ['clouds'])
    return OK
Exemplo n.º 6
0
def delete_rule(request):
    """Deletes a rule.

    """
    user = user_from_request(request)
    try:
        ret = requests.delete(
            config.CORE_URI + request.path,
            headers={'Authorization': get_auth_header(user)},
            verify=config.SSL_VERIFY
        )
    except requests.exceptions.SSLError as exc:
        log.error("%r", exc)
        raise SSLError()
    if ret.status_code != 200:
        log.error("Error deleting rule %d:%s", ret.status_code, ret.text)
        raise ServiceUnavailableError()
    trigger_session_update(user.email, ['monitoring'])
    return OK
Exemplo n.º 7
0
    def autoconfigure(self, user, cloud_id, machine_id,
                      key_id=None, username=None, password=None, port=22):
        """Autoconfigure SSH client.

        This will do its best effort to find a suitable keypair and username
        and will try to connect. If it fails it raises
        MachineUnauthorizedError, otherwise it initializes self and returns a
        (key_id, ssh_user) tupple. If connection succeeds, it updates the
        association information in the key with the current timestamp and the
        username used to connect.

        """

        log.info("autoconfiguring Shell for machine %s:%s",
                 cloud_id, machine_id)
        if cloud_id not in user.clouds:
            raise CloudNotFoundError(cloud_id)
        if key_id and key_id not in user.keypairs:
            raise KeypairNotFoundError(key_id)

        # get candidate keypairs if key_id not provided
        keypairs = user.keypairs
        if key_id:
            pref_keys = [key_id]
        else:
            default_keys = [key_id for key_id in keypairs
                            if keypairs[key_id].default]
            assoc_keys = []
            recent_keys = []
            root_keys = []
            sudo_keys = []
            for key_id in keypairs:
                for machine in keypairs[key_id].machines:
                    if [cloud_id, machine_id] == machine[:2]:
                        assoc_keys.append(key_id)
                        if len(machine) > 2 and \
                                int(time() - machine[2]) < 7*24*3600:
                            recent_keys.append(key_id)
                        if len(machine) > 3 and machine[3] == 'root':
                            root_keys.append(key_id)
                        if len(machine) > 4 and machine[4] is True:
                            sudo_keys.append(key_id)
            pref_keys = root_keys or sudo_keys or assoc_keys
            if default_keys and default_keys[0] not in pref_keys:
                pref_keys.append(default_keys[0])

        # try to connect
        for key_id in pref_keys:
            keypair = user.keypairs[key_id]

            # find username
            users = []
            # if username was specified, then try only that
            if username:
                users = [username]
            else:
                for machine in keypair.machines:
                    if machine[:2] == [cloud_id, machine_id]:
                        if len(machine) >= 4 and machine[3]:
                            users.append(machine[3])
                            break
                # if username not found, try several alternatives
                # check to see if some other key is associated with machine
                for other_keypair in user.keypairs.values():
                    for machine in other_keypair.machines:
                        if machine[:2] == [cloud_id, machine_id]:
                            if len(machine) >= 4 and machine[3]:
                                ssh_user = machine[3]
                                if ssh_user not in users:
                                    users.append(ssh_user)
                            if len(machine) >= 6 and machine[5]:
                                port = machine[5]
                # check some common default names
                for name in ['root', 'ubuntu', 'ec2-user', 'user', 'azureuser', 'core']:
                    if name not in users:
                        users.append(name)
            for ssh_user in users:
                try:
                    log.info("ssh -i %s %s@%s:%s",
                             key_id, ssh_user, self.host, port)
                    self.connect(username=ssh_user,
                                 key=keypair.private,
                                 password=password,
                                 port=port)
                except MachineUnauthorizedError:
                    continue
                # this is a hack: if you try to login to ec2 with the wrong
                # username, it won't fail the connection, so a
                # MachineUnauthorizedException won't be raised. Instead, it
                # will prompt you to login as some other user.
                # This hack tries to identify when such a thing is happening
                # and then tries to connect with the username suggested in
                # the prompt.
                retval, resp = self.command('uptime')
                new_ssh_user = None
                if 'Please login as the user ' in resp:
                    new_ssh_user = resp.split()[5].strip('"')
                elif 'Please login as the' in resp:
                    # for EC2 Amazon Linux machines, usually with ec2-user
                    new_ssh_user = resp.split()[4].strip('"')
                if new_ssh_user:
                    log.info("retrying as %s", new_ssh_user)
                    try:
                        self.disconnect()
                        self.connect(username=new_ssh_user,
                                     key=keypair.private,
                                     password=password,
                                     port=port)
                        ssh_user = new_ssh_user
                    except MachineUnauthorizedError:
                        continue
                # we managed to connect succesfully, return
                # but first update key
                assoc = [cloud_id,
                         machine_id,
                         time(),
                         ssh_user,
                         self.check_sudo(),
                         port]
                trigger_session_update_flag = False
                for i in range(3):
                    try:
                        with user.lock_n_load():
                            updated = False
                            for i in range(len(user.keypairs[key_id].machines)):
                                machine = user.keypairs[key_id].machines[i]
                                if [cloud_id, machine_id] == machine[:2]:
                                    old_assoc = user.keypairs[key_id].machines[i]
                                    user.keypairs[key_id].machines[i] = assoc
                                    updated = True
                                    old_ssh_user = None
                                    old_port = None
                                    if len(old_assoc) > 3:
                                        old_ssh_user = old_assoc[3]
                                    if len(old_assoc) > 5:
                                        old_port = old_assoc[5]
                                    if old_ssh_user != ssh_user or old_port != port:
                                        trigger_session_update_flag = True
                            # if association didn't exist, create it!
                            if not updated:
                                user.keypairs[key_id].machines.append(assoc)
                                trigger_session_update_flag = True
                            user.save()
                    except:
                        if i == 2:
                            log.error('RACE CONDITION: shell failed to recover from previous race conditions')
                            raise
                        else:
                            log.error('RACE CONDITION: shell trying to recover from race condition')
                    else:
                        break
                if trigger_session_update_flag:
                    trigger_session_update(user.email, ['keys'])
                return key_id, ssh_user

        raise MachineUnauthorizedError("%s:%s" % (cloud_id, machine_id))
Exemplo n.º 8
0
    def autoconfigure(self, user, backend_id, machine_id,
                      key_id=None, username=None, password=None, port=22):
        """Autoconfigure SSH client.

        This will do its best effort to find a suitable keypair and username
        and will try to connect. If it fails it raises
        MachineUnauthorizedError, otherwise it initializes self and returns a
        (key_id, ssh_user) tupple. If connection succeeds, it updates the
        association information in the key with the current timestamp and the
        username used to connect.

        """

        log.info("autoconfiguring Shell for machine %s:%s",
                 backend_id, machine_id)
        if backend_id not in user.backends:
            raise BackendNotFoundError(backend_id)
        if key_id and key_id not in user.keypairs:
            raise KeypairNotFoundError(key_id)

        # get candidate keypairs if key_id not provided
        keypairs = user.keypairs
        if key_id:
            pref_keys = [key_id]
        else:
            default_keys = [key_id for key_id in keypairs
                            if keypairs[key_id].default]
            assoc_keys = []
            recent_keys = []
            root_keys = []
            sudo_keys = []
            for key_id in keypairs:
                for machine in keypairs[key_id].machines:
                    if [backend_id, machine_id] == machine[:2]:
                        assoc_keys.append(key_id)
                        if len(machine) > 2 and \
                                int(time() - machine[2]) < 7*24*3600:
                            recent_keys.append(key_id)
                        if len(machine) > 3 and machine[3] == 'root':
                            root_keys.append(key_id)
                        if len(machine) > 4 and machine[4] is True:
                            sudo_keys.append(key_id)
            pref_keys = root_keys or sudo_keys or assoc_keys
            if default_keys and default_keys[0] not in pref_keys:
                pref_keys.append(default_keys[0])

        # try to connect
        for key_id in pref_keys:
            keypair = user.keypairs[key_id]

            # find username
            users = []
            # if username was specified, then try only that
            if username:
                users = [username]
            else:
                for machine in keypair.machines:
                    if machine[:2] == [backend_id, machine_id]:
                        if len(machine) >= 4 and machine[3]:
                            users.append(machine[3])
                            break
                # if username not found, try several alternatives
                # check to see if some other key is associated with machine
                for other_keypair in user.keypairs.values():
                    for machine in other_keypair.machines:
                        if machine[:2] == [backend_id, machine_id]:
                            if len(machine) >= 4 and machine[3]:
                                ssh_user = machine[3]
                                if ssh_user not in users:
                                    users.append(ssh_user)
                            if len(machine) >= 6 and machine[5]:
                                port = machine[5]
                # check some common default names
                for name in ['root', 'ubuntu', 'ec2-user', 'user', 'azureuser']:
                    if name not in users:
                        users.append(name)
            for ssh_user in users:
                try:
                    log.info("ssh -i %s %s@%s:%s",
                             key_id, ssh_user, self.host, port)
                    self.connect(username=ssh_user,
                                 key=keypair.private,
                                 password=password,
                                 port=port)
                except MachineUnauthorizedError:
                    continue
                # this is a hack: if you try to login to ec2 with the wrong
                # username, it won't fail the connection, so a
                # MachineUnauthorizedException won't be raised. Instead, it
                # will prompt you to login as some other user.
                # This hack tries to identify when such a thing is happening
                # and then tries to connect with the username suggested in
                # the prompt.
                retval, resp = self.command('uptime')
                new_ssh_user = None
                if 'Please login as the user ' in resp:
                    new_ssh_user = resp.split()[5].strip('"')
                elif 'Please login as the' in resp:
                    # for EC2 Amazon Linux machines, usually with ec2-user
                    new_ssh_user = resp.split()[4].strip('"')
                if new_ssh_user:
                    log.info("retrying as %s", new_ssh_user)
                    try:
                        self.disconnect()
                        self.connect(username=new_ssh_user,
                                     key=keypair.private,
                                     password=password,
                                     port=port)
                        ssh_user = new_ssh_user
                    except MachineUnauthorizedError:
                        continue
                # we managed to connect succesfully, return
                # but first update key
                assoc = [backend_id,
                         machine_id,
                         time(),
                         ssh_user,
                         self.check_sudo(),
                         port]
                trigger_session_update_flag = False
                with user.lock_n_load():
                    updated = False
                    for i in range(len(user.keypairs[key_id].machines)):
                        machine = user.keypairs[key_id].machines[i]
                        if [backend_id, machine_id] == machine[:2]:
                            old_assoc = user.keypairs[key_id].machines[i]
                            user.keypairs[key_id].machines[i] = assoc
                            updated = True
                            old_ssh_user = None
                            old_port = None
                            if len(old_assoc) > 3:
                                old_ssh_user = old_assoc[3]
                            if len(old_assoc) > 5:
                                old_port = old_assoc[5]
                            if old_ssh_user != ssh_user or old_port != port:
                                trigger_session_update_flag = True
                    # if association didn't exist, create it!
                    if not updated:
                        user.keypairs[key_id].machines.append(assoc)
                        trigger_session_update_flag = True
                    user.save()
                if trigger_session_update_flag:
                    trigger_session_update(user.email, ['keys'])
                return key_id, ssh_user

        raise MachineUnauthorizedError("%s:%s" % (backend_id, machine_id))