Skip to content
Snippets Groups Projects
Unverified Commit fc3b8dba authored by Thomas Woerner's avatar Thomas Woerner Committed by GitHub
Browse files

Merge pull request #335 from seocam/multi-dnszone

Allow to manage multiple dnszone entries.
parents 3a572440 75d16c2d
No related branches found
No related tags found
No related merge requests found
......@@ -163,7 +163,7 @@ Variable | Description | Required
-------- | ----------- | --------
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
`name` \| `zone_name` | The zone name string. | yes
`name` \| `zone_name` | The zone name string or list of strings. | yes
`forwarders` | The list of forwarders dicts. Each `forwarders` dict entry has:| no
  | `ip_address` - The IPv4 or IPv6 address of the DNS server. | yes
  | `port` - The custom port that should be used on this server. | no
......
......@@ -506,7 +506,7 @@ class FreeIPABaseModule(AnsibleModule):
# when needed.
self.ipa_params = AnsibleFreeIPAParams(self)
def get_ipa_command_args(self):
def get_ipa_command_args(self, **kwargs):
"""
Return a dict to be passed to an IPA command.
......@@ -538,7 +538,7 @@ class FreeIPABaseModule(AnsibleModule):
elif hasattr(self, param_name):
method = getattr(self, param_name)
if callable(method):
value = method()
value = method(**kwargs)
# We don't have a way to guess the value so fail.
else:
......
......@@ -41,7 +41,7 @@ options:
name:
description: The zone name string.
required: true
type: str
type: list
alises: ["zone_name"]
forwarders:
description: The list of global DNS forwarders.
......@@ -268,7 +268,7 @@ class DNSZoneModule(FreeIPABaseModule):
return True
def get_ipa_nsec3paramrecord(self):
def get_ipa_nsec3paramrecord(self, **kwargs):
nsec3param_rec = self.ipa_params.nsec3param_rec
if nsec3param_rec is not None:
error_msg = (
......@@ -280,7 +280,7 @@ class DNSZoneModule(FreeIPABaseModule):
self.fail_json(msg=error_msg)
return nsec3param_rec
def get_ipa_idnsforwarders(self):
def get_ipa_idnsforwarders(self, **kwargs):
if self.ipa_params.forwarders is not None:
forwarders = []
for forwarder in self.ipa_params.forwarders:
......@@ -304,14 +304,14 @@ class DNSZoneModule(FreeIPABaseModule):
return forwarders
def get_ipa_idnsallowtransfer(self):
def get_ipa_idnsallowtransfer(self, **kwargs):
if self.ipa_params.allow_transfer is not None:
error_msg = "Invalid ip_address for DNS allow_transfer: %s"
self.validate_ips(self.ipa_params.allow_transfer, error_msg)
return (";".join(self.ipa_params.allow_transfer) or "none") + ";"
def get_ipa_idnsallowquery(self):
def get_ipa_idnsallowquery(self, **kwargs):
if self.ipa_params.allow_query is not None:
error_msg = "Invalid ip_address for DNS allow_query: %s"
self.validate_ips(self.ipa_params.allow_query, error_msg)
......@@ -334,70 +334,78 @@ class DNSZoneModule(FreeIPABaseModule):
return ".".join((name, domain))
def get_ipa_idnssoarname(self):
def get_ipa_idnssoarname(self, **kwargs):
if self.ipa_params.admin_email is not None:
return DNSName(
self._replace_at_symbol_in_rname(self.ipa_params.admin_email)
)
def get_ipa_idnssoamname(self):
def get_ipa_idnssoamname(self, **kwargs):
if self.ipa_params.name_server is not None:
return DNSName(self.ipa_params.name_server)
def get_ipa_skip_overlap_check(self):
if not self.zone and self.ipa_params.skip_overlap_check is not None:
def get_ipa_skip_overlap_check(self, **kwargs):
zone = kwargs.get('zone')
if not zone and self.ipa_params.skip_overlap_check is not None:
return self.ipa_params.skip_overlap_check
def get_ipa_skip_nameserver_check(self):
if not self.zone and self.ipa_params.skip_nameserver_check is not None:
def get_ipa_skip_nameserver_check(self, **kwargs):
zone = kwargs.get('zone')
if not zone and self.ipa_params.skip_nameserver_check is not None:
return self.ipa_params.skip_nameserver_check
def get_zone(self, zone_name):
get_zone_args = {"idnsname": zone_name, "all": True}
response = self.api_command("dnszone_find", args=get_zone_args)
zone = None
is_zone_active = False
if response["count"] == 1:
self.zone = response["result"][0]
self.is_zone_active = self.zone.get("idnszoneactive") == ["TRUE"]
return self.zone
zone = response["result"][0]
is_zone_active = zone.get("idnszoneactive") == ["TRUE"]
return zone, is_zone_active
# Zone doesn't exist yet
self.zone = None
self.is_zone_active = False
def get_zone_names(self):
if len(self.ipa_params.name) > 1 and self.ipa_params.state != "absent":
self.fail_json(
msg=("Please provide a single name. Multiple values for 'name'"
"can only be supplied for state 'absent'.")
)
@property
def zone_name(self):
return self.ipa_params.name
def define_ipa_commands(self):
for zone_name in self.get_zone_names():
# Look for existing zone in IPA
self.get_zone(self.zone_name)
args = self.get_ipa_command_args()
zone, is_zone_active = self.get_zone(zone_name)
args = self.get_ipa_command_args(zone=zone)
just_added = False
if self.ipa_params.state in ["present", "enabled", "disabled"]:
if not self.zone:
if not zone:
# Since the zone doesn't exist we just create it
# with given args
self.add_ipa_command("dnszone_add", self.zone_name, args)
self.is_zone_active = True
self.add_ipa_command("dnszone_add", zone_name, args)
is_zone_active = True
just_added = True
else:
# Zone already exist so we need to verify if given args
# matches the current config. If not we updated it.
if self.require_ipa_attrs_change(args, self.zone):
self.add_ipa_command("dnszone_mod", self.zone_name, args)
if self.require_ipa_attrs_change(args, zone):
self.add_ipa_command("dnszone_mod", zone_name, args)
if self.ipa_params.state == "enabled" and not self.is_zone_active:
self.add_ipa_command("dnszone_enable", self.zone_name)
if self.ipa_params.state == "enabled" and not is_zone_active:
self.add_ipa_command("dnszone_enable", zone_name)
if self.ipa_params.state == "disabled" and self.is_zone_active:
self.add_ipa_command("dnszone_disable", self.zone_name)
if self.ipa_params.state == "disabled" and is_zone_active:
self.add_ipa_command("dnszone_disable", zone_name)
if self.ipa_params.state == "absent":
if self.zone:
self.add_ipa_command("dnszone_del", self.zone_name)
if zone:
self.add_ipa_command("dnszone_del", zone_name)
# Due to a bug in FreeIPA dnszone-add won't set
# SOA Serial. The good news is that dnszone-mod does the job.
......@@ -408,7 +416,7 @@ class DNSZoneModule(FreeIPABaseModule):
args = {
"idnssoaserial": self.ipa_params.serial,
}
self.add_ipa_command("dnszone_mod", self.zone_name, args)
self.add_ipa_command("dnszone_mod", zone_name, args)
def get_argument_spec():
......@@ -426,7 +434,7 @@ def get_argument_spec():
ipaadmin_principal=dict(type="str", default="admin"),
ipaadmin_password=dict(type="str", required=False, no_log=True),
name=dict(
type="str", default=None, required=True, aliases=["zone_name"]
type="list", default=None, required=True, aliases=["zone_name"]
),
forwarders=dict(
type="list",
......
......@@ -149,3 +149,40 @@
forwarders: []
register: result
failed_when: not result.changed
- name: Create zones test1
ipadnszone:
ipaadmin_password: SomeADMINpassword
name: test1.testzone.local
- name: Create zones test2
ipadnszone:
ipaadmin_password: SomeADMINpassword
name: test2.testzone.local
- name: Create zones test3
ipadnszone:
ipaadmin_password: SomeADMINpassword
name: test3.testzone.local
- name: Ensure multiple zones are absent
ipadnszone:
ipaadmin_password: SomeADMINpassword
name:
- test1.testzone.local
- test2.testzone.local
- test3.testzone.local
state: absent
register: result
failed_when: not result.changed
- name: Ensure multiple zones are absent, again
ipadnszone:
ipaadmin_password: SomeADMINpassword
name:
- test1.testzone.local
- test2.testzone.local
- test3.testzone.local
state: absent
register: result
failed_when: result.changed
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment