def test_distro_overrides_recipe(self): with session.begin(): lc = data_setup.create_labcontroller() system1 = data_setup.create_system(lab_controller=lc, arch=u'x86_64') i386_distro = self._create_i386_distro(lc) osmajor = i386_distro.osversion.osmajor io = OSMajorInstallOptions.lazy_create( osmajor_id=osmajor.id, arch_id=Arch.by_name('i386').id) io.ks_meta = 'lang=en_UK.UTF-8' session.expire(osmajor, ['install_options_by_arch']) recipe = self._create_recipe(system1) distro_tree_id = i386_distro.trees[0].id kickstart = self._run_create_kickstart([ '--recipe-id', str(recipe.id), '--distro-tree-id', str(distro_tree_id), ]) # Make sure we are using the tree from --distro-tree-id self.assertIn( 'url=http://lab.test-kickstart.example.com/distros/' 'RHEL-6.3/Workstation/i386/os/', kickstart) self.assertNotIn( 'url=http://lab.test-kickstart.invalid/distros/' 'RHEL-6.2/Server/x86_64/os/', kickstart) self.assertIn('lang en_UK.UTF-8', kickstart) self.assertNotIn('lang en_US.UTF-8', kickstart)
def test_add_submission_delegate(self): with session.begin(): user = data_setup.create_user(password='******') delegate = data_setup.create_user() client_config = create_client_config(username=user.user_name, password='******') out = run_client(['bkr', 'user-modify', '--add-submission-delegate', delegate.user_name], config=client_config) self.assertTrue('Added submission delegate %s' % delegate.user_name in out, out) session.expire(user) with session.begin(): self.assertEqual(user.submission_delegates, [delegate])
def test_remove_submission_delegate(self): with session.begin(): user = data_setup.create_user(password='******') delegate1 = data_setup.create_user() delegate2 = data_setup.create_user() user.submission_delegates[:] = [delegate1, delegate2] client_config = create_client_config(username=user.user_name, password='******') out = run_client(['bkr', 'user-modify', '--remove-submission-delegate', delegate1.user_name], config=client_config) self.assertTrue('Removed submission delegate %s' % delegate1.user_name in out) session.expire(user) with session.begin(): self.assertEqual(user.submission_delegates, [delegate2])
def test_install_done_preserves_system_resource_fqdn(self): with session.begin(): distro_tree = data_setup.create_distro_tree() recipe = data_setup.create_recipe(distro_tree=distro_tree) system = data_setup.create_system(lab_controller=self.lc) initial_fqdn = system.fqdn data_setup.create_job_for_recipes([recipe]) data_setup.mark_recipe_waiting(recipe, system=system) self.assertEqual(recipe.resource.fqdn, initial_fqdn) result = self.server.recipes.install_done(recipe.id, 'somename') self.assertEqual(result, initial_fqdn) with session.begin(): session.expire(recipe.resource) self.assertEqual(recipe.resource.fqdn, initial_fqdn)
def test_release_action_leaveon(self): with session.begin(): system = data_setup.create_system(status=SystemStatus.manual, shared=True, lab_controller=self.lab_controller) system.release_action = ReleaseAction.leave_on user = data_setup.create_user(password=u'password') system.reserve_manually(service=u'testdata', user=user) server = self.get_server() server.auth.login_password(user.user_name, 'password') server.systems.release(system.fqdn) with session.begin(): session.expire(system) self.assertEquals(system.command_queue[0].action, 'on') self.assertEquals(system.command_queue[1].action, 'clear_netboot')
def add_distro_tree_to_lab(distro_tree, lab_controller, urls=None): if urls is None: urls = [u'%s://%s%s/distros/%s/%s/%s/os/' % (scheme, lab_controller.fqdn, scheme == 'nfs' and ':' or '', distro_tree.distro.name, distro_tree.variant, distro_tree.arch.arch) for scheme in ['nfs', 'http', 'ftp']] # Instead of using the LabControllerDistroTree model like normal, # we hack the rows directly into the database. This is specifically to # avoid firing the mark_systems_pending_when_distro_tree_added_to_lab # event listener, which is not necessary when we are setting up test data, # and can be potentially quite expensive. session.execute(LabControllerDistroTree.__table__.insert().values([ {'distro_tree_id': distro_tree.id, 'lab_controller_id': lab_controller.id, 'url': url} for url in urls])) session.expire(distro_tree, ['lab_controller_assocs'])
def test_install_done_updates_resource_fqdn(self): with session.begin(): distro_tree = data_setup.create_distro_tree() recipe = data_setup.create_recipe(distro_tree=distro_tree) guestrecipe = data_setup.create_guestrecipe( host=recipe, distro_tree=distro_tree) data_setup.create_job_for_recipes([recipe, guestrecipe]) data_setup.mark_recipe_running(recipe) data_setup.mark_recipe_waiting(guestrecipe) fqdn = 'theguestname' result = self.server.recipes.install_done(guestrecipe.id, fqdn) self.assertEqual(result, fqdn) with session.begin(): session.expire(guestrecipe.resource) self.assertEqual(guestrecipe.resource.fqdn, fqdn)
def test_install_done_updates_resource_fqdn(self): with session.begin(): distro_tree = data_setup.create_distro_tree() recipe = data_setup.create_recipe(distro_tree=distro_tree) guestrecipe = data_setup.create_guestrecipe(host=recipe, distro_tree=distro_tree) data_setup.create_job_for_recipes([recipe, guestrecipe]) data_setup.mark_recipe_running(recipe) data_setup.mark_recipe_waiting(guestrecipe) fqdn = 'theguestname' result = self.server.recipes.install_done(guestrecipe.id, fqdn) self.assertEqual(result, fqdn) with session.begin(): session.expire(guestrecipe.resource) self.assertEqual(guestrecipe.resource.fqdn, fqdn)
def test_reprovision_failure(self): with session.begin(): system = data_setup.create_system(status=SystemStatus.manual, shared=True, lab_controller=self.lab_controller) system.release_action = ReleaseAction.reprovision system.reprovision_distro_tree = data_setup.create_distro_tree( osmajor=u'BrokenDistro') user = data_setup.create_user(password=u'password') system.reserve(service=u'testdata', user=user) server = self.get_server() server.auth.login_password(user.user_name, 'password') server.systems.release(system.fqdn) with session.begin(): session.expire(system) self.assertEquals(system.command_queue[0].action, 'clear_netboot') self.assert_(system.user is None, system.user)
def test_can_open_edit_page_for_owned_existing_groups(self): with session.begin(): data_setup.add_owner_to_group(self.user, self.group) b = self.browser login(b, user=self.user.user_name, password='******') b.get(get_server_base() + 'groups/') # not doing a look up using XPATH since, the group may not be on # the first page when run as part of the suite. b.get(get_server_base() + 'groups/edit?group_id=%d' % self.group.group_id) b.find_element_by_xpath('//input[@id="Group_root_password"]').clear() b.find_element_by_xpath('//input[@id="Group_root_password"]'). \ send_keys('blapppy7') b.find_element_by_id('Group').submit() self.assertEquals(b.find_element_by_class_name('flash').text, u'OK') session.expire(self.group) self.assertEquals('blapppy7', self.group.root_password)
def test_reprovision_failure(self): with session.begin(): system = data_setup.create_system(status=SystemStatus.manual, shared=True, lab_controller=self.lab_controller) system.release_action = ReleaseAction.reprovision system.reprovision_distro_tree = data_setup.create_distro_tree( osmajor=u'BrokenDistro') # tree has no URLs so cannot actually be provisioned system.reprovision_distro_tree.lab_controller_assocs[:] = [] user = data_setup.create_user(password=u'password') system.reserve_manually(service=u'testdata', user=user) server = self.get_server() server.auth.login_password(user.user_name, 'password') server.systems.release(system.fqdn) with session.begin(): session.expire(system) self.assertEquals(system.command_queue[0].action, 'clear_netboot') self.assert_(system.user is None, system.user)
def test_release_action_reprovision(self): with session.begin(): system = data_setup.create_system(status=SystemStatus.manual, shared=True, lab_controller=self.lab_controller) system.release_action = ReleaseAction.reprovision system.reprovision_distro_tree = data_setup.create_distro_tree( osmajor=u'Fedora20') user = data_setup.create_user(password=u'password') system.reserve_manually(service=u'testdata', user=user) server = self.get_server() server.auth.login_password(user.user_name, 'password') server.systems.release(system.fqdn) with session.begin(): session.expire(system) self.assertEquals(system.command_queue[0].action, 'on') self.assertEquals(system.command_queue[1].action, 'off') self.assertEquals(system.command_queue[2].action, 'configure_netboot') self.assertEquals(system.command_queue[3].action, 'clear_logs') self.assertEquals(system.command_queue[4].action, 'clear_netboot')
def test_removing_submission_delegate(self): with session.begin(): submission_delegate = data_setup.create_user() self.user.submission_delegates[:] = [submission_delegate] b = self.browser b.get(get_server_base() + 'prefs') delete_and_confirm(b, '//td[preceding-sibling::td/text()="%s"]' % submission_delegate, 'Remove (-)') self.assertEquals(b.find_element_by_class_name('flash').text, '%s removed as a submission delegate' % submission_delegate) # Check they have been removed in DB session.expire(self.user) with session.begin(): self.assertEquals(self.user.submission_delegates, []) activity = self.user.user_activity[-1] self.assertEqual(activity.action, u'Removed') self.assertEqual(activity.field_name, u'Submission delegate') self.assertEqual(activity.user.user_id, self.user.user_id) self.assertEqual(activity.old_value, submission_delegate.user_name) self.assertEqual(activity.new_value, None)
def test_adding_submission_delegate(self): with session.begin(): submission_delegate = data_setup.create_user() b = self.browser delegate_field = b.find_element_by_id('SubmissionDelegates_user_text') delegate_field.send_keys(submission_delegate.user_name) b.find_element_by_id('SubmissionDelegates').submit() self.assertEquals(b.find_element_by_class_name('flash').text, 'Added %s as a submission delegate' % submission_delegate) session.expire(self.user) # Check user has indeed been added, and activity updated with session.begin(): self.assertEqual(self.user.submission_delegates, [submission_delegate]) activity = self.user.user_activity[-1] self.assertEqual(activity.action, u'Added') self.assertEqual(activity.field_name, u'Submission delegate') self.assertEqual(activity.user_id, self.user.user_id) self.assertEqual(activity.new_value, submission_delegate.user_name) self.assertEqual(activity.old_value, None)
def test_removing_submission_delegate(self): with session.begin(): submission_delegate = data_setup.create_user() self.user.submission_delegates[:] = [submission_delegate] b = self.browser pane = self.go_to_prefs_tab(tab='Submission Delegates') pane.find_element_by_xpath('//li[a/text()="%s"]' '/button[contains(text(), "Remove")]' % submission_delegate.user_name).click() b.find_element_by_xpath('//div[@id="submission-delegates" and not(.//ul/li)]') # Check they have been removed in DB session.expire(self.user) with session.begin(): self.assertEquals(self.user.submission_delegates, []) activity = self.user.user_activity[-1] self.assertEqual(activity.action, u'Removed') self.assertEqual(activity.field_name, u'Submission delegate') self.assertEqual(activity.user.user_id, self.user.user_id) self.assertEqual(activity.old_value, submission_delegate.user_name) self.assertEqual(activity.new_value, None)
def test_removing_submission_delegate(self): with session.begin(): submission_delegate = data_setup.create_user() self.user.submission_delegates[:] = [submission_delegate] b = self.browser pane = self.go_to_prefs_tab(tab='Submission Delegates') pane.find_element_by_xpath('//li[a/text()="%s"]' '/button[contains(text(), "Remove")]' % submission_delegate.user_name).click() b.find_element_by_xpath( '//div[@id="submission-delegates" and not(.//ul/li)]') # Check they have been removed in DB session.expire(self.user) with session.begin(): self.assertEquals(self.user.submission_delegates, []) activity = self.user.user_activity[-1] self.assertEqual(activity.action, u'Removed') self.assertEqual(activity.field_name, u'Submission delegate') self.assertEqual(activity.user.user_id, self.user.user_id) self.assertEqual(activity.old_value, submission_delegate.user_name) self.assertEqual(activity.new_value, None)
def test_adding_submission_delegate(self): with session.begin(): submission_delegate = data_setup.create_user() b = self.browser delegate_field = b.find_element_by_id('SubmissionDelegates_user_text') delegate_field.send_keys(submission_delegate.user_name) b.find_element_by_id('SubmissionDelegates').submit() self.assertEquals( b.find_element_by_class_name('flash').text, 'Added %s as a submission delegate' % submission_delegate) session.expire(self.user) # Check user has indeed been added, and activity updated with session.begin(): self.assertEqual(self.user.submission_delegates, [submission_delegate]) activity = self.user.user_activity[-1] self.assertEqual(activity.action, u'Added') self.assertEqual(activity.field_name, u'Submission delegate') self.assertEqual(activity.user_id, self.user.user_id) self.assertEqual(activity.new_value, submission_delegate.user_name) self.assertEqual(activity.old_value, None)
def test_removing_submission_delegate(self): with session.begin(): submission_delegate = data_setup.create_user() self.user.submission_delegates[:] = [submission_delegate] b = self.browser b.get(get_server_base() + 'prefs') delete_and_confirm( b, '//td[preceding-sibling::td/text()="%s"]' % submission_delegate, 'Remove (-)') self.assertEquals( b.find_element_by_class_name('flash').text, '%s removed as a submission delegate' % submission_delegate) # Check they have been removed in DB session.expire(self.user) with session.begin(): self.assertEquals(self.user.submission_delegates, []) activity = self.user.user_activity[-1] self.assertEqual(activity.action, u'Removed') self.assertEqual(activity.field_name, u'Submission delegate') self.assertEqual(activity.user.user_id, self.user.user_id) self.assertEqual(activity.old_value, submission_delegate.user_name) self.assertEqual(activity.new_value, None)
def test_distro_overrides_recipe(self): with session.begin(): lc = data_setup.create_labcontroller() system1 = data_setup.create_system(lab_controller=lc, arch=u'x86_64') i386_distro = self._create_i386_distro(lc) osmajor = i386_distro.osversion.osmajor io = OSMajorInstallOptions.lazy_create(osmajor_id=osmajor.id, arch_id=Arch.by_name('i386').id) io.ks_meta = 'lang=en_UK.UTF-8' session.expire(osmajor, ['install_options_by_arch']) recipe = self._create_recipe(system1) distro_tree_id = i386_distro.trees[0].id kickstart = self._run_create_kickstart(['--recipe-id', str(recipe.id), '--distro-tree-id', str(distro_tree_id),]) # Make sure we are using the tree from --distro-tree-id self.assertIn('url=http://lab.test-kickstart.example.com/distros/' 'RHEL-6.3/Workstation/i386/os/', kickstart) self.assertNotIn('url=http://lab.test-kickstart.invalid/distros/' 'RHEL-6.2/Server/x86_64/os/', kickstart) self.assertIn('lang en_UK.UTF-8', kickstart) self.assertNotIn('lang en_US.UTF-8', kickstart)
def test_group_modify_password(self): # Test successful hashed password change hashed_password = '******' run_client([ 'bkr', 'group-modify', '--root-password', hashed_password, self.group.group_name ], config=self.client_config) session.expire(self.group) with session.begin(): group = self.group self.assertEquals(group.root_password, hashed_password) self.assertEquals(group.activity[-1].action, u'Changed') self.assertEquals(group.activity[-1].field_name, u'Root Password') self.assertEquals(group.activity[-1].user.user_id, self.user.user_id) self.assertEquals(group.activity[-1].service, u'HTTP') # Test successful cleartext password change good_password = data_setup.unique_name('Borrow or %srob?') run_client([ 'bkr', 'group-modify', '--root-password', good_password, self.group.group_name ], config=self.client_config) session.expire(self.group) with session.begin(): group = self.group self.assertEquals(group.root_password, good_password) self.assertEquals(group.activity[-1].action, u'Changed') self.assertEquals(group.activity[-1].field_name, u'Root Password') self.assertEquals(group.activity[-1].user.user_id, self.user.user_id) self.assertEquals(group.activity[-1].service, u'HTTP') # Test unsuccessful cleartext password change short_password = '******' try: run_client([ 'bkr', 'group-modify', '--root-password', short_password, self.group.group_name ], config=self.client_config) self.fail('Should fail with short password') except ClientError, e: self.assertTrue('password is too short' in str(e)) session.expire(self.group) with session.begin(): group = self.group self.assertEquals(group.root_password, good_password)
def test_group_modify_password(self): # Test successful hashed password change hashed_password = '******' run_client(['bkr', 'group-modify', '--root-password', hashed_password, self.group.group_name], config=self.client_config) session.expire(self.group) with session.begin(): group = self.group self.assertEquals(group.root_password, hashed_password) self.assertEquals(group.activity[-1].action, u'Changed') self.assertEquals(group.activity[-1].field_name, u'Root Password') self.assertEquals(group.activity[-1].user.user_id, self.user.user_id) self.assertEquals(group.activity[-1].service, u'HTTP') # Test successful cleartext password change good_password = data_setup.unique_name('Borrow or %srob?') run_client(['bkr', 'group-modify', '--root-password', good_password, self.group.group_name], config=self.client_config) session.expire(self.group) with session.begin(): group = self.group self.assertEquals(group.root_password, good_password) self.assertEquals(group.activity[-1].action, u'Changed') self.assertEquals(group.activity[-1].field_name, u'Root Password') self.assertEquals(group.activity[-1].user.user_id, self.user.user_id) self.assertEquals(group.activity[-1].service, u'HTTP') # Test unsuccessful cleartext password change short_password = '******' try: run_client(['bkr', 'group-modify', '--root-password', short_password, self.group.group_name], config=self.client_config) self.fail('Should fail with short password') except ClientError as e: # Number of req chars was changed in RPM, however RHEL is using older one # RHEL requires 7, Fedora requires 8 at this moment self.assertTrue( re.search('The group root password is shorter than . characters', str(e))) session.expire(self.group) with session.begin(): group = self.group self.assertEquals(group.root_password, good_password)
def test_group_modify_password(self): # Test successful hashed password change hashed_password = '******' run_client(['bkr', 'group-modify', '--root-password', hashed_password, self.group.group_name], config=self.client_config) session.expire(self.group) with session.begin(): group = self.group self.assertEquals(group.root_password, hashed_password) self.assertEquals(group.activity[-1].action, u'Changed') self.assertEquals(group.activity[-1].field_name, u'Root Password') self.assertEquals(group.activity[-1].user.user_id, self.user.user_id) self.assertEquals(group.activity[-1].service, u'XMLRPC') # Test successful cleartext password change good_password = data_setup.unique_name('Borrow or %srob?') run_client(['bkr', 'group-modify', '--root-password', good_password, self.group.group_name], config=self.client_config) session.expire(self.group) with session.begin(): group = self.group self.assertEquals(group.root_password, crypt.crypt(good_password, group.root_password)) self.assertEquals(group.activity[-1].action, u'Changed') self.assertEquals(group.activity[-1].field_name, u'Root Password') self.assertEquals(group.activity[-1].user.user_id, self.user.user_id) self.assertEquals(group.activity[-1].service, u'XMLRPC') # Test unsuccessful cleartext password change short_password = '******' try: run_client(['bkr', 'group-modify', '--root-password', short_password, self.group.group_name], config=self.client_config) self.fail('Should fail with short password') except ClientError, e: self.assertTrue('password is too short' in str(e)) session.expire(self.group) with session.begin(): group = self.group self.assertEquals(group.root_password, crypt. \ crypt(good_password, group.root_password))
def action_import(self, csv_file, *args, **kw): """ TurboGears method to import data from csv """ log = [] try: # ... process CSV file contents here ... missing = object() reader = csv.DictReader(csv_file.file, restkey=missing, restval=missing) for data in reader: if missing in data: log.append('Too many fields on line %s (expecting %s)' % (reader.line_num, len(reader.fieldnames))) continue if any(value is missing for value in data.itervalues()): missing_fields = [field for field, value in data.iteritems() if value is missing] log.append('Missing fields on line %s: %s' % (reader.line_num, ', '.join(missing_fields))) continue if 'csv_type' in data: if data['csv_type'] in system_types and \ 'fqdn' in data: try: system = System.query.filter(System.fqdn == data['fqdn']).one() except InvalidRequestError: # Create new system with some defaults # Assume the system is broken until proven otherwise. # Also assumes its a machine. we have to pick something system = System(fqdn=data['fqdn'], owner=identity.current.user, type=SystemType.machine, status=SystemStatus.broken) if system.can_admin(identity.current.user): # Remove fqdn, can't change that via csv. data.pop('fqdn') if not self.from_csv(system, data, log): if system.id: # System already existed but some or all of the # import data was invalid. session.expire(system) else: # System didn't exist before import but some # or all of the import data was invalid. session.expunge(system) del(system) else: # Save out our system. If we created it above we # want to make sure its found on subsequent lookups session.add(system) session.flush([system]) else: log.append("You are not the owner of %s" % system.fqdn) elif data['csv_type'] == 'user_group' and \ 'user' in data: user = User.by_user_name(data['user']) if user: CSV_GroupUser.from_csv(user, data, log) else: log.append('%s is not a valid user' % data['user']) else: log.append("Invalid csv_type %s or missing required fields" % data['csv_type']) else: log.append("Missing csv_type from record") except csv.Error, e: session.rollback() log.append('Error parsing CSV file: %s' % e)
def action_import(self, csv_file, *args, **kw): """ TurboGears method to import data from csv """ log = [] try: # ... process CSV file contents here ... missing = object() reader = csv.DictReader(csv_file.file, restkey=missing, restval=missing) for data in reader: if missing in data: log.append('Too many fields on line %s (expecting %s)' % (reader.line_num, len(reader.fieldnames))) continue if any(value is missing for value in data.itervalues()): missing_fields = [field for field, value in data.iteritems() if value is missing] log.append('Missing fields on line %s: %s' % (reader.line_num, ', '.join(missing_fields))) continue if 'csv_type' in data: if data['csv_type'] in system_types and ('fqdn' in data or 'id' in data): if data.get('id', None): try: system = System.query.filter(System.id == data['id']).one() except InvalidRequestError as e: log.append('Error importing system on line %s: Non-existent system id' % reader.line_num) continue else: try: system = System.query.filter(System.fqdn == data['fqdn']).one() except InvalidRequestError: # Create new system with some defaults # Assume the system is broken until proven otherwise. # Also assumes its a machine. we have to pick something try: system = System(fqdn=data['fqdn'], owner=identity.current.user, type=SystemType.machine, status=SystemStatus.broken) session.add(system) except ValueError as e: log.append('Error importing system on line %s: %s' % (reader.line_num, str(e))) continue # new systems are visible to everybody by default system.custom_access_policy = SystemAccessPolicy() system.custom_access_policy.add_rule( SystemPermission.view, everybody=True) if system.can_edit(identity.current.user): # we change the FQDN only when a valid system id is supplied if not data.get('id', None): data.pop('fqdn') try: self.from_csv(system, data, log) except ValueError as e: log.append('Error importing system on line %s: %s' % (reader.line_num, str(e))) if system.id: # System already existed but some or all of the # import data was invalid. session.expire(system) else: # System didn't exist before import but some # or all of the import data was invalid. session.expunge(system) del(system) else: session.add(system) session.flush() else: log.append("You are not the owner of %s" % system.fqdn) elif data['csv_type'] == 'user_group' and \ 'user' in data: user = User.by_user_name(data['user']) if user: CSV_GroupUser.from_csv(user, data, log) else: log.append('%s is not a valid user' % data['user']) else: log.append("Invalid csv_type %s or missing required fields" % data['csv_type']) else: log.append("Missing csv_type from record") except csv.Error, e: session.rollback() log.append('Error parsing CSV file: %s' % e)
def cleanup_system(self, system): with session.begin(): session.expire(system) system.status = SystemStatus.removed system.lab_controller = None