Example #1
0
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
Example #4
0
    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