awspub 0.0.14__tar.gz → 0.0.15__tar.gz

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.
Files changed (35) hide show
  1. {awspub-0.0.14 → awspub-0.0.15}/PKG-INFO +4 -2
  2. awspub-0.0.15/awspub/__init__.py +3 -0
  3. {awspub-0.0.14 → awspub-0.0.15}/awspub/api.py +0 -20
  4. {awspub-0.0.14 → awspub-0.0.15}/awspub/cli/__init__.py +0 -19
  5. {awspub-0.0.14 → awspub-0.0.15}/awspub/image.py +1 -73
  6. {awspub-0.0.14 → awspub-0.0.15}/awspub/image_marketplace.py +1 -1
  7. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/test_image.py +0 -51
  8. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/test_image_marketplace.py +13 -0
  9. {awspub-0.0.14 → awspub-0.0.15}/pyproject.toml +1 -1
  10. awspub-0.0.14/awspub/__init__.py +0 -3
  11. {awspub-0.0.14 → awspub-0.0.15}/LICENSE +0 -0
  12. {awspub-0.0.14 → awspub-0.0.15}/awspub/common.py +0 -0
  13. {awspub-0.0.14 → awspub-0.0.15}/awspub/configmodels.py +0 -0
  14. {awspub-0.0.14 → awspub-0.0.15}/awspub/context.py +0 -0
  15. {awspub-0.0.14 → awspub-0.0.15}/awspub/exceptions.py +0 -0
  16. {awspub-0.0.14 → awspub-0.0.15}/awspub/s3.py +0 -0
  17. {awspub-0.0.14 → awspub-0.0.15}/awspub/snapshot.py +0 -0
  18. {awspub-0.0.14 → awspub-0.0.15}/awspub/sns.py +0 -0
  19. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/__init__.py +0 -0
  20. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/fixtures/config-invalid-s3-extra.yaml +0 -0
  21. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/fixtures/config-minimal.yaml +0 -0
  22. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/fixtures/config-valid-nonawspub.yaml +0 -0
  23. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/fixtures/config1.vmdk +0 -0
  24. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/fixtures/config1.yaml +0 -0
  25. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/fixtures/config2-mapping.yaml +0 -0
  26. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/fixtures/config2.yaml +0 -0
  27. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/fixtures/config3-duplicate-keys.yaml +0 -0
  28. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/test_api.py +0 -0
  29. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/test_cli.py +0 -0
  30. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/test_common.py +0 -0
  31. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/test_context.py +0 -0
  32. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/test_s3.py +0 -0
  33. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/test_snapshot.py +0 -0
  34. {awspub-0.0.14 → awspub-0.0.15}/awspub/tests/test_sns.py +0 -0
  35. {awspub-0.0.14 → awspub-0.0.15}/readme.rst +0 -0
@@ -1,8 +1,9 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: awspub
3
- Version: 0.0.14
3
+ Version: 0.0.15
4
4
  Summary: Publish images to AWS EC2
5
5
  License: GPL-3.0-or-later
6
+ License-File: LICENSE
6
7
  Keywords: AWS,EC2,publication
7
8
  Author: Thomas Bechtold
8
9
  Author-email: thomasbechtold@jpberlin.de
@@ -13,6 +14,7 @@ Classifier: Programming Language :: Python :: 3.10
13
14
  Classifier: Programming Language :: Python :: 3.11
14
15
  Classifier: Programming Language :: Python :: 3.12
15
16
  Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
16
18
  Requires-Dist: autodoc-pydantic (>=2.0.1,<3.0.0)
17
19
  Requires-Dist: boto3
18
20
  Requires-Dist: boto3-stubs[essential,marketplace-catalog,s3,sns,ssm,sts] (>=1.28.83,<2.0.0)
