def _try_autocreate(user_name): """ If the necessary WSGI environment variables are populated, automatically creates a new Beaker user account based on their values and returns it. Otherwise returns None. """ from bkr.server.model import session, User if not flask.request.environ.get('REMOTE_USER_FULLNAME'): log.debug( 'User autocreation attempted for %r but ' 'REMOTE_USER_FULLNAME env var was not populated', user_name) return if not flask.request.environ.get('REMOTE_USER_EMAIL'): log.debug( 'User autocreation attempted for %r but ' 'REMOTE_USER_EMAIL env var was not populated', user_name) return user = User() user.user_name = user_name.decode('utf8') user.display_name = flask.request.environ['REMOTE_USER_FULLNAME'].decode( 'utf8') user.email_address = flask.request.environ['REMOTE_USER_EMAIL'].decode( 'utf8') session.add(user) session.flush() log.debug('Autocreated user %s', user) return user
def _try_autocreate(user_name): """ If the necessary WSGI environment variables are populated, automatically creates a new Beaker user account based on their values and returns it. Otherwise returns None. """ from bkr.server.model import session, User if not flask.request.environ.get('REMOTE_USER_FULLNAME'): log.debug('User autocreation attempted for %r but ' 'REMOTE_USER_FULLNAME env var was not populated', user_name) return if not flask.request.environ.get('REMOTE_USER_EMAIL'): log.debug('User autocreation attempted for %r but ' 'REMOTE_USER_EMAIL env var was not populated', user_name) return user = User() user.user_name = user_name.decode('utf8') user.display_name = flask.request.environ['REMOTE_USER_FULLNAME'].decode('utf8') user.email_address = flask.request.environ['REMOTE_USER_EMAIL'].decode('utf8') session.add(user) session.flush() log.debug('Autocreated user %s', user) return user
def setUp(self): with session.begin(): self.lc = data_setup.create_labcontroller() self.lc.user.password = u'logmein' job = data_setup.create_job() self.recipe = job.recipesets[0].recipes[0] session.flush() self.recipe.logs = [] self.server = self.get_server()
def check_filter(self, filterxml, present=[], absent=[]): session.flush() query = XmlHost.from_string(filterxml).apply_filter(System.query) if present: self.assertItemsEqual(present, query.filter(System.id.in_([s.id for s in present])).all()) if absent: self.assertItemsEqual([], query.filter(System.id.in_([s.id for s in absent])).all())
def setUp(self): with session.begin(): self.user = data_setup.create_user(password="******") self.system = data_setup.create_system() self.group = data_setup.create_group() self.user.groups.append(self.group) self.system.groups.append(self.group) self.rand_group = data_setup.create_group(group_name=data_setup.unique_name(u"aardvark%s")) session.flush() self.browser = self.get_browser()
def setUp(self): with session.begin(): self.user = data_setup.create_user(password='******') self.system = data_setup.create_system() self.group = data_setup.create_group() self.user.groups.append(self.group) self.rand_group = data_setup.create_group \ (group_name=data_setup.unique_name(u'aardvark%s')) session.flush() self.browser = self.get_browser()
def test_token_is_ignored_if_proxy_does_not_exist(self): # As above, this should never actually happen. user = data_setup.create_user() proxy = data_setup.create_user() cookie = self.acquire_cookie(user, proxy) session.delete(proxy) session.flush() with app.test_request_context(headers={'Cookie': cookie}): identity.check_authentication() self.assertIsNone(identity.current.user) self.assertIsNone(identity.current.proxied_by_user)
def test_token_is_ignored_if_user_does_not_exist(self): # This should be impossible since we don't allow deleting User objects. # But let's test it for completeness' sake. user = data_setup.create_user() cookie = self.acquire_cookie(user) session.delete(user) session.flush() with app.test_request_context(headers={'Cookie': cookie}): identity.check_authentication() self.assertIsNone(identity.current.user) self.assertIsNone(identity.current.proxied_by_user)
def test_delete_non_existing_pool(self): with session.begin(): pool = data_setup.create_system_pool() b = self.browser login(b) self.go_to_pool_edit(pool) session.delete(pool) session.flush() b.find_element_by_xpath('//button[contains(string(.), "Delete")]').click() modal = b.find_element_by_class_name('modal') modal.find_element_by_xpath('.//p[text()="Are you sure you want to ' 'delete this pool?"]') modal.find_element_by_xpath('.//button[text()="OK"]').click() self.assertIn('System pool %s does not exist' % pool.name, b.find_element_by_class_name('alert-error').text)
def test_delete_non_existing_pool(self): with session.begin(): pool = data_setup.create_system_pool() b = self.browser login(b) self.go_to_pool_edit(pool) session.delete(pool) session.flush() b.find_element_by_xpath( '//button[contains(string(.), "Delete")]').click() modal = b.find_element_by_class_name('modal') modal.find_element_by_xpath('.//p[text()="Are you sure you want to ' 'delete this pool?"]') modal.find_element_by_xpath('.//button[text()="OK"]').click() self.assertIn('System pool %s does not exist' % pool.name, b.find_element_by_class_name('alert-error').text)
def post_recipeset_comment(id): """ Adds a new comment to a recipe set. The request must be :mimetype:`application/json`. :param id: ID of the recipe set. :jsonparam string comment: Comment text. """ recipeset = _get_rs_by_id(id) if not recipeset.can_comment(identity.current.user): raise Forbidden403('Cannot post recipe set comment') data = read_json_request(request) if 'comment' not in data: raise BadRequest400('Missing "comment" key') with convert_internal_errors(): comment = RecipeSetComment(user=identity.current.user, comment=data['comment']) recipeset.comments.append(comment) session.flush() # to populate the id return jsonify(comment.__json__())
def post_recipe_task_comment(recipeid, taskid): """ Adds a new comment to a recipe task. The request must be :mimetype:`application/json`. :param recipeid: Recipe id. :param taskid: Recipe task id. :jsonparam string comment: Comment text. """ task = _get_recipe_task_by_id(recipeid, taskid) if not task.can_comment(identity.current.user): raise Forbidden403('Cannot post recipe task comment') data = read_json_request(request) if 'comment' not in data: raise BadRequest400('Missing "comment" key') with convert_internal_errors(): comment = RecipeTaskComment(user=identity.current.user, comment=data['comment']) task.comments.append(comment) session.flush() # to populate the id return jsonify(comment.__json__())
def test_arch_inside_or(self): # The bug was that <arch/> inside <or/> with other conditions would # produce a cartesian product where the join condition was on one side # of the OR, leading to a row explosion (similar to the case above). lc = data_setup.create_labcontroller(fqdn=u'bz1183239.lab') data_setup.create_system(lab_controller=lc, arch=[u'i386', u'x86_64']) session.flush() filter = """ <hostRequires> <labcontroller value="bz1183239.lab" /> <or> <system><arch value="i386" /></system> <hostname op="!=" value="blerch" /> </or> </hostRequires> """ query = XmlHost.from_string(filter).apply_filter(System.query) self.assertEquals(len(query.all()), 1) # with the bug this count comes out as 2 instead of 1, # which doesn't sound so bad... # but when it's 30575826 instead of 4131, that's bad self.assertEquals(query.count(), 1)
def test_keyvalue_does_not_cause_duplicate_rows(self): system = data_setup.create_system() disk_key = Key.by_name(u'DISK') system.key_values_int.extend([ Key_Value_Int(disk_key, 30718), Key_Value_Int(disk_key, 140011), Key_Value_Int(disk_key, 1048570)]) session.flush() filter = """ <hostRequires> <and> <system><name op="=" value="%s" /></system> <key_value key="DISK" op=">" value="9000" /> </and> </hostRequires> """ % system.fqdn query = XmlHost.from_string(filter).apply_filter(System.query) self.assertEquals(len(query.all()), 1) # with the bug this count comes out as 3 instead of 1, # which doesn't sound so bad... # but when it's 926127 instead of 278, that's bad self.assertEquals(query.count(), 1)
def generate_kickstart(install_options, distro_tree, system, user, recipe=None, ks_appends=None, kickstart=None, installation=None): if recipe: lab_controller = recipe.recipeset.lab_controller elif system: lab_controller = system.lab_controller else: raise ValueError("Must specify either a system or a recipe") recipe_whiteboard = job_whiteboard = '' if recipe: if recipe.whiteboard: recipe_whiteboard = recipe.whiteboard if recipe.recipeset.job.whiteboard: job_whiteboard = recipe.recipeset.job.whiteboard installation = installation if installation is not None else recipe.installation # User-supplied templates don't get access to our model objects, in case # they do something foolish/naughty. restricted_context = { 'kernel_options_post': install_options.kernel_options_post_str, 'recipe_whiteboard': recipe_whiteboard, 'job_whiteboard': job_whiteboard, 'distro_tree': RestrictedDistroTree(installation.osmajor, installation.osminor, installation.distro_name, installation.variant, installation.arch.arch, installation.tree_url, distro_tree), 'distro': RestrictedDistro(installation.osmajor, installation.osminor, installation.distro_name), 'lab_controller': RestrictedLabController(lab_controller), 'recipe': RestrictedRecipe(recipe) if recipe else None, 'ks_appends': ks_appends or [], } restricted_context.update(install_options.ks_meta) # System templates and snippets have access to more useful stuff. context = dict(restricted_context) context.update({ 'system': system, 'lab_controller': lab_controller, 'user': user, 'recipe': recipe, 'config': config, }) if distro_tree: context.update({ 'distro_tree': distro_tree, 'distro': distro_tree.distro, }) else: # But user-defined distros only get access to our "Restricted" model objects context.update({ 'distro_tree': RestrictedDistroTree(installation.osmajor, installation.osminor, installation.distro_name, installation.variant, installation.arch.arch, installation.tree_url), 'distro': RestrictedDistro(installation.osmajor, installation.osminor, installation.distro_name), }) snippet_locations = [] if system: snippet_locations.append( 'snippets/per_system/%%s/%s' % system.fqdn) snippet_locations.extend([ 'snippets/per_lab/%%s/%s' % lab_controller.fqdn, 'snippets/per_osversion/%%s/%s.%s' % (installation.osmajor, installation.osminor), 'snippets/per_osmajor/%%s/%s' % installation.osmajor, 'snippets/%s', ]) def snippet(name): template = None candidates = [location % name for location in snippet_locations] for candidate in candidates: try: template = template_env.get_template(candidate) break except jinja2.TemplateNotFound: continue if template: retval = template.render(context) if retval and not retval.endswith('\n'): retval += '\n' return retval else: return u'# no snippet data for %s\n' % name restricted_context['snippet'] = snippet context['snippet'] = snippet with TemplateRenderingEnvironment(): if kickstart: template = template_env.from_string( "{% snippet 'install_method' %}\n" + kickstart) result = template.render(restricted_context) else: template = kickstart_template(installation.osmajor) result = template.render(context) rendered_kickstart = RenderedKickstart(kickstart=result) session.add(rendered_kickstart) session.flush() # so that it has an id return rendered_kickstart
def generate_kickstart(install_options, distro_tree, system, user, recipe=None, ks_appends=None, kickstart=None): if recipe: lab_controller = recipe.recipeset.lab_controller elif system: lab_controller = system.lab_controller else: raise ValueError("Must specify either a system or a recipe") # User-supplied templates don't get access to our model objects, in case # they do something foolish/naughty. recipe_whiteboard = job_whiteboard = '' if recipe: if recipe.whiteboard: recipe_whiteboard = recipe.whiteboard if recipe.recipeset.job.whiteboard: job_whiteboard = recipe.recipeset.job.whiteboard restricted_context = { 'kernel_options_post': install_options.kernel_options_post_str, 'recipe_whiteboard': recipe_whiteboard, 'job_whiteboard': job_whiteboard, } restricted_context.update(install_options.ks_meta) # XXX find a better place to set this, perhaps from the kickstart templates rhel_osmajor = ['RedHatEnterpriseLinux6', 'RedHatEnterpriseLinux7'] if distro_tree.distro.osversion.osmajor.osmajor in rhel_osmajor \ or distro_tree.distro.osversion.osmajor.osmajor.startswith('Fedora'): restricted_context['end'] = '%end' # System templates and snippets have access to more useful stuff. context = dict(restricted_context) context.update({ 'distro_tree': distro_tree, 'distro': distro_tree.distro, 'system': system, 'lab_controller': lab_controller, 'user': user, 'recipe': recipe, 'config': config, 'ks_appends': ks_appends or [], }) snippet_locations = [] if system: snippet_locations.append( 'snippets/per_system/%%s/%s' % system.fqdn) snippet_locations.extend([ 'snippets/per_lab/%%s/%s' % lab_controller.fqdn, 'snippets/per_osversion/%%s/%s' % distro_tree.distro.osversion, 'snippets/per_osmajor/%%s/%s' % distro_tree.distro.osversion.osmajor, 'snippets/%s', ]) def snippet(name): template = None candidates = [location % name for location in snippet_locations] for candidate in candidates: try: template = template_env.get_template(candidate) break except jinja2.TemplateNotFound: continue if template: retval = template.render(context) if retval and not retval.endswith('\n'): retval += '\n' return retval else: return u'# no snippet data for %s\n' % name restricted_context['snippet'] = snippet context['snippet'] = snippet with TemplateRenderingEnvironment(): if kickstart: template = template_env.from_string( "{% snippet 'install_method' %}\n" + kickstart) result = template.render(restricted_context) else: template = kickstart_template(distro_tree) result = template.render(context) rendered_kickstart = RenderedKickstart(kickstart=result) session.flush() # so that it has an id return rendered_kickstart