def new_system_user(user_full_name, username, raw_password, joomla_password, access_level, email, project_group, organisation, approved_by, created_by, massive_account, vm_id, vm_ip): """ Create a new user (in Joomla) *and* add them to a given VM. FIXME Is there no way to create a user without assigning them to a VM? """ # Create an SSH keypair for the new user. temp_dir = tempfile.mkdtemp() private_key_filename = username public_key_filename = username + '.pub' private_key_path = os.path.join(temp_dir, private_key_filename) public_key_path = os.path.join(temp_dir, public_key_filename) exit_code, stdout, stderr = run_shell_command("ssh-keygen -f {private_key_path} -N ''".format(private_key_path=private_key_path)) private_key = b64encode(open(private_key_path, 'r').read()) public_key = b64encode(open(public_key_path, 'r').read()) os.remove(private_key_path) os.remove(public_key_path) if access_level == enums.UserAccess.Administrator: group_access_id = Cvl_usergroups.select(sqlobject.AND(Cvl_usergroups.q.title=='Administrator', Cvl_usergroups.q.parentID==2)).getOne().id # FIXME magic value 2? else: group_access_id = Cvl_usergroups.select(sqlobject.AND(Cvl_usergroups.q.title=='User', Cvl_usergroups.q.parentID==2)).getOne().id # FIXME magic value 2? encrypted_unix_password = crypt.crypt(raw_password, 'CvlEncryption') driver_id = 0 # FIXME this is not supported activation = '0' send_email = 0 register_date = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') logging.debug('Create VM user account .....') # FIXME Is OperationState used? # FIXME all public and private keys have the same name - this is ok? user_record, user_vm_record, user_group_map_record = cvlsql.sql_add_user(user_full_name, username, joomla_password, email, enums.OperationState.Idle, public_key, cvl_config.PUBLIC_KEY_NAME, private_key, cvl_config.PRIVATE_KEY_NAME, massive_account, project_group, group_access_id, approved_by, created_by, driver_id, activation, send_email, register_date, organisation, encrypted_unix_password) # FIXME This ought to be a celery task, otherwise a dead VM will stop the process? cvlfabric.env.hosts = [vm_ip] cvlfabric.execute(cvlfabric.new_user, username=username, password=encrypted_unix_password, public_key=public_key) cvlsql.add_user_to_vm(user_record, Cvl_cvl_vm.select(Cvl_cvl_vm.q.vmIp==vm_ip).getOne()) return user_record.id
def JoinServer(self): user_db = Cvl_users.select(Cvl_users.q.id==self.userId).getOne() user_vm_db = Cvl_cvl_vm_user.select(Cvl_cvl_vm_user.q.id==self.userId).getOne() vm_db = cvlsql.sql_get_vm(self.serverIp) cvlfabric.env.hosts = [self.serverIp] cvlfabric.execute(cvlfabric.new_user, username=user_db.username, password=user_vm_db.vmPassword, public_key=user_vm_db.publicKey) cvlsql.add_user_to_vm(user_db, vm_db) return True
def AddServer(self): #from CvlAddVm import AddVm #process = AddVm(self.path, self.userId, self.serverName, self.nectarId) #if process.run() == False: # logging.error("Failed to add VM " + self.serverName) # return False #return True logging.debug('AddServer: ' + str((self.userId, self.serverName, self.nectarId,))) try: vm_name = self.serverName vm_info = utils.get_vm_info(vm_name) logging.debug('vm_info: ' + str(vm_info)) vm_ip = vm_info['ip'] vm_ram = vm_info['ram'] vm_disk = vm_info['disk'] vm_id = vm_info['id'] vm_vcpus = vm_info['vcpus'] vm_db = cvlsql.sql_add_vm(0, vm_name, vm_id, vm_ip, vm_ram, vm_vcpus, vm_disk, self.projectGroup, self.nectarId) logging.debug('Added vm to database: ' + str(vm_db)) user_db = Cvl_users.select(Cvl_users.q.id==self.userId).getOne() user_vm_db = Cvl_cvl_vm_user.select(Cvl_cvl_vm_user.q.id==self.userId).getOne() logging.debug('username: '******'creating user account <%s> on vm %s' % (user_db.username, vm_ip,)) cvlfabric.env.hosts = [vm_ip] cvlfabric.execute(cvlfabric.new_user, username=user_db.username, password=user_vm_db.vmPassword, public_key=user_vm_db.publicKey) cvlsql.add_user_to_vm(user_db, vm_db) return True except: logging.debug('error adding unmanaged VM to system: ' + traceback.format_exc()) return False
def run(self, vm_name, username, email, cpu, user_id, path, project_group, nectar_id): """ The main task. Everything happens here, from booting the VM, creating user accounts, adding database records, and installing the CVL packages. """ params = (vm_name, username, email, cpu, user_id, path, project_group, nectar_id) self.email = email self.username = username self.vm_name = vm_name self.update_state(state="PROGRESS", meta={'params': params, 'info': 'starting up...',}) logging.debug('create_cvl_vm: ' + str((vm_name, username, email, cpu, user_id, path, project_group, nectar_id,))) driver = 0 # FIXME this should be in cvl_config? Somewhere? flavor = nova_client().flavors.find(vcpus=int(cvl_config.VM_CPU[cpu])) password, vm_public_key = get_vm_password_and_key(user_id) logging.debug("Retrieved user's VM password and public key") # We use vm_name as a unique key for the VM, so boot # one if a VM with that name doesn't already exist. self.update_state(state="PROGRESS", meta={'params': params, 'info': 'checking for existing VM',}) try: vm = nova_client().servers.find(name=vm_name) vm_already_exists = True # FIXME need to also check if the ip address matches one already in the database except novaclient.exceptions.NotFound: try: vm = nova_boot(vm_name, driver, flavor.name) vm_already_exists = False except: raise ValueError, 'Failed to run nova_boot: %s' % (traceback.format_exc(),) self.vm = vm if vm_already_exists: raise ValueError, 'Attempt to create VM with name <%s> but a VM already exists with that name' % (vm_name,) # Wait for the server to get an IP. while get_vm_info(vm_name)['ip'] is None: logging.debug('VM has no IP, sleeping...') time.sleep(1) vm_info = get_vm_info(vm_name) logging.debug('VM info: ' + str(vm_info)) vm_ip = vm_info['ip'] vm_ram = vm_info['ram'] vm_disk = vm_info['disk'] vm_id = vm_info['id'] self.vm_db = sql_add_vm(driver, vm_name, vm_id, vm_ip, vm_ram, cpu, vm_disk, project_group, nectar_id) add_user_to_vm(Cvl_users.select(Cvl_users.q.username==username).getOne(), self.vm_db) self.vm_db.state = enums.VmState.Configuration # Wait until we can actually ssh into the server. self.update_state(state="PROGRESS", meta={'params': params, 'info': 'waiting for SSH connection to VM',}) while not can_ssh_to_server(vm_name): logging.debug("Can't ssh to %s:%s, sleeping..." % (vm_name, vm_ip,)) time.sleep(1) cvlfabric.env.hosts = [vm_ip] self.update_state(state="PROGRESS", meta={'params': params, 'info': 'creating user account on VM',}) logging.debug('Creating user account <%s> on the VM %s' % (username, vm_ip,)) try: cvlfabric.execute(cvlfabric.new_user, username=username, password=password, public_key=vm_public_key) self.update_state(state="PROGRESS", meta={'params': params, 'info': 'creating secondary storage on VM',}) logging.debug('Creating secondary storage on the VM') cvlfabric.execute(cvlfabric.create_secondary_storage) self.update_state(state="PROGRESS", meta={'params': params, 'info': 'setting VM hostname',}) logging.debug('Setting VM\'s hostname') cvlfabric.execute(cvlfabric.setup_networking, nice_vm_name=vm_name) self.update_state(state="PROGRESS", meta={'params': params, 'info': 'installing base CVL system',}) logging.debug('Installing base CVL system') cvlfabric.execute(cvlfabric.install_cvl_base) self.update_state(state="PROGRESS", meta={'params': params, 'info': 'installing CVL system (system extension and imaging tools)',}) logging.debug('Installing CVL system (system extension and imaging tools)') cvlfabric.execute(cvlfabric.install_cvl_system) self.update_state(state="PROGRESS", meta={'params': params, 'info': 'installing fail2ban',}) logging.debug('Installing fail2ban') cvlfabric.execute(cvlfabric.install_fail2ban) except: raise ValueError, traceback.format_exc() # avoid SystemExit... self.vm_db.state = enums.VmState.Active return params