diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c63289f2d2b26b784b2c9fcfa7801802572536ce..60b3d8624431ccefa85f6a095bf097faf711ae2f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -49,6 +49,7 @@ include: stages: - build - create-vps + - test-dns - setup-cluster - helm-release - apps-ready @@ -142,6 +143,13 @@ create-vps: on_stop: terminate-droplet auto_stop_in: 1 week +# Stage: test-dns +test-dns: + stage: test-dns + script: + - *debug_information + - cd ansible/ + - pytest -v -s -m 'dns' --connection=ansible --ansible-inventory=${CLUSTER_DIR}/inventory.yml --hosts='ansible://*' # Stage: setup-cluster # ==================== diff --git a/requirements.in b/requirements.in index d31c24c634e2bd0af45aee72666f6e4956694813..87151868e8395a36f46facc7cc28bdcc9be092f5 100644 --- a/requirements.in +++ b/requirements.in @@ -7,6 +7,8 @@ # # ansible>=2.9.10 is needed for using the `k8s` resource ansible>=2.9.10,<2.10 +# needed for test_dns.py +dnspython>=2.1.0 # Needed for ansible k8s resource openshift>=0.12.0 # Needed for testinfra using the ansible module @@ -15,6 +17,8 @@ psutil>=5.5.0 pyopenssl>=19.0.0 pytest-rerunfailures>=8.0 testinfra>=3.0.0 +# needed for test_dns.py +tld>=0.12.5 setuptools>=40.6.2 wheel>=0.33.1 -e git+https://open.greenhost.net/greenhost/cloud-api#egg=greenhost_cloud diff --git a/requirements.txt b/requirements.txt index 270c09ba2361a93cd2edcfb8a23e948734f06f00..25fc0ba57515035fe714a487c94dcd932af1733a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -36,14 +36,12 @@ cryptography==3.4.6 # ansible # paramiko # pyopenssl +dnspython==2.1.0 + # via -r requirements.in google-auth==1.27.1 # via kubernetes idna==2.10 # via requests -importlib-metadata==3.7.3 - # via - # pluggy - # pytest iniconfig==1.1.1 # via pytest jinja2==2.11.3 @@ -139,10 +137,10 @@ tabulate==0.8.9 # via greenhost-cloud testinfra==6.0.0 # via -r requirements.in +tld==0.12.5 + # via -r requirements.in toml==0.10.2 # via pytest -typing-extensions==3.7.4.3 - # via importlib-metadata urllib3==1.26.4 # via # kubernetes @@ -152,8 +150,6 @@ websocket-client==0.58.0 # via kubernetes wheel==0.36.2 # via -r requirements.in -zipp==3.4.1 - # via importlib-metadata # The following packages are considered to be unsafe in a requirements file: # setuptools diff --git a/test/pytest.ini b/test/pytest.ini index 083c14bcc77323e71050ef750798ad43e3c615ff..8c3edaa21609cf60f27105478d666f34668cefc8 100644 --- a/test/pytest.ini +++ b/test/pytest.ini @@ -6,6 +6,7 @@ markers = prometheus: Test prometheus helmreleases: Test deployed helmreleases installed by flux apps_running: Test if all the pods for the helmreleases are running + dns: Check if cluster domain resolves at all nameservers # https://docs.pytest.org/en/latest/warnings.html filterwarnings = diff --git a/test/pytest/test_dns.py b/test/pytest/test_dns.py new file mode 100755 index 0000000000000000000000000000000000000000..08f74654068c33a392a91ea5cd476db9f34aefe0 --- /dev/null +++ b/test/pytest/test_dns.py @@ -0,0 +1,67 @@ +""" +Test if main domain of cluster is resolvable at all authorative nameservers, +and also external ones, and check if all nameservers return the same result. +""" + +import os +import dns.resolver +import pytest +import tld + +@pytest.mark.testinfra +@pytest.mark.dns +def test_dns(host): + """Get domain from ansible vars, resolve it against all nameservers and + check if all results are the same. + """ + + def test_nameserver(nameserver: str, domain: str): + """Resolve domain at given nameserver.""" + my_resolver = dns.resolver.Resolver() + my_resolver.nameservers = [nameserver] + answer = my_resolver.resolve(domain) + addr = answer[0].address + print(f"{domain} @{nameserver}: {addr}") + return addr + + # Get ansible domain + ansible_vars = host.ansible.get_variables() + assert 'domain' in ansible_vars + domain = ansible_vars['domain'] + + # Get FLD and authorative nameservers for domain + fld = tld.get_fld(domain, fix_protocol=True) + authorative_nameservers_raw = dns.resolver.resolve(fld, 'NS') + authorative_nameservers = [] + for nameserver in authorative_nameservers_raw: + ips = dns.resolver.resolve(nameserver.to_text()) + authorative_nameservers.append(ips[0].address) + + system_nameservers = dns.resolver.get_default_resolver() + external_nameservers = ['1.1.1.1', '8.8.8.8'] + + results = [] + print('\nTesting authorative nameservers:') + print(authorative_nameservers) + for i in authorative_nameservers: + print(i) + results.append(test_nameserver(i, domain)) + results.append(test_nameserver(i, "*." + domain)) + + print('\nTesting system nameservers:') + for i in system_nameservers.nameservers: + results.append(test_nameserver(i, domain)) + results.append(test_nameserver(i, "*." + domain)) + + print('\nTesting external nameservers') + for i in external_nameservers: + results.append(test_nameserver(i, domain)) + results.append(test_nameserver(i, "*." + domain)) + + unique = set(results) + print(f'\nResults: {unique}') + assert len(unique) == 1 + + +if __name__ == "__main__": + test_dns('localhost')