diff options
13 files changed, 110 insertions, 47 deletions
diff --git a/src/lib/Server/Reports/reports/templates/base.html b/src/lib/Server/Reports/reports/templates/base.html index b968e4e84..d733e5563 100644 --- a/src/lib/Server/Reports/reports/templates/base.html +++ b/src/lib/Server/Reports/reports/templates/base.html @@ -3,9 +3,9 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>{% block title %}Bcfg2 Reporting System{% endblock %}</title> - <link rel="stylesheet" type="text/css" href="/site_media/boxypastel.css" /> - <link rel="stylesheet" type="text/css" href="/site_media/base.css" /> - <script type="text/javascript" src="/site_media/main.js"></script> + <link rel="stylesheet" type="text/css" href="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/boxypastel.css" /> + <link rel="stylesheet" type="text/css" href="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/base.css" /> + <script type="text/javascript" src="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/main.js"></script> {% block extra_header_info %}{% endblock %} </head> @@ -19,21 +19,21 @@ <div id="sidebar"> {% block sidebar %} <ul class="sidebar"> - <li><a href="/" class="sidebar">Home</a></li> - <li><a href="/clients/" class="sidebar">Clients</a></li> + <li><a href="{% url Bcfg2.Server.Reports.reports.views.client_index %}../" class="sidebar">Home</a></li> + <li><a href="{% url Bcfg2.Server.Reports.reports.views.client_index %}" class="sidebar">Clients</a></li> <li> - <a href="/displays/" class="sidebar">Displays</a> + <a href="{% url Bcfg2.Server.Reports.reports.views.display_index %}" class="sidebar">Displays</a> <ul class="sidebar-level2"> - <li><a href="/displays/sys-view/" class="sidebar">System</a></li> - <li><a href="/displays/summary/" class="sidebar">Summary</a></li> - <li><a href="/displays/timing/" class="sidebar">Timing</a></li> + <li><a href="{% url Bcfg2.Server.Reports.reports.views.display_sys_view %}" class="sidebar">System</a></li> + <li><a href="{% url Bcfg2.Server.Reports.reports.views.display_summary %}" class="sidebar">Summary</a></li> + <li><a href="{% url Bcfg2.Server.Reports.reports.views.display_timing %}" class="sidebar">Timing</a></li> </ul> </li> <li> <span class="sidebar">Config Items</span> <ul class="sidebar-level2"> - <li><a href="/elements/bad/" class="sidebar">Bad</a></li> - <li><a href="/elements/modified/" class="sidebar">Modified</a></li> + <li><a href="{% url Bcfg2.Server.Reports.reports.views.bad_item_index %}" class="sidebar">Bad</a></li> + <li><a href="{% url Bcfg2.Server.Reports.reports.views.modified_item_index %}" class="sidebar">Modified</a></li> </ul> </li> </ul> diff --git a/src/lib/Server/Reports/reports/templates/clients/client-nodebox.html b/src/lib/Server/Reports/reports/templates/clients/client-nodebox.html index dade598cf..77621cace 100644 --- a/src/lib/Server/Reports/reports/templates/clients/client-nodebox.html +++ b/src/lib/Server/Reports/reports/templates/clients/client-nodebox.html @@ -7,7 +7,7 @@ <table class="invisitable"> <tr><td width="43%"><h2>Node: <span class="nodename"> - <a href="/clients/{{client.name}}/{{interaction.id}}">{{client.name}}</a></span></h2></td> + <a href="{% url Bcfg2.Server.Reports.reports.views.client_detail client.name,pk=i.id %}">{{client.name}}</a></span></h2></td> <td width="23%"> {% if interaction.repo_revision %}Revision: {{interaction.repo_revision}}{% endif %} </td> @@ -32,7 +32,7 @@ <span class="nodelisttitle"><a href="javascript:toggleLayer('{{client.name}}-bad');" title="Click to expand" class="commentLink">{{interaction.bad_items.count}}</a> items did not verify and are considered Dirty.<br /></span> <div class="items" id="{{client.name}}-bad"><ul class="plain"> {% for bad in interaction.bad_items.all|sortwell %} - <li><strong>{{bad.kind}}: </strong><tt><a href="/elements/bad/{{bad.id}}">{{bad.name}}</a></tt></li> + <li><strong>{{bad.kind}}: </strong><tt><a href="{% url Bcfg2.Server.Reports.reports.views.config_item_bad bad.id%}">{{bad.name}}</a></tt></li> {% endfor %} </ul></div> </div> @@ -42,7 +42,7 @@ <span class="nodelisttitle"><a href="javascript:toggleLayer('{{client.name}}-modified');" title="Click to expand" class="commentLink">{{interaction.modified_items.count}}</a> items were modified in the last run.<br /></span> <div class="items" id="{{client.name}}-modified"><ul class="plain"> {% for modified in interaction.modified_items.all|sortwell %} - <li><strong>{{modified.kind}}: </strong><tt><a href="/elements/modified/{{modified.id}}">{{modified.name}}</a></tt></li> + <li><strong>{{modified.kind}}: </strong><tt><a href="{% url Bcfg2.Server.Reports.reports.views.config_item_modified modified.id %}">{{modified.name}}</a></tt></li> {% endfor %} </ul></div> </div> diff --git a/src/lib/Server/Reports/reports/templates/clients/detail.html b/src/lib/Server/Reports/reports/templates/clients/detail.html index 4ac2123c1..dd992547c 100644 --- a/src/lib/Server/Reports/reports/templates/clients/detail.html +++ b/src/lib/Server/Reports/reports/templates/clients/detail.html @@ -3,12 +3,15 @@ {% block title %}Info for: {{client.name}}{% endblock %} {% block content %} +<h2>Client Status Detail page for {{client.name}}</h2><br/> <b>Select time: </b> <select name=quick onChange="MM_jumpMenu('parent',this,0)"> {% for i in client.interactions.all %} - <option {% ifequal i.id interaction.id %}selected {% endifequal %} value="/clients/{{client.name}}/{{i.id}}/"> {{i.timestamp}} + <option {% ifequal i.id interaction.id %}selected {% endifequal %} value="{% url Bcfg2.Server.Reports.reports.views.client_detail client.name,pk=i.id %}"> {{i.timestamp}} {% endfor %} </select> + +<a href="{% url Bcfg2.Server.Reports.reports.views.client_manage client.name %}">Manage</a> {{client.name}} options.<br/> {% include "clients/client-nodebox.html" %} {% endblock %} diff --git a/src/lib/Server/Reports/reports/templates/clients/index.html b/src/lib/Server/Reports/reports/templates/clients/index.html index 9870e2942..f8dd9167c 100644 --- a/src/lib/Server/Reports/reports/templates/clients/index.html +++ b/src/lib/Server/Reports/reports/templates/clients/index.html @@ -15,7 +15,7 @@ <ul style="list-style-type:none;"> {% for client in client_list_a %} <li><div class="{{client.current_interaction.state}}-lineitem"> - <a href="{{client.name}}/">{{ client.name }}</a> + <a href="{% url Bcfg2.Server.Reports.reports.views.client_detail client.name %}">{{ client.name }}</a> </div></li> {% endfor %} </ul> @@ -24,12 +24,12 @@ {% if client_list_b %} {% for client in client_list_b %} <li><div class="{{client.current_interaction.state}}-lineitem"> - <a href="{{client.name}}/">{{ client.name }}</a> + <a href="{% url Bcfg2.Server.Reports.reports.views.client_detail client.name %}">{{ client.name }}</a> </div></li> {% endfor %} {% endif %} </ul> -</tr></tab.e> +</tr></table> {% else %} <p>No client records are available.</p> {% endif %} diff --git a/src/lib/Server/Reports/reports/templates/clients/manage.html b/src/lib/Server/Reports/reports/templates/clients/manage.html new file mode 100644 index 000000000..6b7cd2ee0 --- /dev/null +++ b/src/lib/Server/Reports/reports/templates/clients/manage.html @@ -0,0 +1,27 @@ +{% extends "base.html" %} +{% block extra_header_info %} +<script type="text/javascript" src="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/CalendarPopup.js"></script> +<script language="JavaScript">var cal = new CalendarPopup();</script> +{% endblock%} +{% block title %}{{client.name}}{% endblock %} + +{% block content %} +<h2>Client Options Management page for {{client.name}}</h2><br/> +<p>Client status detail page: <a href="{% url Bcfg2.Server.Reports.reports.views.client_detail client.name %}">{{client.name}}</a>.</p> +<p>Hosts may be prevented from showing up in the reporting system if they have been retired, are no longer managed by bcfg2 :(, etc. </p> +<b>Select deactivation date: </b> +<div> +<span class="mini-date"> +<b>Enter date or use calendar popup: </b> +<form name="timestamp-select" action="{% url Bcfg2.Server.Reports.reports.views.client_manage client.name %}" method="post"> +<input type="text" name="date1" value="{{timestamp_date}}" size=10>@ +<input type="text" name="time" value="{{timestamp_time}}" size=8> +<a href="" onClick="cal.select(document.forms['timestamp-select'].date1,'anchor1','yyyy-MM-dd'); return false;" + name="anchor1" ID="anchor1">Calendar</a> +<input type="submit" value="Submit"> +</form> +</span><br/><br/><br/></div> +<br/><br/> +<p>{{message}}</p> + +{% endblock %} diff --git a/src/lib/Server/Reports/reports/templates/config_items/index.html b/src/lib/Server/Reports/reports/templates/config_items/index.html index 60a09fe57..32e1ed17b 100644 --- a/src/lib/Server/Reports/reports/templates/config_items/index.html +++ b/src/lib/Server/Reports/reports/templates/config_items/index.html @@ -3,8 +3,8 @@ {% extends "base.html" %} {% block extra_header_info %} -<link rel="stylesheet" type="text/css" href="/site_media/syntax-coloring.css" /> -<script type="text/javascript" src="/site_media/CalendarPopup.js"></script> +<link rel="stylesheet" type="text/css" href="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/syntax-coloring.css" /> +<script type="text/javascript" src="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/CalendarPopup.js"></script> <script language="JavaScript">var cal = new CalendarPopup();</script> {% endblock%} {% block title %}Configuration Element Details{% endblock %} @@ -17,6 +17,7 @@ {% endblock %} {% block content %} + {% ifequal mod_or_bad "bad" %} <div class="bad"> <h2>Bad {{item.kind}}: {{item.name}}</h2> @@ -56,14 +57,19 @@ <input type="text" name="time" value="{{timestamp_time}}" size=8> <a href="" onClick="cal.select(document.forms['timestamp-select'].date1,'anchor1','yyyy-MM-dd'); return false;" name="anchor1" ID="anchor1">Calendar</A> -<input type="button" name="go" value="Go" onClick="location.href='/elements/{{mod_or_bad}}/{{item.id}}/'+document.forms['timestamp-select'].date1.value+'@'+document.forms['timestamp-select'].time.value;" /> - | <input type="button" name="now" value="Now" onClick="location.href='/elements/{{mod_or_bad}}/{{item.id}}';"/> +{% ifequal mod_or_bad "modified" %} + <input type="button" name="go" value="Go" onClick="location.href='{% url Bcfg2.Server.Reports.reports.views.config_item_modified eyedee=item.id%}'+document.forms['timestamp-select'].date1.value+'@'+document.forms['timestamp-select'].time.value;" /> + | <input type="button" name="now" value="Now" onClick="location.href='{% url Bcfg2.Server.Reports.reports.views.config_item_modified eyedee=item.id%}';"/> +{% else %} + <input type="button" name="go" value="Go" onClick="location.href='{% url Bcfg2.Server.Reports.reports.views.config_item_bad eyedee=item.id%}'+document.forms['timestamp-select'].date1.value+'@'+document.forms['timestamp-select'].time.value;" /> + | <input type="button" name="now" value="Now" onClick="location.href='{% url Bcfg2.Server.Reports.reports.views.config_item_bad eyedee=item.id%}';"/> +{% endifequal %} </form> </span><br/><br/><br/></div> {% if associated_client_list %} <p>The following clients had this problem as of {{timestamp_date}}@{{timestamp_time}}:</p> {% for client in associated_client_list %} - <a href="/clients/{{client.name}}">{{client.name}}</a><br/> + <a href="{% url Bcfg2.Server.Reports.reports.views.client_detail client.name %}">{{client.name}}</a><br/> {% endfor %} <br /> <br /> diff --git a/src/lib/Server/Reports/reports/templates/config_items/listing.html b/src/lib/Server/Reports/reports/templates/config_items/listing.html index 8c4500258..f3be1e4d5 100644 --- a/src/lib/Server/Reports/reports/templates/config_items/listing.html +++ b/src/lib/Server/Reports/reports/templates/config_items/listing.html @@ -2,20 +2,20 @@ {% load django_templating_sigh %} {% block extra_header_info %} -<link rel="stylesheet" type="text/css" href="/site_media/yui/tabview/assets/tabview.css"> -<link rel="stylesheet" type="text/css" href="/site_media/yui/round_tabs.css"> +<link rel="stylesheet" type="text/css" href="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/yui/tabview/assets/tabview.css"> +<link rel="stylesheet" type="text/css" href="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/yui/round_tabs.css"> -<script type="text/javascript" src="/site_media/yui/yahoo/yahoo.js"></script> -<script type="text/javascript" src="/site_media/yui/event/event.js"></script> -<script type="text/javascript" src="/site_media/yui/dom/dom.js"></script> -<script type="text/javascript" src="/site_media/yui/tabview/tabview.js"></script> +<script type="text/javascript" src="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/yui/yahoo/yahoo.js"></script> +<script type="text/javascript" src="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/yui/event/event.js"></script> +<script type="text/javascript" src="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/yui/dom/dom.js"></script> +<script type="text/javascript" src="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/yui/tabview/tabview.js"></script> <script type="text/javascript"> YAHOO.example.init = function( ){ var tabView = new YAHOO.widget.TabView( { id: 'demo' } ); {% for item_list in item_list_pseudodict %} tabView.addTab( new YAHOO.widget.Tab({ label: '{{item_list.0}}', - content: '<p><ul style="list-style-type:none;">{% for item in item_list.1|sortwell %}<li><strong>{{item.kind}}: </strong><tt><a href="/elements/{{mod_or_bad}}/{{item.id}}">{{item.name}}</a></tt></li>{% endfor %}</ul></p>', + content: '<p><ul style="list-style-type:none;">{% for item in item_list.1|sortwell %}<li><strong>{{item.kind}}: </strong><tt>{% ifequal mod_or_bad "modified" %}<a href="{%url Bcfg2.Server.Reports.reports.views.config_item_modified eyedee=item.id%}">{{item.name}}</a>{% else %}<a href="{%url Bcfg2.Server.Reports.reports.views.config_item_bad eyedee=item.id%}">{{item.name}}</a>{% endifequal %}</tt></li>{% endfor %}</ul></p>', active: 'True' })); {% endfor %} diff --git a/src/lib/Server/Reports/reports/templates/displays/index.html b/src/lib/Server/Reports/reports/templates/displays/index.html index 5d1d3bf76..c078539b6 100644 --- a/src/lib/Server/Reports/reports/templates/displays/index.html +++ b/src/lib/Server/Reports/reports/templates/displays/index.html @@ -11,8 +11,8 @@ {% block content %} <ul> -<li><a href="/displays/sys-view/">System View</a></li> -<li><a href="/displays/summary/">Summary Only</a></li> -<li><a href="/displays/timing/">Timing</a></li> +<li><a href="{% url Bcfg2.Server.Reports.reports.views.display_sys_view %}">System View</a></li> +<li><a href="{% url Bcfg2.Server.Reports.reports.views.display_summary %}">Summary Only</a></li> +<li><a href="{% url Bcfg2.Server.Reports.reports.views.display_timing %}">Timing</a></li> </ul> {% endblock %} diff --git a/src/lib/Server/Reports/reports/templates/displays/summary-block-direct-links.html b/src/lib/Server/Reports/reports/templates/displays/summary-block-direct-links.html index a218e12b6..60f97eadc 100644 --- a/src/lib/Server/Reports/reports/templates/displays/summary-block-direct-links.html +++ b/src/lib/Server/Reports/reports/templates/displays/summary-block-direct-links.html @@ -1,7 +1,7 @@ {% extends "displays/summary-block.html" %} -{% block linkprefix1 %}/clients/{% endblock %} -{% block linkprefix2 %}/clients/{% endblock %} -{% block linkprefix3 %}/clients/{% endblock %} -{% block linkprefix4 %}/clients/{% endblock %} -{% block linkprefix5 %}/clients/{% endblock %} -{% block linkprefix6 %}/clients/{% endblock %}
\ No newline at end of file +{% block linkprefix1 %}{% url Bcfg2.Server.Reports.reports.views.client_index %}{% endblock %} +{% block linkprefix2 %}{% url Bcfg2.Server.Reports.reports.views.client_index %}{% endblock %} +{% block linkprefix3 %}{% url Bcfg2.Server.Reports.reports.views.client_index %}{% endblock %} +{% block linkprefix4 %}{% url Bcfg2.Server.Reports.reports.views.client_index %}{% endblock %} +{% block linkprefix5 %}{% url Bcfg2.Server.Reports.reports.views.client_index %}{% endblock %} +{% block linkprefix6 %}{% url Bcfg2.Server.Reports.reports.views.client_index %}{% endblock %}
\ No newline at end of file diff --git a/src/lib/Server/Reports/reports/templates/displays/summary.html b/src/lib/Server/Reports/reports/templates/displays/summary.html index cf253c25c..8c83bd501 100644 --- a/src/lib/Server/Reports/reports/templates/displays/summary.html +++ b/src/lib/Server/Reports/reports/templates/displays/summary.html @@ -1,6 +1,6 @@ {% extends "base.html" %} {% block extra_header_info %} -<script type="text/javascript" src="/site_media/CalendarPopup.js"></script> +<script type="text/javascript" src="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/CalendarPopup.js"></script> <script language="JavaScript">var cal = new CalendarPopup();</script> {% endblock%} {% block title %}Display Index Listing{% endblock %} @@ -21,8 +21,8 @@ <input type="text" name="time" value="{{timestamp_time}}" size=8> <a href="" onClick="cal.select(document.forms['timestamp-select'].date1,'anchor1','yyyy-MM-dd'); return false;" name="anchor1" ID="anchor1">Calendar</A> -<input type="button" name="go" value="Go" onClick="location.href='/displays/summary/'+document.forms['timestamp-select'].date1.value+'@'+document.forms['timestamp-select'].time.value;" /> - | <input type="button" name="now" value="Now" onClick="location.href='/displays/summary/';"/> +<input type="button" name="go" value="Go" onClick="location.href='{% url Bcfg2.Server.Reports.reports.views.display_summary %}'+document.forms['timestamp-select'].date1.value+'@'+document.forms['timestamp-select'].time.value;" /> + | <input type="button" name="now" value="Now" onClick="location.href='{% url Bcfg2.Server.Reports.reports.views.display_summary %}';"/> </form> </span><br/><br/><br/></div> {% include "displays/summary-block-direct-links.html" %} diff --git a/src/lib/Server/Reports/reports/templates/displays/timing.html b/src/lib/Server/Reports/reports/templates/displays/timing.html index e9020b8ef..8586de2cf 100644 --- a/src/lib/Server/Reports/reports/templates/displays/timing.html +++ b/src/lib/Server/Reports/reports/templates/displays/timing.html @@ -1,8 +1,8 @@ {% extends "base.html" %} {% block extra_header_info %} -<script type="text/javascript" src="/site_media/sorttable.js"></script> -<script type="text/javascript" src="/site_media/CalendarPopup.js"></script> +<script type="text/javascript" src="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/sorttable.js"></script> +<script type="text/javascript" src="{% url Bcfg2.Server.Reports.reports.views.client_index %}../site_media/CalendarPopup.js"></script> <script language="JavaScript">var cal = new CalendarPopup();</script> {% endblock%} {% block title %}Display Index Listing{% endblock %} @@ -21,8 +21,8 @@ <input type="text" name="time" value="{{timestamp_time}}" size=8> <a href="" onClick="cal.select(document.forms['timestamp-select'].date1,'anchor1','yyyy-MM-dd'); return false;" name="anchor1" ID="anchor1">Calendar</A> -<input type="button" name="go" value="Go" onClick="location.href='/displays/timing/'+document.forms['timestamp-select'].date1.value+'@'+document.forms['timestamp-select'].time.value;" /> - | <input type="button" name="now" value="Now" onClick="location.href='/displays/timing/';"/> +<input type="button" name="go" value="Go" onClick="location.href='{% url Bcfg2.Server.Reports.reports.views.display_timing %}'+document.forms['timestamp-select'].date1.value+'@'+document.forms['timestamp-select'].time.value;" /> + | <input type="button" name="now" value="Now" onClick="location.href='{% url Bcfg2.Server.Reports.reports.views.display_timing %}';"/> </form> </span><br/><br/><br/></div> <center> @@ -38,7 +38,7 @@ </tr> {% for dict_unit in stats_list %} <tr> - <td class="sortable"><a href="/clients/{{dict_unit.name}}/">{{dict_unit.name}}</a></td> + <td class="sortable"><a href="{% url Bcfg2.Server.Reports.reports.views.client_detail dict_unit.name%}/">{{dict_unit.name}}</a></td> <td class="sortable">{{dict_unit.parse}}</td> <td class="sortable">{{dict_unit.probe}}</td> <td class="sortable">{{dict_unit.inventory}}</td> diff --git a/src/lib/Server/Reports/reports/views.py b/src/lib/Server/Reports/reports/views.py index 5ddfa6533..1d7fabe52 100644 --- a/src/lib/Server/Reports/reports/views.py +++ b/src/lib/Server/Reports/reports/views.py @@ -172,6 +172,31 @@ def client_detail(request, hostname = None, pk = None): interaction = client.interactions.get(pk=pk)#can this be a get object or 404? return render_to_response('clients/detail.html', {'client': client, 'interaction': interaction}) +def client_manage(request, hostname = None): + #SETUP error pages for when you specify a client or interaction that doesn't exist + client = get_object_or_404(Client, name=hostname) + currenttime = datetime.now().isoformat('@') + if client.expiration != None: + message = "This client currently has an expiration date of %s. Reports after %s will not include data for this host. You may change this if you wish by selecting a new time, earlier or later."%(client.expiration,client.expiration) + else: + message = "This client is currently active and displayed. You may choose a date after which this client will no longer appear in reports." + if request.method == 'POST': + date = request.POST['date1'] + time = request.POST['time'] + try: + timestamp = datetime(*(strptime(date+"@"+time, "%Y-%m-%d@%H:%M:%S")[0:6])) + except ValueError: + timestamp = None + if timestamp==None: + message = "Invalid removal date, please try again using the format: yyyy-mm-dd hh:mm:ss." + else: + client.expiration = timestamp + client.save() + message = "Expiration for client set to %s."%client.expiration + return render_to_response('clients/manage.html', {'client': client, 'message': message, + 'timestamp_date' : currenttime[:10], + 'timestamp_time' : currenttime[11:19]}) + def display_sys_view(request, timestamp = 'now'): client_lists = prepare_client_lists(request, timestamp) return render_to_response('displays/sys_view.html', client_lists) diff --git a/src/lib/Server/Reports/urls.py b/src/lib/Server/Reports/urls.py index 6d5fe8833..9f602cb4d 100644 --- a/src/lib/Server/Reports/urls.py +++ b/src/lib/Server/Reports/urls.py @@ -4,7 +4,9 @@ urlpatterns = patterns('', # Example: # (r'^Bcfg2.Server.Reports/', include('Bcfg2.Server.Reports.apps.foo.urls.foo')), (r'^/*$','Bcfg2.Server.Reports.reports.views.index'), + (r'^clients/(?P<hostname>\S+)/(?P<pk>\d+)/$', 'Bcfg2.Server.Reports.reports.views.client_detail'), + (r'^clients/(?P<hostname>\S+)/manage/$', 'Bcfg2.Server.Reports.reports.views.client_manage'), (r'^clients/(?P<hostname>\S+)/$', 'Bcfg2.Server.Reports.reports.views.client_detail'), (r'^clients/(?P<hostname>\S+)$', 'Bcfg2.Server.Reports.reports.views.client_detail'), #hack because hostnames have periods and we still want to append slash |