boto3-assist 0.25.0__py3-none-any.whl → 0.26.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- boto3_assist/dynamodb/dynamodb_index.py +1 -6
- boto3_assist/erc/__init__.py +64 -0
- boto3_assist/erc/ecr_connection.py +57 -0
- boto3_assist/version.py +1 -1
- {boto3_assist-0.25.0.dist-info → boto3_assist-0.26.0.dist-info}/METADATA +1 -1
- {boto3_assist-0.25.0.dist-info → boto3_assist-0.26.0.dist-info}/RECORD +9 -7
- {boto3_assist-0.25.0.dist-info → boto3_assist-0.26.0.dist-info}/WHEEL +0 -0
- {boto3_assist-0.25.0.dist-info → boto3_assist-0.26.0.dist-info}/licenses/LICENSE-EXPLAINED.txt +0 -0
- {boto3_assist-0.25.0.dist-info → boto3_assist-0.26.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -171,12 +171,7 @@ class DynamoDBIndex:
|
|
|
171
171
|
)
|
|
172
172
|
return key
|
|
173
173
|
|
|
174
|
-
elif
|
|
175
|
-
self.name == DynamoDBIndexes.PRIMARY_INDEX
|
|
176
|
-
and include_sort_key
|
|
177
|
-
# if it ends with a # we are assuming that we are doing a wild card mapping
|
|
178
|
-
and not str(self.sort_key.value).endswith("#")
|
|
179
|
-
):
|
|
174
|
+
elif self.name == DynamoDBIndexes.PRIMARY_INDEX and include_sort_key:
|
|
180
175
|
# this is a direct primary key which is used in a get call
|
|
181
176
|
# this is different than query keys
|
|
182
177
|
key = {}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import boto3
|
|
2
|
+
from botocore.exceptions import ClientError
|
|
3
|
+
from .ecr_connection import ECRConnection
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ECR(ECRConnection):
|
|
7
|
+
pass
|
|
8
|
+
|
|
9
|
+
def retag_image(self, repository_name: str, source_tag: str, target_tag: str):
|
|
10
|
+
"""
|
|
11
|
+
ReTag an ECR Image without the overhead of pulling it down, tagging and pushing.
|
|
12
|
+
Simply retags by getting the manifest, and pushing up changes.
|
|
13
|
+
Args:
|
|
14
|
+
repository_name (str):
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
ecr = self.client
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
# 1) Get the manifest for the source tag
|
|
21
|
+
resp = ecr.batch_get_image(
|
|
22
|
+
repositoryName=repository_name,
|
|
23
|
+
imageIds=[{"imageTag": source_tag}],
|
|
24
|
+
# optional, but helps ensure you get the right manifest type:
|
|
25
|
+
acceptedMediaTypes=[
|
|
26
|
+
"application/vnd.docker.distribution.manifest.v2+json",
|
|
27
|
+
"application/vnd.oci.image.manifest.v1+json",
|
|
28
|
+
],
|
|
29
|
+
)
|
|
30
|
+
images = resp.get("images", [])
|
|
31
|
+
if not images:
|
|
32
|
+
raise RuntimeError(f"No image found with tag {source_tag!r}")
|
|
33
|
+
|
|
34
|
+
manifest = images[0]["imageManifest"]
|
|
35
|
+
|
|
36
|
+
# 2) Push the same manifest under the new tag
|
|
37
|
+
put_resp = ecr.put_image(
|
|
38
|
+
repositoryName=repository_name,
|
|
39
|
+
imageManifest=manifest,
|
|
40
|
+
imageTag=target_tag,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
failures = put_resp.get("failures")
|
|
44
|
+
|
|
45
|
+
if failures and len(failures) > 0:
|
|
46
|
+
raise RuntimeError(
|
|
47
|
+
f"Failed to tag {repository_name}:{target_tag} - {failures}"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
print(f"Successfully tagged {repository_name}:{target_tag}")
|
|
51
|
+
return put_resp
|
|
52
|
+
|
|
53
|
+
except ClientError as e:
|
|
54
|
+
print(
|
|
55
|
+
f"ECR error: {e.response.get('Error', {}).get('Code', 'NA')} "
|
|
56
|
+
f"- {e.response.get('Error', {}).get('Message', 'NA')}"
|
|
57
|
+
)
|
|
58
|
+
raise
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
if __name__ == "__main__":
|
|
62
|
+
# Example: retag version 1.16.54 → dev
|
|
63
|
+
ecr: ECR = ECR(aws_profile="geek-cafe", aws_region="us-east-1")
|
|
64
|
+
ecr.retag_image("my-repo", "1.16.54", "dev")
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Geek Cafe, LLC
|
|
3
|
+
Maintainers: Eric Wilson
|
|
4
|
+
MIT License. See Project Root for the license information.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Optional
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
from aws_lambda_powertools import Logger
|
|
11
|
+
|
|
12
|
+
from boto3_assist.connection import Connection
|
|
13
|
+
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from mypy_boto3_ecr import Client
|
|
16
|
+
else:
|
|
17
|
+
Client = object
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
logger = Logger()
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ECRConnection(Connection):
|
|
24
|
+
"""Connection"""
|
|
25
|
+
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
*,
|
|
29
|
+
aws_profile: Optional[str] = None,
|
|
30
|
+
aws_region: Optional[str] = None,
|
|
31
|
+
aws_end_point_url: Optional[str] = None,
|
|
32
|
+
aws_access_key_id: Optional[str] = None,
|
|
33
|
+
aws_secret_access_key: Optional[str] = None,
|
|
34
|
+
) -> None:
|
|
35
|
+
super().__init__(
|
|
36
|
+
service_name="ecr",
|
|
37
|
+
aws_profile=aws_profile,
|
|
38
|
+
aws_region=aws_region,
|
|
39
|
+
aws_access_key_id=aws_access_key_id,
|
|
40
|
+
aws_secret_access_key=aws_secret_access_key,
|
|
41
|
+
aws_end_point_url=aws_end_point_url,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
self.__client: Client | None = None
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def client(self) -> Client:
|
|
48
|
+
"""Client Connection"""
|
|
49
|
+
if self.__client is None:
|
|
50
|
+
self.__client = self.session.client
|
|
51
|
+
|
|
52
|
+
return self.__client
|
|
53
|
+
|
|
54
|
+
@client.setter
|
|
55
|
+
def client(self, value: Client):
|
|
56
|
+
logger.info("Setting Client")
|
|
57
|
+
self.__client = value
|
boto3_assist/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '0.
|
|
1
|
+
__version__ = '0.26.0'
|
|
@@ -6,7 +6,7 @@ boto3_assist/connection_tracker.py,sha256=UgfR9RlvXf3A4ssMr3gDMpw89ka8mSRvJn4M34
|
|
|
6
6
|
boto3_assist/http_status_codes.py,sha256=G0zRSWenwavYKETvDF9tNVUXQz3Ae2gXdBETYbjvJe8,3284
|
|
7
7
|
boto3_assist/role_assumption_mixin.py,sha256=PMUU5yC2FUBjFD1UokVkRY3CPB5zTw85AhIB5BMtbc8,1031
|
|
8
8
|
boto3_assist/session_setup_mixin.py,sha256=X-JQKyyaWNA8Z8kKgf2V2I5vsiLAH8udLTX_xepnsdQ,3140
|
|
9
|
-
boto3_assist/version.py,sha256=
|
|
9
|
+
boto3_assist/version.py,sha256=Yk2dE3467PDiOPAi-UY_vFwY2lR6HNd27tFHSJqUVxg,23
|
|
10
10
|
boto3_assist/aws_lambda/event_info.py,sha256=OkZ4WzuGaHEu_T8sB188KBgShAJhZpWASALKRGBOhMg,14648
|
|
11
11
|
boto3_assist/aws_lambda/mock_context.py,sha256=LPjHP-3YSoY6iPl1kPqJDwSVf1zLNTcukUunDtYcbK0,116
|
|
12
12
|
boto3_assist/cloudwatch/cloudwatch_connection.py,sha256=mnGWaLSQpHh5EeY7Ek_2o9JKHJxOELIYtQVMX1IaHn4,2480
|
|
@@ -23,7 +23,7 @@ boto3_assist/dynamodb/dynamodb.py,sha256=TiO1lnQGiWxaWZ5-nnaWMMThFl3PMkD2r5ApIxE
|
|
|
23
23
|
boto3_assist/dynamodb/dynamodb_connection.py,sha256=D4KmVpMpE0OuVOwW5g4JBWllUNkwy0hMXEGUiToAMBc,3608
|
|
24
24
|
boto3_assist/dynamodb/dynamodb_helpers.py,sha256=RoRRqKjdwfC-2-gvlkLvCoNWhIoMrHm-68dkyhXI_Xk,12080
|
|
25
25
|
boto3_assist/dynamodb/dynamodb_importer.py,sha256=nCKsyRQeMqDSf0Q5mQ_X_oVIg4PRnu0hcUzZnBli610,3471
|
|
26
|
-
boto3_assist/dynamodb/dynamodb_index.py,sha256=
|
|
26
|
+
boto3_assist/dynamodb/dynamodb_index.py,sha256=MKQU4837rjYExMGCucGe2HBkPQPGszb8O6LR9EZBqek,8902
|
|
27
27
|
boto3_assist/dynamodb/dynamodb_iservice.py,sha256=O9Aj0PFEvcuk2vhARifWTFnUwcQW5EXzwZS478Hm-N0,796
|
|
28
28
|
boto3_assist/dynamodb/dynamodb_key.py,sha256=4IYnG4a99AjdOKUcDaWhNF_lvZJRZcKOIPzBQQzVdB0,3294
|
|
29
29
|
boto3_assist/dynamodb/dynamodb_model_base.py,sha256=Bgnjs62lHTqqJ2nZbPV1JHvcK6d2-aaRsJtcc8DEqKk,12291
|
|
@@ -38,6 +38,8 @@ boto3_assist/ec2/ec2_connection.py,sha256=IrtaidH6_SF5l3OeNehRsTlC-sX7EURVqcO-U6
|
|
|
38
38
|
boto3_assist/environment_services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
39
|
boto3_assist/environment_services/environment_loader.py,sha256=1uVLqSPQriUWazGXpxPJBLveGL8rLZaT5ZsciqqjVek,3979
|
|
40
40
|
boto3_assist/environment_services/environment_variables.py,sha256=4ccBKdPt6O7hcRT3zBHd8vqu8yQU8udmoD5RLAT3iMs,6801
|
|
41
|
+
boto3_assist/erc/__init__.py,sha256=ZVpE1TayNer4ZFb3t3wlo5LkWD9G-HbYE2DkoQoMI9w,2175
|
|
42
|
+
boto3_assist/erc/ecr_connection.py,sha256=5fbJiouHe2uta4OiN-NKOo3fS2608Zcc01fWBOyPbI4,1370
|
|
41
43
|
boto3_assist/errors/custom_exceptions.py,sha256=QAMW49NbClELVnRd00u4NHfzVtRS3Tc1TrsIMUP9wLw,1041
|
|
42
44
|
boto3_assist/models/serializable_model.py,sha256=ZMrRJRvJWLY8PBSKK_nPCgYKv1qUxDPEVdcADKbIHsI,266
|
|
43
45
|
boto3_assist/s3/s3.py,sha256=ESTPXtyDi8mrwHaYNWjQLNGTuTUV4CxKDqw-O_KGzKs,2052
|
|
@@ -57,8 +59,8 @@ boto3_assist/utilities/logging_utility.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5N
|
|
|
57
59
|
boto3_assist/utilities/numbers_utility.py,sha256=wzv9d0uXT_2_ZHHio7LBzibwxPqhGpvbq9HinrVn_4A,10160
|
|
58
60
|
boto3_assist/utilities/serialization_utility.py,sha256=Jc6H0cpcZjLO7tdyUZdBWHzItduLkw6sh2YQh8Hc8D8,21647
|
|
59
61
|
boto3_assist/utilities/string_utility.py,sha256=XxUIz19L2LFFTRDAAmdPa8Qhn40u9yO7g4nULFuvg0M,11033
|
|
60
|
-
boto3_assist-0.
|
|
61
|
-
boto3_assist-0.
|
|
62
|
-
boto3_assist-0.
|
|
63
|
-
boto3_assist-0.
|
|
64
|
-
boto3_assist-0.
|
|
62
|
+
boto3_assist-0.26.0.dist-info/METADATA,sha256=-yZ9DoMpzAKIhtRnjzhum_akSUrp0s2hhx8j_3yIoL4,2879
|
|
63
|
+
boto3_assist-0.26.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
64
|
+
boto3_assist-0.26.0.dist-info/licenses/LICENSE-EXPLAINED.txt,sha256=WFREvTpfTjPjDHpOLADxJpCKpIla3Ht87RUUGii4ODU,606
|
|
65
|
+
boto3_assist-0.26.0.dist-info/licenses/LICENSE.txt,sha256=PXDhFWS5L5aOTkVhNvoitHKbAkgxqMI2uUPQyrnXGiI,1105
|
|
66
|
+
boto3_assist-0.26.0.dist-info/RECORD,,
|
|
File without changes
|
{boto3_assist-0.25.0.dist-info → boto3_assist-0.26.0.dist-info}/licenses/LICENSE-EXPLAINED.txt
RENAMED
|
File without changes
|
|
File without changes
|