awspub 0.0.10__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.
awspub/context.py ADDED
@@ -0,0 +1,108 @@
1
+ import hashlib
2
+ import logging
3
+ import pathlib
4
+ from string import Template
5
+ from typing import Dict
6
+
7
+ from ruamel.yaml import YAML
8
+
9
+ from awspub.configmodels import ConfigModel
10
+
11
+ logger = logging.getLogger(__name__)
12
+
13
+
14
+ class Context:
15
+ """
16
+ Context holds the used configuration and some
17
+ automatically calculated values
18
+ """
19
+
20
+ def __init__(self, conf_path: pathlib.Path, conf_template_mapping_path: pathlib.Path):
21
+ self._conf_path = conf_path
22
+ self._conf = None
23
+ self._conf_template_mapping_path = conf_template_mapping_path
24
+ self._conf_template_mapping = {}
25
+ yaml = YAML(typ="safe")
26
+
27
+ # read the config mapping first
28
+ if self._conf_template_mapping_path:
29
+ with open(self._conf_template_mapping_path, "r") as ctm:
30
+ self._conf_template_mapping = yaml.load(ctm)
31
+ logger.debug(f"loaded config template mapping for substitution: {self._conf_template_mapping}")
32
+
33
+ # read the config itself
34
+ with open(self._conf_path, "r") as f:
35
+ template = Template(f.read())
36
+ # substitute the values in the config with values from the config template mapping
37
+ ft = template.substitute(**self._conf_template_mapping)
38
+ y = yaml.load(ft)["awspub"]
39
+ self._conf = ConfigModel(**y).model_dump()
40
+ logger.debug(f"config loaded and validated as: {self._conf}")
41
+
42
+ # handle relative paths in config files. those are relative to the config file dirname
43
+ if not self.conf["source"]["path"].is_absolute():
44
+ self.conf["source"]["path"] = pathlib.Path(self._conf_path).parent / self.conf["source"]["path"]
45
+
46
+ for image_name, props in self.conf["images"].items():
47
+ if props["uefi_data"] and not self.conf["images"][image_name]["uefi_data"].is_absolute():
48
+ self.conf["images"][image_name]["uefi_data"] = (
49
+ pathlib.Path(self._conf_path).parent / self.conf["images"][image_name]["uefi_data"]
50
+ )
51
+
52
+ # calculate the sha256 sum of the source file once
53
+ self._source_sha256_obj = self._sha256sum(self.conf["source"]["path"])
54
+ self._source_sha256 = self._source_sha256_obj.hexdigest()
55
+
56
+ @property
57
+ def conf(self):
58
+ return self._conf
59
+
60
+ @property
61
+ def source_sha256(self):
62
+ """
63
+ The sha256 sum hexdigest of the source->path value from the given
64
+ configuration. This value is used in different places (eg. to automatically
65
+ upload to S3 with this value as key)
66
+ """
67
+ return self._source_sha256
68
+
69
+ @property
70
+ def tags_dict(self) -> Dict[str, str]:
71
+ """
72
+ Common tags which will be used for all AWS resources
73
+ This includes tags defined in the configuration file
74
+ but doesn't include image group specific tags.
75
+ Usually the tags() method should be used.
76
+ """
77
+ tags = dict()
78
+ tags["awspub:source:filename"] = self.conf["source"]["path"].name
79
+ tags["awspub:source:architecture"] = self.conf["source"]["architecture"]
80
+ tags["awspub:source:sha256"] = self.source_sha256
81
+ tags.update(self.conf.get("tags", {}))
82
+ return tags
83
+
84
+ @property
85
+ def tags(self):
86
+ """
87
+ Helper to make tags directly usable by the AWS EC2 API
88
+ which requires a list of dicts with "Key" and "Value" defined.
89
+ """
90
+ tags = []
91
+ for name, value in self.tags_dict.items():
92
+ tags.append({"Key": name, "Value": value})
93
+ return tags
94
+
95
+ def _sha256sum(self, file_path: pathlib.Path):
96
+ """
97
+ Calculate a sha256 sum for a given file
98
+
99
+ :param file_path: the path to the local file to upload
100
+ :type file_path: pathlib.Path
101
+ :return: a haslib Hash object
102
+ :rtype: _hashlib.HASH
103
+ """
104
+ sha256_hash = hashlib.sha256()
105
+ with open(file_path.resolve(), "rb") as f:
106
+ for byte_block in iter(lambda: f.read(4096), b""):
107
+ sha256_hash.update(byte_block)
108
+ return sha256_hash
awspub/exceptions.py ADDED
@@ -0,0 +1,28 @@
1
+ class MultipleSnapshotsException(Exception):
2
+ pass
3
+
4
+
5
+ class MultipleImportSnapshotTasksException(Exception):
6
+ pass
7
+
8
+
9
+ class MultipleImagesException(Exception):
10
+ pass
11
+
12
+
13
+ class IncompleteImageSetException(Exception):
14
+ pass
15
+
16
+
17
+ class BucketDoesNotExistException(Exception):
18
+ def __init__(self, bucket_name: str, *args, **kwargs):
19
+ msg = f"The bucket named '{bucket_name}' does not exist. You will need to create the bucket before proceeding."
20
+ super().__init__(msg, *args, **kwargs)
21
+
22
+
23
+ class AWSNotificationException(Exception):
24
+ pass
25
+
26
+
27
+ class AWSAuthorizationException(Exception):
28
+ pass