cloudconsolelink 1.0.24__tar.gz → 2.0.0__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 (25) hide show
  1. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/PKG-INFO +37 -5
  2. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/README.md +16 -0
  3. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink/__init__.py +1 -1
  4. cloudconsolelink-2.0.0/cloudconsolelink/clouds/aws/__init__.py +137 -0
  5. cloudconsolelink-2.0.0/cloudconsolelink/clouds/aws/links.py +1035 -0
  6. cloudconsolelink-2.0.0/cloudconsolelink/clouds/azure/__init__.py +52 -0
  7. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink/clouds/gcp/__init__.py +1 -2
  8. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink/clouds/gcp/links.py +308 -105
  9. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink.egg-info/PKG-INFO +37 -5
  10. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink.egg-info/SOURCES.txt +3 -1
  11. cloudconsolelink-2.0.0/cloudconsolelink.egg-info/requires.txt +8 -0
  12. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/setup.cfg +1 -1
  13. cloudconsolelink-2.0.0/setup.py +58 -0
  14. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/tests/test_aws.py +74 -1
  15. cloudconsolelink-2.0.0/tests/test_provider_coverage.py +288 -0
  16. cloudconsolelink-1.0.24/cloudconsolelink/clouds/aws/__init__.py +0 -108
  17. cloudconsolelink-1.0.24/cloudconsolelink/clouds/aws/links.py +0 -1026
  18. cloudconsolelink-1.0.24/cloudconsolelink/clouds/azure/__init__.py +0 -45
  19. cloudconsolelink-1.0.24/setup.py +0 -48
  20. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/LICENSE +0 -0
  21. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink/clouds/__init__.py +0 -0
  22. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink.egg-info/dependency_links.txt +0 -0
  23. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink.egg-info/top_level.txt +0 -0
  24. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/tests/test_azure.py +0 -0
  25. {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/tests/test_gcp.py +0 -0
@@ -1,18 +1,34 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: cloudconsolelink
3
- Version: 1.0.24
3
+ Version: 2.0.0
4
4
  Summary: Generate console links for cloud resources
5
5
  Home-page: https://github.com/Cloudanix/cloud-console-links
6
6
  Maintainer: Cloudanix
7
- Maintainer-email: ganesh@cloudanix.com
8
- License: apache2
7
+ Maintainer-email: support@cloudanix.com
8
+ License: Apache-2.0
9
9
  Classifier: Programming Language :: Python :: 3
10
10
  Classifier: Intended Audience :: Developers
11
- Classifier: License :: OSI Approved :: Apache Software License
12
11
  Classifier: Natural Language :: English
13
12
  Classifier: Operating System :: OS Independent
14
13
  Description-Content-Type: text/markdown
15
14
  License-File: LICENSE
15
+ Provides-Extra: dev
16
+ Requires-Dist: pre-commit~=4.2; extra == "dev"
17
+ Requires-Dist: pytest~=8.3; extra == "dev"
18
+ Requires-Dist: pytest-cov==2.11; extra == "dev"
19
+ Requires-Dist: pytest-mock~=3.14; extra == "dev"
20
+ Requires-Dist: types-PyYAML~=6.0; extra == "dev"
21
+ Requires-Dist: types-requests~=2.32; extra == "dev"
22
+ Dynamic: classifier
23
+ Dynamic: description
24
+ Dynamic: description-content-type
25
+ Dynamic: home-page
26
+ Dynamic: license
27
+ Dynamic: license-file
28
+ Dynamic: maintainer
29
+ Dynamic: maintainer-email
30
+ Dynamic: provides-extra
31
+ Dynamic: summary
16
32
 
17
33
  # What is cloudconsolelink?
18
34
  This project for generate console links for AWS, GCP and Azure cloud resources
@@ -20,6 +36,22 @@ This project for generate console links for AWS, GCP and Azure cloud resources
20
36
  # Install
21
37
  Run ```pip install cloudconsolelink``` to install our code
22
38
 
39
+ For local development, install the package with dev extras:
40
+
41
+ ```bash
42
+ pip install -e '.[dev]'
43
+ ```
44
+
45
+ Verification shortcuts:
46
+
47
+ ```bash
48
+ make test
49
+ make coverage
50
+ make test-arn
51
+ make test-aws-links
52
+ make check
53
+ ```
54
+
23
55
  # Usage
24
56
 
25
57
  ### Import Package
@@ -4,6 +4,22 @@ This project for generate console links for AWS, GCP and Azure cloud resources
4
4
  # Install
5
5
  Run ```pip install cloudconsolelink``` to install our code
6
6
 
7
+ For local development, install the package with dev extras:
8
+
9
+ ```bash
10
+ pip install -e '.[dev]'
11
+ ```
12
+
13
+ Verification shortcuts:
14
+
15
+ ```bash
16
+ make test
17
+ make coverage
18
+ make test-arn
19
+ make test-aws-links
20
+ make check
21
+ ```
22
+
7
23
  # Usage
8
24
 
9
25
  ### Import Package
@@ -1,2 +1,2 @@
1
1
  # version of the module
2
- __version__ = '1.0.24'
2
+ __version__ = "2.0.0"
@@ -0,0 +1,137 @@
1
+ import logging
2
+ import urllib.parse
3
+ from typing import Dict
4
+
5
+ from .links import get_links
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+
10
+ def get_console(partition: str) -> str:
11
+ consoles = {
12
+ "aws": "console.aws.amazon.com",
13
+ "aws-us-gov": "console.amazonaws-us-gov.com",
14
+ "aws-cn": "console.amazonaws.cn",
15
+ }
16
+ return consoles.get(partition, "")
17
+
18
+
19
+ def get_arn_string(data: Dict) -> str:
20
+ if not data.get("resourceType", ""):
21
+ return (
22
+ f"{data.get('prefix', '')}:{data.get('partition', '')}:{data.get('service', '')}:"
23
+ f"{data.get('region', '')}:{data.get('account', '')}:{data.get('resource', '')}"
24
+ )
25
+
26
+ elif data.get("hasPath", ""):
27
+ return (
28
+ f"{data.get('prefix', '')}:{data.get('partition', '')}:{data.get('service', '')}:"
29
+ f"{data.get('region', '')}:{data.get('account', '')}:{data.get('resourceType', '')}"
30
+ f"/{data.get('resource', '')}"
31
+ )
32
+
33
+ else:
34
+ return (
35
+ f"{data.get('prefix', '')}:{data.get('partition', '')}:{data.get('service', '')}:"
36
+ f"{data.get('region', '')}:{data.get('account', '')}:{data.get('resourceType', '')}:"
37
+ f"{data.get('resource', '')}"
38
+ )
39
+
40
+
41
+ def get_qualifiers(resource: str) -> list[str]:
42
+ return resource.split(":")
43
+
44
+
45
+ def get_resource_path(resource: str) -> str:
46
+ return resource.split("/")[-1]
47
+
48
+
49
+ class AWSLinker:
50
+ def get_console_link(self, arn: str) -> str:
51
+ logger.debug(f"Start Process for AWS ARN: {arn}")
52
+ arn = arn.strip()
53
+ firstTokens = arn.split(":")
54
+ tokens = firstTokens[:7]
55
+
56
+ try:
57
+ data: dict[str, str | bool] = {
58
+ "prefix": tokens[0],
59
+ "partition": tokens[1],
60
+ "service": tokens[2],
61
+ "region": tokens[3],
62
+ "account": tokens[4],
63
+ "resourceType": "",
64
+ "resource": "",
65
+ "hasPath": False,
66
+ }
67
+
68
+ except IndexError:
69
+ logger.error(f"AWS ARN {arn} is too short")
70
+ raise ValueError(f"AWS ARN {arn} is too short")
71
+
72
+ if len(tokens) > 6:
73
+ data["resourceType"] = tokens[5]
74
+ data["resource"] = tokens[6]
75
+ data["hasPath"] = False
76
+
77
+ elif len(tokens) > 5 and tokens[5].count("/") > 0:
78
+ data["resourceType"] = tokens[5][: tokens[5].index("/")]
79
+ data["resource"] = tokens[5][tokens[5].index("/") + 1 :]
80
+ data["hasPath"] = True
81
+
82
+ elif len(tokens) > 5 and tokens[5].count("/") == 0:
83
+ data["resourceType"] = ""
84
+ data["resource"] = tokens[5]
85
+ data["hasPath"] = False
86
+
87
+ else:
88
+ logger.error(f"Invalid AWS ARN {arn}")
89
+ raise ValueError(f"Invalid AWS ARN {arn}")
90
+
91
+ console = get_console(str(data.get("partition", "")))
92
+ if not console:
93
+ logger.error(
94
+ f"AWS ARN {arn} has invalid partition (Valid Partitions: aws, aws-us-gov, aws-cn)",
95
+ )
96
+ raise ValueError(
97
+ f"AWS ARN {arn} has invalid partition (Valid Partitions: aws, aws-us-gov, aws-cn)",
98
+ )
99
+ data["console"] = console
100
+
101
+ links = get_links()
102
+
103
+ if data["prefix"] != "arn":
104
+ logger.error(f"Invalid AWS ARN {arn}")
105
+ raise ValueError(f"Invalid AWS ARN {arn}")
106
+
107
+ elif not links.get(data["service"], None):
108
+ logger.error(f"AWS service {data['service']} unknown")
109
+ raise ValueError(f"AWS service {data['service']} unknown")
110
+
111
+ elif not links.get(data["service"], {}).get(data["resourceType"], None):
112
+ logger.error(
113
+ f"AWS service {data['service']} resource type {data['resourceType']} not supported",
114
+ )
115
+
116
+ # If resource type does not exist, take the user to service home page
117
+ return f"https://console.aws.amazon.com/{data['service']}"
118
+
119
+ # raise ValueError(f"AWS service {data['service']} resource type {data['resourceType']} not supported")
120
+
121
+ else:
122
+ template_context = {
123
+ "arn": arn,
124
+ "data": data,
125
+ "get_arn_string": get_arn_string,
126
+ "get_qualifiers": get_qualifiers,
127
+ "get_resource_path": get_resource_path,
128
+ }
129
+ data["resource"] = urllib.parse.quote(str(data["resource"]))
130
+ return eval(
131
+ f"f'{links[data['service']][data['resourceType']]}'",
132
+ {"__builtins__": {}},
133
+ template_context,
134
+ ).replace(
135
+ " ",
136
+ "",
137
+ )