Skip to content

Commit

Permalink
Add domain nameservers checking hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
mondeja committed Jun 28, 2021
1 parent 0adf4f9 commit 0a340e2
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 1.2.2
current_version = 1.3.0

[bumpversion:file:setup.cfg]

Expand Down
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,22 @@ repos:
hooks:
- id: setup-cfg-fmt
- repo: https://github.com/mondeja/pre-commit-hooks
rev: v1.1.2
rev: v1.2.2
hooks:
- id: dev-extras-required
- repo: https://github.com/asottile/pyupgrade
rev: v2.12.0
rev: v2.19.4
hooks:
- id: pyupgrade
args:
- --py36-plus
- repo: https://github.com/psf/black
rev: 20.8b1
rev: 21.6b0
hooks:
- id: black
files: \.py$
- repo: https://github.com/PyCQA/flake8
rev: 3.9.1
rev: 3.9.2
hooks:
- id: flake8
name: flake8-package
Expand All @@ -35,7 +35,7 @@ repos:
- flake8-implicit-str-concat
files: ^tests/
- repo: https://github.com/PyCQA/isort
rev: 5.8.0
rev: 5.9.1
hooks:
- id: isort
args:
Expand Down
26 changes: 21 additions & 5 deletions .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,38 @@
- pyyaml
always_run: true
pass_filenames: false
- id: cloudflare-nameservers
name: cloudflare-nameservers
entry: nameservers-endswith-hook -nameserver=cloudflare.com
description: Check that Cloudflare mannages a domain
language: python
pass_filenames: false
always_run: true
additional_dependencies:
- dnspython
- id: dev-extras-required
name: dev-extras-required
entry: dev-extras-required-hook
description: Check if your development dependencies contains all other extras requirements
files: '(setup\.cfg)|(pyproject\.toml)'
language: python
- id: wavelint
name: wavelint
entry: wavelint-hook
description: Lints WAVE files
files: \.wav$
- id: nameservers-endswith
name: nameservers-endswith
entry: nameservers-endswith-hook
description: Check if the nameservers of a domain ends with a predefined string
language: python
pass_filenames: false
always_run: true
- id: root-editorconfig-required
name: root-editorconfig-required
entry: root-editorconfig-required-hook
description: Check if your repository has an '.editorconfig' file and if this has a 'root' directive defined as 'true' before section headers
language: python
always_run: true
pass_filenames: false
- id: wavelint
name: wavelint
entry: wavelint-hook
description: Lints WAVE files
files: \.wav$
language: python
32 changes: 31 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@

```yaml
- repo: https://github.com/mondeja/pre-commit-hooks
rev: v1.2.2
rev: v1.3.0
hooks:
- id: dev-extras-required
- id: root-editorconfig-required
- id: cloudflare-nameservers
args:
- -domain=my-web.xyz
```

## Hooks
Expand Down Expand Up @@ -53,6 +57,26 @@ requirement to another groups, it will be added to development requirements.
mandatory if the extras requirements are defined in a `pyproject.toml` file
and this is located in another directory than the current one.

### **`nameservers-endswith`**

Check that the nameservers of a domain ends with a string or raise an error.
You can use it to check if a site like Clouflare is managing a domain using
`-nameserver=cloudflare.com`.

#### Parameters

- `-domain=DOMAIN` (*str*): Domain name whose nameservers will be checked.
- `-nameserver=NAMESERVER` (*str*): String to end the domain name servers in.

### **`cloudflare-nameservers`**

Check that [Cloudflare][cloudflare-link] is handling the nameservers of a
domain.

#### Parameters

- `-domain=DOMAIN` (*str*): Domain name whose nameservers will be checked.

### **`root-editorconfig-required`**

Check if your repository has an `.editorconfig` file and if this has a `root`
Expand All @@ -76,6 +100,10 @@ durations...
- `-max-duration=TIME` (*float*): Maximum duration in seconds that your
sounds must have.

## More hooks

- [mondeja/pre-commit-po-hooks][pre-commit-po-hooks-link]

[pypi-link]: https://pypi.org/project/mondeja_pre_commit_hooks
[pypi-version-badge-link]: https://img.shields.io/pypi/v/mondeja_pre_commit_hooks
[pypi-pyversions-badge-link]: https://img.shields.io/pypi/pyversions/mondeja_pre_commit_hooks
Expand All @@ -85,3 +113,5 @@ durations...
[tests-link]: https://github.com/mondeja/pre-commit-hooks/actions?query=workflow%CI

