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