diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2433251c2cae9c33c7a936a2ba4b571abb167985..1a8ca07faa427991eed05db5c4fd033bd9c0f4f8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -25,7 +25,20 @@ docker_image_push: - export CI_CUSTOM_REGISTRY_IMAGE="${CI_REGISTRY}/${CI_CUSTOM_REGISTRY_PATH}/${CI_CUSTOM_IMAGE_NAME}" - export CI_DOCKER_TAG=$(if [[ "$CI_COMMIT_TAG" == "" ]]; then echo develop; else echo $CI_COMMIT_TAG; fi) - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_CUSTOM_REGISTRY_USER\",\"password\":\"$CI_CUSTOM_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_CUSTOM_REGISTRY_IMAGE:$CI_DOCKER_TAG --build-arg KYPO_PYPI_DOWNLOAD_URL=$KYPO_PYPI_DOWNLOAD_URL + - > + if [ -z "$DJNG_ADMIN_USER" ] && [ -z "$DJNG_ADMIN_PASSWORD" ]; then + /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_CUSTOM_REGISTRY_IMAGE:$CI_DOCKER_TAG --build-arg KYPO_PYPI_DOWNLOAD_URL=$KYPO_PYPI_DOWNLOAD_URL + else + if [ -z "$DJNG_ADMIN_USER" ]; then + /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_CUSTOM_REGISTRY_IMAGE:$CI_DOCKER_TAG --build-arg KYPO_PYPI_DOWNLOAD_URL=$KYPO_PYPI_DOWNLOAD_URL --build-arg DJNG_ADMIN_PASSWORD=$DJNG_ADMIN_PASSWORD + else + if [ -z "$DJNG_ADMIN_PASSWORD" ]; then + /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_CUSTOM_REGISTRY_IMAGE:$CI_DOCKER_TAG --build-arg KYPO_PYPI_DOWNLOAD_URL=$KYPO_PYPI_DOWNLOAD_URL --build-arg DJNG_ADMIN_USER=$DJNG_ADMIN_USER + else + /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_CUSTOM_REGISTRY_IMAGE:$CI_DOCKER_TAG --build-arg KYPO_PYPI_DOWNLOAD_URL=$KYPO_PYPI_DOWNLOAD_URL --build-arg DJNG_ADMIN_USER=$DJNG_ADMIN_USER --build-arg DJNG_ADMIN_PASSWORD=$DJNG_ADMIN_PASSWORD + fi + fi + fi rules: - if: $CI_COMMIT_BRANCH == "develop" - if: $CI_COMMIT_TAG diff --git a/Dockerfile b/Dockerfile index ad934b554a732dd44db6ed1fe60d1906c2e5680e..d51cd6a02db1aa270f29f949a29947f208208e66 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,8 +18,10 @@ RUN pipenv run pip3 install gunicorn FROM python:3.8-slim as app WORKDIR /app -ENV DJANGO_ADMIN_USER "admin" -ENV DJANGO_ADMIN_PASSWORD "admin" +ARG DJNG_ADMIN_USER="admin" +ARG DJNG_ADMIN_PASSWORD="PmOn78IbUv12" +ENV DJANGO_ADMIN_USER=$DJNG_ADMIN_USER +ENV DJANGO_ADMIN_PASSWORD=$DJNG_ADMIN_PASSWORD ENV DJANGO_ADMIN_EMAIL "admin@example.com" ENV PYTHONDONTWRITEBYTECODE=1 diff --git a/Pipfile b/Pipfile index 3dcb149bb2c6eb0527f3d5934b2eacd0d5950550..6f40b73415d6b86161a1ea18fa0a183fcb88f2a3 100644 --- a/Pipfile +++ b/Pipfile @@ -21,9 +21,9 @@ pytest-django = "*" [packages] drf-oidc-auth = { index = "kypo", version = ">=2.0.1" } -csirtmu-oidc-client = { index = "kypo", version = ">=0.2.1" } +csirtmu-oidc-client = { index = "kypo", version = ">=0.3.0" } csirtmu-uag-auth = { index = "kypo", version = "==0.1.10" } -kypo-terraform-client = { index = "kypo", version = "~=0.2.2" } +kypo-terraform-client = { index = "kypo", version = "~=0.2.4" } automated-problem-generation-lib = { index = "kypo", version = ">=0.1.2" } better-profanity = "*" # tox cannot install it correctly for automated-problem-generation-lib django = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 8635df25d1289fa8f46a538428c1849b3fb8cdc8..fb0fee737e3d2973f675b047343f2aa0bae574a9 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "0bf2546bd5fb8f3206762520522d84ebe7007f38abefdede29ec927f88a64243" + "sha256": "3e6802bbe86e55498e022c84b20c62adf18bbd21a4972c32a03718a1678a8e57" }, "pipfile-spec": 6, "requires": { @@ -38,11 +38,11 @@ }, "attrs": { "hashes": [ - "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", - "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" + "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", + "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.4.0" + "markers": "python_version >= '3.5'", + "version": "==22.1.0" }, "automated-problem-generation-lib": { "hashes": [ @@ -85,66 +85,80 @@ }, "cffi": { "hashes": [ - "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3", - "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2", - "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636", - "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20", - "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728", - "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27", - "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66", - "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443", - "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0", - "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7", - "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39", - "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605", - "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a", - "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37", - "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029", - "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139", - "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc", - "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df", - "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14", - "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880", - "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2", - "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a", - "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e", - "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474", - "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024", - "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8", - "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0", - "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e", - "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a", - "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e", - "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032", - "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6", - "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e", - "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b", - "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e", - "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954", - "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962", - "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c", - "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4", - "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55", - "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962", - "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023", - "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c", - "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6", - "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8", - "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382", - "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7", - "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc", - "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997", - "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796" - ], - "version": "==1.15.0" + "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5", + "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef", + "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104", + "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426", + "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405", + "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375", + "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a", + "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e", + "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc", + "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf", + "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185", + "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497", + "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3", + "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35", + "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c", + "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83", + "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21", + "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca", + "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984", + "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac", + "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd", + "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee", + "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a", + "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2", + "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192", + "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7", + "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585", + "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f", + "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e", + "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27", + "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b", + "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e", + "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e", + "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d", + "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c", + "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415", + "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82", + "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02", + "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314", + "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325", + "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c", + "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3", + "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914", + "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045", + "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d", + "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9", + "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5", + "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2", + "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c", + "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3", + "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2", + "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8", + "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d", + "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d", + "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9", + "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162", + "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76", + "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4", + "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e", + "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9", + "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6", + "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b", + "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01", + "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0" + ], + "version": "==1.15.1" }, "charset-normalizer": { "hashes": [ - "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597", - "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df" + "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5", + "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413" ], - "markers": "python_version >= '3.5'", - "version": "==2.0.12" + "markers": "python_version >= '3.6'", + "version": "==2.1.0" }, "click": { "hashes": [ @@ -164,11 +178,11 @@ }, "cmd2": { "hashes": [ - "sha256:e6f49b0854b6aec2f20073bae99f1deede16c24b36fde682045d73c80c4cfb51", - "sha256:f3b0467daca18fca0dc7838de7726a72ab64127a018a377a86a6ed8ebfdbb25f" + "sha256:073e555c05853b0f6965f3d03329babdf9e38a5f2cea028e61a64cd7eeb74ad5", + "sha256:a77e3056751393270b4125c990cf527db132f15951a20a3a5dd2df4290aadf20" ], "markers": "python_version >= '3.6'", - "version": "==2.4.1" + "version": "==2.4.2" }, "colorama": { "hashes": [ @@ -195,38 +209,38 @@ }, "cryptography": { "hashes": [ - "sha256:093cb351031656d3ee2f4fa1be579a8c69c754cf874206be1d4cf3b542042804", - "sha256:0cc20f655157d4cfc7bada909dc5cc228211b075ba8407c46467f63597c78178", - "sha256:1b9362d34363f2c71b7853f6251219298124aa4cc2075ae2932e64c91a3e2717", - "sha256:1f3bfbd611db5cb58ca82f3deb35e83af34bb8cf06043fa61500157d50a70982", - "sha256:2bd1096476aaac820426239ab534b636c77d71af66c547b9ddcd76eb9c79e004", - "sha256:31fe38d14d2e5f787e0aecef831457da6cec68e0bb09a35835b0b44ae8b988fe", - "sha256:3b8398b3d0efc420e777c40c16764d6870bcef2eb383df9c6dbb9ffe12c64452", - "sha256:3c81599befb4d4f3d7648ed3217e00d21a9341a9a688ecdd615ff72ffbed7336", - "sha256:419c57d7b63f5ec38b1199a9521d77d7d1754eb97827bbb773162073ccd8c8d4", - "sha256:46f4c544f6557a2fefa7ac8ac7d1b17bf9b647bd20b16decc8fbcab7117fbc15", - "sha256:471e0d70201c069f74c837983189949aa0d24bb2d751b57e26e3761f2f782b8d", - "sha256:59b281eab51e1b6b6afa525af2bd93c16d49358404f814fe2c2410058623928c", - "sha256:731c8abd27693323b348518ed0e0705713a36d79fdbd969ad968fbef0979a7e0", - "sha256:95e590dd70642eb2079d280420a888190aa040ad20f19ec8c6e097e38aa29e06", - "sha256:a68254dd88021f24a68b613d8c51d5c5e74d735878b9e32cc0adf19d1f10aaf9", - "sha256:a7d5137e556cc0ea418dca6186deabe9129cee318618eb1ffecbd35bee55ddc1", - "sha256:aeaba7b5e756ea52c8861c133c596afe93dd716cbcacae23b80bc238202dc023", - "sha256:dc26bb134452081859aa21d4990474ddb7e863aa39e60d1592800a8865a702de", - "sha256:e53258e69874a306fcecb88b7534d61820db8a98655662a3dd2ec7f1afd9132f", - "sha256:ef15c2df7656763b4ff20a9bc4381d8352e6640cfeb95c2972c38ef508e75181", - "sha256:f224ad253cc9cea7568f49077007d2263efa57396a2f2f78114066fd54b5c68e", - "sha256:f8ec91983e638a9bcd75b39f1396e5c0dc2330cbd9ce4accefe68717e6779e0a" + "sha256:190f82f3e87033821828f60787cfa42bff98404483577b591429ed99bed39d59", + "sha256:2be53f9f5505673eeda5f2736bea736c40f051a739bfae2f92d18aed1eb54596", + "sha256:30788e070800fec9bbcf9faa71ea6d8068f5136f60029759fd8c3efec3c9dcb3", + "sha256:3d41b965b3380f10e4611dbae366f6dc3cefc7c9ac4e8842a806b9672ae9add5", + "sha256:4c590ec31550a724ef893c50f9a97a0c14e9c851c85621c5650d699a7b88f7ab", + "sha256:549153378611c0cca1042f20fd9c5030d37a72f634c9326e225c9f666d472884", + "sha256:63f9c17c0e2474ccbebc9302ce2f07b55b3b3fcb211ded18a42d5764f5c10a82", + "sha256:6bc95ed67b6741b2607298f9ea4932ff157e570ef456ef7ff0ef4884a134cc4b", + "sha256:7099a8d55cd49b737ffc99c17de504f2257e3787e02abe6d1a6d136574873441", + "sha256:75976c217f10d48a8b5a8de3d70c454c249e4b91851f6838a4e48b8f41eb71aa", + "sha256:7bc997818309f56c0038a33b8da5c0bfbb3f1f067f315f9abd6fc07ad359398d", + "sha256:80f49023dd13ba35f7c34072fa17f604d2f19bf0989f292cedf7ab5770b87a0b", + "sha256:91ce48d35f4e3d3f1d83e29ef4a9267246e6a3be51864a5b7d2247d5086fa99a", + "sha256:a958c52505c8adf0d3822703078580d2c0456dd1d27fabfb6f76fe63d2971cd6", + "sha256:b62439d7cd1222f3da897e9a9fe53bbf5c104fff4d60893ad1355d4c14a24157", + "sha256:b7f8dd0d4c1f21759695c05a5ec8536c12f31611541f8904083f3dc582604280", + "sha256:d204833f3c8a33bbe11eda63a54b1aad7aa7456ed769a982f21ec599ba5fa282", + "sha256:e007f052ed10cc316df59bc90fbb7ff7950d7e2919c9757fd42a2b8ecf8a5f67", + "sha256:f2dcb0b3b63afb6df7fd94ec6fbddac81b5492513f7b0436210d390c14d46ee8", + "sha256:f721d1885ecae9078c3f6bbe8a88bc0786b6e749bf32ccec1ef2b18929a05046", + "sha256:f7a6de3e98771e183645181b3627e2563dcde3ce94a9e42a3f427d2255190327", + "sha256:f8c0a6e9e1dd3eb0414ba320f85da6b0dcbd543126e30fcc546e7372a7fbf3b9" ], "index": "pypi", - "version": "==37.0.2" + "version": "==37.0.4" }, "csirtmu-oidc-client": { "hashes": [ - "sha256:5cf4e588a7c4a272c84f8e081147ee15a1272561b16585e0809a51c3496471a6" + "sha256:121d1ccfe01ecd6e2cb8867fe18c1ac0d2e5edb76d16010c9492f4204308069e" ], "index": "kypo", - "version": "==0.2.1" + "version": "==0.3.4" }, "csirtmu-uag-auth": { "hashes": [ @@ -331,11 +345,11 @@ }, "dogpile.cache": { "hashes": [ - "sha256:27725b7c9017ff706f2d5e3a6f36ac18986a90c9208efed411d23211d8d78a44", - "sha256:eedc1e327e66c93f0c15a8740569ab74ef3d8929042f108f98fded9e35faff55" + "sha256:3f0ca10b46b165e0b0e65e0e74b1a4b36187787b69db7c0f7073077adff2f05d", + "sha256:d844e8bb638cc4f544a4c89a834dfd36fe935400b71a16cbd744ebdfb720fd4e" ], "markers": "python_version >= '3.6'", - "version": "==1.1.6" + "version": "==1.1.8" }, "drf-oidc-auth": { "hashes": [ @@ -386,11 +400,11 @@ }, "google-auth": { "hashes": [ - "sha256:819b70140d05501739e1387291d39f0de3b4dff3b00ae4aff8e7a05369957f89", - "sha256:9b1da39ab8731c3061f36fefde9f8bb902dbee9eb28e3a67e8cfa7dc1be76227" + "sha256:1deba4a54f95ef67b4139eaf5c20eaa7047215eec9f6a2344599b8596db8863b", + "sha256:7904dbd44b745c7323fef29565adee2fe7ff48473e2d94443aced40b0404a395" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==2.8.0" + "version": "==2.10.0" }, "idna": { "hashes": [ @@ -400,6 +414,14 @@ "markers": "python_version >= '3.5'", "version": "==3.3" }, + "importlib-resources": { + "hashes": [ + "sha256:5481e97fb45af8dcf2f798952625591c58fe599d0735d86b10f54de086a61681", + "sha256:f78a8df21a79bcc30cfd400bdc38f314333de7c0fb619763f6b9dabab8268bb7" + ], + "markers": "python_version < '3.9'", + "version": "==5.9.0" + }, "inflection": { "hashes": [ "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417", @@ -413,7 +435,7 @@ "sha256:27f503220e6845d9db954fb212b95b0362d8b7e6c1b2326a87061c3de93594b1", "sha256:d7bc01b1c2a43b259570bb307f057abc578786ea734ba2b87b836c5efc5bd443" ], - "markers": "python_version < '4' and python_full_version >= '3.6.2'", + "markers": "python_version < '4.0' and python_full_version >= '3.6.2'", "version": "==1.0.2" }, "itypes": { @@ -457,17 +479,18 @@ }, "jsonschema": { "hashes": [ - "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163", - "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a" + "sha256:408c4c8ed0dede3b268f7a441784f74206380b04f93eb2d537c7befb3df3099f", + "sha256:8ebad55894c002585271af2d327d99339ef566fb085d9129b69e2623867c4106" ], - "version": "==3.2.0" + "markers": "python_version >= '3.7'", + "version": "==4.9.1" }, "keystoneauth1": { "hashes": [ - "sha256:066f1addd89114cd6a1b9cb3555c8eaa7d013673ee1034bdfe506068804a9e05", - "sha256:99c29492c5e53098d6a5779b3213669cfbf5c2193fb6eb95d6f000b7a2b2029b" + "sha256:249894b8a9e28df2f4a6001cf217b522c41812b0b20b153535cea56e1b2d6620", + "sha256:6ebb5f044c9dfd263087a328d51d479947d1ddc90c09daf4191df7dc71334323" ], - "version": "==4.6.0" + "version": "==5.0.0" }, "kubernetes": { "hashes": [ @@ -479,31 +502,31 @@ }, "kypo-openstack-lib": { "hashes": [ - "sha256:882ea51c365c5c02ea45841eec02b7f283b99c362f4d4238e403b73def94c058" + "sha256:c64c5e0a8e276f86f3abb7c99e837a0ffdde438060b0122936f9a9da964f6ddf" ], "markers": "python_version >= '3'", - "version": "==0.38.2" + "version": "==0.38.4" }, "kypo-python-commons": { "hashes": [ - "sha256:7fb873e29c4aaeccbcbf99b0822209fba4fc527fd7a5a7705bd065739b6f7cac" + "sha256:95cb31f11d546f321db10274f270f45b22d4af52515a7f0ca5350b63c9d1e343" ], "markers": "python_version >= '3'", - "version": "==0.1.5" + "version": "==0.1.7" }, "kypo-terraform-client": { "hashes": [ - "sha256:7a8a3b034e2aca34f10ea639d3c50fe039ec96f17b47b92ae4d0d07be4ed56ce" + "sha256:54f17237177a1eebad1687713bb52d3d6a695f4176ad368fd622d23b7f12765d" ], "index": "kypo", - "version": "==0.2.2" + "version": "==0.2.5" }, "kypo-topology-definition": { "hashes": [ - "sha256:e1318414df115de00b8b0526d86b77721792038a37a41459b43ab1b232f6f7a1" + "sha256:b88773ebb200bece4ed3c7330d1d64643f45f3faccacd60d952272c15cf5779d" ], "markers": "python_version >= '3'", - "version": "==0.5.1" + "version": "==0.5.2" }, "markupsafe": { "hashes": [ @@ -667,11 +690,11 @@ }, "openstacksdk": { "hashes": [ - "sha256:2c8af1ff416d33e5c3f184a42f2088808fb3bf4f9560b7682d31ec94110f6a16", - "sha256:3f73c3cc28089e93b342eb7f348b285f5a65ffe505898be15db250c75bb855eb" + "sha256:013f560dda31b56e6c1a22f487d9f8cbfdf1bc295c0e88753774c55478cf0747", + "sha256:310f319a04ee1bd99684805ef2c9a8c01d75568c03085a97089035495e2bad7d" ], "markers": "python_version >= '3.6'", - "version": "==0.99.0" + "version": "==0.100.0" }, "ordered-set": { "hashes": [ @@ -697,27 +720,27 @@ }, "osc-lib": { "hashes": [ - "sha256:2a03f69fad9c9bc9bdd75292907c6a2f3de570b22c5afd13b0118e920f4ba0a6", - "sha256:854eabb14ad3480f4cdc63a55944e0ce2d9cc4ce2683cdfddadcd149821e67ab" + "sha256:3a3b8c30af11c158e61ff8e5936556a5c4fca3abae5f08d0185e1f50beb03b5f", + "sha256:3c3ccc358c61a0ba48391480486ce6c18d6591f6325abe75d04ee5968a49718b" ], "markers": "python_version >= '3.6'", - "version": "==2.6.0" + "version": "==2.6.1" }, "oslo.config": { "hashes": [ - "sha256:96933d3011dae15608a11616bfb00d947e22da3cb09b6ff37ddd7576abd4764c", - "sha256:b1e2a398450ea35a8e5630d8b23057b8939838c4433cd25a20cc3a36d5df9e3b" + "sha256:3b6b63c43cf1e09344ba850bcb11d6f2b9201086fbeb0a97a8950e7eac3f2645", + "sha256:f876bf759f186c854c71417b83b44ba68d69b11ed3a79c324c7737a0bfc962f1" ], - "markers": "python_version >= '3.6'", - "version": "==8.8.0" + "markers": "python_version >= '3.8'", + "version": "==9.0.0" }, "oslo.context": { "hashes": [ - "sha256:75a9a722a552fba8a89e8a01028fa82a6190ab317a9591bb83303a2210a79144", - "sha256:a0cf84fe7970cc070a821c1a88dc66dfceb81233a93f137a3715108804c7b9d5" + "sha256:88c0c6d076681c60d560f7d66565e42ac116c5aa8a28a04db7c0ac0025133224", + "sha256:e325ade501b9533de1cf1fd96597dbf83406f3986d874ad9a8f5db9c2cc4a965" ], - "markers": "python_version >= '3.6'", - "version": "==4.1.0" + "markers": "python_version >= '3.8'", + "version": "==5.0.0" }, "oslo.i18n": { "hashes": [ @@ -737,11 +760,11 @@ }, "oslo.serialization": { "hashes": [ - "sha256:3aa472f434aee8bbcc0725312b7f409aa1fa54bbc134904124cf49b0e86b9115", - "sha256:6c1c483231c3827787af9b6ca4a45f4e45fe364772a24692b02de78fe48eafb1" + "sha256:2845328d0f47dc8a23fed2a82253e90acff0aa731dbd24f379cf8e50e6cc66ba", + "sha256:b0452bb2fcb99ee3e11bce3e1163f25a6393681233d2b3c2abdc4e5efd49d2a3" ], - "markers": "python_version >= '3.6'", - "version": "==4.3.0" + "markers": "python_version >= '3.8'", + "version": "==5.0.0" }, "oslo.utils": { "hashes": [ @@ -767,6 +790,14 @@ "markers": "python_version >= '2.6'", "version": "==5.9.0" }, + "pkgutil-resolve-name": { + "hashes": [ + "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174", + "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e" + ], + "markers": "python_version < '3.9'", + "version": "==1.3.10" + }, "prettytable": { "hashes": [ "sha256:118eb54fd2794049b810893653b20952349df6d3bc1764e7facd8a18064fa9b0", @@ -1003,35 +1034,35 @@ }, "python-gitlab": { "hashes": [ - "sha256:29ae7fb9b8c9aeb2e6e19bd2fd04867e93ecd7af719978ce68fac0cf116ab30d", - "sha256:73b5aa6502efa557ee1a51227cceb0243fac5529627da34f08c5f265bf50417c" + "sha256:08ccb2d2db6882bca76e370b0b7fee724e978b1e0de2970f1a704fa451bbcfa0", + "sha256:a6c26e5fa9f211d711b15b7e151d8667d8dd9a6194038c3ae81160d2c2f0b25c" ], "index": "pypi", - "version": "==3.5.0" + "version": "==3.8.0" }, "python-glanceclient": { "hashes": [ - "sha256:6b7b452e648ab9a29b050cb7d84914eec3c8110b4de60683aa8193d378246bec", - "sha256:cdb28c976f4b9a9f7ded56f38bd8f3185e54593ed98a2675b21b7eb91fb77cd3" + "sha256:767bf12449a5b7ff4c46b3f34908ea7a7f0802fb817692361a5a133f143fcd4f", + "sha256:a5f42722fad9170d7a79117690fc66b615a963ba96901bbd4946af4275cef334" ], "markers": "python_version >= '3.8'", - "version": "==4.0.0" + "version": "==4.0.1" }, "python-keystoneclient": { "hashes": [ - "sha256:5bad91bda4f6f5658e1e03daa2f19f4cdc6c1f1b611afacca9ca1a3ace2ab99a", - "sha256:6d7f05c692e7db2692778284c779ae6cea8b2159914b4417a5fa0bfea1e29cdc" + "sha256:0f50da33bf20b55acfc59d4f9460fa2efc1be15fd05ec3f23674d03eba2bea3f", + "sha256:f650d3fbe94b069bba0aafd07fc2681c62263acddc2a57bb7fddb42d2b1ef5f4" ], - "markers": "python_version >= '3.6'", - "version": "==4.5.0" + "markers": "python_version >= '3.8'", + "version": "==5.0.0" }, "python-neutronclient": { "hashes": [ - "sha256:9bc66b2952912c2ba298d4c8492db897a5eafcb0ecf757e37baa691b70b47b4e", - "sha256:9e66734a2d4a4669f85b04a2d0ff9ae8b9310af2f00f024df69c92a828b2c338" + "sha256:20e09e5d832fa8d90b2c88cd07550af599b49481be731094f07664f086a0ec60", + "sha256:f54cbfde73406a80aae540921c045408faccbd1eb015f35ac112cea3019269fb" ], - "markers": "python_version >= '3.6'", - "version": "==7.8.0" + "markers": "python_version >= '3.8'", + "version": "==8.0.0" }, "python-novaclient": { "hashes": [ @@ -1089,19 +1120,19 @@ }, "redis": { "hashes": [ - "sha256:2f7a57cf4af15cd543c4394bcbe2b9148db2606a37edba755368836e3a1d053e", - "sha256:f57f8df5d238a8ecf92f499b6b21467bfee6c13d89953c27edf1e2bc673622e7" + "sha256:a52d5694c9eb4292770084fa8c863f79367ca19884b329ab574d5cb2036b3e54", + "sha256:ddf27071df4adf3821c4f2ca59d67525c3a82e5f268bed97b813cb4fabf87880" ], "index": "pypi", - "version": "==4.3.3" + "version": "==4.3.4" }, "requests": { "hashes": [ - "sha256:bc7861137fbce630f17b03d3ad02ad0bf978c844f3536d0edda6499dafce2b6f", - "sha256:d568723a7ebd25875d8d1eaf5dfa068cd2fc8194b2e483d7b1f7c81918dbec6b" + "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983", + "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349" ], "index": "pypi", - "version": "==2.28.0" + "version": "==2.28.1" }, "requests-oauthlib": { "hashes": [ @@ -1135,19 +1166,19 @@ }, "rq": { "hashes": [ - "sha256:62d06b44c3acfa5d1933c5a4ec3fbc2484144a8af60e318d0b8447c5236271e2", - "sha256:92f4cf38b2364c1697b541e77c0fe62b7e5242fa864324f262be126ee2a07e3a" + "sha256:50d0cf687cfb2530eac9396c7426e420958a166e8f4666bd2096bdcf7f4ad03e", + "sha256:c0bbf898b56817da053cdc992ab46da2729a7ccd70dd50316ad9209b7d7b71c1" ], "index": "pypi", - "version": "==1.10.1" + "version": "==1.11.0" }, "rsa": { "hashes": [ - "sha256:5c6bd9dc7a543b7fe4304a631f8a8a3b674e2bbfc49c2ae96200cdbe55df6b17", - "sha256:95c5d300c4e879ee69708c428ba566c59478fd653cc3a22243eeb8ed846950bb" + "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7", + "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21" ], "markers": "python_version >= '3.6'", - "version": "==4.8" + "version": "==4.9" }, "ruamel.yaml": { "hashes": [ @@ -1190,11 +1221,11 @@ }, "setuptools": { "hashes": [ - "sha256:990a4f7861b31532871ab72331e755b5f14efbe52d336ea7f6118144dd478741", - "sha256:c1848f654aea2e3526d17fc3ce6aeaa5e7e24e66e645b5be2171f3f6b4e5a178" + "sha256:73bfae4791da7c1c56882ab17577d00f7a37a0347162aeb9360058de0dc25083", + "sha256:abcb76aa4decd7a17cbe0e4b31bdf549d106ba7f668e87e0860f5f7b84b9b3fe" ], "markers": "python_version >= '3.7'", - "version": "==62.6.0" + "version": "==63.4.2" }, "simplejson": { "hashes": [ @@ -1297,19 +1328,19 @@ }, "stevedore": { "hashes": [ - "sha256:a547de73308fd7e90075bb4d301405bebf705292fa90a90fc3bcf9133f58616c", - "sha256:f40253887d8712eaa2bb0ea3830374416736dc8ec0e22f5a65092c1174c44335" + "sha256:87e4d27fe96d0d7e4fc24f0cbe3463baae4ec51e81d95fbe60d2474636e0c7d8", + "sha256:f82cc99a1ff552310d19c379827c2c64dd9f85a38bcd5559db2470161867b786" ], - "markers": "python_version >= '3.6'", - "version": "==3.5.0" + "markers": "python_version >= '3.8'", + "version": "==4.0.0" }, "structlog": { "hashes": [ - "sha256:68c4c29c003714fe86834f347cb107452847ba52414390a7ee583472bde00fc9", - "sha256:fd7922e195262b337da85c2a91c84be94ccab1f8fd1957bd6986f6904e3761c8" + "sha256:760d37b8839bd4fe1747bed7b80f7f4de160078405f4b6a1db9270ccbfce6c30", + "sha256:94b29b1d62b2659db154f67a9379ec1770183933d6115d21f21aa25cfc9a7393" ], "index": "pypi", - "version": "==21.5.0" + "version": "==22.1.0" }, "texttable": { "hashes": [ @@ -1328,17 +1359,19 @@ }, "urllib3": { "hashes": [ - "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14", - "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e" + "sha256:c33ccba33c819596124764c23a97d25f32b28433ba0dedeb77d873a38722c9bc", + "sha256:ea6e8fb210b19d950fab93b60c9009226c63a28808bc8386e05301e25883ac0a" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", - "version": "==1.26.9" + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5' and python_version < '4.0'", + "version": "==1.26.11" }, "warlock": { "hashes": [ - "sha256:a093c4d04b42b7907f69086e476a766b7639dca50d95edc83aef6aeab9db2090" + "sha256:448df959cec31904f686ac8c6b1dfab80f0cdabce3d303be517dd433eeebf012", + "sha256:99abbf9525b2a77f2cde896d3a9f18a5b4590db063db65e08207694d2e0137fc" ], - "version": "==1.3.3" + "markers": "python_version >= '3.7' and python_version < '4.0'", + "version": "==2.0.1" }, "wcwidth": { "hashes": [ @@ -1431,23 +1464,31 @@ "sha256:e925d4c2da00de5c74ffe1babdd774427bc5adb0389f3be6abb31f5380b59b10" ], "version": "==0.7.1" + }, + "zipp": { + "hashes": [ + "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2", + "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009" + ], + "markers": "python_version < '3.10'", + "version": "==3.8.1" } }, "develop": { "attrs": { "hashes": [ - "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4", - "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd" + "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6", + "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==21.4.0" + "markers": "python_version >= '3.5'", + "version": "==22.1.0" }, "distlib": { "hashes": [ - "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b", - "sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579" + "sha256:a7f75737c70be3b25e2bee06288cec4e4c221de18455b2dd037fe2a795cab2fe", + "sha256:b710088c59f06338ca514800ad795a132da19fda270e3ce4affc74abf955a26c" ], - "version": "==0.3.4" + "version": "==0.3.5" }, "filelock": { "hashes": [ @@ -1522,11 +1563,11 @@ }, "pytest-mock": { "hashes": [ - "sha256:2c6d756d5d3bf98e2e80797a959ca7f81f479e7d1f5f571611b0fdd6d1745240", - "sha256:d989f11ca4a84479e288b0cd1e6769d6ad0d3d7743dcc75e460d1416a5f2135a" + "sha256:77f03f4554392558700295e05aed0b1096a20d4a60a4f3ddcde58b0c31c8fca2", + "sha256:8a9e226d6c0ef09fcf20c94eb3405c388af438a90f3e39687f84166da82d5948" ], "index": "pypi", - "version": "==3.8.1" + "version": "==3.8.2" }, "six": { "hashes": [ @@ -1554,19 +1595,19 @@ }, "tox": { "hashes": [ - "sha256:0805727eb4d6b049de304977dfc9ce315a1938e6619c3ab9f38682bb04662a5a", - "sha256:37888f3092aa4e9f835fc8cc6dadbaaa0782651c41ef359e3a5743fcb0308160" + "sha256:c138327815f53bc6da4fe56baec5f25f00622ae69ef3fe4e1e385720e22486f9", + "sha256:c38e15f4733683a9cc0129fba078633e07eb0961f550a010ada879e95fb32632" ], "index": "pypi", - "version": "==3.25.0" + "version": "==3.25.1" }, "virtualenv": { "hashes": [ - "sha256:4c44b1d77ca81f8368e2d7414f9b20c428ad16b343ac6d226206c5b84e2b4fcc", - "sha256:804cce4de5b8a322f099897e308eecc8f6e2951f1a8e7e2b3598dff865f01336" + "sha256:4193b7bc8a6cd23e4eb251ac64f29b4398ab2c233531e66e40b19a6b7b0d30c1", + "sha256:d86ea0bb50e06252d79e6c241507cb904fcd66090c3271381372d6221a3970f9" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==20.15.0" + "markers": "python_version >= '3.6'", + "version": "==20.16.3" } } } diff --git a/README.md b/README.md index 6d2652348bc63a4ad4b4b232b613f8d64d5c1c94..bd49960ca8714d82d47050c17d6081b799b76462 100644 --- a/README.md +++ b/README.md @@ -33,3 +33,5 @@ Documentation found in this ## Wiki The wiki with documentation to this project: [KYPO Sandbox Service wiki](https://gitlab.ics.muni.cz/kypo-crp/backend-python/kypo-sandbox-service/-/wikis/home) +## Deployment +When a change to develop branch occurs, the repository is built into an image with the name *develop* that is then uploaded to the artifact repository. If a new tag is made from master, the image with the name of the tag is built and uploaded. The service comes with an admin account that can be used to access the admin panel. The default credentials are admin - PmOn78IbUv12. This can be changed for every build by setting DJNG_ADMIN_USER and DJNG_ADMIN_PASSWORD gitlab variables before building the image. diff --git a/config.yml b/config.yml index ca6bf475486ea7c21b3d0c4e3487924116967534..932455311dbd86d3812ead88a20408de44739f06 100644 --- a/config.yml +++ b/config.yml @@ -8,6 +8,10 @@ # SECURITY WARNING: don't run with debug turned on in production! debug: True +# A secret key used by django to provide cryptographic signing. +# SECURITY WARNING: change this key for production environment and keep it secret! +#django_secret_key: "-^mu0=6s@*x4jdbrz5yr!++p*02#%m$_4&0uw8h1)&r5u!v=12" + # A list of strings representing the host/domain names that this Django site can serve. #allowed_hosts: [] diff --git a/kypo/sandbox_ansible_app/lib/container.py b/kypo/sandbox_ansible_app/lib/container.py index 8817839474701c8bc9a475d5f1d622d9c64c3062..af59a3242b571cf02fe277d3545585071bbda2bd 100644 --- a/kypo/sandbox_ansible_app/lib/container.py +++ b/kypo/sandbox_ansible_app/lib/container.py @@ -287,15 +287,17 @@ class KubernetesContainer(BaseContainer): w = watch.Watch() pod_name = self._wait_for_pod_start() - for log in w.stream(self.CORE_API.read_namespaced_pod_log, name=pod_name, - namespace=self.KUBERNETES_NAMESPACE, _preload_content=False): - self.output_class.objects.create(**self.stage_info, content=log) - job = self.BATCH_API.read_namespaced_job_status(name=self.job_name, - namespace=self.KUBERNETES_NAMESPACE) - if job.status.succeeded or job.status.failed: - w.stop() - break - + job_done = False + while not job_done: + for log in w.stream(self.CORE_API.read_namespaced_pod_log, name=pod_name, + namespace=self.KUBERNETES_NAMESPACE, _preload_content=False): + self.output_class.objects.create(**self.stage_info, content=log) + job = self.BATCH_API.read_namespaced_job_status(name=self.job_name, + namespace=self.KUBERNETES_NAMESPACE) + if job.status.succeeded or job.status.failed: + job_done = True + w.stop() + break self._save_pod_outputs(pod_name) def check_container_status(self): diff --git a/kypo/sandbox_common_lib/kypo_service_config.py b/kypo/sandbox_common_lib/kypo_service_config.py index 9150636e2af434d43fa42b9f66a0931e9444a95e..465277866bb27245db10e63aca1f682f2c4929dc 100644 --- a/kypo/sandbox_common_lib/kypo_service_config.py +++ b/kypo/sandbox_common_lib/kypo_service_config.py @@ -11,6 +11,7 @@ from kypo.sandbox_common_lib.kypo_config import KypoConfiguration STACK_NAME_PREFIX = 'default0' MICROSERVICE_NAME = 'kypo-sandbox-service' DEBUG = True +DJANGO_SECRET_KEY = '-^mu0=6s@*x4jdbrz5yr!++p*02#%m$_4&0uw8h1)&r5u!v=12' ALLOWED_HOSTS = ['*'] # Allow everyone CORS_ORIGIN_ALLOW_ALL = True CORS_ORIGIN_WHITELIST = [] @@ -47,6 +48,7 @@ class KypoServiceConfig(Object): validator=stack_name_prefix_validator) microservice_name = Attribute(type=str, default=MICROSERVICE_NAME) debug = Attribute(type=bool, default=DEBUG) + django_secret_key = Attribute(type=str, default=DJANGO_SECRET_KEY) allowed_hosts = Attribute(type=StrList, default=tuple(ALLOWED_HOSTS)) cors_origin_allow_all = Attribute(type=bool, default=CORS_ORIGIN_ALLOW_ALL) cors_origin_whitelist = Attribute(type=StrList, default=tuple(CORS_ORIGIN_WHITELIST)) diff --git a/kypo/sandbox_instance_app/lib/nodes.py b/kypo/sandbox_instance_app/lib/nodes.py index c6c709eca91f3b1b1826ffbac69c0496b31eb38c..414ecca7ded7735a5e86fddf140ec40271c27dca 100644 --- a/kypo/sandbox_instance_app/lib/nodes.py +++ b/kypo/sandbox_instance_app/lib/nodes.py @@ -1,13 +1,19 @@ """ VM Service module for VM management. """ +import django_rq from django.conf import settings +from django.core.cache import cache from kypo.terraform_driver import TerraformInstance from kypo.sandbox_instance_app.models import Sandbox from kypo.sandbox_common_lib import utils, exceptions +CACHE_CONSOLE_PREFIX = "console-" +CACHE_CONSOLE_TIMEOUT = 7200 # the console URLs can last for about 2-3 hours +CACHE_JOB_WORKER_TIME = 300 + def node_action(sandbox: Sandbox, node_name: str, action: str) -> None: """Perform action on given node.""" @@ -28,8 +34,27 @@ def get_node(sandbox: Sandbox, node_name: str) -> TerraformInstance: return client.get_node(sandbox.allocation_unit.get_stack_name(), node_name) +def get_console_url_job(stack_name, node_name, console_type, console_cache_name, + job_cache_id_running): + client = utils.get_terraform_client() + console_url = client.get_console_url(stack_name, node_name, console_type) + cache.set(console_cache_name, console_url, CACHE_CONSOLE_TIMEOUT) + cache.delete(job_cache_id_running) + + def get_console_url(sandbox: Sandbox, node_name: str) -> str: """Get console URL for given VM.""" - client = utils.get_terraform_client() - return client.get_console_url(sandbox.allocation_unit.get_stack_name(), node_name, - settings.KYPO_CONFIG.os_console_type.value) + console_cache_name = CACHE_CONSOLE_PREFIX + str(sandbox.id) + '-' + node_name + job_cache_id_running = CACHE_CONSOLE_PREFIX + str(sandbox.id) + '-' + node_name + '-running' + console_url = cache.get(console_cache_name, None) + if console_url: + return console_url + + job_running = cache.get(job_cache_id_running, False) + if not job_running: + cache.set(job_cache_id_running, True, CACHE_JOB_WORKER_TIME) + django_rq.enqueue(get_console_url_job, sandbox.allocation_unit.get_stack_name(), + node_name, settings.KYPO_CONFIG.os_console_type.value, console_cache_name, + job_cache_id_running) + return "" + diff --git a/kypo/sandbox_instance_app/lib/pools.py b/kypo/sandbox_instance_app/lib/pools.py index 49b7a95d353406d5a4917af2a88ca6e78e634b5a..e7c1c1dfcad17b4f696bfbd5ec3e64cb9e60d278 100644 --- a/kypo/sandbox_instance_app/lib/pools.py +++ b/kypo/sandbox_instance_app/lib/pools.py @@ -26,6 +26,7 @@ from kypo.cloud_commons import KypoException, InvalidTopologyDefinition,\ LOG = structlog.get_logger() POOL_CACHE_TIMEOUT = None +PROJECT_LIMITS_CACHE_IDENTIFIER = 'project-limits' POOL_CACHE_PREFIX = "hardware-usage-pool-{}" @@ -254,16 +255,26 @@ def get_hardware_usage_of_sandbox(pool: Pool) -> Optional[HardwareUsage]: """ # sentinel object is used to differentiate between stored None and cache miss sentinel = object() - hardware_usage_cached = cache.get(get_cache_key(pool), sentinel) definition = pool.definition - if hardware_usage_cached is not sentinel: - return hardware_usage_cached + hardware_usage = cache.get(get_cache_key(pool), sentinel) + if hardware_usage is sentinel: + hardware_usage = _get_hardware_usage(definition.url, definition.rev) + + limits = cache.get(PROJECT_LIMITS_CACHE_IDENTIFIER, sentinel) + if limits is sentinel: + client = utils.get_terraform_client() + limits = client.get_project_limits() + + hardware_usage_pool = hardware_usage + if hardware_usage_pool: + hardware_usage_pool *= get_pool_size(pool) + hardware_usage_pool /= limits - hardware_usage = _get_hardware_usage(definition.url, definition.rev) cache.set(get_cache_key(pool), hardware_usage, POOL_CACHE_TIMEOUT) + cache.set(PROJECT_LIMITS_CACHE_IDENTIFIER, limits, POOL_CACHE_TIMEOUT) - return hardware_usage + return hardware_usage_pool def get_cache_key(pool: Pool) -> str: diff --git a/kypo/sandbox_instance_app/serializers.py b/kypo/sandbox_instance_app/serializers.py index b3944e9904e7175dde5c396bd8e9687bfc72be76..3417a796784a10b0476889a78b513daf06fd2052 100644 --- a/kypo/sandbox_instance_app/serializers.py +++ b/kypo/sandbox_instance_app/serializers.py @@ -12,6 +12,7 @@ from rest_framework import serializers from kypo.sandbox_common_lib.serializers import UserSerializer from kypo.sandbox_definition_app.models import Definition +from kypo.sandbox_definition_app.serializers import DefinitionSerializer from kypo.sandbox_instance_app import models from kypo.sandbox_instance_app.lib import pools, requests from kypo.sandbox_cloud_app import serializers as cloud_serializers @@ -21,17 +22,17 @@ class PoolSerializer(serializers.ModelSerializer): size = serializers.SerializerMethodField( help_text="Number of allocation units associated with this pool.") lock_id = serializers.SerializerMethodField() - definition_id = serializers.PrimaryKeyRelatedField( - source='definition', queryset=Definition.objects.all() - ) + definition = serializers.SerializerMethodField() + definition_id = serializers.PrimaryKeyRelatedField(source='definition', queryset=Definition.objects.all(), write_only=True) created_by = serializers.SerializerMethodField() hardware_usage = serializers.SerializerMethodField() class Meta: model = models.Pool fields = ('id', 'definition_id', 'size', 'max_size', 'lock_id', 'rev', 'rev_sha', - 'created_by', 'hardware_usage') - read_only_fields = ('id', 'size', 'lock', 'rev', 'rev_sha', 'created_by', 'hardware_usage') + 'created_by', 'hardware_usage', 'definition') + read_only_fields = ('id', 'size', 'lock', 'rev', 'rev_sha', 'created_by', 'hardware_usage', + 'definition') @staticmethod def validate_max_size(value): @@ -58,8 +59,13 @@ class PoolSerializer(serializers.ModelSerializer): hardware_usage = pools.get_hardware_usage_of_sandbox(obj) return HardwareUsageSerializer(hardware_usage).data + @staticmethod + def get_definition(obj: models.Pool): + return DefinitionSerializer(obj.definition).data + class PoolSerializerCreate(PoolSerializer): + class Meta(PoolSerializer.Meta): read_only_fields = ('id', 'size') @@ -97,16 +103,22 @@ class SandboxAllocationUnitSerializer(serializers.ModelSerializer): cleanup_request = CleanupRequestSerializer() pool_id = serializers.PrimaryKeyRelatedField(source='pool', read_only=True) created_by = serializers.SerializerMethodField() + locked = serializers.SerializerMethodField() class Meta: model = models.SandboxAllocationUnit - fields = ('id', 'pool_id', 'allocation_request', 'cleanup_request', 'created_by') - read_only_fields = ('id', 'pool_id', 'allocation_request', 'cleanup_request', 'created_by') + fields = ('id', 'pool_id', 'allocation_request', 'cleanup_request', 'created_by', 'locked') + read_only_fields = ('id', 'pool_id', 'allocation_request', 'cleanup_request', 'created_by', + 'locked') @staticmethod def get_created_by(obj: models.SandboxAllocationUnit): return UserSerializer(obj.created_by).data + @staticmethod + def get_locked(obj: models.SandboxAllocationUnit): + return hasattr(obj, 'sandbox') and hasattr(obj.sandbox, 'lock') + class SandboxAllocationUnitIdListSerializer(serializers.Serializer): unit_ids = serializers.ListField(child=serializers.IntegerField()) @@ -260,9 +272,9 @@ class SandboxResourceSerializer(serializers.Serializer): class HardwareUsageSerializer(serializers.Serializer): - vcpu = serializers.FloatField() - ram = serializers.FloatField() - instances = serializers.FloatField() - network = serializers.FloatField() - subnet = serializers.FloatField() - port = serializers.FloatField() + vcpu = serializers.DecimalField(decimal_places=3, max_digits=2) + ram = serializers.DecimalField(decimal_places=3, max_digits=2) + instances = serializers.DecimalField(decimal_places=3, max_digits=2) + network = serializers.DecimalField(decimal_places=3, max_digits=2) + subnet = serializers.DecimalField(decimal_places=3, max_digits=2) + port = serializers.DecimalField(decimal_places=3, max_digits=2) diff --git a/kypo/sandbox_instance_app/tests/test_pools.py b/kypo/sandbox_instance_app/tests/test_pools.py index 9d2c3780c003cb5f80717e7bbf36ba7cf32e1095..fc4e17c8c11d1b7a417fbcdefd8fff2fbba73a5a 100644 --- a/kypo/sandbox_instance_app/tests/test_pools.py +++ b/kypo/sandbox_instance_app/tests/test_pools.py @@ -11,7 +11,7 @@ from kypo.sandbox_instance_app.lib import pools, sshconfig from kypo.sandbox_instance_app.models import SandboxAllocationUnit, Sandbox from kypo.sandbox_instance_app.views import PoolListCreateView -from kypo.cloud_commons import exceptions +from kypo.cloud_commons import exceptions, HardwareUsage pytestmark = pytest.mark.django_db @@ -51,7 +51,9 @@ class TestCreatePool: max_size=-10), created_by=created_by) def test_pool_views(self, mocker): - mocker.patch("kypo.sandbox_instance_app.lib.pools.get_hardware_usage_of_sandbox") + mocker.patch("kypo.sandbox_instance_app.lib.pools.get_hardware_usage_of_sandbox", + return_value=HardwareUsage(**{'vcpu': 0.0, 'ram': 0.0, 'instances': 0.0, + 'network': 0.0, 'subnet': 0.0, 'port': 0.0})) request = self.arf.get(reverse('pool-list')) response = PoolListCreateView.as_view()(request) assert len(response.data['results']) == 2 diff --git a/kypo/sandbox_instance_app/urls.py b/kypo/sandbox_instance_app/urls.py index 798da73b1a329ff982aeb2a06f311124186a44d6..7cc212a206b8c0da598f9dc30d83e9168b1473a2 100644 --- a/kypo/sandbox_instance_app/urls.py +++ b/kypo/sandbox_instance_app/urls.py @@ -15,6 +15,10 @@ urlpatterns = [ name='pool-allocation-request-list'), path('pools/<int:pool_id>/cleanup-requests', views.PoolCleanupRequestsListCreateView.as_view(), name='pool-cleanup-request-list'), + path('pools/<int:pool_id>/cleanup-failed', views.PoolCleanupRequestFailedCreateView.as_view(), + name='pool-cleanup-request-failed'), + path('pools/<int:pool_id>/cleanup-unlocked', views.PoolCleanupRequestUnlockedCreateView.as_view(), + name='pool-cleanup-request-unlocked'), path('pools/<int:pool_id>/variables', views.PoolVariablesView.as_view(), name='pool-variables'), @@ -30,6 +34,9 @@ urlpatterns = [ views.SandboxCleanupRequestView.as_view(), name='sandbox-cleanup-request'), path('sandbox-allocation-units/<int:unit_id>/allocation-stages/restart', views.SandboxAllocationStagesRestartView.as_view(), name='allocation-stages-restart'), + path('sandbox-allocation-units/<int:unit_id>/lock', + views.SandboxAllocationUnitLockRetrieveCreateDestroyView.as_view(), + name='sandbox-lock-detail-create-destroy'), # Allocation request path('allocation-requests/<request_id>', @@ -65,10 +72,6 @@ urlpatterns = [ # Sandboxes path('sandboxes/<int:sandbox_id>', views.SandboxDetailView.as_view(), name='sandbox-detail'), - path('sandboxes/<int:sandbox_id>/locks', views.SandboxLockListCreateView.as_view(), - name='sandbox-lock-list'), - path('sandboxes/<int:sandbox_id>/locks/<int:lock_id>', - views.SandboxLockDetailDestroyView.as_view(), name='sandbox-lock-detail'), path('sandboxes/<int:sandbox_id>/topology', views.SandboxTopologyView.as_view(), name='sandbox-topology'), diff --git a/kypo/sandbox_instance_app/views.py b/kypo/sandbox_instance_app/views.py index 8e779034878a67f8e50c3a70b48d0e234ef3d004..d6cb8a775ef7177548490ef3b4402f191295e9b1 100644 --- a/kypo/sandbox_instance_app/views.py +++ b/kypo/sandbox_instance_app/views.py @@ -36,9 +36,9 @@ class PoolListCreateView(generics.ListCreateAPIView): def post(self, request, *args, **kwargs): """Creates new pool. - Also creates a new key-pair in OpenStack for this pool. - It is then used as management key for this pool. That means that - the management key-pair is the same for each sandbox in the pool. + Also creates a new key-pair and certificate, which is then passed to terraform client. + The key is then used as management key for this pool, which means that the management + key-pair is the same for each sandbox in the pool. """ created_by = None if isinstance(request.user, AnonymousUser) else request.user pool = pools.create_pool(request.data, created_by) @@ -140,22 +140,56 @@ class PoolCleanupRequestsListCreateView(generics.ListCreateAPIView): openapi.Parameter('force', openapi.IN_QUERY, description="Force the deletion of sandboxes", type=openapi.TYPE_BOOLEAN, default=False), - ], - request_body=serializers.SandboxAllocationUnitIdListSerializer) + ]) def post(self, request, *args, **kwargs): """Deletes multiple sandboxes. With an optional parameter *force*, it forces the deletion.""" pool_id = kwargs.get('pool_id') get_object_or_404(Pool, pk=pool_id) - pool_units = SandboxAllocationUnit.objects.filter( - pool_id=pool_id) - unit_ids = request.data.get('unit_ids') + pool_units = SandboxAllocationUnit.objects.filter(pool_id=pool_id) + force = request.GET.get('force', 'false') == 'true' + cleanup_requests = sandbox_requests.create_cleanup_requests(pool_units, force) + serializer = serializers.CleanupRequestSerializer(cleanup_requests, many=True) + return Response(serializer.data, status=status.HTTP_202_ACCEPTED) + + +class PoolCleanupRequestUnlockedCreateView(APIView): + @swagger_auto_schema( + manual_parameters=[ + openapi.Parameter('force', openapi.IN_QUERY, + description="Force the deletion of sandboxes", + type=openapi.TYPE_BOOLEAN, default=False), + ]) + def post(self, request, *args, **kwargs): + """Deletes all unlocked sandboxes in a pool. With an optional parameter *force*, it forces + the deletion.""" + pool_id = kwargs.get('pool_id') + get_object_or_404(Pool, pk=pool_id) + pool_units = SandboxAllocationUnit.objects.filter(pool_id=pool_id) + pool_units = [unit for unit in pool_units if hasattr(unit, 'sandbox') and + not hasattr(unit.sandbox, "lock")] force = request.GET.get('force', 'false') == 'true' - units_to_cleanup = SandboxAllocationUnit.objects.filter(id__in=unit_ids) if len(unit_ids) \ - else pool_units - units_to_cleanup = [allocation_unit for allocation_unit in units_to_cleanup - if allocation_unit in pool_units] - cleanup_requests = sandbox_requests.create_cleanup_requests(units_to_cleanup, force) + cleanup_requests = sandbox_requests.create_cleanup_requests(pool_units, force) + serializer = serializers.CleanupRequestSerializer(cleanup_requests, many=True) + return Response(serializer.data, status=status.HTTP_202_ACCEPTED) + + +class PoolCleanupRequestFailedCreateView(APIView): + @swagger_auto_schema( + manual_parameters=[ + openapi.Parameter('force', openapi.IN_QUERY, + description="Force the deletion of sandboxes", + type=openapi.TYPE_BOOLEAN, default=False), + ]) + def post(self, request, *args, **kwargs): + """Deletes all failed sandboxes in a pool. With an optional parameter *force*, it forces + the deletion.""" + pool_id = kwargs.get('pool_id') + get_object_or_404(Pool, pk=pool_id) + pool_units = SandboxAllocationUnit.objects.filter(pool_id=pool_id) + force = request.GET.get('force', 'false') == 'true' + pool_units = [unit for unit in pool_units if unit.allocation_request.stages.filter(failed=True).count()] + cleanup_requests = sandbox_requests.create_cleanup_requests(pool_units, force) serializer = serializers.CleanupRequestSerializer(cleanup_requests, many=True) return Response(serializer.data, status=status.HTTP_202_ACCEPTED) @@ -410,28 +444,43 @@ class SandboxDetailView(generics.RetrieveAPIView): @utils.add_error_responses_doc('get', [401, 403, 404, 500]) @utils.add_error_responses_doc('post', [400, 401, 403, 404, 500]) -class SandboxLockListCreateView(generics.ListCreateAPIView): +class SandboxAllocationUnitLockRetrieveCreateDestroyView(generics.RetrieveDestroyAPIView, + generics.CreateAPIView): + """ + post: Create locks for given sandbox allocation unit if its sandbox exists. + delete: Destroy locks for given sandbox allocation unit if its sandbox exists.""" + queryset = SandboxAllocationUnit.objects.all() + lookup_url_kwarg = "unit_id" serializer_class = serializers.SandboxLockSerializer - """get: List locks for given sandbox.""" - def get_queryset(self): - sandbox_id = self.kwargs.get('sandbox_id') - get_object_or_404(Sandbox, pk=sandbox_id) - return SandboxLock.objects.filter(sandbox=sandbox_id) + def get(self, request, *args, **kwargs): + """get: Retrieve lock for given sandbox allocation unit if its sandbox exists.""" + allocation_unit = self.get_object() + if not hasattr(allocation_unit, "sandbox"): + raise Http404(f'Sandbox allocation unit {allocation_unit.id} has no sandbox.') + sandbox_id = allocation_unit.sandbox.id + lock = SandboxLock.objects.get(sandbox=sandbox_id) + return Response(self.get_serializer(lock).data) def post(self, request, *args, **kwargs): - """Lock given sandbox.""" - sandbox = sandboxes.get_sandbox(kwargs.get('sandbox_id')) + """Lock sandbox of given sandbox allocation unit if the sandbox exists.""" + allocation_unit = self.get_object() + if not hasattr(allocation_unit, "sandbox"): + raise Http404(f'Sandbox allocation unit {allocation_unit.id} has no sandbox.') + sandbox = allocation_unit.sandbox lock = sandboxes.lock_sandbox(sandbox) - return Response(self.serializer_class(lock).data, status=status.HTTP_201_CREATED) + return Response(self.get_serializer(lock).data, status=status.HTTP_201_CREATED) - -@utils.add_error_responses_doc('get', [401, 403, 404, 500]) -class SandboxLockDetailDestroyView(generics.RetrieveDestroyAPIView): - """delete: Delete given lock.""" - queryset = SandboxLock.objects.all() - lookup_url_kwarg = "lock_id" - serializer_class = serializers.SandboxLockSerializer + def delete(self, request, *args, **kwargs): + """Delete lock of given sandbox allocation unit if it has sandbox.""" + allocation_unit = self.get_object() + if not hasattr(allocation_unit, "sandbox"): + raise Http404(f'Sandbox allocation unit {allocation_unit.id} has no sandbox.') + sandbox = allocation_unit.sandbox + if not hasattr(sandbox, "lock"): + raise Http404(f'No SandboxLock matches the given query') + SandboxLock.objects.filter(sandbox=sandbox.id).delete() + return Response(status=status.HTTP_204_NO_CONTENT) @utils.add_error_responses_doc('get', [401, 403, 404, 500]) @@ -550,13 +599,20 @@ class SandboxConsolesView(APIView): # noinspection PyMethodMayBeStatic def get(self, request, *args, **kwargs): - """Retrieve spice console urls for all machines in the topology.""" + """Retrieve spice console urls for all machines in the topology. Returns 202 if + consoles are not ready yet.""" sandbox = sandboxes.get_sandbox(kwargs.get('sandbox_id')) topology_instance = sandboxes.get_topology_instance(sandbox) node_names = [host.name for host in topology_instance.get_hosts() if not host.hidden] + \ [router.name for router in topology_instance.get_routers()] - consoles = {name: nodes.get_console_url(sandbox, name) for name in node_names} - return Response(consoles) + consoles = {} + is_ready = True + for name in node_names: + console_url = nodes.get_console_url(sandbox, name) + if not console_url: + is_ready = False + consoles[name] = console_url + return Response(consoles) if is_ready else Response(status=status.HTTP_202_ACCEPTED) @utils.add_error_responses_doc('get', [401, 403, 404, 500]) diff --git a/kypo/sandbox_service_project/settings.py b/kypo/sandbox_service_project/settings.py index 0b6e5caac56b7d753b83c393fa0e1c04cd91320d..ea1ca3741f76bd0c9695c45699eb6811b8cd5be8 100644 --- a/kypo/sandbox_service_project/settings.py +++ b/kypo/sandbox_service_project/settings.py @@ -26,7 +26,7 @@ KYPO_CONFIG = KYPO_SERVICE_CONFIG.app_config os.environ['REQUESTS_CA_BUNDLE'] = KYPO_CONFIG.ssl_ca_certificate_verify # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = '-^mu0=6s@*x4jdbrz5yr!++p*02#%m$_4&0uw8h1)&r5u!v=12' +SECRET_KEY = KYPO_SERVICE_CONFIG.django_secret_key # SECURITY WARNING: don't run with debug turned on in production! DEBUG = KYPO_SERVICE_CONFIG.debug diff --git a/kypo/sandbox_service_project/tests/config.yml b/kypo/sandbox_service_project/tests/config.yml index 7f8a62a5b1c4e895d40e5861931d1891cc0e0dbe..6aed0fa09bc675ef0deccb95932f5c7a163a7771 100644 --- a/kypo/sandbox_service_project/tests/config.yml +++ b/kypo/sandbox_service_project/tests/config.yml @@ -8,6 +8,10 @@ stack_name_prefix: kypotest # SECURITY WARNING: don't run with debug turned on in production! debug: True +# A secret key used by django to provide cryptographic signing. +# SECURITY WARNING: change this key for production environment and keep it secret! +#django_secret_key: "-^mu0=6s@*x4jdbrz5yr!++p*02#%m$_4&0uw8h1)&r5u!v=12ASS" + # A list of strings representing the host/domain names that this Django site can serve. #allowed_hosts: [] diff --git a/kypo/sandbox_service_project/tests/settings.py b/kypo/sandbox_service_project/tests/settings.py index 0dbf6fe6b14cefeb44397d27bc57c0d76bc7c39f..3e7bc4ac94deff34af6b081ae04ff064448ec9f2 100644 --- a/kypo/sandbox_service_project/tests/settings.py +++ b/kypo/sandbox_service_project/tests/settings.py @@ -24,7 +24,7 @@ KYPO_SERVICE_CONFIG = KypoServiceConfig.from_file(KYPO_SANDBOX_SERVICE_CONFIG_PA KYPO_CONFIG = KYPO_SERVICE_CONFIG.app_config # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = '-^mu0=6s@*x4jdbrz5yr!++p*02#%m$_4&0uw8h1)&r5u!v=12' +SECRET_KEY = KYPO_SERVICE_CONFIG.django_secret_key # SECURITY WARNING: don't run with debug turned on in production! DEBUG = KYPO_SERVICE_CONFIG.debug