From 5637790af5397b54211b4b175f93885d7a80e2f2 Mon Sep 17 00:00:00 2001 From: SporeStack Date: Thu, 25 May 2023 16:24:08 +0000 Subject: [PATCH] v10.6.0: Add `sporestack server update-server` command. Also improve test coverage slightly. --- CHANGELOG.md | 6 + Pipfile.lock | 350 +++++++++++++++++++---------------- integration-test.sh | 6 +- src/sporestack/__init__.py | 2 +- src/sporestack/api.py | 32 ++-- src/sporestack/api_client.py | 14 +- src/sporestack/cli.py | 32 +++- src/sporestack/client.py | 14 +- src/sporestack/models.py | 25 +++ tests/test_api_client.py | 54 ++++++ 10 files changed, 353 insertions(+), 182 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 29f709a..b061768 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Nothing yet. +## [10.6.0 - 2023-05-25] + +## Added + +- `sporestack server update-hostname` command. + ## [10.5.0 - 2023-05-12] ## Changed diff --git a/Pipfile.lock b/Pipfile.lock index ca8c186..5ed1dac 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -24,11 +24,11 @@ }, "certifi": { "hashes": [ - "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", - "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" + "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7", + "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716" ], "markers": "python_version >= '3.6'", - "version": "==2022.12.7" + "version": "==2023.5.7" }, "click": { "hashes": [ @@ -48,22 +48,22 @@ }, "httpcore": { "hashes": [ - "sha256:0fdfea45e94f0c9fd96eab9286077f9ff788dd186635ae61b312693e4d943599", - "sha256:cc045a3241afbf60ce056202301b4d8b6af08845e3294055eb26b09913ef903c" + "sha256:125f8375ab60036db632f34f4b627a9ad085048eef7cb7d2616fea0f739f98af", + "sha256:5581b9c12379c4288fe70f43c710d16060c10080617001e6b22a3b6dbcbefd36" ], "markers": "python_version >= '3.7'", - "version": "==0.17.0" + "version": "==0.17.2" }, "httpx": { "extras": [ "socks" ], "hashes": [ - "sha256:447556b50c1921c351ea54b4fe79d91b724ed2b027462ab9a329465d147d5a4e", - "sha256:507d676fc3e26110d41df7d35ebd8b3b8585052450f4097401c9be59d928c63e" + "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd", + "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd" ], "markers": "python_version >= '3.7'", - "version": "==0.24.0" + "version": "==0.24.1" }, "idna": { "hashes": [ @@ -73,47 +73,79 @@ "markers": "python_version >= '3.5'", "version": "==3.4" }, - "pydantic": { + "markdown-it-py": { "hashes": [ - "sha256:01aea3a42c13f2602b7ecbbea484a98169fb568ebd9e247593ea05f01b884b2e", - "sha256:0cd181f1d0b1d00e2b705f1bf1ac7799a2d938cce3376b8007df62b29be3c2c6", - "sha256:10a86d8c8db68086f1e30a530f7d5f83eb0685e632e411dbbcf2d5c0150e8dcd", - "sha256:193924c563fae6ddcb71d3f06fa153866423ac1b793a47936656e806b64e24ca", - "sha256:464855a7ff7f2cc2cf537ecc421291b9132aa9c79aef44e917ad711b4a93163b", - "sha256:516f1ed9bc2406a0467dd777afc636c7091d71f214d5e413d64fef45174cfc7a", - "sha256:6434b49c0b03a51021ade5c4daa7d70c98f7a79e95b551201fff682fc1661245", - "sha256:64d34ab766fa056df49013bb6e79921a0265204c071984e75a09cbceacbbdd5d", - "sha256:670bb4683ad1e48b0ecb06f0cfe2178dcf74ff27921cdf1606e527d2617a81ee", - "sha256:68792151e174a4aa9e9fc1b4e653e65a354a2fa0fed169f7b3d09902ad2cb6f1", - "sha256:701daea9ffe9d26f97b52f1d157e0d4121644f0fcf80b443248434958fd03dc3", - "sha256:7d45fc99d64af9aaf7e308054a0067fdcd87ffe974f2442312372dfa66e1001d", - "sha256:80b1fab4deb08a8292d15e43a6edccdffa5377a36a4597bb545b93e79c5ff0a5", - "sha256:82dffb306dd20bd5268fd6379bc4bfe75242a9c2b79fec58e1041fbbdb1f7914", - "sha256:8c7f51861d73e8b9ddcb9916ae7ac39fb52761d9ea0df41128e81e2ba42886cd", - "sha256:950ce33857841f9a337ce07ddf46bc84e1c4946d2a3bba18f8280297157a3fd1", - "sha256:976cae77ba6a49d80f461fd8bba183ff7ba79f44aa5cfa82f1346b5626542f8e", - "sha256:9f6f0fd68d73257ad6685419478c5aece46432f4bdd8d32c7345f1986496171e", - "sha256:a7cd2251439988b413cb0a985c4ed82b6c6aac382dbaff53ae03c4b23a70e80a", - "sha256:abfb7d4a7cd5cc4e1d1887c43503a7c5dd608eadf8bc615413fc498d3e4645cd", - "sha256:ae150a63564929c675d7f2303008d88426a0add46efd76c3fc797cd71cb1b46f", - "sha256:b0f85904f73161817b80781cc150f8b906d521fa11e3cdabae19a581c3606209", - "sha256:b4a849d10f211389502059c33332e91327bc154acc1845f375a99eca3afa802d", - "sha256:c15582f9055fbc1bfe50266a19771bbbef33dd28c45e78afbe1996fd70966c2a", - "sha256:c230c0d8a322276d6e7b88c3f7ce885f9ed16e0910354510e0bae84d54991143", - "sha256:cc1dde4e50a5fc1336ee0581c1612215bc64ed6d28d2c7c6f25d2fe3e7c3e918", - "sha256:cf135c46099ff3f919d2150a948ce94b9ce545598ef2c6c7bf55dca98a304b52", - "sha256:cfc83c0678b6ba51b0532bea66860617c4cd4251ecf76e9846fa5a9f3454e97e", - "sha256:d2a5ebb48958754d386195fe9e9c5106f11275867051bf017a8059410e9abf1f", - "sha256:d71e69699498b020ea198468e2480a2f1e7433e32a3a99760058c6520e2bea7e", - "sha256:d75ae19d2a3dbb146b6f324031c24f8a3f52ff5d6a9f22f0683694b3afcb16fb", - "sha256:dfe2507b8ef209da71b6fb5f4e597b50c5a34b78d7e857c4f8f3115effaef5fe", - "sha256:e0cfe895a504c060e5d36b287ee696e2fdad02d89e0d895f83037245218a87fe", - "sha256:e79e999e539872e903767c417c897e729e015872040e56b96e67968c3b918b2d", - "sha256:ecbbc51391248116c0a055899e6c3e7ffbb11fb5e2a4cd6f2d0b93272118a209", - "sha256:f4a2b50e2b03d5776e7f21af73e2070e1b5c0d0df255a827e7c632962f8315af" + "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30", + "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1" ], "markers": "python_version >= '3.7'", - "version": "==1.10.7" + "version": "==2.2.0" + }, + "mdurl": { + "hashes": [ + "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" + ], + "markers": "python_version >= '3.7'", + "version": "==0.1.2" + }, + "pydantic": { + "hashes": [ + "sha256:052d8654cb65174d6f9490cc9b9a200083a82cf5c3c5d3985db765757eb3b375", + "sha256:0c6fafa0965b539d7aab0a673a046466d23b86e4b0e8019d25fd53f4df62c277", + "sha256:1243d28e9b05003a89d72e7915fdb26ffd1d39bdd39b00b7dbe4afae4b557f9d", + "sha256:12f7b0bf8553e310e530e9f3a2f5734c68699f42218bf3568ef49cd9b0e44df4", + "sha256:1410275520dfa70effadf4c21811d755e7ef9bb1f1d077a21958153a92c8d9ca", + "sha256:16f8c3e33af1e9bb16c7a91fc7d5fa9fe27298e9f299cff6cb744d89d573d62c", + "sha256:17aef11cc1b997f9d574b91909fed40761e13fac438d72b81f902226a69dac01", + "sha256:191ba419b605f897ede9892f6c56fb182f40a15d309ef0142212200a10af4c18", + "sha256:1952526ba40b220b912cdc43c1c32bcf4a58e3f192fa313ee665916b26befb68", + "sha256:1ced8375969673929809d7f36ad322934c35de4af3b5e5b09ec967c21f9f7887", + "sha256:2e4148e635994d57d834be1182a44bdb07dd867fa3c2d1b37002000646cc5459", + "sha256:34d327c81e68a1ecb52fe9c8d50c8a9b3e90d3c8ad991bfc8f953fb477d42fb4", + "sha256:35db5301b82e8661fa9c505c800d0990bc14e9f36f98932bb1d248c0ac5cada5", + "sha256:3e59417ba8a17265e632af99cc5f35ec309de5980c440c255ab1ca3ae96a3e0e", + "sha256:42aa0c4b5c3025483240a25b09f3c09a189481ddda2ea3a831a9d25f444e03c1", + "sha256:666bdf6066bf6dbc107b30d034615d2627e2121506c555f73f90b54a463d1f33", + "sha256:66a703d1983c675a6e0fed8953b0971c44dba48a929a2000a493c3772eb61a5a", + "sha256:6a82d6cda82258efca32b40040228ecf43a548671cb174a1e81477195ed3ed56", + "sha256:6f2e754d5566f050954727c77f094e01793bcb5725b663bf628fa6743a5a9108", + "sha256:7456eb22ed9aaa24ff3e7b4757da20d9e5ce2a81018c1b3ebd81a0b88a18f3b2", + "sha256:7b1f6cb446470b7ddf86c2e57cd119a24959af2b01e552f60705910663af09a4", + "sha256:7d5b8641c24886d764a74ec541d2fc2c7fb19f6da2a4001e6d580ba4a38f7878", + "sha256:84d80219c3f8d4cad44575e18404099c76851bc924ce5ab1c4c8bb5e2a2227d0", + "sha256:88f195f582851e8db960b4a94c3e3ad25692c1c1539e2552f3df7a9e972ef60e", + "sha256:93e6bcfccbd831894a6a434b0aeb1947f9e70b7468f274154d03d71fabb1d7c6", + "sha256:93e766b4a8226e0708ef243e843105bf124e21331694367f95f4e3b4a92bbb3f", + "sha256:ab523c31e22943713d80d8d342d23b6f6ac4b792a1e54064a8d0cf78fd64e800", + "sha256:bb14388ec45a7a0dc429e87def6396f9e73c8c77818c927b6a60706603d5f2ea", + "sha256:c0ab53b609c11dfc0c060d94335993cc2b95b2150e25583bec37a49b2d6c6c3f", + "sha256:c33b60054b2136aef8cf190cd4c52a3daa20b2263917c49adad20eaf381e823b", + "sha256:ceb6a23bf1ba4b837d0cfe378329ad3f351b5897c8d4914ce95b85fba96da5a1", + "sha256:d532bf00f381bd6bc62cabc7d1372096b75a33bc197a312b03f5838b4fb84edd", + "sha256:df7800cb1984d8f6e249351139667a8c50a379009271ee6236138a22a0c0f319", + "sha256:e82d4566fcd527eae8b244fa952d99f2ca3172b7e97add0b43e2d97ee77f81ab", + "sha256:f90c1e29f447557e9e26afb1c4dbf8768a10cc676e3781b6a577841ade126b85", + "sha256:f9613fadad06b4f3bc5db2653ce2f22e0de84a7c6c293909b48f6ed37b83c61f" + ], + "markers": "python_version >= '3.7'", + "version": "==1.10.8" + }, + "pygments": { + "hashes": [ + "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c", + "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1" + ], + "markers": "python_version >= '3.7'", + "version": "==2.15.1" + }, + "rich": { + "hashes": [ + "sha256:2d11b9b8dd03868f09b4fffadc84a6a8cda574e40dc90821bd845720ebb8e89c", + "sha256:69cdf53799e63f38b95b9bf9c875f8c90e78dd62b2f00c13a911c7a3b9fa4704" + ], + "markers": "python_full_version >= '3.7.0'", + "version": "==13.3.5" }, "segno": { "hashes": [ @@ -152,11 +184,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb", - "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4" + "sha256:06006244c70ac8ee83fa8282cb188f697b8db25bc8b4df07be1873c43897060c", + "sha256:3a8b36f13dd5fdc5d1b16fe317f5668545de77fa0b8e02006381fd49d731ab98" ], "markers": "python_version >= '3.7'", - "version": "==4.5.0" + "version": "==4.6.2" } }, "develop": { @@ -225,11 +257,11 @@ }, "certifi": { "hashes": [ - "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", - "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" + "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7", + "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716" ], "markers": "python_version >= '3.6'", - "version": "==2022.12.7" + "version": "==2023.5.7" }, "charset-normalizer": { "hashes": [ @@ -325,84 +357,84 @@ "toml" ], "hashes": [ - "sha256:0342a28617e63ad15d96dca0f7ae9479a37b7d8a295f749c14f3436ea59fdcb3", - "sha256:066b44897c493e0dcbc9e6a6d9f8bbb6607ef82367cf6810d387c09f0cd4fe9a", - "sha256:10b15394c13544fce02382360cab54e51a9e0fd1bd61ae9ce012c0d1e103c813", - "sha256:12580845917b1e59f8a1c2ffa6af6d0908cb39220f3019e36c110c943dc875b0", - "sha256:156192e5fd3dbbcb11cd777cc469cf010a294f4c736a2b2c891c77618cb1379a", - "sha256:1637253b11a18f453e34013c665d8bf15904c9e3c44fbda34c643fbdc9d452cd", - "sha256:292300f76440651529b8ceec283a9370532f4ecba9ad67d120617021bb5ef139", - "sha256:30dcaf05adfa69c2a7b9f7dfd9f60bc8e36b282d7ed25c308ef9e114de7fc23b", - "sha256:338aa9d9883aaaad53695cb14ccdeb36d4060485bb9388446330bef9c361c252", - "sha256:373ea34dca98f2fdb3e5cb33d83b6d801007a8074f992b80311fc589d3e6b790", - "sha256:38c0a497a000d50491055805313ed83ddba069353d102ece8aef5d11b5faf045", - "sha256:40cc0f91c6cde033da493227797be2826cbf8f388eaa36a0271a97a332bfd7ce", - "sha256:4436cc9ba5414c2c998eaedee5343f49c02ca93b21769c5fdfa4f9d799e84200", - "sha256:509ecd8334c380000d259dc66feb191dd0a93b21f2453faa75f7f9cdcefc0718", - "sha256:5c587f52c81211d4530fa6857884d37f514bcf9453bdeee0ff93eaaf906a5c1b", - "sha256:5f3671662dc4b422b15776cdca89c041a6349b4864a43aa2350b6b0b03bbcc7f", - "sha256:6599bf92f33ab041e36e06d25890afbdf12078aacfe1f1d08c713906e49a3fe5", - "sha256:6e8a95f243d01ba572341c52f89f3acb98a3b6d1d5d830efba86033dd3687ade", - "sha256:706ec567267c96717ab9363904d846ec009a48d5f832140b6ad08aad3791b1f5", - "sha256:780551e47d62095e088f251f5db428473c26db7829884323e56d9c0c3118791a", - "sha256:7ff8f3fb38233035028dbc93715551d81eadc110199e14bbbfa01c5c4a43f8d8", - "sha256:828189fcdda99aae0d6bf718ea766b2e715eabc1868670a0a07bf8404bf58c33", - "sha256:857abe2fa6a4973f8663e039ead8d22215d31db613ace76e4a98f52ec919068e", - "sha256:883123d0bbe1c136f76b56276074b0c79b5817dd4238097ffa64ac67257f4b6c", - "sha256:8877d9b437b35a85c18e3c6499b23674684bf690f5d96c1006a1ef61f9fdf0f3", - "sha256:8e575a59315a91ccd00c7757127f6b2488c2f914096077c745c2f1ba5b8c0969", - "sha256:97072cc90f1009386c8a5b7de9d4fc1a9f91ba5ef2146c55c1f005e7b5c5e068", - "sha256:9a22cbb5ede6fade0482111fa7f01115ff04039795d7092ed0db43522431b4f2", - "sha256:a063aad9f7b4c9f9da7b2550eae0a582ffc7623dca1c925e50c3fbde7a579771", - "sha256:a08c7401d0b24e8c2982f4e307124b671c6736d40d1c39e09d7a8687bddf83ed", - "sha256:a0b273fe6dc655b110e8dc89b8ec7f1a778d78c9fd9b4bda7c384c8906072212", - "sha256:a2b3b05e22a77bb0ae1a3125126a4e08535961c946b62f30985535ed40e26614", - "sha256:a66e055254a26c82aead7ff420d9fa8dc2da10c82679ea850d8feebf11074d88", - "sha256:aa387bd7489f3e1787ff82068b295bcaafbf6f79c3dad3cbc82ef88ce3f48ad3", - "sha256:ae453f655640157d76209f42c62c64c4d4f2c7f97256d3567e3b439bd5c9b06c", - "sha256:b5016e331b75310610c2cf955d9f58a9749943ed5f7b8cfc0bb89c6134ab0a84", - "sha256:b9a4ee55174b04f6af539218f9f8083140f61a46eabcaa4234f3c2a452c4ed11", - "sha256:bd3b4b8175c1db502adf209d06136c000df4d245105c8839e9d0be71c94aefe1", - "sha256:bebea5f5ed41f618797ce3ffb4606c64a5de92e9c3f26d26c2e0aae292f015c1", - "sha256:c10fbc8a64aa0f3ed136b0b086b6b577bc64d67d5581acd7cc129af52654384e", - "sha256:c2c41c1b1866b670573657d584de413df701f482574bad7e28214a2362cb1fd1", - "sha256:cf97ed82ca986e5c637ea286ba2793c85325b30f869bf64d3009ccc1a31ae3fd", - "sha256:d1f25ee9de21a39b3a8516f2c5feb8de248f17da7eead089c2e04aa097936b47", - "sha256:d2fbc2a127e857d2f8898aaabcc34c37771bf78a4d5e17d3e1f5c30cd0cbc62a", - "sha256:dc945064a8783b86fcce9a0a705abd7db2117d95e340df8a4333f00be5efb64c", - "sha256:ddc5a54edb653e9e215f75de377354e2455376f416c4378e1d43b08ec50acc31", - "sha256:e8834e5f17d89e05697c3c043d3e58a8b19682bf365048837383abfe39adaed5", - "sha256:ef9659d1cda9ce9ac9585c045aaa1e59223b143f2407db0eaee0b61a4f266fb6", - "sha256:f6f5cab2d7f0c12f8187a376cc6582c477d2df91d63f75341307fcdcb5d60303", - "sha256:f81c9b4bd8aa747d417407a7f6f0b1469a43b36a85748145e144ac4e8d303cb5", - "sha256:f99ef080288f09ffc687423b8d60978cf3a465d3f404a18d1a05474bd8575a47" + "sha256:004948e296149644d208964300cb3d98affc5211e9e490e9979af4030b0d6473", + "sha256:13cde6bb0e58fb67d09e2f373de3899d1d1e866c5a9ff05d93615f2f54fbd2bb", + "sha256:1c9e4a5eb1bbc3675ee57bc31f8eea4cd7fb0cbcbe4912cf1cb2bf3b754f4a80", + "sha256:2025f913f2edb0272ef15d00b1f335ff8908c921c8eb2013536fcaf61f5a683d", + "sha256:25bad4196104761bc26b1dae9b57383826542ec689ff0042f7f4f4dd7a815cba", + "sha256:2692306d3d4cb32d2cceed1e47cebd6b1d2565c993d6d2eda8e6e6adf53301e6", + "sha256:272ab31228a9df857ab5df5d67936d8861464dc89c5d3fab35132626e9369379", + "sha256:2e8c0e79820cdd67978e1120983786422d279e07a381dbf89d03bbb23ec670a6", + "sha256:3062fd5c62df988cea9f2972c593f77fed1182bfddc5a3b12b1e606cb7aba99e", + "sha256:3436927d1794fa6763b89b60c896f9e3bd53212001026ebc9080d23f0c2733c1", + "sha256:35db06450272473eab4449e9c2ad9bc6a0a68dab8e81a0eae6b50d9c2838767e", + "sha256:392154d09bd4473b9d11351ab5d63391f3d5d24d752f27b3be7498b0ee2b5226", + "sha256:3cff6980fe7100242170092bb40d2b1cdad79502cd532fd26b12a2b8a5f9aee0", + "sha256:42c692b55a647a832025a4c048007034fe77b162b566ad537ce65ad824b12a84", + "sha256:44c9b9f1a245f3d0d202b1a8fa666a80b5ecbe4ad5d0859c0fb16a52d9763224", + "sha256:496b86f1fc9c81a1cd53d8842ef712e950a4611bba0c42d33366a7b91ba969ec", + "sha256:4bbd58eb5a2371bf160590f4262109f66b6043b0b991930693134cb617bc0169", + "sha256:4e3783a286d5a93a2921396d50ce45a909aa8f13eee964465012f110f0cbb611", + "sha256:4f3c7c19581d471af0e9cb49d928172cd8492cd78a2b7a4e82345d33662929bb", + "sha256:52c139b7ab3f0b15f9aad0a3fedef5a1f8c0b2bdc291d88639ca2c97d3682416", + "sha256:541280dde49ce74a4262c5e395b48ea1207e78454788887118c421cb4ffbfcac", + "sha256:5906f6a84b47f995cd1bf0aca1c72d591c55ee955f98074e93660d64dfc66eb9", + "sha256:6284a2005e4f8061c58c814b1600ad0074ccb0289fe61ea709655c5969877b70", + "sha256:6727a0d929ff0028b1ed8b3e7f8701670b1d7032f219110b55476bb60c390bfb", + "sha256:697f4742aa3f26c107ddcb2b1784a74fe40180014edbd9adaa574eac0529914c", + "sha256:6b9f64526286255735847aed0221b189486e0b9ed943446936e41b7e44b08783", + "sha256:6babcbf1e66e46052442f10833cfc4a0d3554d8276aa37af8531a83ed3c1a01d", + "sha256:6e7f1a8328eeec34c54f1d5968a708b50fc38d31e62ca8b0560e84a968fbf9a9", + "sha256:71f739f97f5f80627f1fee2331e63261355fd1e9a9cce0016394b6707ac3f4ec", + "sha256:76d06b721c2550c01a60e5d3093f417168658fb454e5dfd9a23570e9bffe39a1", + "sha256:77a04b84d01f0e12c66f16e69e92616442dc675bbe51b90bfb074b1e5d1c7fbd", + "sha256:97729e6828643f168a2a3f07848e1b1b94a366b13a9f5aba5484c2215724edc8", + "sha256:9a8723ccec4e564d4b9a79923246f7b9a8de4ec55fa03ec4ec804459dade3c4f", + "sha256:a5ffd45c6b93c23a8507e2f436983015c6457aa832496b6a095505ca2f63e8f1", + "sha256:a6f03f87fea579d55e0b690d28f5042ec1368650466520fbc400e7aeaf09e995", + "sha256:aac1d5fdc5378f6bac2c0c7ebe7635a6809f5b4376f6cf5d43243c1917a67087", + "sha256:ae82c5f168d2a39a5d69a12a69d4dc23837a43cf2ca99be60dfe59996ea6b113", + "sha256:bc7b667f8654376e9353dd93e55e12ce2a59fb6d8e29fce40de682273425e044", + "sha256:c1d7a31603c3483ac49c1726723b0934f88f2c011c660e6471e7bd735c2fa110", + "sha256:c534431153caffc7c495c3eddf7e6a6033e7f81d78385b4e41611b51e8870446", + "sha256:c93d52c3dc7b9c65e39473704988602300e3cc1bad08b5ab5b03ca98bbbc68c1", + "sha256:cbcc874f454ee51f158afd604a315f30c0e31dff1d5d5bf499fc529229d964dd", + "sha256:d3cacc6a665221108ecdf90517a8028d07a2783df3417d12dcfef1c517e67478", + "sha256:d712cefff15c712329113b01088ba71bbcef0f7ea58478ca0bbec63a824844cb", + "sha256:d7786b2fa7809bf835f830779ad285215a04da76293164bb6745796873f0942d", + "sha256:dc11b42fa61ff1e788dd095726a0aed6aad9c03d5c5984b54cb9e1e67b276aa5", + "sha256:dc4d5187ef4d53e0d4c8eaf530233685667844c5fb0b855fea71ae659017854b", + "sha256:f5440cdaf3099e7ab17a5a7065aed59aff8c8b079597b61c1f8be6f32fe60636", + "sha256:fa079995432037b5e2ef5ddbb270bcd2ded9f52b8e191a5de11fe59a00ea30d8", + "sha256:fbe6e8c0a9a7193ba10ee52977d4d5e7652957c1f56ccefed0701db8801a2a3b", + "sha256:fde5c7a9d9864d3e07992f66767a9817f24324f354caa3d8129735a3dc74f126" ], "markers": "python_version >= '3.7'", - "version": "==7.2.5" + "version": "==7.2.6" }, "docutils": { "hashes": [ - "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6", - "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc" + "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6", + "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b" ], "markers": "python_version >= '3.7'", - "version": "==0.19" + "version": "==0.20.1" }, "flit": { "hashes": [ - "sha256:5ee0f88fd1cfa4160d1a8fa01237e96d06d677ae0403a0bbabbb277cb37c5e9c", - "sha256:d0f2a8f4bd45dc794befbf5839ecc0fd3830d65a57bd52b5997542fac5d5e937" + "sha256:076c3aaba5ac24cf0ad3251f910900d95a08218e6bcb26f21fef1036cc4679ca", + "sha256:d75edf5eb324da20d53570a6a6f87f51e606eee8384925cd66a90611140844c7" ], "index": "pypi", - "version": "==3.8.0" + "version": "==3.9.0" }, "flit-core": { "hashes": [ - "sha256:64a29ec845164a6abe1136bf4bc5ae012bdfe758ed42fc7571a9059a7c80bd83", - "sha256:b305b30c99526df5e63d6022dd2310a0a941a187bd3884f4c8ef0418df6c39f3" + "sha256:72ad266176c4a3fcfab5f2930d76896059851240570ce9a98733b658cb786eba", + "sha256:7aada352fb0c7f5538c4fafeddf314d3a6a92ee8e2b1de70482329e42de70301" ], "markers": "python_version >= '3.6'", - "version": "==3.8.0" + "version": "==3.9.0" }, "h11": { "hashes": [ @@ -414,22 +446,22 @@ }, "httpcore": { "hashes": [ - "sha256:0fdfea45e94f0c9fd96eab9286077f9ff788dd186635ae61b312693e4d943599", - "sha256:cc045a3241afbf60ce056202301b4d8b6af08845e3294055eb26b09913ef903c" + "sha256:125f8375ab60036db632f34f4b627a9ad085048eef7cb7d2616fea0f739f98af", + "sha256:5581b9c12379c4288fe70f43c710d16060c10080617001e6b22a3b6dbcbefd36" ], "markers": "python_version >= '3.7'", - "version": "==0.17.0" + "version": "==0.17.2" }, "httpx": { "extras": [ "socks" ], "hashes": [ - "sha256:447556b50c1921c351ea54b4fe79d91b724ed2b027462ab9a329465d147d5a4e", - "sha256:507d676fc3e26110d41df7d35ebd8b3b8585052450f4097401c9be59d928c63e" + "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd", + "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd" ], "markers": "python_version >= '3.7'", - "version": "==0.24.0" + "version": "==0.24.1" }, "idna": { "hashes": [ @@ -561,35 +593,35 @@ }, "mypy": { "hashes": [ - "sha256:023fe9e618182ca6317ae89833ba422c411469156b690fde6a315ad10695a521", - "sha256:031fc69c9a7e12bcc5660b74122ed84b3f1c505e762cc4296884096c6d8ee140", - "sha256:2de7babe398cb7a85ac7f1fd5c42f396c215ab3eff731b4d761d68d0f6a80f48", - "sha256:2e93a8a553e0394b26c4ca683923b85a69f7ccdc0139e6acd1354cc884fe0128", - "sha256:390bc685ec209ada4e9d35068ac6988c60160b2b703072d2850457b62499e336", - "sha256:3a2d219775a120581a0ae8ca392b31f238d452729adbcb6892fa89688cb8306a", - "sha256:3efde4af6f2d3ccf58ae825495dbb8d74abd6d176ee686ce2ab19bd025273f41", - "sha256:4a99fe1768925e4a139aace8f3fb66db3576ee1c30b9c0f70f744ead7e329c9f", - "sha256:4b41412df69ec06ab141808d12e0bf2823717b1c363bd77b4c0820feaa37249e", - "sha256:4c8d8c6b80aa4a1689f2a179d31d86ae1367ea4a12855cc13aa3ba24bb36b2d8", - "sha256:4d19f1a239d59f10fdc31263d48b7937c585810288376671eaf75380b074f238", - "sha256:4e4a682b3f2489d218751981639cffc4e281d548f9d517addfd5a2917ac78119", - "sha256:695c45cea7e8abb6f088a34a6034b1d273122e5530aeebb9c09626cea6dca4cb", - "sha256:701189408b460a2ff42b984e6bd45c3f41f0ac9f5f58b8873bbedc511900086d", - "sha256:70894c5345bea98321a2fe84df35f43ee7bb0feec117a71420c60459fc3e1eed", - "sha256:8293a216e902ac12779eb7a08f2bc39ec6c878d7c6025aa59464e0c4c16f7eb9", - "sha256:8d26b513225ffd3eacece727f4387bdce6469192ef029ca9dd469940158bc89e", - "sha256:a197ad3a774f8e74f21e428f0de7f60ad26a8d23437b69638aac2764d1e06a6a", - "sha256:bea55fc25b96c53affab852ad94bf111a3083bc1d8b0c76a61dd101d8a388cf5", - "sha256:c9a084bce1061e55cdc0493a2ad890375af359c766b8ac311ac8120d3a472950", - "sha256:d0e9464a0af6715852267bf29c9553e4555b61f5904a4fc538547a4d67617937", - "sha256:d8e9187bfcd5ffedbe87403195e1fc340189a68463903c39e2b63307c9fa0394", - "sha256:eaeaa0888b7f3ccb7bcd40b50497ca30923dba14f385bde4af78fac713d6d6f6", - "sha256:f46af8d162f3d470d8ffc997aaf7a269996d205f9d746124a179d3abe05ac602", - "sha256:f70a40410d774ae23fcb4afbbeca652905a04de7948eaf0b1789c8d1426b72d1", - "sha256:fe91be1c51c90e2afe6827601ca14353bbf3953f343c2129fa1e247d55fd95ba" + "sha256:1c4c42c60a8103ead4c1c060ac3cdd3ff01e18fddce6f1016e08939647a0e703", + "sha256:44797d031a41516fcf5cbfa652265bb994e53e51994c1bd649ffcd0c3a7eccbf", + "sha256:473117e310febe632ddf10e745a355714e771ffe534f06db40702775056614c4", + "sha256:4c99c3ecf223cf2952638da9cd82793d8f3c0c5fa8b6ae2b2d9ed1e1ff51ba85", + "sha256:550a8b3a19bb6589679a7c3c31f64312e7ff482a816c96e0cecec9ad3a7564dd", + "sha256:658fe7b674769a0770d4b26cb4d6f005e88a442fe82446f020be8e5f5efb2fae", + "sha256:6e33bb8b2613614a33dff70565f4c803f889ebd2f859466e42b46e1df76018dd", + "sha256:6e42d29e324cdda61daaec2336c42512e59c7c375340bd202efa1fe0f7b8f8ca", + "sha256:74bc9b6e0e79808bf8678d7678b2ae3736ea72d56eede3820bd3849823e7f305", + "sha256:76ec771e2342f1b558c36d49900dfe81d140361dd0d2df6cd71b3db1be155409", + "sha256:7d23370d2a6b7a71dc65d1266f9a34e4cde9e8e21511322415db4b26f46f6b8c", + "sha256:87df44954c31d86df96c8bd6e80dfcd773473e877ac6176a8e29898bfb3501cb", + "sha256:8c5979d0deb27e0f4479bee18ea0f83732a893e81b78e62e2dda3e7e518c92ee", + "sha256:95d8d31a7713510685b05fbb18d6ac287a56c8f6554d88c19e73f724a445448a", + "sha256:a22435632710a4fcf8acf86cbd0d69f68ac389a3892cb23fbad176d1cddaf228", + "sha256:a8763e72d5d9574d45ce5881962bc8e9046bf7b375b0abf031f3e6811732a897", + "sha256:c1eb485cea53f4f5284e5baf92902cd0088b24984f4209e25981cc359d64448d", + "sha256:c5d2cc54175bab47011b09688b418db71403aefad07cbcd62d44010543fc143f", + "sha256:cbc07246253b9e3d7d74c9ff948cd0fd7a71afcc2b77c7f0a59c26e9395cb152", + "sha256:d0b6c62206e04061e27009481cb0ec966f7d6172b5b936f3ead3d74f29fe3dcf", + "sha256:ddae0f39ca146972ff6bb4399f3b2943884a774b8771ea0a8f50e971f5ea5ba8", + "sha256:e1f4d16e296f5135624b34e8fb741eb0eadedca90862405b1f1fde2040b9bd11", + "sha256:e86c2c6852f62f8f2b24cb7a613ebe8e0c7dc1402c61d36a609174f63e0ff017", + "sha256:ebc95f8386314272bbc817026f8ce8f4f0d2ef7ae44f947c4664efac9adec929", + "sha256:f9dca1e257d4cc129517779226753dbefb4f2266c4eaad610fc15c6a7e14283e", + "sha256:faff86aa10c1aa4a10e1a301de160f3d8fc8703b88c7e98de46b531ff1276a9a" ], "index": "pypi", - "version": "==1.2.0" + "version": "==1.3.0" }, "mypy-extensions": { "hashes": [ @@ -633,11 +665,11 @@ }, "platformdirs": { "hashes": [ - "sha256:47692bc24c1958e8b0f13dd727307cff1db103fca36399f457da8e05f222fdc4", - "sha256:7954a68d0ba23558d753f73437c55f89027cf8f5108c19844d4b82e5af396335" + "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f", + "sha256:e2378146f1964972c03c085bb5662ae80b2b8c06226c54b2ff4aa9483e8a13a5" ], "markers": "python_version >= '3.7'", - "version": "==3.5.0" + "version": "==3.5.1" }, "pluggy": { "hashes": [ @@ -673,11 +705,11 @@ }, "pytest-cov": { "hashes": [ - "sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b", - "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470" + "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6", + "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a" ], "index": "pypi", - "version": "==4.0.0" + "version": "==4.1.0" }, "pytest-mock": { "hashes": [ @@ -705,11 +737,11 @@ }, "requests": { "hashes": [ - "sha256:10e94cc4f3121ee6da529d358cdaeaff2f1c409cd377dbc72b825852f2f7e294", - "sha256:239d7d4458afcb28a692cdd298d87542235f4ca8d36d03a15bfc128a6559a2f4" + "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", + "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" ], "markers": "python_version >= '3.7'", - "version": "==2.30.0" + "version": "==2.31.0" }, "requests-toolbelt": { "hashes": [ @@ -800,11 +832,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb", - "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4" + "sha256:06006244c70ac8ee83fa8282cb188f697b8db25bc8b4df07be1873c43897060c", + "sha256:3a8b36f13dd5fdc5d1b16fe317f5668545de77fa0b8e02006381fd49d731ab98" ], "markers": "python_version >= '3.7'", - "version": "==4.5.0" + "version": "==4.6.2" }, "urllib3": { "hashes": [ diff --git a/integration-test.sh b/integration-test.sh index 1189019..6490a5e 100755 --- a/integration-test.sh +++ b/integration-test.sh @@ -58,9 +58,13 @@ sporestack server launch --no-quote --token realtestingtoken --operating-system sporestack server list --token realtestingtoken | grep sporestackpythonintegrationtestdelme sporestack server topup --token realtestingtoken --hostname sporestackpythonintegrationtestdelme --days 1 sporestack server info --token realtestingtoken --hostname sporestackpythonintegrationtestdelme -sporestack server json --token realtestingtoken --hostname sporestackpythonintegrationtestdelme +MACHINE_ID=$(sporestack server json --token realtestingtoken --hostname sporestackpythonintegrationtestdelme | jq -r .machine_id) sporestack server autorenew-enable --token realtestingtoken --hostname sporestackpythonintegrationtestdelme sporestack server autorenew-disable --token realtestingtoken --hostname sporestackpythonintegrationtestdelme +sporestack server update-hostname "$MACHINE_ID" --hostname "new" | grep sporestackpythonintegrationtestdelme +sporestack server update-hostname "$MACHINE_ID" --hostname "" +sporestack server update-hostname "$MACHINE_ID" --hostname "new again" | grep set +sporestack server update-hostname "$MACHINE_ID" --hostname sporestackpythonintegrationtestdelme sporestack server start --token realtestingtoken --hostname sporestackpythonintegrationtestdelme sporestack server stop --token realtestingtoken --hostname sporestackpythonintegrationtestdelme sporestack server rebuild --token realtestingtoken --hostname sporestackpythonintegrationtestdelme diff --git a/src/sporestack/__init__.py b/src/sporestack/__init__.py index dc029df..4ef034e 100644 --- a/src/sporestack/__init__.py +++ b/src/sporestack/__init__.py @@ -2,4 +2,4 @@ __all__ = ["api", "api_client", "exceptions"] -__version__ = "10.5.0" +__version__ = "10.6.0" diff --git a/src/sporestack/api.py b/src/sporestack/api.py index fd4e9d6..c537538 100644 --- a/src/sporestack/api.py +++ b/src/sporestack/api.py @@ -199,17 +199,21 @@ class TokenMessageSender(str, Enum): class TokenMessage(BaseModel): - message: str = Field( - ..., - title="Message", - min_length=1, - max_length=10_000, - ) - sent_at: datetime = Field( - ..., - title="Sent At", - description="When the message was sent.", - ) - sender: TokenMessageSender = Field( - ..., title="Sender", description="Who sent the message." - ) + message: Annotated[ + str, + Field( + title="Message", + min_length=1, + max_length=10_000, + ), + ] + sent_at: Annotated[ + datetime, + Field( + title="Sent At", + description="When the message was sent.", + ), + ] + sender: Annotated[ + TokenMessageSender, Field(title="Sender", description="Who sent the message.") + ] diff --git a/src/sporestack/api_client.py b/src/sporestack/api_client.py index bd15e50..96f5c09 100644 --- a/src/sporestack/api_client.py +++ b/src/sporestack/api_client.py @@ -7,7 +7,7 @@ import httpx from pydantic import parse_obj_as from . import __version__, api, exceptions -from .models import Invoice, TokenInfo +from .models import Invoice, ServerUpdateRequest, TokenInfo log = logging.getLogger(__name__) @@ -212,6 +212,18 @@ class APIClient: response_object = api.ServerInfo.Response.parse_obj(response.json()) return response_object + def server_update( + self, + machine_id: str, + hostname: Union[str, None] = None, + autorenew: Union[bool, None] = None, + ) -> None: + """Update server settings.""" + request = ServerUpdateRequest(hostname=hostname, autorenew=autorenew) + url = self.api_endpoint + f"/server/{machine_id}" + response = self._httpx_client.patch(url=url, json=request.dict()) + _handle_response(response) + def servers_launched_from_token( self, token: str ) -> api.ServersLaunchedFromToken.Response: diff --git a/src/sporestack/cli.py b/src/sporestack/cli.py index c1a2f0a..ec46151 100644 --- a/src/sporestack/cli.py +++ b/src/sporestack/cli.py @@ -19,6 +19,7 @@ else: # pragma: nocover if TYPE_CHECKING: from . import api + from .api_client import APIClient from .models import Invoice @@ -78,6 +79,12 @@ def get_api_endpoint() -> str: return api_endpoint +def get_api_client() -> "APIClient": + from .api_client import APIClient + + return APIClient(api_endpoint=get_api_endpoint()) + + def make_payment(invoice: "Invoice") -> None: import segno @@ -124,11 +131,9 @@ def launch( _token = load_token(token) from . import utils - from .api_client import APIClient from .client import Client - api_client = APIClient(api_endpoint=get_api_endpoint()) - client = Client(api_client=api_client, client_token=_token) + client = Client(api_client=get_api_client(), client_token=_token) typer.echo(f"Loading SSH key from {ssh_key_file}...") if not ssh_key_file.exists(): @@ -585,6 +590,27 @@ def forget( typer.echo(f"{machine_id} was forgotten.") +@server_cli.command() +def update_hostname( + machine_id: str, + hostname: Annotated[str, typer.Option()], +) -> None: + """Update a server's hostname, given its machine ID.""" + from .client import Server + + server = Server(machine_id=machine_id, api_client=get_api_client()) + + current_hostname = server.info().hostname + server.update(hostname=hostname) + if current_hostname == "": + typer.echo(f"{machine_id}'s hostname was set to {hostname}.") + else: + typer.echo( + f"{machine_id}'s hostname was updated from {current_hostname} to " + f"{hostname}." + ) + + @server_cli.command() def rebuild( hostname: str = "", machine_id: str = "", token: str = DEFAULT_TOKEN diff --git a/src/sporestack/client.py b/src/sporestack/client.py index dc11049..394b3da 100644 --- a/src/sporestack/client.py +++ b/src/sporestack/client.py @@ -22,7 +22,7 @@ class Server: self.api_client.server_rebuild(self.machine_id) def forget(self) -> None: - """Forget about the server so it doesn't show up in server listings.""" + """Forget about the server so it doesn't show up when listing servers.""" self.api_client.server_forget(self.machine_id) def delete(self) -> None: @@ -39,11 +39,19 @@ class Server: def autorenew_enable(self) -> None: """Enables autorenew on the server.""" - self.api_client.autorenew_enable(self.machine_id) + self.api_client.server_update(self.machine_id, autorenew=True) def autorenew_disable(self) -> None: """Disables autorenew on the server.""" - self.api_client.autorenew_disable(self.machine_id) + self.api_client.server_update(self.machine_id, autorenew=False) + + def update( + self, hostname: Union[str, None] = None, autorenew: Union[bool, None] = None + ) -> None: + """Update details about a server.""" + self.api_client.server_update( + self.machine_id, hostname=hostname, autorenew=autorenew + ) def topup(self, days: int) -> None: """ diff --git a/src/sporestack/models.py b/src/sporestack/models.py index 6637eac..b78f95e 100644 --- a/src/sporestack/models.py +++ b/src/sporestack/models.py @@ -126,3 +126,28 @@ class Invoice(BaseModel): ), ), ] + + +class ServerUpdateRequest(BaseModel): + hostname: Annotated[ + Union[str, None], + Field( + min_length=0, + max_length=128, + title="Hostname", + description="Hostname to refer to your server by.", + example="web-1", + regex="(^$|^[a-zA-Z0-9-_. ]+$)", + ), + ] = None + autorenew: Annotated[ + Union[bool, None], + Field( + title="Autorenew", + description=( + "Automatically renew the server from the token, " + "keeping it at 1 week expiration." + ), + example=True, + ), + ] = None diff --git a/tests/test_api_client.py b/tests/test_api_client.py index 4f161ea..cce7c89 100644 --- a/tests/test_api_client.py +++ b/tests/test_api_client.py @@ -102,3 +102,57 @@ def test_token_info(respx_mock: respx.MockRouter) -> None: assert info_response.days_remaining == 0 assert route.called + + +def test_server_info(respx_mock: respx.MockRouter) -> None: + dummy_machine_id = "dummyinvalidmachineid" + flavor = { + "slug": "a flavor slug", + "cores": 1, + "memory": 1024, + "disk": 25, + "price": 38, + "ipv4": "/32", + "ipv6": "/128", + "bandwidth_per_month": 1.0, + } + + response_json = { + "machine_id": dummy_machine_id, + "hostname": "a hostname", + "flavor": flavor, + "region": "a region", + "token": "a token", + "running": True, + "created_at": 1, + "expiration": 2, + "autorenew": False, + "ipv4": "0.0.0.0", + "ipv6": "::0", + "deleted": False, + "deleted_at": 0, + "deleted_by": None, + "forgotten_at": None, + "operating_system": "debian-11", + } + route_response = httpx.Response(200, json=response_json) + route = respx_mock.get(f"/server/{dummy_machine_id}/info").mock( + return_value=route_response + ) + + client = api_client.APIClient() + info_response = client.server_info(dummy_machine_id) + # These aren't exhaustive, but there's a number here. + assert info_response.machine_id == dummy_machine_id + assert info_response.hostname == response_json["hostname"] + assert info_response.flavor == response_json["flavor"] + assert info_response.token == response_json["token"] + assert info_response.running == response_json["running"] + assert info_response.created_at == response_json["created_at"] + assert info_response.expiration == response_json["expiration"] + assert info_response.autorenew == response_json["autorenew"] + assert info_response.forgotten_at == response_json["forgotten_at"] + # Not sure why mypy dislikes this. It passes pytest. + assert info_response.flavor.slug == response_json["flavor"]["slug"] # type: ignore + + assert route.called