def package(request, packagename): # there may be multiple Package with same name but different sourcename package = get_list_or_404(Package, name=packagename)[0] updates = package.update_set.order_by('host__name') if "plain" in request.GET: return render(request, "package.txt", {"updates": updates}, content_type="text/plain") return render(request, 'packageview.html', {'package': package, 'updates': updates})
def package(request, packagename): # there may be multiple Package with same name but different sourcename package = get_list_or_404(Package, name=packagename)[0] updates = package.update_set.order_by("host__name") if "plain" in request.GET: return render(request, "package.txt", {"updates": updates}, mimetype="text/plain") return render(request, "packageview.html", {"package": package, "updates": updates})
def query(request): ''' Puppet query view. Will display a user selected list of facts @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding JSON ''' class MatrixForm(forms.Form): hosts = forms.ModelMultipleChoiceField(queryset=Host.objects.all(), widget=FilteredSelectMultiple("hosts", is_stacked=False)) facts = forms.ModelMultipleChoiceField(queryset=Fact.objects.all() .exclude(name__startswith='---') # ruby objects .exclude(name__startswith='package_updates') .exclude(name__startswith='macaddress_') # VMs have tons of network interfaces :/ .exclude(name__startswith='ipaddress_') .exclude(name__startswith='ipaddress6_') .exclude(name__startswith='network_') .exclude(name__startswith='netmask_'), widget=FilteredSelectMultiple("parameters", is_stacked=False)) if request.method == 'GET': f = MatrixForm(label_suffix='') return render(request, "query.html", { 'form': f }) else: f = MatrixForm(request.POST) if f.is_valid(): results = [] facts = [] for fact in f.cleaned_data['facts']: facts.append(fact.name) facts.sort() values = FactValue.objects.all() values = values.filter(fact_name__in=f.cleaned_data['facts']) values = values.filter(host__in=f.cleaned_data['hosts']) values = values.order_by('host') # itertools.groupby needs sorted input values = values.select_related() # performance optimization from itertools import groupby for key, values in groupby(values, key=lambda x: x.host.name): row = {} for v in values: row[v.name] = v.value row = [ row.get(k, None) for k in facts ] results.append({'host': key, 'facts': row }) return render(request, "query_results.html", { 'facts': facts, 'results': results }) else: return render(request, "query.html", { 'form': f })
def search(request): ''' Search view. Scans request for q (GET case) or qarea (POST case) and searches for corresponding instances in all subapps matching the query If txt is send in a GET it will display results in txt and not in html format @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' if u'txt' in request.GET: template = 'results.txt' content_type = 'text/plain' else: template = 'results.html' content_type = 'text/html' if u'q' in request.GET: key = request.GET['q'] elif u'qarea' in request.POST: key = projectwide_functions.get_search_terms(request.POST['qarea']) else: key = None results = { 'hwdoc': None, 'puppet': None, 'updates': None, } results['puppet'] = puppet_functions.search(key).select_related() results['hwdoc'] = hwdoc_functions.search(key).select_related( 'servermanagement', 'rack', 'model', 'model__vendor', 'allocation') results['hwdoc'] = hwdoc_functions.populate_tickets(results['hwdoc']) results['hwdoc'] = hwdoc_functions.populate_hostnames(results['hwdoc']) try: return render(request, template, { 'results': results, }, content_type=content_type) except TemplateSyntaxError as e: if re.search('too many SQL variables', e.message): return render(request, 'error.html', content_type=content_type)
def index(request): timeout = datetime.now() - timedelta(seconds=HOST_TIMEOUT) hosts = Host.objects.all() problemhosts = Host.objects.filter(updated_at__lte=timeout).order_by('-updated_at') factcount = Fact.objects.count() factvaluecount = FactValue.objects.count() updatecount = Host.objects.filter(package__isnull=False).distinct().count() packagecount = Package.objects.count() securitycount = Package.objects.filter(update__is_security=True).distinct().count() if 'servermon.hwdoc' in INSTALLED_APPS: hwdoc_installed = True else: hwdoc_installed = False return render(request, "index.html", { 'problemhosts': problemhosts, 'timeout': timeout, 'hosts': hosts, 'factcount': factcount, 'factvaluecount': factvaluecount, 'updatecount': updatecount, 'packagecount': packagecount, 'securitycount': securitycount, 'hwdoc_installed': hwdoc_installed, })
def datacenter(request, datacenter_id): ''' Rackrow view. It should display all non-authenticated user viewable data @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' template = 'datacenter.html' datacenter = get_object_or_404(Datacenter, pk=datacenter_id) rackrows = datacenter.rackrow_set.all() for rackrow in rackrows: racks = [str(x).zfill(2) for x in rackrow.rackposition_set.values_list('rack__pk', flat=True)] equipments = functions.search(racks) equipments = equipments.exclude(comments='') if equipments.count() > 0: rackrow.tickets = True return render(request, template, { 'datacenter': datacenter, 'rackrows': rackrows, })
def rack(request, rack_id): ''' Rack view. It should display all non-authenticated user viewable data @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' template = 'rack.html' rack = get_object_or_404(Rack, pk=rack_id) try: rack.prev = Rack.objects.filter( rackposition__position__lt=rack.rackposition.position, rackposition__rr=rack.rackposition.rr ).order_by('-rackposition__position')[0] except (IndexError, RackPosition.DoesNotExist): rack.prev = None try: rack.next = Rack.objects.filter( rackposition__position__gt=rack.rackposition.position, rackposition__rr=rack.rackposition.rr ).order_by('rackposition__position')[0] except (IndexError, RackPosition.DoesNotExist): rack.next = None equipments = functions.search(str(rack.name)) equipments = functions.populate_tickets(equipments) equipments = functions.populate_hostnames(equipments) equipments = { 'hwdoc': functions.calculate_empty_units(rack, equipments), } return render(request, template, { 'rack': rack, 'equipments': equipments })
def index(request): ''' First page view @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' timeout = datetime.now() - timedelta(seconds=HOST_TIMEOUT) hosts = Host.objects.all() problemhosts = Host.objects.filter(updated_at__lte=timeout).order_by('-updated_at') factcount = Fact.objects.count() factvaluecount = FactValue.objects.count() updatecount = Host.objects.filter(package__isnull=False).distinct().count() packagecount = Package.objects.count() securitycount = Package.objects.filter(update__is_security=True).distinct().count() return render(request, "index.html", { 'problemhosts': problemhosts, 'timeout': timeout, 'hosts': hosts, 'factcount': factcount, 'factvaluecount': factvaluecount, 'updatecount': updatecount, 'packagecount': packagecount, 'securitycount': securitycount, })
def advancedsearch(request): ''' Advanced search view. Renders free text search @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' return render(request, 'advancedsearch.html')
def index(request): ''' hwdoc index view @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' return render(request, 'hwdocindex.html')
def commented_equipment(request): ''' Equipment with comments view. It should display all non-authenticated user viewable data @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' template = 'interesting_equipment.html' equipments = { 'hwdoc': Equipment.objects.exclude(comments='').distinct() } return render(request, template, { 'equipments': equipments })
def unallocated_equipment(request): ''' Unallocated Equipment view. It should display all non-authenticated user viewable data @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' template = 'interesting_equipment.html' equipments = { 'hwdoc': Equipment.objects.filter(allocation__isnull=True).distinct() } return render(request, template, { 'equipments': equipments })
def project(request, project_id): ''' Project view. It should display all non-authenticated user viewable data @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' template = 'project.html' project = get_object_or_404(Project,pk=project_id) return render(request, template, { 'project': project, })
def inventory(request): keys = [ 'is_virtual', 'manufacturer', 'productname', 'bios_date', 'bios_version', 'serialnumber', 'architecture', 'processorcount', 'memorytotal', ] # This could be more normally be expressed starting with Host as the base # model, since we are essentially asking for hosts plus their facts. # # However, Django's select_related doesn't traverse reverse foreign keys, # and hence we were forced to do one fact query per host, i.e N+1 queries. # # Django 1.4 has prefetch_related() which may or may not help; until then # work around the ORM and combine it with itertools.groupby(). Should # still have a performance hit for, say, more than 1k hosts. facts = FactValue.objects.all() facts = facts.filter(fact_name__name__in=keys) facts = facts.order_by('host') # itertools.groupby needs sorted input facts = facts.select_related() # performance optimization hosts = [] from itertools import groupby for key, values in groupby(facts, key=lambda x: x.host.name): host = {'name': key } for v in values: host[v.name] = v.value host['resources'] = [] if host.get('manufacturer', '').startswith('Dell '): name = host.get('productname') if name: # Dell PowerEdge R210 II hack name = re.sub(r'\bii\b', '2', slugify(name)) host['resources'].append(('Drivers', DELL_DRIVERS_ROOT + name + ".html")) serial = host.get('serialnumber') if serial: host['resources'].append(('Support', DELL_SUPPORT_ROOT + serial)) hosts.append(host) return render(request, "inventory.html", {'hosts': hosts})
def project(request, project_id): ''' Project view. It should display all non-authenticated user viewable data @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' template = 'project.html' project = get_object_or_404(Project,pk=project_id) equipments = { 'hwdoc': functions.search(project.name) } return render(request, template, { 'project': project, 'equipments': equipments })
def ticketed_equipment(request): ''' Equipment with tickets view. It should display all non-authenticated user viewable data @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' template = 'interesting_equipment.html' equipments = Equipment.objects.exclude(comments='') equipments = functions.populate_tickets(equipments) equipments = [x for x in equipments if hasattr(x, 'tickets')] equipments = { 'hwdoc': equipments } return render(request, template, { 'equipments': equipments })
def inventory(request): ''' Puppet inventory view. Will display a pre-selected list of facts @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding JSON ''' keys = [ 'is_virtual', 'manufacturer', 'productname', 'bios_date', 'bios_version', 'serialnumber', 'architecture', 'processorcount', 'memorysize', ] # This could be more normally be expressed starting with Host as the base # model, since we are essentially asking for hosts plus their facts. # # However, Django's select_related doesn't traverse reverse foreign keys, # and hence we were forced to do one fact query per host, i.e N+1 queries. # # Django 1.4 has prefetch_related() which may or may not help; until then # work around the ORM and combine it with itertools.groupby(). Should # still have a performance hit for, say, more than 1k hosts. facts = FactValue.objects.all() facts = facts.filter(fact_name__name__in=keys) facts = facts.order_by('host') # itertools.groupby needs sorted input facts = facts.select_related() # performance optimization hosts = [] from itertools import groupby for key, values in groupby(facts, key=lambda x: x.host.name): host = {'name': key } for v in values: host[v.name] = v.value hosts.append(host) return render(request, "inventory.html", {'hosts': hosts})
def rack(request, rack_id): ''' Rack view. It should display all non-authenticated user viewable data @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' template = 'rack.html' rack = get_object_or_404(Rack, pk=rack_id) equipments = functions.search(str(rack.pk)) equipments = functions.populate_tickets(equipments) return render(request, template, { 'rack': rack, 'equipments': equipments })
def opensearch(request): ''' opensearch search view. Renders opensearch.xml @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding XML ''' fqdn = Site.objects.get_current().domain try: contact = ADMINS[0][0] except IndexError: contact = '*****@*****.**' return render(request, 'opensearch.xml', { 'opensearchbaseurl': "http://%s" % fqdn, 'fqdn': fqdn, 'contact': contact, }, content_type = 'application/opensearchdescription+xml')
def index(request): ''' hwdoc index view @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' datacenters = Datacenter.objects.all() racks = Rack.objects.order_by('id').all() projects = Project.objects.order_by('name').all() models = EquipmentModel.objects.select_related('vendor').order_by('vendor__name','name').all() return render(request, 'hwdocindex.html', { 'racks': racks, 'projects': projects, 'models': models, 'datacenters': datacenters, })
def rackrow(request, rackrow_id): ''' Rackrow view. It should display all non-authenticated user viewable data @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' template = 'rackrow.html' rackrow = get_object_or_404(RackRow, pk=rackrow_id) racks = rackrow.rackposition_set.select_related() for rack in racks: rack.equipments = functions.populate_tickets( rack.rack.equipment_set.select_related('model__vendor', 'model')) return render(request, template, { 'rackrow': rackrow, 'racks': racks, })
def search(request): if not request.POST or (not 'search' in request.POST): return HttpResponseRedirect('/') fieldmap = [ ('Hostname', 'fqdn'), ('MAC Address', 'macaddress_'), ('IPv4 Address', 'ipaddress_'), ('IPv6 Address', 'ipaddress6_'), ('Vendor', 'manufacturer'), ('Model', 'productname'), ('Puppet class', 'puppetclass'), ('Operating system', 'operatingsystem') ] matches = [] regex = re.compile(r'(' + request.POST['search'] + ')', re.IGNORECASE) base = FactValue.objects.filter(value__icontains=request.POST['search']) base = base.distinct().order_by('host__name') for name, field in fieldmap: res = base if field.endswith('_'): res = res.filter(fact_name__name__startswith=field) else: res = res.filter(fact_name__name=field) res = res.select_related() for r in res: matches.append({ 'name': r.host.name, 'attribute': name, 'value': regex.sub(r'<strong>\1</strong>', r.value), }) return render(request, "search.html", { 'matches': matches, 'search': request.POST['search'] })
def equipment(request, equipment_id): ''' Equipment view. It should display all non-authenticated user viewable data @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' template = 'equipment.html' equipment = get_object_or_404(Equipment,pk=equipment_id) equipment = functions.populate_tickets((equipment,))[0] try: equipment.prev = Equipment.objects.filter(rack=equipment.rack, unit__lt=equipment.unit).order_by('-unit')[0] except IndexError: equipment.prev = None try: equipment.next = Equipment.objects.filter(rack=equipment.rack, unit__gt=equipment.unit).order_by('unit')[0] except IndexError: equipment.next = None return render(request, template, { 'equipment': equipment, })
def search(request): ''' Search view. Scans request for q (GET case) or qarea (POST case) and searches for corresponding Equipment instances matching the query If txt is send in a GET it will display results in txt and not in html format @type request: HTTPRequest @param request: Django HTTPRequest object @rtype: HTTPResponse @return: HTTPResponse object rendering corresponding HTML ''' if u'txt' in request.GET: template = 'results.txt' mimetype = 'text/plain' else: template = 'results.html' mimetype = 'text/html' if u'q' in request.GET: key = request.GET['q'] elif u'qarea' in request.POST: key = functions.get_search_terms(request.POST['qarea']) else: key = None results = functions.search(key).select_related( 'servermanagement', 'rack', 'model', 'model__vendor', 'allocation') results = functions.populate_tickets(results) return render(request, template, { 'results': results, }, mimetype=mimetype)
def packagelist(request): packages = Package.objects.annotate(host_count=Count("hosts"), security_count=Sum("update__is_security")) return render(request, "packagelist.html", {"packages": packages})
def hostlist(request): hosts = Host.objects.annotate(update_count=Count('update'), security_count=Sum('update__is_security')) return render(request, 'hostlist.html', {'hosts': hosts })
def packagelist(request): packages = Package.objects.annotate(host_count=Count('hosts'), security_count=Sum('update__is_security')) return render(request, 'packagelist.html', {'packages': packages })
def host(request, hostname): host = get_object_or_404(Host, name=hostname) updates = [] system = [] location = [] try: iflist = host.get_fact_value('interfaces').split(',') except AttributeError: iflist = [] # Network part interfaces = [] for iface in iflist: d = {} iface1 = iface.replace(':','_') mac = host.get_fact_value('macaddress_%s' % iface1) ip = host.get_fact_value('ipaddress_%s' % iface1) netmask = host.get_fact_value('netmask_%s' % iface1) ip6 = host.get_fact_value('ipaddress6_%s' % iface1) d = { 'iface': iface, 'mac': mac } if netmask and ip: d['ipaddr'] = "%s/%d" % (ip, IP(ip).make_net(netmask).prefixlen()) if ip6: d['ipaddr6'] = ip6 interfaces.append(d) # System part fields = [ ('bios_date', 'BIOS Date'), ('bios_version', 'BIOS Version'), ('manufacturer', 'System Vendor'), ('productname', 'Model'), ('serialnumber', 'Serial number'), ('processorcount', 'Processors'), ('architecture', 'Architecture'), ('virtual', 'Machine Type'), ('uptime', 'Uptime'), ] for fact, label in fields: system.append({ 'name': label, 'value': host.get_fact_value(fact) }) system.append({ 'name': 'Processor type', 'value': ", ".join([ p['value'] for p in host.factvalue_set.filter(fact_name__name__startswith='processor').exclude(fact_name__name='processorcount').values('value').distinct() ]), }) system.append({ 'name': 'Operating System', 'value': "%s %s" % (host.get_fact_value('operatingsystem'), host.get_fact_value('operatingsystemrelease')) }) system.append({ 'name': 'Memory', 'value': "%s (%s free)" % (host.get_fact_value('memorytotal'), host.get_fact_value('memoryfree')) }) system.append({ 'name': 'Puppet classes', 'value': ", ".join([ f.value for f in host.factvalue_set.filter(fact_name__name='puppetclass') ]) }) # Location info part try: eq = Equipment.objects.get(serial=host.get_fact_value('serialnumber')) location.append({ 'name': 'Rack Unit', 'value': "%s" % ( eq.unit ) }) location.append({ 'name': 'Rack', 'value': "%s" % ( eq.rack ) }) location.append({ 'name': 'Rack Row', 'value': "%s" % ( eq.rack.rackposition.rr ) }) location.append({ 'name': 'IPMI Method', 'value': "%s" % ( eq.servermanagement.method ) }) location.append({ 'name': 'IPMI Hostname', 'value': "%s" % ( eq.servermanagement.hostname ) }) location.append({ 'name': 'IPMI MAC', 'value': "%s" % ( eq.servermanagement.mac ) }) location.append({ 'name': 'Datacenter', 'value': "%s" % ( eq.rack.rackposition.rr.dc ) }) except: location.append({ 'name': 'Location', 'value': "%s" % ( 'No location information found' ) }) # Updates info updates = Update.objects.filter(host=host).order_by('package__name') updates = updates.select_related() return render(request, 'hostview.html', { 'host': host, 'updates': updates, 'interfaces': interfaces, 'system': system, 'location': location, })
def host(request, hostname): host = get_object_or_404(Host, name=hostname) updates = [] system = [] try: iflist = host.get_fact_value("interfaces").split(",") except AttributeError: iflist = [] interfaces = [] for iface in iflist: d = {} iface1 = iface.replace(":", "_") mac = host.get_fact_value("macaddress_%s" % iface1) ip = host.get_fact_value("ipaddress_%s" % iface1) netmask = host.get_fact_value("netmask_%s" % iface1) ip6 = host.get_fact_value("ipaddress6_%s" % iface1) d = {"iface": iface, "mac": mac} if netmask and ip: d["ipaddr"] = "%s/%d" % (ip, IP(ip).make_net(netmask).prefixlen()) if ip6: d["ipaddr6"] = ip6 interfaces.append(d) fields = [ ("bios_date", "BIOS Date"), ("bios_version", "BIOS Version"), ("manufacturer", "System Vendor"), ("productname", "Model"), ("serialnumber", "Serial number"), ("processorcount", "Processors"), ("architecture", "Architecture"), ("virtual", "Machine Type"), ("uptime", "Uptime"), ] system = [] for fact, label in fields: system.append({"name": label, "value": host.get_fact_value(fact)}) system.append( { "name": "Processor type", "value": ", ".join( [ p["value"] for p in host.factvalue_set.filter(fact_name__name__startswith="processor") .exclude(fact_name__name="processorcount") .values("value") .distinct() ] ), } ) system.append( { "name": "Operating System", "value": "%s %s" % (host.get_fact_value("operatingsystem"), host.get_fact_value("operatingsystemrelease")), } ) system.append( { "name": "Memory", "value": "%s (%s free)" % (host.get_fact_value("memorytotal"), host.get_fact_value("memoryfree")), } ) system.append( { "name": "Puppet classes", "value": ", ".join([f.value for f in host.factvalue_set.filter(fact_name__name="puppetclass")]), } ) updates = Update.objects.filter(host=host).order_by("package__name") updates = updates.select_related() return render( request, "hostview.html", {"host": host, "updates": updates, "interfaces": interfaces, "system": system} )
def hostlist(request): hosts = Host.objects.annotate(update_count=Count("update"), security_count=Sum("update__is_security")) return render(request, "hostlist.html", {"hosts": hosts})