Resolve "Automatic token generation"
This commit is contained in:
parent
a30d4b70ea
commit
57a85158b3
7 changed files with 338 additions and 27 deletions
0
__init__.py
Normal file
0
__init__.py
Normal file
105
poetry.lock
generated
105
poetry.lock
generated
|
|
@ -47,6 +47,17 @@ category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cffi"
|
||||||
|
version = "1.14.6"
|
||||||
|
description = "Foreign Function Interface for Python calling C code."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
pycparser = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "charset-normalizer"
|
name = "charset-normalizer"
|
||||||
version = "2.0.3"
|
version = "2.0.3"
|
||||||
|
|
@ -89,6 +100,25 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4"
|
||||||
[package.extras]
|
[package.extras]
|
||||||
toml = ["toml"]
|
toml = ["toml"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cryptography"
|
||||||
|
version = "3.4.7"
|
||||||
|
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
cffi = ">=1.12"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"]
|
||||||
|
docstest = ["doc8", "pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling (>=4.0.1)"]
|
||||||
|
pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"]
|
||||||
|
sdist = ["setuptools-rust (>=0.11.4)"]
|
||||||
|
ssh = ["bcrypt (>=3.1.5)"]
|
||||||
|
test = ["pytest (>=6.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "3.2"
|
version = "3.2"
|
||||||
|
|
@ -144,6 +174,14 @@ category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pycparser"
|
||||||
|
version = "2.20"
|
||||||
|
description = "C parser in Python"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyflakes"
|
name = "pyflakes"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
|
|
@ -272,7 +310,7 @@ sentry = ["sentry_sdk"]
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.7"
|
python-versions = "^3.7"
|
||||||
content-hash = "c9ce94c5862b60762859b36d4d9630ffb0d66e8d6f836b447ad088bfcc743629"
|
content-hash = "c7e3ea0e9e6da7d9e725dd2b72bab6a4c6ffae8fe3b28e1de23f3877572e4a22"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
appdirs = [
|
appdirs = [
|
||||||
|
|
@ -289,6 +327,53 @@ certifi = [
|
||||||
{file = "certifi-2021.5.30-py2.py3-none-any.whl", hash = "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"},
|
{file = "certifi-2021.5.30-py2.py3-none-any.whl", hash = "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"},
|
||||||
{file = "certifi-2021.5.30.tar.gz", hash = "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"},
|
{file = "certifi-2021.5.30.tar.gz", hash = "sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee"},
|
||||||
]
|
]
|
||||||
|
cffi = [
|
||||||
|
{file = "cffi-1.14.6-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:22b9c3c320171c108e903d61a3723b51e37aaa8c81255b5e7ce102775bd01e2c"},
|
||||||
|
{file = "cffi-1.14.6-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:f0c5d1acbfca6ebdd6b1e3eded8d261affb6ddcf2186205518f1428b8569bb99"},
|
||||||
|
{file = "cffi-1.14.6-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:99f27fefe34c37ba9875f224a8f36e31d744d8083e00f520f133cab79ad5e819"},
|
||||||
|
{file = "cffi-1.14.6-cp27-cp27m-win32.whl", hash = "sha256:55af55e32ae468e9946f741a5d51f9896da6b9bf0bbdd326843fec05c730eb20"},
|
||||||
|
{file = "cffi-1.14.6-cp27-cp27m-win_amd64.whl", hash = "sha256:7bcac9a2b4fdbed2c16fa5681356d7121ecabf041f18d97ed5b8e0dd38a80224"},
|
||||||
|
{file = "cffi-1.14.6-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ed38b924ce794e505647f7c331b22a693bee1538fdf46b0222c4717b42f744e7"},
|
||||||
|
{file = "cffi-1.14.6-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e22dcb48709fc51a7b58a927391b23ab37eb3737a98ac4338e2448bef8559b33"},
|
||||||
|
{file = "cffi-1.14.6-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:aedb15f0a5a5949ecb129a82b72b19df97bbbca024081ed2ef88bd5c0a610534"},
|
||||||
|
{file = "cffi-1.14.6-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:48916e459c54c4a70e52745639f1db524542140433599e13911b2f329834276a"},
|
||||||
|
{file = "cffi-1.14.6-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f627688813d0a4140153ff532537fbe4afea5a3dffce1f9deb7f91f848a832b5"},
|
||||||
|
{file = "cffi-1.14.6-cp35-cp35m-win32.whl", hash = "sha256:f0010c6f9d1a4011e429109fda55a225921e3206e7f62a0c22a35344bfd13cca"},
|
||||||
|
{file = "cffi-1.14.6-cp35-cp35m-win_amd64.whl", hash = "sha256:57e555a9feb4a8460415f1aac331a2dc833b1115284f7ded7278b54afc5bd218"},
|
||||||
|
{file = "cffi-1.14.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e8c6a99be100371dbb046880e7a282152aa5d6127ae01783e37662ef73850d8f"},
|
||||||
|
{file = "cffi-1.14.6-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:19ca0dbdeda3b2615421d54bef8985f72af6e0c47082a8d26122adac81a95872"},
|
||||||
|
{file = "cffi-1.14.6-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d950695ae4381ecd856bcaf2b1e866720e4ab9a1498cba61c602e56630ca7195"},
|
||||||
|
{file = "cffi-1.14.6-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9dc245e3ac69c92ee4c167fbdd7428ec1956d4e754223124991ef29eb57a09d"},
|
||||||
|
{file = "cffi-1.14.6-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8661b2ce9694ca01c529bfa204dbb144b275a31685a075ce123f12331be790b"},
|
||||||
|
{file = "cffi-1.14.6-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b315d709717a99f4b27b59b021e6207c64620790ca3e0bde636a6c7f14618abb"},
|
||||||
|
{file = "cffi-1.14.6-cp36-cp36m-win32.whl", hash = "sha256:80b06212075346b5546b0417b9f2bf467fea3bfe7352f781ffc05a8ab24ba14a"},
|
||||||
|
{file = "cffi-1.14.6-cp36-cp36m-win_amd64.whl", hash = "sha256:a9da7010cec5a12193d1af9872a00888f396aba3dc79186604a09ea3ee7c029e"},
|
||||||
|
{file = "cffi-1.14.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4373612d59c404baeb7cbd788a18b2b2a8331abcc84c3ba40051fcd18b17a4d5"},
|
||||||
|
{file = "cffi-1.14.6-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f10afb1004f102c7868ebfe91c28f4a712227fe4cb24974350ace1f90e1febbf"},
|
||||||
|
{file = "cffi-1.14.6-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:fd4305f86f53dfd8cd3522269ed7fc34856a8ee3709a5e28b2836b2db9d4cd69"},
|
||||||
|
{file = "cffi-1.14.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d6169cb3c6c2ad50db5b868db6491a790300ade1ed5d1da29289d73bbe40b56"},
|
||||||
|
{file = "cffi-1.14.6-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d4b68e216fc65e9fe4f524c177b54964af043dde734807586cf5435af84045c"},
|
||||||
|
{file = "cffi-1.14.6-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33791e8a2dc2953f28b8d8d300dde42dd929ac28f974c4b4c6272cb2955cb762"},
|
||||||
|
{file = "cffi-1.14.6-cp37-cp37m-win32.whl", hash = "sha256:0c0591bee64e438883b0c92a7bed78f6290d40bf02e54c5bf0978eaf36061771"},
|
||||||
|
{file = "cffi-1.14.6-cp37-cp37m-win_amd64.whl", hash = "sha256:8eb687582ed7cd8c4bdbff3df6c0da443eb89c3c72e6e5dcdd9c81729712791a"},
|
||||||
|
{file = "cffi-1.14.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ba6f2b3f452e150945d58f4badd92310449876c4c954836cfb1803bdd7b422f0"},
|
||||||
|
{file = "cffi-1.14.6-cp38-cp38-manylinux1_i686.whl", hash = "sha256:64fda793737bc4037521d4899be780534b9aea552eb673b9833b01f945904c2e"},
|
||||||
|
{file = "cffi-1.14.6-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:9f3e33c28cd39d1b655ed1ba7247133b6f7fc16fa16887b120c0c670e35ce346"},
|
||||||
|
{file = "cffi-1.14.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26bb2549b72708c833f5abe62b756176022a7b9a7f689b571e74c8478ead51dc"},
|
||||||
|
{file = "cffi-1.14.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb687a11f0a7a1839719edd80f41e459cc5366857ecbed383ff376c4e3cc6afd"},
|
||||||
|
{file = "cffi-1.14.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d2ad4d668a5c0645d281dcd17aff2be3212bc109b33814bbb15c4939f44181cc"},
|
||||||
|
{file = "cffi-1.14.6-cp38-cp38-win32.whl", hash = "sha256:487d63e1454627c8e47dd230025780e91869cfba4c753a74fda196a1f6ad6548"},
|
||||||
|
{file = "cffi-1.14.6-cp38-cp38-win_amd64.whl", hash = "sha256:c33d18eb6e6bc36f09d793c0dc58b0211fccc6ae5149b808da4a62660678b156"},
|
||||||
|
{file = "cffi-1.14.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:06c54a68935738d206570b20da5ef2b6b6d92b38ef3ec45c5422c0ebaf338d4d"},
|
||||||
|
{file = "cffi-1.14.6-cp39-cp39-manylinux1_i686.whl", hash = "sha256:f174135f5609428cc6e1b9090f9268f5c8935fddb1b25ccb8255a2d50de6789e"},
|
||||||
|
{file = "cffi-1.14.6-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f3ebe6e73c319340830a9b2825d32eb6d8475c1dac020b4f0aa774ee3b898d1c"},
|
||||||
|
{file = "cffi-1.14.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c8d896becff2fa653dc4438b54a5a25a971d1f4110b32bd3068db3722c80202"},
|
||||||
|
{file = "cffi-1.14.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4922cd707b25e623b902c86188aca466d3620892db76c0bdd7b99a3d5e61d35f"},
|
||||||
|
{file = "cffi-1.14.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c9e005e9bd57bc987764c32a1bee4364c44fdc11a3cc20a40b93b444984f2b87"},
|
||||||
|
{file = "cffi-1.14.6-cp39-cp39-win32.whl", hash = "sha256:eb9e2a346c5238a30a746893f23a9535e700f8192a68c07c0258e7ece6ff3728"},
|
||||||
|
{file = "cffi-1.14.6-cp39-cp39-win_amd64.whl", hash = "sha256:818014c754cd3dba7229c0f5884396264d51ffb87ec86e927ef0be140bfdb0d2"},
|
||||||
|
{file = "cffi-1.14.6.tar.gz", hash = "sha256:c9a875ce9d7fe32887784274dd533c57909b7b1dcadcc128a2ac21331a9765dd"},
|
||||||
|
]
|
||||||
charset-normalizer = [
|
charset-normalizer = [
|
||||||
{file = "charset-normalizer-2.0.3.tar.gz", hash = "sha256:c46c3ace2d744cfbdebceaa3c19ae691f53ae621b39fd7570f59d14fb7f2fd12"},
|
{file = "charset-normalizer-2.0.3.tar.gz", hash = "sha256:c46c3ace2d744cfbdebceaa3c19ae691f53ae621b39fd7570f59d14fb7f2fd12"},
|
||||||
{file = "charset_normalizer-2.0.3-py3-none-any.whl", hash = "sha256:88fce3fa5b1a84fdcb3f603d889f723d1dd89b26059d0123ca435570e848d5e1"},
|
{file = "charset_normalizer-2.0.3-py3-none-any.whl", hash = "sha256:88fce3fa5b1a84fdcb3f603d889f723d1dd89b26059d0123ca435570e848d5e1"},
|
||||||
|
|
@ -355,6 +440,20 @@ coverage = [
|
||||||
{file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"},
|
{file = "coverage-5.5-pp37-none-any.whl", hash = "sha256:2a3859cb82dcbda1cfd3e6f71c27081d18aa251d20a17d87d26d4cd216fb0af4"},
|
||||||
{file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"},
|
{file = "coverage-5.5.tar.gz", hash = "sha256:ebe78fe9a0e874362175b02371bdfbee64d8edc42a044253ddf4ee7d3c15212c"},
|
||||||
]
|
]
|
||||||
|
cryptography = [
|
||||||
|
{file = "cryptography-3.4.7-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:3d8427734c781ea5f1b41d6589c293089704d4759e34597dce91014ac125aad1"},
|
||||||
|
{file = "cryptography-3.4.7-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:8e56e16617872b0957d1c9742a3f94b43533447fd78321514abbe7db216aa250"},
|
||||||
|
{file = "cryptography-3.4.7-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:37340614f8a5d2fb9aeea67fd159bfe4f5f4ed535b1090ce8ec428b2f15a11f2"},
|
||||||
|
{file = "cryptography-3.4.7-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:240f5c21aef0b73f40bb9f78d2caff73186700bf1bc6b94285699aff98cc16c6"},
|
||||||
|
{file = "cryptography-3.4.7-cp36-abi3-manylinux2014_x86_64.whl", hash = "sha256:1e056c28420c072c5e3cb36e2b23ee55e260cb04eee08f702e0edfec3fb51959"},
|
||||||
|
{file = "cryptography-3.4.7-cp36-abi3-win32.whl", hash = "sha256:0f1212a66329c80d68aeeb39b8a16d54ef57071bf22ff4e521657b27372e327d"},
|
||||||
|
{file = "cryptography-3.4.7-cp36-abi3-win_amd64.whl", hash = "sha256:de4e5f7f68220d92b7637fc99847475b59154b7a1b3868fb7385337af54ac9ca"},
|
||||||
|
{file = "cryptography-3.4.7-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:26965837447f9c82f1855e0bc8bc4fb910240b6e0d16a664bb722df3b5b06873"},
|
||||||
|
{file = "cryptography-3.4.7-pp36-pypy36_pp73-manylinux2014_x86_64.whl", hash = "sha256:eb8cc2afe8b05acbd84a43905832ec78e7b3873fb124ca190f574dca7389a87d"},
|
||||||
|
{file = "cryptography-3.4.7-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:7ec5d3b029f5fa2b179325908b9cd93db28ab7b85bb6c1db56b10e0b54235177"},
|
||||||
|
{file = "cryptography-3.4.7-pp37-pypy37_pp73-manylinux2014_x86_64.whl", hash = "sha256:ee77aa129f481be46f8d92a1a7db57269a2f23052d5f2433b4621bb457081cc9"},
|
||||||
|
{file = "cryptography-3.4.7.tar.gz", hash = "sha256:3d10de8116d25649631977cb37da6cbdd2d6fa0e0281d014a5b7d337255ca713"},
|
||||||
|
]
|
||||||
idna = [
|
idna = [
|
||||||
{file = "idna-3.2-py3-none-any.whl", hash = "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a"},
|
{file = "idna-3.2-py3-none-any.whl", hash = "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a"},
|
||||||
{file = "idna-3.2.tar.gz", hash = "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"},
|
{file = "idna-3.2.tar.gz", hash = "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"},
|
||||||
|
|
@ -375,6 +474,10 @@ pathspec = [
|
||||||
{file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"},
|
{file = "pathspec-0.8.1-py2.py3-none-any.whl", hash = "sha256:aa0cb481c4041bf52ffa7b0d8fa6cd3e88a2ca4879c533c9153882ee2556790d"},
|
||||||
{file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"},
|
{file = "pathspec-0.8.1.tar.gz", hash = "sha256:86379d6b86d75816baba717e64b1a3a3469deb93bb76d613c9ce79edc5cb68fd"},
|
||||||
]
|
]
|
||||||
|
pycparser = [
|
||||||
|
{file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"},
|
||||||
|
{file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},
|
||||||
|
]
|
||||||
pyflakes = [
|
pyflakes = [
|
||||||
{file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"},
|
{file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"},
|
||||||
{file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"},
|
{file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"},
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ click = "^8.0.1"
|
||||||
python-dotenv = "^0.15.0"
|
python-dotenv = "^0.15.0"
|
||||||
requests = "^2.25.1"
|
requests = "^2.25.1"
|
||||||
sentry_sdk = {version = "^0.19.5", optional = true}
|
sentry_sdk = {version = "^0.19.5", optional = true}
|
||||||
|
cryptography = "^3.4.7"
|
||||||
|
|
||||||
[tool.poetry.extras]
|
[tool.poetry.extras]
|
||||||
sentry = ["sentry_sdk"]
|
sentry = ["sentry_sdk"]
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import click
|
||||||
|
|
||||||
from transip_client.main import detect
|
from transip_client.main import detect
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_DNS = "myip.opendns.com"
|
DEFAULT_DNS = "myip.opendns.com"
|
||||||
DEFAULT_DNS_NAME = "@resolver1.opendns.com"
|
DEFAULT_DNS_NAME = "@resolver1.opendns.com"
|
||||||
DEFAULT_API_URL = "https://api.transip.nl/v6"
|
DEFAULT_API_URL = "https://api.transip.nl/v6"
|
||||||
|
|
@ -9,13 +10,39 @@ DEFAULT_API_URL = "https://api.transip.nl/v6"
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
@click.argument("domains", envvar="DOMAINS", nargs=-1)
|
@click.argument("domains", envvar="DOMAINS", nargs=-1)
|
||||||
@click.argument("token", envvar="TOKEN")
|
@click.option("--token", envvar="TOKEN")
|
||||||
|
@click.option("--login", envvar="LOGIN")
|
||||||
|
@click.option("--private-key-path", envvar="PRIVATE_KEY_PATH")
|
||||||
@click.option("--dns", envvar="DNS", default=DEFAULT_DNS)
|
@click.option("--dns", envvar="DNS", default=DEFAULT_DNS)
|
||||||
@click.option("--dns-name", envvar="DNS_NAME", default=DEFAULT_DNS_NAME)
|
@click.option("--dns-name", envvar="DNS_NAME", default=DEFAULT_DNS_NAME)
|
||||||
@click.option("--api-url", envvar="API_URL", default=DEFAULT_API_URL)
|
@click.option("--api-url", envvar="API_URL", default=DEFAULT_API_URL)
|
||||||
@click.option("--read-only/--write", envvar="READ_ONLY", default=False)
|
@click.option("--read-only/--write", envvar="READ_ONLY", default=False)
|
||||||
def run(domains, token, dns, dns_name, api_url, read_only):
|
def run(domains, token, login, private_key_path, dns, dns_name, api_url, read_only):
|
||||||
if not domains:
|
if not domains:
|
||||||
raise ValueError("No domain(s) specified")
|
raise ValueError("No domain(s) specified")
|
||||||
|
|
||||||
detect(domains, (dns, dns_name), api_url, token, read_only)
|
token_retrieval = any(
|
||||||
|
(
|
||||||
|
login,
|
||||||
|
private_key_path,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if token_retrieval and not all((login, private_key_path)):
|
||||||
|
raise ValueError(
|
||||||
|
"Both a login name and the path to a private key need to be specified"
|
||||||
|
)
|
||||||
|
elif not token_retrieval and not token:
|
||||||
|
raise ValueError(
|
||||||
|
"Either a token or a login name with a path to a private key need"
|
||||||
|
" to be specified"
|
||||||
|
)
|
||||||
|
|
||||||
|
detect(
|
||||||
|
domains,
|
||||||
|
(dns, dns_name),
|
||||||
|
(private_key_path, login),
|
||||||
|
token,
|
||||||
|
api_url,
|
||||||
|
read_only,
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,18 @@
|
||||||
|
import base64
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import time
|
||||||
|
|
||||||
from concurrent.futures import ThreadPoolExecutor, as_completed
|
from concurrent.futures import ThreadPoolExecutor, as_completed
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
from cryptography.hazmat.backends import default_backend
|
||||||
|
from cryptography.hazmat.primitives import serialization
|
||||||
|
from cryptography.hazmat.primitives.asymmetric.padding import PKCS1v15
|
||||||
|
from cryptography.hazmat.primitives.hashes import SHA512
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
@ -22,6 +29,43 @@ def _get_ip(resolvers):
|
||||||
return output.decode("utf-8").strip()
|
return output.decode("utf-8").strip()
|
||||||
|
|
||||||
|
|
||||||
|
def _get_token(private_key_path, login, api_url):
|
||||||
|
request = requests.Request(
|
||||||
|
"POST",
|
||||||
|
f"{api_url}/auth",
|
||||||
|
json={
|
||||||
|
"login": login,
|
||||||
|
"nonce": str(int(time.time() * 1000)),
|
||||||
|
"read_only": False,
|
||||||
|
"expiration_time": "30 minutes",
|
||||||
|
"label": "Custom token",
|
||||||
|
"global_key": True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
prepped_request = request.prepare()
|
||||||
|
|
||||||
|
with open(private_key_path, "rb") as file:
|
||||||
|
private_key = serialization.load_pem_private_key(
|
||||||
|
file.read(), password=None, backend=default_backend()
|
||||||
|
)
|
||||||
|
|
||||||
|
signature = private_key.sign(prepped_request.body, PKCS1v15(), SHA512())
|
||||||
|
signature = base64.b64encode(signature)
|
||||||
|
|
||||||
|
prepped_request.headers["Signature"] = signature.decode("ascii")
|
||||||
|
|
||||||
|
with requests.Session() as session:
|
||||||
|
response = session.send(prepped_request)
|
||||||
|
|
||||||
|
if not response.ok:
|
||||||
|
response.raise_for_status()
|
||||||
|
|
||||||
|
response_data = response.json()
|
||||||
|
|
||||||
|
return response_data["token"]
|
||||||
|
|
||||||
|
|
||||||
def _get_domain(domain, token, api_url):
|
def _get_domain(domain, token, api_url):
|
||||||
headers = {"Authorization": f"Bearer {token}"}
|
headers = {"Authorization": f"Bearer {token}"}
|
||||||
|
|
||||||
|
|
@ -79,11 +123,15 @@ def _update_domains(updated_domains, api_url, token, read_only):
|
||||||
logger.info(f"Updated domain {domain}")
|
logger.info(f"Updated domain {domain}")
|
||||||
|
|
||||||
|
|
||||||
def detect(domains, resolvers, api_url, token, read_only):
|
def detect(domains, resolvers, credentials, token, api_url, read_only):
|
||||||
ip = _get_ip(resolvers)
|
ip = _get_ip(resolvers)
|
||||||
domain_data = _get_domain_data(domains, token, api_url)
|
|
||||||
updated_domains = {}
|
updated_domains = {}
|
||||||
|
|
||||||
|
if all(credentials):
|
||||||
|
token = _get_token(*credentials, api_url)
|
||||||
|
|
||||||
|
domain_data = _get_domain_data(domains, token, api_url)
|
||||||
|
|
||||||
for data in domain_data:
|
for data in domain_data:
|
||||||
dns_entries = data["dnsEntries"]
|
dns_entries = data["dnsEntries"]
|
||||||
domain = data["domain"]
|
domain = data["domain"]
|
||||||
|
|
|
||||||
27
transip_client/tests/files/test-private-key.pem
Normal file
27
transip_client/tests/files/test-private-key.pem
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpgIBAAKCAQEAz7ojmkmZ2QA2L0QW/K2BLoxLs6eGWw/LBV5E+beTPz9rejla
|
||||||
|
Qj/Dq8T7qnBvM8TtLH3Bwwu6H15oqnVis0OhAZTuAFwQuUrzw9g83S+KHxBGATVb
|
||||||
|
eWQxwkf9ma8GIX+xFnby3XGvVXZjKZgUMZAeFK7c/eXxnRJ8QnN/aoXibiFP0bgS
|
||||||
|
jjGpsoS6FdjRkau7BbdOJg0fRcTIjkdd11r5pg1oRGAApwU6g+HtjQWYLiNoIxba
|
||||||
|
8Vv0SSdK9V/hgk/aqLXGmCCjvLqvEK0KxK9y035Sn6C4AnohdiSO5SRYZgipM9F0
|
||||||
|
RJzc20qCcTL6CpIS4SupA6121eno/bxAQY4q8wIDAQABAoIBAQC3KM9fqWoIFtGw
|
||||||
|
F3+VSH9RRc8yF5K2FFTU5Ow4q48gA5GG8a8OHx8vA79L51uF8CuYQUJp8psoMZxk
|
||||||
|
QKDIo+cBeAnrM0Jjvxz1IGN6PAKzpSu0wRFpFdlyDvwjWFo1i1vgDP3UF/ubhYmm
|
||||||
|
ETws/4AmiJC/JtNFxhjeluxQRsECjLDf52iqO/LbyxQUAElIkMC24ni2SHnLZfQ3
|
||||||
|
KIBS3MdVULGrAO6dF805vF/CbPajzgsDZzuzcOFjYetHm+qvUV8Tp34M00Mzf5Ar
|
||||||
|
7joBLCHgeFWfwPIY0l7LnRhs8Z79vAi/slMi/zrQnFi/5aiLE86y195LXeXh59If
|
||||||
|
BS7eq+YhAoGBAPmGmVR282oMhDFkzR6N2vkKbRCg8p6QMYK3L6/vYYVbf+S4ePH+
|
||||||
|
GJo41iG76YIx77UPR5wE6+KRStmc6SkvXPy8mJzNVRzMX7xIgtLbNfx37HSqIkKy
|
||||||
|
CN3rppQ8VTxsaEM8LwKvAQ/V1xxvtmhct08oEQCPqeQHHdrOEvFwl7HbAoGBANUd
|
||||||
|
56NRDcKmF0mnoCgJpTZxVImpbOcrislQHKJvVjz8JegBcv+JBoX4p/g62FXh0CIJ
|
||||||
|
fr7KyKsWpH77zniNFu9xgwEs3RaK+z/+GsHsH4IWBkgj4ABweGOiCw+oeN0WdA8w
|
||||||
|
4okF2VYZbzXbpH3ULrwAvKnElGFcBboSY9yLwHLJAoGBAIGsKz6z2mfAPWqV4esA
|
||||||
|
+Uz22BsOKUex06kEnemmU13EYUBxhZjs3cg3xUAesYkRfmrvl91CyXsi2m0gmCLp
|
||||||
|
FD/bmsvSAWtH4nCsliAR/4pGoEE4sTlL4EPD1PuwJvORutVGD4Arhje+f12tyHOP
|
||||||
|
y0t9nOhXwIhaEm/FLB8AzjSFAoGBAK3NSKZ5KLawi1dnHAbq7tC6lg36nTTd3r6U
|
||||||
|
1fVmxTbRD/zoiad6UVaa1ilrnBhWI05O3g2tBP/6ZEanBthrf+Pgd81SkC+dQpAK
|
||||||
|
pDm4Xm3Rlmfo0fqpvpTKhyjK5V6wvA/Tdzv2CCvebELJEJoJm9943mO5TKUlzgnU
|
||||||
|
i5pGYrl5AoGBAN+b0liV/tDP7NT2pwSTqoW+8itEhBu0QxiHr/QM2941C4+tV4g9
|
||||||
|
wDC2CkQftSm1zx3unnDvU/WXSeJN4GWI7RmQNdsj84mPZVMfFqhvS8F7czbBMHV8
|
||||||
|
OHJdQYlyGPHP9WeP1H0K/zuFEcU6sY/Prl0fRIqhTroI6xEaEd+1bZx7
|
||||||
|
-----END RSA PRIVATE KEY-----
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from unittest.mock import call, patch
|
from unittest.mock import call, patch
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from click.testing import CliRunner
|
from click.testing import CliRunner
|
||||||
from requests import HTTPError
|
from requests import HTTPError
|
||||||
|
|
@ -20,6 +22,9 @@ class RunTestCase(TestCase):
|
||||||
patcher = patch("transip_client.main.requests.put")
|
patcher = patch("transip_client.main.requests.put")
|
||||||
self.mocked_put = patcher.start()
|
self.mocked_put = patcher.start()
|
||||||
|
|
||||||
|
patcher = patch("transip_client.main.requests.Session.send")
|
||||||
|
self.mocked_session = patcher.start()
|
||||||
|
|
||||||
self.runner = CliRunner()
|
self.runner = CliRunner()
|
||||||
|
|
||||||
def test_simple(self):
|
def test_simple(self):
|
||||||
|
|
@ -46,7 +51,7 @@ class RunTestCase(TestCase):
|
||||||
}
|
}
|
||||||
|
|
||||||
with self.assertLogs("transip_client.main", level="INFO") as logger:
|
with self.assertLogs("transip_client.main", level="INFO") as logger:
|
||||||
result = self.runner.invoke(run, ["foobar.com", "TOKEN"])
|
result = self.runner.invoke(run, ["foobar.com"], env={"TOKEN": "token"})
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
logger.output, ["INFO:transip_client.main:Updated domain foobar.com"]
|
logger.output, ["INFO:transip_client.main:Updated domain foobar.com"]
|
||||||
|
|
@ -56,7 +61,7 @@ class RunTestCase(TestCase):
|
||||||
|
|
||||||
self.mocked_get.assert_called_with(
|
self.mocked_get.assert_called_with(
|
||||||
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
||||||
headers={"Authorization": "Bearer TOKEN"},
|
headers={"Authorization": "Bearer token"},
|
||||||
)
|
)
|
||||||
|
|
||||||
expected_json = json.dumps(
|
expected_json = json.dumps(
|
||||||
|
|
@ -75,7 +80,7 @@ class RunTestCase(TestCase):
|
||||||
self.mocked_put.assert_called_with(
|
self.mocked_put.assert_called_with(
|
||||||
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
||||||
data=expected_json,
|
data=expected_json,
|
||||||
headers={"Authorization": "Bearer TOKEN"},
|
headers={"Authorization": "Bearer token"},
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_error_response(self):
|
def test_error_response(self):
|
||||||
|
|
@ -83,7 +88,7 @@ class RunTestCase(TestCase):
|
||||||
self.mocked_get.return_value.raise_for_status.side_effect = HTTPError
|
self.mocked_get.return_value.raise_for_status.side_effect = HTTPError
|
||||||
|
|
||||||
with self.assertLogs("transip_client.main", level="INFO") as logger:
|
with self.assertLogs("transip_client.main", level="INFO") as logger:
|
||||||
result = self.runner.invoke(run, ["foobar.com", "TOKEN"])
|
result = self.runner.invoke(run, ["foobar.com"], env={"TOKEN": "token"})
|
||||||
|
|
||||||
error_log = logger.output[0]
|
error_log = logger.output[0]
|
||||||
|
|
||||||
|
|
@ -92,7 +97,7 @@ class RunTestCase(TestCase):
|
||||||
|
|
||||||
self.mocked_get.assert_called_with(
|
self.mocked_get.assert_called_with(
|
||||||
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
||||||
headers={"Authorization": "Bearer TOKEN"},
|
headers={"Authorization": "Bearer token"},
|
||||||
)
|
)
|
||||||
|
|
||||||
self.mocked_put.assert_not_called()
|
self.mocked_put.assert_not_called()
|
||||||
|
|
@ -120,13 +125,13 @@ class RunTestCase(TestCase):
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
result = self.runner.invoke(run, ["foobar.com", "TOKEN"])
|
result = self.runner.invoke(run, ["foobar.com"], env={"TOKEN": "token"})
|
||||||
|
|
||||||
self.assertEqual(result.exit_code, 0)
|
self.assertEqual(result.exit_code, 0)
|
||||||
|
|
||||||
self.mocked_get.assert_called_with(
|
self.mocked_get.assert_called_with(
|
||||||
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
||||||
headers={"Authorization": "Bearer TOKEN"},
|
headers={"Authorization": "Bearer token"},
|
||||||
)
|
)
|
||||||
|
|
||||||
self.mocked_put.assert_not_called()
|
self.mocked_put.assert_not_called()
|
||||||
|
|
@ -154,13 +159,15 @@ class RunTestCase(TestCase):
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
result = self.runner.invoke(run, ["foobar.com", "TOKEN", "--read-only"])
|
result = self.runner.invoke(
|
||||||
|
run, ["foobar.com", "--read-only"], env={"TOKEN": "token"}
|
||||||
|
)
|
||||||
|
|
||||||
self.assertEqual(result.exit_code, 0)
|
self.assertEqual(result.exit_code, 0)
|
||||||
|
|
||||||
self.mocked_get.assert_called_with(
|
self.mocked_get.assert_called_with(
|
||||||
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
||||||
headers={"Authorization": "Bearer TOKEN"},
|
headers={"Authorization": "Bearer token"},
|
||||||
)
|
)
|
||||||
|
|
||||||
self.mocked_put.assert_not_called()
|
self.mocked_put.assert_not_called()
|
||||||
|
|
@ -190,7 +197,9 @@ class RunTestCase(TestCase):
|
||||||
|
|
||||||
with self.assertLogs("transip_client.main", level="INFO") as logger:
|
with self.assertLogs("transip_client.main", level="INFO") as logger:
|
||||||
result = self.runner.invoke(
|
result = self.runner.invoke(
|
||||||
run, ["foobar.com", "TOKEN", "--api-url", "https://other-provider.com"]
|
run,
|
||||||
|
["foobar.com", "--api-url", "https://other-provider.com"],
|
||||||
|
env={"TOKEN": "token"},
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
|
@ -201,7 +210,7 @@ class RunTestCase(TestCase):
|
||||||
|
|
||||||
self.mocked_get.assert_called_with(
|
self.mocked_get.assert_called_with(
|
||||||
f"https://other-provider.com/domains/foobar.com/dns",
|
f"https://other-provider.com/domains/foobar.com/dns",
|
||||||
headers={"Authorization": "Bearer TOKEN"},
|
headers={"Authorization": "Bearer token"},
|
||||||
)
|
)
|
||||||
|
|
||||||
expected_json = json.dumps(
|
expected_json = json.dumps(
|
||||||
|
|
@ -220,7 +229,7 @@ class RunTestCase(TestCase):
|
||||||
self.mocked_put.assert_called_with(
|
self.mocked_put.assert_called_with(
|
||||||
f"https://other-provider.com/domains/foobar.com/dns",
|
f"https://other-provider.com/domains/foobar.com/dns",
|
||||||
data=expected_json,
|
data=expected_json,
|
||||||
headers={"Authorization": "Bearer TOKEN"},
|
headers={"Authorization": "Bearer token"},
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_env_var(self):
|
def test_env_var(self):
|
||||||
|
|
@ -248,7 +257,12 @@ class RunTestCase(TestCase):
|
||||||
|
|
||||||
with self.assertLogs("transip_client.main", level="INFO") as logger:
|
with self.assertLogs("transip_client.main", level="INFO") as logger:
|
||||||
result = self.runner.invoke(
|
result = self.runner.invoke(
|
||||||
run, ["foobar.com", "TOKEN"], env={"API_URL": "https://new-api.com"}
|
run,
|
||||||
|
["foobar.com"],
|
||||||
|
env={
|
||||||
|
"TOKEN": "token",
|
||||||
|
"API_URL": "https://new-api.com",
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
|
|
@ -259,7 +273,7 @@ class RunTestCase(TestCase):
|
||||||
|
|
||||||
self.mocked_get.assert_called_with(
|
self.mocked_get.assert_called_with(
|
||||||
"https://new-api.com/domains/foobar.com/dns",
|
"https://new-api.com/domains/foobar.com/dns",
|
||||||
headers={"Authorization": "Bearer TOKEN"},
|
headers={"Authorization": "Bearer token"},
|
||||||
)
|
)
|
||||||
|
|
||||||
expected_json = json.dumps(
|
expected_json = json.dumps(
|
||||||
|
|
@ -278,7 +292,7 @@ class RunTestCase(TestCase):
|
||||||
self.mocked_put.assert_called_with(
|
self.mocked_put.assert_called_with(
|
||||||
"https://new-api.com/domains/foobar.com/dns",
|
"https://new-api.com/domains/foobar.com/dns",
|
||||||
data=expected_json,
|
data=expected_json,
|
||||||
headers={"Authorization": "Bearer TOKEN"},
|
headers={"Authorization": "Bearer token"},
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_multi_arg_env_var(self):
|
def test_multi_arg_env_var(self):
|
||||||
|
|
@ -328,7 +342,7 @@ class RunTestCase(TestCase):
|
||||||
|
|
||||||
with self.assertLogs("transip_client.main", level="INFO") as logger:
|
with self.assertLogs("transip_client.main", level="INFO") as logger:
|
||||||
result = self.runner.invoke(
|
result = self.runner.invoke(
|
||||||
run, ["TOKEN"], env={"DOMAINS": "foobar.com foofoo.com"}
|
run, [], env={"TOKEN": "token", "DOMAINS": "foobar.com foofoo.com"}
|
||||||
)
|
)
|
||||||
|
|
||||||
self.assertIsNone(result.exception)
|
self.assertIsNone(result.exception)
|
||||||
|
|
@ -345,13 +359,13 @@ class RunTestCase(TestCase):
|
||||||
expected_calls = [
|
expected_calls = [
|
||||||
call(
|
call(
|
||||||
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
||||||
headers={"Authorization": "Bearer TOKEN"},
|
headers={"Authorization": "Bearer token"},
|
||||||
),
|
),
|
||||||
call().raise_for_status(),
|
call().raise_for_status(),
|
||||||
call().json(),
|
call().json(),
|
||||||
call(
|
call(
|
||||||
f"{DEFAULT_API_URL}/domains/foofoo.com/dns",
|
f"{DEFAULT_API_URL}/domains/foofoo.com/dns",
|
||||||
headers={"Authorization": "Bearer TOKEN"},
|
headers={"Authorization": "Bearer token"},
|
||||||
),
|
),
|
||||||
call().raise_for_status(),
|
call().raise_for_status(),
|
||||||
call().json(),
|
call().json(),
|
||||||
|
|
@ -377,13 +391,13 @@ class RunTestCase(TestCase):
|
||||||
call(
|
call(
|
||||||
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
||||||
data=expected_json,
|
data=expected_json,
|
||||||
headers={"Authorization": "Bearer TOKEN"},
|
headers={"Authorization": "Bearer token"},
|
||||||
),
|
),
|
||||||
call().raise_for_status(),
|
call().raise_for_status(),
|
||||||
call(
|
call(
|
||||||
f"{DEFAULT_API_URL}/domains/foofoo.com/dns",
|
f"{DEFAULT_API_URL}/domains/foofoo.com/dns",
|
||||||
data=expected_json,
|
data=expected_json,
|
||||||
headers={"Authorization": "Bearer TOKEN"},
|
headers={"Authorization": "Bearer token"},
|
||||||
),
|
),
|
||||||
call().raise_for_status(),
|
call().raise_for_status(),
|
||||||
]
|
]
|
||||||
|
|
@ -391,10 +405,101 @@ class RunTestCase(TestCase):
|
||||||
self.mocked_put.assert_has_calls(expected_calls, any_order=True)
|
self.mocked_put.assert_has_calls(expected_calls, any_order=True)
|
||||||
|
|
||||||
def test_no_domains(self):
|
def test_no_domains(self):
|
||||||
result = self.runner.invoke(run, ["TOKEN"])
|
result = self.runner.invoke(run, [], env={"TOKEN": "token"})
|
||||||
|
|
||||||
self.assertEqual(result.exit_code, 1)
|
self.assertEqual(result.exit_code, 1)
|
||||||
self.assertEqual(str(result.exception), "No domain(s) specified")
|
self.assertEqual(str(result.exception), "No domain(s) specified")
|
||||||
|
|
||||||
self.mocked_get.assert_not_called()
|
self.mocked_get.assert_not_called()
|
||||||
self.mocked_put.assert_not_called()
|
self.mocked_put.assert_not_called()
|
||||||
|
|
||||||
|
def test_no_token_or_login_with_private_key_path(self):
|
||||||
|
result = self.runner.invoke(run, ["foobar.com"])
|
||||||
|
|
||||||
|
self.assertEqual(result.exit_code, 1)
|
||||||
|
self.assertEqual(
|
||||||
|
str(result.exception),
|
||||||
|
"Either a token or a login name with a path to a private key need"
|
||||||
|
" to be specified"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.mocked_get.assert_not_called()
|
||||||
|
self.mocked_put.assert_not_called()
|
||||||
|
|
||||||
|
def test_login_without_private_key_path(self):
|
||||||
|
result = self.runner.invoke(run, ["foobar.com"], env={"LOGIN": "foo"})
|
||||||
|
|
||||||
|
self.assertEqual(result.exit_code, 1)
|
||||||
|
self.assertEqual(
|
||||||
|
str(result.exception),
|
||||||
|
"Both a login name and the path to a private key need to be specified"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.mocked_get.assert_not_called()
|
||||||
|
self.mocked_put.assert_not_called()
|
||||||
|
|
||||||
|
def test_login_with_private_key_path(self):
|
||||||
|
self.mocked_dns.return_value = b"111.420\n"
|
||||||
|
self.mocked_get.return_value.json.return_value = {
|
||||||
|
"dnsEntries": [
|
||||||
|
{
|
||||||
|
"name": "@",
|
||||||
|
"expire": 60,
|
||||||
|
"type": "A",
|
||||||
|
"content": "111.421",
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"_links": [
|
||||||
|
{
|
||||||
|
"rel": "self",
|
||||||
|
"link": "https://api.transip.nl/v6/domains/foobar.com/dns",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rel": "domain",
|
||||||
|
"link": "https://api.transip.nl/v6/domains/foobar.com",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
self.mocked_session.return_value.json.return_value = {"token": "FOOBAR"}
|
||||||
|
|
||||||
|
private_key_path = (
|
||||||
|
Path(os.path.dirname(__file__)) / "files" / "test-private-key.pem"
|
||||||
|
)
|
||||||
|
|
||||||
|
with self.assertLogs("transip_client.main", level="INFO") as logger:
|
||||||
|
result = self.runner.invoke(
|
||||||
|
run,
|
||||||
|
["foobar.com"],
|
||||||
|
env={"LOGIN": "foo", "PRIVATE_KEY_PATH": str(private_key_path)}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
logger.output, ["INFO:transip_client.main:Updated domain foobar.com"]
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(result.exit_code, 0)
|
||||||
|
|
||||||
|
self.mocked_get.assert_called_with(
|
||||||
|
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
||||||
|
headers={"Authorization": "Bearer FOOBAR"},
|
||||||
|
)
|
||||||
|
|
||||||
|
expected_json = json.dumps(
|
||||||
|
{
|
||||||
|
"dnsEntries": [
|
||||||
|
{
|
||||||
|
"name": "@",
|
||||||
|
"expire": 60,
|
||||||
|
"type": "A",
|
||||||
|
"content": "111.420",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self.mocked_put.assert_called_with(
|
||||||
|
f"{DEFAULT_API_URL}/domains/foobar.com/dns",
|
||||||
|
data=expected_json,
|
||||||
|
headers={"Authorization": "Bearer FOOBAR"},
|
||||||
|
)
|
||||||
Loading…
Add table
Add a link
Reference in a new issue