diff --git a/datadog_checks_base/datadog_checks/base/data/agent_requirements.in b/datadog_checks_base/datadog_checks/base/data/agent_requirements.in index ad798f30a1ab7..48bdbe7bc612f 100644 --- a/datadog_checks_base/datadog_checks/base/data/agent_requirements.in +++ b/datadog_checks_base/datadog_checks/base/data/agent_requirements.in @@ -15,7 +15,7 @@ flup==1.0.3.dev-20110405; python_version < '3.0' flup-py3==1.0.3; python_version > '3.0' gearman==2.0.2; sys_platform != 'win32' and python_version < '3.0' httplib2==0.10.3 -in-toto==0.3.0 +in-toto==0.4.1 ipaddress==1.0.22; python_version < '3.0' jaydebeapi==1.1.1 jpype1==0.7.0 @@ -56,7 +56,7 @@ requests==2.22.0 requests-kerberos==0.12.0 requests_ntlm==1.1.0 scandir==1.8 -securesystemslib[crypto,pynacl]==0.11.3 +securesystemslib[crypto,pynacl]==0.12.2 selectors34==1.2.0; sys_platform == 'win32' and python_version < '3.4' semver==2.9.0 serpent==1.27; sys_platform == 'win32' @@ -64,7 +64,7 @@ service_identity[idna]==18.1.0 simplejson==3.6.5 six==1.12.0 supervisor==4.0.1 -tuf==0.11.2.dev3 +tuf==0.12.1 uptime==3.0.1 vertica-python==0.9.4 win-inet-pton==1.1.0; sys_platform == 'win32' and python_version < '3.0' diff --git a/datadog_checks_dev/setup.py b/datadog_checks_dev/setup.py index 7ec08d6bb3d86..c868977612398 100644 --- a/datadog_checks_dev/setup.py +++ b/datadog_checks_dev/setup.py @@ -70,7 +70,7 @@ 'click', 'colorama', 'docker-compose>=1.23.1,<1.24.0', - 'in-toto==0.3.0', + 'in-toto>=0.4.1', 'pip-tools', 'pylint', 'Pillow', diff --git a/datadog_checks_downloader/datadog_checks/downloader/cli.py b/datadog_checks_downloader/datadog_checks/downloader/cli.py index cb652260fcf36..ea356a166e10c 100644 --- a/datadog_checks_downloader/datadog_checks/downloader/cli.py +++ b/datadog_checks_downloader/datadog_checks/downloader/cli.py @@ -7,13 +7,9 @@ import argparse import re -# 3rd party. -from tuf.exceptions import UnknownTargetError - -# 2nd party. # 2nd party. from .download import REPOSITORY_URL_PREFIX, TUFDownloader -from .exceptions import NonCanonicalVersion, NonDatadogPackage, NoSuchDatadogPackageOrVersion +from .exceptions import NonCanonicalVersion, NonDatadogPackage # Private module functions. @@ -27,11 +23,6 @@ def __is_canonical(version): return re.match(P, version) is not None -def __get_wheel_distribution_name(standard_distribution_name): - # https://www.python.org/dev/peps/pep-0491/#escaping-and-unicode - return re.sub('[^\\w\\d.]+', '_', standard_distribution_name, re.UNICODE) - - # Public module functions. @@ -60,23 +51,11 @@ def download(): if not standard_distribution_name.startswith('datadog-'): raise NonDatadogPackage(standard_distribution_name) - else: - wheel_distribution_name = __get_wheel_distribution_name(standard_distribution_name) - tuf_downloader = TUFDownloader(repository_url_prefix=repository_url_prefix, verbose=verbose) - - if not version: - version = tuf_downloader.get_latest_version(standard_distribution_name, wheel_distribution_name) - else: - if not __is_canonical(version): - raise NonCanonicalVersion(version) - - target_relpath = 'simple/{}/{}-{}-py2.py3-none-any.whl'.format( - standard_distribution_name, wheel_distribution_name, version - ) - - try: - target_abspath = tuf_downloader.download(target_relpath) - except UnknownTargetError: - raise NoSuchDatadogPackageOrVersion(standard_distribution_name, version) - - print(target_abspath) # pylint: disable=print-statement + + if version and not __is_canonical(version): + raise NonCanonicalVersion(version) + + tuf_downloader = TUFDownloader(repository_url_prefix=repository_url_prefix, verbose=verbose) + wheel_relpath = tuf_downloader.get_wheel_relpath(standard_distribution_name, version=version) + wheel_abspath = tuf_downloader.download(wheel_relpath) + print(wheel_abspath) # pylint: disable=print-statement diff --git a/datadog_checks_downloader/datadog_checks/downloader/data/repo/metadata/current/root.json b/datadog_checks_downloader/datadog_checks/downloader/data/repo/metadata/current/root.json index 4006666e86687..6f4581c3f6468 100644 --- a/datadog_checks_downloader/datadog_checks/downloader/data/repo/metadata/current/root.json +++ b/datadog_checks_downloader/datadog_checks/downloader/data/repo/metadata/current/root.json @@ -1,109 +1,109 @@ { "signatures": [ { - "keyid": "84c091f5c45111dcc40a3f4743fb1e9ce0deab6621522d77263cb512264c9dba", - "sig": "81747346ea7ac12284bc604a5d3a0b368aa25767e983ff09d515b1b386be3f93b56fbb714a29370dd036ce10fceea8c9c362c6c623e849ccbd0c3a940f35c1b6ed5557d72f8f829e928d41f6ea8292e4246c4a2aa54ed4e71fa1fbc262e24b1c03c473da2562a3f58dd1f5c254b65f5bfe60e75970b5183ef5347df450a0bb663cb00688aa99ea78daba78113fc554e7a406daecd3fdc925d0d52c3d6279d861ef00c4a938a78a2257b05b0fcf64c8395f55dc29f73d1ed1e34f9ab4e823e799d1f12af4f9605b4064df3c1662c87fdbc320c3c5e6c94ef367cee6fb3c3809c794a6c28d4197709618c273bd26ce4b0990b00fe93b58362af8a93d9b16fe90ca8c1e4334bc53f5014a93739b33b1bebf6e354b0bfa392c5d8d02d8d64655eedc643f35342c9f09af632cb85bacef7542792cfb5827f6ff5c4b0bf603cc00f866e2719b013d3ff71ac130640af0ce6dbfd19c2e12ed0be914ebec9555f66ae75ba1a25eba80d032614f2945d85c1d1002ab3c1c780c71d946fcb82084e17cadbb13a642bee23e982a976ffd39e6c6bcd4f26d2c6603898f235b686dcd964bdef46c369f0370c5e849b386c51169153042a2db6e196f0252af805b14d1349318d9639e599b3c07729799fe26b2ca454664e0e6949457709e654ac61628d9bd2b6f9c88b8e880b18b2fbd2d0a218608d244fca0832042c5e7ed6c146fc109b58f8c" + "keyid": "81818a2306b6eb928a8d6bf6dd5544075b0b0edfbf0bc1c90f13143bc5986262", + "sig": "a13f7039fa97f27490c73caf798f1acf8d55a273c727558309e0312fe470d9a9d28ddf01aeb0bf17d9d5f9b9b4a22b2b3ede217267539dbd67eb78a77f57a44d0019e2d934705508bc9e7d18ab545b4051f9732adcf028c364d53afd9ab6897cc1f189152a747db511fe80d1f7cf61efb35a5ce427712ffc12626427eb792f37febafb9d9baef1d07d9a592a23be87501048406a58445a8bc7f6d663c3f5fbfa38f2d1b69d40dd04c015ba03d2f68348bd3a8f28baae4865de17cdf34ee9884bb31ed9871691556989eec0543507229322655a07811cf0d520982ffef8dfba70d0a36ec6e09a34d57fc9262e3a4db9e73e26b03f00f543c4232cd2aed98311426baeca0d9fc63da55942d6885e9a801a524516688d55604b9a46f92bc88b438b4a2917258f47904353e59ec4c16190110bcc1f1f0a7ce3f9fb404cc23c0bbce2740ecddad8fa1794d19e1d02e91d309e5bdc81338a291fd1d279dd79f32b1b4fec502fe2aa28674327d6df447920992bee1ac15c1d7bfbd8d9d5fa61deb7d25fe6880d809e8ac51ac33ff1d93c847aa1267b28f4854d3ea9293a03367514bcebedb7c5cc5e6d07d46b1d671382d606d0b9331c42730b2368495d6282302cf823191b70daebea6195e61ffd10e14470cbced763c70cf4159d8c02642c5e6f8303c136298ffd9b7ec538772224f026e10748f8552808420c1551ffea4700e449c5" }, { - "keyid": "d95df75e244a9e5e861c4af6d42d7bfa1382d393bbc46f35f25ecdb5f0b374e0", - "sig": "b0655290bab620649fc5d8fec2ed122e7865550183e087cf5f49a026d7e33123ca8afba8b8c2ff85de4634cec6e7ce1261ddd527be81f448f1777acdc25ccf3e20480dd1d36e0e7ba8bda2be6d375b2076f14536c47b4405e5f3719677f2cd93f559919ceb0dd3ff47da85c9cfebf86abbcc249df2c47f72e38dcc62cfef71b6aa110e8225f1760fd5516bd734fbc0c8f3e3389495ee53d37429478e03549d9250d4d5f3856a8b605d127a8ef3158b589e341930f98698ed82e19729cf349397ef38be614be1dddfbe884689b4be663bd0428bcbf9c279ac30dcf16315ea6b7fb62ed40086a8a1671d170d69b96c2945c05bf8791b22e8d22a23cfaa45d067e47a2f1de9956ba191ede59f4773747731dbddd4cc88f3808b222dc08a0f0ddce38e2afbcc00af9fcd874096349f67c9d7bfabbb1041f7e03668699ab3c5208f418351b5a3a702cc5e02bd1bcdc08b376ade0a44e34a84c9b1543e27894d25a70d9daecb3533123b929e6c61cba090115e7cb3959c4e545923b7b659d3b038166c9b5e557774dfe60c9e13bbed4fd292db1f6f08cf081019468e76e81b964058936d613cec7eba67123b4dd85ddcee24c835993d84aa7f79c45bee5138e748c9614c0bc7a593312225b4e977a1e0b559550fb76731bf359c80f5eeaeabd98edcf15150ee76b73df5e115534062372bd52c738996dbf4f885953022a63bdc3e0b1c" + "keyid": "e877b48676d9435070983ad82dbd9c2df0cd7541208de13d7c042aa0e304f40f", + "sig": "1d2efd5fe2fb970694c312f57c136a6ecca66bfe732685fc3401a41781b8260ff8562f971bb6876d394066c12efa266d7129a346a2acfccc634ba4685f8511eb7d90f39336a2a28c6106c2b68986f4092a9cb4e2627919bdd0119441f0cdc10f8e86eacd6684e0a5b39f1e9b70cfd817faa98f387734845cbb2d7a90b0d534ca8c5a0b43c68cfe9334e21acf551166bba459f3ff23b9d5aea134737c7549976583188f05ba38eb77874225103a8c510ca9d0539ef3471629cdfac953732612608dd1b44fb10e0c1c05236e13db7426d906b52e181c550033b78754e345b184ad853af4b6fe3e4aa6e68bab054a178dce3aaf5c71db5747f6bb55337819989da8e8160e755cf12947826b7724f4873e2b43a93e6bcc86dd69f18fec55753c441acbbd55d60f40ee69cca4cdf5fc8f7d3eb018c0691b02a6cf026a570ca3189e4f6c8e53b2ab23e97cd8cd2afa79f2bfee7b65973173327bfd4008bf84ffce1211d65bb8dbc26e4808f7b4f729fb840972fa0a6af7b9ab326f0038c4781efffbd818561f627488990c2855263f2d79425e8faed9458c82475b22fc830b8413f53cd11272b50b0f4a09b2bcfda7450e2472d1486036073a6349f6ab4ae80c5a167fe2b7ffe4739c36b18a2f247c3f8e5ce6d0a791a9fd8c2e36381389c3eec0d748f09d7a30c95145f4d01a7e7a72bf9f68e7de69a6025a5a352b76fff4a3089e87" }, { - "keyid": "81818a2306b6eb928a8d6bf6dd5544075b0b0edfbf0bc1c90f13143bc5986262", - "sig": "0f5dc61faba77c6a8bd15e49a8bb637079d46ce4f6d6aca19f5d1efbb17672f3d17bf54b7e76dfd463d1840a7660fdbf74da8b441e913adf1682c7ccf4aa7e6558e7e16a89f60bfd870244498b030e75acf0e469b5aee0157de800249f0dd578505a3c49d1aea50a836157edcea0dff8d2a15f5fe1f36e38f7008490078632bff9229cc203ee0b543dfa33a742be0a7962a177011295abba6c47ef747d5bb70d4771224ada3323c9718f33bc439484130423d7104b3b5f8fce20490d05fb7118d1bff05a5db55e40f76aac957d66190c21a581ca5d061fb607af0dcd9115a6ef75c0f6c1a0a66a47f458c6cdd4761699f90cdbe2ac3b8534d6afd35b3a2ab73d0a7edcbe314ecaf6559791c230dba05896ff7962e337f4686177f166b58f8db06c14b4a3c459734ac8ebc6e69d40563a2ae9932329bf73fe884441ca8a19f07f35336209c7d38784abe0c7ef8094058e638abf9d80c7dd61805065f1c69b6fa1c952749ce58c50e0aa61cd91443ce35d33c8e9dd9715540b22a59143bab7aa06869ba549848f9d0f7c9602df5e2dca6856fad5a6077418dc435d56e3c707e75f78709cd1422dc4e2b00fe3b54c83e1184e7b8ce817bb9830b6870fa42aa01087372d37e001f8d815f2862170183e268882454df0654dff034daf9f1a312b82d09b30478766ff68903bc031fb5ccc56b990221297fd3b5a4f120b114d00cd893a" + "keyid": "6680314567663101789ab2dd095e47b4495f78e508aa25bf916c6ccc50e5820c", + "sig": "0f3fb60579653354bf417f8c0bbcba10090179cffab5390e233a4bbf155de6da815069e8b7f444c13ed800f96da53d6dc67701e5a806c3aca77479e962bc3d7aac4763004211d683769dc677875c6469257aeb2918c587293f0792ecc7daa6efea2ada474beaeea65d429e60dfe159b7d82c9dd0dc94cbacab5915067f665bb5d8a0d8ae35edc8fa5deb4a498213888ddf63c591f7de5b0e746469b99e0ef9dc3e28adfd0c91a99a151d38efacdbd4c9e53278e4ebd7bbc619078e9d9345d1a30ca5dc48cd2f03821d43dfcd34f545548142752f09eb36a4585d0c5fc85af7a988d4921ca274d0231259c2b18553b24ee6c882fefd943bec83576f4b113ded7c594d6e00f7464223b25c3d3be4921b1bf652d0a04ef3dd578d049df32f2919be7748ef651b42b58e826b68839f178f7579b133dfbe7c814074623147c95cb977d35e71c83fa767897ead17a201905a0c5db94d6d16877c8feb5c3e2062c645358d59ec411f5649e6902debd6a5c985d1120bfd0e012b4dc0ef622ff815c9c51a723056c6a1ea38a8cc2937bc707ce307cd69dc70f376eb0ee6f5b2c5f79cd65e9468f73c799deebe9fe59afb0d854f1ed135d485a0c44cb9538335f7601c1b074da42006e91bd054a0604bf5e5a10d0f6ee97be6271644481da6b5341f224ba6970b98ae560d538fb40af2c6fd94b5f3a30f00427bd65577195945ac5ddb1fa9" }, { - "keyid": "33976fe18999d18bd7dd8285ad94d357d74d688db67490521922b00df3582f53", - "sig": "97d47ea79a29fcfb0dafb43025a6436a1a77dee2755a83a36a7e140da4f9e21dc0ade688d118de5c0eddcd232e54869884a6d53a983fb7505cdc8656e0647679f29265934300d8e6820db6b217c94ec38b6908ccd8c4bf96c4875a0fb02b5eb2106bbb8442e614c66daefbd5730c4d182659dbc7d57432a2026479ef82e4b2e505815b5ff37b7ef1aa6fc0d2ef3d52002894dcd6f7a74e39c803ac713a2fde52a701110f789a4d7429bdc17ec420da9739863693b754a14e83dbc29a2c0c42283e6999586be80c392751455681103d1d7ac5459fb063cc72620f160b3f405df193f83709657a54bed632eea3c6aa51c1a3c9ea199eaf96825b9feba4038a4cca85c107485e6f7285cec1e285400998e1b89dc812490be97ea4485294572f4a077846756dacddd7bf3336f44392e4c40f27480e279a24a2af1474c649160e0b758d4d8520ecda60450b4a8fea04bc3de423830874d85c3425a538f56c03b3edafa14730dc8c2be890acd2e23f704e759af5821e850ac80037254e49f63d32e9a227dc1ce7a95db37b39020c3a1ef8ec1429d8eb6dff91e924f0eb321c25a0c99635beba0b2b4dab38f791e67db497fa495930a2b06d7f0901b04f5c8d20e2942934c553c57661f5b2e28cf1ad3c9df7c09dd13692a282f0bbd006e2f1baf0a9a180156ce16c50ce5c36f56e88a3fe125f6b2d6bae4300f52bb2451ac002bfd51b" + "keyid": "0f9921fcf6a369536465f31ebcd4ea13359700f6a09ec08c76f429e55f8a6c20", + "sig": "7b55fd2fc4b810fbd961704195ce35799c899af24618c2c6135e79b82327142eccb2c39ec3f4b6722fa38dbec3059270203cf23ec25c551e1d6384ceb5b64c2b51ec5b48a94a61df71851040987124aa1d25b4b7b0a139c7d65126093e21db4c7ac6b5c07b86d9e56bc115a8be5840b1ed2374cf1192706d9182c21b404e13196793820e6f2d054e78aa67625d6bc6f0c54d2fa26b3f69725f8e92761f3fc99dfba889ae6a1e9a7e9f3831e4c445dc54199cfd0fef648d3dd1c7a29d7fd1eeca3756d88d98ed0b11f5ad722e6be3912b460802f370b463241245751768321089a702f108ec15238030ae125bf434e26222af81fb33a45034258f1b66e5793ee226fc7f031c100b52482260bfde57da23d314ee3fa921d7a9ce0dedd9d0777aef71414ca776fe26746fefe78f62ee3460648aabf93e88a73b08aebde3b24f1d0eff42204f953460b859fb169c940d9079b4ce75f2743d61ee57539c933d126dbd280e9a3f4a082688ccd79e3c8ae5ef77288061a3d5e90d91e4aec90fe2c23bbf9d526b08e81144655c25c834ad1b2d0e363bf7931aa016f28e517da356716fc6d45bc41db2770a3d8d8baabb6bb94d2a0118b8c69b9a5fef44b476f8d041de1eec7e79f9ade3829524a083d3996e43e132fcf0737ccd337509f5f7f54beeb1d989fb5460f3912fb6737699f58acbd988a10cbe255d5ae43a8855583bf1819e6c" }, { - "keyid": "0f9921fcf6a369536465f31ebcd4ea13359700f6a09ec08c76f429e55f8a6c20", - "sig": "0701656638341b93b2d4fecc517b5b3e4e81e9beccae63b43edb630633471114003cfd6dca5ad0537f0d29741e729671f25a5bf03233272a78c11c3fea0e504c9edb00551fcaaa7b2bf8256c406d04931fd92201fd0800c9cf912a830416780f29cda41dd142d50a724ba20ba73bba79eca646533e7b4c7439b8407cad4845dd80791aca0383e2eb95f2dec11d1bf93487d936232dbf1be41383f070e4d3d580482d1b8b6fc8d23f0c40f83c9a2b983131aa9d697c18fc606e4aba228ba532c83dd2180ba2b37a94cb13486858e62a17f6f3602c8492317a2b5f80dfe7dc6e334bf0131b1e83f73ee0db01695b94b457d115316961ed09dcfdf7f1c79a2b43a15551ab2ccb62cbb0545022bf39dda35dbc5074083061b769553ab7b2104a3836354d1bd7a33371b0ea57610e78fa9c2de0f584217b55f8185e2c92707b372b6db6d2a2804062753f74226a151db3d44409cdf82e2ed1d66d262fa7d4654ec5f6215f2154d34e94db2b0e5a099397f51f2fa161be344fe392f909ca9e0a01d0d0a64e37322d5f28cd50e5b1dca62fe0cc67ef3db1d4511ab2a503e58b02e8a4979362ae34796c70e211a64e067cd2994f57386efc80ab53dae719ae7d8a1dacc1ea7dc1e803796d80bee58181dc4b0c5975558ea163397539493aa51749fb80518a067e0445f9f14e3f3b911a731e1ec0510874c2c3c5e834b7b5c4226b42b49d" + "keyid": "c2531fea13e3ffafbb8db165baa0e9eea6990ce74b3513f9ce1116e5b4a2d98f", + "sig": "932f53a850e8dc1e73b11229b508fe3e2eac5855de80d64a6dfb329145d658178af7300b939729a582a3f6ec40b184585695468a93af6b74a2647be0149748ac39c0f621428e74333e9eb68d36e1ae5164b1ff7b87cad696f8f0b77dd9f86399b2d8701fa1f24ff6810610e2478a51e52847617f0bcfd92095db72904fd727281920d592796bdf73b2231f1d7381e1790097457ebc681850beea4d7fa0f838cd5e10bc217cc4c939aa2c778094604fe70c2f52d912ae6c567028fc1a93774f22f99a3ce67f13a52d6f31971acec4a39d6a195a2238690ab87c28c534d6fbac8a92d160681bc07495a1cf945d57f1b530f0f384030c6b35d74c894656feb50f99a68d3f340b2f106576bdf2780c9372b0eeb9090660b4fd4fcb155458348a43595d1f3492499ae8b82eb158fd11efc4da26362c7d7715da4705358ca45a9193ecdc2722a0ad965ff15fc0c265ae81c61aa20c475c17655264c47ee2cc2f830f223188fb1055e42f65e35783ff34ccadf81749ebb2bb613d524a895d12af280adac0c7b1e1b1fe205864edcf97b68d55a251b6fffb2ea70c4dc94dc4cad8b5610171c30b297005c6418b5683b2017f7143c687f5c0302d4a9581daf9cc1b12892a2c880d8eada98634331367056ac37aa314b45499660c601933fbaf4a9c571793f9d558d3475c7632d88dfc6ad3ccbc13ed9aba1f5dba2a41c35612792be283e1" }, { - "keyid": "6680314567663101789ab2dd095e47b4495f78e508aa25bf916c6ccc50e5820c", - "sig": "2bd669ed1a3717999cc6598aea9c038e5530a530b59dfb452864d2ded55f0e39ba114f66e39e0af2746afdf8200378234b76de5da73560a8e834cb6a9bf0ed4e4029e47c6e83f2945b7436c9780d05f662b4a6ca332f004ca4d21f6ed653bb5c043d7f3650bfae457b07eb48ddf8e9e03b07f813684aedeb819ce9e7997f24c1b89484781b2c7b267c0aa46c9906b150a3134d9b35e0831f8246f1da6ae087a21d2f4ea34997b395823509a42c73a126a6a0eda0d6550b180a7e56a8a5ea73d9ed5791a13c4832d3d1b29478495158412177aea4692a2d7e598a77d49033779a1560541e20dfd5b8e8ddca2ce849d2bb5d0d95cb39592859b6cf4946313a036b092f846264c23039cf541db7656027d03211075686cb889e11836ef9140465b0c50e902c7e48ff0ab48c85fac5536f9a831f7b6bb47da324f9e4d10f585ae6ef46568929c1eb6b82cf261fa20de80d035f03c55617fd6aa4044af0277de1e89571dc75f00d49cbabdde7147c081a6349fbb2945835e08a55d4fe443809973d4a3a99e80b3110cddbc5694a10cd9cbe9b2015fd29b30428c3f3437ca9e4fe2088d2b09a91ec719cc381a6a7254bc7094ff3c3e83a9cfc4039077287a39a9b9c733ad2b34c2a7c6500784b594c9388f94347943eb7cd8dff73694f5804b2b09fb6ebae1d266bb64fb732f3b815e923d661dd0945716033d7061db1d182cf339eb2" + "keyid": "f473c0dc57b7e5692313502ae3fcd5d17cb64217e09e811ae2c41a89daa5249f", + "sig": "b589de9a01797805341f4f3481fa134786c09dae98096c5018328af2b0a0403b1360f5f58b1bedc0692ac429b2a95fda1e67d2f6a64755cf2afd27c58e99a51334a4508babb2bf44690ccca2b8989fd21c4a4d3a57948d3ca713b0b34d551966fb49ede201be3cf1504fc414a6a41ed723eebef0664170f9534b89b0ba99a445eee7b8fa5941dffe9e598170cf32cd198a8265a55878c3ca42216fd8d570698313163dd7a2826b5034b405fe1aef093f1b2345297744d9bf5ccdc4b152c939d0a5cf78b82c1ca17f3979cc96c9f133c425c4eaef62aacdf1b5d9df2061e7743b67962b992c4c250b026caeeae8b501f5bdfe25429a9107666759334e354a1fcf0e757afc7e378f9b4a83a7db460494b4ada243430f9fb90a801e6a7eb131fb1fca2547e132621311e742747338d02c28d511d8272f2d700e1640eb04d6326e81eefdc0d1680099dab223bc1b429ef6b6c0d1a44a85c1e7cee35647e1f2c017a92c4469e9e98eaf77eb0a5162c2d94e3011f415eaea0f0ce663318bda9d1ce9eabbbe6e2dc79c9ae39f545bfc3dc7215b455aae51e62051cede8422f2ea566b10db27de73ab7d37fad873fc18cf415c82b07584bfbe4b87d47b1327b3f3d2f4727a7f2e7629da0ebf8fcd1c8134f86095970f2e5481cb4f9126712e48ece67764c0d8c55b09875f960065cc587ffc41e9f745e4ec3551cede11807a11aa51b305" } ], "signed": { "_type": "root", "consistent_snapshot": true, - "expires": "2020-05-23T14:10:03Z", + "expires": "2020-11-25T17:13:16Z", "keys": { - "0f9921fcf6a369536465f31ebcd4ea13359700f6a09ec08c76f429e55f8a6c20": { + "16c093631ffae33d246fef66d5c37eefcf83f588411886026bbeccba1c44019a": { "keyid_hash_algorithms": [ "sha256", "sha512" ], "keytype": "rsa", "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAn8Hdn37znxvpM329aXS8\n1XG1WdxPU0pZwbDD/5HwTzdA1iFW3+mwDrKNnEJCLO+XoUx+Ho72x/BmsDsOqD0M\nTDZVfA+3TJwEn2Y0PHdtqul832WUXG1ezlI+9LiPDDbN3oWTWPmXNDxld78rODsd\nCqLEd2O00ykh7LDRXkaB6BmwtR3xWt0VDr8IfAJXRoaQL4/tVI4zBTm9HZ+IiJxH\n25C5DqvNgn/zYil/i62HbSxdepj/ENsahhAuRXduy++J23hh7TogyhTrZTbrgY1g\nDn1QcSxo5tXrM3cnefROpZtxynuy0idbD3IW8xBxu0REBXiJHAPpFjKbO4vEh3aw\nRdb7h+faL+qwbb5M2kdmLZWkfT3HyiB6JnQXrtHQsWIbbOH2K7gEiiv+i43H3xbq\nkXXgRBlJJC/NEebMvyRlcscZIlrNBDiP6e0rRok4wdl5NV0bC8ZRRYyzF8Bu2wGQ\nPEklokMjhvjv3bcFooifpBOXl6kNtwj3rCM37qEPVHn9AGlEgTncb8PBs7T1NVEo\nD0a5IGnlGnkwPfJYWfrAGm0zWagqoVN8lD13Ulm+NWJoXJBbL7Fbi/V9yyxvD9Ix\nWwniYDUyNnm68Tyoh+Nsk6QUaUXXA68RxQQmTuSj8VIFtD8uXHBDLGBn42yCJLqK\n+zSqe5f0vLA/XzrjCN04sFcCAwEAAQ==\n-----END PUBLIC KEY-----" + "public": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5pfywdMe0ExIEqJNYVN9\nwjo3+M66tHEvcCIIV9WoTSN8dnEobnZ5+DCQX4tplyIJxwUeToBvBBoHly2WFzZM\nevjasLELZTX1aDpwJgobjaPhe2+3VRJwaWPLvv2BxCPalRbsvdIYVpvuG0O3TYS7\nCo5PpNP0S1iGMdG3qnZ2kF9z4lO1YlGnsa1/kg70WKGDgG537vs4/0p8tRv/Ji4v\nK3J6yTIq2FoV3GFJiSRRZcu2TjsI6d8m5OhB01+OyGZo4Na71kQclDcqgNHfmySR\nQwAWihOI7dtz9GB3JWcubH7yjxQzPVZVmXRw5qILxDAeuAx3u0wVJVRLZNWE79DL\nZpMsTRUNf7A5oelenryR9e/rgrahXRd5SE3IeDT6dlNMrcaCDCBa0sU1mxJXDYtm\ncz+wbY3jGUMbnm74VQih+i3koieaRpSThQdAWHF022FKc+UpV/6TsQh2Lmommkmp\nAU1YNd7zPvkfEAhMGWqi3G3xKNtqUIeSnKYqPMsSJZiMGuYBK+RS9O8AXvurzrlA\nOcqHqJv8Bya00+v+kTJl26enDQEadx3s9RYDcvClDp3dJBp2liEqqoUymgQtHYTi\n0GxlhoFZlFp+2xpx96tyDRy5p74Zl/tcznZZXVXUyBrjERJ2x6h0H1sdXJYgT9uG\n5LunFH0Z75x68Fb2BNW4pTkCAwEAAQ==\n-----END PUBLIC KEY-----" }, "scheme": "rsassa-pss-sha256" }, - "20585de1ca258adecd3ab82dac4c1a3f22866a926015d89c0e14ccc37d1577c5": { + "617fdbcb160ff27c2744a9538f327041e08a597778a303251a1d48eb147c136f": { "keyid_hash_algorithms": [ "sha256", "sha512" ], "keytype": "rsa", "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAw4xdNL1bzlID9ltutz3T\nm8cPbowT0MmmwHy7Eltq4FHyNgyDK4WJghn8a3Lk3O+A+ZgHfoWzp5lv4mP4bVWK\nf0DNVa8oVeWPqalAiMOEpYUMkRKUZBLkco4oHczfZUjmmEK6ppx4Qm4BgCdHrugL\nddVbtBcwVrnX1PpdA+NrBRAM+k5AQS7yRxQelh2lPV5PE4Pz1/ngCTtZoqDaC3SA\nh0OAc26tPANrRbKxEsJEN2DoDs7RsNJBhEDAO/TNZdr/c5hNjklP9GgGG89Et8fT\n0QpBzopBkK0yL1Tu15+1N9Q+Qmlcrhif0Mg9YgaE0W6QjqECwUlJ91PD++fJCbxq\ndnWzb16EmVMfTMLspxoJz2d2Ln3xJlUN8eUISAp57eXs3MlkCLIlFbE6P18tyUTA\nemUeXO2E5tKPDhlETaITRwbCarL8M3m6sBBRMuSvW2AAWTqcynnl1b0ndrbVuB2d\n7PY5kkUARH79wQjphOV9vYuGVEqUhRb469ZPtysNx1R/QGGMD3ogll5JwLvKMt37\nCanr/1jrBEJTRMKq6Ps1WA9vl9m37GVYITwX8JeJIMLRckP0gQa6jSgJA7dB5+JJ\nhgAUVORc790lM/nEQfk74kvFg6Vinr324m4OAAsEPjRiwPRLanTiN18E8cUjn45b\nZEfOx08HtMmODXUinlxZ+scCAwEAAQ==\n-----END PUBLIC KEY-----" + "public": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoNiKyNlDqc/PoqObVmFS\n6t12iXvCwhTk5TReWMyZnKVVCEx4EG9zEmUozt28ZAnPqpiZ33jdPw13XYr5hvb+\njs++FwQvOiFlr991n9CKh0lTJto5KYfLHgVgULZl5zHMPMVs2YsBQPcrN0dQZ2zL\nFeknKP8F/RLUbo4h2agZBE+UvoDoauEECTBEW2XDFE5KRcS1TGoBlqFXpUaFShB0\nALnwgDGwMXnPcnMDoGGe4w4CeqK0UGr4wWLln7YETheiZOPwTsqEzzqRb51G1+5q\nKWFarQYRNAXIgZDng+I+Yxn/CtMw+TbjpqBWCSY4i9SUPuFvZZqHoudiABYfVLhH\nMouB9Zh6r0JauaBItfztrOodSTcajrK/r9txLypfLuStW87Z3bNCfW7Y77R+BpSd\nP/4HB2h8IVLyY8o7G+gkAgEFXlpV0gzvFNAVIjiS+SKUkNnF5gc8JMN8wlWsurDL\nbXRQBLD3HXpDlJuPodXF/5LdAcIQvEeLgZwA7c3ro87/iMwR+NlDq1FGQBKWpDRz\nEhyy4mMLgBXUI0mJEehG2/CaVCUb8T0yJ2RdWddtEMSdHeJMF+osZYXtUg9RWWWy\nKTGvn6sU2Z5d2C8de4u3y6NYnBOXISOf9OEpluqWMddQaEnOb7ccEK+f8bFa8jaa\nZzZewOc0otKs9WTeBNe6gYsCAwEAAQ==\n-----END PUBLIC KEY-----" }, "scheme": "rsassa-pss-sha256" }, - "55ab70a7aa25265397ce6995a085d3ab57d7a9f25dc581f4ab52a9ca69e2045b": { + "c2531fea13e3ffafbb8db165baa0e9eea6990ce74b3513f9ce1116e5b4a2d98f": { "keyid_hash_algorithms": [ "sha256", "sha512" ], "keytype": "rsa", "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtIm0xc2+/AO2+6fylEHz\n2rZET9FMbVdGzoxO20PKGfbCNZlM1LIb+s9+ejT1Ev2rUDFvFPmiIZRmqX/1dC5x\naVy5NHKnNyebJHYHeQQMSA/IO8TUbLKWtyW/mDaf9Pqh2XXQOoE9S2DgEzAapfJ8\nEglg2Hk7qOpKXKbWpw+lMnwHq5TDBdqKdH9aFUET8MrpT0vleR6rXcGTDl20WZ+L\nYKt7TAD6nHV3EllGGx6RV1ngVN0nhcuhj0EQzKAUUOvpReFmkAJBCoUwTZgUgqtz\n1ncjYyc8nt1gCbfsaO1WSjAWOOw9GJOU4/h8GOkEip0PJ35mWlzLBl+FofNcXlJw\nnmRfVajS195Ynx0GXkUeu8WnmkfJ2Mux+xk8kgXbsWSpESs5Lr3IUtKjNDWe1Qq/\ntxOXMKjho7p6AiJ3QzNsBhdAIb1AbvGeL1xAEDVEHfaKdpQZx9SOVnb0gSsOYkn3\n6UMhG12RLxbatmIa6FU3CNVlSRvlarbokpZeRb2014PFuDJf/eGQKF6trTCy+2d7\ncAZaHSYDhgIOFV1Lq/IYFEt6Z06jraxOt4f0YY0L6X3/VxP5i6wD48xaReATDhgf\nCnKBnxL6V1+bXTRRPA+bFTN8z6EGOzhLZp8ejSYC0HGvb98oKBH30LK7aAjvkaug\nsokOVXK+DmFu5q4y0wC5cK8CAwEAAQ==\n-----END PUBLIC KEY-----" + "public": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA3+ruytvR/2g1VYR8E5vz\nABk5Pyd7dHloQeKIVTH4eqb8v6T5i2c+ACTFgI/asYPn8f0qIjAX6kpoYoYSDb48\nD5e9tWpk1igs1J0Rikh2wyDcZRoIyv8IxtkOdpHNTudcMI+HF4rhOwRwiq7mu4BM\nPS2fWjNC/QY+s3DrHpXTe3a5ztlPD+QygYFK1msduZAuG07X950duQHWMOAPVpKx\nVbdAHRzhVwQt957tg0meToPQ204WwWYmJfQu7shotfFk4IY7zFrzetchFCMqz8oi\nknAaYixBnRL+BA32Gk5Ha9656oS0YNHqnGCv63IjNyFk5sIePW0Y6Zh45/5kjj4e\n7AokYKpW5oVnrJTpuNmUVUfG5xpqO1pAOScK5elG8qRa7phyQ64naX2RBM74VQmw\nKxVziylR2LeZg+wGRzmEWBQR+4M5EiKExfyYnwltPLpmlkLKhVDCiSgSmaMLca7Z\nVzmHZvf5GQbMOxx9OIdhC8/PdLV++SteiMXctA6p6wQQl09XW0LCy6+H6K0S0dba\nBNdX9/6SNQUu7pd0XqiRz/c/QG4ltQVtxqSSpYhXH4Ks6rj9vcLmTqHOkGpR0+Eg\n3GdadPzGUcmqayLlc4cxbg7ft6ztdEnRfT4z9PUaIWd7hD0RchyMf8N0Jd4113Xj\nkfezT9UGz/IjJygbkmi2boMCAwEAAQ==\n-----END PUBLIC KEY-----" }, "scheme": "rsassa-pss-sha256" }, - "6680314567663101789ab2dd095e47b4495f78e508aa25bf916c6ccc50e5820c": { + "e596451036eb5252f140f501c0d3f13a29803963b22e47824c50d0a34a570601": { "keyid_hash_algorithms": [ "sha256", "sha512" ], "keytype": "rsa", "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoRc7znUNqT47lwFzV1tB\nAfVmSLIirJ/+KWittH+PHGCBaY0+2R4DnDLGhCKo6KmJ1xN1/pINW3Kr1SSHWt7p\nELQbNzEIsUEckFmro56JyY34n3a/SnlyQiLdU0rWKNSy+U+VmsCoXCJU5+kAp4Yq\nWNh6bGmKUnHiD1Uco7jfG+Wr6BMiA5eUb8aHFZqwTY4rMVThQh5Hao0ZiIAtyXre\n8NKvbcat09d3LBh8PEqXNiPyP9e9ylMsuCZ8ovo+rwdNx2+Ai0MH40Pjbm4y2TCF\n68frwr4e7QAoV6oxyx9qeA5OkuZOjWrRSJ2rhcj0d9ew0OPp7372VHzShU4Z+yBl\nqI88VYNagZDXoLPAuHjmMrjyKR17Le+KVoqsre0o4I11ytcnREnwxqHHrAoUDqYl\nyNjqdouqss8M0ZsTN8Wd1bkHvt9/lsPgcowLp7w2ppG3c9NTjrS7jTqRn4uacFwW\nV7Ti2AwTWF7cFf94sE8GgQNaYCE1w4MdRfpBqVICx1fggMARH+SLivINDPfPgTSa\n+49uwAUtNSTLgV5Tc+m3S2zYnPCAL9LjLE0JTjdwuUEvUwk87qacJnc5y1QAEvdS\nC//tV2U3bMQk/eXm63lE24FuQkmiIjZksIvzHwNh7DzMMNxb12fG51E2uF4WeQ8M\nw58v0xn8Oi7v758Ve0vi26sCAwEAAQ==\n-----END PUBLIC KEY-----" + "public": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAx+wb/NsK+CVxmqTozrw0\nEsHI926EL1oHa7hHlo0Sih2wwJvDfM+/d1Nvgrv25Ts6T0RaXZSGBkf0pblHq/ft\nb52cEM3EdA4ZXxQxegXePl/DxcmCXaXj4ZTyuu1bA28PWls9oZW7lgdxlJgmsTQr\nWSqEYOn4dk43ECdMOF4D3DjnPypNNARuQxoicdpa6N3KoSQM3k0vOEBBm6Ck/3bk\nqj0Wh8zu0RJWnI4AzmazD4od6GDQWTtRfqzWql/kNnIjlGSQIszwDWJzNsxrmaR9\ndy/h9Vd+gA7yfcBv03CVxrGDDA9KpIyPFQShm3uD/AEKyc0mRCx14H1bpa4i6QYq\nUqIYsmw6uwythpr8JQyn862uqf+YwATQTdXnKz4+BMIybAEPZV0jumZihb3excFe\nPLQz5HjQWmQmRYy7QJAloLuOTIukvxM5XrFJENa7pOOHjAYgpLRrj1+Oe/pwK3x+\n8sEYn9NZA4vkGNboqKLoSyW3SBB/+6d7tD705T5n57hHzcALB7nEz9zlwT4uEFDH\nswtQEnIbD9KdI7JjOQTnrNdfj4Tiged84LInLpyNWtY/8+LhOtH1U1nZ8ayFFh2b\nehdCUtVwyT4gnZJiRgklD4uaq7v2+1uEK0rajZOoGSvuSfPIJgEgucSusyyewE7u\ng2CJhNRLK2h/NNSrwgxIEicCAwEAAQ==\n-----END PUBLIC KEY-----" }, "scheme": "rsassa-pss-sha256" }, - "81818a2306b6eb928a8d6bf6dd5544075b0b0edfbf0bc1c90f13143bc5986262": { + "e877b48676d9435070983ad82dbd9c2df0cd7541208de13d7c042aa0e304f40f": { "keyid_hash_algorithms": [ "sha256", "sha512" ], "keytype": "rsa", "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArzjvSRH+jTZ1sJL+pQ4a\nQOxRFH2yzLvb09hRpgMa6oniUp1FZI/1Qx50vPqkiq1CP1rhc+DNnH7CCERV2mMq\nmu4C6SpGB9hFh8wkAAaBolTlGQF5U+TLhFbqZKXc1ZQkxDaK8/8ye5/TsVcwcLLZ\nMdEKCpbi37YF4vXaAgQn9lCdRjuUwBbjWdGijuU28AcJfVlJgbAxPukTN++t7une\nbn2gNJXRs81fK1IkGXlMowCymqHGPdQqqTyISTCyQBtx2OVrHiJiukbOXP3vYJdQ\nmAZd/5k6ikpkxU4oUt7YZwDu9p7yKDn9yAUw+BEHMpHNtp1zhE4SKOBzptVLDbW8\nEHG0jPS54Ivr2JSde62y5n7oOVpuaeLZMVpawCJ809GMmo+zzZtr/CGhyBlpK1Z7\nnWFlTHiFqAUCpAJ4otR84vS3lGLE1Fmk/xgfm0+RC3Epos2ILN96GtHELzYLERWI\nvF6w8l6uuUJA6W7waMiKHxQWYCOiczRvBmCZxDtGBRvJZ4SWN9dPO15ik0eGCqBl\n4tFfvlMO17L5/+t4USf1hkHXw505uHfaJ+L/sDS1zoi7pT5dek7Pcea3NhlGFHwC\njtDJ1itZXVtstaxLr33Mh5ZlO6ZB7e528W8t31rOF/S5dERmAzW+jhNDfJQVuffm\n6bDvz+7zp4BXxloT0/E+DZ8CAwEAAQ==\n-----END PUBLIC KEY-----" + "public": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA17+m0WN/ei8HNHMmKpae\nyTGjyUVzXn2XUwH2A4CugdkLkPpwNGXUEbr6PIryWIL0EiLO0WCABmfMclAr41cU\nn08koFo+qZzZQctHDeQcYfJvxR8MJDXe7BbUyrpvCht9lneS6WzoFpqs/Gm6v54V\nWDRC0NB/AX/nTh/jvTtOYTMkkC9HfoEcZdItnGrpqFNC8g+kx+I8mAP97qjQGX+d\nTGb5fJUe+VKPkkq2119DOnNcLGEEG/6sMRoEwUkV7tTzUbAoZ42iiQ5RxXakzrg9\nm8cwhFG6ul7Ty14gEyBc8majGDNkygwFEJuAp1DFEwEwdeDJTIt1DRVJ+DKsMjTQ\nqf4KGsL4C54YGPvUBrElAGNesi3/p7K37RHx5g7uoYijn5c6Nhu+1JM4io0QU9nY\ntY7Qcx1GyBJ9ap+mzWosf4Cj+XtdaPrlVDvmVeUEwDQnyK6N2G2kQdan0vA1p14B\nQtUg+mo5bi8mCGBQLPET6zOh8vGJulz25iznJMk1ITN5yg/Aw+1tAM7eEb2TXTtf\nbRNJEUMBQmC7SON4b8w+pZLiaYoCIDIirQzkkpVM5qn5M9dJSw19VKxp+vZ81CLk\nZRiiNIHXyS02Cth5czN1WkpwZ9K0oHMEpMvT4Gi+AysaxyWnf8w3I4oKJ7e0f+qT\nWlY9SeYp+PQlLU5Hu9lGCIUCAwEAAQ==\n-----END PUBLIC KEY-----" }, "scheme": "rsassa-pss-sha256" }, - "aeec26293d275857dc46df87a2cf4ca14451d7226f6b99238af1df285a9a48c0": { + "f473c0dc57b7e5692313502ae3fcd5d17cb64217e09e811ae2c41a89daa5249f": { "keyid_hash_algorithms": [ "sha256", "sha512" ], "keytype": "rsa", "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA7Gn/3GXVz5uBDG9mcvTt\n43aE8fxHKltzkedcpu8LpzR5pZkiJl5GTjp5v6ftSAMMTup0EJQATqrXKZQPnk5u\nOTkHkYGq45PvF2yuKhwutC4NHL/Q+2zGrg6/v42I2RuFPTtwzYtuZv2r7sIAH/Zw\nhlftG7sQzdO417+z6cQ457v2UrwPHL7KJ+bZdtx0Ql52G1R1YvhOHkIsMbd2DV16\nXOaXVkbejJC32JQPsJeyssY8uH0bWHLdkRsapM2ftUJbAJQK20hHOddWNYDTKEkF\nZ3v1Wp/fePowBFua3108xP7A6KF8Z75CZY83/ffcU2H5wpc51E4SOA46fmk445mG\nrqAtSEpqGpVcD+vaGLRQ/omXS0sIL/K7anOO9m6jIUhZqKdtbtB1grZn8olfmJQm\natxc2OGCeWJSnNNfv8R1nA3zoTIk+AzVxnlFKnGffx69IwqXIu1Vv7HC0MBgcfpv\nbTZespJm7HUnng0aNSxwMmWO6jgHTz0kgD5OKIqPqewS0Nh542nm1mMpR0ZPZJg/\ngXXlQ1wMNMTFEiwZuRRn+eIeOfa/S8bxr30SG5kBY1KAkPdFA7UgGnR14xib2ju/\nJBsiu3pBYHE/3CAH6/nWmvSK5kgAN8GNGKv9QqfOclgs5PDSenA9Eqpq/xeBNh4X\nDsNTH76/iNJOUxjtmSVrKhsCAwEAAQ==\n-----END PUBLIC KEY-----" + "public": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvidVhYcIBbhVH5Wkdq2u\nhff4ipqcakq0rAwvA0UhPQagsG6FWcHRH/tC04L7GYZuPBb3cvPrmJrejHiU/y8/\nsCnyHhwFMYSwi29UzHAsDi9tQ2ZLqmvE61PYSp7orID1OnCPlJQ2oyaEIsN5ILy1\n5/qJSipinvJPNZZp3PIMtOGaJwt95DBPIFSIylLIj4CF4/UR7B7bppBnDI+jZqvb\nVci0UNpIQUuyb4aQQR4Lb7NJUNQWh0m7HngbdNAXEj8Z/pSXoRJpN2yqHqxC+pCC\nFAoMr7OMsyhlaxIfUTpHx08X2DfdzzYtG0ywEphzS32IoPY2MJ5v8CUnJomh96q0\nc0velHsS2vLSHepj4REp2l8PLgebPsmaqL7BHonww98WPXw1y4bCtIe/Phs9SUcQ\n7JA+r4ejIvtcOV496ZWzx3pnj/jmgB1LIGab9a2dQzNrNNWEfn5vfSPUOi46N/1o\n+x7j5AR/de9v7pRWsbBqAddY3MAAqWZJLgO8sbhaHG4rEpj4D1X3CyYdTqfUtxBK\nAx7CBNPn+G+ON+W8obchz4j6Tpi6GO+nfieQ8Kzs806RW7oLSjjrqZ3vGiA0XZkg\n5EKO5mVc4sRPLqOHvDmS8D7YwWu7Lqj62sn5EzHxWF5BotxUEVtDN1PkeBQtd9hO\n0isRvfh50fveSwQEwlbd4RMCAwEAAQ==\n-----END PUBLIC KEY-----" }, "scheme": "rsassa-pss-sha256" }, - "e2cd3b1ab9e2f2c3b94be7a938b54cfe246ae2aa4bd8a89006fa083548b1cd2e": { + "f5fd00f64a3b7011edbb613791c98c95175a69bb00c229eb778b28af735bedc3": { "keyid_hash_algorithms": [ "sha256", "sha512" ], "keytype": "rsa", "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxFbWxDKUK6wls5LJUIow\nE7CEH8rqf46M9S9lD9hW0pzbe9WUdxZbTw/4DfUGVgJNCKEcz3jMX9cw+6pyfykl\nckGkbXbUyP8RmO3P+PEDHqgs/sqsLonUTU16KIDQRlI/QOwReT+E3zRMSLj5Krrj\nC74a/NrATDGuN967W5L8e1QyNmRlyicYyJ9MyivEPgynL+5iQK1pPICxo348p5UV\nsSSixdfJjUqsSht+lFWuQXQuySlbNamrhW+IWnl84zrLBj2rB3PqwYsiMVRYK6Q5\nzcGPMEI24ij8OurigmImqpMZtj+/gPKez/MI7tPrEXtG6jiZzpOStT5aszBuxP0q\n8BnxPlHHg9IXPwIUJ+kDoJDksvC/2BlshrsODQpwQqLQ7Sa+DcmIMuqzCGusJ/PG\n9G+2PVK4yZQklgCEf88HzsMceqg5T/05b5ipRMI2drPM75omt13AbOKxIomT1XvJ\niPzyotWC8A0lolOzWrFclH7Pk77TgVXn7DjwYrxqxNuhFPTQiihGi4rCVfxN4GiY\nlX3fwjzUfYeIeu82pa3VJbi7yhH33AJy1i0K6/7ceW/vjmkCb2yYpQwPcZyQgOV8\nGN9zJir5H/pgUtWZ3EbBDBzYLoHEHMQIrjx8mGP9xzTsKs1u3LKbpeFWNBciv+50\nKx82mx/I6C1gibVa9/vVS8sCAwEAAQ==\n-----END PUBLIC KEY-----" + "public": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0IwUnBbIvHX/J4gGxis9\nkCI6gnr8qdza+5Wh3CTsVX2fmovpsxO6cu/W97f6Qx7OtujXVhjz13tItG+tsZx/\nhofzEvgpooWiFmlJqe/4i8ff35VALrIVgZadCyV54liq338aeo6f5/7OEFoPy+B5\nCVEinWcAMYBPxGNJlOcSxnFkKlaHV2vL4iUrh/1IMMZCr4Oq6FhK/+ZsPHe4khbw\nk7HcNjdeNGHV5RvJVAfXbAfMFCelaQqAISkoem6le3Tjz/EoJ4ZSYmH9AeTBsZON\nvf5h4pco8ddbVKIw03IlVdantIb7XGLVwp2sxE+4mF1QgeRdORkG2+dotXYk9lTP\n022AWEvr6fF26WSl5nJvpJkcqiIZmoiIG7hvjFdGqEIhoLP9vNVYTYHkNyBVQkTf\nTKgati62D3ApJ34D7Zb84wtrnP8JSxA5vxE5lobFQ73u00T3L5y0uLghdIOWdacF\nrPj7THTy+2dOMtoNlWE8ZMIIYCBpr83Nkb2ZxEE93eCLTuKAvgpOxkCjHdkV0RT2\nVdy9LmGbjJRQFmmI64qxOqY+YshW8Yeifij5Jfa6G1Shoe18BPxjngEDRKmg3H/K\njOX7/aw9rC95zTHpgCuN7kIDVFvBemFo8LiXFiv4GhnHCUMZbhuYqdqDDN05myDO\nd4Dsb+L7IGd5ua+g6h96tQsCAwEAAQ==\n-----END PUBLIC KEY-----" }, "scheme": "rsassa-pss-sha256" } @@ -111,34 +111,34 @@ "roles": { "root": { "keyids": [ - "0f9921fcf6a369536465f31ebcd4ea13359700f6a09ec08c76f429e55f8a6c20", - "81818a2306b6eb928a8d6bf6dd5544075b0b0edfbf0bc1c90f13143bc5986262", - "6680314567663101789ab2dd095e47b4495f78e508aa25bf916c6ccc50e5820c" + "c2531fea13e3ffafbb8db165baa0e9eea6990ce74b3513f9ce1116e5b4a2d98f", + "f473c0dc57b7e5692313502ae3fcd5d17cb64217e09e811ae2c41a89daa5249f", + "e877b48676d9435070983ad82dbd9c2df0cd7541208de13d7c042aa0e304f40f" ], "threshold": 2 }, "snapshot": { "keyids": [ - "20585de1ca258adecd3ab82dac4c1a3f22866a926015d89c0e14ccc37d1577c5" + "f5fd00f64a3b7011edbb613791c98c95175a69bb00c229eb778b28af735bedc3" ], "threshold": 1 }, "targets": { "keyids": [ - "e2cd3b1ab9e2f2c3b94be7a938b54cfe246ae2aa4bd8a89006fa083548b1cd2e", - "55ab70a7aa25265397ce6995a085d3ab57d7a9f25dc581f4ab52a9ca69e2045b", - "aeec26293d275857dc46df87a2cf4ca14451d7226f6b99238af1df285a9a48c0" + "e596451036eb5252f140f501c0d3f13a29803963b22e47824c50d0a34a570601", + "16c093631ffae33d246fef66d5c37eefcf83f588411886026bbeccba1c44019a", + "617fdbcb160ff27c2744a9538f327041e08a597778a303251a1d48eb147c136f" ], "threshold": 2 }, "timestamp": { "keyids": [ - "20585de1ca258adecd3ab82dac4c1a3f22866a926015d89c0e14ccc37d1577c5" + "f5fd00f64a3b7011edbb613791c98c95175a69bb00c229eb778b28af735bedc3" ], "threshold": 1 } }, - "spec_version": "1.0", - "version": 4 + "spec_version": "1.0.0", + "version": 5 } } \ No newline at end of file diff --git a/datadog_checks_downloader/datadog_checks/downloader/download.py b/datadog_checks_downloader/datadog_checks/downloader/download.py index 78e11044e4659..e72ed9be0dab4 100644 --- a/datadog_checks_downloader/datadog_checks/downloader/download.py +++ b/datadog_checks_downloader/datadog_checks/downloader/download.py @@ -1,15 +1,18 @@ # (C) Datadog, Inc. 2019 # All rights reserved # Licensed under a 3-clause BSD style license (see LICENSE) +import collections import glob import logging import logging.config import os import re import shutil +import sys import tempfile from in_toto import verifylib +from in_toto.exceptions import LinkNotFoundError from in_toto.models.metadata import Metablock from in_toto.util import import_public_keys_from_files_as_dict from pkg_resources import parse_version @@ -18,11 +21,15 @@ from tuf.exceptions import UnknownTargetError from .exceptions import ( + DuplicatePackage, InconsistentSimpleIndex, MissingVersions, NoInTotoLinkMetadataFound, NoInTotoRootLayoutPublicKeysFound, NoSuchDatadogPackage, + NoSuchDatadogPackageVersion, + PythonVersionMismatch, + RevokedDeveloper, ) from .parameters import substitute @@ -39,6 +46,9 @@ # abspath = os.path.join(REPOSITORIES_DIR, REPOSITORY_DIR) REPOSITORY_DIR = 'repo' REPOSITORY_URL_PREFIX = 'https://dd-integrations-core-wheels-build-stable.datadoghq.com' +# Where to find our in-toto root layout. +IN_TOTO_METADATA_DIR = 'in-toto-metadata' +IN_TOTO_ROOT_LAYOUT = '2.root.layout' # Global variables. @@ -88,41 +98,63 @@ def __init__(self, repository_url_prefix=REPOSITORY_URL_PREFIX, verbose=0): # we use the same consistent snapshot to download targets. self.__updater.refresh() - def __download_in_toto_metadata(self, target): - # A list to collect where in-toto metadata targets live. - target_relpaths = [] - - fileinfo = target.get('fileinfo') - - if fileinfo: - custom = fileinfo.get('custom') - - if custom: - in_toto_metadata = custom.get('in-toto') + def __download_with_tuf(self, target_relpath): + target = self.__updater.get_one_valid_targetinfo(target_relpath) + updated_targets = self.__updater.updated_targets((target,), self.__targets_dir) - # A long but safe way of checking whether there is any in-toto - # metadata embeddeed in an expected, hard-coded location. - if in_toto_metadata: + # Either the target has not been updated... + if not len(updated_targets): + logger.debug('{} has not been updated'.format(target_relpath)) + # or, it has been updated, in which case... + else: + # First, we use TUF to download and verify the target. + assert len(updated_targets) == 1 + updated_target = updated_targets[0] + assert updated_target == target + self.__updater.download_target(updated_target, self.__targets_dir) - for target_relpath in in_toto_metadata: - # Download the in-toto layout / link metadata file - # using TUF, which, among other things, prevents - # mix-and-match attacks by MitM attackers, and rollback - # attacks even by attackers who control the repository: - # https://www.usenix.org/conference/atc17/technical-sessions/presentation/kuppusamy - # NOTE: Avoid recursively downloading in-toto metadata - # for in-toto metadata themselves, and so on ad - # infinitum. - self.__get_target(target_relpath, download_in_toto_metadata=False) + logger.info('TUF verified {}'.format(target_relpath)) - # Add this file to the growing collection of where - # in-toto metadata live. - target_relpaths.append(target_relpath) + target_abspath = os.path.join(self.__targets_dir, target_relpath) + return target_abspath, target + + def __download_in_toto_root_layout(self): + # NOTE: We expect the root layout to be signed with *offline* keys. + # NOTE: We effectively tie every version of this downloader to its + # expected version of the root layout. This is so that, for example, we + # can introduce new parameters w/o breaking old downloaders that don't + # know how to substitute them. + target_relpath = os.path.join(IN_TOTO_METADATA_DIR, IN_TOTO_ROOT_LAYOUT) + return self.__download_with_tuf(target_relpath) + + def __download_custom(self, target, extension): + # A set to collect where in-toto pubkeys / links live. + target_abspaths = set() + + fileinfo = target.get('fileinfo', {}) + custom = fileinfo.get('custom', {}) + in_toto_metadata = custom.get('in-toto', []) + + for target_relpath in in_toto_metadata: + # Download in-toto *link* metadata files using TUF, + # which, among other things, prevents mix-and-match + # attacks by MitM attackers, and rollback attacks even + # by attackers who control the repository: + # https://www.usenix.org/conference/atc17/technical-sessions/presentation/kuppusamy + # NOTE: Avoid recursively downloading in-toto metadata + # for in-toto metadata themselves, and so on ad + # infinitum. + if target_relpath.endswith(extension): + target_abspath, _ = self.__download_with_tuf(target_relpath) + + # Add this file to the growing collection of where + # in-toto pubkeys / links live. + target_abspaths.add(target_abspath) # Return list of where in-toto metadata files live. - return target_relpaths + return target_abspaths - def __update_in_toto_layout_pubkeys(self): + def __download_in_toto_layout_pubkeys(self, target, target_relpath): ''' NOTE: We assume that all the public keys needed to verify any in-toto root layout, or sublayout, metadata file has been directly signed by @@ -131,48 +163,53 @@ def __update_in_toto_layout_pubkeys(self): guarantees if _ALL_ targets were signed using _online_ keys. ''' - target_relpaths = [] - targets = self.__updater.targets_of_role('targets') + pubkey_abspaths = self.__download_custom(target, '.pub') + if not len(pubkey_abspaths): + raise NoInTotoRootLayoutPublicKeysFound(target_relpath) + else: + return pubkey_abspaths - for target in targets: - target_relpath = target['filepath'] + def __download_in_toto_links(self, target, target_relpath): + link_abspaths = self.__download_custom(target, '.link') + if not len(link_abspaths): + raise NoInTotoLinkMetadataFound(target_relpath) + else: + return link_abspaths + + def __load_root_layout(self, target_relpath): + root_layout = Metablock.load(IN_TOTO_ROOT_LAYOUT) + root_layout_pubkeys = glob.glob('*.pub') + root_layout_pubkeys = import_public_keys_from_files_as_dict(root_layout_pubkeys) + # Parameter substitution. + root_layout_params = substitute(target_relpath) + return root_layout, root_layout_pubkeys, root_layout_params - # Download this target only if it _looks_ like a public key. - if target_relpath.endswith('.pub'): - # NOTE: Avoid recursively downloading in-toto metadata for - # in-toto root layout pubkeys themselves, and so on ad - # infinitum. - self.__get_target(target_relpath, download_in_toto_metadata=False) - target_relpaths.append(target_relpath) + def __handle_in_toto_verification_exception(self, target_relpath, e): + logger.exception('in-toto failed to verify {}'.format(target_relpath)) - return target_relpaths + if isinstance(e, LinkNotFoundError) and str(e) == RevokedDeveloper.MSG: + raise RevokedDeveloper(target_relpath, IN_TOTO_ROOT_LAYOUT) + else: + raise - def __verify_in_toto_metadata(self, target_relpath, in_toto_inspection_packet): + def __in_toto_verify(self, inspection_packet, target_relpath): # Make a temporary directory in a parent directory we control. tempdir = tempfile.mkdtemp(dir=REPOSITORIES_DIR) # Copy files over into temp dir. - for rel_path in in_toto_inspection_packet: - # Don't confuse Python with any leading path separator. - rel_path = rel_path.lstrip('/') - abs_path = os.path.join(self.__targets_dir, rel_path) + for abs_path in inspection_packet: shutil.copy(abs_path, tempdir) # Switch to the temp dir. os.chdir(tempdir) - # Load the root layout and public keys. - layout = Metablock.load('root.layout') - pubkeys = glob.glob('*.pub') - layout_key_dict = import_public_keys_from_files_as_dict(pubkeys) - # Parameter substitution. - params = substitute(target_relpath) + # Load the root layout and public keys in this temp dir. + root_layout, root_layout_pubkeys, root_layout_params = self.__load_root_layout(target_relpath) try: - verifylib.in_toto_verify(layout, layout_key_dict, substitution_parameters=params) - except Exception: - logger.exception('in-toto failed to verify {}'.format(target_relpath)) - raise + verifylib.in_toto_verify(root_layout, root_layout_pubkeys, substitution_parameters=root_layout_params) + except Exception as e: + self.__handle_in_toto_verification_exception(target_relpath, e) else: logger.info('in-toto verified {}'.format(target_relpath)) finally: @@ -182,94 +219,107 @@ def __verify_in_toto_metadata(self, target_relpath, in_toto_inspection_packet): # Delete temp dir. shutil.rmtree(tempdir) - def __download_and_verify_in_toto_metadata(self, target, target_relpath): - in_toto_metadata_relpaths = self.__download_in_toto_metadata(target) + def __download_and_verify_in_toto_metadata(self, target_relpath, target_abspath, target): + # First, get our in-toto root layout. + root_layout_abspath, root_layout_target = self.__download_in_toto_root_layout() + inspection_packet = {target_abspath, root_layout_abspath} - if not len(in_toto_metadata_relpaths): - raise NoInTotoLinkMetadataFound(target_relpath) + # Second, get the public keys for the root layout. + pubkey_abspaths = self.__download_in_toto_layout_pubkeys(root_layout_target, target_relpath) - else: - pubkey_relpaths = self.__update_in_toto_layout_pubkeys() - - if not len(pubkey_relpaths): - raise NoInTotoRootLayoutPublicKeysFound(target_relpath) - - else: - # Everything we need for in-toto inspection to work: the wheel, - # the in-toto root layout, in-toto links, and public keys to - # verify the in-toto layout. - in_toto_inspection_packet = [target_relpath] + in_toto_metadata_relpaths + pubkey_relpaths - self.__verify_in_toto_metadata(target_relpath, in_toto_inspection_packet) - - def __get_target(self, target_relpath, download_in_toto_metadata=True): - target = self.__updater.get_one_valid_targetinfo(target_relpath) - updated_targets = self.__updater.updated_targets((target,), self.__targets_dir) + # Third, get the in-toto links for the target of interest. + link_abspaths = self.__download_in_toto_links(target, target_relpath) - # Either the target has not been updated... - if not len(updated_targets): - logger.debug('{} has not been updated'.format(target_relpath)) - # or, it has been updated, in which case... - else: - # First, we use TUF to download and verify the target. - assert len(updated_targets) == 1 - updated_target = updated_targets[0] - assert updated_target == target - self.__updater.download_target(updated_target, self.__targets_dir) + # Everything we need for in-toto inspection to work: the wheel, + # the in-toto root layout, in-toto links, and public keys to + # verify the in-toto layout. + inspection_packet |= pubkey_abspaths | link_abspaths + self.__in_toto_verify(inspection_packet, target_relpath) - logger.info('TUF verified {}'.format(target_relpath)) + def __download_with_tuf_in_toto(self, target_relpath): + target_abspath, target = self.__download_with_tuf(target_relpath) # Next, we use in-toto to verify the supply chain of the target. # NOTE: We use a flag to avoid recursively downloading in-toto # metadata for in-toto metadata themselves, and so on ad infinitum. # All other files, presumably packages, should also be # inspected. - if download_in_toto_metadata: - self.__download_and_verify_in_toto_metadata(target, target_relpath) + try: + self.__download_and_verify_in_toto_metadata(target_relpath, target_abspath, target) + except Exception: + os.remove(target_abspath) + raise else: - logger.debug('Switched off in-toto verification for {}'.format(target_relpath)) + return target_abspath - target_path = os.path.join(self.__targets_dir, target_relpath) - return target_path - - def download(self, target_relpath, download_in_toto_metadata=True): + def download(self, target_relpath): ''' Returns: If download over TUF and in-toto is successful, this function will return the complete filepath to the desired target. ''' - return self.__get_target(target_relpath, download_in_toto_metadata=download_in_toto_metadata) + return self.__download_with_tuf_in_toto(target_relpath) - def get_latest_version(self, standard_distribution_name, wheel_distribution_name): - ''' - Returns: - If download over TUF is successful, this function will return the - latest known version of the Datadog integration. - ''' - target_relpath = 'simple/{}/index.html'.format(standard_distribution_name) + def __get_versions(self, standard_distribution_name): + index_relpath = 'simple/{}/index.html'.format(standard_distribution_name) + # https://www.python.org/dev/peps/pep-0491/#escaping-and-unicode + wheel_distribution_name = re.sub('[^\\w\\d.]+', '_', standard_distribution_name, re.UNICODE) + pattern = "(.*?)
" + # version: {python_tag: href} + wheels = collections.defaultdict(dict) try: # NOTE: We do not perform in-toto inspection for simple indices; only for wheels. - target_abspath = self.download(target_relpath, download_in_toto_metadata=False) + index_abspath, _ = self.__download_with_tuf(index_relpath) except UnknownTargetError: raise NoSuchDatadogPackage(standard_distribution_name) - pattern = "(.*?)
" - versions = [] - - with open(target_abspath) as simple_index: + with open(index_abspath) as simple_index: for line in simple_index: match = re.match(pattern, line) + if match: - href = match.group(1) - version = match.group(2) - text = match.group(3) + href, version, python_tag, text = match.groups() + if href != text: raise InconsistentSimpleIndex(href, text) else: - # https://setuptools.readthedocs.io/en/latest/pkg_resources.html#parsing-utilities - versions.append(parse_version(version)) + python_tags = wheels[version] + if python_tag in python_tags: + raise DuplicatePackage(standard_distribution_name, version, python_tag) + python_tags[python_tag] = href - if not len(versions): + return wheels + + def get_wheel_relpath(self, standard_distribution_name, version=None): + ''' + Returns: + If download over TUF is successful, this function will return the + latest known version of the Datadog integration. + ''' + wheels = self.__get_versions(standard_distribution_name) + + if not wheels: raise MissingVersions(standard_distribution_name) - else: - return max(versions) + + if not version: + # https://setuptools.readthedocs.io/en/latest/pkg_resources.html#parsing-utilities + version = str(max(parse_version(v) for v in wheels.keys())) + + python_tags = wheels[version] + if not python_tags: + raise NoSuchDatadogPackageVersion(standard_distribution_name, version) + + # First, try finding the pure Python wheel for this version. + this_python = 'py{}'.format(sys.version_info[0]) + href = python_tags.get(this_python) + + # Otherwise, try finding the universal Python wheel for this version. + if not href: + href = python_tags.get('py2.py3') + + # Otherwise, fuhgedaboutit. + if not href: + raise PythonVersionMismatch(standard_distribution_name, version, this_python, python_tags) + + return 'simple/{}/{}'.format(standard_distribution_name, href) diff --git a/datadog_checks_downloader/datadog_checks/downloader/exceptions.py b/datadog_checks_downloader/datadog_checks/downloader/exceptions.py index 0301403eae9e0..42a6d477ac8e9 100644 --- a/datadog_checks_downloader/datadog_checks/downloader/exceptions.py +++ b/datadog_checks_downloader/datadog_checks/downloader/exceptions.py @@ -7,55 +7,83 @@ class CLIError(Exception): + pass + + +class NonCanonicalVersion(CLIError): + def __init__(self, version): + self.version = version + + def __str__(self): + return '{}'.format(self.version) + + +class NonDatadogPackage(CLIError): def __init__(self, standard_distribution_name): self.standard_distribution_name = standard_distribution_name def __str__(self): - return 'Unexpected CLI error for {}!'.format(self.standard_distribution_name) + return '{}'.format(self.standard_distribution_name) -class InconsistentSimpleIndex(CLIError): - def __init__(self, href, text): - self.href = href - self.text = text +# Exceptions for the download module. - def __str__(self): - return '{} != {}'.format(self.href, self.text) +class SimpleIndexError(Exception): + def __init__(self, standard_distribution_name): + self.standard_distribution_name = standard_distribution_name -class MissingVersions(CLIError): def __str__(self): - return 'No version found for {} !'.format(self.standard_distribution_name) + return '{}'.format(self.standard_distribution_name) -class NonCanonicalVersion(CLIError): - def __init__(self, version): - self.version = version +class MissingVersions(SimpleIndexError): + pass - def __str__(self): - return '{} is not a valid PEP 440 version!'.format(self.version) +class NoSuchDatadogPackage(SimpleIndexError): + pass -class NonDatadogPackage(CLIError): - def __str__(self): - return '{} is not a Datadog package!'.format(self.standard_distribution_name) +class InconsistentSimpleIndex(SimpleIndexError): + def __init__(self, href, text): + self.href = href + self.text = text -class NoSuchDatadogPackage(CLIError): def __str__(self): - return 'Could not find the {} package!'.format(self.standard_distribution_name) + return '{}: {}!={}'.format(self.standard_distribution_name, self.href, self.text) -class NoSuchDatadogPackageOrVersion(CLIError): +class NoSuchDatadogPackageVersion(SimpleIndexError): def __init__(self, standard_distribution_name, version): - super(NoSuchDatadogPackageOrVersion, self).__init__(standard_distribution_name) + super(NoSuchDatadogPackageVersion, self).__init__(standard_distribution_name) self.version = version def __str__(self): - return 'Either no {} package, or {} version!'.format(self.standard_distribution_name, self.version) + return '{}-{}'.format(self.standard_distribution_name, self.version) -# Exceptions for the download module. +class DuplicatePackage(SimpleIndexError): + def __init__(self, standard_distribution_name, version, python_tag): + super(DuplicatePackage, self).__init__(standard_distribution_name) + self.version = version + self.python_tag = python_tag + + def __str__(self): + return '{}-{}-{}'.format(self.standard_distribution_name, self.version, self.python_tag) + + +class PythonVersionMismatch(SimpleIndexError): + def __init__(self, standard_distribution_name, version, this_python, python_tags): + super(PythonVersionMismatch, self).__init__(standard_distribution_name) + self.version = version + self.this_python = this_python + self.python_tags = python_tags + + def __str__(self): + return '{}-{}: {} not in {}'.format( + self.standard_distribution_name, self.version, self.this_python, self.python_tags + ) class TUFInTotoError(Exception): @@ -63,14 +91,23 @@ def __init__(self, target_relpath): self.target_relpath = target_relpath def __str__(self): - return 'Unexpected tuf-in-toto error for {}!'.format(self.target_relpath) + return '{}'.format(self.target_relpath) class NoInTotoLinkMetadataFound(TUFInTotoError): - def __str__(self): - return 'in-toto link metadata expected, but not found for {}!'.format(self.target_relpath) + pass class NoInTotoRootLayoutPublicKeysFound(TUFInTotoError): + pass + + +class RevokedDeveloper(TUFInTotoError): + MSG = "Step 'tag' requires '1' link metadata file(s), found '0'." + + def __init__(self, target_relpath, in_toto_root_layout): + super(RevokedDeveloper, self).__init__(target_relpath) + self.in_toto_root_layout = in_toto_root_layout + def __str__(self): - return 'in-toto root layout public keys expected, but not found for {}!'.format(self.target_relpath) + return '{} ({})'.format(self.target_relpath, self.in_toto_root_layout) diff --git a/datadog_checks_downloader/datadog_checks/downloader/parameters.py b/datadog_checks_downloader/datadog_checks/downloader/parameters.py index d59ef38cd6bf1..e5f514c38c8d7 100644 --- a/datadog_checks_downloader/datadog_checks/downloader/parameters.py +++ b/datadog_checks_downloader/datadog_checks/downloader/parameters.py @@ -15,14 +15,19 @@ from pkg_resources import safe_name +from .exceptions import NonDatadogPackage + EXCEPTIONS = {'datadog_checks_base', 'datadog_checks_dev', 'datadog_checks_downloader'} def substitute(target_relpath): filename = os.path.basename(target_relpath) name, ext = os.path.splitext(filename) - wheel_distribution_name, package_version, _, _, _ = name.split('-') - assert wheel_distribution_name.startswith('datadog_'), wheel_distribution_name + wheel_distribution_name, package_version, python_tag, _, _ = name.split('-') + + if not wheel_distribution_name.startswith('datadog_'): + raise NonDatadogPackage(wheel_distribution_name) + standard_distribution_name = safe_name(wheel_distribution_name) # These names are the exceptions. In this case, the wheel distribution name @@ -40,8 +45,9 @@ def substitute(target_relpath): package_github_dir = wheel_distribution_name[8:] return { - 'wheel_distribution_name': wheel_distribution_name, 'package_version': package_version, 'package_github_dir': package_github_dir, + 'python_tag': python_tag, 'standard_distribution_name': standard_distribution_name, + 'wheel_distribution_name': wheel_distribution_name, } diff --git a/datadog_checks_downloader/requirements.in b/datadog_checks_downloader/requirements.in index b22d2c4b869dc..057938acc98a8 100644 --- a/datadog_checks_downloader/requirements.in +++ b/datadog_checks_downloader/requirements.in @@ -1,12 +1,12 @@ # -# At the time of writing (Mar 22 2019), this was the latest version of these +# At the time of writing (Nov 27 2019), this was the latest version of these # libraries. # -tuf==0.11.2.dev3 -in-toto==0.3.0 +tuf==0.12.1 +in-toto==0.4.1 # # Make sure TUF and in-toto use the same version of this library, which they -# both use in common. At the time of writing (Oct 9 2018), this was the latest +# both use in common. At the time of writing (Nov 27 2019), this was the latest # version of the library. # -securesystemslib[crypto,pynacl]==0.11.3 +securesystemslib[crypto,pynacl]==0.12.2