[setup-py-upgrade-link]: https://github.com/asottile/setup-py-upgrade
[cloudflare-link]: https://cloudflare.com
[pre-commit-po-hooks-link]: https://github.com/mondeja/pre-commit-po-hooks
76 changes: 76 additions & 0 deletions hooks/nameservers_endswith.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
"""Script that checks if the nameservers of a domain ends with a defined string."""

import argparse
import sys

import dns.resolver


def nameservers_endswith(domain, nameserver, quiet=False):
"""Check that the nameservers of a domain endswith a strip after stripping
it all newlines and points.
Parameters
----------
domain : str
Domain whose nameserves will be checked.
nameserver: str
String that should match with the end of the string for the nameservers
handlers of the domain. For example, passing ``cloudflare.com`` you
can check if a domain is handled by Cloudflare.
quiet : bool, optional
Don't print the error in STDERR if a nameserver doesn't match.
"""
response = True

for ns in sorted(dns.resolver.resolve(domain, "NS")):
ns_ = ns.to_text().strip().strip(".")
if not ns_.endswith(nameserver):
if not quiet:
sys.stderr.write(
f"Found invalid nameserver '{ns_}' for domain '{domain}'.\n"
)
response = False
return response


def main():
parser = argparse.ArgumentParser()
parser.add_argument("-q", "--quiet", action="store_true", help="Supress output")
parser.add_argument(
"-d",
"-domain",
"--domain",
type=str,
metavar="DOMAIN",
required=True,
default=None,
dest="domain",
help="Domain which nameservers will be checked.",
)
parser.add_argument(
"-ns",
"-nameserver",
"--nameserver",
type=str,
metavar="end",
required=True,
default=None,
dest="nameserver",
help=(
"End of the string that must match the nameservers handlers"
" of the domain."
),
)
args = parser.parse_args()

return (
0 if nameservers_endswith(args.domain, args.nameserver, quiet=args.quiet) else 1
)


if __name__ == "__main__":
sys.exit(main())
5 changes: 4 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = mondeja_pre_commit_hooks
version = 1.2.2
version = 1.3.0
description = My own useful pre-commit hooks
long_description = file: README.md
long_description_content_type = text/markdown
Expand Down Expand Up @@ -33,16 +33,19 @@ exclude =
console_scripts =
add-pre-commit-hook = hooks.add_pre_commit_hook:main
dev-extras-required-hook = hooks.dev_extras_required:main
nameservers-endswith-hook = hooks.nameservers_endswith:main
root-editorconfig-required-hook = hooks.root_editorconfig_required:main
wavelint-hook = hooks.wavelint:main

[options.extras_require]
dev =
dnspython==2.1.0
pytest==6.2.0
pytest-cov==2.12.1
pyyaml==5.4.1
waves==0.2.5
test =
dnspython==2.1.0
pytest==6.2.0
pytest-cov==2.12.1
pyyaml==5.4.1
Expand Down
52 changes: 52 additions & 0 deletions tests/test_nameserver_endswith.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Tests for 'nameserver-endswith' hook."""

import contextlib
import io

import pytest

from hooks.nameservers_endswith import nameservers_endswith


@pytest.mark.parametrize("quiet", (True, False), ids=("quiet=True", "quiet=False"))
@pytest.mark.parametrize(
("domain", "nameserver", "expected_result", "expected_stderr"),
(
pytest.param(
"mkdocs-mdpo.ga",
"cloudflare.com",
True,
"",
id="domain=mkdocs-mdpo.ga-nameserver=cloudflare.com",
),
pytest.param(
"mkdocs-mdpo.ga",
"cloudflare.co",
False,
(
"Found invalid nameserver 'irma.ns.cloudflare.com' for domain"
" 'mkdocs-mdpo.ga'.\nFound invalid nameserver"
" 'craig.ns.cloudflare.com' for domain 'mkdocs-mdpo.ga'.\n"
),
id="domain=mkdocs-mdpo.ga-nameserver=cloudflare.co",
),
),
)
def test_nameservers_endswith(
domain, nameserver, expected_result, expected_stderr, quiet
):
stderr = io.StringIO()

with contextlib.redirect_stderr(stderr):
result = nameservers_endswith(
domain,
nameserver,
quiet=quiet,
)

assert result is expected_result

if not quiet:
assert expected_stderr == stderr.getvalue()
else:
assert not stderr.getvalue()

0 comments on commit 0a340e2

Please sign in to comment.