def login(self): if self.request.POST: username = self.request.POST.get('username') password = self.request.POST.get('password') try: user = self.request.userdb.login(username, password) except UserDoesNotExist: return { 'username': username, 'message': self.translate( _("Please enter the correct username and password")), } if user is False: return { 'username': username, 'message': self.translate( _("Please enter the correct username and password")), } headers = remember(self.request, username) created_msg( self.request, self.translate( _('Welcome ${username}', mapping={'username': user['username']})), 'info') return HTTPFound(location=self.request.route_path('home'), headers=headers) else: return {}
def login(self): if self.request.POST: username = self.request.POST.get('username') password = self.request.POST.get('password') try: user = self.request.userdb.login(username, password) except UserDoesNotExist: return { 'username': username, 'message': self.translate( _("Please enter the correct username and password")), } if user is False: return { 'username': username, 'message': self.translate(_("Please enter the correct username and password")), } headers = remember(self.request, username) created_msg(self.request, self.translate( _('Welcome ${username}', mapping={'username': user['username']}) ), 'info') return HTTPFound(location=self.request.route_path('home'), headers=headers) else: return {}
class AdminUserOUManage(colander.MappingSchema): ou_managed = colander.SchemaNode(colander.List(), title=_('This user can register workstation under these Organitation Units'), widget=deferred_choices_widget) ou_availables = colander.SchemaNode(colander.List(), title=_('Organitation Unit availables to register workstations by this user'), widget=deferred_choices_widget)
def login(self): if self.request.POST: username = self.request.POST.get('username') password = self.request.POST.get('password') try: user = self.request.userdb.login(username, password) except UserDoesNotExist: return { 'username': username, 'message': self.translate( _("The requested username doesn't exists")), } if user is False: return { 'username': username, 'message': self.translate(_("The password doesn't match")), } headers = remember(self.request, username) self.request.session.flash(self.translate( _('welcome ${username}', mapping={'username': user['username']}) )) return HTTPFound(location=self.request.route_path('home'), headers=headers) else: return {}
def login(self): if self.request.POST: username = self.request.POST.get('username') password = self.request.POST.get('password') try: user = self.request.userdb.login(username, password) except UserDoesNotExist: return { 'username': username, 'message': self.translate(_("The requested username doesn't exists")), } if user is False: return { 'username': username, 'message': self.translate(_("The password doesn't match")), } headers = remember(self.request, username) self.request.session.flash( self.translate( _('welcome ${username}', mapping={'username': user['username']}))) return HTTPFound(location=self.request.route_path('home'), headers=headers) else: return {}
def save(self, postvars): logger.debug( "forms.py ::: MaintenanceForm - postvars = {0}".format(postvars)) if postvars['maintenance_message'] == "": logger.debug( "forms.py ::: MaintenanceForm - Deleting maintenance message") self.request.db.settings.delete_one({'key': 'maintenance_message'}) self.created_msg( _('Maintenance message was deleted successfully.')) else: logger.debug( "forms.py ::: MaintenanceForm - Creating maintenance message") compose = postvars['maintenance_message'] maintenance_mode(self.request, compose) msg = self.request.db.settings.find_one( {'key': 'maintenance_message'}) if msg is None: msg = { 'key': 'maintenance_message', 'value': compose, 'type': 'string' } self.request.db.settings.insert_one(msg) else: self.request.db.settings.update_one( {'key': 'maintenance_message'}, {'$set': { 'value': compose }}) self.request.session['maintenance_message'] = compose self.created_msg(_('Maintenance settings saved successfully.'))
class BaseUser(colander.MappingSchema): first_name = colander.SchemaNode(colander.String(), title=_('First name'), default='', missing='') last_name = colander.SchemaNode(colander.String(), title=_('Last name'), default='', missing='')
def admins_superuser(context, request): username = request.matchdict['username'] if '_superuser' in request.POST: is_superuser = True message = _('Now the user is a super user') elif '_no_superuser' in request.POST: is_superuser = False message = _('Now the user is not a super user') message.translate('es') request.userdb.collection.update({'username': username}, {'$set': {'is_superuser': is_superuser}}) messages.created_msg(request, message, 'success') return HTTPFound(location=request.route_url('admins'))
class ActiveDirectoryVariableSpecific(colander.MappingSchema): sssd_conf = colander.SchemaNode(deform.FileData(), widget=FileUploadWidget(filestore), title=_('SSSD conf')) krb5_conf = colander.SchemaNode(deform.FileData(), widget=FileUploadWidget(filestore), title=_('KRB5 conf')) smb_conf = colander.SchemaNode(deform.FileData(), widget=FileUploadWidget(filestore), title=_('SMB conf')) pam_conf = colander.SchemaNode(deform.FileData(), widget=FileUploadWidget(filestore), title=_('PAM conf'))
class AdminUserOUPerm(colander.MappingSchema): ou_selected = colander.SchemaNode(colander.List(), title=_('Select an Organization Unit'), widget=deferred_choices_widget) permission = colander.SchemaNode(colander.Set(), title=_('Permissions'), validator=colander.All( colander.Length(min=1), PermissionValidator()), widget=deform.widget.CheckboxChoiceWidget( values=PERMISSIONS, inline=True))
class Setting(colander.MappingSchema): _id = colander.SchemaNode(ObjectIdField()) key = colander.SchemaNode(colander.String(), title=_('Key'), default='', missing='') value = colander.SchemaNode(colander.String('UTF-8'), title=_('Value'), default='', missing='') type = colander.SchemaNode(colander.String(), title=_('Type'), default='', missing='')
def admin_delete(context, request): if request.method != 'DELETE': raise HTTPMethodNotAllowed("Only delete method is accepted") username = request.GET.get('username') if request.session['auth.userid'] == username: forget(request) settings = get_current_registry().settings api = get_chef_api(settings, request.user) success_remove_chef = delete_chef_admin_user(api, username) if not success_remove_chef: messages.created_msg(request, _('User deleted unsuccessfully from chef'), 'danger') request.userdb.delete_users({'username': username}) messages.created_msg(request, _('User deleted successfully'), 'success') return {'ok': 'ok'}
def __init__(self, schema, collection, *args, **kwargs): buttons = (GecosButton(title=_('Submit'), css_class='pull-right', name='_submit'), GecosButton(title=_('Delete'), name='_delete', css_class='pull-right', type='button')) super(AdminUserEditForm, self).__init__(schema, collection, buttons=buttons, *args, **kwargs) schema.children[self.sorted_fields.index('password')] = schema.children[self.sorted_fields.index('password')].clone() schema.children[self.sorted_fields.index('repeat_password')] = schema.children[self.sorted_fields.index('repeat_password')].clone() schema.children[self.sorted_fields.index('password')].missing = '' schema.children[self.sorted_fields.index('repeat_password')].missing = '' self.children[self.sorted_fields.index('username')].widget.readonly = True
def __call__(self, node, value): super(UpdateSequenceValidator, self).__call__(node,value) if self.filename: m = re.match(self.pattern, self.filename) request = pyramid.threadlocal.get_current_request() from gecoscc.db import get_db mongodb = get_db(request) nextseq = getNextUpdateSeq(mongodb) # Numeric update naming if m is not None and m.group(1) != nextseq: err_msg = _(self.err_msg, mapping={'val': nextseq}) node.raise_invalid(err_msg) else: if mongodb.updates.find({'name':self.filename}).count() > 0: node.raise_invalid(_('This name already exists'))
def admins_superuser(context, request): username = request.matchdict['username'] if '_superuser' in request.POST: is_superuser = True message = _('Now the user is a super user') elif '_no_superuser' in request.POST: is_superuser = False message = _('Now the user is not a super user') message.translate('es') request.userdb.collection.update({'username': username}, {'$set': { 'is_superuser': is_superuser }}) messages.created_msg(request, message, 'success') return HTTPFound(location=request.route_url('admins'))
def settings_save(_context, request): data = request.POST.get('data') response = Response() if data is not None: data = json.loads(data) for key in data: k = key.replace("___", ".") setting_data = request.db.settings.find_one({"key": k}) if setting_data is None: setting = create_setting(k) else: setting = Setting().deserialize(setting_data) if isinstance(data[key], str): Setting().set_value(setting, 'value', data[key]) else: Setting().set_value(setting, 'value', json.dumps(data[key])) # Save in mongoDB obj = Setting().serialize(setting) if obj['_id'] == colander.null: del obj['_id'] request.db.settings.insert_one(obj) else: obj['_id'] = ObjectId(obj['_id']) request.db.settings.replace_one({'_id': obj['_id']}, obj) messages.created_msg(request, _('Settings modified successfully'), 'success') response.write('SUCCESS') return response
def __call__(self, node, value): if value['password'] != value['repeat_password']: node.raise_invalid(_('The passwords do not match')) from gecoscc.userdb import create_password if bool(value['password']): value['password'] = create_password(value['password']) del value['repeat_password']
class LowerAlphaNumeric(object): err_msg = _('Only lowercase letters, numbers or dots') regex = re.compile(r'^([a-z0-9\.])*$') def __call__(self, node, value): if not self.regex.match(value): node.raise_invalid(self.err_msg)
class UpdateSequenceValidator(UpdateBaseValidator): ''' Subclass for validating numeric sequence of an update Attributes: err_msg (str): error message pattern (str): regex for valid numeric sequence ''' err_msg = _('No valid update sequence. Must be: {$val}') def __call__(self, node, value): super(UpdateSequenceValidator, self).__call__(node,value) if self.filename: m = re.match(SERIALIZED_UPDATE_PATTERN, self.filename) request = pyramid.threadlocal.get_current_request() from gecoscc.db import get_db mongodb = get_db(request) nextseq = getNextUpdateSeq(mongodb) # Numeric update naming if m is not None and m.group(1) != nextseq: err_msg = _(self.err_msg, mapping={'val': nextseq}) node.raise_invalid(err_msg) else: if mongodb.updates.find({'name':self.filename}).count() > 0: node.raise_invalid(_('This name already exists')) sequence = re.match(BASE_UPDATE_PATTERN, self.filename).group(1) if mongodb.updates.find({'_id': sequence}).count() > 0: node.raise_invalid(_('This sequence already exists'))
class Maintenance(colander.MappingSchema): maintenance_message = colander.SchemaNode(colander.String(), validator=colander.Length(max=500), widget=deform.widget.TextAreaWidget(rows=10, cols=80, maxlength=500, css_class='deform-widget-textarea-maintenance'), title=_('Users will be warned with this message'), default='', missing='')
class UpdateFileStructureValidator(UpdateBaseValidator): ''' Subclass for validating zip file content This structure is defined by UPDATE_STRUCTURE variable in this file. UPDATE_STRUCTURE = ['control','cookbook/','scripts/'] Attributes: err_msg (str): error message ''' err_msg = _('No valid zip file structure') def __call__(self, node, value): super(UpdateFileStructureValidator, self).__call__(node,value) if os.path.isdir(self.decompress): for archive in os.listdir(self.decompress): # Adding slash if archive is a dir for comparison if os.path.isdir(self.decompress + archive): archive += os.sep if archive not in UPDATE_STRUCTURE: node.raise_invalid(gettext(self.err_msg)) for required in UPDATE_STRUCTURE: if not os.path.exists(self.decompress + required): node.raise_invalid(gettext(self.err_msg))
def admin_delete(context, request): if request.method != 'DELETE': raise HTTPMethodNotAllowed("Only delete method is accepted") username = request.GET.get('username') if request.session['auth.userid'] == username: forget(request) settings = get_current_registry().settings api = get_chef_api(settings, request.user) success_remove_chef = delete_chef_admin_user(api, username) if not success_remove_chef: messages.created_msg(request, _('User deleted unsuccessfully from chef'), 'danger') request.userdb.delete_user({'username': username}) messages.created_msg(request, _('User deleted successfully'), 'success') return {'ok': 'ok'}
def __init__(self, schema, action='', method='POST', buttons=(), formid='deform', use_ajax=False, ajax_options='{}', autocomplete=None, **kw): if not buttons: buttons = (GecosButton(title=_('Submit'), css_class='pull-right'), ) if self.sorted_fields: schema.children.sort( key=lambda item: self.sorted_fields.index(item.name)) super(GecosForm, self).__init__(schema, action=action, method=method, buttons=buttons, formid='deform', use_ajax=use_ajax, ajax_options=ajax_options, autocomplete=None, **kw) self.widget.template = self.template self.widget.item_template = self.item_template self.widget.css_class = self.css_class
class AuthLDAPVariable(colander.MappingSchema): uri = colander.SchemaNode(colander.String(), title=_('uri'), default='URL_LDAP') base = colander.SchemaNode(colander.String(), title=_('base'), default='OU_BASE_USER') basegroup = colander.SchemaNode(colander.String(), title=_('base group'), default='OU_BASE_GROUP') binddn = colander.SchemaNode(colander.String(), title=_('binddn'), default='USER_WITH_BIND_PRIVILEGES') bindpwd = colander.SchemaNode(colander.String(), title=_('bindpwd'), default='PASSWORD_USER_BIND')
def settings_save(_context, request): data = request.POST.get('data') response = Response() if data is not None: data = json.loads(data) for key in data: k = key.replace("___", ".") setting_data = request.db.settings.find_one({"key": k }) if setting_data is None: setting = create_setting(k) else: setting = Setting().deserialize(setting_data) if isinstance(data[key], str) or isinstance(data[key], unicode): Setting().set_value(setting, 'value', data[key]) else: Setting().set_value(setting, 'value', json.dumps(data[key])) # Save in mongoDB obj = Setting().serialize(setting) if obj['_id'] == colander.null: del obj['_id'] else: obj['_id'] = ObjectId(obj['_id']) #logger.debug('save= %s'%(obj)) request.db.settings.save(obj) messages.created_msg(request, _('Settings modified successfully'), 'success') response.write('SUCCESS') return response
def save(self, update): settings = get_current_registry().settings update = update['local_file'] if update['local_file'] is not None else update['remote_file'] sequence = re.match('^update-(\w+)\.zip$', update['filename']).group(1) logger.debug("forms.py ::: UpdateForm - sequence = %s" % sequence) # Updates directory: /opt/gecoscc/updates/<sequence> updatesdir = settings['updates.dir'] + sequence logger.debug("forms.py ::: UpdateForm - updatesdir = %s" % updatesdir) # Update zip file zipped = settings['updates.tmp'] + update['filename'] logger.debug("forms.py ::: UpdateForm - zipped = %s" % zipped) try: # https://docs.python.org/2/library/shutil.html # The destination directory, named by dst, must not already exist; it will be created as well as missing parent directories # Checking copytree NFS shutil.copytree(update['decompress'], updatesdir) shutil.rmtree(update['decompress']) # Move zip file to updates dir shutil.move(zipped, updatesdir) # Decompress cookbook zipfile cookbookdir = settings['updates.cookbook'].format(sequence) logger.debug("forms.py ::: UpdateForm - cookbookdir = %s" % cookbookdir) for cookbook in os.listdir(cookbookdir): cookbook = cookbookdir + os.sep + cookbook logger.debug("forms.py ::: UpdateForm - cookbook = %s" % cookbook) if zipfile.is_zipfile(cookbook): zip_ref = zipfile.ZipFile(cookbook,'r') zip_ref.extractall(cookbookdir + os.sep + settings['chef.cookbook_name']) zip_ref.close() # Insert update register self.request.db.updates.insert({'_id': sequence, 'name': update['filename'], 'path': updatesdir, 'timestamp': int(time.time()), 'rollback':0, 'user': self.request.user['username']}) # Launching task for script execution script_runner.delay(self.request.user, sequence) link = '<a href="' + self.request.route_url('updates_tail',sequence=sequence) + '">' + _("here") + '</a>' self.created_msg(_("Update log. %s") % link) except OSError as e: error = True if e.errno == errno.EACCES: self.created_msg(_('Permission denied: %s') % updatesdir, 'danger') else: self.created_msg(_('There was an error attempting to upload an update. Please contact an administrator'), 'danger') except (IOError, os.error) as e: pass except errors.DuplicateKeyError as e: logger.error('Duplicate key error') self.created_msg(_('There was an error attempting to upload an update. Please contact an administrator'), 'danger')
def save(self, admin_user): if admin_user['password'] == '': del admin_user['password'] self.collection.update({'username': self.username}, {'$set': admin_user}) if admin_user['username'] != self.username and self.request.session['auth.userid'] == self.username: self.request.session['auth.userid'] = admin_user['username'] self.created_msg(_('User edited successfully'))
def __init__(self, schema, collection, username, request, *args, **kwargs): schema.get( 'ou_managed' ).title += '<p><a href="#ou-managed" class="add-another">%s</a></p>' % _( 'Add another') schema.get( 'ou_availables' ).title += '<p><a href="#ou-availables" class="add-another">%s</a></p>' % _( 'Add another') schema.children.append(self.ou_managed_count) schema.children.append(self.ou_availables_count) super(AdminUserOUManageForm, self).__init__(schema, collection=collection, username=username, request=request, *args, **kwargs)
def save(self, admin_user): if admin_user['password'] == '': del admin_user['password'] self.collection.update({'username': self.username}, {'$set': admin_user}) if admin_user['username'] != self.username and self.request.session[ 'auth.userid'] == self.username: self.request.session['auth.userid'] = admin_user['username'] self.created_msg(_('User edited successfully'))
def __init__(self, schema, request, *args, **kwargs): self.request = request buttons = (GecosButton(title=_('Submit'), css_class='deform-maintenance-submit'), ) super(MaintenanceForm, self).__init__(schema, buttons=buttons, *args, **kwargs)
def __call__(self, node, value): super(UpdateSequenceValidator, self).__call__(node,value) if self.filename: m = re.match(SERIALIZED_UPDATE_PATTERN, self.filename) request = pyramid.threadlocal.get_current_request() from gecoscc.db import get_db mongodb = get_db(request) nextseq = getNextUpdateSeq(mongodb) # Numeric update naming if m is not None and m.group(1) != nextseq: err_msg = _(self.err_msg, mapping={'val': nextseq}) node.raise_invalid(err_msg) else: if mongodb.updates.find({'name':self.filename}).count() > 0: node.raise_invalid(_('This name already exists')) sequence = re.match(BASE_UPDATE_PATTERN, self.filename).group(1) if mongodb.updates.find({'_id': sequence}).count() > 0: node.raise_invalid(_('This sequence already exists'))
def __call__(self, node, value): ignore_unique = getattr(node, 'ignore_unique', False) if ignore_unique: return request = pyramid.threadlocal.get_current_request() from gecoscc.db import get_db mongodb = get_db(request) if mongodb.adminusers.find({node.name: value}).count() > 0: err_msg = _(self.err_msg, mapping={'val': value}) node.raise_invalid(err_msg)
def save(self, postvars): logger.debug("forms.py ::: MaintenanceForm - postvars = {0}".format(postvars)) if postvars['maintenance_message'] == "": logger.debug("forms.py ::: MaintenanceForm - Deleting maintenance message") self.request.db.settings.remove({'key':'maintenance_message'}) self.created_msg(_('Maintenance message was deleted successfully.')) else: logger.debug("forms.py ::: MaintenanceForm - Creating maintenance message") compose = postvars['maintenance_message'] maintenance_mode(self.request, compose) msg = self.request.db.settings.find_one({'key':'maintenance_message'}) if msg is None: msg = {'key':'maintenance_message', 'value': compose, 'type':'string'} self.request.db.settings.insert(msg) else: self.request.db.settings.update({'key':'maintenance_message'},{'$set':{ 'value': compose}}) self.request.session['maintenance_message'] = compose self.created_msg(_('Maintenance settings saved successfully.'))
class AdminUserVariables(colander.MappingSchema): uri_ntp = colander.SchemaNode(colander.String(), default='URI_NTP_SERVER.EX', title=_('URI ntp')) auth_type = colander.SchemaNode(colander.String(), title=_('Auth type'), default='LDAP', widget=deform.widget.SelectWidget(values=AUTH_TYPE_CHOICES)) specific_conf = colander.SchemaNode(colander.Boolean(), title=_('Specific conf'), default=False) auth_ldap = AuthLDAPVariable(title=_('Auth LDAP')) auth_ad = ActiveDirectoryVariableNoSpecific(title=_('Auth Active directory')) auth_ad_spec = ActiveDirectoryVariableSpecific(title=_('Auth Active directory')) def get_config_files(self, mode, username): return self.get_files(mode, username, ['sssd.conf', 'krb5.conf', 'smb.conf', 'pam.conf']) def get_files(self, mode, username, file_name): settings = get_current_registry().settings first_boot_media = settings.get('firstboot_api.media') user_media = os.path.join(first_boot_media, username) if mode == 'w' and not os.path.exists(user_media): os.makedirs(user_media) if isinstance(file_name, list): files = [open(os.path.join(user_media, name), mode) for name in file_name] return files return open(os.path.join(user_media, file_name), mode)
class UpdateNamingValidator(UpdateBaseValidator): ''' Subclass for validating naming convention of an update Attributes: err_msg (str): error message pattern (str): regex for valid naming convention ''' err_msg = _('The uploaded file is not followed naming convention') pattern = BASE_UPDATE_PATTERN def __call__(self, node, value): super(UpdateNamingValidator, self).__call__(node, value) if self.filename and not (re.match(self.pattern, self.filename)): node.raise_invalid(self.err_msg)
def save(self, admin_user): self.collection.insert(admin_user) admin_user['plain_password'] = self.cstruct['password'] settings = get_current_registry().settings user = self.request.user api = get_chef_api(settings, user) try: create_chef_admin_user(api, settings, admin_user['username']) self.created_msg(_('User created successfully')) return True except ChefServerError as e: self.created_msg(e.message, 'danger') self.collection.remove({'username': admin_user['username']}) raise e
class AdminUser(BaseUser): validator = AdminUserValidator() username = colander.SchemaNode(colander.String(), title=_('Username'), validator=colander.All( Unique('adminusers', 'There is a user with this username: ${val}'), LowerAlphaNumeric())) password = colander.SchemaNode(colander.String(), title=_('Password'), widget=deform.widget.PasswordWidget(), validator=colander.Length(min=6)) repeat_password = colander.SchemaNode(colander.String(), default='', title=_('Repeat the password'), widget=deform.widget.PasswordWidget(), validator=colander.Length(min=6)) email = colander.SchemaNode(colander.String(), title=_('Email'), validator=colander.All( colander.Email(), Unique('adminusers', 'There is a user with this email: ${val}')))
def save(self, variables): if variables['auth_type'] != 'LDAP' and variables.get('specific_conf', False): for i, fileout in enumerate(self.schema.get_config_files('w', self.username)): fileout_name = fileout.name.split(os.sep)[-1] file_field = variables['auth_ad_spec'][fileout_name.replace('.', '_')] if not file_field: continue filein = file_field['fp'] fileout.write(filein.read()) filein.close() fileout.close() del variables['auth_ad_spec'] self.collection.update({'username': self.username}, {'$set': {'variables': variables}}) self.created_msg(_('Variables updated successfully'))
class RemoteStoragePolicy(BasePolicy): name = 'remote-storage' screen_name = _('Remote Storage') schema = { 'type': 'object', 'properties': { 'name': { 'type': 'string' }, 'node': { 'type': 'string' }, 'storage_id': { 'type': 'string' }, 'storage_node': { 'type': 'object', 'properties': { 'memberof': { 'type': 'array' }, 'server': { 'type': 'string' }, 'port': { 'type': 'integer' }, 'protocol': { 'type': 'string' }, 'localpath': { 'type': 'string' }, 'mount': { 'type': 'string' }, 'extraops': { 'type': 'string' }, }, 'required': ['server', 'protocol', 'localpath', 'mount'] } }, 'required': ['name', 'node', 'storage_id'] } def translate_to_recipes(self): return {}
def __init__(self, schema, collection, *args, **kwargs): buttons = (GecosButton(title=_('Submit'), css_class='pull-right', name='_submit'), GecosButton(title=_('Delete'), name='_delete', css_class='pull-right', type='button')) super(AdminUserEditForm, self).__init__(schema, collection, buttons=buttons, *args, **kwargs) schema.children[self.sorted_fields.index( 'password')] = schema.children[self.sorted_fields.index( 'password')].clone() schema.children[self.sorted_fields.index( 'repeat_password')] = schema.children[self.sorted_fields.index( 'repeat_password')].clone() schema.children[self.sorted_fields.index('password')].missing = '' schema.children[self.sorted_fields.index( 'repeat_password')].missing = '' self.children[self.sorted_fields.index( 'username')].widget.readonly = True
class UpdateModel(colander.MappingSchema): ''' Schema for representing an update in form ''' local_file = colander.SchemaNode(deform.FileData(), widget=FileUploadWidget(filestore), preparer=unzip_preparer, validator = colander.All( UpdateNamingValidator(), UpdateSequenceValidator(), UpdateFileStructureValidator(), UpdateControlFileValidator(), UpdateScriptRangeValidator()), missing=colander.null, title=_('Update ZIP')) remote_file = colander.SchemaNode(UrlFile(), preparer=unzip_preparer, validator = colander.All( UpdateNamingValidator(), UpdateSequenceValidator(), UpdateFileStructureValidator(), UpdateControlFileValidator()), missing=colander.null, title=_('URL download'))
def __init__(self, schema, action='', method='POST', buttons=(), formid='deform', use_ajax=False, ajax_options='{}', autocomplete=None, **kw): if not buttons: buttons = (GecosButton(title=_('Submit'), css_class='pull-right'),) if self.sorted_fields: schema.children.sort(key=lambda item: self.sorted_fields.index(item.name)) super(GecosForm, self).__init__(schema, action=action, method=method, buttons=buttons, formid='deform', use_ajax=use_ajax, ajax_options=ajax_options, autocomplete=None, **kw) self.widget.template = self.template self.widget.item_template = self.item_template self.widget.css_class = self.css_class
def save(self, permissions): ''' Saving permissions ''' (ou_managed, ou_availables, ou_remote, ou_readonly) = (set(), set(), set(), set()) for p in permissions: ou_selected = p['ou_selected'][0] if 'MANAGE' in p['permission']: ou_managed.add(ou_selected) if 'LINK' in p['permission']: ou_availables.add(ou_selected) if 'READONLY' in p['permission']: ou_readonly.add(ou_selected) if 'REMOTE' in p['permission']: ou_remote.add(ou_selected) if 'MANAGE' not in p['permission']: ou_readonly.add(ou_selected) logger.debug("PermissionsForm ::: save - ou_managed = {}".format(ou_managed)) logger.debug("PermissionsForm ::: save - ou_availables = {}".format(ou_availables)) logger.debug("PermissionsForm ::: save - ou_remote = {}".format(ou_remote)) logger.debug("PermissionsForm ::: save - ou_readonly = {}".format(ou_readonly)) self.collection.update( {'username': self.username}, {'$set': { 'ou_managed': list(ou_managed), 'ou_availables': list(ou_availables), 'ou_remote': list(ou_remote), 'ou_readonly': list(ou_readonly) } } ) self.created_msg(_('User edited successfully'))
def save(self, upload): logger.info("CookbookUpload - upload - %s" % upload) error = False settings = get_current_registry().settings rootdir = settings['cookbook_upload_rootdir'] + '/' logger.debug("forms.py ::: CookbookUpload - rootdir = %s" % rootdir) uploadir = rootdir + self.username + "/uploads/" + str(int(time.time())) + "/" logger.debug("forms.py ::: CookbookUpload - uploadir = %s" % uploadir) try: if not os.path.exists(uploadir): os.makedirs(uploadir) if upload['local_file']: f = upload['local_file'] with open('/tmp/' + f['filename'], 'wb') as zipped: zipped.write(f['fp'].read()) elif upload['remote_file']: f = urllib2.urlopen(upload['remote_file']) with open('/tmp/' + os.path.basename(upload['remote_file']), "wb") as zipped: zipped.write(f.read()) logger.info("forms.py ::: CookbookUpload - zipped = %s" % zipped) # Decompress zipfile into temporal dir tmpdir = tempfile.mkdtemp() zip_ref = zipfile.ZipFile(zipped.name,'r') zip_ref.extractall(tmpdir) zip_ref.close() # Getting cookbook's name cookbook_name = cookbook_ver = "" for name in glob.glob(tmpdir + "/*"): logger.info("forms.py ::: CookbookUpload - name = %s" % name) tmpdir = name logger.info("forms.py ::: CookbookUpload - tmpdir = %s" % tmpdir) with open("%s/metadata.rb" % name) as metafile: for line in metafile: logger.debug("forms.py ::: CookbookUpload - line = %s" % line) matchname = re.search(r'name[ \t]+(")?(\w+)(?(1)\1|)', line) matchver = re.search(r'version[ \t]+(")?([\d.]+)(?(1)\1|)', line) if matchname: cookbook_name = matchname.group(2) elif matchver: cookbook_ver = matchver.group(2) break if not (cookbook_name and cookbook_ver): raise ParseMetadataException() logger.debug("forms.py ::: CookbookUpload - cookbook_name = %s" % cookbook_name) logger.debug("forms.py ::: CookbookUpload - cookbook_ver = %s" % cookbook_ver) cookbook_path = uploadir + cookbook_name logger.debug("forms.py ::: CookbookUpload - cookbook_path = %s" % cookbook_path) os.rename(tmpdir, cookbook_path) except urllib2.HTTPError as e: error = True self.created_msg(_('There was an error downloading zip file'), 'danger') except urllib2.URLError as e: error = True self.created_msg(_('There was an error downloading zip file'), 'danger') except zipfile.BadZipfile as e: error = True self.created_msg(_('File is not a zip file: %s') % zipped.name, 'danger') except OSError as e: error = True if e.errno == errno.EACCES: self.created_msg(_('Permission denied: %s') % uploadir, 'danger') else: logger.error("forms.py ::: CookbookUpload - Error = %s" % e.strerror) self.created_msg(_('There was an error attempting to upload the cookbook. Please contact an administrator'), 'danger') except IOError as e: logger.debug("forms.py ::: CookbookUpload - e = %s" % e) error = True self.created_msg(_('No such file or directory: metadata.rb'), 'danger') except ParseMetadataException as e: logger.debug("forms.py ::: CookbookUpload - e = %s" % e) error = True self.created_msg(_('No cookbook name or version found in metadata.rb'),'danger') if not error: obj = { "_id": ObjectId(), "name": cookbook_name, "path": uploadir, "type": 'upload', "version": cookbook_ver } cookbook_upload.delay(self.request.user, 'upload', obj) logbook_link = '<a href="' + self.request.application_url + '/#logbook' + '">' + _("here") + '</a>' self.created_msg(_("Upload cookbook enqueue. Visit logbook %s") % logbook_link)
def settings_save(context, request): data = request.POST.get('data') settings = request.db.settings.find() response = Response() if data is not None: data = json.loads(data) for key in data: k = key.replace("___", ".") setting_data = request.db.settings.find_one({"key": k }) if setting_data is None: setting = create_setting(k) else: setting = Setting().deserialize(setting_data) if isinstance(data[key], str) or isinstance(data[key], unicode): Setting().set_value(setting, 'value', data[key]) else: Setting().set_value(setting, 'value', json.dumps(data[key])) # Save in mongoDB obj = Setting().serialize(setting) if obj['_id'] == colander.null: del obj['_id'] else: obj['_id'] = ObjectId(obj['_id']) #logger.debug('save= %s'%(obj)) request.db.settings.save(obj) # If saving "software_profiles", save them also in "software_profiles" collection if key == "software_profiles": collection = request.db.software_profiles # Update the software profiles for new_profile in data[key]: name = new_profile['name'] db_profile = collection.find_one({'name': name}) if not db_profile: collection.insert(new_profile) logger.debug("Created profile: %s" % name) elif new_profile['packages'] != db_profile['packages']: collection.update({'name': name}, new_profile) logger.debug("Updated profile: %s" % name) # Check if the user is trying to delete a software profile sp_policy = request.db.policies.find_one({"slug" : "package_profile_res"}) if not sp_policy: messages.created_msg(request, _('Software Profiles policy not found'), 'warning') response.write('SUCCESS') return response db_profiles = collection.find() for profile in db_profiles: profile_found = False for new_profile in data[key]: if new_profile['name'] == profile['name']: profile_found = True if not profile_found: # Check if we can delete the software profile # (the software profile is not in use) logger.debug("Try to delete: %s - %s"%(str(profile['_id']), profile['name'])) obj_related_list = "policies.%s.object_related_list"%(str(sp_policy['_id'])) profile_id = str(profile['_id']) nnodes = request.db.nodes.find({obj_related_list : profile_id}).count() logger.debug("Found %s nodes"%(nnodes)) if nnodes == 0: # It it's not used we can delete it collection.remove({"_id": profile['_id']}) else: # It's used, so we can't delete it messages.created_msg(request, _('Software Profile in use: %s')%(profile['name']), 'warning') response.write('SUCCESS') return response messages.created_msg(request, _('Settings modified successfully'), 'success') response.write('SUCCESS') return response
def report_permission(context, request, file_ext): ''' Generate a report with all the admin permissions. Args: Returns: headers (list) : The headers of the table to export rows (list) : Rows with the report data widths (list) : The witdhs of the columns of the table to export page : Translation of the word "page" to the current language of : Translation of the word "of" to the current language report_type : Type of report (html, csv or pdf) ''' items = [] total_ous = [] vmark_html = "<div class='centered'><img alt=\"OK\" src='/static/images/checkmark.jpg'/></div>" xmark_html = "<div class='centered'><img alt=\"NOK\" src='/static/images/xmark.jpg'/></div>" # Get all admins admins = request.db.adminusers.find() for admin in admins: ou_readonly = admin.get('ou_readonly', []) ou_availables = admin.get('ou_availables', []) ou_remote = admin.get('ou_remote', []) ou_managed = admin.get('ou_managed', []) admin_ous = set(ou_readonly + ou_availables + ou_remote + ou_managed) total_ous += admin_ous for ou in admin_ous: item = {} item['_id'] = str(admin['_id']) item['username'] = admin['username'] item['OU'] = ou item['email'] = admin['email'] item['name'] = admin['first_name']+" "+admin['last_name'] if file_ext == 'csv': item['readonly'] = _('Yes') if ou in ou_readonly else _('No') item['link'] = _('Yes') if ou in ou_availables else _('No') item['remote'] = _('Yes') if ou in ou_remote else _('No') item['managed'] = _('Yes') if ou in ou_managed else _('No') else: item['readonly'] = vmark_html if ou in ou_readonly else xmark_html item['link'] = vmark_html if ou in ou_availables else xmark_html item['remote'] = vmark_html if ou in ou_remote else xmark_html item['managed'] = vmark_html if ou in ou_managed else xmark_html items.append(item) logger.debug("report_permission: items = {}".format(items)) # Get all OU names ids = map(lambda x: ObjectId(x), total_ous) result = request.db.nodes.find({'_id': {'$in': ids}},{'_id':1, 'path':1}) ou_paths = {} for r in result: path = r['path']+','+str(r['_id']) ou_paths.update({str(r['_id']): get_complete_path(request.db, path)}) logger.debug("report_permission: ou_paths = {}".format(ou_paths)) rows = [] for item in items: row = [] item['OU'] = ou_paths.get(item['OU'], item['OU']) if file_ext == 'pdf': row.append(item['username']+"<br/>"+item['email']) row.append(item['OU']) row.append(treatment_string_to_pdf(item, 'readonly', 80)) row.append(treatment_string_to_pdf(item, 'link', 80)) row.append(treatment_string_to_pdf(item, 'remote', 80)) row.append(treatment_string_to_pdf(item, 'managed', 80)) else: row.append(treatment_string_to_csv(item, 'username')) row.append(treatment_string_to_csv(item, 'email')) row.append(treatment_string_to_csv(item, 'name')) row.append(treatment_string_to_csv(item, 'OU')) row.append(treatment_string_to_csv(item, 'readonly')) row.append(treatment_string_to_csv(item, 'link')) row.append(treatment_string_to_csv(item, 'remote')) row.append(treatment_string_to_csv(item, 'managed')) rows.append(row) if file_ext == 'pdf': header = (_(u'Username and Email').encode('utf-8'), _(u'Organizational Unit').encode('utf-8'), _(u'Read Only').encode('utf-8'), _(u'Link').encode('utf-8'), _(u'Remote').encode('utf-8'), _(u'Manage').encode('utf-8')) else: header = (_(u'Username').encode('utf-8'), _(u'Email').encode('utf-8'), _(u'Name').encode('utf-8'), _(u'Organizational Unit').encode('utf-8'), _(u'Read Only').encode('utf-8'), _(u'Link').encode('utf-8'), _(u'Remote').encode('utf-8'), _(u'Manage').encode('utf-8')) # Column widths in percentage if file_ext == 'pdf': widths = (36, 36, 7, 7, 7, 7) else: widths = (20, 20, 20, 20, 20, 10, 10, 10, 10) now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M") title = _(u'Permissions report') return {'headers': header, 'rows': rows, 'widths': widths, 'report_title': title, 'page': _(u'Page').encode('utf-8'), 'of': _(u'of').encode('utf-8'), 'report_type': file_ext, 'now': now}
def report_user(context, request, file_ext): ''' Generate a report with all the users that belongs to an OU. If the administrator is a superadmin the generated report will contain all the users in the database. Args: ou_id (string) : ID of the OU. Returns: headers (list) : The headers of the table to export rows (list) : Rows with the report data widths (list) : The witdhs of the columns of the table to export page : Translation of the word "page" to the current language of : Translation of the word "of" to the current language report_type : Type of report (html, csv or pdf) ''' # Check current user permissions ou_id = check_visibility_of_ou(request) if ou_id is None: raise HTTPBadRequest() # Get user data query = request.db.nodes.find( {'type': 'user','path': get_filter_nodes_belonging_ou(ou_id)}) rows = [] if file_ext == 'pdf': rows = [(' '+item['name'], ' '+item['first_name']+" "+item['last_name'], ' '+item['email'], ' '+item['phone'], ' '+item['address'], ' '+str(item['_id'])) for item in query] else: rows = [(treatment_string_to_csv(item, 'name') if file_ext == 'csv' else get_html_node_link(item), treatment_string_to_csv(item, 'first_name'), treatment_string_to_csv(item, 'last_name'), treatment_string_to_csv(item, 'email'), treatment_string_to_csv(item, 'phone'), treatment_string_to_csv(item, 'address'), str(item['_id'])) for item in query] if file_ext == 'pdf': header = (u'Username', u'Name', u'Email', u'Phone', u'Address', u'ID') else: header = (_(u'Username').encode('utf-8'), _(u'First name').encode('utf-8'), _(u'Last name').encode('utf-8'), _(u'Email').encode('utf-8'), _(u'Phone').encode('utf-8'), _(u'Address').encode('utf-8'), _(u'Id').encode('utf-8')) # Column widths in percentage if file_ext == 'pdf': widths = (15, 15, 25, 10, 15, 20) else: widths = (15, 25, 10, 10, 5, 20, 15) title = _(u'Users report') now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M") return {'headers': header, 'rows': rows, 'widths': widths, 'report_title': title, 'page': _(u'Page').encode('utf-8'), 'of': _(u'of').encode('utf-8'), 'report_type': file_ext, 'now': now}
def report_audit(context, request, file_ext): ''' Generate audit log for user information tracking Args: Returns: headers (list) : The headers of the table to export rows (list) : Rows with the report data widths (list) : The witdhs of the columns of the table to export page : Translation of the word "page" to the current language of : Translation of the word "of" to the current language report_type : Type of report (html, csv or pdf) ''' rows = [] # Getting audit logs items = request.db.auditlog.find() for item in items: row = [] # Converts timestamp to date item['date'] =datetime.datetime.fromtimestamp(item['timestamp']).strftime('%d/%m/%Y %H:%M:%S') if file_ext == 'pdf': row.append(treatment_string_to_pdf(item, 'action', 10)) row.append(treatment_string_to_pdf(item, 'username', 15)) row.append(treatment_string_to_pdf(item, 'ipaddr', 20)) row.append(item['user-agent'])#treatment_string_to_pdf(item, 'user-agent',100)) row.append(treatment_string_to_pdf(item, 'date', 80)) else: row.append(treatment_string_to_csv(item, 'action')) row.append(treatment_string_to_csv(item, 'username')) row.append(treatment_string_to_csv(item, 'ipaddr')) row.append(treatment_string_to_csv(item, 'user-agent')) row.append(treatment_string_to_csv(item, 'date')) rows.append(row) header = (_(u'Action').encode('utf-8'), _(u'Username').encode('utf-8'), _(u'IP Address').encode('utf-8'), _(u'User Agent').encode('utf-8'), _(u'Date').encode('utf-8')) # Column widths in percentage widths = (10, 15, 20, 40, 15) title = _(u'Audit report') now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M") return {'headers': header, 'rows': rows, 'widths': widths, 'report_title': title, 'page': _(u'Page').encode('utf-8'), 'of': _(u'of').encode('utf-8'), 'report_type': file_ext, 'now': now}
def __init__(self, schema, request, *args, **kwargs): self.request = request buttons = (GecosButton(title=_('Submit'), css_class='deform-maintenance-submit'),) super(MaintenanceForm, self).__init__(schema, buttons=buttons, *args, **kwargs)
def get(self): result = super(ComputerResource, self).get() node_collection = self.request.db.nodes if not result.get('node_chef_id', None): return result logger.info("/api/computers/: node_chef_id: %s" % (str(result.get('node_chef_id', None)))) try: api = get_chef_api(self.request.registry.settings, self.request.user) computer_node = ChefNode(result['node_chef_id'], api) ohai = to_deep_dict(computer_node.attributes) nodeid = result.get('_id',None) usernames = [i['username'] for i in ohai.get('ohai_gecos', {}).get('users', [])] users = list(node_collection.find({ "$and": [ { "$or": [{"name": {"$in": usernames}}] }, { "type":"user"}, { "computers": {"$elemMatch": {"$eq": ObjectId(nodeid)}}} ] },{'_id':1,'name':1,'path':1})) # ObjectId to string for JSON serialize [d.update({'_id': str(d['_id'])}) for d in users] # Create a list of users that provides at least one user policy to this computer users_inheritance_pre = list(node_collection.find({ "$and": [ { "$or": [{"name": {"$in": usernames}}] }, { "type":"user"}, { "computers": {"$elemMatch": {"$eq": ObjectId(nodeid)}}} ] },{'_id':1,'name':1,'path':1, 'inheritance': 1})) [d.update({'_id': str(d['_id'])}) for d in users_inheritance_pre] users_inheritance = [] for usr_inh in users_inheritance_pre: if 'inheritance' in usr_inh: policies_list = get_inheritance_tree_policies_list(usr_inh['inheritance'], []) if len(policies_list) > 0: users_inheritance.append(usr_inh) cpu = ohai.get('cpu', {}).get('0', {}) dmi = ohai.get('dmi', {}) # debug_mode flag for logs tab debug_mode = False try: debug_mode = computer_node.attributes.get_dotted(DEBUG_MODE_ENABLE_ATTR_PATH) except KeyError: pass # Get logs info logs_data = node_collection.find_one({"type": "computer", "_id": ObjectId(nodeid)}, {"logs": True}) logs = {} if logs_data is not None and 'logs' in logs_data: logs_data = logs_data['logs'] date_format = locale.nl_langinfo(locale.D_T_FMT) date = datetime.datetime(*map(int, re.split('[^\d]', logs_data['date'])[:-1])) localename = locale.normalize(get_current_request().locale_name+'.UTF-8') logger.debug("/api/computers/: localename: %s" % (str(localename))) locale.setlocale(locale.LC_TIME, localename) logs['date'] = date.strftime(date_format) logger.debug("/api/computers/: date: %s" % (str(logs['date']))) logs['files'] = logs_data['files'] for filedata in logs_data['files']: # Do not send file contents del filedata['content'] # Get Help Channel info help_channel_enabled = True helpchannel_data = self.request.db.helpchannel.find( {"computer_node_id" : result['node_chef_id']}).sort( [("last_modified", pymongo.DESCENDING)]).limit(6) helpchannel = {} helpchannel['current'] = None helpchannel['last'] = [] if helpchannel_data is not None: c = 0 for hcdata in helpchannel_data: # Format date date_format = locale.nl_langinfo(locale.D_T_FMT) logger.info("last_modified: {0}".format( hcdata['last_modified'])) last_mod = re.split('[^\d]', str(hcdata['last_modified'])) logger.info("last_mod: {0}".format(last_mod)) date = datetime.datetime(*map(int, last_mod[:-2])) localename = locale.normalize(get_current_request().locale_name+'.UTF-8') logger.debug("/api/computers/: localename: %s" % (str(localename))) locale.setlocale(locale.LC_TIME, localename) hcdata['last_modified'] = date.strftime(date_format) if hcdata['user_node_id']: # Format user user_data = node_collection.find_one({"type": "user", "_id": ObjectId(hcdata['user_node_id'])}) if user_data: hcdata['user'] = user_data['name'] else: logger.error("User not found: {0}".format(hcdata['user_node_id'])) else: hcdata['user'] = '' if hcdata['adminuser_id']: # Format user user_data = self.request.db.adminusers.find_one({"_id": ObjectId(hcdata['adminuser_id'])}) if user_data: hcdata['admin'] = user_data['username'] else: logger.error("Admin user not found: {0}".format(hcdata['adminuser_id'])) else: hcdata['admin'] = '' # Translate status info hcdata['status'] = _('Unknown status') if hcdata['action'] == 'request': hcdata['status'] = _('User is requesting support') elif hcdata['action'] == 'accepted': hcdata['status'] = _('User is requesting support') elif hcdata['action'] == 'finished user': hcdata['status'] = _('Terminated by user') elif hcdata['action'] == 'finished tech': hcdata['status'] = _('Terminated by technician') elif hcdata['action'] == 'finished error': hcdata['status'] = _('Terminated because of a communication error') elif hcdata['action'] == 'giving support': hcdata['status'] = _('The technician is giving support to the user') hcdata['_id'] = str(hcdata['_id']) if (c==0 and hcdata['action']=='accepted'): helpchannel['current'] = hcdata else: helpchannel['last'].append(hcdata) c = c + 1 result.update({'ohai': ohai, 'users': users, # Users related with this computer 'users_inheritance': users_inheritance, # Users related with this computer that provides at least one user policy 'uptime': ohai.get('uptime', ''), #'gcc_link': ohai.get('gcc_link',True), 'ipaddress': ohai.get('ipaddress', ''), 'cpu': '%s %s' % (cpu.get('vendor_id', ''), cpu.get('model_name', '')), 'product_name': dmi.get('system', {}).get('product_name', ''), 'manufacturer': dmi.get('system', {}).get('manufacturer', ''), 'ram': ohai.get('memory', {}).get('total', ''), 'lsb': ohai.get('lsb', {}), 'kernel': ohai.get('kernel', {}), 'filesystem': ohai.get('filesystem', {}), 'debug_mode': debug_mode, 'logs': logs, 'helpchannel': helpchannel, 'help_channel_enabled': help_channel_enabled }) except (urllib2.URLError, ChefError, ChefServerError): pass return result
def report_status(context, request, file_ext): ''' Generate a report with all the users that belongs to an OU. If the administrator is a superadmin the generated report will contain all the users in the database. Args: ou_id (string) : ID of the OU. Returns: headers (list) : The headers of the table to export rows (list) : Rows with the report data widths (list) : The witdhs of the columns of the table to export page : Translation of the word "page" to the current language of : Translation of the word "of" to the current language report_type : Type of report (html, csv or pdf) ''' # Check current user permissions ou_id = check_visibility_of_ou(request) if ou_id is None: raise HTTPBadRequest() # Get user data query = request.db.nodes.find( {'type': 'computer','path': get_filter_nodes_belonging_ou(ou_id)}).sort('last_agent_run_time', -1) rows = [] current_time = int(time.time()) logger.debug("report_status: current_time = {}".format(current_time)) # update_error_interval: Hours. Converts it to seconds update_error_interval = timedelta(hours=int(get_current_registry().settings.get('update_error_interval', 24))).seconds logger.debug("report_status: update_error_interval = {}".format(update_error_interval)) # gecos-agent runs every 60 minutes (cron resource: minutes 30) # See https://github.com/gecos-team/gecos-workstation-management-cookbook/blob/master/recipes/default.rb (line: 57) # 10-min max delay margin of chef-client concurrent executions # See https://github.com/gecos-team/gecosws-agent/blob/trusty/scripts/gecos-chef-client-wrapper (line: 30) # 15-min delay margin of network or chef-client execution # 60 + 10 + 15 = 85 delay_margin = timedelta(minutes=85).seconds for item in query: row = [] last_agent_run_time = int(item.get('last_agent_run_time',0)) logger.debug("report_status: last_agent_run_time = {}".format(last_agent_run_time)) if last_agent_run_time + delay_margin >= current_time: item['status'] = '<div class="centered" style="width: 100%"><img alt="OK" src="/static/images/checkmark.jpg"/></div>' \ if file_ext != 'csv' else 'OK' # Chef-run error or update_error_interval hours has elapsed from last agent run time elif (item['error_last_chef_client'] or last_agent_run_time + update_error_interval >= current_time ): item['status'] = '<div class="centered" style="width: 100%"><img alt="ERROR" src="/static/images/xmark.jpg"/></div>' \ if file_ext != 'csv' else 'ERROR' # delay_margin < last_agent_run_time < update_error_interval else: item['status'] = '<div class="centered" style="width: 100%"><img alt="WARN" src="/static/images/alertmark.jpg"/></div>' \ if file_ext != 'csv' else 'WARN' if file_ext == 'pdf': row.append(treatment_string_to_pdf(item, 'name', 20)) row.append(item['_id']) if last_agent_run_time != 0: row.append(datetime.utcfromtimestamp(last_agent_run_time).strftime('%Y-%m-%d %H:%M:%S')) else: row.append(' -- ') row.append(item['status']) else: if file_ext == 'csv': row.append(treatment_string_to_csv(item, 'name')) else: row.append(get_html_node_link(item)) row.append(item['_id']) if last_agent_run_time != 0: row.append(datetime.utcfromtimestamp(last_agent_run_time).strftime('%Y-%m-%d %H:%M:%S')) else: row.append('--') row.append(treatment_string_to_csv(item, 'status')) rows.append(row) header = (_(u'Name').encode('utf-8'), _(u'Id').encode('utf-8'), _(u'Agent last runtime').encode('utf-8'), _(u'Status').encode('utf-8')) # Column widths in percentage if file_ext == 'pdf': widths = (45, 20, 20, 15) else: widths = (15, 35, 15, 20) title = _(u'Computer with anomalies') now = datetime.now().strftime("%d/%m/%Y %H:%M") return {'headers': header, 'rows': rows, 'widths': widths, 'report_title': title, 'page': _(u'Page').encode('utf-8'), 'of': _(u'of').encode('utf-8'), 'report_type': file_ext, 'now': now}
def report_computer(context, request, file_ext): ''' Generate a report with all the computers that belongs to an OU. If the administrator is a superadmin the generated report will contain all the computers in the database. Args: ou_id (string) : ID of the OU. Returns: headers (list) : The headers of the table to export rows (list) : Rows with the report data widths (list) : The witdhs of the columns of the table to export page : Translation of the word "page" to the current language of : Translation of the word "of" to the current language report_type : Type of report (html, csv or pdf) ''' # Check current user permissions ou_id = check_visibility_of_ou(request) if ou_id is None: raise HTTPBadRequest() # Get user data query = request.db.nodes.find( {'type': 'computer', 'path': get_filter_nodes_belonging_ou(ou_id)}) if file_ext == 'pdf': rows = [(treatment_string_to_pdf(item, 'name', 20), treatment_string_to_pdf(item, 'family', 10), treatment_string_to_pdf(item, 'registry', 10), treatment_string_to_pdf(item, 'serial', 15), #treatment_string_to_pdf(item, 'node_chef_id', 25), item['_id']) for item in query] else: rows = [(treatment_string_to_csv(item, 'name') if file_ext == 'csv' else get_html_node_link(item), treatment_string_to_csv(item, 'family'), treatment_string_to_csv(item, 'registry'), treatment_string_to_csv(item, 'serial'), #treatment_string_to_csv(item, 'node_chef_id'), item['_id']) for item in query] header = (_(u'Name').encode('utf-8'), _(u'Type').encode('utf-8'), _(u'Registry number').encode('utf-8'), _(u'Serial number').encode('utf-8'), #_(u'Node chef id').encode('utf-8'), _(u'Id').encode('utf-8')) # Column widths in percentage widths = (20, 20, 20, 20, 20) title = _(u'Computers report') now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M") return {'headers': header, 'rows': rows, 'widths': widths, 'report_title': title, 'page': _(u'Page').encode('utf-8'), 'of': _(u'of').encode('utf-8'), 'report_type': file_ext, 'now': now}
def save(self, upload): self.created_msg(_('Restore cookbook.'))
def report_storages(context, request, file_ext): ''' Generate a report with all the storages and its related users. Args: ou_id (string) : ID of the OU. Returns: headers (list) : The headers of the table to export rows (list) : Rows with the report data widths (list) : The witdhs of the columns of the table to export page : Translation of the word "page" to the current language of : Translation of the word "of" to the current language report_type : Type of report (html, csv or pdf) ''' # Check current user permissions ou_id = check_visibility_of_ou(request) if ou_id is None: raise HTTPBadRequest() # Get storages policy policy = request.db.policies.find_one({'slug': 'storage_can_view'}) property_name = 'policies.' + str(policy['_id']) + '.object_related_list' # Get all storages query = request.db.nodes.find( {'type': 'storage','path': get_filter_nodes_belonging_ou(ou_id)}) rows = [] if file_ext == 'pdf': for item in query: row = [] # No path in PDF because it's too long row.append('--') row.append(item['name']) row.append(item['uri']) row.append(item['_id']) # Get all nodes related with this storage nodes_query = request.db.nodes.find({property_name: str(item['_id'])}) # Targets: ou, group or user users = [] for node in nodes_query: if node['type'] == 'ou': users = list(request.db.nodes.find( {'path': get_filter_nodes_belonging_ou(node['_id']), 'type': 'user'})) elif node['type'] == 'group': users = list(request.db.nodes.find( {'_id': node['members'], 'type': 'user'})) elif node['type'] == 'user': users = [node] if len(users) == 0: row.append('--') row.append('--') rows.append(row) else: for user in users: user_row = list(row) user_row.append(user['name']) # No path in PDF because it's too long user_row.append('--') rows.append(user_row) else: for item in query: row = [] item['complete_path'] = get_complete_path(request.db, item['path']) row.append(treatment_string_to_csv(item, 'complete_path')) if file_ext == 'csv': row.append(treatment_string_to_csv(item, 'name')) else: # html links row.append(get_html_node_link(item)) row.append(treatment_string_to_csv(item, 'uri')) row.append(item['_id']) # Get all nodes related with this printer nodes_query = request.db.nodes.find({property_name: str(item['_id'])}) # Targets: ou, group or user users = [] for node in nodes_query: if node['type'] == 'ou': users = list(request.db.nodes.find( {'path': get_filter_nodes_belonging_ou(node['_id']), 'type': 'user'})) elif node['type'] == 'group': users = list(request.db.nodes.find( {'_id': node['members'], 'type': 'user'})) elif node['type'] == 'user': users = [node] if len(users) == 0: row.append('--') rows.append(row) else: for user in users: user_row = list(row) if file_ext == 'csv': user_row.append(treatment_string_to_csv(user, 'name')) else: # html links user_row.append(get_html_node_link(user)) user['complete_path'] = get_complete_path(request.db, item['path']) rows.append(user_row) header = (_(u'Path').encode('utf-8'), _(u'Name').encode('utf-8'), _(u'Uri').encode('utf-8'), _(u'Id').encode('utf-8'), _(u'User').encode('utf-8')) # Column widths in percentage widths = (0, 20, 45, 15, 20, 0) title = _(u'Storages and related users report') now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M") return {'headers': header, 'rows': rows, 'widths': widths, 'report_title': title, 'page': _(u'Page').encode('utf-8'), 'of': _(u'of').encode('utf-8'), 'report_type': file_ext, 'now': now}
import pyramid from bson import ObjectId from bson.objectid import InvalidId from colander import null from copy import copy from deform.widget import FileUploadWidget, _normalize_choices, SelectWidget from gecoscc.i18n import gettext_lazy as _ from gecoscc.i18n import gettext from gecoscc.utils import get_items_ou_children, getNextUpdateSeq, get_chef_api, get_cookbook from pyramid.threadlocal import get_current_registry OU_ORDER = 1 UPDATE_STRUCTURE = ['control', 'cookbook/', 'scripts/'] PERMISSIONS = (('READONLY', _('read')), ('MANAGE', _('manage')), ('LINK', _('link')), ('REMOTE', _('remote'))) class MemoryTmpStore(dict): def preview_url(self, _name): return None filestore = MemoryTmpStore() class MyModel(object): pass
def save(self, ous_managed): self.collection.update({'username': self.username}, {'$set': ous_managed}) self.created_msg(_('User edited successfully'))
def __init__(self, schema, collection, username, request, *args, **kwargs): schema.get('ou_managed').title += '<p><a href="#ou-managed" class="add-another">%s</a></p>' % _('Add another') schema.get('ou_availables').title += '<p><a href="#ou-availables" class="add-another">%s</a></p>' % _('Add another') schema.children.append(self.ou_managed_count) schema.children.append(self.ou_availables_count) super(AdminUserOUManageForm, self).__init__(schema, collection=collection, username=username, request=request, *args, **kwargs)