def _create_labcontroller_helper(data): with convert_internal_errors(): if LabController.query.filter_by(fqdn=data['fqdn']).count(): raise Conflict409('Lab Controller %s already exists' % data['fqdn']) user = find_user_or_create(data['user_name']) user = update_user( user=user, display_name=data['fqdn'], email_address=data.get('email_address', user.email_address), password=data.get('password', user.password) ) labcontroller = LabController(fqdn=data['fqdn'], disabled=False) labcontroller.record_activity( user=identity.current.user, service=u'HTTP', action=u'Changed', field=u'FQDN', old=u'', new=data['fqdn']) labcontroller.user = user labcontroller.record_activity( user=identity.current.user, service=u'HTTP', action=u'Changed', field=u'User', old=u'', new=user.user_name) # For backwards compatibility labcontroller.record_activity( user=identity.current.user, service=u'HTTP', action=u'Changed', field=u'Disabled', old=u'', new=unicode(labcontroller.disabled)) session.add(labcontroller) # flush it so we return an id, otherwise we'll end up back in here from # the edit form session.flush() response = jsonify(labcontroller.__json__()) response.status_code = 201 return response
def create_labcontroller(fqdn=None, user=None): if fqdn is None: fqdn = unique_name(u'lab%s.testdata.invalid') try: lc = LabController.by_name(fqdn) except NoResultFound: if user is None: user = User(user_name='host/%s' % fqdn) lc = LabController(fqdn=fqdn) lc.user = user user.groups.append(Group.by_name(u'lab_controller')) return lc log.debug('labcontroller %s already exists' % fqdn) return lc
def save(self, **kw): if kw.get('id'): labcontroller = LabController.by_id(kw['id']) else: labcontroller = LabController() session.add(labcontroller) if labcontroller.fqdn != kw['fqdn']: activity = LabControllerActivity(identity.current.user, 'WEBUI', 'Changed', 'FQDN', labcontroller.fqdn, kw['fqdn']) labcontroller.fqdn = kw['fqdn'] labcontroller.write_activity.append(activity) # labcontroller.user is used by the lab controller to login here try: # pick up an existing user if it exists. luser = User.query.filter_by(user_name=kw['lusername']).one() except InvalidRequestError: # Nope, create from scratch luser = User() if labcontroller.user != luser: if labcontroller.user is None: old_user_name = None else: old_user_name = labcontroller.user.user_name activity = LabControllerActivity(identity.current.user, 'WEBUI', 'Changed', 'User', old_user_name, unicode(kw['lusername'])) labcontroller.user = luser labcontroller.write_activity.append(activity) # Make sure user is a member of lab_controller group group = Group.by_name(u'lab_controller') if group not in luser.groups: luser.groups.append(group) luser.display_name = kw['fqdn'] luser.email_address = kw['email'] luser.user_name = kw['lusername'] if kw['lpassword']: luser.password = kw['lpassword'] if labcontroller.disabled != kw['disabled']: activity = LabControllerActivity(identity.current.user, 'WEBUI', 'Changed', 'Disabled', unicode(labcontroller.disabled), unicode(kw['disabled'])) labcontroller.disabled = kw['disabled'] labcontroller.write_activity.append(activity) flash( _(u"%s saved" % labcontroller.fqdn) ) redirect(".")
def remove(self, id, *args, **kw): labcontroller = LabController.by_id(id) labcontroller.removed = datetime.utcnow() # de-associate systems systems = System.query.filter(System.lab_controller == labcontroller) System.record_bulk_activity(systems, user=identity.current.user, service=u'WEBUI', action=u'Changed', field=u'lab_controller', old=labcontroller.fqdn, new=None) systems.update({'lab_controller_id': None}, synchronize_session=False) # cancel running recipes watchdogs = Watchdog.by_status(labcontroller=labcontroller, status='active') for w in watchdogs: w.recipe.recipeset.job.cancel(msg='LabController %s has been deleted' % labcontroller.fqdn) # remove distro trees distro_tree_assocs = LabControllerDistroTree.query\ .filter(LabControllerDistroTree.lab_controller == labcontroller)\ .join(LabControllerDistroTree.distro_tree) DistroTree.record_bulk_activity(distro_tree_assocs, user=identity.current.user, service=u'WEBUI', action=u'Removed', field=u'lab_controller_assocs', old=labcontroller.fqdn, new=None) distro_tree_assocs.delete(synchronize_session=False) labcontroller.disabled = True labcontroller.record_activity(user=identity.current.user, service=u'WEBUI', field=u'Disabled', action=u'Changed', old=unicode(False), new=unicode(True)) labcontroller.record_activity(user=identity.current.user, service=u'WEBUI', field=u'Removed', action=u'Changed', old=unicode(False), new=unicode(True)) flash( _(u"%s removed") % labcontroller.fqdn ) raise redirect(".")
def remove(self, id, *args, **kw): try: labcontroller = LabController.by_id(id) labcontroller.removed = datetime.utcnow() systems = System.query.filter_by(lab_controller_id=id).values(System.id) for system_id in systems: sys_activity = SystemActivity(identity.current.user, 'WEBUI', \ 'Changed', 'lab_controller', labcontroller.fqdn, None, system_id=system_id[0]) system_table.update().where(system_table.c.lab_controller_id == id).\ values(lab_controller_id=None).execute() watchdogs = Watchdog.by_status(labcontroller=labcontroller, status='active') for w in watchdogs: w.recipe.recipeset.job.cancel(msg='LabController %s has been deleted' % labcontroller.fqdn) for lca in labcontroller._distro_trees: lca.distro_tree.activity.append(DistroTreeActivity( user=identity.current.user, service=u'WEBUI', action=u'Removed', field_name=u'lab_controller_assocs', old_value=u'%s %s' % (lca.lab_controller, lca.url), new_value=None)) session.delete(lca) labcontroller.disabled = True LabControllerActivity(identity.current.user, 'WEBUI', 'Changed', 'Disabled', unicode(False), unicode(True), lab_controller_id=id) LabControllerActivity(identity.current.user, 'WEBUI', 'Changed', 'Removed', unicode(False), unicode(True), lab_controller_id=id) session.commit() finally: session.close() flash( _(u"%s removed") % labcontroller.fqdn ) raise redirect(".")
def yum_config(self, distro_tree_id, *args, **kwargs): # Ignore positional args, so that we can make nice URLs like # /distrotrees/yum_config/12345/RHEL-6.2-Server-i386.repo try: distro_tree = DistroTree.by_id(int(distro_tree_id)) except (ValueError, NoResultFound): raise cherrypy.NotFound(distro_tree_id) if not kwargs.get('lab'): lc = distro_tree.lab_controller_assocs[0].lab_controller else: try: lc = LabController.by_name(kwargs['lab']) except NoResultFound: raise cherrypy.HTTPError(status=400, message='No such lab controller %r' % kwargs['lab']) base = distro_tree.url_in_lab(lc, scheme='http') if not base: raise cherrypy.HTTPError(status=404, message='%s is not present in lab %s' % (distro_tree, lc)) if not distro_tree.repos: return '# No repos for %s' % distro_tree sections = [] for repo in distro_tree.repos: sections.append('''[%s] name=%s baseurl=%s enabled=1 gpgcheck=0 ''' % (repo.repo_id, repo.repo_id, urlparse.urljoin(base, repo.path))) return '\n'.join(sections)
def index(self, **kwargs): kwargs.setdefault('tag', 'STABLE') value = dict((k, v) for k, v in kwargs.iteritems() if k in ['osmajor', 'tag', 'distro']) options = {} tags = DistroTag.used() options['tag'] = [('', 'None selected')] + \ [(tag.tag, tag.tag) for tag in tags] options['osmajor'] = [('', 'None selected')] + \ [(osmajor.osmajor, osmajor.osmajor) for osmajor in OSMajor.ordered_by_osmajor(OSMajor.in_any_lab())] options['distro'] = self._get_distro_options(**kwargs) options['lab_controller_id'] = [(None, 'None selected')] + \ LabController.get_all(valid=True) options['distro_tree_id'] = self._get_distro_tree_options(**kwargs) attrs = {} if not options['distro']: attrs['distro'] = dict(disabled=True) return dict(title=_(u'Reserve Workflow'), widget=self.widget, value=value, widget_options=options, widget_attrs=attrs)
def index(self, **kwargs): value = dict((k, v) for k, v in kwargs.iteritems() if k in ['osmajor', 'tag', 'distro']) options = {} tags = DistroTag.used() # It's important that 'None selected' is prepended # rather then appended to the list of tags, as that will ensure # it is the default option in the drop down. options['tag'] = [('', 'None selected')] + \ [(tag.tag, tag.tag) for tag in tags] options['osmajor'] = [('', 'None selected')] + \ [(osmajor.osmajor, osmajor.osmajor) for osmajor in OSMajor.ordered_by_osmajor(OSMajor.in_any_lab())] options['distro'] = self._get_distro_options(**kwargs) options['lab_controller_id'] = [(None, 'None selected')] + \ LabController.get_all(valid=True) options['distro_tree_id'] = self._get_distro_tree_options(**kwargs) attrs = {} if not options['distro']: attrs['distro'] = dict(disabled=True) return dict(title=_(u'Reserve Workflow'), widget=self.widget, value=value, widget_options=options, widget_attrs=attrs)
def lab_controller_add(self, distro_tree_id, lab_controller_id, url): try: distro_tree = DistroTree.by_id(distro_tree_id) except NoResultFound: flash(_(u'Invalid distro tree id %s') % distro_tree_id) redirect('.') try: lab_controller = LabController.by_id(lab_controller_id) except NoResultFound: flash(_(u'Invalid lab controller id %s') % lab_controller_id) redirect(str(distro_tree.id)) url = url.strip() if not url.endswith('/'): url = url + '/' if not urlparse.urlparse(url).scheme: flash(_(u'URL %r is not absolute') % url) redirect(str(distro_tree.id)) distro_tree.lab_controller_assocs.append( LabControllerDistroTree(lab_controller=lab_controller, url=url)) distro_tree.activity.append(DistroTreeActivity( user=identity.current.user, service=u'WEBUI', action=u'Added', field_name=u'lab_controller_assocs', old_value=None, new_value=u'%s %s' % (lab_controller, url))) flash(_(u'Added %s %s') % (lab_controller, url)) redirect(str(distro_tree.id))
def validate_python(self, form_fields, state): lc_id = form_fields.get('id', None) email_address = form_fields['email'] user_name = form_fields['lusername'] try: User.by_email_address(email_address) except NoResultFound: email_is_used = False else: email_is_used = True if User.by_user_name(user_name): new_user = False else: new_user = True if not lc_id: labcontroller = None luser = None else: labcontroller = LabController.by_id(lc_id) luser = labcontroller.user try: if not labcontroller and email_is_used: # New LC using dupe email raise ValueError if new_user and email_is_used: #New user using dupe email raise ValueError if luser: _check_user_email(email_address, luser.user_id) except ValueError: error = {'email' : self.message('not_unique', state)} raise Invalid('Email address is not unique', form_fields, state, error_dict=error)
def _check_lc_leaks(self): with session.begin(): lc = LabController.by_name(lc_fqdn) # check for outstanding watchdogs watchdogs = Watchdog.query\ .join(Watchdog.recipe).join(Recipe.recipeset)\ .filter(RecipeSet.lab_controller == lc) if watchdogs.count(): # If your test case hits this error, you need to fix it so that # any running recipes are cancelled otherwise beaker-watchdog # will eventually pick them up and abort them, interfering with # some later test. raise AssertionError('Leaked watchdogs for %s: %s' % (lc_fqdn, watchdogs.all())) # check for systems left associated to the LC systems = System.query.filter(System.lab_controller == lc) if systems.count(): # If your test case hits this error, you need to fix it so that # any systems which were associated to the LC are # de-associated, otherwise subsequent tests which invoke the # scheduler will try to schedule recipes onto the system and # then beaker-provision will start trying to run the # provisioning commands. raise AssertionError('Leaked systems for %s: %s' % (lc_fqdn, systems.all()))
def watchdogs(self, status='active', lc=None): """ Return all active/expired tasks for this lab controller The lab controllers login with host/fqdn """ # TODO work on logic that determines whether or not originator # was qpid or kobo ? if lc is None: try: labcontroller = identity.current.user.lab_controller except AttributeError: raise BX( _('No lab controller passed in and not currently logged in' )) if not labcontroller: raise BX( _(u'Invalid login: %s, must log in as a lab controller' % identity.current.user)) else: try: labcontroller = LabController.by_name(lc) except InvalidRequestError: raise BX(_(u'Invalid lab controller: %s' % lc)) return [ dict(recipe_id=w.recipe.id, system=w.recipe.resource.fqdn, is_virt_recipe=(w.recipe.resource.type == ResourceType.virt)) for w in Watchdog.by_status(labcontroller, status) ]
def lab_controller_add(self, distro_tree_id, lab_controller_id, url): try: distro_tree = DistroTree.by_id(distro_tree_id) except NoResultFound: flash(_(u'Invalid distro tree id %s') % distro_tree_id) redirect('.') try: lab_controller = LabController.by_id(lab_controller_id) except ValueError: flash(_(u'Invalid lab controller id %s') % lab_controller_id) redirect(str(distro_tree.id)) url = url.strip() if not url.endswith('/'): url = url + '/' if not urlparse.urlparse(url).scheme: flash(_(u'URL %r is not absolute') % url) redirect(str(distro_tree.id)) distro_tree.lab_controller_assocs.append( LabControllerDistroTree(lab_controller=lab_controller, url=url)) distro_tree.activity.append(DistroTreeActivity( user=identity.current.user, service=u'WEBUI', action=u'Added', field_name=u'lab_controller_assocs', old_value=None, new_value=u'%s %s' % (lab_controller, url))) flash(_(u'Added %s %s') % (lab_controller, url)) redirect(str(distro_tree.id))
def has_active_recipes(self, id): labcontroller = LabController.by_id(id) count = Watchdog.by_status(labcontroller=labcontroller, status='active').count() if count: return {'has_active_recipes' : True} else: return {'has_active_recipes' : False}
def doit(): distro_trees = [] for id in request.form.getlist('distro_tree_id'): try: distro_trees.append(DistroTree.by_id(id)) except NoResultFound: raise BadRequest400('Distro tree %r does not exist' % id) job_details = {} job_details['pick'] = request.form.get('pick') or 'auto' if job_details['pick'] == 'fqdn': try: job_details['system'] = System.by_fqdn(request.form.get('system'), identity.current.user) except NoResultFound: raise BadRequest400('System %s not found' % request.form.get('system')) elif job_details['pick'] == 'lab': try: job_details['lab'] = LabController.by_name(request.form.get('lab')) except NoResultFound: raise BadRequest400('Lab controller %s not found' % request.form.get('lab')) days = int(request.form.get('reserve_days') or DEFAULT_RESERVE_DAYS) days = min(days, MAX_DAYS_PROVISION) job_details['reservetime'] = days * 24 * 60 * 60 job_details['whiteboard'] = request.form.get('whiteboard') job_details['ks_meta'] = request.form.get('ks_meta') job_details['koptions'] = request.form.get('koptions') job_details['koptions_post'] = request.form.get('koptions_post') with convert_internal_errors(): job = Job.provision_system_job(distro_trees, **job_details) return 'Created %s' % job.t_id, 201, [('Location', url('/jobs/%s' % job.id))]
def test_lookup_secret_fqdn(self): with session.begin(): system = data_setup.create_system() system.private = True lab_controller_user = LabController.by_name(self.lc_fqdn).user system2 = System.by_fqdn(str(system.fqdn), user=lab_controller_user) self.assertEquals(system, system2)
def doit(): distro_trees = [] for id in request.form.getlist('distro_tree_id'): try: distro_trees.append(DistroTree.by_id(id)) except NoResultFound: raise BadRequest400('Distro tree %r does not exist' % id) job_details = {} job_details['pick'] = request.form.get('pick') or 'auto' if job_details['pick'] == 'fqdn': try: job_details['system'] = System.by_fqdn(request.form.get('system'), identity.current.user) except NoResultFound: raise BadRequest400('System %s not found' % request.form.get('system')) elif job_details['pick'] == 'lab': try: job_details['lab'] = LabController.by_name(request.form.get('lab')) except NoResultFound: raise BadRequest400('Lab controller %s not found' % request.form.get('lab')) days = int(request.form.get('reserve_days') or DEFAULT_RESERVE_DAYS) days = min(days, MAX_DAYS_PROVISION) job_details['reservetime'] = days * 24 * 60 * 60 job_details['whiteboard'] = request.form.get('whiteboard') job_details['ks_meta'] = request.form.get('ks_meta') job_details['koptions'] = request.form.get('koptions') job_details['koptions_post'] = request.form.get('koptions_post') with convert_internal_errors(): job = Job.provision_system_job(distro_trees, **job_details) return 'Created %s' % job.t_id, 201, [('Location', absolute_url('/jobs/%s' % job.id))]
def find_labcontroller_or_raise404(fqdn): """Returns a lab controller object or raises a NotFound404 error if the lab controller does not exist in the database.""" try: labcontroller = LabController.by_name(fqdn) except NoResultFound: raise NotFound404('Lab controller %s does not exist' % fqdn) return labcontroller
def has_active_recipes(self, id): labcontroller = LabController.by_id(id) count = Watchdog.by_status(labcontroller=labcontroller, status='active').count() if count: return {'has_active_recipes': True} else: return {'has_active_recipes': False}
def create_labcontroller(fqdn=None, user=None): if fqdn is None: fqdn = unique_name(u'lab%s.testdata.invalid') try: lc = LabController.by_name(fqdn) except NoResultFound: if user is None: user = User(user_name=u'host/%s' % fqdn, email_address=u'root@%s' % fqdn) lc = LabController(fqdn=fqdn) lc.user = user session.add(lc) user.groups.append(Group.by_name(u'lab_controller')) # Need to ensure it is inserted now, since we aren't using lazy_create # here so a subsequent call to create_labcontroller could try and # create the same LC again. session.flush() return lc log.debug('labcontroller %s already exists' % fqdn) return lc
def unremove(self, id): labcontroller = LabController.by_id(id) labcontroller.removed = None labcontroller.disabled = False labcontroller.record_activity(user=identity.current.user, service=u'WEBUI', field=u'Disabled', action=u'Changed', old=unicode(True), new=unicode(False)) labcontroller.record_activity(user=identity.current.user, service=u'WEBUI', field=u'Removed', action=u'Changed', old=unicode(True), new=unicode(False)) flash('Successfully re-added %s' % labcontroller.fqdn) redirect(url('.'))
def validate_python(self, form_fields, state): lc_id = form_fields.get('id', None) fqdn = form_fields['fqdn'] lusername = form_fields['lusername'] try: existing_lc_with_fqdn = LabController.by_name(fqdn) except NoResultFound: existing_lc_with_fqdn = None existing_user_with_lusername = User.by_user_name(lusername) if not lc_id: labcontroller = None luser = None else: labcontroller = LabController.by_id(lc_id) luser = labcontroller.user errors = {} if not labcontroller and existing_lc_with_fqdn: # New LC using duplicate FQDN errors['fqdn'] = self.message('fqdn_not_unique', state) elif (labcontroller and existing_lc_with_fqdn and labcontroller != existing_lc_with_fqdn): # Existing LC changing FQDN to a duplicate one errors['fqdn'] = self.message('fqdn_not_unique', state) if (not luser and existing_user_with_lusername and existing_user_with_lusername.lab_controller): # New LC using username that is already in use errors['lusername'] = self.message('username_in_use', state) if (luser and existing_user_with_lusername and luser != existing_user_with_lusername and existing_user_with_lusername.lab_controller): # Existing LC changing username to one that is already in use errors['lusername'] = self.message('username_in_use', state) if errors: raise Invalid('Validation failed', form_fields, state, error_dict=errors)
def unremove(self, id): labcontroller = LabController.by_id(id) labcontroller.removed = None labcontroller.disabled = False LabControllerActivity(identity.current.user, 'WEBUI', 'Changed', 'Disabled', unicode(True), unicode(False), lab_controller_id = id) LabControllerActivity(identity.current.user, 'WEBUI', 'Changed', 'Removed', unicode(True), unicode(False), lab_controller_id=id) flash('Succesfully re-added %s' % labcontroller.fqdn) redirect(url('.'))
def edit(self, id, **kw): options = {} if id: labcontroller = LabController.by_id(id) options.update({'user': labcontroller.user}) else: labcontroller = None return dict(form=self.labcontroller_form, action='./save', options=options, value=labcontroller, title='Edit Lab Controller')
def edit(self, id, **kw): options = {} if id: labcontroller = LabController.by_id(id) options.update({'user' : labcontroller.user}) else: labcontroller=None return dict( form = self.labcontroller_form, action = './save', options = options, value = labcontroller, )
def remove(self, id, *args, **kw): labcontroller = LabController.by_id(id) labcontroller.removed = datetime.utcnow() # de-associate systems systems = System.query.filter(System.lab_controller == labcontroller) System.record_bulk_activity(systems, user=identity.current.user, service=u'WEBUI', action=u'Changed', field=u'lab_controller', old=labcontroller.fqdn, new=None) systems.update({'lab_controller_id': None}, synchronize_session=False) # cancel running recipes watchdogs = Watchdog.by_status(labcontroller=labcontroller, status='active') for w in watchdogs: w.recipe.recipeset.job.cancel( msg='LabController %s has been deleted' % labcontroller.fqdn) # remove distro trees distro_tree_assocs = LabControllerDistroTree.query\ .filter(LabControllerDistroTree.lab_controller == labcontroller)\ .join(LabControllerDistroTree.distro_tree) DistroTree.record_bulk_activity(distro_tree_assocs, user=identity.current.user, service=u'WEBUI', action=u'Removed', field=u'lab_controller_assocs', old=labcontroller.fqdn, new=None) distro_tree_assocs.delete(synchronize_session=False) labcontroller.disabled = True labcontroller.record_activity(user=identity.current.user, service=u'WEBUI', field=u'Disabled', action=u'Changed', old=unicode(False), new=unicode(True)) labcontroller.record_activity(user=identity.current.user, service=u'WEBUI', field=u'Removed', action=u'Changed', old=unicode(False), new=unicode(True)) flash(_(u"%s removed") % labcontroller.fqdn) raise redirect(".")
def doit(): distro_trees = [] for id in request.form.getlist('distro_tree_id'): try: distro_trees.append(DistroTree.by_id(id)) except NoResultFound: raise BadRequest400('Distro tree %r does not exist' % id) job_details = {} job_details['pick'] = request.form.get('pick') or 'auto' system_choice = 'any system' if job_details['pick'] == 'fqdn': try: job_details['system'] = System.by_fqdn(request.form.get('system'), identity.current.user) system_choice = 'a specific system' except DatabaseLookupError: raise BadRequest400('System %s not found' % request.form.get('system')) elif job_details['pick'] == 'lab': try: job_details['lab'] = LabController.by_name(request.form.get('lab')) system_choice = 'any lab system' except NoResultFound: raise BadRequest400('Lab controller %s not found' % request.form.get('lab')) reservetime = int( request.form.get('reserve_duration') or DEFAULT_RESERVE_SECONDS) if reservetime > MAX_SECONDS_PROVISION: raise BadRequest400( 'Reservation time exceeds maximum time of %s hours' % MAX_HOURS_PROVISION) job_details['reservetime'] = reservetime job_details['whiteboard'] = request.form.get('whiteboard') if not job_details['whiteboard']: job_details['whiteboard'] = ( "Reserve Workflow provision of distro %s on %s for %d seconds" % (request.form.get('distro'), system_choice, job_details['reservetime'])) job_details['ks_meta'] = request.form.get('ks_meta') job_details['koptions'] = request.form.get('koptions') job_details['koptions_post'] = request.form.get('koptions_post') with convert_internal_errors(): job = Job.provision_system_job(distro_trees, **job_details) return 'Created %s' % job.t_id, 201, [('Location', absolute_url('/jobs/%s' % job.id))]
def test_lab_controller_remove(self): b = self.browser lc_name = data_setup.unique_name('lc%s.com') lc_email = data_setup.unique_name('me@my%s.com') self._add_lc(b, lc_name, lc_email, data_setup.ADMIN_USER) with session.begin(): sys = data_setup.create_system() sys.lab_controller = LabController.by_name(lc_name) b.get(get_server_base() + 'labcontrollers') b.find_element_by_xpath("//table[@id='widget']/tbody/tr/" "td[preceding-sibling::td/a[normalize-space(text())='%s']]" "/a[normalize-space(text())='Remove (-)']" % lc_name).click() self.assert_('%s removed' % lc_name in b.find_element_by_css_selector('.flash').text) # Search in LC activity b.get(get_server_base() + 'activity/labcontroller') b.find_element_by_id('advancedsearch').click() b.find_element_by_xpath("//select[@id='activitysearch_0_table']/" "option[@value='LabController/Name']").click() b.find_element_by_xpath("//select[@id='activitysearch_0_operation']/" "option[@value='is']").click() b.find_element_by_xpath("//input[@id='activitysearch_0_value']"). \ send_keys(lc_name) b.find_element_by_xpath("//input[@name='Search']").click() self.assert_(is_activity_row_present(b, object_='LabController: %s' % lc_name, via='WEBUI', property_='Disabled', action='Changed', new_value='True')) self.assert_(is_activity_row_present(b, object_='LabController: %s' % lc_name, via='WEBUI', property_='Removed', action='Changed', new_value='True')) # Ensure System Actvity has been updated to note removal of LC b.get(get_server_base() + 'activity/system') b.find_element_by_id('advancedsearch').click() b.find_element_by_xpath("//select[@id='activitysearch_0_table']/" "option[@value='System/Name']").click() b.find_element_by_xpath("//select[@id='activitysearch_0_operation']/" "option[@value='is']").click() b.find_element_by_xpath("//input[@id='activitysearch_0_value']"). \ send_keys(sys.fqdn) b.find_element_by_xpath("//input[@name='Search']").click() self.assert_(is_activity_row_present(b, object_='System: %s' % sys.fqdn, via='WEBUI', property_='lab_controller', action='Changed', new_value=''))
def save(self, **kw): if kw.get('id'): labcontroller = LabController.by_id(kw['id']) else: labcontroller = LabController() session.add(labcontroller) if labcontroller.fqdn != kw['fqdn']: activity = LabControllerActivity(identity.current.user, 'WEBUI', 'Changed', 'FQDN', labcontroller.fqdn, kw['fqdn']) labcontroller.fqdn = kw['fqdn'] labcontroller.write_activity.append(activity) # labcontroller.user is used by the lab controller to login here try: # pick up an existing user if it exists. luser = User.query.filter_by(user_name=kw['lusername']).one() except InvalidRequestError: # Nope, create from scratch luser = User() if labcontroller.user != luser: if labcontroller.user is None: old_user_name = None else: old_user_name = labcontroller.user.user_name activity = LabControllerActivity(identity.current.user, 'WEBUI', 'Changed', 'User', old_user_name, unicode(kw['lusername'])) labcontroller.user = luser labcontroller.write_activity.append(activity) # Make sure user is a member of lab_controller group group = Group.by_name(u'lab_controller') if group not in luser.groups: luser.groups.append(group) luser.display_name = kw['fqdn'] luser.email_address = kw['email'] luser.user_name = kw['lusername'] if kw['lpassword']: luser.password = kw['lpassword'] if labcontroller.disabled != kw['disabled']: activity = LabControllerActivity(identity.current.user, 'WEBUI', 'Changed', 'Disabled', unicode(labcontroller.disabled), unicode(kw['disabled'])) labcontroller.disabled = kw['disabled'] labcontroller.write_activity.append(activity) flash(_(u"%s saved" % labcontroller.fqdn)) redirect(".")
def test_lab_controller_add(self): b = self.browser lc_name = data_setup.unique_name("lc%s.com") lc_email = data_setup.unique_name("me@my%s.com") self._add_lc(lc_name, lc_email) self.assert_("%s saved" % lc_name in b.find_element_by_css_selector(".flash").text) # check activity with session.begin(): lc = LabController.by_name(lc_name) self.assertEquals(lc.activity[0].field_name, u"Disabled") self.assertEquals(lc.activity[0].action, u"Changed") self.assertEquals(lc.activity[0].new_value, u"False") self.assertEquals(lc.activity[1].field_name, u"User") self.assertEquals(lc.activity[1].action, u"Changed") self.assertEquals(lc.activity[1].new_value, u"host/" + lc_name) self.assertEquals(lc.activity[2].field_name, u"FQDN") self.assertEquals(lc.activity[2].action, u"Changed") self.assertEquals(lc.activity[2].new_value, lc_name)
def test_lab_controller_add(self): b = self.browser lc_name = data_setup.unique_name('lc%s.com') lc_email = data_setup.unique_name('me@my%s.com') self._add_lc(lc_name, lc_email) self.assert_('%s saved' % lc_name in b.find_element_by_css_selector('.flash').text) # check activity with session.begin(): lc = LabController.by_name(lc_name) self.assertEquals(lc.activity[0].field_name, u'Disabled') self.assertEquals(lc.activity[0].action, u'Changed') self.assertEquals(lc.activity[0].new_value, u'False') self.assertEquals(lc.activity[1].field_name, u'User') self.assertEquals(lc.activity[1].action, u'Changed') self.assertEquals(lc.activity[1].new_value, u'host/' + lc_name) self.assertEquals(lc.activity[2].field_name, u'FQDN') self.assertEquals(lc.activity[2].action, u'Changed') self.assertEquals(lc.activity[2].new_value, lc_name)
def test_lab_controller_create(self): fqdn = data_setup.unique_name(u'mylab%s') run_client(['bkr', 'labcontroller-create', '--fqdn', fqdn, '--user', 'host/%s' % fqdn, '--email', 'lab1@%s.com' % fqdn]) with session.begin(): lc = LabController.by_name(fqdn) self.assertEqual(lc.user.user_name, 'host/%s' % fqdn) self.assertEqual(lc.user.email_address, 'lab1@%s.com' % fqdn) self.assertIn(Group.by_name(u'lab_controller'), lc.user.groups) # cann't create duplicate lab controller try: run_client(['bkr', 'labcontroller-create', '--fqdn', fqdn, '--user', 'host/%s' % fqdn, '--email', 'lab1@%s.com' % fqdn]) self.fail('Must fail') except ClientError as e: self.assertIn("Lab Controller %s already exists" % fqdn, e.stderr_output)
def watchdogs(self, status='active',lc=None): """ Return all active/expired tasks for this lab controller The lab controllers login with host/fqdn """ # TODO work on logic that determines whether or not originator # was qpid or kobo ? if lc is None: try: labcontroller = identity.current.user.lab_controller except AttributeError: raise BX(_('No lab controller passed in and not currently logged in')) if not labcontroller: raise BX(_(u'Invalid login: %s, must log in as a lab controller' % identity.current.user)) else: try: labcontroller = LabController.by_name(lc) except InvalidRequestError: raise BX(_(u'Invalid lab controller: %s' % lc)) return [dict(recipe_id = w.recipe.id, system = w.recipe.resource.fqdn) for w in Watchdog.by_status(labcontroller, status)]
def _get_distro_tree_options(self, distro=None, lab_controller_id=None, **kwargs): """ Returns a list of distro trees for the given distro. """ if not distro: return [] try: distro = Distro.by_name(distro) except NoResultFound: return [] trees = distro.dyn_trees.join(DistroTree.arch)\ .order_by(DistroTree.variant, Arch.arch) if lab_controller_id: try: lc = LabController.by_id(lab_controller_id) except NoResultFound: return [] trees = trees.filter(DistroTree.lab_controller_assocs.any( LabControllerDistroTree.lab_controller == lc)) else: trees = trees.filter(DistroTree.lab_controller_assocs.any()) return [(tree.id, unicode(tree)) for tree in trees]
def lab_controller_add(self, distro_tree_id, lab_controller_id, url): try: distro_tree = DistroTree.by_id(distro_tree_id) except NoResultFound: flash(_(u'Invalid distro tree id %s') % distro_tree_id) redirect('.') try: lab_controller = LabController.by_id(lab_controller_id) except ValueError: flash(_(u'Invalid lab controller id %s') % lab_controller_id) redirect(str(distro_tree.id)) # make sure the url ends with / url = os.path.join(url.strip(), '') try: self.add_distro_urls(distro_tree, lab_controller, [url]) except ValueError as e: flash(_(u'%s') % e) redirect(str(distro_tree.id)) flash(_(u'Changed/Added %s %s') % (lab_controller, url)) redirect(str(distro_tree.id))
def test_lab_controller_create(self): fqdn = data_setup.unique_name(u'mylab%s') run_client([ 'bkr', 'labcontroller-create', '--fqdn', fqdn, '--user', 'host/%s' % fqdn, '--email', 'lab1@%s.com' % fqdn ]) with session.begin(): lc = LabController.by_name(fqdn) self.assertEqual(lc.user.user_name, 'host/%s' % fqdn) self.assertEqual(lc.user.email_address, 'lab1@%s.com' % fqdn) self.assertIn(Group.by_name(u'lab_controller'), lc.user.groups) # cann't create duplicate lab controller try: run_client([ 'bkr', 'labcontroller-create', '--fqdn', fqdn, '--user', 'host/%s' % fqdn, '--email', 'lab1@%s.com' % fqdn ]) self.fail('Must fail') except ClientError as e: self.assertIn("Lab Controller %s already exists" % fqdn, e.stderr_output)
def update_system(fqdn): system = _get_system_by_FQDN(fqdn) if not system.can_edit(identity.current.user): raise Forbidden403('Cannot edit system') data = read_json_request(request) # helper for recording activity below def record_activity(field, old, new, action=u'Changed'): system.record_activity(user=identity.current.user, service=u'HTTP', action=action, field=field, old=old, new=new) with convert_internal_errors(): # XXX what a nightmare... need to use a validation/conversion library, # and maybe simplify/relocate the activity recording stuff somehow changed = False renamed = False if 'fqdn' in data: new_fqdn = data['fqdn'].lower() if new_fqdn != system.fqdn: if System.query.filter(System.fqdn == new_fqdn).count(): raise Conflict409('System %s already exists' % new_fqdn) record_activity(u'FQDN', system.fqdn, new_fqdn) system.fqdn = new_fqdn changed = True renamed = True if 'owner' in data and data['owner'].get('user_name') != system.owner.user_name: if not system.can_change_owner(identity.current.user): raise Forbidden403('Cannot change owner') new_owner = User.by_user_name(data['owner'].get('user_name')) if new_owner is None: raise BadRequest400('No such user %s' % data['owner'].get('user_name')) record_activity(u'Owner', system.owner, new_owner) system.owner = new_owner changed = True if 'status' in data: new_status = SystemStatus.from_string(data['status']) if new_status != system.status: record_activity(u'Status', system.status, new_status) system.status = new_status if not new_status.bad and system.status_reason: # clear the status reason for "good" statuses record_activity(u'Status Reason', system.status_reason, None) system.status_reason = None changed = True if 'status_reason' in data: new_reason = data['status_reason'] or None if new_reason and not system.status.bad: raise ValueError('Cannot set status reason when status is %s' % system.status) if new_reason != system.status_reason: record_activity(u'Status Reason', system.status_reason, new_reason) system.status_reason = new_reason changed = True if 'type' in data: new_type = SystemType.from_string(data['type']) if new_type != system.type: record_activity(u'Type', system.type, new_type) system.type = new_type changed = True if 'arches' in data: new_arches = [Arch.by_name(a) for a in (data['arches'] or [])] added_arches = set(new_arches).difference(system.arch) removed_arches = set(system.arch).difference(new_arches) if added_arches or removed_arches: for added_arch in added_arches: record_activity(u'Arch', None, added_arch, u'Added') for removed_arch in removed_arches: record_activity(u'Arch', removed_arch, None, u'Removed') system.arch[:] = new_arches changed = True if 'lab_controller_id' in data: if data['lab_controller_id']: new_lc = LabController.by_id(data['lab_controller_id']) else: new_lc = None if new_lc != system.lab_controller: if system.open_reservation is not None: raise Conflict409('Unable to change lab controller while system ' 'is in use (return the system first)') record_activity(u'Lab Controller', system.lab_controller, new_lc) system.lab_controller = new_lc changed = True # If we're given any power-related keys, need to ensure system.power exists if not system.power and set(['power_type', 'power_address', 'power_user', 'power_password', 'power_id', 'power_quiescent_period'])\ .intersection(data.keys()): system.power = Power() if 'power_type' in data: new_power_type = PowerType.by_name(data['power_type']) if new_power_type != system.power.power_type: if not system.power.power_type: old_power_type = '' else: old_power_type = system.power.power_type.name record_activity(u'power_type', old_power_type, new_power_type.name) system.power.power_type = new_power_type changed = True if 'power_address' in data: new_power_address = data['power_address'] if not new_power_address: raise ValueError('Power address is required') if new_power_address != system.power.power_address: record_activity(u'power_address', system.power.power_address, data['power_address']) system.power.power_address = new_power_address changed = True if 'power_user' in data: new_power_user = data['power_user'] or u'' if new_power_user != (system.power.power_user or u''): record_activity(u'power_user', u'********', u'********') system.power.power_user = new_power_user changed = True if 'power_password' in data: new_power_password = data['power_password'] or u'' if new_power_password != (system.power.power_passwd or u''): record_activity(u'power_passwd', u'********', u'********') system.power.power_passwd = new_power_password changed = True if 'power_id' in data: new_power_id = data['power_id'] or u'' if new_power_id != (system.power.power_id or u''): record_activity(u'power_id', system.power.power_id, new_power_id) system.power.power_id = new_power_id changed = True if 'power_quiescent_period' in data: new_qp = int(data['power_quiescent_period']) if new_qp != system.power.power_quiescent_period: record_activity(u'power_quiescent_period', system.power.power_quiescent_period, new_qp) system.power.power_quiescent_period = new_qp changed = True if 'release_action' in data: new_release_action = ReleaseAction.from_string(data['release_action']) if new_release_action != (system.release_action or ReleaseAction.power_off): record_activity(u'release_action', (system.release_action or ReleaseAction.power_off), new_release_action) system.release_action = new_release_action changed = True if 'reprovision_distro_tree' in data: if (not data['reprovision_distro_tree'] or 'id' not in data['reprovision_distro_tree']): new_rpdt = None else: new_rpdt = DistroTree.by_id(data['reprovision_distro_tree']['id']) if new_rpdt != system.reprovision_distro_tree: record_activity(u'reprovision_distro_tree', unicode(system.reprovision_distro_tree), unicode(new_rpdt)) system.reprovision_distro_tree = new_rpdt changed = True if 'location' in data: new_location = data['location'] or None if new_location != system.location: record_activity(u'Location', system.location, new_location) system.location = new_location changed = True if 'lender' in data: new_lender = data['lender'] or None if new_lender != system.lender: record_activity(u'Lender', system.lender, new_lender) system.lender = new_lender changed = True if 'kernel_type' in data: new_kernel_type = KernelType.by_name(data['kernel_type']) if new_kernel_type != system.kernel_type: record_activity(u'Kernel Type', system.kernel_type, new_kernel_type) system.kernel_type = new_kernel_type changed = True if 'hypervisor' in data: if data['hypervisor']: new_hypervisor = Hypervisor.by_name(data['hypervisor']) else: new_hypervisor = None if new_hypervisor != system.hypervisor: record_activity(u'Hypervisor', system.hypervisor, new_hypervisor) system.hypervisor = new_hypervisor changed = True if 'vendor' in data: new_vendor = data['vendor'] or None if new_vendor != system.vendor: record_activity(u'Vendor', system.vendor, new_vendor) system.vendor = new_vendor changed = True if 'model' in data: new_model = data['model'] or None if new_model != system.model: record_activity(u'Model', system.model, new_model) system.model = new_model changed = True if 'serial_number' in data: new_serial_number = data['serial_number'] or None if new_serial_number != system.serial: record_activity(u'Serial Number', system.serial, new_serial_number) system.serial = new_serial_number changed = True if 'mac_address' in data: new_mac_address = data['mac_address'] or None if new_mac_address != system.mac_address: record_activity(u'MAC Address', system.mac_address, new_mac_address) system.mac_address = new_mac_address changed = True if 'memory' in data: new_memory = int(data['memory']) if data['memory'] else None if new_memory != system.memory: record_activity(u'Memory', system.memory, new_memory) system.memory = new_memory changed = True if 'numa_nodes' in data: new_numa_nodes = int(data['numa_nodes']) if data['numa_nodes'] else None if not system.numa: system.numa = Numa() if new_numa_nodes != system.numa.nodes: record_activity(u'NUMA/Nodes', system.numa.nodes, new_numa_nodes) system.numa.nodes = new_numa_nodes changed = True if changed: # XXX clear checksum!? system.date_modified = datetime.datetime.utcnow() response = jsonify(system.__json__()) if renamed: response.headers.add('Location', url('/view/%s' % system.fqdn)) return response
def update_system(fqdn): system = _get_system_by_FQDN(fqdn) if not system.can_edit(identity.current.user): raise Forbidden403('Cannot edit system') data = read_json_request(request) # helper for recording activity below def record_activity(field, old, new, action=u'Changed'): system.record_activity(user=identity.current.user, service=u'HTTP', action=action, field=field, old=old, new=new) with convert_internal_errors(): # XXX what a nightmare... need to use a validation/conversion library, # and maybe simplify/relocate the activity recording stuff somehow changed = False renamed = False if 'fqdn' in data: new_fqdn = data['fqdn'].lower() if new_fqdn != system.fqdn: if System.query.filter(System.fqdn == new_fqdn).count(): raise Conflict409('System %s already exists' % new_fqdn) record_activity(u'FQDN', system.fqdn, new_fqdn) system.fqdn = new_fqdn changed = True renamed = True if 'owner' in data and data['owner'].get( 'user_name') != system.owner.user_name: if not system.can_change_owner(identity.current.user): raise Forbidden403('Cannot change owner') new_owner = User.by_user_name(data['owner'].get('user_name')) if new_owner is None: raise BadRequest400('No such user %s' % data['owner'].get('user_name')) record_activity(u'Owner', system.owner, new_owner) system.owner = new_owner changed = True if 'status' in data: new_status = SystemStatus.from_string(data['status']) if new_status != system.status: record_activity(u'Status', system.status, new_status) system.status = new_status if not new_status.bad and system.status_reason: # clear the status reason for "good" statuses record_activity(u'Status Reason', system.status_reason, None) system.status_reason = None changed = True if 'status_reason' in data: new_reason = data['status_reason'] or None if new_reason and not system.status.bad: raise ValueError('Cannot set status reason when status is %s' % system.status) if new_reason != system.status_reason: record_activity(u'Status Reason', system.status_reason, new_reason) system.status_reason = new_reason changed = True if 'type' in data: new_type = SystemType.from_string(data['type']) if new_type != system.type: record_activity(u'Type', system.type, new_type) system.type = new_type changed = True if 'arches' in data: new_arches = [Arch.by_name(a) for a in (data['arches'] or [])] added_arches = set(new_arches).difference(system.arch) removed_arches = set(system.arch).difference(new_arches) if added_arches or removed_arches: for added_arch in added_arches: record_activity(u'Arch', None, added_arch, u'Added') for removed_arch in removed_arches: record_activity(u'Arch', removed_arch, None, u'Removed') system.arch[:] = new_arches changed = True if 'lab_controller_id' in data: if data['lab_controller_id']: new_lc = LabController.by_id(data['lab_controller_id']) else: new_lc = None if new_lc != system.lab_controller: if system.open_reservation is not None: raise Conflict409( 'Unable to change lab controller while system ' 'is in use (return the system first)') record_activity(u'Lab Controller', system.lab_controller, new_lc) system.lab_controller = new_lc changed = True # If we're given any power-related keys, need to ensure system.power exists if not system.power and set(['power_type', 'power_address', 'power_user', 'power_password', 'power_id', 'power_quiescent_period'])\ .intersection(data.keys()): system.power = Power() if 'power_type' in data: new_power_type = PowerType.by_name(data['power_type']) if new_power_type != system.power.power_type: if not system.power.power_type: old_power_type = '' else: old_power_type = system.power.power_type.name record_activity(u'power_type', old_power_type, new_power_type.name) system.power.power_type = new_power_type changed = True if 'power_address' in data: new_power_address = data['power_address'] if not new_power_address: raise ValueError('Power address is required') if new_power_address != system.power.power_address: record_activity(u'power_address', system.power.power_address, data['power_address']) system.power.power_address = new_power_address changed = True if 'power_user' in data: new_power_user = data['power_user'] or u'' if new_power_user != (system.power.power_user or u''): record_activity(u'power_user', u'********', u'********') system.power.power_user = new_power_user changed = True if 'power_password' in data: new_power_password = data['power_password'] or u'' if new_power_password != (system.power.power_passwd or u''): record_activity(u'power_passwd', u'********', u'********') system.power.power_passwd = new_power_password changed = True if 'power_id' in data: new_power_id = data['power_id'] or u'' if new_power_id != (system.power.power_id or u''): record_activity(u'power_id', system.power.power_id, new_power_id) system.power.power_id = new_power_id changed = True if 'power_quiescent_period' in data: new_qp = int(data['power_quiescent_period']) if new_qp != system.power.power_quiescent_period: record_activity(u'power_quiescent_period', system.power.power_quiescent_period, new_qp) system.power.power_quiescent_period = new_qp changed = True if 'release_action' in data: new_release_action = ReleaseAction.from_string( data['release_action']) if new_release_action != (system.release_action or ReleaseAction.power_off): record_activity( u'release_action', (system.release_action or ReleaseAction.power_off), new_release_action) system.release_action = new_release_action changed = True if 'reprovision_distro_tree' in data: if (not data['reprovision_distro_tree'] or 'id' not in data['reprovision_distro_tree']): new_rpdt = None else: new_rpdt = DistroTree.by_id( data['reprovision_distro_tree']['id']) if new_rpdt != system.reprovision_distro_tree: record_activity(u'reprovision_distro_tree', unicode(system.reprovision_distro_tree), unicode(new_rpdt)) system.reprovision_distro_tree = new_rpdt changed = True if 'location' in data: new_location = data['location'] or None if new_location != system.location: record_activity(u'Location', system.location, new_location) system.location = new_location changed = True if 'lender' in data: new_lender = data['lender'] or None if new_lender != system.lender: record_activity(u'Lender', system.lender, new_lender) system.lender = new_lender changed = True if 'kernel_type' in data: new_kernel_type = KernelType.by_name(data['kernel_type']) if new_kernel_type != system.kernel_type: record_activity(u'Kernel Type', system.kernel_type, new_kernel_type) system.kernel_type = new_kernel_type changed = True if 'hypervisor' in data: if data['hypervisor']: new_hypervisor = Hypervisor.by_name(data['hypervisor']) else: new_hypervisor = None if new_hypervisor != system.hypervisor: record_activity(u'Hypervisor', system.hypervisor, new_hypervisor) system.hypervisor = new_hypervisor changed = True if 'vendor' in data: new_vendor = data['vendor'] or None if new_vendor != system.vendor: record_activity(u'Vendor', system.vendor, new_vendor) system.vendor = new_vendor changed = True if 'model' in data: new_model = data['model'] or None if new_model != system.model: record_activity(u'Model', system.model, new_model) system.model = new_model changed = True if 'serial_number' in data: new_serial_number = data['serial_number'] or None if new_serial_number != system.serial: record_activity(u'Serial Number', system.serial, new_serial_number) system.serial = new_serial_number changed = True if 'mac_address' in data: new_mac_address = data['mac_address'] or None if new_mac_address != system.mac_address: record_activity(u'MAC Address', system.mac_address, new_mac_address) system.mac_address = new_mac_address changed = True if 'memory' in data: new_memory = int(data['memory']) if data['memory'] else None if new_memory != system.memory: record_activity(u'Memory', system.memory, new_memory) system.memory = new_memory changed = True if 'numa_nodes' in data: new_numa_nodes = int( data['numa_nodes']) if data['numa_nodes'] else None if not system.numa: system.numa = Numa() if new_numa_nodes != system.numa.nodes: record_activity(u'NUMA/Nodes', system.numa.nodes, new_numa_nodes) system.numa.nodes = new_numa_nodes changed = True if changed: # XXX clear checksum!? system.date_modified = datetime.datetime.utcnow() response = jsonify(system.__json__()) if renamed: response.headers.add('Location', url('/view/%s' % system.fqdn)) return response
def update_labcontroller(fqdn): """ Updates attributes of the lab controller identified by it's FQDN. The request body must be a json object or only the FQDN if that is the only value to be updated. :param string fqdn: Lab controller's new fully-qualified domain name. :jsonparam string user_name: User name associated with the lab controller. :jsonparam string email_address: Email of the user account associated with the lab controller. :jsonparam string password: Optional password for the user account used to login. :jsonparam string removed: If True, detaches all systems, cancels all running recipes and removes associated distro trees. If False, restores the lab controller. :jsonparam bool disabled: Whether the lab controller should be disabled. New recipes are not scheduled on a lab controller while it is disabled. :status 200: LabController updated. :status 400: Invalid data was given. """ labcontroller = find_labcontroller_or_raise404(fqdn) if not labcontroller.can_edit(identity.current.user): raise Forbidden403('Cannot edit lab controller') data = read_json_request(request) with convert_internal_errors(): # should the lab controller be removed? if data.get('removed', False) and not labcontroller.removed: remove_labcontroller(labcontroller) # should the controller be restored? if data.get('removed') is False and labcontroller.removed: restore_labcontroller(labcontroller) fqdn_changed = False new_fqdn = data.get('fqdn', fqdn) if labcontroller.fqdn != new_fqdn: lc = None try: lc = LabController.by_name(new_fqdn) except NoResultFound: pass if lc is not None: raise BadRequest400('FQDN %s already in use' % new_fqdn) labcontroller.record_activity(user=identity.current.user, service=u'HTTP', field=u'fqdn', action=u'Changed', old=labcontroller.fqdn, new=new_fqdn) labcontroller.fqdn = new_fqdn labcontroller.user.display_name = new_fqdn fqdn_changed = True if 'user_name' in data: user = find_user_or_create(data['user_name']) if labcontroller.user != user: user = update_user(user, display_name=new_fqdn, email_address=data.get( 'email_address', user.email_address), password=data.get('password', user.password)) labcontroller.record_activity(user=identity.current.user, service=u'HTTP', field=u'User', action=u'Changed', old=labcontroller.user.user_name, new=user.user_name) labcontroller.user = user if 'email_address' in data: new_email_address = data.get('email_address') if labcontroller.user.email_address != new_email_address: labcontroller.user.email_address = new_email_address if data.get('password') is not None: labcontroller.user.password = data.get('password') if labcontroller.disabled != data.get('disabled', labcontroller.disabled): labcontroller.record_activity(user=identity.current.user, service=u'HTTP', field=u'disabled', action=u'Changed', old=unicode(labcontroller.disabled), new=data['disabled']) labcontroller.disabled = data['disabled'] response = jsonify(labcontroller.__json__()) if fqdn_changed: response.headers.add('Location', absolute_url(labcontroller.href)) return response
def _from_csv(cls,system,data,csv_type,log): """ Import data from CSV file into System Objects """ for key in data.keys(): if key in cls.reg_keys and key != 'id': if data[key]: newdata = smart_bool(data[key]) else: newdata = None current_data = getattr(system, key, None) if unicode(newdata) != unicode(current_data): setattr(system,key,newdata) system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=key, old=u'%s' % current_data, new=u'%s' % newdata) # import arch if 'arch' in data: arch_objs = [] if data['arch']: arches = data['arch'].split(',') for arch in arches: try: arch_obj = Arch.by_name(arch) except ValueError: raise ValueError("%s: Invalid arch %s" % (system.fqdn, arch)) arch_objs.append(arch_obj) if system.arch != arch_objs: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'arch', old=u'%s' % system.arch, new=u'%s' % arch_objs) system.arch = arch_objs # import cc if 'cc' in data: cc_objs = [] if data['cc']: cc_objs = data['cc'].split(',') if system.cc != cc_objs: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'cc', old=u'%s' % system.cc, new=u'%s' % cc_objs) system.cc = cc_objs # import labController if 'lab_controller' in data: if data['lab_controller']: try: lab_controller = LabController.by_name(data['lab_controller']) except InvalidRequestError: raise ValueError("%s: Invalid lab controller %s" % (system.fqdn, data['lab_controller'])) else: lab_controller = None if system.lab_controller != lab_controller: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'lab_controller', old=u'%s' % system.lab_controller, new=u'%s' % lab_controller) system.lab_controller = lab_controller # import owner if 'owner' in data: if data['owner']: owner = User.by_user_name(data['owner']) if not owner: raise ValueError("%s: Invalid User %s" % (system.fqdn, data['owner'])) else: owner = None if system.owner != owner: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'owner', old=u'%s' % system.owner, new=u'%s' % owner) system.owner = owner # import status if 'status' in data and data['status']: try: systemstatus = SystemStatus.from_string(data['status']) except ValueError: raise ValueError("%s: Invalid Status %s" % (system.fqdn, data['status'])) if system.status != systemstatus: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'status', old=u'%s' % system.status, new=u'%s' % systemstatus) system.status = systemstatus # import type if 'type' in data: if not data['type']: raise ValueError("%s: Invalid Type None" % system.fqdn) try: systemtype = SystemType.from_string(data['type']) except ValueError: raise ValueError("%s: Invalid Type %s" % (system.fqdn, data['type'])) if system.type != systemtype: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'type', old=u'%s' % system.type, new=u'%s' % systemtype) system.type = systemtype # import secret if 'secret' in data: # 'private' used to be a field on system (called 'secret' in the UI # and CSV). The field is replaced by the 'view' permission in the # access policy so CSV export no longer produces 'secret' in its # output. However we still accept it on import for compatibility. # It is mapped to the 'view everybody' rule in the access policy. if not data['secret']: raise ValueError("%s: Invalid secret None" % system.fqdn) secret = smart_bool(data['secret']) view_everybody = system.custom_access_policy.grants_everybody( SystemPermission.view) if secret and view_everybody: # remove 'view everybody' rule for rule in system.custom_access_policy.rules: if rule.permission == SystemPermission.view and rule.everybody: system.record_activity(user=identity.current.user, service=u'HTTP', field=u'Access Policy Rule', action=u'Removed', old=repr(rule)) session.delete(rule) if not secret and not view_everybody: # add rule granting 'view everybody' new_rule = system.custom_access_policy.add_rule(everybody=True, permission=SystemPermission.view) system.record_activity(user=identity.current.user, service=u'HTTP', field=u'Access Policy Rule', action=u'Added', new=repr(new_rule))
def _from_csv(cls, system, data, csv_type, log): """ Import data from CSV file into System Objects """ for key in data.keys(): if key in cls.reg_keys and key != 'id': if data[key]: newdata = smart_bool(data[key]) else: newdata = None current_data = getattr(system, key, None) if unicode(newdata) != unicode(current_data): setattr(system, key, newdata) system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=key, old=u'%s' % current_data, new=u'%s' % newdata) # import arch if 'arch' in data: arch_objs = [] if data['arch']: arches = data['arch'].split(',') for arch in arches: try: arch_obj = Arch.by_name(arch) except ValueError: raise ValueError("%s: Invalid arch %s" % (system.fqdn, arch)) arch_objs.append(arch_obj) if system.arch != arch_objs: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'arch', old=u'%s' % system.arch, new=u'%s' % arch_objs) system.arch = arch_objs # import cc if 'cc' in data: cc_objs = [] if data['cc']: cc_objs = data['cc'].split(',') if system.cc != cc_objs: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'cc', old=u'%s' % system.cc, new=u'%s' % cc_objs) system.cc = cc_objs # import labController if 'lab_controller' in data: if data['lab_controller']: try: lab_controller = LabController.by_name( data['lab_controller']) except InvalidRequestError: raise ValueError("%s: Invalid lab controller %s" % (system.fqdn, data['lab_controller'])) else: lab_controller = None if system.lab_controller != lab_controller: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'lab_controller', old=u'%s' % system.lab_controller, new=u'%s' % lab_controller) system.lab_controller = lab_controller # import owner if 'owner' in data: if data['owner']: owner = User.by_user_name(data['owner']) if not owner: raise ValueError("%s: Invalid User %s" % (system.fqdn, data['owner'])) if owner.removed: raise ValueError('%s: user %s is deleted' % (system.fqdn, owner.user_name)) else: owner = None if system.owner != owner: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'owner', old=u'%s' % system.owner, new=u'%s' % owner) system.owner = owner # import status if 'status' in data and data['status']: try: systemstatus = SystemStatus.from_string(data['status']) except ValueError: raise ValueError("%s: Invalid Status %s" % (system.fqdn, data['status'])) if system.status != systemstatus: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'status', old=u'%s' % system.status, new=u'%s' % systemstatus) system.status = systemstatus # import type if 'type' in data: if not data['type']: raise ValueError("%s: Invalid Type None" % system.fqdn) try: systemtype = SystemType.from_string(data['type']) except ValueError: raise ValueError("%s: Invalid Type %s" % (system.fqdn, data['type'])) if system.type != systemtype: system.record_activity(user=identity.current.user, service=u'CSV', action=u'Changed', field=u'type', old=u'%s' % system.type, new=u'%s' % systemtype) system.type = systemtype # import secret if 'secret' in data: # 'private' used to be a field on system (called 'secret' in the UI # and CSV). The field is replaced by the 'view' permission in the # access policy so CSV export no longer produces 'secret' in its # output. However we still accept it on import for compatibility. # It is mapped to the 'view everybody' rule in the access policy. if not data['secret']: raise ValueError("%s: Invalid secret None" % system.fqdn) secret = smart_bool(data['secret']) view_everybody = system.custom_access_policy.grants_everybody( SystemPermission.view) if secret and view_everybody: # remove 'view everybody' rule for rule in system.custom_access_policy.rules: if rule.permission == SystemPermission.view and rule.everybody: system.record_activity(user=identity.current.user, service=u'HTTP', field=u'Access Policy Rule', action=u'Removed', old=repr(rule)) session.delete(rule) if not secret and not view_everybody: # add rule granting 'view everybody' new_rule = system.custom_access_policy.add_rule( everybody=True, permission=SystemPermission.view) system.record_activity(user=identity.current.user, service=u'HTTP', field=u'Access Policy Rule', action=u'Added', new=repr(new_rule))
def get_lc(): return LabController.by_name(lc_fqdn)
def update_labcontroller(fqdn): """ Updates attributes of the lab controller identified by it's FQDN. The request body must be a json object or only the FQDN if that is the only value to be updated. :param string fqdn: Lab controller's new fully-qualified domain name. :jsonparam string user_name: User name associated with the lab controller. :jsonparam string email_address: Email of the user account associated with the lab controller. :jsonparam string password: Optional password for the user account used to login. :jsonparam string removed: If True, detaches all systems, cancels all running recipes and removes associated distro trees. If False, restores the lab controller. :jsonparam bool disabled: Whether the lab controller should be disabled. New recipes are not scheduled on a lab controller while it is disabled. :status 200: LabController updated. :status 400: Invalid data was given. """ labcontroller = find_labcontroller_or_raise404(fqdn) if not labcontroller.can_edit(identity.current.user): raise Forbidden403('Cannot edit lab controller') data = read_json_request(request) with convert_internal_errors(): # should the lab controller be removed? if data.get('removed', False) and not labcontroller.removed: remove_labcontroller(labcontroller) # should the controller be restored? if data.get('removed') is False and labcontroller.removed: restore_labcontroller(labcontroller) fqdn_changed = False new_fqdn = data.get('fqdn', fqdn) if labcontroller.fqdn != new_fqdn: lc = None try: lc = LabController.by_name(new_fqdn) except NoResultFound: pass if lc is not None: raise BadRequest400('FQDN %s already in use' % new_fqdn) labcontroller.record_activity( user=identity.current.user, service=u'HTTP', field=u'fqdn', action=u'Changed', old=labcontroller.fqdn, new=new_fqdn) labcontroller.fqdn = new_fqdn labcontroller.user.display_name = new_fqdn fqdn_changed = True if 'user_name' in data: user = find_user_or_create(data['user_name']) if labcontroller.user != user: user = update_user( user, display_name=new_fqdn, email_address=data.get('email_address', user.email_address), password=data.get('password', user.password) ) labcontroller.record_activity( user=identity.current.user, service=u'HTTP', field=u'User', action=u'Changed', old=labcontroller.user.user_name, new=user.user_name) labcontroller.user = user if 'email_address' in data: new_email_address = data.get('email_address') if labcontroller.user.email_address != new_email_address: labcontroller.user.email_address = new_email_address if data.get('password') is not None: labcontroller.user.password = data.get('password') if labcontroller.disabled != data.get('disabled', labcontroller.disabled): labcontroller.record_activity( user=identity.current.user, service=u'HTTP', field=u'disabled', action=u'Changed', old=unicode(labcontroller.disabled), new=data['disabled']) labcontroller.disabled = data['disabled'] response = jsonify(labcontroller.__json__()) if fqdn_changed: response.headers.add('Location', absolute_url(labcontroller.href)) return response
def test_lookup_secret_fqdn(self): with session.begin(): system = data_setup.create_system(private=True) lab_controller_user = LabController.by_name(self.lc_fqdn).user system2 = System.by_fqdn(str(system.fqdn), user=lab_controller_user) self.assertEquals(system, system2)
def get_lc(self): return LabController.by_name(self.get_lc_fqdn())