classifyawsetsjsonbyregion 0.1.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.
@@ -0,0 +1,5 @@
1
+ """Top-level package for Classify AWSets JSON by Region."""
2
+
3
+ __author__ = """Yukihiko Shinoda"""
4
+ __email__ = "yuk.hik.future@gmail.com"
5
+ __version__ = "0.1.0"
@@ -0,0 +1,46 @@
1
+ """Analyze AWSets JSON."""
2
+ from __future__ import annotations
3
+
4
+ import json
5
+ from typing import Any
6
+
7
+ from classifyawsetsjsonbyregion.awsets import Awset, AwsetFilter
8
+ from classifyawsetsjsonbyregion.awsregion.classifier import Classifier
9
+ from classifyawsetsjsonbyregion.config import Config
10
+ from classifyawsetsjsonbyregion.csv import OutputCsv
11
+ from classifyawsetsjsonbyregion.filepath import FilePathCreator
12
+
13
+ CONFIG: Config = Config()
14
+
15
+
16
+ class AwsetsJsonAnalyzer:
17
+ """To analyze AWSets JSON."""
18
+
19
+ UTF8 = "utf-8"
20
+
21
+ def __init__(self) -> None:
22
+ CONFIG.load("config.yml")
23
+ self.file_path_creator = FilePathCreator()
24
+ self.classifier = Classifier(CONFIG.region_exclude)
25
+ self.awset_filter = AwsetFilter(CONFIG.ignore_pattern)
26
+
27
+ def analyze(self) -> None:
28
+ awsets = json.loads(self.file_path_creator.path_resources_json.read_text(encoding=self.UTF8))
29
+ awsets = [awset for awset in awsets if awset["Region"] not in CONFIG.region_exclude]
30
+ self.file_path_creator.file_awsets_other_regions.write_text(json.dumps(awsets, indent=2), encoding=self.UTF8)
31
+ for region_name, awsets_in_region in self.classifier.classify_by_region(awsets).items():
32
+ self.analyze_each_region(region_name, awsets_in_region)
33
+
34
+ def analyze_each_region(self, region_name: str, awsets: list[Awset]) -> None:
35
+ """Analyzes AWSets in each region."""
36
+ sorted_awsets = sorted(awsets, key=lambda x: (x["Type"], x["Name"], x["Tags"]))
37
+ path_json = self.file_path_creator.create_path_json_per_region(region_name)
38
+ path_json.write_text(json.dumps(sorted_awsets, indent=2), encoding=self.UTF8)
39
+ output_csv = OutputCsv(self.file_path_creator.create_path_csv_per_region(region_name))
40
+ with output_csv.writer() as writer:
41
+ # Reason: Return values are None. pylint: disable=expression-not-assigned
42
+ [writer.writerow(self.to_row(awset)) for awset in sorted_awsets if self.awset_filter.is_passed(awset)]
43
+
44
+ @staticmethod
45
+ def to_row(awset: Awset) -> list[Any]:
46
+ return [awset["Type"], awset["Name"], awset["Tags"]]
@@ -0,0 +1,39 @@
1
+ """Model of AWSets."""
2
+ from __future__ import annotations
3
+
4
+ import re
5
+ import sys
6
+
7
+ if sys.version_info >= (3, 8):
8
+ from typing import TypedDict
9
+ else:
10
+ from typing_extensions import TypedDict # pragma: no cover
11
+
12
+
13
+ class Awset(TypedDict):
14
+ Region: str
15
+ Type: str
16
+ Name: str
17
+ Tags: dict[str, str]
18
+
19
+
20
+ class AwsetFilter:
21
+ """To filter AWSets data for specific investigation purpose."""
22
+
23
+ def __init__(self, dict_ignore_pattern: dict[str, list[str]]) -> None:
24
+ self.dict_ignore_pattern = dict_ignore_pattern
25
+
26
+ def is_passed(self, awset: Awset) -> bool:
27
+ """Filter AWSets data.
28
+
29
+ Args:
30
+ awset: AWSets data of target resource
31
+ Returns:
32
+ True: Target resource should be filtered
33
+ False: Target resource should not be filtered
34
+ """
35
+ list_ignore_pattern = self.dict_ignore_pattern.get(awset["Type"])
36
+ if not list_ignore_pattern:
37
+ return True
38
+ regex = "|".join(list_ignore_pattern)
39
+ return not re.search(regex, awset["Name"])
@@ -0,0 +1 @@
1
+ """AWS region."""
@@ -0,0 +1,51 @@
1
+ """Classifies AWSets into each regions."""
2
+ from __future__ import annotations
3
+
4
+ from typing import TYPE_CHECKING
5
+
6
+ if TYPE_CHECKING:
7
+ from classifyawsetsjsonbyregion.awsets import Awset
8
+
9
+
10
+ REGIONS = {
11
+ "us-east-1": "US East (N. Virginia)",
12
+ "us-east-2": "US East (Ohio)",
13
+ "us-west-1": "US West (N. California)",
14
+ "us-west-2": "US West (Oregon)",
15
+ "ap-south-1": "Asia Pacific (Mumbai)",
16
+ "ap-northeast-3": "Asia Pacific (Osaka)",
17
+ "ap-northeast-2": "Asia Pacific (Seoul)",
18
+ "ap-southeast-1": "Asia Pacific (Singapore)",
19
+ "ap-southeast-2": "Asia Pacific (Sydney)",
20
+ "ap-northeast-1": "Asia Pacific (Tokyo)",
21
+ "ca-central-1": "Canada (Central)",
22
+ "eu-central-1": "Europe (Frankfurt)",
23
+ "eu-west-1": "Europe (Ireland)",
24
+ "eu-west-2": "Europe (London)",
25
+ "eu-west-3": "Europe (Paris)",
26
+ "eu-north-1": "Europe (Stockholm)",
27
+ "sa-east-1": "South America (São Paulo)",
28
+ "aws-global": "global",
29
+ }
30
+
31
+
32
+ def create_classified_awsets_empty(regions_exclude: list[str]) -> dict[str, list[Awset]]:
33
+ classified_awsets_empty: dict[str, list[Awset]] = {}
34
+ for region_name in REGIONS:
35
+ if region_name in regions_exclude:
36
+ continue
37
+ classified_awsets_empty[region_name] = []
38
+ return classified_awsets_empty
39
+
40
+
41
+ class Classifier:
42
+ """To report in each region."""
43
+
44
+ def __init__(self, region_exclude: list[str]) -> None:
45
+ self.classified_awsets = create_classified_awsets_empty(region_exclude)
46
+
47
+ def classify_by_region(self, awsets: list[Awset]) -> dict[str, list[Awset]]:
48
+ for awset in awsets:
49
+ region = awset["Region"]
50
+ self.classified_awsets[region].append(awset)
51
+ return self.classified_awsets
@@ -0,0 +1,17 @@
1
+ """Console script for classifyawsetsjsonbyregion."""
2
+ import sys
3
+
4
+ import click
5
+
6
+ from classifyawsetsjsonbyregion.analyzer import AwsetsJsonAnalyzer
7
+
8
+
9
+ @click.command()
10
+ def main() -> int:
11
+ """Console script for classifyawsetsjsonbyregion."""
12
+ AwsetsJsonAnalyzer().analyze()
13
+ return 0
14
+
15
+
16
+ if __name__ == "__main__":
17
+ sys.exit(main()) # pragma: no cover
@@ -0,0 +1,11 @@
1
+ """Configurations."""
2
+ from dataclasses import dataclass
3
+ from typing import Dict, List
4
+
5
+ from yamldataclassconfig import YamlDataClassConfig
6
+
7
+
8
+ @dataclass
9
+ class Config(YamlDataClassConfig):
10
+ region_exclude: List[str] = None # type: ignore[assignment]
11
+ ignore_pattern: Dict[str, List[str]] = None # type: ignore[assignment]
@@ -0,0 +1,27 @@
1
+ """Json to CSV."""
2
+ from contextlib import contextmanager, suppress
3
+ import csv
4
+ from pathlib import Path
5
+ from typing import TYPE_CHECKING
6
+
7
+ if TYPE_CHECKING:
8
+ from collections.abc import Generator
9
+
10
+ import _csv
11
+
12
+ # Reason: For type hinting.
13
+ standard_csv_writer = _csv._writer # noqa: SLF001 pylint: disable=protected-access,no-member
14
+
15
+
16
+ class OutputCsv:
17
+ """To output AWSets data into CSV."""
18
+
19
+ def __init__(self, path_csv: Path) -> None:
20
+ self.path_csv = path_csv
21
+ with suppress(FileNotFoundError):
22
+ self.path_csv.unlink()
23
+
24
+ @contextmanager
25
+ def writer(self) -> "Generator[standard_csv_writer, None, None]":
26
+ with self.path_csv.open("w", newline="") as csv_file_pointer:
27
+ yield csv.writer(csv_file_pointer, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL)
@@ -0,0 +1,21 @@
1
+ """JSON per each regions."""
2
+ from pathlib import Path
3
+
4
+
5
+ class FilePathCreator:
6
+ """To aggregate path to file."""
7
+
8
+ DIRECTORY_INPUT = Path("input")
9
+ DIRECTORY_INTERMEDIATE = Path("intermediate")
10
+ DIRECTORY_OUTPUT = Path("output")
11
+
12
+ def __init__(self) -> None:
13
+ self.path_resources_json = self.DIRECTORY_INPUT / "awsets.json"
14
+ output_file_name = f"{self.path_resources_json.stem}-other-regions.json"
15
+ self.file_awsets_other_regions = self.DIRECTORY_INTERMEDIATE / output_file_name
16
+
17
+ def create_path_json_per_region(self, regions_name: str) -> Path:
18
+ return self.DIRECTORY_INTERMEDIATE / f"{self.file_awsets_other_regions.stem}-{regions_name}.json"
19
+
20
+ def create_path_csv_per_region(self, region_name: str) -> Path:
21
+ return self.DIRECTORY_OUTPUT / f"{self.file_awsets_other_regions.stem}-{region_name}.csv"
File without changes
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Yukihiko Shinoda
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,133 @@
1
+ Metadata-Version: 2.1
2
+ Name: classifyawsetsjsonbyregion
3
+ Version: 0.1.0
4
+ Summary: Classifies AWSets JSON by region.
5
+ Author-email: Yukihiko Shinoda <yuk.hik.future@gmail.com>
6
+ Maintainer-email: Yukihiko Shinoda <yuk.hik.future@gmail.com>
7
+ License: MIT License
8
+
9
+ Copyright (c) 2023 Yukihiko Shinoda
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+
29
+ Project-URL: homepage, https://github.com/yukihiko-shinoda/classify-awsets-json-by-region
30
+ Project-URL: repository, https://github.com/yukihiko-shinoda/classify-awsets-json-by-region
31
+ Keywords: classifyawsetsjsonbyregion,classify-awsets-json-by-region,awsets,aws
32
+ Classifier: Development Status :: 4 - Beta
33
+ Classifier: Intended Audience :: Developers
34
+ Classifier: Intended Audience :: Information Technology
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Natural Language :: English
37
+ Classifier: Operating System :: OS Independent
38
+ Classifier: Programming Language :: Python
39
+ Classifier: Programming Language :: Python :: 3
40
+ Classifier: Programming Language :: Python :: 3.7
41
+ Classifier: Programming Language :: Python :: 3.8
42
+ Classifier: Programming Language :: Python :: 3.9
43
+ Classifier: Programming Language :: Python :: 3.10
44
+ Classifier: Programming Language :: Python :: 3.11
45
+ Classifier: Topic :: Scientific/Engineering
46
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
47
+ Classifier: Topic :: Security
48
+ Classifier: Topic :: Text Processing
49
+ Classifier: Topic :: Text Processing :: Filters
50
+ Classifier: Typing :: Typed
51
+ Requires-Python: >=3.7
52
+ Description-Content-Type: text/markdown
53
+ License-File: LICENSE
54
+ Requires-Dist: click (>=7.0)
55
+ Requires-Dist: yamldataclassconfig
56
+ Requires-Dist: typing-extensions ; python_version <= "3.7"
57
+ Provides-Extra: test
58
+
59
+ # Classify AWSets JSON by Region
60
+
61
+ [![Test](https://github.com/yukihiko-shinoda/classify-awsets-json-by-region/workflows/Test/badge.svg)](https://github.com/yukihiko-shinoda/classify-awsets-json-by-region/actions?query=workflow%3ATest)
62
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/d3006b43fedc1ffd5db7/test_coverage)](https://codeclimate.com/github/yukihiko-shinoda/classify-awsets-json-by-region/test_coverage)
63
+ [![Maintainability](https://api.codeclimate.com/v1/badges/d3006b43fedc1ffd5db7/maintainability)](https://codeclimate.com/github/yukihiko-shinoda/classify-awsets-json-by-region/maintainability)
64
+ [![Code Climate technical debt](https://img.shields.io/codeclimate/tech-debt/yukihiko-shinoda/classify-awsets-json-by-region)](https://codeclimate.com/github/yukihiko-shinoda/classify-awsets-json-by-region)
65
+ [![Python versions](https://img.shields.io/pypi/pyversions/classifyawsetsjsonbyregion.svg)](https://pypi.org/project/classifyawsetsjsonbyregion)
66
+ [![Twitter URL](https://img.shields.io/twitter/url?style=social&url=https%3A%2F%2Fgithub.com%2Fyukihiko-shinoda%2Fclassify-awsets-json-by-region)](http://twitter.com/share?text=Classify%20AWSets%20JSON%20by%20Region&url=https://pypi.org/project/classifyawsetsjsonbyregion/&hashtags=python)
67
+
68
+ Classifies AWSets JSON by AWS region.
69
+
70
+ ## Advantage
71
+
72
+ - Output the list of AWS resources as CSV files classified by AWS region
73
+ - Enable filter to exclude AWS resources not in question
74
+
75
+ ### Output the list of AWS resources as CSV files classified by AWS region
76
+
77
+ You can check the states of AWS resources by AWS region. It's also useful to compare the states of AWS resources between AWS regions by using text diff tools like [Visual Studio Code].
78
+
79
+ ### Enable filter to exclude AWS resources not in question
80
+
81
+ You can exclude AWS resources not in question by using `config.yml`. It's useful to reduce the number of AWS resources to be checked, such like the one AWS created by default. You can focus on AWS resources in question.
82
+
83
+ ## Quickstart
84
+
85
+ 1.\
86
+ Install `classifyawsetsjsonbyregion` with pip:
87
+
88
+ ```console
89
+ pip install classifyawsetsjsonbyregion
90
+ ```
91
+
92
+ 2.\
93
+ Create following directories:
94
+
95
+ - `input`
96
+ - `output`
97
+ - `intermediate`
98
+
99
+ 3.\
100
+ Put AWSets JSON files in it and rename it as `awsets.json`:
101
+
102
+ ```plaintext
103
+ your_working_directory/
104
+ +---input/
105
+ +---awsets.json
106
+ +---intermediate/
107
+ +---output/
108
+ ```
109
+
110
+ 4.\
111
+ Run `classify-awsets-json-by-region`:
112
+
113
+ ```console
114
+ classify-awsets-json-by-region
115
+ ```
116
+
117
+ <!-- markdownlint-disable no-trailing-punctuation -->
118
+ ## How do I...
119
+ <!-- markdownlint-enable no-trailing-punctuation -->
120
+
121
+ <!-- markdownlint-disable no-trailing-punctuation -->
122
+ ### Use intermediate directory for?
123
+ <!-- markdownlint-enable no-trailing-punctuation -->
124
+
125
+ This directory is for intermediate files. These files are useful for debugging. The contents of these files are the classifying result of AWSets JSON before filtering AWS resources. Note that the file for excluded AWS regions is not created.
126
+
127
+ ## Credits
128
+
129
+ This package was created with [Cookiecutter] and the [yukihiko-shinoda/cookiecutter-pypackage] project template.
130
+
131
+ [Cookiecutter]: https://github.com/audreyr/cookiecutter
132
+ [Visual Studio Code]: https://code.visualstudio.com/
133
+ [yukihiko-shinoda/cookiecutter-pypackage]: https://github.com/audreyr/cookiecutter-pypackage
@@ -0,0 +1,16 @@
1
+ classifyawsetsjsonbyregion/__init__.py,sha256=jDplQozIZ-Q3voVnqku-SwpmbB1MIHatZrwNbvAL4Dc,158
2
+ classifyawsetsjsonbyregion/analyzer.py,sha256=EUr2ALsLpSjOEW9C0MW9chAB2lHEiGfQWKzzbZGavQk,2115
3
+ classifyawsetsjsonbyregion/awsets.py,sha256=IMVf91hmGpr7HEaNd-93zqgQ9-CZP8d4QtxlOoL0Zs8,1045
4
+ classifyawsetsjsonbyregion/cli.py,sha256=1TbPwcvVubuN8E2Uil7oPQ9tkleTNfwRi4Gx5IodMeY,359
5
+ classifyawsetsjsonbyregion/config.py,sha256=BuSXdQ2FuE7aFLto8uTr4VJxhsmybIO5Pm25vuidAzA,328
6
+ classifyawsetsjsonbyregion/csv.py,sha256=WqBObx3doUxSE9_PvGbhUOKmpR7ygM6aCGD9QXk7C7E,831
7
+ classifyawsetsjsonbyregion/filepath.py,sha256=uX7f6ocwGsj5H94lQ6e5sXSJQhq8RLQ4D9UyHlUv4kI,859
8
+ classifyawsetsjsonbyregion/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ classifyawsetsjsonbyregion/awsregion/__init__.py,sha256=bWKS1SwYtC4Vi8gdLzqDaFL7hzc5vgR9P0sriC6Wtig,18
10
+ classifyawsetsjsonbyregion/awsregion/classifier.py,sha256=epUf-nyEPkMmbue9S7SXqgUBdL0NSh8a5iS4HVfdC_4,1713
11
+ classifyawsetsjsonbyregion-0.1.0.dist-info/LICENSE,sha256=NiIdqgTwrHZWOeTg5VvcrBrgM1t1juwgA3G2QjSrj1k,1073
12
+ classifyawsetsjsonbyregion-0.1.0.dist-info/METADATA,sha256=UeS8dSrQSz-ct94JBr-zmL5blR-a-BKUZPWUWuMkdHA,6131
13
+ classifyawsetsjsonbyregion-0.1.0.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
14
+ classifyawsetsjsonbyregion-0.1.0.dist-info/entry_points.txt,sha256=reGLUm0s5HqhUIYLseszDqxqmAxpu4xHJCKoFPKU0GE,87
15
+ classifyawsetsjsonbyregion-0.1.0.dist-info/top_level.txt,sha256=PlOuOCJMhrrbkQ4vFG7utFaWef-LipkyZ_q3Go8JIyA,27
16
+ classifyawsetsjsonbyregion-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.40.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ classify-awsets-json-by-region = classifyawsetsjsonbyregion.cli:main
@@ -0,0 +1 @@
1
+ classifyawsetsjsonbyregion