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