launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #26770
[Merge] ~pappacena/launchpad:upgrade-boto into launchpad:master
Thiago F. Pappacena has proposed merging ~pappacena/launchpad:upgrade-boto into launchpad:master.
Commit message:
Upgrading boto lib and removing workarounds for public ECR image uploads
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~pappacena/launchpad/+git/launchpad/+merge/400419
Dependencies MP: https://code.launchpad.net/~pappacena/lp-source-dependencies/+git/lp-source-dependencies/+merge/400418
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~pappacena/launchpad:upgrade-boto into launchpad:master.
diff --git a/lib/lp/oci/model/ociregistryclient.py b/lib/lp/oci/model/ociregistryclient.py
index 4d51843..923f670 100644
--- a/lib/lp/oci/model/ociregistryclient.py
+++ b/lib/lp/oci/model/ociregistryclient.py
@@ -1,4 +1,4 @@
-# Copyright 2020 Canonical Ltd. This software is licensed under the
+# Copyright 2020-2021 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Client for talking to an OCI registry."""
@@ -59,8 +59,6 @@ proxy_urlfetch = partial(urlfetch, use_proxy=True)
OCI_AWS_BEARER_TOKEN_DOMAINS_FLAG = 'oci.push.aws.bearer_token_domains'
-OCI_AWS_BOT_EXTRA_MODEL_PATH = 'oci.push.aws.boto.extra_paths'
-OCI_AWS_BOT_EXTRA_MODEL_NAME = 'oci.push.aws.boto.extra_model_name'
def is_aws_bearer_token_domain(domain):
@@ -68,7 +66,9 @@ def is_aws_bearer_token_domain(domain):
instead of basic auth."""
domains = getFeatureFlag(OCI_AWS_BEARER_TOKEN_DOMAINS_FLAG)
if not domains:
- return False
+ # We know that public ECR default domain is bearer token. If the
+ # flag is not set, force it.
+ domains = 'public.ecr.aws'
return any(domain.endswith(i) for i in domains.split())
@@ -680,23 +680,13 @@ class AWSAuthenticatorMixin:
def _getBotoClient(self):
params = self._getClientParameters()
- if not self.should_use_aws_extra_model:
- return boto3.client('ecr', **params)
- model_path = getFeatureFlag(OCI_AWS_BOT_EXTRA_MODEL_PATH)
- model_name = getFeatureFlag(OCI_AWS_BOT_EXTRA_MODEL_NAME)
- if not model_path or not model_name:
- log.warning(
- "%s or %s feature rules are not set. Using default model." %
- (OCI_AWS_BOT_EXTRA_MODEL_PATH, OCI_AWS_BOT_EXTRA_MODEL_NAME))
- return boto3.client('ecr', **params)
- session = boto3.Session()
- session._loader.search_paths.extend([model_path])
- return session.client(model_name, **params)
+ client_type = 'ecr-public' if self.is_public_ecr else 'ecr'
+ return boto3.client(client_type, **params)
@property
- def should_use_aws_extra_model(self):
- """Returns True if the given registry domain requires extra boto API
- model.
+ def is_public_ecr(self):
+ """Returns True if the given registry domain is a public ECR. False
+ otherwhise.
"""
domain = urlparse(self.push_rule.registry_url).netloc
return is_aws_bearer_token_domain(domain)
diff --git a/lib/lp/oci/tests/test_ociregistryclient.py b/lib/lp/oci/tests/test_ociregistryclient.py
index e30a470..5fe9f2f 100644
--- a/lib/lp/oci/tests/test_ociregistryclient.py
+++ b/lib/lp/oci/tests/test_ociregistryclient.py
@@ -1,4 +1,4 @@
-# Copyright 2020 Canonical Ltd. This software is licensed under the
+# Copyright 2020-2021 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Tests for the OCI Registry client."""
@@ -1045,7 +1045,7 @@ class TestRegistryHTTPClient(OCIConfigHelperMixin, SpyProxyCallsMixin,
instance = RegistryHTTPClient.getInstance(push_rule)
self.assertEqual(AWSRegistryHTTPClient, type(instance))
- self.assertFalse(instance.should_use_aws_extra_model)
+ self.assertFalse(instance.is_public_ecr)
self.assertIsInstance(instance, RegistryHTTPClient)
@responses.activate
@@ -1066,7 +1066,7 @@ class TestRegistryHTTPClient(OCIConfigHelperMixin, SpyProxyCallsMixin,
instance = RegistryHTTPClient.getInstance(push_rule)
self.assertEqual(AWSRegistryBearerTokenClient, type(instance))
- self.assertTrue(instance.should_use_aws_extra_model)
+ self.assertTrue(instance.is_public_ecr)
self.assertIsInstance(instance, RegistryHTTPClient)
@responses.activate
@@ -1336,26 +1336,58 @@ class TestAWSAuthenticator(OCIConfigHelperMixin, TestCaseWithFactory):
auth.push_rule = push_rule
self.assertRaises(OCIRegistryAuthenticationError, auth._getRegion)
- def test_should_use_extra_model(self):
+ def test_should_use_public_ecr_boto_model(self):
self.setConfig({
OCI_AWS_BEARER_TOKEN_DOMAINS_FLAG: 'bearertoken.example.com'})
+ boto_client_mock = self.useFixture(
+ MockPatch('lp.oci.model.ociregistryclient.boto3.client')).mock
cred = self.factory.makeOCIRegistryCredentials(
- url="https://myregistry.bearertoken.example.com")
+ url="https://myregistry.bearertoken.example.com",
+ credentials=dict(
+ region='us-east-1', username='user1', password='passwd1'))
push_rule = self.factory.makeOCIPushRule(registry_credentials=cred)
with admin_logged_in():
auth = AWSAuthenticatorMixin()
auth.push_rule = push_rule
- self.assertTrue(auth.should_use_aws_extra_model)
+ self.assertTrue(auth.is_public_ecr)
- def test_should_not_use_extra_model(self):
+ client = auth._getBotoClient()
+ self.assertEqual(boto_client_mock.return_value, client)
+ self.assertEqual(1, boto_client_mock.call_count)
+ call = boto_client_mock.call_args
+ self.assertEqual(
+ mock.call(
+ 'ecr-public', config=mock.ANY,
+ region_name='us-east-1', aws_secret_access_key='passwd1',
+ aws_access_key_id='user1'), call)
+ self.assertThat(
+ call[1]['config'], MatchesStructure.byEquality(proxies=None))
+
+ def test_should_not_use_public_ecr_boto_model(self):
self.setConfig({
OCI_AWS_BEARER_TOKEN_DOMAINS_FLAG: 'bearertoken.example.com'})
+ boto_client_mock = self.useFixture(
+ MockPatch('lp.oci.model.ociregistryclient.boto3.client')).mock
cred = self.factory.makeOCIRegistryCredentials(
- url="https://123456789.dkr.ecr.sa-west-1.amazonaws.com")
+ url="https://123456789.dkr.ecr.sa-west-1.amazonaws.com",
+ credentials=dict(
+ region='us-east-1', username='user1', password='passwd1'))
push_rule = self.factory.makeOCIPushRule(registry_credentials=cred)
with admin_logged_in():
auth = AWSAuthenticatorMixin()
auth.push_rule = push_rule
- self.assertFalse(auth.should_use_aws_extra_model)
+ self.assertFalse(auth.is_public_ecr)
+
+ client = auth._getBotoClient()
+ self.assertEqual(boto_client_mock.return_value, client)
+ self.assertEqual(1, boto_client_mock.call_count)
+ call = boto_client_mock.call_args
+ self.assertEqual(
+ mock.call(
+ 'ecr', config=mock.ANY, region_name='us-east-1',
+ aws_secret_access_key='passwd1',
+ aws_access_key_id='user1'), call)
+ self.assertThat(
+ call[1]['config'], MatchesStructure.byEquality(proxies=None))
diff --git a/requirements/launchpad.txt b/requirements/launchpad.txt
index 581b579..f1bafe7 100644
--- a/requirements/launchpad.txt
+++ b/requirements/launchpad.txt
@@ -22,8 +22,8 @@ billiard==3.5.0.5
bleach==3.1.0
breezy==3.0.1
bson==0.5.9
-boto3==1.16.2
-botocore==1.19.2
+boto3==1.17.40
+botocore==1.20.40
celery==4.1.1
Chameleon==3.6.2
configobj==5.0.6
@@ -134,7 +134,7 @@ rabbitfixture==0.5.0
requests-file==1.4.3
requests-toolbelt==0.9.1
responses==0.9.0
-s3transfer==0.3.3
+s3transfer==0.3.6
scandir==1.7
secure-cookie==0.1.0
service-identity==18.1.0
Follow ups