saltext.gandi 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- saltext_gandi-0.1.0/.codecov.yml +25 -0
- saltext_gandi-0.1.0/.copier-answers.yml +33 -0
- saltext_gandi-0.1.0/.coveragerc +44 -0
- saltext_gandi-0.1.0/.envrc.example +7 -0
- saltext_gandi-0.1.0/.gitignore +136 -0
- saltext_gandi-0.1.0/.gitlab/issue_templates/Bug.md +16 -0
- saltext_gandi-0.1.0/.gitlab/issue_templates/Feature.md +4 -0
- saltext_gandi-0.1.0/.gitlab/merge_request_templates/Default.md +7 -0
- saltext_gandi-0.1.0/.gitlab-ci.yml +199 -0
- saltext_gandi-0.1.0/.pre-commit-config.yaml +150 -0
- saltext_gandi-0.1.0/.pre-commit-hooks/check-cli-examples.py +64 -0
- saltext_gandi-0.1.0/.pre-commit-hooks/check-gitlab-ci.py +50 -0
- saltext_gandi-0.1.0/.pre-commit-hooks/make-autodocs.py +123 -0
- saltext_gandi-0.1.0/.pylintrc +679 -0
- saltext_gandi-0.1.0/CHANGELOG.md +22 -0
- saltext_gandi-0.1.0/CODE-OF-CONDUCT.md +127 -0
- saltext_gandi-0.1.0/CONTRIBUTING.md +14 -0
- saltext_gandi-0.1.0/LICENSE +373 -0
- saltext_gandi-0.1.0/Makefile +58 -0
- saltext_gandi-0.1.0/PKG-INFO +182 -0
- saltext_gandi-0.1.0/README.md +125 -0
- saltext_gandi-0.1.0/changelog/.template.jinja +15 -0
- saltext_gandi-0.1.0/docs/Makefile +20 -0
- saltext_gandi-0.1.0/docs/_ext/saltdomain.py +18 -0
- saltext_gandi-0.1.0/docs/_static/.gitkeep +0 -0
- saltext_gandi-0.1.0/docs/changelog.md +12 -0
- saltext_gandi-0.1.0/docs/conf.py +199 -0
- saltext_gandi-0.1.0/docs/index.rst +47 -0
- saltext_gandi-0.1.0/docs/make.bat +35 -0
- saltext_gandi-0.1.0/docs/ref/.gitkeep +0 -0
- saltext_gandi-0.1.0/docs/ref/modules/index.rst +16 -0
- saltext_gandi-0.1.0/docs/ref/modules/saltext.gandi.modules.gandi_billing.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/modules/saltext.gandi.modules.gandi_domain.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/modules/saltext.gandi.modules.gandi_linkedzone.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/modules/saltext.gandi.modules.gandi_livedns.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/modules/saltext.gandi.modules.gandi_mod.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/runners/index.rst +16 -0
- saltext_gandi-0.1.0/docs/ref/runners/saltext.gandi.runners.gandi_billing.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/runners/saltext.gandi.runners.gandi_domain.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/runners/saltext.gandi.runners.gandi_linkedzone.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/runners/saltext.gandi.runners.gandi_livedns.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/runners/saltext.gandi.runners.gandi_mod.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/states/index.rst +14 -0
- saltext_gandi-0.1.0/docs/ref/states/saltext.gandi.states.gandi_domain.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/states/saltext.gandi.states.gandi_linkedzone.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/states/saltext.gandi.states.gandi_livedns.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/utils/index.rst +18 -0
- saltext_gandi-0.1.0/docs/ref/utils/saltext.gandi.utils.billing.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/utils/saltext.gandi.utils.client.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/utils/saltext.gandi.utils.domain.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/utils/saltext.gandi.utils.linkedzone.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/utils/saltext.gandi.utils.livedns.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/utils/saltext.gandi.utils.profile.rst +5 -0
- saltext_gandi-0.1.0/docs/ref/utils/saltext.gandi.utils.resources.rst +5 -0
- saltext_gandi-0.1.0/docs/sitevars.rst +0 -0
- saltext_gandi-0.1.0/docs/topics/configuration.md +224 -0
- saltext_gandi-0.1.0/docs/topics/dns-models.md +141 -0
- saltext_gandi-0.1.0/docs/topics/installation.md +28 -0
- saltext_gandi-0.1.0/docs/topics/testing.md +171 -0
- saltext_gandi-0.1.0/docs/topics/troubleshooting.md +148 -0
- saltext_gandi-0.1.0/docs/topics/usage.md +256 -0
- saltext_gandi-0.1.0/endpoints-report.txt +125 -0
- saltext_gandi-0.1.0/noxfile.py +545 -0
- saltext_gandi-0.1.0/pyproject.toml +198 -0
- saltext_gandi-0.1.0/setup.cfg +4 -0
- saltext_gandi-0.1.0/setup.py +5 -0
- saltext_gandi-0.1.0/src/saltext/gandi/__init__.py +28 -0
- saltext_gandi-0.1.0/src/saltext/gandi/modules/__init__.py +0 -0
- saltext_gandi-0.1.0/src/saltext/gandi/modules/gandi_billing.py +92 -0
- saltext_gandi-0.1.0/src/saltext/gandi/modules/gandi_domain.py +1526 -0
- saltext_gandi-0.1.0/src/saltext/gandi/modules/gandi_linkedzone.py +436 -0
- saltext_gandi-0.1.0/src/saltext/gandi/modules/gandi_livedns.py +962 -0
- saltext_gandi-0.1.0/src/saltext/gandi/modules/gandi_mod.py +225 -0
- saltext_gandi-0.1.0/src/saltext/gandi/runners/__init__.py +0 -0
- saltext_gandi-0.1.0/src/saltext/gandi/runners/gandi_billing.py +98 -0
- saltext_gandi-0.1.0/src/saltext/gandi/runners/gandi_domain.py +1535 -0
- saltext_gandi-0.1.0/src/saltext/gandi/runners/gandi_linkedzone.py +443 -0
- saltext_gandi-0.1.0/src/saltext/gandi/runners/gandi_livedns.py +971 -0
- saltext_gandi-0.1.0/src/saltext/gandi/runners/gandi_mod.py +176 -0
- saltext_gandi-0.1.0/src/saltext/gandi/states/__init__.py +0 -0
- saltext_gandi-0.1.0/src/saltext/gandi/states/gandi_domain.py +755 -0
- saltext_gandi-0.1.0/src/saltext/gandi/states/gandi_linkedzone.py +385 -0
- saltext_gandi-0.1.0/src/saltext/gandi/states/gandi_livedns.py +675 -0
- saltext_gandi-0.1.0/src/saltext/gandi/utils/__init__.py +0 -0
- saltext_gandi-0.1.0/src/saltext/gandi/utils/billing.py +97 -0
- saltext_gandi-0.1.0/src/saltext/gandi/utils/client.py +682 -0
- saltext_gandi-0.1.0/src/saltext/gandi/utils/domain.py +903 -0
- saltext_gandi-0.1.0/src/saltext/gandi/utils/linkedzone.py +371 -0
- saltext_gandi-0.1.0/src/saltext/gandi/utils/livedns.py +627 -0
- saltext_gandi-0.1.0/src/saltext/gandi/utils/profile.py +88 -0
- saltext_gandi-0.1.0/src/saltext/gandi/utils/resources.py +229 -0
- saltext_gandi-0.1.0/src/saltext/gandi/version.py +1 -0
- saltext_gandi-0.1.0/src/saltext.gandi.egg-info/PKG-INFO +182 -0
- saltext_gandi-0.1.0/src/saltext.gandi.egg-info/SOURCES.txt +149 -0
- saltext_gandi-0.1.0/src/saltext.gandi.egg-info/dependency_links.txt +1 -0
- saltext_gandi-0.1.0/src/saltext.gandi.egg-info/entry_points.txt +2 -0
- saltext_gandi-0.1.0/src/saltext.gandi.egg-info/not-zip-safe +1 -0
- saltext_gandi-0.1.0/src/saltext.gandi.egg-info/requires.txt +35 -0
- saltext_gandi-0.1.0/src/saltext.gandi.egg-info/scm_file_list.json +143 -0
- saltext_gandi-0.1.0/src/saltext.gandi.egg-info/scm_version.json +8 -0
- saltext_gandi-0.1.0/src/saltext.gandi.egg-info/top_level.txt +1 -0
- saltext_gandi-0.1.0/tests/__init__.py +0 -0
- saltext_gandi-0.1.0/tests/conftest.py +55 -0
- saltext_gandi-0.1.0/tests/functional/__init__.py +0 -0
- saltext_gandi-0.1.0/tests/functional/conftest.py +150 -0
- saltext_gandi-0.1.0/tests/functional/modules/__init__.py +0 -0
- saltext_gandi-0.1.0/tests/functional/modules/test_gandi.py +50 -0
- saltext_gandi-0.1.0/tests/functional/modules/test_gandi_billing.py +30 -0
- saltext_gandi-0.1.0/tests/functional/runners/__init__.py +0 -0
- saltext_gandi-0.1.0/tests/functional/states/__init__.py +0 -0
- saltext_gandi-0.1.0/tests/functional/states/test_gandi_domain.py +93 -0
- saltext_gandi-0.1.0/tests/functional/states/test_gandi_linkedzone.py +58 -0
- saltext_gandi-0.1.0/tests/functional/states/test_gandi_livedns.py +58 -0
- saltext_gandi-0.1.0/tests/integration/__init__.py +0 -0
- saltext_gandi-0.1.0/tests/integration/conftest.py +133 -0
- saltext_gandi-0.1.0/tests/integration/modules/__init__.py +0 -0
- saltext_gandi-0.1.0/tests/integration/modules/test_gandi.py +54 -0
- saltext_gandi-0.1.0/tests/integration/modules/test_gandi_billing.py +66 -0
- saltext_gandi-0.1.0/tests/integration/modules/test_gandi_domain.py +131 -0
- saltext_gandi-0.1.0/tests/integration/modules/test_gandi_linkedzone.py +111 -0
- saltext_gandi-0.1.0/tests/integration/modules/test_gandi_livedns.py +158 -0
- saltext_gandi-0.1.0/tests/integration/runners/__init__.py +0 -0
- saltext_gandi-0.1.0/tests/integration/states/__init__.py +0 -0
- saltext_gandi-0.1.0/tests/integration/states/test_gandi_livedns.py +188 -0
- saltext_gandi-0.1.0/tests/unit/__init__.py +0 -0
- saltext_gandi-0.1.0/tests/unit/conftest.py +86 -0
- saltext_gandi-0.1.0/tests/unit/modules/__init__.py +0 -0
- saltext_gandi-0.1.0/tests/unit/modules/test_gandi.py +103 -0
- saltext_gandi-0.1.0/tests/unit/runners/__init__.py +0 -0
- saltext_gandi-0.1.0/tests/unit/runners/test_gandi.py +61 -0
- saltext_gandi-0.1.0/tests/unit/states/__init__.py +0 -0
- saltext_gandi-0.1.0/tests/unit/states/test_gandi_domain.py +443 -0
- saltext_gandi-0.1.0/tests/unit/states/test_gandi_linkedzone.py +297 -0
- saltext_gandi-0.1.0/tests/unit/states/test_gandi_livedns.py +441 -0
- saltext_gandi-0.1.0/tests/unit/utils/__init__.py +0 -0
- saltext_gandi-0.1.0/tests/unit/utils/test_client.py +537 -0
- saltext_gandi-0.1.0/tests/unit/utils/test_domain.py +309 -0
- saltext_gandi-0.1.0/tests/unit/utils/test_linkedzone.py +255 -0
- saltext_gandi-0.1.0/tests/unit/utils/test_livedns.py +335 -0
- saltext_gandi-0.1.0/tests/unit/utils/test_profile.py +73 -0
- saltext_gandi-0.1.0/tools/gandi_docs.py +110 -0
- saltext_gandi-0.1.0/tools/helpers/__init__.py +0 -0
- saltext_gandi-0.1.0/tools/helpers/cmd.py +297 -0
- saltext_gandi-0.1.0/tools/helpers/copier.py +114 -0
- saltext_gandi-0.1.0/tools/helpers/git.py +30 -0
- saltext_gandi-0.1.0/tools/helpers/pre_commit.py +115 -0
- saltext_gandi-0.1.0/tools/helpers/prompt.py +54 -0
- saltext_gandi-0.1.0/tools/helpers/venv.py +128 -0
- saltext_gandi-0.1.0/tools/initialize.py +26 -0
- saltext_gandi-0.1.0/tools/verify_endpoints.py +109 -0
- saltext_gandi-0.1.0/tools/version.py +92 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
coverage:
|
|
3
|
+
status:
|
|
4
|
+
project:
|
|
5
|
+
default: false
|
|
6
|
+
app:
|
|
7
|
+
informational: true
|
|
8
|
+
paths:
|
|
9
|
+
- src/
|
|
10
|
+
tests:
|
|
11
|
+
informational: true
|
|
12
|
+
paths:
|
|
13
|
+
- tests/
|
|
14
|
+
patch:
|
|
15
|
+
default: false
|
|
16
|
+
app:
|
|
17
|
+
informational: true
|
|
18
|
+
paths:
|
|
19
|
+
- src/
|
|
20
|
+
tests:
|
|
21
|
+
informational: true
|
|
22
|
+
paths:
|
|
23
|
+
- tests/
|
|
24
|
+
github_checks:
|
|
25
|
+
annotations: false
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Autogenerated. Do not edit this by hand, use `copier update`.
|
|
2
|
+
---
|
|
3
|
+
_commit: 0.10.0
|
|
4
|
+
_src_path: https://github.com/salt-extensions/salt-extension-copier
|
|
5
|
+
author: Gary T. Giesen
|
|
6
|
+
author_email: ggiesen@giesen.me
|
|
7
|
+
coc_contact: ggiesen@giesen.me
|
|
8
|
+
copyright_begin: 2026
|
|
9
|
+
docs_url: https://ggiesen.gitlab.io/saltext-gandi/
|
|
10
|
+
integration_name: Gandi
|
|
11
|
+
license: other
|
|
12
|
+
license_classifier: 'License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)'
|
|
13
|
+
loaders:
|
|
14
|
+
- module
|
|
15
|
+
- runner
|
|
16
|
+
- state
|
|
17
|
+
max_salt_version: '3008'
|
|
18
|
+
no_saltext_namespace: false
|
|
19
|
+
os_support:
|
|
20
|
+
- Linux
|
|
21
|
+
- macOS
|
|
22
|
+
- Windows
|
|
23
|
+
package_name: gandi
|
|
24
|
+
project_name: gandi
|
|
25
|
+
python_requires: '3.10'
|
|
26
|
+
relax_pylint: false
|
|
27
|
+
salt_version: '3006'
|
|
28
|
+
source_url: https://gitlab.com/ggiesen/saltext-gandi
|
|
29
|
+
ssh_fixtures: false
|
|
30
|
+
summary: Salt Extension for interacting with the Gandi.net API
|
|
31
|
+
test_containers: false
|
|
32
|
+
tracker_url: https://gitlab.com/ggiesen/saltext-gandi/-/issues
|
|
33
|
+
url: https://gitlab.com/ggiesen/saltext-gandi
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
[run]
|
|
2
|
+
branch = True
|
|
3
|
+
cover_pylib = False
|
|
4
|
+
relative_files = True
|
|
5
|
+
parallel = True
|
|
6
|
+
concurrency = multiprocessing
|
|
7
|
+
|
|
8
|
+
omit =
|
|
9
|
+
.nox/*
|
|
10
|
+
setup.py
|
|
11
|
+
|
|
12
|
+
[report]
|
|
13
|
+
# Regexes for lines to exclude from consideration
|
|
14
|
+
exclude_also =
|
|
15
|
+
# Don't complain about missing debug-only code:
|
|
16
|
+
def __repr__
|
|
17
|
+
|
|
18
|
+
# Don't complain if tests don't hit defensive assertion code:
|
|
19
|
+
raise AssertionError
|
|
20
|
+
raise NotImplementedError
|
|
21
|
+
|
|
22
|
+
# Don't complain if non-runnable code isn't run:
|
|
23
|
+
if 0:
|
|
24
|
+
if False:
|
|
25
|
+
if __name__ == .__main__.:
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
@(abc\.)?abstractmethod
|
|
28
|
+
|
|
29
|
+
# Add markers which exclude statements in between.
|
|
30
|
+
# Requires coverage>=7.6.0.
|
|
31
|
+
no cover: start(?s:.)*?no cover: stop
|
|
32
|
+
|
|
33
|
+
omit =
|
|
34
|
+
.nox/*
|
|
35
|
+
setup.py
|
|
36
|
+
|
|
37
|
+
ignore_errors = True
|
|
38
|
+
|
|
39
|
+
[paths]
|
|
40
|
+
source =
|
|
41
|
+
saltext/gandi
|
|
42
|
+
src/saltext/gandi
|
|
43
|
+
testsuite =
|
|
44
|
+
tests/
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
pip-wheel-metadata/
|
|
24
|
+
share/python-wheels/
|
|
25
|
+
*.egg-info/
|
|
26
|
+
.installed.cfg
|
|
27
|
+
*.egg
|
|
28
|
+
MANIFEST
|
|
29
|
+
|
|
30
|
+
# PyInstaller
|
|
31
|
+
# Usually these files are written by a python script from a template
|
|
32
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
33
|
+
*.manifest
|
|
34
|
+
*.spec
|
|
35
|
+
|
|
36
|
+
# Installer logs
|
|
37
|
+
pip-log.txt
|
|
38
|
+
pip-delete-this-directory.txt
|
|
39
|
+
|
|
40
|
+
# Unit test / coverage reports
|
|
41
|
+
htmlcov/
|
|
42
|
+
.tox/
|
|
43
|
+
.nox/
|
|
44
|
+
.coverage
|
|
45
|
+
.coverage.*
|
|
46
|
+
.cache
|
|
47
|
+
nosetests.xml
|
|
48
|
+
coverage.xml
|
|
49
|
+
*.cover
|
|
50
|
+
*.py,cover
|
|
51
|
+
.hypothesis/
|
|
52
|
+
.pytest_cache/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
target/
|
|
76
|
+
|
|
77
|
+
# Jupyter Notebook
|
|
78
|
+
.ipynb_checkpoints
|
|
79
|
+
|
|
80
|
+
# IPython
|
|
81
|
+
profile_default/
|
|
82
|
+
ipython_config.py
|
|
83
|
+
|
|
84
|
+
# pyenv
|
|
85
|
+
.python-version
|
|
86
|
+
|
|
87
|
+
# pipenv
|
|
88
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
89
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
90
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
91
|
+
# install all needed dependencies.
|
|
92
|
+
#Pipfile.lock
|
|
93
|
+
|
|
94
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
95
|
+
__pypackages__/
|
|
96
|
+
|
|
97
|
+
# Celery stuff
|
|
98
|
+
celerybeat-schedule
|
|
99
|
+
celerybeat.pid
|
|
100
|
+
|
|
101
|
+
# SageMath parsed files
|
|
102
|
+
*.sage.py
|
|
103
|
+
|
|
104
|
+
# Environments
|
|
105
|
+
!.envrc.example
|
|
106
|
+
.env
|
|
107
|
+
.venv
|
|
108
|
+
env/
|
|
109
|
+
venv/
|
|
110
|
+
ENV/
|
|
111
|
+
env.bak/
|
|
112
|
+
venv.bak/
|
|
113
|
+
|
|
114
|
+
# Spyder project settings
|
|
115
|
+
.spyderproject
|
|
116
|
+
.spyproject
|
|
117
|
+
|
|
118
|
+
# Rope project settings
|
|
119
|
+
.ropeproject
|
|
120
|
+
|
|
121
|
+
# mkdocs documentation
|
|
122
|
+
/site
|
|
123
|
+
|
|
124
|
+
# mypy
|
|
125
|
+
.mypy_cache/
|
|
126
|
+
.dmypy.json
|
|
127
|
+
dmypy.json
|
|
128
|
+
|
|
129
|
+
# Pyre type checker
|
|
130
|
+
.pyre/
|
|
131
|
+
|
|
132
|
+
# Ignore the setuptools_scm auto-generated version module
|
|
133
|
+
src/saltext/gandi/version.py
|
|
134
|
+
|
|
135
|
+
# Ignore CI generated artifacts
|
|
136
|
+
artifacts/
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
## Description
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## Setup
|
|
5
|
+
(Salt version, extension version, master vs minion, which Gandi API, production
|
|
6
|
+
or sandbox)
|
|
7
|
+
|
|
8
|
+
## Steps to reproduce
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## Expected vs actual
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## Trace-ID
|
|
15
|
+
(If the failure came back from the Gandi API, the error message includes a
|
|
16
|
+
`Trace-ID`. Paste it here -- Gandi support can look the request up by it.)
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
# GitLab CI for saltext-gandi.
|
|
2
|
+
#
|
|
3
|
+
# The salt-extension-copier template ships CI as GitHub Actions, which do not
|
|
4
|
+
# run on GitLab. This pipeline reproduces that matrix natively on GitLab:
|
|
5
|
+
# pre-commit lint, a nox test matrix across Salt/Python, a docs build, and
|
|
6
|
+
# GitLab Pages. Salt version is selected through the noxfile's SALT_REQUIREMENT
|
|
7
|
+
# environment variable (see noxfile.py).
|
|
8
|
+
#
|
|
9
|
+
# The matrix covers the two Salt majors upstream currently marks as supported
|
|
10
|
+
# LTS releases (3006 and 3008). 3007 is deliberately omitted: the copier
|
|
11
|
+
# template's own support data marks it `supported: false`. Python bounds per
|
|
12
|
+
# Salt major come from that same data -- 3006 tops out at 3.11, 3008 goes
|
|
13
|
+
# further, so the matrix is not a full cross product.
|
|
14
|
+
|
|
15
|
+
stages:
|
|
16
|
+
- lint
|
|
17
|
+
- test
|
|
18
|
+
- docs
|
|
19
|
+
- publish
|
|
20
|
+
|
|
21
|
+
variables:
|
|
22
|
+
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
|
|
23
|
+
|
|
24
|
+
# No `cache:` here on purpose. The self-hosted runner has no [runners.cache]
|
|
25
|
+
# backend configured, so declaring one only produces
|
|
26
|
+
# "ERROR: Could not create cache adapter" on every job. Artifacts are unaffected;
|
|
27
|
+
# they go through GitLab.
|
|
28
|
+
|
|
29
|
+
.py-base:
|
|
30
|
+
before_script:
|
|
31
|
+
- python -m pip install --upgrade pip nox
|
|
32
|
+
|
|
33
|
+
pre-commit:
|
|
34
|
+
stage: lint
|
|
35
|
+
image: python:3.10
|
|
36
|
+
before_script:
|
|
37
|
+
- python -m pip install --upgrade pip pre-commit
|
|
38
|
+
script:
|
|
39
|
+
- pre-commit run --all-files --show-diff-on-failure --color always
|
|
40
|
+
|
|
41
|
+
.tests:
|
|
42
|
+
stage: test
|
|
43
|
+
extends: .py-base
|
|
44
|
+
# Unit and functional only. The integration tests talk to Gandi's sandbox and
|
|
45
|
+
# need credentials, so they get their own job that runs on a schedule.
|
|
46
|
+
script:
|
|
47
|
+
- nox --force-color -e tests-3 -- tests/unit tests/functional -vv --showlocals
|
|
48
|
+
coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
|
|
49
|
+
artifacts:
|
|
50
|
+
when: always
|
|
51
|
+
reports:
|
|
52
|
+
junit: artifacts/junit-report.xml
|
|
53
|
+
paths:
|
|
54
|
+
- artifacts/
|
|
55
|
+
expire_in: 2 weeks
|
|
56
|
+
|
|
57
|
+
tests-salt3006-py3.10:
|
|
58
|
+
extends: .tests
|
|
59
|
+
image: python:3.10
|
|
60
|
+
variables:
|
|
61
|
+
SALT_REQUIREMENT: "salt>=3006,<3007"
|
|
62
|
+
tests-salt3006-py3.11:
|
|
63
|
+
extends: .tests
|
|
64
|
+
image: python:3.11
|
|
65
|
+
variables:
|
|
66
|
+
SALT_REQUIREMENT: "salt>=3006,<3007"
|
|
67
|
+
tests-salt3008-py3.10:
|
|
68
|
+
extends: .tests
|
|
69
|
+
image: python:3.10
|
|
70
|
+
variables:
|
|
71
|
+
SALT_REQUIREMENT: "salt>=3008"
|
|
72
|
+
tests-salt3008-py3.12:
|
|
73
|
+
extends: .tests
|
|
74
|
+
image: python:3.12
|
|
75
|
+
variables:
|
|
76
|
+
SALT_REQUIREMENT: "salt>=3008"
|
|
77
|
+
|
|
78
|
+
# Check the endpoint table in src/saltext/gandi/utils/resources.py against
|
|
79
|
+
# Gandi's live documentation.
|
|
80
|
+
#
|
|
81
|
+
# Gandi publishes no OpenAPI or RAML document, so there is nothing to diff
|
|
82
|
+
# schemas against. What the docs do carry is a complete, machine-readable
|
|
83
|
+
# endpoint index: every operation gets an HTML anchor id of the form
|
|
84
|
+
# `#get-v5-livedns-domains-fqdn-records`. tools/verify_endpoints.py scrapes
|
|
85
|
+
# those and diffs them against the resource table, which catches endpoints
|
|
86
|
+
# added or withdrawn upstream.
|
|
87
|
+
#
|
|
88
|
+
# It cannot catch field-level drift -- that only surfaces at runtime, or in the
|
|
89
|
+
# sandbox integration job below.
|
|
90
|
+
#
|
|
91
|
+
# Scheduled rather than per-push: it depends on api.gandi.net being up, and a
|
|
92
|
+
# docs outage should not fail an unrelated merge request.
|
|
93
|
+
verify-endpoints:
|
|
94
|
+
stage: test
|
|
95
|
+
extends: .py-base
|
|
96
|
+
image: python:3.10
|
|
97
|
+
script:
|
|
98
|
+
- nox --force-color -e verify-endpoints
|
|
99
|
+
artifacts:
|
|
100
|
+
when: always
|
|
101
|
+
paths:
|
|
102
|
+
- endpoints-report.txt
|
|
103
|
+
expire_in: 2 weeks
|
|
104
|
+
rules:
|
|
105
|
+
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
|
106
|
+
- when: manual
|
|
107
|
+
allow_failure: true
|
|
108
|
+
|
|
109
|
+
# Integration tests against Gandi's sandbox (api.sandbox.gandi.net).
|
|
110
|
+
#
|
|
111
|
+
# Sandbox accounts are separate from production ones and are created at
|
|
112
|
+
# admin.sandbox.gandi.net; the token below is a sandbox personal access token,
|
|
113
|
+
# stored as a masked, protected CI variable. Nothing here can touch production:
|
|
114
|
+
# the profile hardcodes the sandbox base URL, and the job fails fast if
|
|
115
|
+
# GANDI_SANDBOX_TOKEN is unset rather than silently falling back.
|
|
116
|
+
#
|
|
117
|
+
# Scheduled only. These tests create and destroy real objects in the sandbox,
|
|
118
|
+
# and running them on every merge request would both slow the pipeline down and
|
|
119
|
+
# make the sandbox account's state depend on pipeline concurrency.
|
|
120
|
+
integration-sandbox:
|
|
121
|
+
stage: test
|
|
122
|
+
extends: .py-base
|
|
123
|
+
image: python:3.10
|
|
124
|
+
script:
|
|
125
|
+
- test -n "$GANDI_SANDBOX_TOKEN" || { echo "GANDI_SANDBOX_TOKEN is not set"; exit 1; }
|
|
126
|
+
- nox --force-color -e tests-3 -- tests/integration --run-destructive -vv
|
|
127
|
+
artifacts:
|
|
128
|
+
when: always
|
|
129
|
+
reports:
|
|
130
|
+
junit: artifacts/junit-report.xml
|
|
131
|
+
paths:
|
|
132
|
+
- artifacts/
|
|
133
|
+
expire_in: 2 weeks
|
|
134
|
+
rules:
|
|
135
|
+
- if: '$CI_PIPELINE_SOURCE == "schedule"'
|
|
136
|
+
- when: manual
|
|
137
|
+
allow_failure: true
|
|
138
|
+
|
|
139
|
+
.docs-base:
|
|
140
|
+
image: python:3.10
|
|
141
|
+
# sphinxcontrib-spelling wraps the enchant C library, which is not in the
|
|
142
|
+
# python images. Without it Sphinx aborts loading the extension.
|
|
143
|
+
before_script:
|
|
144
|
+
- apt-get update -qq
|
|
145
|
+
- apt-get install -y -qq libenchant-2-2 hunspell-en-us
|
|
146
|
+
- python -m pip install --upgrade pip nox
|
|
147
|
+
|
|
148
|
+
docs:
|
|
149
|
+
stage: docs
|
|
150
|
+
extends: .docs-base
|
|
151
|
+
script:
|
|
152
|
+
- nox --force-color -e docs
|
|
153
|
+
artifacts:
|
|
154
|
+
paths:
|
|
155
|
+
- docs/_build/html
|
|
156
|
+
expire_in: 2 weeks
|
|
157
|
+
|
|
158
|
+
pages:
|
|
159
|
+
stage: docs
|
|
160
|
+
extends: .docs-base
|
|
161
|
+
script:
|
|
162
|
+
- nox --force-color -e docs
|
|
163
|
+
- mv docs/_build/html public
|
|
164
|
+
artifacts:
|
|
165
|
+
paths:
|
|
166
|
+
- public
|
|
167
|
+
rules:
|
|
168
|
+
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
|
169
|
+
|
|
170
|
+
# Publish to PyPI via Trusted Publishing (OIDC, no stored token).
|
|
171
|
+
#
|
|
172
|
+
# This is deliberately a MANUAL, tag-only job: nothing is published without an
|
|
173
|
+
# operator clicking "run", so tagging a release does not auto-fire an upload.
|
|
174
|
+
# It relies on a PyPI trusted publisher configured for this project with:
|
|
175
|
+
# namespace ggiesen / repo saltext-gandi / pipeline .gitlab-ci.yml /
|
|
176
|
+
# environment "release"
|
|
177
|
+
# The ``environment: release`` below MUST match that PyPI configuration, and the
|
|
178
|
+
# ``aud: pypi`` id_token is what twine exchanges for a short-lived PyPI token.
|
|
179
|
+
publish:
|
|
180
|
+
stage: publish
|
|
181
|
+
image: python:3.12
|
|
182
|
+
variables:
|
|
183
|
+
# setuptools_scm needs the full history and the tag object to derive a clean
|
|
184
|
+
# release version; the default shallow clone can yield a "+local" version.
|
|
185
|
+
GIT_DEPTH: "0"
|
|
186
|
+
id_tokens:
|
|
187
|
+
PYPI_ID_TOKEN:
|
|
188
|
+
aud: pypi
|
|
189
|
+
environment: release
|
|
190
|
+
before_script:
|
|
191
|
+
- python -m pip install --upgrade build twine
|
|
192
|
+
script:
|
|
193
|
+
- python -m build
|
|
194
|
+
- twine check dist/*
|
|
195
|
+
# No credentials passed: twine uses the PYPI_ID_TOKEN trusted-publishing flow.
|
|
196
|
+
- twine upload dist/*
|
|
197
|
+
rules:
|
|
198
|
+
- if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+/'
|
|
199
|
+
when: manual
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
minimum_pre_commit_version: 2.4.0
|
|
3
|
+
repos:
|
|
4
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
5
|
+
rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # v6.0.0
|
|
6
|
+
hooks:
|
|
7
|
+
- id: check-merge-conflict # Check for files that contain merge conflict strings.
|
|
8
|
+
args: [--assume-in-merge]
|
|
9
|
+
- id: trailing-whitespace # Trim trailing whitespace.
|
|
10
|
+
args: [--markdown-linebreak-ext=md]
|
|
11
|
+
- id: mixed-line-ending # Ensure files use UNIX-style newlines only.
|
|
12
|
+
args: [--fix=lf]
|
|
13
|
+
- id: end-of-file-fixer # Ensure files end with a newline.
|
|
14
|
+
- id: check-ast # Check whether files parse as valid Python.
|
|
15
|
+
|
|
16
|
+
# ----- Formatting ---------------------------------------------------------------------------->
|
|
17
|
+
- repo: https://github.com/saltstack/pre-commit-remove-import-headers
|
|
18
|
+
rev: e79f595c0df31b8cb152c53993ce7c3c64f07cd4 # 1.1.0
|
|
19
|
+
hooks:
|
|
20
|
+
- id: remove-import-headers
|
|
21
|
+
|
|
22
|
+
- repo: local
|
|
23
|
+
hooks:
|
|
24
|
+
- id: check-cli-examples
|
|
25
|
+
name: Check CLI examples on execution modules
|
|
26
|
+
entry: python .pre-commit-hooks/check-cli-examples.py
|
|
27
|
+
language: python
|
|
28
|
+
files: ^src/saltext/gandi/modules/.*\.py$
|
|
29
|
+
|
|
30
|
+
- repo: local
|
|
31
|
+
hooks:
|
|
32
|
+
- id: check-gitlab-ci
|
|
33
|
+
name: Check .gitlab-ci.yml references resolve
|
|
34
|
+
entry: python .pre-commit-hooks/check-gitlab-ci.py
|
|
35
|
+
language: python
|
|
36
|
+
# `language: system` would rely on a `python` on PATH, which is not
|
|
37
|
+
# guaranteed -- pre-commit invoked from the venv does not put one there.
|
|
38
|
+
additional_dependencies:
|
|
39
|
+
- PyYAML
|
|
40
|
+
files: ^\.gitlab-ci\.yml$
|
|
41
|
+
pass_filenames: false
|
|
42
|
+
|
|
43
|
+
- id: check-docs
|
|
44
|
+
name: Check rST doc files exist for modules/states
|
|
45
|
+
entry: python .pre-commit-hooks/make-autodocs.py
|
|
46
|
+
language: python
|
|
47
|
+
pass_filenames: false
|
|
48
|
+
|
|
49
|
+
- repo: https://github.com/saltstack/salt-rewrite
|
|
50
|
+
# Automatically rewrite code with known rules
|
|
51
|
+
rev: 2401c0faef69b6b846c719d611bcfe358234d5d1 # 2.5.2
|
|
52
|
+
hooks:
|
|
53
|
+
- id: salt-rewrite
|
|
54
|
+
alias: rewrite-docstrings
|
|
55
|
+
name: Salt extensions docstrings auto-fixes
|
|
56
|
+
files: ^src/saltext/gandi/.*\.py$
|
|
57
|
+
args: [--silent]
|
|
58
|
+
|
|
59
|
+
- repo: https://github.com/saltstack/salt-rewrite
|
|
60
|
+
# Automatically rewrite code with known rules
|
|
61
|
+
rev: 2401c0faef69b6b846c719d611bcfe358234d5d1 # 2.5.2
|
|
62
|
+
hooks:
|
|
63
|
+
- id: salt-rewrite
|
|
64
|
+
alias: rewrite-tests
|
|
65
|
+
name: Rewrite the test suite
|
|
66
|
+
files: ^tests/.*\.py$
|
|
67
|
+
args: [--silent, -E, fix_docstrings]
|
|
68
|
+
|
|
69
|
+
- repo: https://github.com/asottile/pyupgrade
|
|
70
|
+
rev: 75992aaa40730136014f34227e0135f63fc951b4 # v3.21.2
|
|
71
|
+
hooks:
|
|
72
|
+
- id: pyupgrade
|
|
73
|
+
name: Rewrite Code to be Py3.10+
|
|
74
|
+
args: [
|
|
75
|
+
--py310-plus,
|
|
76
|
+
]
|
|
77
|
+
exclude: src/saltext/gandi/version.py
|
|
78
|
+
|
|
79
|
+
- repo: https://github.com/PyCQA/isort
|
|
80
|
+
rev: a333737ed43df02b18e6c95477ea1b285b3de15a # 8.0.1
|
|
81
|
+
hooks:
|
|
82
|
+
- id: isort
|
|
83
|
+
args: [
|
|
84
|
+
--py 310,
|
|
85
|
+
]
|
|
86
|
+
exclude: src/saltext/gandi/(__init__|version).py
|
|
87
|
+
|
|
88
|
+
- repo: https://github.com/psf/black
|
|
89
|
+
rev: 87928e6d6761a4a6d22250e1fee5601b3998086e # 26.5.1
|
|
90
|
+
hooks:
|
|
91
|
+
- id: black
|
|
92
|
+
args: [-l 100]
|
|
93
|
+
exclude: src/saltext/gandi/version.py
|
|
94
|
+
|
|
95
|
+
- repo: https://github.com/adamchainz/blacken-docs
|
|
96
|
+
rev: fda77690955e9b63c6687d8806bafd56a526e45f # 1.20.0
|
|
97
|
+
hooks:
|
|
98
|
+
- id: blacken-docs
|
|
99
|
+
args: [--skip-errors]
|
|
100
|
+
files: ^(docs/.*\.rst|src/saltext/gandi/.*\.py)$
|
|
101
|
+
additional_dependencies:
|
|
102
|
+
- black==26.5.1
|
|
103
|
+
# <---- Formatting -----------------------------------------------------------------------------
|
|
104
|
+
|
|
105
|
+
# ----- Security ------------------------------------------------------------------------------>
|
|
106
|
+
- repo: https://github.com/PyCQA/bandit
|
|
107
|
+
rev: 92ae8b82fb422a639f0ed8d99e96cea769594e08 # 1.9.4
|
|
108
|
+
hooks:
|
|
109
|
+
- id: bandit
|
|
110
|
+
alias: bandit-salt
|
|
111
|
+
name: Run bandit against the code base
|
|
112
|
+
args: [--silent, -lll, --skip, B701]
|
|
113
|
+
exclude: src/saltext/gandi/version.py
|
|
114
|
+
|
|
115
|
+
- repo: https://github.com/PyCQA/bandit
|
|
116
|
+
rev: 92ae8b82fb422a639f0ed8d99e96cea769594e08 # 1.9.4
|
|
117
|
+
hooks:
|
|
118
|
+
- id: bandit
|
|
119
|
+
alias: bandit-tests
|
|
120
|
+
name: Run bandit against the test suite
|
|
121
|
+
args: [--silent, -lll, --skip, B701]
|
|
122
|
+
files: ^tests/.*
|
|
123
|
+
# <---- Security -------------------------------------------------------------------------------
|
|
124
|
+
|
|
125
|
+
# ----- Code Analysis ------------------------------------------------------------------------->
|
|
126
|
+
|
|
127
|
+
- repo: local
|
|
128
|
+
hooks:
|
|
129
|
+
- id: nox
|
|
130
|
+
alias: lint-src
|
|
131
|
+
name: Lint Source Code
|
|
132
|
+
language: python
|
|
133
|
+
entry: nox -e lint-code-pre-commit --
|
|
134
|
+
files: ^((setup|noxfile)|src/.*)\.py$
|
|
135
|
+
require_serial: true
|
|
136
|
+
additional_dependencies:
|
|
137
|
+
- nox==2026.4.10
|
|
138
|
+
- uv==0.11.26 # Makes this hook much faster
|
|
139
|
+
|
|
140
|
+
- id: nox
|
|
141
|
+
alias: lint-tests
|
|
142
|
+
name: Lint Tests
|
|
143
|
+
language: python
|
|
144
|
+
entry: nox -e lint-tests-pre-commit --
|
|
145
|
+
files: ^tests/.*\.py$
|
|
146
|
+
require_serial: true
|
|
147
|
+
additional_dependencies:
|
|
148
|
+
- nox==2026.4.10
|
|
149
|
+
- uv==0.11.26 # Makes this hook much faster
|
|
150
|
+
# <---- Code Analysis --------------------------------------------------------------------------
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import ast
|
|
2
|
+
import pathlib
|
|
3
|
+
import re
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
CODE_ROOT = pathlib.Path(__file__).resolve().parent.parent
|
|
7
|
+
EXECUTION_MODULES_PATH = CODE_ROOT / "src" / "saltext" / "gandi" / "modules"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def check_cli_examples(files):
|
|
11
|
+
"""
|
|
12
|
+
Check that every function on every execution module provides a CLI example
|
|
13
|
+
"""
|
|
14
|
+
errors = 0
|
|
15
|
+
for file in files:
|
|
16
|
+
path = pathlib.Path(file).resolve()
|
|
17
|
+
try:
|
|
18
|
+
relpath = path.relative_to(EXECUTION_MODULES_PATH)
|
|
19
|
+
if str(relpath.parent) != ".":
|
|
20
|
+
# We don't want to check nested packages
|
|
21
|
+
continue
|
|
22
|
+
except ValueError:
|
|
23
|
+
# We're only interested in execution modules
|
|
24
|
+
continue
|
|
25
|
+
module = ast.parse(path.read_text(), filename=str(path))
|
|
26
|
+
for funcdef in [node for node in module.body if isinstance(node, ast.FunctionDef)]:
|
|
27
|
+
if funcdef.name.startswith("_"):
|
|
28
|
+
# We're not interested in internal functions
|
|
29
|
+
continue
|
|
30
|
+
|
|
31
|
+
docstring = ast.get_docstring(funcdef, clean=False)
|
|
32
|
+
if not docstring:
|
|
33
|
+
errors += 1
|
|
34
|
+
print(
|
|
35
|
+
"The function {!r} on '{}' does not have a docstring".format(
|
|
36
|
+
funcdef.name,
|
|
37
|
+
path.relative_to(CODE_ROOT),
|
|
38
|
+
),
|
|
39
|
+
file=sys.stderr,
|
|
40
|
+
)
|
|
41
|
+
continue
|
|
42
|
+
|
|
43
|
+
if _check_cli_example_present(docstring) is False:
|
|
44
|
+
errors += 1
|
|
45
|
+
print(
|
|
46
|
+
"The function {!r} on '{}' does not have a 'CLI Example:' in it's docstring".format(
|
|
47
|
+
funcdef.name,
|
|
48
|
+
path.relative_to(CODE_ROOT),
|
|
49
|
+
),
|
|
50
|
+
file=sys.stderr,
|
|
51
|
+
)
|
|
52
|
+
continue
|
|
53
|
+
sys.exit(errors)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
CLI_EXAMPLE_PRESENT_RE = re.compile(r"CLI Example(?:s)?:")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _check_cli_example_present(docstring):
|
|
60
|
+
return CLI_EXAMPLE_PRESENT_RE.search(docstring) is not None
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
if __name__ == "__main__":
|
|
64
|
+
check_cli_examples(sys.argv[1:])
|