From 0aa1e3f469295270e839d6900e96000d12ee1a0b Mon Sep 17 00:00:00 2001 From: Andre Lima Date: Tue, 2 Jul 2024 13:43:15 -0300 Subject: [PATCH 01/11] upgraded to pydantic2.x --- poetry.lock | 236 ++++++++++++++++++++++++++++++++++++------------- pyproject.toml | 2 +- 2 files changed, 174 insertions(+), 64 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0452cd1..5ea9326 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiofiles" @@ -152,6 +152,20 @@ files = [ [package.dependencies] frozenlist = ">=1.1.0" +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[package.dependencies] +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} + [[package]] name = "astroid" version = "2.15.6" @@ -167,8 +181,8 @@ files = [ lazy-object-proxy = ">=1.4.0" typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} wrapt = [ - {version = ">=1.11,<2", markers = "python_version < \"3.11\""}, {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}, + {version = ">=1.11,<2", markers = "python_version < \"3.11\""}, ] [[package]] @@ -684,23 +698,17 @@ tests = ["noseofyeti[black] (==2.4.1)", "pytest (==7.2.1)"] [[package]] name = "diffsync" -version = "1.8.0" +version = "1.4.0" description = "Library to easily sync/diff/update 2 different data sources" optional = false -python-versions = ">=3.7,<4.0" +python-versions = ">=3.6.2,<4.0.0" files = [ - {file = "diffsync-1.8.0-py3-none-any.whl", hash = "sha256:e9c7677170d40155083cd48e91aa80817f8f097364f744b95d6b4c2ec405c909"}, - {file = "diffsync-1.8.0.tar.gz", hash = "sha256:1d59e11009c46a55501aee87c31b978dabda137ae32049105687671c5e7675b9"}, + {file = "diffsync-1.4.0-py3-none-any.whl", hash = "sha256:92f4b54e7cd813180c1c88c43ac1885fbf7dd2ab6e6f119b80c22705c02a604c"}, + {file = "diffsync-1.4.0.tar.gz", hash = "sha256:34b432290f59a342bb71607a2221717d3f1c24e33aa558aa09cfbed2025ee2ac"}, ] -[package.dependencies] -colorama = ">=0.4.3,<0.5.0" -packaging = ">=21.3,<24.0" -pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0" -structlog = ">=20.1.0,<23.0.0" - [package.extras] -redis = ["redis (>=4.3,<5.0)"] +docs = ["colorama (>=0.4.3,<0.5.0)", "dataclasses (>=0.7,<0.8)", "m2r2 (>=0.2.7,<0.3.0)", "pydantic (>=1.7.4,!=1.8,!=1.8.1,<2.0.0)", "sphinx (>=4.0.2,<5.0.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "structlog (>=20.1.0,<22.0.0)", "toml (>=0.10.2,<0.11.0)"] [[package]] name = "dill" @@ -1492,6 +1500,16 @@ files = [ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, @@ -2717,55 +2735,125 @@ files = [ [[package]] name = "pydantic" -version = "1.10.12" -description = "Data validation and settings management using python type hints" +version = "2.8.0" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic-1.10.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a1fcb59f2f355ec350073af41d927bf83a63b50e640f4dbaa01053a28b7a7718"}, - {file = "pydantic-1.10.12-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b7ccf02d7eb340b216ec33e53a3a629856afe1c6e0ef91d84a4e6f2fb2ca70fe"}, - {file = "pydantic-1.10.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fb2aa3ab3728d950bcc885a2e9eff6c8fc40bc0b7bb434e555c215491bcf48b"}, - {file = "pydantic-1.10.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:771735dc43cf8383959dc9b90aa281f0b6092321ca98677c5fb6125a6f56d58d"}, - {file = "pydantic-1.10.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ca48477862372ac3770969b9d75f1bf66131d386dba79506c46d75e6b48c1e09"}, - {file = "pydantic-1.10.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a5e7add47a5b5a40c49b3036d464e3c7802f8ae0d1e66035ea16aa5b7a3923ed"}, - {file = "pydantic-1.10.12-cp310-cp310-win_amd64.whl", hash = "sha256:e4129b528c6baa99a429f97ce733fff478ec955513630e61b49804b6cf9b224a"}, - {file = "pydantic-1.10.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b0d191db0f92dfcb1dec210ca244fdae5cbe918c6050b342d619c09d31eea0cc"}, - {file = "pydantic-1.10.12-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:795e34e6cc065f8f498c89b894a3c6da294a936ee71e644e4bd44de048af1405"}, - {file = "pydantic-1.10.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69328e15cfda2c392da4e713443c7dbffa1505bc9d566e71e55abe14c97ddc62"}, - {file = "pydantic-1.10.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2031de0967c279df0d8a1c72b4ffc411ecd06bac607a212892757db7462fc494"}, - {file = "pydantic-1.10.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ba5b2e6fe6ca2b7e013398bc7d7b170e21cce322d266ffcd57cca313e54fb246"}, - {file = "pydantic-1.10.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2a7bac939fa326db1ab741c9d7f44c565a1d1e80908b3797f7f81a4f86bc8d33"}, - {file = "pydantic-1.10.12-cp311-cp311-win_amd64.whl", hash = "sha256:87afda5539d5140cb8ba9e8b8c8865cb5b1463924d38490d73d3ccfd80896b3f"}, - {file = "pydantic-1.10.12-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:549a8e3d81df0a85226963611950b12d2d334f214436a19537b2efed61b7639a"}, - {file = "pydantic-1.10.12-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:598da88dfa127b666852bef6d0d796573a8cf5009ffd62104094a4fe39599565"}, - {file = "pydantic-1.10.12-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba5c4a8552bff16c61882db58544116d021d0b31ee7c66958d14cf386a5b5350"}, - {file = "pydantic-1.10.12-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c79e6a11a07da7374f46970410b41d5e266f7f38f6a17a9c4823db80dadf4303"}, - {file = "pydantic-1.10.12-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab26038b8375581dc832a63c948f261ae0aa21f1d34c1293469f135fa92972a5"}, - {file = "pydantic-1.10.12-cp37-cp37m-win_amd64.whl", hash = "sha256:e0a16d274b588767602b7646fa05af2782576a6cf1022f4ba74cbb4db66f6ca8"}, - {file = "pydantic-1.10.12-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6a9dfa722316f4acf4460afdf5d41d5246a80e249c7ff475c43a3a1e9d75cf62"}, - {file = "pydantic-1.10.12-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a73f489aebd0c2121ed974054cb2759af8a9f747de120acd2c3394cf84176ccb"}, - {file = "pydantic-1.10.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b30bcb8cbfccfcf02acb8f1a261143fab622831d9c0989707e0e659f77a18e0"}, - {file = "pydantic-1.10.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fcfb5296d7877af406ba1547dfde9943b1256d8928732267e2653c26938cd9c"}, - {file = "pydantic-1.10.12-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2f9a6fab5f82ada41d56b0602606a5506aab165ca54e52bc4545028382ef1c5d"}, - {file = "pydantic-1.10.12-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dea7adcc33d5d105896401a1f37d56b47d443a2b2605ff8a969a0ed5543f7e33"}, - {file = "pydantic-1.10.12-cp38-cp38-win_amd64.whl", hash = "sha256:1eb2085c13bce1612da8537b2d90f549c8cbb05c67e8f22854e201bde5d98a47"}, - {file = "pydantic-1.10.12-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ef6c96b2baa2100ec91a4b428f80d8f28a3c9e53568219b6c298c1125572ebc6"}, - {file = "pydantic-1.10.12-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6c076be61cd0177a8433c0adcb03475baf4ee91edf5a4e550161ad57fc90f523"}, - {file = "pydantic-1.10.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d5a58feb9a39f481eda4d5ca220aa8b9d4f21a41274760b9bc66bfd72595b86"}, - {file = "pydantic-1.10.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5f805d2d5d0a41633651a73fa4ecdd0b3d7a49de4ec3fadf062fe16501ddbf1"}, - {file = "pydantic-1.10.12-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1289c180abd4bd4555bb927c42ee42abc3aee02b0fb2d1223fb7c6e5bef87dbe"}, - {file = "pydantic-1.10.12-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5d1197e462e0364906cbc19681605cb7c036f2475c899b6f296104ad42b9f5fb"}, - {file = "pydantic-1.10.12-cp39-cp39-win_amd64.whl", hash = "sha256:fdbdd1d630195689f325c9ef1a12900524dceb503b00a987663ff4f58669b93d"}, - {file = "pydantic-1.10.12-py3-none-any.whl", hash = "sha256:b749a43aa51e32839c9d71dc67eb1e4221bb04af1033a32e3923d46f9effa942"}, - {file = "pydantic-1.10.12.tar.gz", hash = "sha256:0fe8a415cea8f340e7a9af9c54fc71a649b43e8ca3cc732986116b3cb135d303"}, -] - -[package.dependencies] -typing-extensions = ">=4.2.0" - -[package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] + {file = "pydantic-2.8.0-py3-none-any.whl", hash = "sha256:ead4f3a1e92386a734ca1411cb25d94147cf8778ed5be6b56749047676d6364e"}, + {file = "pydantic-2.8.0.tar.gz", hash = "sha256:d970ffb9d030b710795878940bd0489842c638e7252fc4a19c3ae2f7da4d6141"}, +] + +[package.dependencies] +annotated-types = ">=0.4.0" +pydantic-core = "2.20.0" +typing-extensions = [ + {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, + {version = ">=4.6.1", markers = "python_version < \"3.13\""}, +] + +[package.extras] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.20.0" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.20.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:e9dcd7fb34f7bfb239b5fa420033642fff0ad676b765559c3737b91f664d4fa9"}, + {file = "pydantic_core-2.20.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:649a764d9b0da29816889424697b2a3746963ad36d3e0968784ceed6e40c6355"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7701df088d0b05f3460f7ba15aec81ac8b0fb5690367dfd072a6c38cf5b7fdb5"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab760f17c3e792225cdaef31ca23c0aea45c14ce80d8eff62503f86a5ab76bff"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb1ad5b4d73cde784cf64580166568074f5ccd2548d765e690546cff3d80937d"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b81ec2efc04fc1dbf400647d4357d64fb25543bae38d2d19787d69360aad21c9"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4a9732a5cad764ba37f3aa873dccb41b584f69c347a57323eda0930deec8e10"}, + {file = "pydantic_core-2.20.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6dc85b9e10cc21d9c1055f15684f76fa4facadddcb6cd63abab702eb93c98943"}, + {file = "pydantic_core-2.20.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:21d9f7e24f63fdc7118e6cc49defaab8c1d27570782f7e5256169d77498cf7c7"}, + {file = "pydantic_core-2.20.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8b315685832ab9287e6124b5d74fc12dda31e6421d7f6b08525791452844bc2d"}, + {file = "pydantic_core-2.20.0-cp310-none-win32.whl", hash = "sha256:c3dc8ec8b87c7ad534c75b8855168a08a7036fdb9deeeed5705ba9410721c84d"}, + {file = "pydantic_core-2.20.0-cp310-none-win_amd64.whl", hash = "sha256:85770b4b37bb36ef93a6122601795231225641003e0318d23c6233c59b424279"}, + {file = "pydantic_core-2.20.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:58e251bb5a5998f7226dc90b0b753eeffa720bd66664eba51927c2a7a2d5f32c"}, + {file = "pydantic_core-2.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:78d584caac52c24240ef9ecd75de64c760bbd0e20dbf6973631815e3ef16ef8b"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5084ec9721f82bef5ff7c4d1ee65e1626783abb585f8c0993833490b63fe1792"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6d0f52684868db7c218437d260e14d37948b094493f2646f22d3dda7229bbe3f"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1def125d59a87fe451212a72ab9ed34c118ff771e5473fef4f2f95d8ede26d75"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b34480fd6778ab356abf1e9086a4ced95002a1e195e8d2fd182b0def9d944d11"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d42669d319db366cb567c3b444f43caa7ffb779bf9530692c6f244fc635a41eb"}, + {file = "pydantic_core-2.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:53b06aea7a48919a254b32107647be9128c066aaa6ee6d5d08222325f25ef175"}, + {file = "pydantic_core-2.20.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1f038156b696a1c39d763b2080aeefa87ddb4162c10aa9fabfefffc3dd8180fa"}, + {file = "pydantic_core-2.20.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3f0f3a4a23717280a5ee3ac4fb1f81d6fde604c9ec5100f7f6f987716bb8c137"}, + {file = "pydantic_core-2.20.0-cp311-none-win32.whl", hash = "sha256:316fe7c3fec017affd916a0c83d6f1ec697cbbbdf1124769fa73328e7907cc2e"}, + {file = "pydantic_core-2.20.0-cp311-none-win_amd64.whl", hash = "sha256:2d06a7fa437f93782e3f32d739c3ec189f82fca74336c08255f9e20cea1ed378"}, + {file = "pydantic_core-2.20.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:d6f8c49657f3eb7720ed4c9b26624063da14937fc94d1812f1e04a2204db3e17"}, + {file = "pydantic_core-2.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad1bd2f377f56fec11d5cfd0977c30061cd19f4fa199bf138b200ec0d5e27eeb"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed741183719a5271f97d93bbcc45ed64619fa38068aaa6e90027d1d17e30dc8d"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d82e5ed3a05f2dcb89c6ead2fd0dbff7ac09bc02c1b4028ece2d3a3854d049ce"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2ba34a099576234671f2e4274e5bc6813b22e28778c216d680eabd0db3f7dad"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:879ae6bb08a063b3e1b7ac8c860096d8fd6b48dd9b2690b7f2738b8c835e744b"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b0eefc7633a04c0694340aad91fbfd1986fe1a1e0c63a22793ba40a18fcbdc8"}, + {file = "pydantic_core-2.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:73deadd6fd8a23e2f40b412b3ac617a112143c8989a4fe265050fd91ba5c0608"}, + {file = "pydantic_core-2.20.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:35681445dc85446fb105943d81ae7569aa7e89de80d1ca4ac3229e05c311bdb1"}, + {file = "pydantic_core-2.20.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0f6dd3612a3b9f91f2e63924ea18a4476656c6d01843ca20a4c09e00422195af"}, + {file = "pydantic_core-2.20.0-cp312-none-win32.whl", hash = "sha256:7e37b6bb6e90c2b8412b06373c6978d9d81e7199a40e24a6ef480e8acdeaf918"}, + {file = "pydantic_core-2.20.0-cp312-none-win_amd64.whl", hash = "sha256:7d4df13d1c55e84351fab51383520b84f490740a9f1fec905362aa64590b7a5d"}, + {file = "pydantic_core-2.20.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:d43e7ab3b65e4dc35a7612cfff7b0fd62dce5bc11a7cd198310b57f39847fd6c"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b6a24d7b5893392f2b8e3b7a0031ae3b14c6c1942a4615f0d8794fdeeefb08b"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b2f13c3e955a087c3ec86f97661d9f72a76e221281b2262956af381224cfc243"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:72432fd6e868c8d0a6849869e004b8bcae233a3c56383954c228316694920b38"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d70a8ff2d4953afb4cbe6211f17268ad29c0b47e73d3372f40e7775904bc28fc"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e49524917b8d3c2f42cd0d2df61178e08e50f5f029f9af1f402b3ee64574392"}, + {file = "pydantic_core-2.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a4f0f71653b1c1bad0350bc0b4cc057ab87b438ff18fa6392533811ebd01439c"}, + {file = "pydantic_core-2.20.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:16197e6f4fdecb9892ed2436e507e44f0a1aa2cff3b9306d1c879ea2f9200997"}, + {file = "pydantic_core-2.20.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:763602504bf640b3ded3bba3f8ed8a1cc2fc6a87b8d55c1c5689f428c49c947e"}, + {file = "pydantic_core-2.20.0-cp313-none-win32.whl", hash = "sha256:a3f243f318bd9523277fa123b3163f4c005a3e8619d4b867064de02f287a564d"}, + {file = "pydantic_core-2.20.0-cp313-none-win_amd64.whl", hash = "sha256:03aceaf6a5adaad3bec2233edc5a7905026553916615888e53154807e404545c"}, + {file = "pydantic_core-2.20.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d6f2d8b8da1f03f577243b07bbdd3412eee3d37d1f2fd71d1513cbc76a8c1239"}, + {file = "pydantic_core-2.20.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a272785a226869416c6b3c1b7e450506152d3844207331f02f27173562c917e0"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efbb412d55a4ffe73963fed95c09ccb83647ec63b711c4b3752be10a56f0090b"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1e4f46189d8740561b43655263a41aac75ff0388febcb2c9ec4f1b60a0ec12f3"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87d3df115f4a3c8c5e4d5acf067d399c6466d7e604fc9ee9acbe6f0c88a0c3cf"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a340d2bdebe819d08f605e9705ed551c3feb97e4fd71822d7147c1e4bdbb9508"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:616b9c2f882393d422ba11b40e72382fe975e806ad693095e9a3b67c59ea6150"}, + {file = "pydantic_core-2.20.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:25c46bb2ff6084859bbcfdf4f1a63004b98e88b6d04053e8bf324e115398e9e7"}, + {file = "pydantic_core-2.20.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:23425eccef8f2c342f78d3a238c824623836c6c874d93c726673dbf7e56c78c0"}, + {file = "pydantic_core-2.20.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:52527e8f223ba29608d999d65b204676398009725007c9336651c2ec2d93cffc"}, + {file = "pydantic_core-2.20.0-cp38-none-win32.whl", hash = "sha256:1c3c5b7f70dd19a6845292b0775295ea81c61540f68671ae06bfe4421b3222c2"}, + {file = "pydantic_core-2.20.0-cp38-none-win_amd64.whl", hash = "sha256:8093473d7b9e908af1cef30025609afc8f5fd2a16ff07f97440fd911421e4432"}, + {file = "pydantic_core-2.20.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:ee7785938e407418795e4399b2bf5b5f3cf6cf728077a7f26973220d58d885cf"}, + {file = "pydantic_core-2.20.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0e75794883d635071cf6b4ed2a5d7a1e50672ab7a051454c76446ef1ebcdcc91"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:344e352c96e53b4f56b53d24728217c69399b8129c16789f70236083c6ceb2ac"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:978d4123ad1e605daf1ba5e01d4f235bcf7b6e340ef07e7122e8e9cfe3eb61ab"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c05eaf6c863781eb834ab41f5963604ab92855822a2062897958089d1335dad"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc7e43b4a528ffca8c9151b6a2ca34482c2fdc05e6aa24a84b7f475c896fc51d"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:658287a29351166510ebbe0a75c373600cc4367a3d9337b964dada8d38bcc0f4"}, + {file = "pydantic_core-2.20.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1dacf660d6de692fe351e8c806e7efccf09ee5184865893afbe8e59be4920b4a"}, + {file = "pydantic_core-2.20.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3e147fc6e27b9a487320d78515c5f29798b539179f7777018cedf51b7749e4f4"}, + {file = "pydantic_core-2.20.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c867230d715a3dd1d962c8d9bef0d3168994ed663e21bf748b6e3a529a129aab"}, + {file = "pydantic_core-2.20.0-cp39-none-win32.whl", hash = "sha256:22b813baf0dbf612752d8143a2dbf8e33ccb850656b7850e009bad2e101fc377"}, + {file = "pydantic_core-2.20.0-cp39-none-win_amd64.whl", hash = "sha256:3a7235b46c1bbe201f09b6f0f5e6c36b16bad3d0532a10493742f91fbdc8035f"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cafde15a6f7feaec2f570646e2ffc5b73412295d29134a29067e70740ec6ee20"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2aec8eeea0b08fd6bc2213d8e86811a07491849fd3d79955b62d83e32fa2ad5f"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:840200827984f1c4e114008abc2f5ede362d6e11ed0b5931681884dd41852ff1"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8ea1d8b7df522e5ced34993c423c3bf3735c53df8b2a15688a2f03a7d678800"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5b8376a867047bf08910573deb95d3c8dfb976eb014ee24f3b5a61ccc5bee1b"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d08264b4460326cefacc179fc1411304d5af388a79910832835e6f641512358b"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:7a3639011c2e8a9628466f616ed7fb413f30032b891898e10895a0a8b5857d6c"}, + {file = "pydantic_core-2.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:05e83ce2f7eba29e627dd8066aa6c4c0269b2d4f889c0eba157233a353053cea"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:603a843fea76a595c8f661cd4da4d2281dff1e38c4a836a928eac1a2f8fe88e4"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ac76f30d5d3454f4c28826d891fe74d25121a346c69523c9810ebba43f3b1cec"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e3b1d4b1b3f6082849f9b28427ef147a5b46a6132a3dbaf9ca1baa40c88609"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2761f71faed820e25ec62eacba670d1b5c2709bb131a19fcdbfbb09884593e5a"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a0586cddbf4380e24569b8a05f234e7305717cc8323f50114dfb2051fcbce2a3"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:b8c46a8cf53e849eea7090f331ae2202cd0f1ceb090b00f5902c423bd1e11805"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b4a085bd04af7245e140d1b95619fe8abb445a3d7fdf219b3f80c940853268ef"}, + {file = "pydantic_core-2.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:116b326ac82c8b315e7348390f6d30bcfe6e688a7d3f1de50ff7bcc2042a23c2"}, + {file = "pydantic_core-2.20.0.tar.gz", hash = "sha256:366be8e64e0cb63d87cf79b4e1765c0703dd6313c729b22e7b9e378db6b96877"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydocstyle" @@ -2854,8 +2942,8 @@ files = [ astroid = ">=2.15.6,<=2.17.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ - {version = ">=0.2", markers = "python_version < \"3.11\""}, {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, + {version = ">=0.2", markers = "python_version < \"3.11\""}, ] isort = ">=4.2.5,<6" mccabe = ">=0.6,<0.8" @@ -3108,6 +3196,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -3115,8 +3204,15 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -3133,6 +3229,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -3140,6 +3237,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -3268,7 +3366,8 @@ files = [ {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win32.whl", hash = "sha256:763d65baa3b952479c4e972669f679fe490eee058d5aa85da483ebae2009d231"}, {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:1a6391a7cabb7641c32517539ca42cf84b87b667bad38b78d4d42dd23e957c81"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:9c7617df90c1365638916b98cdd9be833d31d337dbcd722485597b43c4a215bf"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win32.whl", hash = "sha256:f6d3d39611ac2e4f62c3128a9eed45f19a6608670c5a2f4f07f24e8de3441d38"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:da538167284de58a52109a9b89b8f6a53ff8437dd6dc26d33b57bf6699153122"}, @@ -3622,6 +3721,17 @@ files = [ {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, ] +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + [[package]] name = "unicon" version = "23.8" @@ -3993,4 +4103,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.8.0" -content-hash = "0a19845548fb26c574aa51c14401ccb8028e6416e761c47ffe1063e40a025414" +content-hash = "86f6ca2a2c62eeebf648b58e269964cc4f7fe967cc5437a126073019f1f162fa" diff --git a/pyproject.toml b/pyproject.toml index 5d2cd21..1660214 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -24,7 +24,7 @@ toml = "^0.10" nornir = "^3.0" termcolor = ">=1.1,<3" click = "^7.1 || ^8.0" -pydantic = "^1.6" +pydantic = "^2.0" genie = ">=22.7,<24" pyats = ">=22.7,<24" netmiko = "^3.3" From c6b2124eb452d4a03a62a6c2b90103ea571dabc4 Mon Sep 17 00:00:00 2001 From: Andre Lima Date: Tue, 2 Jul 2024 15:52:09 -0300 Subject: [PATCH 02/11] added pydantic-settings --- poetry.lock | 52 +++++++++++++++++++++++++++++++++++--------------- pyproject.toml | 1 + 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5ea9326..065a9c8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -181,8 +181,8 @@ files = [ lazy-object-proxy = ">=1.4.0" typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} wrapt = [ - {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}, {version = ">=1.11,<2", markers = "python_version < \"3.11\""}, + {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}, ] [[package]] @@ -2748,8 +2748,8 @@ files = [ annotated-types = ">=0.4.0" pydantic-core = "2.20.0" typing-extensions = [ - {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, {version = ">=4.6.1", markers = "python_version < \"3.13\""}, + {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, ] [package.extras] @@ -2855,6 +2855,25 @@ files = [ [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" +[[package]] +name = "pydantic-settings" +version = "2.3.4" +description = "Settings management using Pydantic" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_settings-2.3.4-py3-none-any.whl", hash = "sha256:11ad8bacb68a045f00e4f862c7a718c8a9ec766aa8fd4c32e39a0594b207b53a"}, + {file = "pydantic_settings-2.3.4.tar.gz", hash = "sha256:c5802e3d62b78e82522319bbc9b8f8ffb28ad1c988a99311d04f2a6051fca0a7"}, +] + +[package.dependencies] +pydantic = ">=2.7.0" +python-dotenv = ">=0.21.0" + +[package.extras] +toml = ["tomli (>=2.0.1)"] +yaml = ["pyyaml (>=6.0.1)"] + [[package]] name = "pydocstyle" version = "6.3.0" @@ -2942,8 +2961,8 @@ files = [ astroid = ">=2.15.6,<=2.17.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ - {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, {version = ">=0.2", markers = "python_version < \"3.11\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, ] isort = ">=4.2.5,<6" mccabe = ">=0.6,<0.8" @@ -3136,6 +3155,20 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "python-dotenv" +version = "1.0.1" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, + {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + [[package]] name = "python-engineio" version = "3.14.2" @@ -3710,17 +3743,6 @@ six = "*" diagrams = ["pygraphviz"] test = ["pytest"] -[[package]] -name = "typing-extensions" -version = "4.7.1" -description = "Backported and Experimental Type Hints for Python 3.7+" -optional = false -python-versions = ">=3.7" -files = [ - {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, - {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, -] - [[package]] name = "typing-extensions" version = "4.12.2" @@ -4103,4 +4125,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.8.0" -content-hash = "86f6ca2a2c62eeebf648b58e269964cc4f7fe967cc5437a126073019f1f162fa" +content-hash = "f02375f51755c9c29b4cc7a9bb052f70737c59481bfe3a4be5cfdc70a34fc0d0" diff --git a/pyproject.toml b/pyproject.toml index 1660214..9df9e91 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,6 +37,7 @@ nornir-napalm = "^0.1.2" nornir-utils = "^0.1.2" nornir-netmiko = "^0.1.1" pybatfish = "2023.5.12.784" +pydantic-settings = "^2.3.4" [tool.poetry.dev-dependencies] bandit = "*" From 1e948045ba2aa3f71c58d37e8fcdb5c77cdace13 Mon Sep 17 00:00:00 2001 From: Andre Lima Date: Tue, 2 Jul 2024 15:56:27 -0300 Subject: [PATCH 03/11] redefined settings with pydantic_settings - required in pydantic v2 --- .../adapters/nautobot_api/settings.py | 22 ++---- .../adapters/netbox_api/settings.py | 22 ++---- network_importer/config.py | 69 ++++++------------- tests/unit/adapters/test_base_adapter.py | 8 +-- 4 files changed, 39 insertions(+), 82 deletions(-) diff --git a/network_importer/adapters/nautobot_api/settings.py b/network_importer/adapters/nautobot_api/settings.py index 1734ac3..dc683a8 100644 --- a/network_importer/adapters/nautobot_api/settings.py +++ b/network_importer/adapters/nautobot_api/settings.py @@ -1,6 +1,7 @@ """Settings definition for the NetboxAPIAdapter.""" from typing import List, Optional, Union -from pydantic import BaseSettings +from pydantic_settings import BaseSettings +from pydantic import Field from diffsync import DiffSyncModelFlags @@ -9,25 +10,16 @@ class AdapterSettings(BaseSettings): """Config settings for the netbox_api adapter. Not used currently.""" model_flag_tags: List[str] = list() # List of tags that defines what objects to assign the model_flag to. - model_flag: Optional[DiffSyncModelFlags] # The model flag that will be applied to objects based on tag. + model_flag: Optional[DiffSyncModelFlags] = None # The model flag that will be applied to objects based on tag. class InventorySettings(BaseSettings): """Config settings for the NautobotAPI inventory.""" - address: Optional[str] = "http://localhost" - token: Optional[str] = None - verify_ssl: Union[bool, str] = True + address: Optional[str] = Field(default="http://localhost", env="NAUTOBOT_ADDRESS") + token: Optional[str] = Field(default=None, env="NAUTOBOT_TOKEN") + verify_ssl: Union[bool, str] = Field(default=True, env="NAUTOBOT_VERIFY_SSL") use_primary_ip: Optional[bool] = True fqdn: Optional[str] = None - filter: Optional[str] = None - - class Config: - """Additional parameters to automatically map environment variable to some settings.""" - - fields = { - "address": {"env": "NAUTOBOT_ADDRESS"}, - "token": {"env": "NAUTOBOT_TOKEN"}, - "verify_ssl": {"env": "NAUTOBOT_VERIFY_SSL"}, - } + filter: Optional[str] = None \ No newline at end of file diff --git a/network_importer/adapters/netbox_api/settings.py b/network_importer/adapters/netbox_api/settings.py index a7d27cd..dba3d59 100644 --- a/network_importer/adapters/netbox_api/settings.py +++ b/network_importer/adapters/netbox_api/settings.py @@ -1,6 +1,7 @@ """Settings definition for the NetboxAPIAdapter.""" from typing import List, Union, Optional -from pydantic import BaseSettings +from pydantic import Field +from pydantic_settings import BaseSettings from diffsync import DiffSyncModelFlags @@ -9,25 +10,16 @@ class AdapterSettings(BaseSettings): """Config settings for the netbox_api adapter. Not used currently.""" model_flag_tags: List[str] = list() # List of tags that defines what objects to assign the model_flag to. - model_flag: Optional[DiffSyncModelFlags] # The model flag that will be applied to objects based on tag. + model_flag: Optional[DiffSyncModelFlags] = None # The model flag that will be applied to objects based on tag. class InventorySettings(BaseSettings): """Config settings for the NetboxAPI inventory.""" - address: Optional[str] = "http://localhost" - token: Optional[str] = None - verify_ssl: Union[bool, str] = True + address: Optional[str] = Field(default="http://localhost", env="NETBOX_ADDRESS") + token: Optional[str] = Field(default=None, env="NETBOX_TOKEN") + verify_ssl: Union[bool, str] = Field(default=True, env="NETBOX_VERIFY_SSL") use_primary_ip: Optional[bool] = True fqdn: Optional[str] = None - filter: Optional[str] = "" - - class Config: - """Additional parameters to automatically map environment variable to some settings.""" - - fields = { - "address": {"env": "NETBOX_ADDRESS"}, - "token": {"env": "NETBOX_TOKEN"}, - "verify_ssl": {"env": "NETBOX_VERIFY_SSL"}, - } + filter: Optional[str] = "" \ No newline at end of file diff --git a/network_importer/config.py b/network_importer/config.py index 8e8a288..963ab2b 100644 --- a/network_importer/config.py +++ b/network_importer/config.py @@ -7,7 +7,8 @@ from typing import List, Dict, Optional, Union import toml -from pydantic import BaseSettings, ValidationError +from pydantic import ValidationError, Field +from pydantic_settings import BaseSettings from typing_extensions import Literal from network_importer.exceptions import ConfigLoadFatalError @@ -38,50 +39,22 @@ class BatfishSettings(BaseSettings): - """Settings definition for the Batfish section of the configuration.""" - - address: str = "localhost" - network_name: str = "network-importer" - snapshot_name: str = "latest" - port_v1: int = 9997 - port_v2: int = 9996 - use_ssl: bool = False - api_key: Optional[str] - - class Config: - """Additional parameters to automatically map environment variable to some settings.""" - - fields = { - "address": {"env": "BATFISH_ADDRESS"}, - "network_name": {"env": "BATFISH_NETWORK_NAME"}, - "snapshot_name": {"env": "BATFISH_SNAPSHOT_NAME"}, - "api_key": {"env": "BATFISH_API_KEY"}, - "port_v1": {"env": "BATFISH_PORT_V1"}, - "port_v2": {"env": "BATFISH_PORT_V2"}, - "use_ssl": {"env": "BATFISH_USE_SSL"}, - } + address: str = Field(default="localhost", env="BATFISH_ADDRESS") + network_name: str = Field(default="network-importer", env="BATFISH_NETWORK_NAME") + snapshot_name: str = Field(default="latest", env="BATFISH_SNAPSHOT_NAME") + port_v1: int = Field(default=9997, env="BATFISH_PORT_V1") + port_v2: int = Field(default=9996, env="BATFISH_PORT_V2") + use_ssl: bool = Field(default=False, env="BATFISH_USE_SSL") + api_key: Optional[str] = Field(default=None, env="BATFISH_API_KEY") class NetworkSettings(BaseSettings): - """Settings definition for the Network section of the configuration.""" - - login: Optional[str] - password: Optional[str] - enable: bool = True - - netmiko_extras: Optional[dict] - napalm_extras: Optional[dict] - - fqdns: List[str] = list() # List of valid FQDN that can be found in the network - - class Config: - """Additional parameters to automatically map environment variable to some settings.""" - - fields = { - "login": {"env": "NETWORK_DEVICE_LOGIN"}, - "password": {"env": "NETWORK_DEVICE_PWD"}, - "enable": {"env": "NETWORK_DEVICE_ENABLE"}, - } + login: Optional[str] = Field(default=None, env="NETWORK_DEVICE_LOGIN") + password: Optional[str] = Field(default=None, env="NETWORK_DEVICE_PWD") + enable: bool = Field(default=True, env="NETWORK_DEVICE_ENABLE") + netmiko_extras: Optional[dict] = None + napalm_extras: Optional[dict] = None + fqdns: List[str] = Field(default_factory=list, env="NETWORK_DEVICE_FQDNS") class LogsSettings(BaseSettings): @@ -113,7 +86,7 @@ class MainSettings(BaseSettings): configs_directory: str = "configs" - backend: Optional[Literal["nautobot", "netbox"]] + backend: Optional[Literal["nautobot", "netbox"]] = None """Only Netbox and Nautobot backend are included by default, if you want to use another backend you must leave backend empty and define inventory.inventory_class and adapters.sot_class manually.""" @@ -126,10 +99,10 @@ class AdaptersSettings(BaseSettings): """Settings definition for the Adapters section of the configuration.""" network_class: str = "network_importer.adapters.network_importer.adapter.NetworkImporterAdapter" - network_settings: Optional[dict] + network_settings: Optional[dict] = None - sot_class: Optional[str] - sot_settings: Optional[dict] + sot_class: Optional[str] = None + sot_settings: Optional[dict] = None class DriversSettings(BaseSettings): @@ -145,8 +118,8 @@ class InventorySettings(BaseSettings): if the use_primary_ip flag is disabled, the inventory will try to use the hostname to the device """ - inventory_class: Optional[str] - settings: Optional[dict] + inventory_class: Optional[str] = None + settings: Optional[dict] = None supported_platforms: List[str] = list() diff --git a/tests/unit/adapters/test_base_adapter.py b/tests/unit/adapters/test_base_adapter.py index adbcc9f..17873da 100644 --- a/tests/unit/adapters/test_base_adapter.py +++ b/tests/unit/adapters/test_base_adapter.py @@ -1,6 +1,6 @@ """test for the base adapter.""" -from typing import List, Optional -from pydantic import BaseSettings +from typing import List, Optional, Type +from pydantic_settings import BaseSettings from network_importer.adapters.base import BaseAdapter @@ -21,12 +21,12 @@ class MyAdapterSettings(BaseSettings): """Fake adapter settings.""" first: List[str] = list() - second: Optional[str] + second: Optional[str] = None class MyAdapter(BaseAdapter): """test adapter.""" - settings_class = MyAdapterSettings + settings_class: Type[BaseSettings] = MyAdapterSettings def load(self): """load must be defined.""" From ba3cf1cf616b1ab2d669b0c6206a63202209ff18 Mon Sep 17 00:00:00 2001 From: Andre Lima Date: Tue, 2 Jul 2024 17:40:29 -0300 Subject: [PATCH 04/11] adjusted model classes for compatibility with pydantic v2 --- .../adapters/nautobot_api/models.py | 24 ++++----- .../adapters/netbox_api/models.py | 26 +++++----- network_importer/models.py | 49 +++++++++---------- 3 files changed, 48 insertions(+), 51 deletions(-) diff --git a/network_importer/adapters/nautobot_api/models.py b/network_importer/adapters/nautobot_api/models.py index 22915e1..ff66e4e 100644 --- a/network_importer/adapters/nautobot_api/models.py +++ b/network_importer/adapters/nautobot_api/models.py @@ -24,16 +24,16 @@ class NautobotSite(Site): """Extension of the Site model.""" - remote_id: Optional[str] + remote_id: Optional[str] = None class NautobotDevice(Device): """Extension of the Device model.""" - remote_id: Optional[str] - primary_ip: Optional[str] + remote_id: Optional[str] = None + primary_ip: Optional[str] = None - device_tag_id: Optional[str] + device_tag_id: Optional[str] = None def get_device_tag_id(self): """Get the Nautobot id of the tag for this device. @@ -60,8 +60,8 @@ def get_device_tag_id(self): class NautobotInterface(Interface): """Extension of the Interface model.""" - remote_id: Optional[str] - connected_endpoint_type: Optional[str] + remote_id: Optional[str] = None + connected_endpoint_type: Optional[str] = None def translate_attrs_for_nautobot(self, attrs): # pylint: disable=too-many-branches """Translate interface attributes into Nautobot format. @@ -280,7 +280,7 @@ def delete(self) -> Optional["DiffSyncModel"]: class NautobotIPAddress(IPAddress): """Extension of the IPAddress model.""" - remote_id: Optional[str] + remote_id: Optional[str] = None def translate_attrs_for_nautobot(self, attrs=None): # pylint: disable=unused-argument """Translate IP address attributes into Nautobot format. @@ -396,7 +396,7 @@ def delete(self) -> Optional["DiffSyncModel"]: class NautobotPrefix(Prefix): """Extension of the Prefix model.""" - remote_id: Optional[str] + remote_id: Optional[str] = None def translate_attrs_for_nautobot(self, attrs): """Translate prefix attributes into Nautobot format. @@ -482,7 +482,7 @@ def update(self, attrs: dict) -> Optional["DiffSyncModel"]: class NautobotVlan(Vlan): """Extension of the Vlan model.""" - remote_id: Optional[str] + remote_id: Optional[str] = None tag_prefix: str = "device=" def translate_attrs_for_nautobot(self, attrs): @@ -629,9 +629,9 @@ def update(self, attrs: dict) -> Optional["DiffSyncModel"]: class NautobotCable(Cable): """Extension of the Cable model.""" - remote_id: Optional[str] - termination_a_id: Optional[str] - termination_z_id: Optional[str] + remote_id: Optional[str] = None + termination_a_id: Optional[str] = None + termination_z_id: Optional[str] = None @classmethod def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: diff --git a/network_importer/adapters/netbox_api/models.py b/network_importer/adapters/netbox_api/models.py index a8a87a4..ce46f1d 100644 --- a/network_importer/adapters/netbox_api/models.py +++ b/network_importer/adapters/netbox_api/models.py @@ -24,16 +24,16 @@ class NetboxSite(Site): """Extension of the Site model.""" - remote_id: Optional[int] + remote_id: Optional[int] = None class NetboxDevice(Device): """Extension of the Device model.""" - remote_id: Optional[int] - primary_ip: Optional[str] + remote_id: Optional[int] = None + primary_ip: Optional[str] = None - device_tag_id: Optional[int] + device_tag_id: Optional[int] = None def get_device_tag_id(self): """Get the Netbox id of the tag for this device. @@ -59,8 +59,8 @@ def get_device_tag_id(self): class NetboxInterface(Interface): """Extension of the Interface model.""" - remote_id: Optional[int] - connected_endpoint_type: Optional[str] + remote_id: Optional[int] = None + connected_endpoint_type: Optional[str] = None def translate_attrs_for_netbox(self, attrs): # pylint: disable=too-many-branches """Translate interface attributes into Netbox format. @@ -279,7 +279,7 @@ def delete(self) -> Optional["DiffSyncModel"]: class NetboxIPAddress(IPAddress): """Extension of the IPAddress model.""" - remote_id: Optional[int] + remote_id: Optional[int] = None def translate_attrs_for_netbox(self, attrs=None): # pylint: disable=unused-argument """Translate IP address attributes into NetBox format. @@ -430,7 +430,7 @@ def create_from_pynetbox(cls, diffsync: "DiffSync", obj, device_name): class NetboxPrefix(Prefix): """Extension of the Prefix model.""" - remote_id: Optional[int] + remote_id: Optional[int] = None def translate_attrs_for_netbox(self, attrs): """Translate prefix attributes into Netbox format. @@ -516,7 +516,7 @@ def update(self, attrs: dict) -> Optional["DiffSyncModel"]: class NetboxVlan(Vlan): """Extension of the Vlan model.""" - remote_id: Optional[int] + remote_id: Optional[int] = None tag_prefix: str = "device=" def translate_attrs_for_netbox(self, attrs): @@ -655,7 +655,7 @@ def update(self, attrs: dict) -> Optional["DiffSyncModel"]: class NetboxVlanPre29(NetboxVlan): """Extension of the Vlan model.""" - remote_id: Optional[int] + remote_id: Optional[int] = None tag_prefix: str = "device=" def translate_attrs_for_netbox(self, attrs): @@ -737,9 +737,9 @@ def update_clean_tags(self, nb_params, obj): class NetboxCable(Cable): """Extension of the Cable model.""" - remote_id: Optional[int] - termination_a_id: Optional[int] - termination_z_id: Optional[int] + remote_id: Optional[int] = None + termination_a_id: Optional[int] = None + termination_z_id: Optional[int] = None @classmethod def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: diff --git a/network_importer/models.py b/network_importer/models.py index 65ed6d0..3a6ccfe 100644 --- a/network_importer/models.py +++ b/network_importer/models.py @@ -28,8 +28,8 @@ class Site(DiffSyncModel): _children = {"vlan": "vlans", "prefix": "prefixes"} name: str - prefixes: List = list() - vlans: List[str] = list() + prefixes: List = list() # Correct as is, no need for Optional since it's initialized as an empty list + vlans: List[str] = list() # Same here class Device(DiffSyncModel): @@ -44,13 +44,12 @@ class Device(DiffSyncModel): _children = {"interface": "interfaces"} name: str - site_name: Optional[str] + site_name: Optional[str] = None interfaces: List = list() - - platform: Optional[str] - model: Optional[str] - role: Optional[str] - vendor: Optional[str] + platform: Optional[str] = None + model: Optional[str] = None + role: Optional[str] = None + vendor: Optional[str] = None class Interface(DiffSyncModel): # pylint: disable=too-many-instance-attributes @@ -64,7 +63,6 @@ class Interface(DiffSyncModel): # pylint: disable=too-many-instance-attributes _shortname = ("name",) _attributes = ( "description", - # "mtu", "is_virtual", "is_lag", "is_lag_member", @@ -79,20 +77,20 @@ class Interface(DiffSyncModel): # pylint: disable=too-many-instance-attributes name: str device_name: str - description: Optional[str] - mtu: Optional[int] - speed: Optional[int] - mode: Optional[str] # TRUNK, ACCESS, L3, NONE + description: Optional[str] = None + mtu: Optional[int] = None + speed: Optional[int] = None + mode: Optional[str] = None # TRUNK, ACCESS, L3, NONE switchport_mode: Optional[str] = "NONE" - active: Optional[bool] - is_virtual: Optional[bool] - is_lag: Optional[bool] - is_lag_member: Optional[bool] - parent: Optional[str] + active: Optional[bool] = None + is_virtual: Optional[bool] = None + is_lag: Optional[bool] = None + is_lag_member: Optional[bool] = None + parent: Optional[str] = None lag_members: List[str] = list() allowed_vlans: List[str] = list() - access_vlan: Optional[str] + access_vlan: Optional[str] = None ips: List[str] = list() @@ -114,7 +112,7 @@ class IPAddress(DiffSyncModel): class Prefix(DiffSyncModel): """Prefix Model based on DiffSyncModel. - An Prefix must be associated with a Site and must be unique within a site. + A Prefix must be associated with a Site and must be unique within a site. """ _modelname = "prefix" @@ -122,9 +120,8 @@ class Prefix(DiffSyncModel): _attributes = ("vlan",) prefix: str - site_name: Optional[str] - vlan: Optional[str] - + site_name: Optional[str] = None + vlan: Optional[str] = None class Cable(DiffSyncModel): """Cable Model based on DiffSyncModel.""" @@ -142,9 +139,9 @@ class Cable(DiffSyncModel): device_z_name: str interface_z_name: str - source: Optional[str] + source: Optional[str] = None is_valid: bool = True - error: Optional[str] + error: Optional[str] = None def __init__(self, *args, **kwargs): """Ensure the cable is unique by ordering the devices alphabetically.""" @@ -201,7 +198,7 @@ class Vlan(DiffSyncModel): vid: int site_name: str - name: Optional[str] + name: Optional[str] = None associated_devices: List[str] = list() From 66ca578412425050cb1bc2602d08d004ecfe88fb Mon Sep 17 00:00:00 2001 From: Andre Lima Date: Wed, 3 Jul 2024 10:27:10 -0300 Subject: [PATCH 05/11] upgraded to DiffSync v2 --- poetry.lock | 19 +++++++++++++------ pyproject.toml | 2 +- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index 065a9c8..40eedca 100644 --- a/poetry.lock +++ b/poetry.lock @@ -698,17 +698,24 @@ tests = ["noseofyeti[black] (==2.4.1)", "pytest (==7.2.1)"] [[package]] name = "diffsync" -version = "1.4.0" +version = "2.0.0" description = "Library to easily sync/diff/update 2 different data sources" optional = false -python-versions = ">=3.6.2,<4.0.0" +python-versions = ">=3.8,<4.0" files = [ - {file = "diffsync-1.4.0-py3-none-any.whl", hash = "sha256:92f4b54e7cd813180c1c88c43ac1885fbf7dd2ab6e6f119b80c22705c02a604c"}, - {file = "diffsync-1.4.0.tar.gz", hash = "sha256:34b432290f59a342bb71607a2221717d3f1c24e33aa558aa09cfbed2025ee2ac"}, + {file = "diffsync-2.0.0-py3-none-any.whl", hash = "sha256:59f864a115abc5b0aa3b9db0d44deff59c81cd5469e5894326c27e29511e3aab"}, + {file = "diffsync-2.0.0.tar.gz", hash = "sha256:712bc85a24f49ef6075344dc3a16c85e27b1416154c46fd5de7acf72e8321a9b"}, ] +[package.dependencies] +colorama = ">=0.4.3,<0.5.0" +packaging = ">=21.3,<24.0" +pydantic = ">=2.0.0,<3.0.0" +structlog = ">=20.1.0,<23.0.0" +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} + [package.extras] -docs = ["colorama (>=0.4.3,<0.5.0)", "dataclasses (>=0.7,<0.8)", "m2r2 (>=0.2.7,<0.3.0)", "pydantic (>=1.7.4,!=1.8,!=1.8.1,<2.0.0)", "sphinx (>=4.0.2,<5.0.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "structlog (>=20.1.0,<22.0.0)", "toml (>=0.10.2,<0.11.0)"] +redis = ["redis (>=4.3,<5.0)"] [[package]] name = "dill" @@ -4125,4 +4132,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.8.0" -content-hash = "f02375f51755c9c29b4cc7a9bb052f70737c59481bfe3a4be5cfdc70a34fc0d0" +content-hash = "52030ab93d7924f9bb1c794b550bee88066f5c8c2172639833aecc958a384c70" diff --git a/pyproject.toml b/pyproject.toml index 9df9e91..2d31708 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ pyats = ">=22.7,<24" netmiko = "^3.3" ntc-templates = ">=2.0,<4" structlog = ">=20.1.0,<24" -diffsync = "^1.2" +diffsync = "^2.0.0" rich = ">=9.2" pynautobot = "^1.0.2" nornir-napalm = "^0.1.2" From 1abbfce9657614bd6b6a0fb36f0ebffa86af071a Mon Sep 17 00:00:00 2001 From: Andre Lima Date: Wed, 3 Jul 2024 15:35:34 -0300 Subject: [PATCH 06/11] adjusted for compatibility with DiffSync v2 --- network_importer/adapters/base.py | 4 +- .../adapters/nautobot_api/adapter.py | 4 +- .../adapters/nautobot_api/models.py | 138 +++++++-------- .../adapters/netbox_api/adapter.py | 4 +- .../adapters/netbox_api/models.py | 158 +++++++++--------- .../models/test_nautobot_ipaddress.py | 6 +- .../models/test_nautobot_prefix.py | 16 +- .../nautobot_api/models/test_nautobot_vlan.py | 6 +- .../models/test_netbox_ipaddress.py | 6 +- .../models/test_netbox_ipaddress_pre29.py | 2 +- .../netbox_api/models/test_netbox_prefix.py | 16 +- .../netbox_api/models/test_netbox_vlan.py | 6 +- .../models/test_netbox_vlan_pre29.py | 6 +- tests/unit/conftest.py | 68 ++++---- 14 files changed, 220 insertions(+), 220 deletions(-) diff --git a/network_importer/adapters/base.py b/network_importer/adapters/base.py index 9524b96..41e7ebd 100644 --- a/network_importer/adapters/base.py +++ b/network_importer/adapters/base.py @@ -1,10 +1,10 @@ """BaseAdapter for the network importer.""" -from diffsync import DiffSync +from diffsync import Adapter from diffsync.exceptions import ObjectNotFound from network_importer.models import Site, Device, Interface, IPAddress, Cable, Vlan, Prefix -class BaseAdapter(DiffSync): +class BaseAdapter(Adapter): """Base Adapter for the network importer.""" site = Site diff --git a/network_importer/adapters/nautobot_api/adapter.py b/network_importer/adapters/nautobot_api/adapter.py index cf7d801..f1c25ad 100644 --- a/network_importer/adapters/nautobot_api/adapter.py +++ b/network_importer/adapters/nautobot_api/adapter.py @@ -201,7 +201,7 @@ def load_nautobot_vlan(self, site): vlans = self.nautobot.ipam.vlans.filter(site=site.name) for nb_vlan in vlans: - vlan = self.vlan.create_from_pynautobot(diffsync=self, obj=nb_vlan, site_name=site.name) + vlan = self.vlan.create_from_pynautobot(adapter=self, obj=nb_vlan, site_name=site.name) self.add(vlan) site.add_child(vlan) @@ -326,7 +326,7 @@ def load_nautobot_ip_address(self, site, device): # pylint: disable=unused-argu ips = self.nautobot.ipam.ip_addresses.filter(device=device.name) for ipaddr in ips: - ip_address = self.ip_address.create_from_pynautobot(diffsync=self, obj=ipaddr, device_name=device.name) + ip_address = self.ip_address.create_from_pynautobot(adapter=self, obj=ipaddr, device_name=device.name) ip_address, _ = self.get_or_add(ip_address) interface = self.get( diff --git a/network_importer/adapters/nautobot_api/models.py b/network_importer/adapters/nautobot_api/models.py index ff66e4e..75787fc 100644 --- a/network_importer/adapters/nautobot_api/models.py +++ b/network_importer/adapters/nautobot_api/models.py @@ -4,7 +4,7 @@ import pynautobot from diffsync.exceptions import ObjectNotFound -from diffsync import DiffSync, DiffSyncModel # pylint: disable=unused-import +from diffsync import Adapter, DiffSyncModel # pylint: disable=unused-import import network_importer.config as config # pylint: disable=import-error from network_importer.adapters.nautobot_api.exceptions import NautobotObjectNotValid @@ -47,9 +47,9 @@ def get_device_tag_id(self): if self.device_tag_id: return self.device_tag_id - tag = self.diffsync.nautobot.extras.tags.get(name=f"device={self.name}") + tag = self.adapter.nautobot.extras.tags.get(name=f"device={self.name}") if not tag: - tag = self.diffsync.nautobot.extras.tags.create( + tag = self.adapter.nautobot.extras.tags.create( name=f"device={self.name}", slug=f"device__{''.join(c if c.isalnum() else '_' for c in self.name)}" ) @@ -77,7 +77,7 @@ def convert_vlan_to_nid(vlan_uid): if not vlan_uid: return None try: - vlan = self.diffsync.get(self.diffsync.vlan, identifier=vlan_uid) + vlan = self.adapter.get(self.adapter.vlan, identifier=vlan_uid) except ObjectNotFound: return None @@ -99,7 +99,7 @@ def convert_vlan_list_to_nids(vlan_uids): nb_params = {} # Identify the id of the device this interface is attached to - device = self.diffsync.get(self.diffsync.device, identifier=self.device_name) + device = self.adapter.get(self.adapter.device, identifier=self.device_name) if not device.remote_id: raise NautobotObjectNotValid(f"device {self.device_name}, is missing a remote_id") @@ -148,7 +148,7 @@ def convert_vlan_list_to_nids(vlan_uids): if "is_lag_member" in attrs and attrs["is_lag_member"] and "parent" in attrs: try: - parent_interface = self.diffsync.get(self.diffsync.interface, identifier=attrs["parent"]) + parent_interface = self.adapter.get(self.adapter.interface, identifier=attrs["parent"]) if parent_interface and parent_interface.remote_id: nb_params["lag"] = parent_interface.remote_id except ObjectNotFound: @@ -161,29 +161,29 @@ def convert_vlan_list_to_nids(vlan_uids): return nb_params @classmethod - def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: + def create(cls, adapter: "Adapter", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: """Create an interface object in Nautobot. Args: - diffsync: The master data store for other DiffSyncModel instances that we might need to reference + adapter: The master data store for other DiffSyncModel instances that we might need to reference ids: Dictionary of unique-identifiers needed to create the new object attrs: Dictionary of additional attributes to set on the new object Returns: NautobotInterface: DiffSync object newly created """ - item = super().create(ids=ids, diffsync=diffsync, attrs=attrs) + item = super().create(ids=ids, adapter=adapter, attrs=attrs) try: nb_params = item.translate_attrs_for_nautobot(attrs) - intf = diffsync.nautobot.dcim.interfaces.create(**nb_params) + intf = adapter.nautobot.dcim.interfaces.create(**nb_params) LOGGER.info("Created interface %s (%s) in Nautobot", intf.name, intf.id) except pynautobot.core.query.RequestError as exc: LOGGER.warning( "Unable to create interface %s on %s in %s (%s)", ids["name"], ids["device_name"], - diffsync.name, + adapter.name, exc.error, ) return item @@ -192,7 +192,7 @@ def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffS "Unable to create interface %s on %s in %s (%s)", ids["name"], ids["device_name"], - diffsync.name, + adapter.name, str(exc), ) return item @@ -222,7 +222,7 @@ def update(self, attrs: dict) -> Optional["DiffSyncModel"]: nb_params = self.translate_attrs_for_nautobot(current_attrs) LOGGER.debug("Update interface : %s", nb_params) try: - intf = self.diffsync.nautobot.dcim.interfaces.get(self.remote_id) + intf = self.adapter.nautobot.dcim.interfaces.get(self.remote_id) intf.update(data=nb_params) LOGGER.info("Updated Interface %s %s (%s) in Nautobot", self.device_name, self.name, self.remote_id) except pynautobot.core.query.RequestError as exc: @@ -230,7 +230,7 @@ def update(self, attrs: dict) -> Optional["DiffSyncModel"]: "Unable to update interface %s on %s in %s (%s)", self.name, self.device_name, - self.diffsync.name, + self.adapter.name, exc.error, ) return None @@ -246,7 +246,7 @@ def delete(self) -> Optional["DiffSyncModel"]: # Check if the interface has some Ips, check if it is the management interface if self.ips: try: - dev = self.diffsync.get(self.diffsync.device, identifier=self.device_name) + dev = self.adapter.get(self.adapter.device, identifier=self.device_name) if dev.primary_ip and dev.primary_ip in self.ips: LOGGER.warning( "Unable to delete interface %s on %s, because it's currently the management interface", @@ -262,14 +262,14 @@ def delete(self) -> Optional["DiffSyncModel"]: ) return None try: - intf = self.diffsync.nautobot.dcim.interfaces.get(self.remote_id) + intf = self.adapter.nautobot.dcim.interfaces.get(self.remote_id) intf.delete() except pynautobot.core.query.RequestError as exc: LOGGER.warning( "Unable to delete Interface %s on %s in %s (%s)", self.name, self.device_name, - self.diffsync.name, + self.adapter.name, exc.error, ) @@ -294,8 +294,8 @@ def translate_attrs_for_nautobot(self, attrs=None): # pylint: disable=unused-ar nb_params = {"address": self.address} try: - interface = self.diffsync.get( - self.diffsync.interface, + interface = self.adapter.get( + self.adapter.interface, identifier=dict(device_name=self.device_name, name=self.interface_name), ) nb_params["assigned_object_type"] = "dcim.interface" @@ -306,11 +306,11 @@ def translate_attrs_for_nautobot(self, attrs=None): # pylint: disable=unused-ar return nb_params @classmethod - def create_from_pynautobot(cls, diffsync: "DiffSync", obj, device_name): # pylint: disable=unused-argument + def create_from_pynautobot(cls, adapter: "Adapter", obj, device_name): # pylint: disable=unused-argument """Create a new NautobotIPAddress object from a pynautobot ip_address object. Args: - diffsync (DiffSync): Nautobot API Adapter + adapter (Adapter): Nautobot API Adapter obj (pynautobot.models.ipam.IpAddresses): IPAddress object returned by pynautobot device_name (str): name of the device associated with this ip address Returns: @@ -320,24 +320,24 @@ def create_from_pynautobot(cls, diffsync: "DiffSync", obj, device_name): # pyli address=obj.address, device_name=device_name, interface_name=obj.assigned_object.name, remote_id=obj.id ) - item = diffsync.apply_model_flag(item, obj) + item = adapter.apply_model_flag(item, obj) return item @classmethod - def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: + def create(cls, adapter: "Adapter", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: """Create an IP address in Nautobot, if the name of a valid interface is provided the interface will be assigned to the interface. Returns: NautobotIPAddress: DiffSync object """ try: - item = super().create(ids=ids, diffsync=diffsync, attrs=attrs) + item = super().create(ids=ids, adapter=adapter, attrs=attrs) nb_params = item.translate_attrs_for_nautobot(attrs) # Add status because it's a mandatory field. nb_params["status"] = "active" - ip_address = diffsync.nautobot.ipam.ip_addresses.create(**nb_params) + ip_address = adapter.nautobot.ipam.ip_addresses.create(**nb_params) except pynautobot.core.query.RequestError as exc: - LOGGER.warning("Unable to create the ip address %s in %s (%s)", ids["address"], diffsync.name, exc.error) + LOGGER.warning("Unable to create the ip address %s in %s (%s)", ids["address"], adapter.name, exc.error) return None LOGGER.info("Created IP %s (%s) in Nautobot", ip_address.address, ip_address.id) @@ -353,7 +353,7 @@ def delete(self) -> Optional["DiffSyncModel"]: """ if self.device_name: try: - dev = self.diffsync.get(self.diffsync.device, identifier=self.device_name) + dev = self.adapter.get(self.adapter.device, identifier=self.device_name) if dev.primary_ip == self.address: LOGGER.warning( "Unable to delete IP Address %s on %s, because it's currently the management IP address", @@ -369,7 +369,7 @@ def delete(self) -> Optional["DiffSyncModel"]: ) return None try: - ipaddr = self.diffsync.nautobot.ipam.ip_addresses.get(self.remote_id) + ipaddr = self.adapter.nautobot.ipam.ip_addresses.get(self.remote_id) if ipaddr: ipaddr.delete() else: @@ -377,14 +377,14 @@ def delete(self) -> Optional["DiffSyncModel"]: "Unable to delete IP address %s on %s in %s because IP address object cannot be located", self.address, self.device_name, - self.diffsync.name, + self.adapter.name, ) except pynautobot.core.query.RequestError as exc: LOGGER.warning( "Unable to delete IP Address %s on %s in %s (%s)", self.address, self.device_name, - self.diffsync.name, + self.adapter.name, exc.error, ) return None @@ -409,12 +409,12 @@ def translate_attrs_for_nautobot(self, attrs): """ nb_params = {"prefix": self.prefix, "status": "active"} - site = self.diffsync.get(self.diffsync.site, identifier=self.site_name) + site = self.adapter.get(self.adapter.site, identifier=self.site_name) nb_params["site"] = site.remote_id if "vlan" in attrs and attrs["vlan"]: try: - vlan = self.diffsync.get(self.diffsync.vlan, identifier=attrs["vlan"]) + vlan = self.adapter.get(self.adapter.vlan, identifier=attrs["vlan"]) if vlan.remote_id: nb_params["vlan"] = vlan.remote_id except ObjectNotFound: @@ -423,20 +423,20 @@ def translate_attrs_for_nautobot(self, attrs): return nb_params @classmethod - def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: + def create(cls, adapter: "Adapter", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: """Create a Prefix in Nautobot. Returns: NautobotPrefix: DiffSync object """ - item = super().create(ids=ids, diffsync=diffsync, attrs=attrs) + item = super().create(ids=ids, adapter=adapter, attrs=attrs) nb_params = item.translate_attrs_for_nautobot(attrs) try: - prefix = diffsync.nautobot.ipam.prefixes.create(**nb_params) + prefix = adapter.nautobot.ipam.prefixes.create(**nb_params) LOGGER.info("Created Prefix %s (%s) in Nautobot", prefix.prefix, prefix.id) except pynautobot.core.query.RequestError as exc: - LOGGER.warning("Unable to create Prefix %s in %s (%s)", ids["prefix"], diffsync.name, exc.error) + LOGGER.warning("Unable to create Prefix %s in %s (%s)", ids["prefix"], adapter.name, exc.error) return None item.remote_id = prefix.id @@ -464,14 +464,14 @@ def update(self, attrs: dict) -> Optional["DiffSyncModel"]: nb_params = self.translate_attrs_for_nautobot(attrs) try: - prefix = self.diffsync.nautobot.ipam.prefixes.get(self.remote_id) + prefix = self.adapter.nautobot.ipam.prefixes.get(self.remote_id) prefix.update(data=nb_params) LOGGER.info("Updated Prefix %s (%s) in Nautobot", self.prefix, self.remote_id) except pynautobot.core.query.RequestError as exc: LOGGER.warning( "Unable to update perfix %s in %s (%s)", self.prefix, - self.diffsync.name, + self.adapter.name, exc.error, ) return None @@ -501,7 +501,7 @@ def translate_attrs_for_nautobot(self, attrs): elif not self.name: nb_params["name"] = f"vlan-{self.vid}" - site = self.diffsync.get(self.diffsync.site, identifier=self.site_name) + site = self.adapter.get(self.adapter.site, identifier=self.site_name) nb_params["site"] = site.remote_id # Add Status @@ -511,7 +511,7 @@ def translate_attrs_for_nautobot(self, attrs): nb_params["tags"] = [] for device_name in attrs["associated_devices"]: try: - device = self.diffsync.get(self.diffsync.device, identifier=device_name) + device = self.adapter.get(self.adapter.device, identifier=device_name) except ObjectNotFound: LOGGER.warning( "Found an associated device on Vlan %s that doesn't exist (%s)", @@ -531,11 +531,11 @@ def translate_attrs_for_nautobot(self, attrs): return nb_params @classmethod - def create_from_pynautobot(cls, diffsync: "DiffSync", obj, site_name): + def create_from_pynautobot(cls, adapter: "Adapter", obj, site_name): """Create a new NautobotVlan object from a pynautobot vlan object. Args: - diffsync (DiffSync): Nautobot API Adapter + adapter (Adapter): Nautobot API Adapter obj (pynautobot.models.ipam.Vlans): Vlan object returned by Pynautobot site_name (str): name of the site associated with this vlan @@ -552,32 +552,32 @@ def create_from_pynautobot(cls, diffsync: "DiffSync", obj, site_name): device_name = tag["name"].split(item.tag_prefix)[1] try: - device = diffsync.get(diffsync.device, identifier=device_name) + device = adapter.get(adapter.device, identifier=device_name) except ObjectNotFound: device = None if device: item.add_device(device_name) device.device_tag_id = tag["id"] - item = diffsync.apply_model_flag(item, obj) + item = adapter.apply_model_flag(item, obj) return item @classmethod - def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: + def create(cls, adapter: "Adapter", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: """Create new Vlan in Nautobot. Returns: NautobotVlan: DiffSync object """ try: - item = super().create(ids=ids, diffsync=diffsync, attrs=attrs) + item = super().create(ids=ids, adapter=adapter, attrs=attrs) nb_params = item.translate_attrs_for_nautobot(attrs) - vlan = diffsync.nautobot.ipam.vlans.create(**nb_params) + vlan = adapter.nautobot.ipam.vlans.create(**nb_params) item.remote_id = vlan.id - LOGGER.info("Created Vlan %s in %s (%s)", item.get_unique_id(), diffsync.name, vlan.id) + LOGGER.info("Created Vlan %s in %s (%s)", item.get_unique_id(), adapter.name, vlan.id) except pynautobot.core.query.RequestError as exc: - LOGGER.warning("Unable to create Vlan %s in %s (%s)", ids, diffsync.name, exc.error) + LOGGER.warning("Unable to create Vlan %s in %s (%s)", ids, adapter.name, exc.error) return None return item @@ -598,7 +598,7 @@ def update_clean_tags(self, nb_params, obj): else: dev_name = tag["name"].split(self.tag_prefix)[1] try: - res = self.diffsync.get(self.diffsync.device, identifier=dev_name) + res = self.adapter.get(self.adapter.device, identifier=dev_name) except ObjectNotFound: res = None if not res: @@ -615,12 +615,12 @@ def update(self, attrs: dict) -> Optional["DiffSyncModel"]: nb_params = self.translate_attrs_for_nautobot(attrs) try: - vlan = self.diffsync.nautobot.ipam.vlans.get(self.remote_id) + vlan = self.adapter.nautobot.ipam.vlans.get(self.remote_id) clean_params = self.update_clean_tags(nb_params=nb_params, obj=vlan) vlan.update(data=clean_params) LOGGER.info("Updated Vlan %s (%s) in Nautobot", self.get_unique_id(), self.remote_id) except pynautobot.core.query.RequestError as exc: - LOGGER.warning("Unable to update Vlan %s in %s (%s)", self.get_unique_id(), self.diffsync.name, exc.error) + LOGGER.warning("Unable to update Vlan %s in %s (%s)", self.get_unique_id(), self.adapter.name, exc.error) return None return super().update(attrs) @@ -634,45 +634,45 @@ class NautobotCable(Cable): termination_z_id: Optional[str] = None @classmethod - def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: + def create(cls, adapter: "Adapter", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: """Create a Cable in Nautobot. Returns: NautobotCable: DiffSync object """ - item = super().create(ids=ids, diffsync=diffsync, attrs=attrs) + item = super().create(ids=ids, adapter=adapter, attrs=attrs) try: - interface_a = diffsync.get( - diffsync.interface, identifier=dict(device_name=ids["device_a_name"], name=ids["interface_a_name"]) + interface_a = adapter.get( + adapter.interface, identifier=dict(device_name=ids["device_a_name"], name=ids["interface_a_name"]) ) except ObjectNotFound: - interface_a = diffsync.get_intf_from_nautobot( + interface_a = adapter.get_intf_from_nautobot( device_name=ids["device_a_name"], intf_name=ids["interface_a_name"] ) if not interface_a: LOGGER.info( "Unable to create Cable %s in %s, unable to find the interface %s %s", item.get_unique_id(), - diffsync.name, + adapter.name, ids["device_a_name"], ids["interface_a_name"], ) return item try: - interface_z = diffsync.get( - diffsync.interface, identifier=dict(device_name=ids["device_z_name"], name=ids["interface_z_name"]) + interface_z = adapter.get( + adapter.interface, identifier=dict(device_name=ids["device_z_name"], name=ids["interface_z_name"]) ) except ObjectNotFound: - interface_z = diffsync.get_intf_from_nautobot( + interface_z = adapter.get_intf_from_nautobot( device_name=ids["device_z_name"], intf_name=ids["interface_z_name"] ) if not interface_z: LOGGER.info( "Unable to create Cable %s in %s, unable to find the interface %s %s", item.get_unique_id(), - diffsync.name, + adapter.name, ids["device_z_name"], ids["interface_z_name"], ) @@ -681,7 +681,7 @@ def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffS if interface_a.connected_endpoint_type: LOGGER.info( "Unable to create Cable in %s, port %s %s is already connected", - diffsync.name, + adapter.name, ids["device_a_name"], ids["interface_a_name"], ) @@ -690,14 +690,14 @@ def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffS if interface_z.connected_endpoint_type: LOGGER.info( "Unable to create Cable in %s, port %s %s is already connected", - diffsync.name, + adapter.name, ids["device_z_name"], ids["interface_z_name"], ) return item try: - cable = diffsync.nautobot.dcim.cables.create( + cable = adapter.nautobot.dcim.cables.create( termination_a_type="dcim.interface", termination_b_type="dcim.interface", termination_a_id=interface_a.remote_id, @@ -705,7 +705,7 @@ def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffS status="connected", ) except pynautobot.core.query.RequestError as exc: - LOGGER.warning("Unable to create Cable %s in %s (%s)", ids, diffsync.name, exc.error) + LOGGER.warning("Unable to create Cable %s in %s (%s)", ids, adapter.name, exc.error) return item interface_a.connected_endpoint_type = "dcim.interface" @@ -725,12 +725,12 @@ def delete(self): LOGGER.warning( "Cable %s is present in %s but not in the Network, please delete it manually if it shouldn't be in %s", self.get_unique_id(), - self.diffsync.name, - self.diffsync.name, + self.adapter.name, + self.adapter.name, ) # try: - # cable = self.diffsync.nautobot.dcim.cables.get(self.remote_id) + # cable = self.adapter.nautobot.dcim.cables.get(self.remote_id) # cable.delete() # except pynautobot.core.query.RequestError as exc: # diff --git a/network_importer/adapters/netbox_api/adapter.py b/network_importer/adapters/netbox_api/adapter.py index 80e805d..9747bb4 100644 --- a/network_importer/adapters/netbox_api/adapter.py +++ b/network_importer/adapters/netbox_api/adapter.py @@ -208,7 +208,7 @@ def load_netbox_vlan(self, site): vlans = self.netbox.ipam.vlans.filter(site=site.name) for nb_vlan in vlans: - vlan = self.vlan.create_from_pynetbox(diffsync=self, obj=nb_vlan, site_name=site.name) + vlan = self.vlan.create_from_pynetbox(adapter=self, obj=nb_vlan, site_name=site.name) self.add(vlan) site.add_child(vlan) @@ -333,7 +333,7 @@ def load_netbox_ip_address(self, site, device): # pylint: disable=unused-argume ips = self.netbox.ipam.ip_addresses.filter(device=device.name) for ipaddr in ips: - ip_address = self.ip_address.create_from_pynetbox(diffsync=self, obj=ipaddr, device_name=device.name) + ip_address = self.ip_address.create_from_pynetbox(adapter=self, obj=ipaddr, device_name=device.name) ip_address, _ = self.get_or_add(ip_address) interface = self.get( diff --git a/network_importer/adapters/netbox_api/models.py b/network_importer/adapters/netbox_api/models.py index ce46f1d..b596096 100644 --- a/network_importer/adapters/netbox_api/models.py +++ b/network_importer/adapters/netbox_api/models.py @@ -4,7 +4,7 @@ import pynetbox from diffsync.exceptions import ObjectNotFound -from diffsync import DiffSync, DiffSyncModel # pylint: disable=unused-import +from diffsync import Adapter, DiffSyncModel # pylint: disable=unused-import import network_importer.config as config # pylint: disable=import-error from network_importer.adapters.netbox_api.exceptions import NetboxObjectNotValid @@ -47,10 +47,10 @@ def get_device_tag_id(self): if self.device_tag_id: return self.device_tag_id - tag = self.diffsync.netbox.extras.tags.get(name=f"device={self.name}") + tag = self.adapter.netbox.extras.tags.get(name=f"device={self.name}") if not tag: - tag = self.diffsync.netbox.extras.tags.create(name=f"device={self.name}", slug=f"device__{self.name}") + tag = self.adapter.netbox.extras.tags.create(name=f"device={self.name}", slug=f"device__{self.name}") self.device_tag_id = tag.id return self.device_tag_id @@ -76,7 +76,7 @@ def convert_vlan_to_nid(vlan_uid): if not vlan_uid: return None try: - vlan = self.diffsync.get(self.diffsync.vlan, identifier=vlan_uid) + vlan = self.adapter.get(self.adapter.vlan, identifier=vlan_uid) except ObjectNotFound: return None @@ -98,7 +98,7 @@ def convert_vlan_list_to_nids(vlan_uids): nb_params = {} # Identify the id of the device this interface is attached to - device = self.diffsync.get(self.diffsync.device, identifier=self.device_name) + device = self.adapter.get(self.adapter.device, identifier=self.device_name) if not device.remote_id: raise NetboxObjectNotValid(f"device {self.device_name}, is missing a remote_id") @@ -147,7 +147,7 @@ def convert_vlan_list_to_nids(vlan_uids): if "is_lag_member" in attrs and attrs["is_lag_member"] and "parent" in attrs: try: - parent_interface = self.diffsync.get(self.diffsync.interface, identifier=attrs["parent"]) + parent_interface = self.adapter.get(self.adapter.interface, identifier=attrs["parent"]) if parent_interface and parent_interface.remote_id: nb_params["lag"] = parent_interface.remote_id except ObjectNotFound: @@ -160,29 +160,29 @@ def convert_vlan_list_to_nids(vlan_uids): return nb_params @classmethod - def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: + def create(cls, adapter: "Adapter", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: """Create an interface object in Netbox. Args: - diffsync: The master data store for other DiffSyncModel instances that we might need to reference + adapter: The master data store for other DiffSyncModel instances that we might need to reference ids: Dictionary of unique-identifiers needed to create the new object attrs: Dictionary of additional attributes to set on the new object Returns: NetboxInterface: DiffSync object newly created """ - item = super().create(ids=ids, diffsync=diffsync, attrs=attrs) + item = super().create(ids=ids, adapter=adapter, attrs=attrs) try: nb_params = item.translate_attrs_for_netbox(attrs) - intf = diffsync.netbox.dcim.interfaces.create(**nb_params) + intf = adapter.netbox.dcim.interfaces.create(**nb_params) LOGGER.info("Created interface %s (%s) in NetBox", intf.name, intf.id) except pynetbox.core.query.RequestError as exc: LOGGER.warning( "Unable to create interface %s on %s in %s (%s)", ids["name"], ids["device_name"], - diffsync.name, + adapter.name, exc.error, ) return item @@ -191,7 +191,7 @@ def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffS "Unable to create interface %s on %s in %s (%s)", ids["name"], ids["device_name"], - diffsync.name, + adapter.name, str(exc), ) return item @@ -221,7 +221,7 @@ def update(self, attrs: dict) -> Optional["DiffSyncModel"]: nb_params = self.translate_attrs_for_netbox(current_attrs) LOGGER.debug("Update interface : %s", nb_params) try: - intf = self.diffsync.netbox.dcim.interfaces.get(self.remote_id) + intf = self.adapter.netbox.dcim.interfaces.get(self.remote_id) intf.update(data=nb_params) LOGGER.info("Updated Interface %s %s (%s) in NetBox", self.device_name, self.name, self.remote_id) except pynetbox.core.query.RequestError as exc: @@ -229,7 +229,7 @@ def update(self, attrs: dict) -> Optional["DiffSyncModel"]: "Unable to update interface %s on %s in %s (%s)", self.name, self.device_name, - self.diffsync.name, + self.adapter.name, exc.error, ) return None @@ -245,7 +245,7 @@ def delete(self) -> Optional["DiffSyncModel"]: # Check if the interface has some Ips, check if it is the management interface if self.ips: try: - dev = self.diffsync.get(self.diffsync.device, identifier=self.device_name) + dev = self.adapter.get(self.adapter.device, identifier=self.device_name) if dev.primary_ip and dev.primary_ip in self.ips: LOGGER.warning( "Unable to delete interface %s on %s, because it's currently the management interface", @@ -261,14 +261,14 @@ def delete(self) -> Optional["DiffSyncModel"]: ) return None try: - intf = self.diffsync.netbox.dcim.interfaces.get(self.remote_id) + intf = self.adapter.netbox.dcim.interfaces.get(self.remote_id) intf.delete() except pynetbox.core.query.RequestError as exc: LOGGER.warning( "Unable to delete Interface %s on %s in %s (%s)", self.name, self.device_name, - self.diffsync.name, + self.adapter.name, exc.error, ) @@ -293,8 +293,8 @@ def translate_attrs_for_netbox(self, attrs=None): # pylint: disable=unused-argu nb_params = {"address": self.address} try: - interface = self.diffsync.get( - self.diffsync.interface, + interface = self.adapter.get( + self.adapter.interface, identifier=dict(device_name=self.device_name, name=self.interface_name), ) nb_params["assigned_object_type"] = "dcim.interface" @@ -305,11 +305,11 @@ def translate_attrs_for_netbox(self, attrs=None): # pylint: disable=unused-argu return nb_params @classmethod - def create_from_pynetbox(cls, diffsync: "DiffSync", obj, device_name): # pylint: disable=unused-argument + def create_from_pynetbox(cls, adapter: "Adapter", obj, device_name): # pylint: disable=unused-argument """Create a new NetboxIPAddress object from a pynetbox ip_address object. Args: - diffsync (DiffSync): Netbox API Adapter + adapter (Adapter): Netbox API Adapter obj (pynetbox.models.ipam.IpAddresses): IPAddress object returned by Pynetbox device_name (str): name of the device associated with this ip address Returns: @@ -319,22 +319,22 @@ def create_from_pynetbox(cls, diffsync: "DiffSync", obj, device_name): # pylint address=obj.address, device_name=device_name, interface_name=obj.assigned_object.name, remote_id=obj.id ) - item = diffsync.apply_model_flag(item, obj) + item = adapter.apply_model_flag(item, obj) return item @classmethod - def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: + def create(cls, adapter: "Adapter", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: """Create an IP address in Netbox, if the name of a valid interface is provided the interface will be assigned to the interface. Returns: NetboxIPAddress: DiffSync object """ try: - item = super().create(ids=ids, diffsync=diffsync, attrs=attrs) + item = super().create(ids=ids, adapter=adapter, attrs=attrs) nb_params = item.translate_attrs_for_netbox(attrs) - ip_address = diffsync.netbox.ipam.ip_addresses.create(**nb_params) + ip_address = adapter.netbox.ipam.ip_addresses.create(**nb_params) except pynetbox.core.query.RequestError as exc: - LOGGER.warning("Unable to create the ip address %s in %s (%s)", ids["address"], diffsync.name, exc.error) + LOGGER.warning("Unable to create the ip address %s in %s (%s)", ids["address"], adapter.name, exc.error) return None LOGGER.info("Created IP %s (%s) in NetBox", ip_address.address, ip_address.id) @@ -350,7 +350,7 @@ def delete(self) -> Optional["DiffSyncModel"]: """ if self.device_name: try: - dev = self.diffsync.get(self.diffsync.device, identifier=self.device_name) + dev = self.adapter.get(self.adapter.device, identifier=self.device_name) if dev.primary_ip == self.address: LOGGER.warning( "Unable to delete IP Address %s on %s, because it's currently the management IP address", @@ -366,14 +366,14 @@ def delete(self) -> Optional["DiffSyncModel"]: ) return None try: - ipaddr = self.diffsync.netbox.ipam.ip_addresses.get(self.remote_id) + ipaddr = self.adapter.netbox.ipam.ip_addresses.get(self.remote_id) ipaddr.delete() except pynetbox.core.query.RequestError as exc: LOGGER.warning( "Unable to delete IP Address %s on %s in %s (%s)", self.address, self.device_name, - self.diffsync.name, + self.adapter.name, exc.error, ) return None @@ -400,8 +400,8 @@ def translate_attrs_for_netbox(self, attrs=None): nb_params = {"address": self.address} try: - interface = self.diffsync.get( - self.diffsync.interface, + interface = self.adapter.get( + self.adapter.interface, identifier=dict(device_name=self.device_name, name=self.interface_name), ) nb_params["interface"] = interface.remote_id @@ -411,18 +411,18 @@ def translate_attrs_for_netbox(self, attrs=None): return nb_params @classmethod - def create_from_pynetbox(cls, diffsync: "DiffSync", obj, device_name): + def create_from_pynetbox(cls, adapter: "Adapter", obj, device_name): """Create a new NetboxIPAddress object from a pynetbox ip_address object specific for version of NetBox prior to 2.9. Args: - diffsync (DiffSync): Netbox API Adapter + adapter (Adapter): Netbox API Adapter obj (pynetbox.models.ipam.IpAddresses): IPAddress object returned by Pynetbox device_name (str): name of the device associated with this ip address Returns: NetboxIPAddress: DiffSync object """ item = cls(address=obj.address, device_name=device_name, interface_name=obj.interface.name, remote_id=obj.id) - item = diffsync.apply_model_flag(item, obj) + item = adapter.apply_model_flag(item, obj) return item @@ -443,12 +443,12 @@ def translate_attrs_for_netbox(self, attrs): """ nb_params = {"prefix": self.prefix, "status": "active"} - site = self.diffsync.get(self.diffsync.site, identifier=self.site_name) + site = self.adapter.get(self.adapter.site, identifier=self.site_name) nb_params["site"] = site.remote_id if "vlan" in attrs and attrs["vlan"]: try: - vlan = self.diffsync.get(self.diffsync.vlan, identifier=attrs["vlan"]) + vlan = self.adapter.get(self.adapter.vlan, identifier=attrs["vlan"]) if vlan.remote_id: nb_params["vlan"] = vlan.remote_id except ObjectNotFound: @@ -457,20 +457,20 @@ def translate_attrs_for_netbox(self, attrs): return nb_params @classmethod - def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: + def create(cls, adapter: "Adapter", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: """Create a Prefix in NetBox. Returns: NetboxPrefix: DiffSync object """ - item = super().create(ids=ids, diffsync=diffsync, attrs=attrs) + item = super().create(ids=ids, adapter=adapter, attrs=attrs) nb_params = item.translate_attrs_for_netbox(attrs) try: - prefix = diffsync.netbox.ipam.prefixes.create(**nb_params) + prefix = adapter.netbox.ipam.prefixes.create(**nb_params) LOGGER.info("Created Prefix %s (%s) in NetBox", prefix.prefix, prefix.id) except pynetbox.core.query.RequestError as exc: - LOGGER.warning("Unable to create Prefix %s in %s (%s)", ids["prefix"], diffsync.name, exc.error) + LOGGER.warning("Unable to create Prefix %s in %s (%s)", ids["prefix"], adapter.name, exc.error) return None item.remote_id = prefix.id @@ -498,14 +498,14 @@ def update(self, attrs: dict) -> Optional["DiffSyncModel"]: nb_params = self.translate_attrs_for_netbox(attrs) try: - prefix = self.diffsync.netbox.ipam.prefixes.get(self.remote_id) + prefix = self.adapter.netbox.ipam.prefixes.get(self.remote_id) prefix.update(data=nb_params) LOGGER.info("Updated Prefix %s (%s) in NetBox", self.prefix, self.remote_id) except pynetbox.core.query.RequestError as exc: LOGGER.warning( "Unable to update perfix %s in %s (%s)", self.prefix, - self.diffsync.name, + self.adapter.name, exc.error, ) return None @@ -535,14 +535,14 @@ def translate_attrs_for_netbox(self, attrs): elif not self.name: nb_params["name"] = f"vlan-{self.vid}" - site = self.diffsync.get(self.diffsync.site, identifier=self.site_name) + site = self.adapter.get(self.adapter.site, identifier=self.site_name) nb_params["site"] = site.remote_id if "associated_devices" in attrs: nb_params["tags"] = [] for device_name in attrs["associated_devices"]: try: - device = self.diffsync.get(self.diffsync.device, identifier=device_name) + device = self.adapter.get(self.adapter.device, identifier=device_name) except ObjectNotFound: LOGGER.error( "Found an associated device on Vlan %s that doesn't exist (%s)", @@ -557,11 +557,11 @@ def translate_attrs_for_netbox(self, attrs): return nb_params @classmethod - def create_from_pynetbox(cls, diffsync: "DiffSync", obj, site_name): + def create_from_pynetbox(cls, adapter: "Adapter", obj, site_name): """Create a new NetboxVlan object from a pynetbox vlan object. Args: - diffsync (DiffSync): Netbox API Adapter + adapter (Adapter): Netbox API Adapter obj (pynetbox.models.ipam.Vlans): Vlan object returned by Pynetbox site_name (str): name of the site associated with this vlan @@ -578,32 +578,32 @@ def create_from_pynetbox(cls, diffsync: "DiffSync", obj, site_name): device_name = tag["name"].split(item.tag_prefix)[1] try: - device = diffsync.get(diffsync.device, identifier=device_name) + device = adapter.get(adapter.device, identifier=device_name) except ObjectNotFound: device = None if device: item.add_device(device_name) device.device_tag_id = tag["id"] - item = diffsync.apply_model_flag(item, obj) + item = adapter.apply_model_flag(item, obj) return item @classmethod - def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: + def create(cls, adapter: "Adapter", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: """Create new Vlan in NetBox. Returns: NetboxVlan: DiffSync object """ try: - item = super().create(ids=ids, diffsync=diffsync, attrs=attrs) + item = super().create(ids=ids, adapter=adapter, attrs=attrs) nb_params = item.translate_attrs_for_netbox(attrs) - vlan = diffsync.netbox.ipam.vlans.create(**nb_params) + vlan = adapter.netbox.ipam.vlans.create(**nb_params) item.remote_id = vlan.id - LOGGER.info("Created Vlan %s in %s (%s)", item.get_unique_id(), diffsync.name, vlan.id) + LOGGER.info("Created Vlan %s in %s (%s)", item.get_unique_id(), adapter.name, vlan.id) except pynetbox.core.query.RequestError as exc: - LOGGER.warning("Unable to create Vlan %s in %s (%s)", ids, diffsync.name, exc.error) + LOGGER.warning("Unable to create Vlan %s in %s (%s)", ids, adapter.name, exc.error) return None return item @@ -624,7 +624,7 @@ def update_clean_tags(self, nb_params, obj): else: dev_name = tag["name"].split(self.tag_prefix)[1] try: - res = self.diffsync.get(self.diffsync.device, identifier=dev_name) + res = self.adapter.get(self.adapter.device, identifier=dev_name) except ObjectNotFound: res = None if not res: @@ -641,12 +641,12 @@ def update(self, attrs: dict) -> Optional["DiffSyncModel"]: nb_params = self.translate_attrs_for_netbox(attrs) try: - vlan = self.diffsync.netbox.ipam.vlans.get(self.remote_id) + vlan = self.adapter.netbox.ipam.vlans.get(self.remote_id) clean_params = self.update_clean_tags(nb_params=nb_params, obj=vlan) vlan.update(data=clean_params) LOGGER.info("Updated Vlan %s (%s) in NetBox", self.get_unique_id(), self.remote_id) except pynetbox.core.query.RequestError as exc: - LOGGER.warning("Unable to update Vlan %s in %s (%s)", self.get_unique_id(), self.diffsync.name, exc.error) + LOGGER.warning("Unable to update Vlan %s in %s (%s)", self.get_unique_id(), self.adapter.name, exc.error) return None return super().update(attrs) @@ -674,7 +674,7 @@ def translate_attrs_for_netbox(self, attrs): elif not self.name: nb_params["name"] = f"vlan-{self.vid}" - site = self.diffsync.get(self.diffsync.site, identifier=self.site_name) + site = self.adapter.get(self.adapter.site, identifier=self.site_name) nb_params["site"] = site.remote_id if "associated_devices" in attrs: @@ -683,11 +683,11 @@ def translate_attrs_for_netbox(self, attrs): return nb_params @classmethod - def create_from_pynetbox(cls, diffsync: "DiffSync", obj, site_name): + def create_from_pynetbox(cls, adapter: "Adapter", obj, site_name): """Create a new NetboxVlan object from a pynetbox vlan object for version of NetBox prior to 2.9. Args: - diffsync (DiffSync): Netbox API Adapter + adapter (Adapter): Netbox API Adapter obj (pynetbox.models.ipam.Vlans): Vlan object returned by Pynetbox site_name (str): name of the site associated with this vlan @@ -702,12 +702,12 @@ def create_from_pynetbox(cls, diffsync: "DiffSync", obj, site_name): all_devices = [tag.split(item.tag_prefix)[1] for tag in obj.tags if item.tag_prefix in tag] for device in all_devices: try: - diffsync.get(diffsync.device, identifier=device) + adapter.get(adapter.device, identifier=device) item.add_device(device) except ObjectNotFound: pass - item = diffsync.apply_model_flag(item, obj) + item = adapter.apply_model_flag(item, obj) return item @@ -727,7 +727,7 @@ def update_clean_tags(self, nb_params, obj): else: dev_name = tag.split(self.tag_prefix)[1] try: - self.diffsync.get(self.diffsync.device, identifier=dev_name) + self.adapter.get(self.adapter.device, identifier=dev_name) except ObjectNotFound: nb_params["tags"].append(tag) @@ -742,45 +742,45 @@ class NetboxCable(Cable): termination_z_id: Optional[int] = None @classmethod - def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: + def create(cls, adapter: "Adapter", ids: dict, attrs: dict) -> Optional["DiffSyncModel"]: """Create a Cable in NetBox. Returns: NetboxCable: DiffSync object """ - item = super().create(ids=ids, diffsync=diffsync, attrs=attrs) + item = super().create(ids=ids, adapter=adapter, attrs=attrs) try: - interface_a = diffsync.get( - diffsync.interface, identifier=dict(device_name=ids["device_a_name"], name=ids["interface_a_name"]) + interface_a = adapter.get( + adapter.interface, identifier=dict(device_name=ids["device_a_name"], name=ids["interface_a_name"]) ) except ObjectNotFound: - interface_a = diffsync.get_intf_from_netbox( + interface_a = adapter.get_intf_from_netbox( device_name=ids["device_a_name"], intf_name=ids["interface_a_name"] ) if not interface_a: LOGGER.info( "Unable to create Cable %s in %s, unable to find the interface %s %s", item.get_unique_id(), - diffsync.name, + adapter.name, ids["device_a_name"], ids["interface_a_name"], ) return item try: - interface_z = diffsync.get( - diffsync.interface, identifier=dict(device_name=ids["device_z_name"], name=ids["interface_z_name"]) + interface_z = adapter.get( + adapter.interface, identifier=dict(device_name=ids["device_z_name"], name=ids["interface_z_name"]) ) except ObjectNotFound: - interface_z = diffsync.get_intf_from_netbox( + interface_z = adapter.get_intf_from_netbox( device_name=ids["device_z_name"], intf_name=ids["interface_z_name"] ) if not interface_z: LOGGER.info( "Unable to create Cable %s in %s, unable to find the interface %s %s", item.get_unique_id(), - diffsync.name, + adapter.name, ids["device_z_name"], ids["interface_z_name"], ) @@ -789,7 +789,7 @@ def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffS if interface_a.connected_endpoint_type: LOGGER.info( "Unable to create Cable in %s, port %s %s is already connected", - diffsync.name, + adapter.name, ids["device_a_name"], ids["interface_a_name"], ) @@ -798,21 +798,21 @@ def create(cls, diffsync: "DiffSync", ids: dict, attrs: dict) -> Optional["DiffS if interface_z.connected_endpoint_type: LOGGER.info( "Unable to create Cable in %s, port %s %s is already connected", - diffsync.name, + adapter.name, ids["device_z_name"], ids["interface_z_name"], ) return item try: - cable = diffsync.netbox.dcim.cables.create( + cable = adapter.netbox.dcim.cables.create( termination_a_type="dcim.interface", termination_b_type="dcim.interface", termination_a_id=interface_a.remote_id, termination_b_id=interface_z.remote_id, ) except pynetbox.core.query.RequestError as exc: - LOGGER.warning("Unable to create Cable %s in %s (%s)", ids, diffsync.name, exc.error) + LOGGER.warning("Unable to create Cable %s in %s (%s)", ids, adapter.name, exc.error) return item interface_a.connected_endpoint_type = "dcim.interface" @@ -832,12 +832,12 @@ def delete(self): LOGGER.warning( "Cable %s is present in %s but not in the Network, please delete it manually if it shouldn't be in %s", self.get_unique_id(), - self.diffsync.name, - self.diffsync.name, + self.adapter.name, + self.adapter.name, ) # try: - # cable = self.diffsync.netbox.dcim.cables.get(self.remote_id) + # cable = self.adapter.netbox.dcim.cables.get(self.remote_id) # cable.delete() # except pynetbox.core.query.RequestError as exc: # diff --git a/tests/unit/adapters/nautobot_api/models/test_nautobot_ipaddress.py b/tests/unit/adapters/nautobot_api/models/test_nautobot_ipaddress.py index 436e2dc..61ff3b0 100644 --- a/tests/unit/adapters/nautobot_api/models/test_nautobot_ipaddress.py +++ b/tests/unit/adapters/nautobot_api/models/test_nautobot_ipaddress.py @@ -47,7 +47,7 @@ def test_create_from_pynautobot(nautobot_api_base): data = yaml.safe_load(open(f"{ROOT}/../fixtures/ip_address.json")) pnb = pynautobot.core.response.Record(values=data, api=api, endpoint=1) - ipaddr = NautobotIPAddress.create_from_pynautobot(diffsync=nautobot_api_base, obj=pnb, device_name="HQ-CORE-SW02") + ipaddr = NautobotIPAddress.create_from_pynautobot(adapter=nautobot_api_base, obj=pnb, device_name="HQ-CORE-SW02") assert ipaddr.interface_name == "TenGigabitEthernet1/0/1" assert ipaddr.device_name == "HQ-CORE-SW02" @@ -59,7 +59,7 @@ def test_create_ip_address_interface(requests_mock, nautobot_api_base): requests_mock.post("http://mock_nautobot/api/ipam/ip-addresses/", json=data, status_code=201) ip_address = NautobotIPAddress.create( - diffsync=nautobot_api_base, + adapter=nautobot_api_base, ids=dict(address="10.63.0.2/31", interface_name="TenGigabitEthernet1/0/1", device_name="HQ-CORE-SW02"), attrs=dict(), ) @@ -74,7 +74,7 @@ def test_create_ip_address_no_interface(requests_mock, nautobot_api_base): requests_mock.post("http://mock_nautobot/api/ipam/ip-addresses/", json=data, status_code=201) ip_address = NautobotIPAddress.create( - diffsync=nautobot_api_base, + adapter=nautobot_api_base, ids=dict(address="10.63.0.2/31", interface_name="TenGigabitEthernet1/0/1", device_name="HQ-CORE-SW02"), attrs=dict(), ) diff --git a/tests/unit/adapters/nautobot_api/models/test_nautobot_prefix.py b/tests/unit/adapters/nautobot_api/models/test_nautobot_prefix.py index 759a908..3cc5ac9 100644 --- a/tests/unit/adapters/nautobot_api/models/test_nautobot_prefix.py +++ b/tests/unit/adapters/nautobot_api/models/test_nautobot_prefix.py @@ -9,7 +9,7 @@ def test_translate_attrs_for_nautobot_default(nautobot_api_base): prefix = NautobotPrefix( - diffsync=nautobot_api_base, + adapter=nautobot_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id="014b6519-bf43-40f7-a40f-d5abb9828cd2", @@ -23,7 +23,7 @@ def test_translate_attrs_for_nautobot_default(nautobot_api_base): def test_translate_attrs_for_nautobot_with_vlan(nautobot_api_base): prefix = NautobotPrefix( - diffsync=nautobot_api_base, + adapter=nautobot_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id="014b6519-bf43-40f7-a40f-d5abb9828cd2", @@ -42,7 +42,7 @@ def test_translate_attrs_for_nautobot_with_vlan(nautobot_api_base): def test_translate_attrs_for_nautobot_with_absent_vlan(nautobot_api_base): prefix = NautobotPrefix( - diffsync=nautobot_api_base, + adapter=nautobot_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id="014b6519-bf43-40f7-a40f-d5abb9828cd2", @@ -59,7 +59,7 @@ def test_create_prefix(requests_mock, nautobot_api_base): requests_mock.post("http://mock_nautobot/api/ipam/prefixes/", json=data, status_code=201) ip_address = NautobotPrefix.create( - diffsync=nautobot_api_base, ids=dict(prefix="10.1.111.0/24", site_name="HQ"), attrs={} + adapter=nautobot_api_base, ids=dict(prefix="10.1.111.0/24", site_name="HQ"), attrs={} ) assert isinstance(ip_address, NautobotPrefix) is True @@ -75,7 +75,7 @@ def test_update_prefix(requests_mock, nautobot_api_base): requests_mock.get(f"http://mock_nautobot/api/ipam/prefixes/{remote_id}/", json=data_no_vlan, status_code=200) requests_mock.patch(f"http://mock_nautobot/api/ipam/prefixes/{remote_id}/", json=data_vlan, status_code=200) - prefix = NautobotPrefix(diffsync=nautobot_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id=remote_id) + prefix = NautobotPrefix(adapter=nautobot_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id=remote_id) prefix.update(attrs=dict(vlan="HQ__111")) assert prefix.vlan == "HQ__111" @@ -86,7 +86,7 @@ def test_create_prefix_with_vlan(requests_mock, nautobot_api_base): requests_mock.post("http://mock_nautobot/api/ipam/prefixes/", json=data, status_code=201) prefix = NautobotPrefix.create( - diffsync=nautobot_api_base, ids=dict(prefix="10.1.111.0/24", site_name="HQ"), attrs=dict(vlan="HQ__111") + adapter=nautobot_api_base, ids=dict(prefix="10.1.111.0/24", site_name="HQ"), attrs=dict(vlan="HQ__111") ) assert isinstance(prefix, NautobotPrefix) is True @@ -96,7 +96,7 @@ def test_create_prefix_with_vlan(requests_mock, nautobot_api_base): def test_translate_attrs_for_nautobot_w_vlan(nautobot_api_base): prefix = NautobotPrefix( - diffsync=nautobot_api_base, + adapter=nautobot_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id="171f82fc-8ab8-4840-9ae3-8337821be2fb", @@ -112,7 +112,7 @@ def test_translate_attrs_for_nautobot_w_vlan(nautobot_api_base): def test_translate_attrs_for_nautobot_wo_vlan(nautobot_api_base): prefix = NautobotPrefix( - diffsync=nautobot_api_base, + adapter=nautobot_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id="171f82fc-8ab8-4840-9ae3-8337821be2fb", diff --git a/tests/unit/adapters/nautobot_api/models/test_nautobot_vlan.py b/tests/unit/adapters/nautobot_api/models/test_nautobot_vlan.py index a834fb7..db1c418 100644 --- a/tests/unit/adapters/nautobot_api/models/test_nautobot_vlan.py +++ b/tests/unit/adapters/nautobot_api/models/test_nautobot_vlan.py @@ -16,7 +16,7 @@ def test_vlan_create_from_pynautobot(nautobot_api_base): data = yaml.safe_load(open(f"{ROOT}/../fixtures/vlan_101_no_tag.json")) pnb = pynautobot.core.response.Record(values=data, api=api, endpoint="eb697742-364d-4714-b585-a267c64d7720") - item = NautobotVlan.create_from_pynautobot(diffsync=nautobot_api_base, obj=pnb, site_name="nyc") + item = NautobotVlan.create_from_pynautobot(adapter=nautobot_api_base, obj=pnb, site_name="nyc") assert isinstance(item, NautobotVlan) is True assert item.remote_id == "eb697742-364d-4714-b585-a267c64d7720" assert item.vid == 101 @@ -33,7 +33,7 @@ def test_vlan_create_from_pynautobot_with_tags(nautobot_api_base): NautobotDevice(name="devA", site_name="nyc", remote_id="eb697742-364d-4714-b585-a267c64d7720") ) - item = NautobotVlan.create_from_pynautobot(diffsync=nautobot_api_base, obj=pnb, site_name="nyc") + item = NautobotVlan.create_from_pynautobot(adapter=nautobot_api_base, obj=pnb, site_name="nyc") assert isinstance(item, NautobotVlan) is True assert item.remote_id == "eb697742-364d-4714-b585-a267c64d7720" assert item.vid == 101 @@ -43,7 +43,7 @@ def test_vlan_create_from_pynautobot_with_tags(nautobot_api_base): nautobot_api_base.add( NautobotDevice(name="devB", site_name="nyc", remote_id="eb697742-364d-4714-b585-a267c64d7731") ) - item = NautobotVlan.create_from_pynautobot(diffsync=nautobot_api_base, obj=pnb, site_name="nyc") + item = NautobotVlan.create_from_pynautobot(adapter=nautobot_api_base, obj=pnb, site_name="nyc") assert isinstance(item, NautobotVlan) is True assert item.remote_id == "eb697742-364d-4714-b585-a267c64d7720" assert item.vid == 101 diff --git a/tests/unit/adapters/netbox_api/models/test_netbox_ipaddress.py b/tests/unit/adapters/netbox_api/models/test_netbox_ipaddress.py index f9e4c96..640605c 100644 --- a/tests/unit/adapters/netbox_api/models/test_netbox_ipaddress.py +++ b/tests/unit/adapters/netbox_api/models/test_netbox_ipaddress.py @@ -41,7 +41,7 @@ def test_create_from_pynetbox(netbox_api_base): data = yaml.safe_load(open(f"{ROOT}/../fixtures/netbox_29/ip_address.json")) pnb = pynetbox.core.response.Record(values=data, api=api, endpoint=1) - ipaddr = NetboxIPAddress.create_from_pynetbox(diffsync=netbox_api_base, obj=pnb, device_name="HQ-CORE-SW02") + ipaddr = NetboxIPAddress.create_from_pynetbox(adapter=netbox_api_base, obj=pnb, device_name="HQ-CORE-SW02") assert ipaddr.interface_name == "TenGigabitEthernet1/0/1" assert ipaddr.device_name == "HQ-CORE-SW02" @@ -53,7 +53,7 @@ def test_create_ip_address_interface(requests_mock, netbox_api_base): requests_mock.post("http://mock/api/ipam/ip-addresses/", json=data, status_code=201) ip_address = NetboxIPAddress.create( - diffsync=netbox_api_base, + adapter=netbox_api_base, ids=dict(address="10.63.0.2/31", interface_name="TenGigabitEthernet1/0/1", device_name="HQ-CORE-SW02"), attrs=dict(), ) @@ -68,7 +68,7 @@ def test_create_ip_address_no_interface(requests_mock, netbox_api_base): requests_mock.post("http://mock/api/ipam/ip-addresses/", json=data, status_code=201) ip_address = NetboxIPAddress.create( - diffsync=netbox_api_base, + adapter=netbox_api_base, ids=dict(address="10.63.0.2/31", interface_name="TenGigabitEthernet1/0/1", device_name="HQ-CORE-SW02"), attrs=dict(), ) diff --git a/tests/unit/adapters/netbox_api/models/test_netbox_ipaddress_pre29.py b/tests/unit/adapters/netbox_api/models/test_netbox_ipaddress_pre29.py index 28f8bb3..edb799f 100644 --- a/tests/unit/adapters/netbox_api/models/test_netbox_ipaddress_pre29.py +++ b/tests/unit/adapters/netbox_api/models/test_netbox_ipaddress_pre29.py @@ -53,7 +53,7 @@ def test_create_from_pynetbox(netbox_api_base): data = yaml.safe_load(open(f"{ROOT}/../fixtures/netbox_28/ip_address.json")) pnb = pynetbox.core.response.Record(values=data, api=api, endpoint=1) - ipaddr = NetboxIPAddressPre29.create_from_pynetbox(diffsync=netbox_api_base, obj=pnb, device_name="HQ-CORE-SW02") + ipaddr = NetboxIPAddressPre29.create_from_pynetbox(adapter=netbox_api_base, obj=pnb, device_name="HQ-CORE-SW02") assert ipaddr.interface_name == "TenGigabitEthernet1/0/1" assert ipaddr.device_name == "HQ-CORE-SW02" diff --git a/tests/unit/adapters/netbox_api/models/test_netbox_prefix.py b/tests/unit/adapters/netbox_api/models/test_netbox_prefix.py index bc60710..f6835cf 100644 --- a/tests/unit/adapters/netbox_api/models/test_netbox_prefix.py +++ b/tests/unit/adapters/netbox_api/models/test_netbox_prefix.py @@ -8,7 +8,7 @@ def test_translate_attrs_for_netbox_default(netbox_api_base): - prefix = NetboxPrefix(diffsync=netbox_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id=44) + prefix = NetboxPrefix(adapter=netbox_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id=44) expected_nb_params = {"prefix": "10.1.111.0/24", "status": "active", "site": 10} nb_params = prefix.translate_attrs_for_netbox(attrs={}) @@ -17,7 +17,7 @@ def test_translate_attrs_for_netbox_default(netbox_api_base): def test_translate_attrs_for_netbox_with_vlan(netbox_api_base): - prefix = NetboxPrefix(diffsync=netbox_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id=44) + prefix = NetboxPrefix(adapter=netbox_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id=44) expected_nb_params = {"prefix": "10.1.111.0/24", "status": "active", "site": 10, "vlan": 23} nb_params = prefix.translate_attrs_for_netbox(attrs=dict(vlan="HQ__111")) @@ -26,7 +26,7 @@ def test_translate_attrs_for_netbox_with_vlan(netbox_api_base): def test_translate_attrs_for_netbox_with_absent_vlan(netbox_api_base): - prefix = NetboxPrefix(diffsync=netbox_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id=44) + prefix = NetboxPrefix(adapter=netbox_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id=44) expected_nb_params = {"prefix": "10.1.111.0/24", "status": "active", "site": 10} nb_params = prefix.translate_attrs_for_netbox(attrs=dict(vlan="HQ__112")) @@ -39,7 +39,7 @@ def test_create_prefix(requests_mock, netbox_api_base): requests_mock.post("http://mock/api/ipam/prefixes/", json=data, status_code=201) ip_address = NetboxPrefix.create( - diffsync=netbox_api_base, ids=dict(prefix="10.1.111.0/24", site_name="HQ"), attrs={} + adapter=netbox_api_base, ids=dict(prefix="10.1.111.0/24", site_name="HQ"), attrs={} ) assert isinstance(ip_address, NetboxPrefix) is True @@ -55,7 +55,7 @@ def test_update_prefix(requests_mock, netbox_api_base): requests_mock.get(f"http://mock/api/ipam/prefixes/{remote_id}/", json=data_no_vlan, status_code=200) requests_mock.patch(f"http://mock/api/ipam/prefixes/{remote_id}/", json=data_vlan, status_code=200) - prefix = NetboxPrefix(diffsync=netbox_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id=remote_id) + prefix = NetboxPrefix(adapter=netbox_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id=remote_id) prefix.update(attrs=dict(vlan="HQ__111")) assert prefix.vlan == "HQ__111" @@ -66,7 +66,7 @@ def test_create_prefix_with_vlan(requests_mock, netbox_api_base): requests_mock.post("http://mock/api/ipam/prefixes/", json=data, status_code=201) prefix = NetboxPrefix.create( - diffsync=netbox_api_base, ids=dict(prefix="10.1.111.0/24", site_name="HQ"), attrs=dict(vlan="HQ__111") + adapter=netbox_api_base, ids=dict(prefix="10.1.111.0/24", site_name="HQ"), attrs=dict(vlan="HQ__111") ) assert isinstance(prefix, NetboxPrefix) is True @@ -75,7 +75,7 @@ def test_create_prefix_with_vlan(requests_mock, netbox_api_base): def test_translate_attrs_for_netbox_w_vlan(netbox_api_base): - prefix = NetboxPrefix(diffsync=netbox_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id=30) + prefix = NetboxPrefix(adapter=netbox_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id=30) netbox_api_base.add(prefix) params = prefix.translate_attrs_for_netbox({"vlan": "HQ__111"}) @@ -86,7 +86,7 @@ def test_translate_attrs_for_netbox_w_vlan(netbox_api_base): def test_translate_attrs_for_netbox_wo_vlan(netbox_api_base): - prefix = NetboxPrefix(diffsync=netbox_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id=30) + prefix = NetboxPrefix(adapter=netbox_api_base, prefix="10.1.111.0/24", site_name="HQ", remote_id=30) netbox_api_base.add(prefix) params = prefix.translate_attrs_for_netbox({"vlan": None}) diff --git a/tests/unit/adapters/netbox_api/models/test_netbox_vlan.py b/tests/unit/adapters/netbox_api/models/test_netbox_vlan.py index d33c88c..b8a8a17 100644 --- a/tests/unit/adapters/netbox_api/models/test_netbox_vlan.py +++ b/tests/unit/adapters/netbox_api/models/test_netbox_vlan.py @@ -19,7 +19,7 @@ def test_vlan_create_from_pynetbox(netbox_api_base): data = yaml.safe_load(open(f"{ROOT}/{FIXTURE_29}/vlan_101_no_tag.json")) pnb = pynetbox.core.response.Record(values=data, api=api, endpoint=1) - item = NetboxVlan.create_from_pynetbox(diffsync=netbox_api_base, obj=pnb, site_name="nyc") + item = NetboxVlan.create_from_pynetbox(adapter=netbox_api_base, obj=pnb, site_name="nyc") assert isinstance(item, NetboxVlan) is True assert item.remote_id == 1 assert item.vid == 101 @@ -34,7 +34,7 @@ def test_vlan_create_from_pynetbox_with_tags(netbox_api_base): netbox_api_base.add(NetboxDevice(name="devA", site_name="nyc", remote_id=30)) - item = NetboxVlan.create_from_pynetbox(diffsync=netbox_api_base, obj=pnb, site_name="nyc") + item = NetboxVlan.create_from_pynetbox(adapter=netbox_api_base, obj=pnb, site_name="nyc") assert isinstance(item, NetboxVlan) is True assert item.remote_id == 1 assert item.vid == 101 @@ -42,7 +42,7 @@ def test_vlan_create_from_pynetbox_with_tags(netbox_api_base): # Try again with one additional device in the inventory netbox_api_base.add(NetboxDevice(name="devB", site_name="nyc", remote_id=31)) - item = NetboxVlan.create_from_pynetbox(diffsync=netbox_api_base, obj=pnb, site_name="nyc") + item = NetboxVlan.create_from_pynetbox(adapter=netbox_api_base, obj=pnb, site_name="nyc") assert isinstance(item, NetboxVlan) is True assert item.remote_id == 1 assert item.vid == 101 diff --git a/tests/unit/adapters/netbox_api/models/test_netbox_vlan_pre29.py b/tests/unit/adapters/netbox_api/models/test_netbox_vlan_pre29.py index 3f106b8..02140ec 100644 --- a/tests/unit/adapters/netbox_api/models/test_netbox_vlan_pre29.py +++ b/tests/unit/adapters/netbox_api/models/test_netbox_vlan_pre29.py @@ -18,7 +18,7 @@ def test_vlan_create_from_pynetbox(netbox_api_base): data = yaml.safe_load(open(f"{ROOT}/{FIXTURE_28}/vlan_101_no_tag.json")) pnb = pynetbox.core.response.Record(values=data, api=api, endpoint=1) - item = NetboxVlanPre29.create_from_pynetbox(diffsync=netbox_api_base, obj=pnb, site_name="nyc") + item = NetboxVlanPre29.create_from_pynetbox(adapter=netbox_api_base, obj=pnb, site_name="nyc") assert isinstance(item, NetboxVlanPre29) is True assert item.remote_id == 1 @@ -34,7 +34,7 @@ def test_vlan_create_from_pynetbox_with_tags(netbox_api_base): netbox_api_base.add(NetboxDevice(name="devA", site_name="nyc", remote_id=30)) - item = NetboxVlanPre29.create_from_pynetbox(diffsync=netbox_api_base, obj=pnb, site_name="nyc") + item = NetboxVlanPre29.create_from_pynetbox(adapter=netbox_api_base, obj=pnb, site_name="nyc") assert isinstance(item, NetboxVlanPre29) is True assert item.remote_id == 1 assert item.vid == 101 @@ -42,7 +42,7 @@ def test_vlan_create_from_pynetbox_with_tags(netbox_api_base): # Try again with one additional device in the inventory netbox_api_base.add(NetboxDevice(name="devB", site_name="nyc", remote_id=31)) - item = NetboxVlanPre29.create_from_pynetbox(diffsync=netbox_api_base, obj=pnb, site_name="nyc") + item = NetboxVlanPre29.create_from_pynetbox(adapter=netbox_api_base, obj=pnb, site_name="nyc") assert isinstance(item, NetboxVlanPre29) is True assert item.remote_id == 1 assert item.vid == 101 diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index 8c1fb5a..9fdca3c 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -3,7 +3,7 @@ import pynetbox import pynautobot -from diffsync import DiffSync +from diffsync import Adapter from diffsync.diff import DiffElement # from diffsync.exceptions import ObjectNotCreated, ObjectNotUpdated, ObjectNotDeleted @@ -78,7 +78,7 @@ def dev_spine2(): return Device(name="spine2", site_name="sfo") -class GenericBackend(DiffSync): +class GenericBackend(Adapter): """An example semi-abstract subclass of DiffSync.""" site = Site @@ -141,9 +141,9 @@ class BackendA(GenericBackend): @pytest.fixture def backend_a(): """Provide an instance of BackendA subclass of DiffSync.""" - diffsync = BackendA() - diffsync.load() - return diffsync + adapter = BackendA() + adapter.load() + return adapter class BackendB(GenericBackend): @@ -182,9 +182,9 @@ class BackendB(GenericBackend): @pytest.fixture def backend_b(): """Provide an instance of BackendB subclass of DiffSync.""" - diffsync = BackendB() - diffsync.load() - return diffsync + adapter = BackendB() + adapter.load() + return adapter @pytest.fixture @@ -208,37 +208,37 @@ def diff_children_nyc_dev1(): @pytest.fixture def netbox_api_empty(): """Provide an instance of NetBoxAPIAdapter with pynetbox initiliazed.""" - diffsync = NetBoxAPIAdapter(nornir=None, settings={}) - diffsync.netbox = pynetbox.api(url="http://mock", token="1234567890") + adapter = NetBoxAPIAdapter(nornir=None, settings={}) + adapter.netbox = pynetbox.api(url="http://mock", token="1234567890") - return diffsync + return adapter @pytest.fixture def netbox_api_base(): """Provide an instance of NetBoxAPIAdapter with pynetbox initiliazed.""" - diffsync = NetBoxAPIAdapter(nornir=None, settings={}) - diffsync.netbox = pynetbox.api(url="http://mock", token="1234567890") + adapter = NetBoxAPIAdapter(nornir=None, settings={}) + adapter.netbox = pynetbox.api(url="http://mock", token="1234567890") - diffsync.add(NetboxSite(name="HQ", remote_id=10)) - diffsync.add(NetboxDevice(name="HQ-CORE-SW02", site_name="HQ", remote_id=29)) - diffsync.add(NetboxInterface(name="TenGigabitEthernet1/0/1", device_name="HQ-CORE-SW02", remote_id=302)) - diffsync.add(NetboxVlan(vid=111, site_name="HQ", remote_id=23)) + adapter.add(NetboxSite(name="HQ", remote_id=10)) + adapter.add(NetboxDevice(name="HQ-CORE-SW02", site_name="HQ", remote_id=29)) + adapter.add(NetboxInterface(name="TenGigabitEthernet1/0/1", device_name="HQ-CORE-SW02", remote_id=302)) + adapter.add(NetboxVlan(vid=111, site_name="HQ", remote_id=23)) - return diffsync + return adapter @pytest.fixture def network_importer_base(): """Provide an instance of NetworkImporterAdapter with pynetbox initiliazed.""" - diffsync = NetworkImporterAdapter(nornir=None, settings={}) + adapter = NetworkImporterAdapter(nornir=None, settings={}) - diffsync.add(Site(name="HQ")) - diffsync.add(Device(name="HQ-CORE-SW02", site_name="HQ", remote_id=29)) - diffsync.add(Interface(name="TenGigabitEthernet1/0/1", device_name="HQ-CORE-SW02")) - diffsync.add(Vlan(vid=111, site_name="HQ")) + adapter.add(Site(name="HQ")) + adapter.add(Device(name="HQ-CORE-SW02", site_name="HQ", remote_id=29)) + adapter.add(Interface(name="TenGigabitEthernet1/0/1", device_name="HQ-CORE-SW02")) + adapter.add(Vlan(vid=111, site_name="HQ")) - return diffsync + return adapter @pytest.fixture @@ -256,28 +256,28 @@ def empty_netbox_query(): @pytest.fixture def nautobot_api_base(): """Provide an instance of NautobotAPIAdapter with pynautoboot initiliazed.""" - diffsync = NautobotAPIAdapter(nornir=None, settings={}) - diffsync.nautobot = pynautobot.api(url="http://mock_nautobot", token="1234567890") + adapter = NautobotAPIAdapter(nornir=None, settings={}) + adapter.nautobot = pynautobot.api(url="http://mock_nautobot", token="1234567890") - diffsync.add(NautobotSite(name="HQ", remote_id="a325e477-62fe-47f0-8b67-acf411b1868f")) - diffsync.add(NautobotDevice(name="HQ-CORE-SW02", site_name="HQ", remote_id="e0633a07-c3e2-41b0-a1df-4627392acf0a")) - diffsync.add( + adapter.add(NautobotSite(name="HQ", remote_id="a325e477-62fe-47f0-8b67-acf411b1868f")) + adapter.add(NautobotDevice(name="HQ-CORE-SW02", site_name="HQ", remote_id="e0633a07-c3e2-41b0-a1df-4627392acf0a")) + adapter.add( NautobotInterface( name="TenGigabitEthernet1/0/1", device_name="HQ-CORE-SW02", remote_id="fecc1d8f-99b1-491d-9bdf-1dcb394e27a1" ) ) - diffsync.add(NautobotVlan(vid=111, site_name="HQ", remote_id="464a2de3-fd5e-4b65-a58d-e0a2a617c12e")) + adapter.add(NautobotVlan(vid=111, site_name="HQ", remote_id="464a2de3-fd5e-4b65-a58d-e0a2a617c12e")) - return diffsync + return adapter @pytest.fixture def nautobot_api_empty(): """Provide an instance of NautobotAPIAdapter with pynautobot initiliazed.""" - diffsync = NautobotAPIAdapter(nornir=None, settings={}) - diffsync.nautobot = pynautobot.api(url="http://mock", token="1234567890") + adapter = NautobotAPIAdapter(nornir=None, settings={}) + adapter.nautobot = pynautobot.api(url="http://mock", token="1234567890") - return diffsync + return adapter @pytest.fixture From 64ae75d48366b6c4415f4d149d218c7280508dbb Mon Sep 17 00:00:00 2001 From: Andre Lima Date: Wed, 3 Jul 2024 16:09:53 -0300 Subject: [PATCH 07/11] fixed tests - NautobotDevice expects remote_id to be a str --- .../adapters/nautobot_api/models/test_nautobot_device.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unit/adapters/nautobot_api/models/test_nautobot_device.py b/tests/unit/adapters/nautobot_api/models/test_nautobot_device.py index 42d8dcf..8a8868c 100644 --- a/tests/unit/adapters/nautobot_api/models/test_nautobot_device.py +++ b/tests/unit/adapters/nautobot_api/models/test_nautobot_device.py @@ -9,7 +9,7 @@ def test_nautobot_get_device_tag_id(): device = NautobotDevice( - name="dev12", site_name="HQ", remote_id=32, device_tag_id="eb697742-364d-4714-b585-a267c64d7720" + name="dev12", site_name="HQ", remote_id="32", device_tag_id="eb697742-364d-4714-b585-a267c64d7720" ) assert device.get_device_tag_id() == "eb697742-364d-4714-b585-a267c64d7720" @@ -18,7 +18,7 @@ def test_nautobot_get_device_tag_id_get_tag(requests_mock, nautobot_api_base): data = yaml.safe_load(open(f"{ROOT}/../fixtures/tag_01_list.json")) requests_mock.get("http://mock_nautobot/api/extras/tags/?name=device%3Ddev1", json=data, status_code=200) - device = NautobotDevice(name="dev1", site_name="HQ", remote_id=32) + device = NautobotDevice(name="dev1", site_name="HQ", remote_id="32") nautobot_api_base.add(device) assert device.get_device_tag_id() == "eb697742-364d-4714-b585-a267c64d7720" @@ -31,7 +31,7 @@ def test_get_device_tag_id_create_tag(requests_mock, nautobot_api_base, empty_na ) requests_mock.post("http://mock_nautobot/api/extras/tags/", json=data, status_code=201) - device = NautobotDevice(name="dev1", site_name="HQ", remote_id=32) + device = NautobotDevice(name="dev1", site_name="HQ", remote_id="32") nautobot_api_base.add(device) assert device.get_device_tag_id() == "3fed3ac5-c623-493c-b029-87487830d159" From 76a1715409661db43891a5fc25fe84919ad2f8bc Mon Sep 17 00:00:00 2001 From: Andre Lima Date: Wed, 3 Jul 2024 16:43:16 -0300 Subject: [PATCH 08/11] code formatted with Black --- network_importer/adapters/nautobot_api/settings.py | 2 +- network_importer/adapters/netbox_api/settings.py | 4 ++-- network_importer/models.py | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/network_importer/adapters/nautobot_api/settings.py b/network_importer/adapters/nautobot_api/settings.py index dc683a8..107f588 100644 --- a/network_importer/adapters/nautobot_api/settings.py +++ b/network_importer/adapters/nautobot_api/settings.py @@ -22,4 +22,4 @@ class InventorySettings(BaseSettings): use_primary_ip: Optional[bool] = True fqdn: Optional[str] = None - filter: Optional[str] = None \ No newline at end of file + filter: Optional[str] = None diff --git a/network_importer/adapters/netbox_api/settings.py b/network_importer/adapters/netbox_api/settings.py index dba3d59..7cf4c7e 100644 --- a/network_importer/adapters/netbox_api/settings.py +++ b/network_importer/adapters/netbox_api/settings.py @@ -10,7 +10,7 @@ class AdapterSettings(BaseSettings): """Config settings for the netbox_api adapter. Not used currently.""" model_flag_tags: List[str] = list() # List of tags that defines what objects to assign the model_flag to. - model_flag: Optional[DiffSyncModelFlags] = None # The model flag that will be applied to objects based on tag. + model_flag: Optional[DiffSyncModelFlags] = None # The model flag that will be applied to objects based on tag. class InventorySettings(BaseSettings): @@ -22,4 +22,4 @@ class InventorySettings(BaseSettings): use_primary_ip: Optional[bool] = True fqdn: Optional[str] = None - filter: Optional[str] = "" \ No newline at end of file + filter: Optional[str] = "" diff --git a/network_importer/models.py b/network_importer/models.py index 3a6ccfe..47ae113 100644 --- a/network_importer/models.py +++ b/network_importer/models.py @@ -123,6 +123,7 @@ class Prefix(DiffSyncModel): site_name: Optional[str] = None vlan: Optional[str] = None + class Cable(DiffSyncModel): """Cable Model based on DiffSyncModel.""" From 3c8d58800768a22e9d8bbb0ad7f84ba9ee564af1 Mon Sep 17 00:00:00 2001 From: Andre Lima Date: Thu, 4 Jul 2024 14:27:45 -0300 Subject: [PATCH 09/11] Bumping package version to 4.0.0 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2d31708..8a560dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "network-importer" -version = "3.1.0" +version = "4.0.0" description = "Network Importer tool to import an existing network into a Database / Source Of Truth" authors = ["Network to Code, LLC "] homepage = "https://github.com/networktocode/network-importer" From f74a14e6788afe05444f2e2dc5a267f66a70e66b Mon Sep 17 00:00:00 2001 From: Michael Sheinberg Date: Mon, 23 Dec 2024 16:18:40 -0800 Subject: [PATCH 10/11] Add back-in docstrings, make linters happy --- network_importer/config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/network_importer/config.py b/network_importer/config.py index 963ab2b..99fe734 100644 --- a/network_importer/config.py +++ b/network_importer/config.py @@ -39,6 +39,7 @@ class BatfishSettings(BaseSettings): + """Settings definition for the Batfish section of the configuration.""" address: str = Field(default="localhost", env="BATFISH_ADDRESS") network_name: str = Field(default="network-importer", env="BATFISH_NETWORK_NAME") snapshot_name: str = Field(default="latest", env="BATFISH_SNAPSHOT_NAME") @@ -49,6 +50,7 @@ class BatfishSettings(BaseSettings): class NetworkSettings(BaseSettings): + """Settings definition for the Network section of the configuration.""" login: Optional[str] = Field(default=None, env="NETWORK_DEVICE_LOGIN") password: Optional[str] = Field(default=None, env="NETWORK_DEVICE_PWD") enable: bool = Field(default=True, env="NETWORK_DEVICE_ENABLE") From 93f41af04c5809d5dd64dc5e0c22e54194fa6c9b Mon Sep 17 00:00:00 2001 From: Michael Sheinberg Date: Mon, 23 Dec 2024 16:20:06 -0800 Subject: [PATCH 11/11] Make black linter happy --- network_importer/config.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/network_importer/config.py b/network_importer/config.py index 99fe734..a3bc775 100644 --- a/network_importer/config.py +++ b/network_importer/config.py @@ -40,6 +40,7 @@ class BatfishSettings(BaseSettings): """Settings definition for the Batfish section of the configuration.""" + address: str = Field(default="localhost", env="BATFISH_ADDRESS") network_name: str = Field(default="network-importer", env="BATFISH_NETWORK_NAME") snapshot_name: str = Field(default="latest", env="BATFISH_SNAPSHOT_NAME") @@ -51,6 +52,7 @@ class BatfishSettings(BaseSettings): class NetworkSettings(BaseSettings): """Settings definition for the Network section of the configuration.""" + login: Optional[str] = Field(default=None, env="NETWORK_DEVICE_LOGIN") password: Optional[str] = Field(default=None, env="NETWORK_DEVICE_PWD") enable: bool = Field(default=True, env="NETWORK_DEVICE_ENABLE")