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.
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/PKG-INFO +37 -5
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/README.md +16 -0
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink/__init__.py +1 -1
- cloudconsolelink-2.0.0/cloudconsolelink/clouds/aws/__init__.py +137 -0
- cloudconsolelink-2.0.0/cloudconsolelink/clouds/aws/links.py +1035 -0
- cloudconsolelink-2.0.0/cloudconsolelink/clouds/azure/__init__.py +52 -0
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink/clouds/gcp/__init__.py +1 -2
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink/clouds/gcp/links.py +308 -105
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink.egg-info/PKG-INFO +37 -5
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink.egg-info/SOURCES.txt +3 -1
- cloudconsolelink-2.0.0/cloudconsolelink.egg-info/requires.txt +8 -0
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/setup.cfg +1 -1
- cloudconsolelink-2.0.0/setup.py +58 -0
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/tests/test_aws.py +74 -1
- cloudconsolelink-2.0.0/tests/test_provider_coverage.py +288 -0
- cloudconsolelink-1.0.24/cloudconsolelink/clouds/aws/__init__.py +0 -108
- cloudconsolelink-1.0.24/cloudconsolelink/clouds/aws/links.py +0 -1026
- cloudconsolelink-1.0.24/cloudconsolelink/clouds/azure/__init__.py +0 -45
- cloudconsolelink-1.0.24/setup.py +0 -48
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/LICENSE +0 -0
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink/clouds/__init__.py +0 -0
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink.egg-info/dependency_links.txt +0 -0
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/cloudconsolelink.egg-info/top_level.txt +0 -0
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/tests/test_azure.py +0 -0
- {cloudconsolelink-1.0.24 → cloudconsolelink-2.0.0}/tests/test_gcp.py +0 -0
|
@@ -1,18 +1,34 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: cloudconsolelink
|
|
3
|
-
Version:
|
|
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:
|
|
8
|
-
License:
|
|
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__ =
|
|
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
|
+
)
|