@@ -0,0 +1,3 @@
1
+ from awspub.api import cleanup, create, list, publish
2
+
3
+ __all__ = ["create", "list", "publish", "cleanup"]
@@ -143,23 +143,3 @@ def cleanup(config: pathlib.Path, config_mapping: pathlib.Path, group: Optional[
143
143
  ctx = Context(config, config_mapping)
144
144
  for image_name, image in _images_filtered(ctx, group):
145
145
  image.cleanup()
146
-
147
-
148
- def verify(config: pathlib.Path, config_mapping: pathlib.Path, group: Optional[str]) -> Dict[str, Dict]:
149
- """
150
- Verify available images in the partition of the used account based on
151
- the given configuration file.
152
- This is EXPERIMENTAL and doesn't work reliable yet!
153
-
154
- :param config: the configuration file path
155
- :type config: pathlib.Path
156
- :param config_mapping: the config template mapping file path
157
- :type config_mapping: pathlib.Path
158
- :param group: only handles images from given group
159
- :type group: Optional[str]
160
- """
161
- problems: Dict[str, Dict] = dict()
162
- ctx = Context(config, config_mapping)
163
- for image_name, image in _images_filtered(ctx, group):
164
- problems[image_name] = image.verify()
165
- return problems
@@ -31,14 +31,6 @@ def _list(args) -> None:
31
31
  args.output.write(images_json)
32
32
 
33
33
 
34
- def _verify(args) -> None:
35
- """
36
- Verify available images against configuration
37
- """
38
- problems = awspub.verify(args.config, args.config_mapping, args.group)
39
- args.output.write((json.dumps({"problems": problems}, indent=4)))
40
-
41
-
42
34
  def _cleanup(args) -> None:
43
35
  """
44
36
  Cleanup available images
@@ -80,17 +72,6 @@ def _parser():
80
72
  p_list.add_argument("config", type=pathlib.Path, help="the image configuration file path")
81
73
  p_list.set_defaults(func=_list)
82
74
 
83
- # verify
84
- p_verify = p_sub.add_parser("verify", help="Verify images")
85
- p_verify.add_argument(
86
- "--output", type=argparse.FileType("w+"), help="output file path. defaults to stdout", default=sys.stdout
87
- )
88
- p_verify.add_argument("--config-mapping", type=pathlib.Path, help="the image config template mapping file path")
89
- p_verify.add_argument("--group", type=str, help="only handles images from given group")
90
- p_verify.add_argument("config", type=pathlib.Path, help="the image configuration file path")
91
-
92
- p_verify.set_defaults(func=_verify)
93
-
94
75
  # cleanup
95
76
  p_cleanup = p_sub.add_parser("cleanup", help="Cleanup images")
96
77
  p_cleanup.add_argument(
@@ -313,6 +313,7 @@ class Image:
313
313
  ec2client_region: EC2Client = boto3.client("ec2", region_name=region)
314
314
  image_info: Optional[_ImageInfo] = self._get(ec2client_region)
315
315
  if image_info:
316
+ logger.info(f"publishing {self.image_name} in region {region}")
316
317
  ec2client_region.modify_image_attribute(
317
318
  ImageId=image_info.image_id,
318
319
  LaunchPermission={
@@ -588,76 +589,3 @@ class Image:
588
589
  # send ssn notification
589
590
  if self.conf["sns"]:
590
591
  self._sns_publish()
591
-
592
- def _verify(self, region: str) -> List[ImageVerificationErrors]:
593
- """
594
- Verify (but don't modify or create anything) the image in a single region
595
- """
596
- problems: List[ImageVerificationErrors] = []
597
- ec2client_region: EC2Client = boto3.client("ec2", region_name=region)
598
- image_info: Optional[_ImageInfo] = self._get(ec2client_region)
599
-
600
- if not image_info:
601
- problems.append(ImageVerificationErrors.NOT_EXIST)
602
- return problems
603
-
604
- image_aws = ec2client_region.describe_images(ImageIds=[image_info.image_id])["Images"][0]
605
-
606
- # verify state
607
- if image_aws["State"] != "available":
608
- problems.append(ImageVerificationErrors.STATE_NOT_AVAILABLE)
609
-
610
- # verify RootDeviceType
611
- if image_aws["RootDeviceType"] != "ebs":
612
- problems.append(ImageVerificationErrors.ROOT_DEVICE_TYPE)
613
-
614
- # verify BootMode
615
- if image_aws["BootMode"] != self.conf["boot_mode"]:
616
- problems.append(ImageVerificationErrors.BOOT_MODE)
617
-
618
- # verify RootDeviceVolumeType, RootDeviceVolumeSize and Snapshot
619
- for bdm in image_aws["BlockDeviceMappings"]:
620
- if bdm.get("DeviceName") and bdm["DeviceName"] == image_aws["RootDeviceName"]:
621
- # here's the root device
622
- if bdm["Ebs"]["VolumeType"] != self.conf["root_device_volume_type"]:
623
- problems.append(ImageVerificationErrors.ROOT_DEVICE_VOLUME_TYPE)
624
- if bdm["Ebs"]["VolumeSize"] != self.conf["root_device_volume_size"]:
625
- problems.append(ImageVerificationErrors.ROOT_DEVICE_VOLUME_SIZE)
626
-
627
- # verify snapshot
628
- snapshot_aws = ec2client_region.describe_snapshots(SnapshotIds=[bdm["Ebs"]["SnapshotId"]])["Snapshots"][
629
- 0
630
- ]
631
- if snapshot_aws["State"] != "completed":
632
- problems.append(ImageVerificationErrors.ROOT_DEVICE_SNAPSHOT_NOT_COMPLETE)
633
-
634
- # verify tpm support
635
- if self.conf["tpm_support"] and image_aws.get("TpmSupport") != self.conf["tpm_support"]:
636
- problems.append(ImageVerificationErrors.TPM_SUPPORT)
637
-
638
- # verify imds support
639
- if self.conf["imds_support"] and image_aws.get("ImdsSupport") != self.conf["imds_support"]:
640
- problems.append(ImageVerificationErrors.IMDS_SUPPORT)
641
-
642
- # billing products
643
- if self.conf["billing_products"] and image_aws.get("BillingProducts") != self.conf["billing_products"]:
644
- problems.append(ImageVerificationErrors.BILLING_PRODUCTS)
645
-
646
- # verify tags
647
- for tag in image_aws["Tags"]:
648
- if tag["Key"] == "Name" and tag["Value"] != self.snapshot_name:
649
- problems.append(ImageVerificationErrors.TAGS)
650
-
651
- return problems
652
-
653
- def verify(self) -> Dict[str, List[ImageVerificationErrors]]:
654
- """
655
- Verify (but don't modify or create anything) that the image configuration
656
- matches what is on AWS
657
- """
658
- logger.info(f"Verifying image {self.image_name} ...")
659
- problems: Dict[str, List[ImageVerificationErrors]] = dict()
660
- for region in self.image_regions:
661
- problems[region] = self._verify(region)
662
-
663
- return problems
@@ -37,7 +37,7 @@ class ImageMarketplace:
37
37
  """
38
38
  entity = self._mpclient.describe_entity(Catalog="AWSMarketplace", EntityId=self.conf["entity_id"])
39
39
  # check if the version already exists
40
- for version in entity["DetailsDocument"]["Versions"]:
40
+ for version in entity["DetailsDocument"].get("Versions", []):
41
41
  if version["VersionTitle"] == self.conf["version_title"]:
42
42
  logger.info(f"Marketplace version '{self.conf['version_title']}' already exists. Do nothing")
43
43
  return
@@ -426,57 +426,6 @@ def test_image__put_ssm_parameters(
426
426
  assert instance.put_parameter.called == put_parameter_called
427
427
 
428
428
 
429
- @pytest.mark.parametrize(
430
- "image_found,config,config_image_name, expected_problems",
431
- [
432
- # image not available
433
- ([], "fixtures/config1.yaml", "test-image-6", [image.ImageVerificationErrors.NOT_EXIST]),
434
- # image matches expectations from config
435
- (
436
- [
437
- {
438
- "Name": "test-image-6",
439
- "State": "available",
440
- "ImageId": "ami-123",
441
- "RootDeviceName": "/dev/sda1",
442
- "RootDeviceType": "ebs",
443
- "BootMode": "uefi-preferred",
444
- "BlockDeviceMappings": [
445
- {
446
- "DeviceName": "/dev/sda1",
447
- "Ebs": {
448
- "DeleteOnTermination": True,
449
- "VolumeType": "gp3",
450
- "VolumeSize": 8,
451
- "SnapshotId": "snap-123",
452
- },
453
- },
454
- ],
455
- "Tags": [
456
- {"Key": "name", "Value": "foobar"},
457
- ],
458
- }
459
- ],
460
- "fixtures/config1.yaml",
461
- "test-image-6",
462
- [],
463
- ),
464
- ],
465
- )
466
- def test_image__verify(image_found, config, config_image_name, expected_problems):
467
- """
468
- Test _verify() for a given image and configuration
469
- """
470
- with patch("boto3.client") as bclient_mock:
471
- instance = bclient_mock.return_value
472
- instance.describe_images.return_value = {"Images": image_found}
473
- instance.describe_snapshots.return_value = {"Snapshots": [{"State": "completed"}]}
474
- ctx = context.Context(curdir / config, None)
475
- img = image.Image(ctx, config_image_name)
476
- problems = img._verify("eu-central-1")
477
- assert problems == expected_problems
478
-
479
-
480
429
  @pytest.mark.parametrize(
481
430
  "partition,imagename,share_list_expected,volume_list_expected",
482
431
  [
@@ -30,6 +30,19 @@ def test_image_marketplace_request_new_version(imagename, new_version, called_st
30
30
  assert instance.start_change_set.called == called_start_change_set
31
31
 
32
32
 
33
+ def test_image_marketplace_request_new_version_none_exists():
34
+ """
35
+ Test the request_new_version logic if no version exist already
36
+ """
37
+ with patch("boto3.client") as bclient_mock:
38
+ instance = bclient_mock.return_value
39
+ instance.describe_entity.return_value = {"DetailsDocument": {}}
40
+ ctx = context.Context(curdir / "fixtures/config1.yaml", None)
41
+ img = image_marketplace.ImageMarketplace(ctx, "test-image-8")
42
+ img.request_new_version("ami-123")
43
+ assert instance.start_change_set.called is True
44
+
45
+
33
46
  @pytest.mark.parametrize(
34
47
  "name,expected",
35
48
  [
@@ -4,7 +4,7 @@ build-backend = "poetry_dynamic_versioning.backend"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "awspub"
7
- version = "0.0.14"
7
+ version = "0.0.15"
8
8
  description = "Publish images to AWS EC2"
9
9
 
10
10
  license = "GPL-3.0-or-later"
@@ -1,3 +0,0 @@
1
- from awspub.api import cleanup, create, list, publish, verify
2
-
3
- __all__ = ["create", "list", "publish", "cleanup", "verify"]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes