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'), _(u'Name'), _(u'Uri'), _(u'Id'), _(u'User')) # 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") # Sort rows rows = sorted(rows, key=lambda i: (i[0].lower(), i[1].lower(), i[4].lower())) return { 'headers': header, 'rows': rows, 'default_order': [[0, 'asc'], [1, 'asc'], [4, 'asc']], 'widths': widths, 'report_title': title, 'page': _(u'Page'), 'of': _(u'of'), 'report_type': file_ext, 'now': now }
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( [('error_last_chef_client', pymongo.DESCENDING), ('last_agent_run_time', pymongo.DESCENDING), ('name', pymongo.ASCENDING) ] ) rows = [] orders = [] 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 = [] order = [] status = '0' 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' status = '0' # 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' status = '2' # 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' status = '1' if file_ext == 'pdf': row.append(treatment_string_to_pdf(item, 'name', 20)) order.append('') row.append(item['_id']) order.append('') if last_agent_run_time != 0: row.append(datetime.utcfromtimestamp( last_agent_run_time).strftime('%d/%m/%Y %H:%M:%S')) else: row.append(' -- ') order.append(last_agent_run_time) row.append(item['status']) order.append(status) else: if file_ext == 'csv': row.append(treatment_string_to_csv(item, 'name')) else: row.append(get_html_node_link(item)) order.append('') row.append(item['_id']) order.append('') if last_agent_run_time != 0: row.append(datetime.utcfromtimestamp( last_agent_run_time).strftime('%d/%m/%Y %H:%M:%S')) else: row.append('--') order.append(last_agent_run_time) row.append(treatment_string_to_csv(item, 'status')) order.append(status) rows.append(row) orders.append(order) 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") # Sort rows rows = sorted(rows, key = lambda i: (get_status(i[3]), i[0].lower())) return {'headers': header, 'rows': rows, 'orders': orders, 'default_order': [[ 3, 'desc' ], [ 0, 'asc' ]], '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_printers(context, request, file_ext): ''' Generate a report with all the printers and its related computers. 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 printers policy policy = request.db.policies.find_one({'slug': 'printer_can_view'}) property_name = 'policies.' + str(policy['_id']) + '.object_related_list' # Get all printers query = request.db.nodes.find( {'type': 'printer', 'path': get_filter_nodes_belonging_ou(ou_id)}) task = ChefTask() 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(treatment_string_to_pdf(item, 'manufacturer', 15)) row.append(treatment_string_to_pdf(item, 'model', 15)) row.append(treatment_string_to_pdf(item, 'serial', 15)) row.append(treatment_string_to_pdf(item, 'registry', 15)) # Get all nodes related with this printer nodes_query = request.db.nodes.find( {property_name: str(item['_id'])}) related_computers = [] related_objects = [] for node in nodes_query: related_computers = task.get_related_computers( node, related_computers, related_objects) # Remove duplicated computers computer_paths = [] computers = [] for computer in related_computers: full_path = computer['path'] + '.' + computer['name'] if not full_path in computer_paths: computer_paths.append(full_path) computers.append(computer) if len(computers) == 0: row.append('--') rows.append(row) else: for computer in computers: computer_row = list(row) computer_row.append(treatment_string_to_pdf( computer, 'name', 15)) # No path in PDF because it's too long rows.append(computer_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')) row.append(treatment_string_to_csv(item, 'name') \ if file_ext == 'csv' else get_html_node_link(item)) row.append(treatment_string_to_csv(item, 'manufacturer')) row.append(treatment_string_to_csv(item, 'model')) row.append(treatment_string_to_csv(item, 'serial')) row.append(treatment_string_to_csv(item, 'registry')) # Get all nodes related with this printer nodes_query = request.db.nodes.find( {property_name: str(item['_id'])}) related_computers = [] related_objects = [] for node in nodes_query: related_computers = task.get_related_computers( node, related_computers, related_objects) # Remove duplicated computers computer_paths = [] computers = [] for computer in related_computers: full_path = computer['path'] + '.' + computer['name'] if not full_path in computer_paths: computer_paths.append(full_path) computers.append(computer) if len(computers) == 0: row.append('--') rows.append(row) else: for computer in computers: computer_row = list(row) computer_row.append(treatment_string_to_csv( computer, 'name') \ if file_ext == 'csv' \ else get_html_node_link(computer)) computer['complete_path'] = get_complete_path( request.db, item['path']) rows.append(computer_row) header = (_(u'Path').encode('utf-8'), _(u'Name').encode('utf-8'), _(u'Manufacturer').encode('utf-8'), _(u'Model').encode('utf-8'), _(u'Serial number').encode('utf-8'), _(u'Registry number').encode('utf-8'), _(u'Computer').encode('utf-8')) # Column widths in percentage if file_ext == 'pdf': widths = (0, 25, 15, 15, 15, 15, 15) else: widths = (0, 20, 10, 10, 10, 10, 20) title = _(u'Printers and related computers report') now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M") # Sort rows rows = sorted(rows, key = lambda i: (i[0].lower(), i[1].lower(), i[6].lower())) return {'headers': header, 'rows': rows, 'default_order': [[ 0, 'asc' ], [ 1, 'asc' ], [ 6, 'asc' ]], '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 = [] orders = [] # Getting audit logs items = request.db.auditlog.find().sort([('timestamp', pymongo.DESCENDING) ]) for item in items: row = [] order = [] # 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)) order.append('') row.append(treatment_string_to_pdf(item, 'username', 15)) order.append('') row.append(treatment_string_to_pdf(item, 'ipaddr', 20)) order.append('') row.append(item['user-agent'] ) #treatment_string_to_pdf(item, 'user-agent',100)) order.append('') row.append(treatment_string_to_pdf(item, 'date', 80)) order.append('') else: row.append(treatment_string_to_csv(item, 'action')) order.append('') row.append(treatment_string_to_csv(item, 'username')) order.append('') row.append(treatment_string_to_csv(item, 'ipaddr')) order.append(ip_to_hex_addr(item['ipaddr'])) row.append(treatment_string_to_csv(item, 'user-agent')) order.append('') row.append(treatment_string_to_csv(item, 'date')) order.append('%s' % (item['timestamp'])) rows.append(row) orders.append(order) header = (_(u'Action'), _(u'Username'), _(u'IP Address'), _(u'User Agent'), _(u'Date')) # 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, 'orders': orders, 'default_order': [[4, 'desc']], 'widths': widths, 'report_title': title, 'page': _(u'Page'), 'of': _(u'of'), 'report_type': file_ext, 'now': now }
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 = [ObjectId(x) for x in 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'), _(u'Organizational Unit'), _(u'Read Only'), _(u'Link'), _(u'Remote'), _(u'Manage')) else: header = (_(u'Username'), _(u'Email'), _(u'Name'), _(u'Organizational Unit'), _(u'Read Only'), _(u'Link'), _(u'Remote'), _(u'Manage')) # 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') # Sort rows # TODO: Use MongoDB Collations to do a "ignore_case" sorting # (MongoDB 2.6 does not support "ignore case" sorting) rows = sorted(rows, key=lambda i: (i[0].lower())) return { 'headers': header, 'rows': rows, 'default_order': [[0, 'asc']], 'widths': widths, 'report_title': title, 'page': _(u'Page'), 'of': _(u'of'), 'report_type': file_ext, 'now': now }
def report_no_user_computers(context, request, file_ext): ''' Generate a report with all the no-user computers that belongs to a 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() task = ChefTask() related_computers = [] related_objects = [] filters = ({'type': 'user', 'path': get_filter_nodes_belonging_ou(ou_id)}) logger.info("report_no-user_computers: filters = {}".format(filters)) users = request.db.nodes.find(filters) for user in users: related_computers = task.get_related_computers_of_user( user, related_computers, related_objects) references = [c['_id'] for c in related_computers] logger.info("report_no-user_computers: references = {}".format(references)) filters2 = ({ 'type': 'computer', 'path': get_filter_nodes_belonging_ou(ou_id) }) filters2.update({'_id': {'$nin': [c['_id'] for c in related_computers]}}) logger.info("report_no-user_computers: filters2 = {}".format(filters2)) computers = request.db.nodes.find(filters2) rows = [] if file_ext == 'pdf': rows = [(item['name'], treatment_string_to_pdf(item, 'family', 15), treatment_string_to_pdf(item, 'registry', 15), treatment_string_to_pdf(item, 'serial', 20), item['node_chef_id'], item['_id']) for item in computers] 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 computers] 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 = (25, 10, 15, 15, 20, 15) title = _(u'No-user computers') now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M") # Sort rows # TODO: Use MongoDB Collations to do a "ignore_case" sorting # (MongoDB 2.6 does not support "ignore case" sorting) rows = sorted(rows, key=lambda i: (i[0].lower())) return { 'headers': header, 'rows': rows, 'default_order': [[0, 'asc']], '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_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}
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 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'), _(u'Type'), _(u'Registry number'), _(u'Serial number'), #_(u'Node chef id'), _(u'Id')) # Column widths in percentage widths = (20, 20, 20, 20, 20) title = _(u'Computers report') now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M") # Sort rows # TODO: Use MongoDB Collations to do a "ignore_case" sorting # (MongoDB 2.6 does not support "ignore case" sorting) rows = sorted(rows, key=lambda i: (i[0].lower())) return { 'headers': header, 'rows': rows, 'widths': widths, 'default_order': [[0, 'asc']], 'report_title': title, 'page': _(u'Page'), 'of': _(u'of'), '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'), _(u'First name'), _(u'Last name'), _(u'Email'), _(u'Phone'), _(u'Address'), _(u'Id')) # 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") # Sort rows # TODO: Use MongoDB Collations to do a "ignore_case" sorting # (MongoDB 2.6 does not support "ignore case" sorting) rows = sorted(rows, key = lambda i: (i[0].lower())) return {'headers': header, 'rows': rows, 'default_order': [[ 0, 'asc' ]], 'widths': widths, 'report_title': title, 'page': _(u'Page'), 'of': _(u'of'), 'report_type': file_ext, 'now': now}
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_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 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_no_user_computers(context, request, file_ext): ''' Generate a report with all the no-user computers that belongs to a 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() task = ChefTask() related_computers = [] related_objects = [] filters = ({'type': 'user','path': get_filter_nodes_belonging_ou(ou_id)}) logger.info("report_no-user_computers: filters = {}".format(filters)) users = request.db.nodes.find(filters) for user in users: related_computers = task.get_related_computers_of_user(user, related_computers, related_objects) references = [c['_id'] for c in related_computers] logger.info("report_no-user_computers: references = {}".format(references)) filters2 = ({'type': 'computer','path': get_filter_nodes_belonging_ou(ou_id)}) filters2.update({'_id': {'$nin': [c['_id'] for c in related_computers]}}) logger.info("report_no-user_computers: filters2 = {}".format(filters2)) computers = request.db.nodes.find(filters2) rows = [] if file_ext == 'pdf': rows = [(item['name'], treatment_string_to_pdf(item, 'family', 15), treatment_string_to_pdf(item, 'registry', 15), treatment_string_to_pdf(item, 'serial', 20), item['node_chef_id'], item['_id']) for item in computers] 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 computers] 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 = (25, 10, 15, 15, 20, 15) title = _(u'No-user computers') 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_printers(context, request, file_ext): ''' Generate a report with all the printers and its related computers. 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 printers policy policy = request.db.policies.find_one({'slug': 'printer_can_view'}) property_name = 'policies.' + str(policy['_id']) + '.object_related_list' # Get all printers query = request.db.nodes.find( {'type': 'printer', 'path': get_filter_nodes_belonging_ou(ou_id)}) task = ChefTask() 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(treatment_string_to_pdf(item, 'manufacturer', 15)) row.append(treatment_string_to_pdf(item, 'model', 15)) row.append(treatment_string_to_pdf(item, 'serial', 15)) row.append(treatment_string_to_pdf(item, 'registry', 15)) # Get all nodes related with this printer nodes_query = request.db.nodes.find({property_name: str(item['_id'])}) related_computers = [] related_objects = [] for node in nodes_query: related_computers = task.get_related_computers(node, related_computers, related_objects) # Remove duplicated computers computer_paths = [] computers = [] for computer in related_computers: full_path = computer['path'] + '.' + computer['name'] if not full_path in computer_paths: computer_paths.append(full_path) computers.append(computer) if len(computers) == 0: row.append('--') rows.append(row) else: for computer in computers: computer_row = list(row) computer_row.append(treatment_string_to_pdf(computer, 'name', 15)) # No path in PDF because it's too long rows.append(computer_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')) row.append(treatment_string_to_csv(item, 'name') if file_ext == 'csv' else get_html_node_link(item)) row.append(treatment_string_to_csv(item, 'manufacturer')) row.append(treatment_string_to_csv(item, 'model')) row.append(treatment_string_to_csv(item, 'serial')) row.append(treatment_string_to_csv(item, 'registry')) # Get all nodes related with this printer nodes_query = request.db.nodes.find({property_name: str(item['_id'])}) related_computers = [] related_objects = [] for node in nodes_query: related_computers = task.get_related_computers(node, related_computers, related_objects) # Remove duplicated computers computer_paths = [] computers = [] for computer in related_computers: full_path = computer['path'] + '.' + computer['name'] if not full_path in computer_paths: computer_paths.append(full_path) computers.append(computer) if len(computers) == 0: row.append('--') rows.append(row) else: for computer in computers: computer_row = list(row) computer_row.append(treatment_string_to_csv(computer, 'name') if file_ext == 'csv' else get_html_node_link(computer)) computer['complete_path'] = get_complete_path(request.db, item['path']) rows.append(computer_row) header = (_(u'Path').encode('utf-8'), _(u'Name').encode('utf-8'), _(u'Manufacturer').encode('utf-8'), _(u'Model').encode('utf-8'), _(u'Serial number').encode('utf-8'), _(u'Registry number').encode('utf-8'), _(u'Computer').encode('utf-8')) # Column widths in percentage if file_ext == 'pdf': widths = (0, 25, 15, 15, 15, 15, 15) else: widths = (0, 20, 10, 10, 10, 10, 20) title = _(u'Printers and related 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}