-
Notifications
You must be signed in to change notification settings - Fork 116
Description
When running this formula under python3, multiple issues crop up:
-
dictsort is used extensively and has changed functionality between py2 and py3. Python2 would happily sort a dictionary containing both strings and integers. Python3 however will return a TypeError saying that int and str are incompatible types.
This is a known change in the sorted() function. -
{{ zone_records | tojson }} seems to break on mixed data as well. I did not dig into the reason yet.
There are two possible ways of resolving the issue:
-
Document that zone data must be all strings. Especially when configuring PTR RRs. Instead of using an int as key, this needs to be wrapped in quotes to ensure there are only strings. This ill work but has the drawback that e.g. '110' is now seen as smaller than e.g. '40' and the order of entries in the zone files appear incorrectly sorted.
-
Remove all use of dictsort and instead rely on the python3 behavior that dicts are now returned in deterministic (but not sorted) order.
What is the preferred solution?
For 2. an example patch might look like this:
diff --git a/bind/config.sls b/bind/config.sls
index 0d200e7..d9a62b8 100644
--- a/bind/config.sls
+++ b/bind/config.sls
@@ -223,9 +223,9 @@ bind_rndc_client_config:
{%- set views = {False: salt['pillar.get']('bind', {})} %}{# process non-view zones in the same loop #}
{%- do views.update(salt['pillar.get']('bind:configured_views', {})) %}
-{%- for view, view_data in views|dictsort %}
+{%- for view, view_data in views.items() %}
{%- set dash_view = '-' + view if view else '' %}
-{%- for zone, zone_data in view_data.get('configured_zones', {})|dictsort -%}
+{%- for zone, zone_data in view_data.get('configured_zones', {}).items() -%}
{%- if 'file' in zone_data %}
{%- set file = zone_data.file %}
{%- set zone = file|replace(".txt", "") %}
@@ -260,7 +260,7 @@ zones{{ dash_view }}-{{ zone }}{{ '.include' if serial_auto else '' }}:
zone: zones{{ dash_view }}-{{ zone }}
soa: {{ salt['pillar.get']("bind:available_zones:" + zone + ":soa") | json }}
includes: {{ salt['pillar.get']("bind:available_zones:" + zone + ":includes") | json }}
- records: {{ zone_records | json }}
+ records: {{ zone_records }}
include: False
{% endif %}
- user: {{ salt['pillar.get']('bind:config:user', map.user) }}
diff --git a/bind/files/zone.jinja b/bind/files/zone.jinja
index 9583197..ac77c62 100644
--- a/bind/files/zone.jinja
+++ b/bind/files/zone.jinja
@@ -28,11 +28,11 @@ $TTL {{ soa['ttl'] }}
{% if include %}
$INCLUDE {{ include }}
{% else %}
-{% for type, rrs in records|dictsort %}
+{% for type, rrs in records.items() %}
;
; {{ type }} RRs
;
-{%- for host, data in rrs|dictsort %}
+{%- for host, data in rrs.items() %}
{%- if data is mapping %}
{%- if 'ttl' in data %}
{{ host }} {{ data['ttl'] }} {{ data['type'] }} {{ data['record'] }}