diff --git a/docs/docsite/extra-docs.yml b/docs/docsite/extra-docs.yml new file mode 100644 index 00000000..b0f892d9 --- /dev/null +++ b/docs/docsite/extra-docs.yml @@ -0,0 +1,6 @@ +--- +sections: + - title: Guides + toctree: + - filter_guide + - hosttech_guide diff --git a/docs/docsite/rst/filter_guide.rst b/docs/docsite/rst/filter_guide.rst new file mode 100644 index 00000000..3ab2c2b0 --- /dev/null +++ b/docs/docsite/rst/filter_guide.rst @@ -0,0 +1,95 @@ +.. _ansible_collections.community.dns.docsite.filter_guide: + +Community.Dns Filter Guide +========================== + +The :ref:`community.dns collection ` offers several filters for working with DNS names: + +- ``community.dns.get_public_suffix``: given a domain name, returns the public suffix; +- ``community.dns.get_registrable_domain``: given a domain name, returns the registrable domain name; +- ``community.dns.remove_public_suffix``: given a domain name, returns the part before the public suffix; +- ``community.dns.remove_registrable_domain``: given a domain name, returns the part before the registrable domain name. + +These filters allow to work with `public suffixes `_; a *public suffix* is a DNS suffix under which users can (or could) directly register names. They use the `Public Suffix List `_, a Mozilla initiative maintained as a community resource which tries to list all such public suffixes. Common examples for public suffixes are ``.com``, ``.net``, but also longer suffixes such as ``.co.uk`` or ``.github.io``. + +The label directly before the public suffix together with the suffix is called the *registrable domain name* or *registered domain name*, since these are usually the names that people can register. Examples for registrable domain names are ``example.com`` and ``example.co.uk``, while ``www.example.com`` is not a registrable domain name. A public suffix itself is also not a registrable domain name, as for example ``github.io``. + +Working with public suffixes +---------------------------- + +The ``community.dns.get_public_suffix`` and ``community.dns.remove_public_suffix`` filters allow to extract and remove public suffixes from DNS names: + +.. code-block:: yaml+jinja + + - assert: + that: + - >- + "www.ansible.com" | community.dns.get_public_suffix == ".com" + - >- + "some.random.prefixes.ansible.co.uk" | community.dns.get_public_suffix == ".co.uk" + - >- + "www.ansible.com" | community.dns.remove_public_suffix == "www.ansible" + - >- + "some.random.prefixes.ansible.co.uk" | community.dns.remove_public_suffix == "some.random.prefixes.ansible" + +The filters also allow additional options (keyword arguments): + +:keep_unknown_suffix: + + A boolean with default value ``true``. This treats unknown TLDs as valid public suffixes. So for example the public suffix of ``example.tlddoesnotexist`` is ``.tlddoesnotexist`` if this is ``true``. If set to ``false``, it will return an empty string in this case. This option corresponds to whether the global wildcard rule ``*`` in the Public Suffix List is used or not. + +:icann_only: + + A boolean with default value ``false``. This controls whether only entries from the ICANN section of the Public Suffix List are used, or also entries from the Private section. For example, ``.co.uk`` is in the ICANN section, but ``github.io`` is in the Private section. + +:normalize_result: + + (Only for ``community.dns.get_public_suffix``) A boolean with default value ``false``. This controls whether the result is reconstructed from the normalized name used during lookup. During normalization, ulabels are converted to alabels, and every label is converted to lowercase. For example, the ulabel ``ëçãmplê`` is converted to ``xn--mpl-llatwb`` (puny-code), and ``Example.COM`` is converted to ``example.com``. + +:keep_leading_period: + + (Only for ``community.dns.get_public_suffix``) A boolean with default value ``true``. This controls whether the leading period of a public suffix is preserved or not. + +:keep_trailing_period: + + (Only for ``community.dns.remove_public_suffix``) A boolean with default value ``false``. This controls whether the trailing period of the prefix (that is, the part before the public suffix) is preserved or not. + +Working with registrable domain names +------------------------------------- + +The ``community.dns.get_registrable_domain`` and ``community.dns.remove_registrable_domain`` filters allow to extract and remove registrable domain names from DNS names: + +.. code-block:: yaml+jinja + + - assert: + that: + - >- + "www.ansible.com" | community.dns.get_registrable_domain == "ansible.com" + - >- + "some.random.prefixes.ansible.co.uk" | community.dns.get_registrable_domain == "ansible.co.uk" + - >- + "www.ansible.com" | community.dns.remove_registrable_domain == "www" + - >- + "some.random.prefixes.ansible.co.uk" | community.dns.remove_registrable_domain == "some.random.prefixes" + +The filters also allow additional options (keyword arguments): + +:keep_unknown_suffix: + + A boolean with default value ``true``. This treats unknown TLDs as valid public suffixes. So for example the public suffix of ``example.tlddoesnotexist`` is ``.tlddoesnotexist`` if this is ``true``, and hence the registrable domain of ``www.example.tlddoesnotexist`` is ``example.tlddoesnotexist``. If set to ``false``, the registrable domain of ``www.example.tlddoesnotexist`` is ``tlddoesnotexist``. This option corresponds to whether the global wildcard rule ``*`` in the Public Suffix List is used or not. + +:icann_only: + + A boolean with default value ``false``. This controls whether only entries from the ICANN section of the Public Suffix List are used, or also entries from the Private section. For example, ``.co.uk`` is in the ICANN section, but ``github.io`` is in the Private section. + +:only_if_registerable: + + A boolean with default value ``true``. This controls the behavior in case there is no label in front of the public suffix. This is the case if the DNS name itself is a public suffix. If set to ``false``, in this case the public suffix is treated as a registrable domain. If set to ``true`` (default), the registrable domain of a public suffix is interpreted as an empty string. + +:normalize_result: + + (Only for ``community.dns.get_registrable_domain``) A boolean with default value ``false``. This controls whether the result is reconstructed from the normalized name used during lookup. During normalization, ulabels are converted to alabels, and every label is converted to lowercase. For example, the ulabel ``ëçãmplê`` is converted to ``xn--mpl-llatwb`` (puny-code), and ``Example.COM`` is converted to ``example.com``. + +:keep_trailing_period: + + (Only for ``community.dns.remove_registrable_domain``) A boolean with default value ``false``. This controls whether the trailing period of the prefix (that is, the part before the registrable domain) is preserved or not. diff --git a/docs/docsite/rst/hosttech_guide.rst b/docs/docsite/rst/hosttech_guide.rst new file mode 100644 index 00000000..13f53bd9 --- /dev/null +++ b/docs/docsite/rst/hosttech_guide.rst @@ -0,0 +1,244 @@ +.. _ansible_collections.community.dns.docsite.hosttech_guide: + +HostTech DNS Guide +================== + +The :ref:`community.dns collection ` offers several modules for working with the `HostTech DNS service `_. +The modules support both the old `WSDL-based API `_ and the new `JSON REST based API `_. + +The collection provides four modules for working with HostTech DNS: + +- ``community.dns.hosttech_dns_record``: create/update/delete DNS records +- ``community.dns.hosttech_dns_record_info``: retrieve information on DNS records +- ``community.dns.hosttech_dns_records``: bulk synchronize DNS records +- ``community.dns.hosttech_dns_zone_info``: retrieve zone information + +Authentication, Requirements and APIs +------------------------------------- + +HostTech currently has two APIs for working with DNS records: the old WSDL-based API, and the new JSON-based REST API. We recommend using the new REST API if possible. + +JSON REST API +~~~~~~~~~~~~~ + +To use the JSON REST API, you need to create a API token. You can manage API tokens in the "DNS Editor" in the "API" section. You must provide the token to the ``hosttech_token`` option of the modules: + +.. code-block:: yaml+jinja + + - community.dns.hosttech_dns_record: + hosttech_token: '{{ token }}' + ... + +In the examples in this guide, we will leave the authentication options away. Please note that you can set them globally with ``module_defaults`` (see :ref:`module_defaults`). + +WSDL API +~~~~~~~~ + +To use the WSDL API, you need to set API credentials. These can be found and changed in the "Servercenter" and there in the "Solutions" section under settings for the "DNS Tool". The username is fixed, but the password can be changed. The credentials must be provided to the ``hosttech_username`` and ``hosttech_password`` options of the modules. + +You also need to install the `lxml Python module `_ to work with the WSDL API. This can be done before using the modules: + +.. code-block:: yaml+jinja + + - name: Make sure lxml is installed + pip: + name: lxml + + - community.dns.hosttech_dns_record: + hosttech_username: '{{ username }}' + hosttech_password: '{{ password }}' + ... + +In the examples in this guide, we will leave the authentication options away. Please note that you can set them globally with ``module_defaults`` (see :ref:`module_defaults`). + +Working with DNS zones +---------------------- + +The ``community.dns.hosttech_dns_zone_info`` module allows to query information on a zone. The zone can be identified both by its name and by its ID (which is an integer): + +.. code-block:: yaml+jinja + + - name: Query zone information by name + community.dns.hosttech_dns_zone_info: + zone: example.com + register: result + + - name: Query zone information by name + community.dns.hosttech_dns_zone_info: + zone_id: 42 + register: result + +The module returns both the zone name and zone ID, so this module can be used to convert from zone ID to zone name and vice versa: + +.. code-block:: yaml+jinja + + - ansible.builtin.debug: + msg: | + The zone ID: {{ result.zone_id }} + The zone name: {{ result.zone_name }} + +Working with DNS records +------------------------ + +Querying DNS records +~~~~~~~~~~~~~~~~~~~~ + +The ``community.dns.hosttech_dns_record_info`` module allows to query DNS records from the API. It can be used to query a single record: + +.. code-block:: yaml+jinja + + - name: Query single record + community.dns.hosttech_dns_record_info: + zone: example.com + type: A # IPv4 addresses + what: single_record # default value + # Either specify a record name: + record: www.example.com + # Or a record prefix ('' is the zone itself): + prefix: www + register: result + + - name: Show IPv4 addresses if record exists + ansible.builtin.debug: + msg: > + IPv4s are {{ result.set.value | join(', ') }}, + TTL is {{ result.set.ttl }} + when: result.set + + - name: Show that record is not set + ansible.builtin.debug: + msg: There is no A record for www.example.com + when: not result.set + +In all examples in this section, you can replace ``zone: example.com`` by ``zone_id: 42`` with the zone's integer ID. + +You can also query a list of all records for a record name or prefix: + +.. code-block:: yaml+jinja + + - name: Query all records for www.example.com + community.dns.hosttech_dns_record_info: + zone: example.com + what: all_types_for_record + # Either specify a record name: + record: www.example.com + # Or a record prefix ('' is the zone itself): + prefix: www + register: result + + - name: Show all records for www.example.com + ansible.builtin.debug: + msg: > + {{ item.type }} record with TTL {{ item.ttl }} has + values {{ item.value | join(', ') }} + loop: result.sets + +Finally you can query all records for a zone: + +.. code-block:: yaml+jinja + + - name: Query all records for a zone + community.dns.hosttech_dns_record_info: + zone: example.com + what: all_records + register: result + + - name: Show all records for the example.com zone + ansible.builtin.debug: + msg: > + {{ item.type }} record for {{ item.record }} with + TTL {{ item.ttl }} has values {{ item.value | join(', ') }} + loop: result.sets + +Creating and updating DNS records +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``community.dns.hosttech_dns_record`` module allows to set, update and remove DNS records. Setting and updating can be done as follows: + +.. code-block:: yaml+jinja + + - name: Make sure record is set to the given value + community.dns.hosttech_dns_record: + zone: example.com + type: A # IPv4 addresses + # Either specify a record name: + record: www.example.com + # Or a record prefix ('' is the zone itself): + prefix: www + # The following makes sure that existing values + # (that differ form the one given) are updated: + overwrite: true + value: + - 1.1.1.1 + - 8.8.8.8 + +If you want to assert that a record has a certain value (and fail if it has a different value), leave away the ``overwrite: true``. + +To delete values, you can either overwrite the values with value ``[]``, or use ``state: absent``: + +.. code-block:: yaml+jinja + + - name: Remove A values for www.example.com + community.dns.hosttech_dns_record: + zone: example.com + type: A # IPv4 addresses + record: www.example.com + overwrite: true + value: [] + + - name: Remove specific AAAA values for www.example.com + community.dns.hosttech_dns_record: + zone: example.com + type: AAAA # IPv6 addresses + prefix: www + state: absent + ttl: 300 + value: + - '::1' + +In the second example, ``overwrite: true`` is not present, but an explicit value and TTL are given. This makes the module remove the current value only if there's a AAAA record for ``www.example.com`` whose current value is ``::1`` and whose TTL is 300. If another value is set, the module will not make any change. This can be useful to not accidentally remove values you do not want to change. + +Bulk synchronization of DNS records +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you want to set/update multiple records at once, or even make sure that the precise set of records you are providing are present and nothing else, you can use the ``community.dns.hosttech_dns_records`` module. + +The following example shows up to set/update multiple records at once: + +.. code-block:: yaml+jinja + + - name: Make sure that multiple records are present + community.dns.hosttech_dns_records: + zone: example.com + records: + - prefix: www + type: A + value: + - 1.1.1.1 + - 8.8.8.8 + - prefix: www + type: AAAA + value: + - '::1' + +The next example shows how to make sure that only the given records are available and all other records are deleted. Note that for the ``type: NS`` record we used ``ignore: true``, which allows us to skip the value. It tells the module that it should not touch the ``NS`` record for ``example.com``. + +.. code-block:: yaml+jinja + + - name: Make sure that multiple records are present + community.dns.hosttech_dns_records: + zone: example.com + prune: true + records: + - prefix: www + type: A + value: + - 1.1.1.1 + - 8.8.8.8 + - prefix: www + type: AAAA + value: + - '::1' + - prefix: '' + type: NS + ignore: true