summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSol Jerome <sol.jerome@gmail.com>2015-07-23 12:03:29 -0500
committerSol Jerome <sol.jerome@gmail.com>2015-07-23 12:03:29 -0500
commitc11fcd8110e537db70bf40b91ed14467184b0e1c (patch)
treee2a39e6d2d7b5841cf71c21b07cd0cffb1fe21da
parent49ab865657f03795139e95490b1978fcceca2f41 (diff)
parent9d5524f345279a6fb6042ea5acd519549cabe5b7 (diff)
downloadbcfg2-c11fcd8110e537db70bf40b91ed14467184b0e1c.tar.gz
bcfg2-c11fcd8110e537db70bf40b91ed14467184b0e1c.tar.bz2
bcfg2-c11fcd8110e537db70bf40b91ed14467184b0e1c.zip
Merge branch 'fix-date-format' of https://github.com/AlexanderS/bcfg2
-rw-r--r--doc/man/bcfg2.conf.txt5
-rw-r--r--doc/releases/1.4.0pre2.txt5
-rw-r--r--man/bcfg2.conf.55
-rw-r--r--src/lib/Bcfg2/DBSettings.py13
-rw-r--r--src/lib/Bcfg2/Options/Types.py27
-rw-r--r--src/lib/Bcfg2/Reporting/templates/base-timeview.html2
-rw-r--r--src/lib/Bcfg2/Reporting/templates/clients/detail.html2
-rw-r--r--src/lib/Bcfg2/Reporting/templates/clients/detailed-list.html4
-rw-r--r--src/lib/Bcfg2/Reporting/templates/config_items/entry_status.html4
-rw-r--r--src/lib/Bcfg2/Reporting/templates/config_items/item.html2
-rw-r--r--src/lib/Bcfg2/Reporting/templates/widgets/interaction_list.inc4
-rw-r--r--testsuite/Testsrc/Testlib/TestOptions/TestTypes.py20
-rw-r--r--testsuite/common.py1
13 files changed, 54 insertions, 40 deletions
diff --git a/doc/man/bcfg2.conf.txt b/doc/man/bcfg2.conf.txt
index 62c4ac1a8..2f014812e 100644
--- a/doc/man/bcfg2.conf.txt
+++ b/doc/man/bcfg2.conf.txt
@@ -718,6 +718,11 @@ Reporting options
Maximum number of children for the reporting collector. Use 0 to
disable the limit. (default is 0)
+ django_settings
+ Arbitrary options for the Django installation. The value expected
+ is a literal python dictionary, that is merged with the already set
+ django settings.
+
See Also
--------
diff --git a/doc/releases/1.4.0pre2.txt b/doc/releases/1.4.0pre2.txt
index a5c10777a..195f81df0 100644
--- a/doc/releases/1.4.0pre2.txt
+++ b/doc/releases/1.4.0pre2.txt
@@ -31,6 +31,11 @@ backwards-incompatible user-facing changes
This fixes potentially long client runs when comparing files that have
diverged significantly.
+* The database options in the config (options and reporting_options in database
+ section) now have to be literal python dictionaries.
+
+ This allows to set arbitrary options with nested settings.
+
Thanks
------
diff --git a/man/bcfg2.conf.5 b/man/bcfg2.conf.5
index 13000a719..ba5158a0d 100644
--- a/man/bcfg2.conf.5
+++ b/man/bcfg2.conf.5
@@ -778,6 +778,11 @@ Turn on Django debugging.
.B max_children
Maximum number of children for the reporting collector. Use 0 to
disable the limit. (default is 0)
+.TP
+.B django_settings
+Arbitrary options for the Django installation. The value expected
+is a literal python dictionary, that is merged with the already set
+django settings.
.UNINDENT
.UNINDENT
.UNINDENT
diff --git a/src/lib/Bcfg2/DBSettings.py b/src/lib/Bcfg2/DBSettings.py
index 5a83c25c3..3e101405d 100644
--- a/src/lib/Bcfg2/DBSettings.py
+++ b/src/lib/Bcfg2/DBSettings.py
@@ -123,6 +123,9 @@ def finalize_django_config(opts=None, silent=False):
opts.web_prefix.rstrip('/') + \
settings['MEDIA_URL']
+ if opts.django_settings:
+ settings.update(opts.django_settings)
+
logger = logging.getLogger()
logger.debug("Finalizing Django settings: %s" % settings)
@@ -229,7 +232,7 @@ class _OptionContainer(object):
dest='db_schema', default='public'),
Bcfg2.Options.Option(
cf=('database', 'options'), help='Database options',
- dest='db_opts', type=Bcfg2.Options.Types.comma_dict,
+ dest='db_opts', type=Bcfg2.Options.Types.literal_dict,
default=dict()),
# reporting database options
Bcfg2.Options.Option(
@@ -258,14 +261,18 @@ class _OptionContainer(object):
Bcfg2.Options.Option(
cf=('database', 'reporting_options'),
help='Reporting database options', dest='reporting_db_opts',
- type=Bcfg2.Options.Types.comma_dict, default=dict()),
+ type=Bcfg2.Options.Types.literal_dict, default=dict()),
# Django options
Bcfg2.Options.Option(
cf=('reporting', 'time_zone'), help='Django timezone'),
Bcfg2.Options.BooleanOption(
cf=('reporting', 'web_debug'), help='Django debug'),
Bcfg2.Options.Option(
- cf=('reporting', 'web_prefix'), help='Web prefix')]
+ cf=('reporting', 'web_prefix'), help='Web prefix'),
+ Bcfg2.Options.Option(
+ cf=('reporting', 'django_settings'),
+ help='Additional django settings',
+ type=Bcfg2.Options.Types.literal_dict, default=dict())]
@staticmethod
def component_parsed_hook(opts):
diff --git a/src/lib/Bcfg2/Options/Types.py b/src/lib/Bcfg2/Options/Types.py
index ac099e135..ad2e04f10 100644
--- a/src/lib/Bcfg2/Options/Types.py
+++ b/src/lib/Bcfg2/Options/Types.py
@@ -5,6 +5,7 @@ import os
import re
import pwd
import grp
+from Bcfg2.Compat import literal_eval
_COMMA_SPLIT_RE = re.compile(r'\s*,\s*')
@@ -32,28 +33,10 @@ def colon_list(value):
return value.split(':')
-def comma_dict(value):
- """ Split an option string on commas, optionally surrounded by
- whitespace, and split the resulting items again on equals signs,
- returning a dict """
- result = dict()
- if value:
- items = comma_list(value)
- for item in items:
- if '=' in item:
- key, value = item.split(r'=', 1)
- if value in ["true", "yes", "on"]:
- result[key] = True
- elif value in ["false", "no", "off"]:
- result[key] = False
- else:
- try:
- result[key] = int(value)
- except ValueError:
- result[key] = value
- else:
- result[item] = True
- return result
+def literal_dict(value):
+ """ literally evaluate the option in order to allow for arbitrarily nested
+ dictionaries """
+ return literal_eval(value)
def anchored_regex_list(value):
diff --git a/src/lib/Bcfg2/Reporting/templates/base-timeview.html b/src/lib/Bcfg2/Reporting/templates/base-timeview.html
index 9a5ef651c..28a9fa0f4 100644
--- a/src/lib/Bcfg2/Reporting/templates/base-timeview.html
+++ b/src/lib/Bcfg2/Reporting/templates/base-timeview.html
@@ -17,7 +17,7 @@ function bcfg2_check_date() {
}
document.write(getCalendarStyles());
</script>
-{% if not timestamp %}Rendered at {% now "Y-m-d H:i" %} | {% else %}View as of {{ timestamp|date:"Y-m-d H:i" }} | {% endif %}{% spaceless %}
+{% if not timestamp %}Rendered at {% now "SHORT_DATETIME_FORMAT" %} | {% else %}View as of {{ timestamp|date:"SHORT_DATETIME_FORMAT" }} | {% endif %}{% spaceless %}
<a id='cal_link' name='cal_link' href='#' onclick='showCalendar(); return false;'
>[change]</a>
<form method='post' action='{{ path }}' id='cal_form' name='cal_form'>
diff --git a/src/lib/Bcfg2/Reporting/templates/clients/detail.html b/src/lib/Bcfg2/Reporting/templates/clients/detail.html
index 6732bb8c9..6809dcc2d 100644
--- a/src/lib/Bcfg2/Reporting/templates/clients/detail.html
+++ b/src/lib/Bcfg2/Reporting/templates/clients/detail.html
@@ -39,7 +39,7 @@ span.history_links a {
<select id="quick" name="quick" onchange="javascript:pageJump('quick');">
<option value="" selected="selected">--- Time ---</option>
{% for i in client.interactions.all|slice:":25" %}
- <option value="{% url "reports_client_detail_pk" hostname=client.name pk=i.id %}">{{i.timestamp|date:"c"}}</option>
+ <option value="{% url "reports_client_detail_pk" hostname=client.name pk=i.id %}">{{i.timestamp|date:"DATETIME_FORMAT"}}</option>
{% endfor %}
</select></span>
</div>
diff --git a/src/lib/Bcfg2/Reporting/templates/clients/detailed-list.html b/src/lib/Bcfg2/Reporting/templates/clients/detailed-list.html
index 6a314bd88..cf778504a 100644
--- a/src/lib/Bcfg2/Reporting/templates/clients/detailed-list.html
+++ b/src/lib/Bcfg2/Reporting/templates/clients/detailed-list.html
@@ -32,7 +32,9 @@ This is needed for Django versions less than 1.5
<td class='right_column_narrow'>{{ entry.bad_count }}</td>
<td class='right_column_narrow'>{{ entry.modified_count }}</td>
<td class='right_column_narrow'>{{ entry.extra_count }}</td>
- <td class='right_column'><span {% if entry.isstale %}class='dirty-lineitem'{% endif %}>{{ entry.timestamp|date:"Y-m-d\&\n\b\s\p\;H:i"|safe }}</span></td>
+ <td class='right_column'><span {% if entry.isstale %}class='dirty-lineitem'{% endif %} style="white-space: nowrap;">
+ {{ entry.timestamp|date:"SHORT_DATETIME_FORMAT"|safe }}
+ </span></td>
<td class='right_column_wide'>
{% if entry.server %}
<a href='{% add_url_filter server=entry.server %}'>{{ entry.server }}</a>
diff --git a/src/lib/Bcfg2/Reporting/templates/config_items/entry_status.html b/src/lib/Bcfg2/Reporting/templates/config_items/entry_status.html
index e3befb0eb..8a5d93690 100644
--- a/src/lib/Bcfg2/Reporting/templates/config_items/entry_status.html
+++ b/src/lib/Bcfg2/Reporting/templates/config_items/entry_status.html
@@ -22,7 +22,9 @@ This is needed for Django versions less than 1.5
{% for inter in inters %}
<tr class='{% cycle listview,listview_alt %}'>
<td><a href='{% url "reports_client_detail" hostname=inter.client.name %}'>{{inter.client.name}}</a></td>
- <td><a href='{% url "reports_client_detail_pk" hostname=inter.client.name pk=inter.pk %}'>{{inter.timestamp|date:"Y-m-d\&\n\b\s\p\;H:i"|safe}}</a></td>
+ <td><a href='{% url "reports_client_detail_pk" hostname=inter.client.name pk=inter.pk %}' style="white-space: nowrap;">
+ {{inter.timestamp|date:"SHORT_DATETIME_FORMAT"|safe}}
+ </a></td>
<td>{{ item.get_state_display }}</td>
<td style='white-space: nowrap'><a href='{% url "reports_item" entry_type=item.class_name pk=item.pk %}'>({{item.pk}}) {{item.short_list|join:","}}</a></td>
</tr>
diff --git a/src/lib/Bcfg2/Reporting/templates/config_items/item.html b/src/lib/Bcfg2/Reporting/templates/config_items/item.html
index c6e6df020..2e2fd36fa 100644
--- a/src/lib/Bcfg2/Reporting/templates/config_items/item.html
+++ b/src/lib/Bcfg2/Reporting/templates/config_items/item.html
@@ -130,7 +130,7 @@ div.entry_list h3 {
<div class='entry_list'>
<div class='entry_list_head'>
- <h3>Occurences on {{ timestamp|date:"Y-m-d" }}</h3>
+ <h3>Occurences on {{ timestamp|date:"SHORT_DATE_FORMAT" }}</h3>
</div>
{% if associated_list %}
<table class="entry_list" cellpadding="3">
diff --git a/src/lib/Bcfg2/Reporting/templates/widgets/interaction_list.inc b/src/lib/Bcfg2/Reporting/templates/widgets/interaction_list.inc
index 30ed2fd3e..444d05e1e 100644
--- a/src/lib/Bcfg2/Reporting/templates/widgets/interaction_list.inc
+++ b/src/lib/Bcfg2/Reporting/templates/widgets/interaction_list.inc
@@ -15,7 +15,9 @@
</tr>
{% for entry in entry_list %}
<tr class='{% cycle listview,listview_alt %}'>
- <td class='left_column'><a href='{% url reports_client_detail_pk hostname=entry.client.name, pk=entry.id %}'>{{ entry.timestamp|date:"Y-m-d\&\n\b\s\p\;H:i"|safe }}</a></td>
+ <td class='left_column'><a href='{% url reports_client_detail_pk hostname=entry.client.name, pk=entry.id %}' class="white-space: nowrap;">
+ {{ entry.timestamp|date:"SHORT_DATETIME_FORMAT"|safe }}
+ </a></td>
{% if not client %}
<td class='right_column_wide'><a href='{% add_url_filter hostname=entry.client.name %}'>{{ entry.client.name }}</a></td>
{% endif %}
diff --git a/testsuite/Testsrc/Testlib/TestOptions/TestTypes.py b/testsuite/Testsrc/Testlib/TestOptions/TestTypes.py
index 404d67fdc..0b67db38a 100644
--- a/testsuite/Testsrc/Testlib/TestOptions/TestTypes.py
+++ b/testsuite/Testsrc/Testlib/TestOptions/TestTypes.py
@@ -46,21 +46,23 @@ class TestOptionTypes(Bcfg2TestCase):
self.assertItemsEqual(self._test_options(["--test", "one:two three"]),
["one", "two three"])
- def test_comma_dict(self):
- """parse comma-dict values."""
- self.options = [Option("--test", type=Types.comma_dict)]
+ def test_literal_dict(self):
+ """parse literal-dict values."""
+ self.options = [Option("--test", type=Types.literal_dict)]
expected = {
"one": True,
"two": 2,
"three": "three",
- "four": False}
+ "four": False,
+ "five": {
+ "a": 1,
+ "b": 2
+ }}
self.assertDictEqual(
self._test_options(["--test",
- "one=yes, two=2 , three=three,four=no"]),
- expected)
-
- self.assertDictEqual(
- self._test_options(["--test", "one,two=2,three=three,four=off"]),
+ '''{ "one": True, "two": 2,
+ "three": "three", "four": False,
+ "five": { "a": 1, "b": 2 }}''']),
expected)
def test_anchored_regex_list(self):
diff --git a/testsuite/common.py b/testsuite/common.py
index 4c7337e0d..e53cfdddf 100644
--- a/testsuite/common.py
+++ b/testsuite/common.py
@@ -64,6 +64,7 @@ try:
set_setup_default("time_zone")
set_setup_default("web_debug", False)
set_setup_default("web_prefix")
+ set_setup_default("django_settings")
import Bcfg2.DBSettings
Bcfg2.DBSettings.finalize_django_config()