cloud-governance 1.1.385__py3-none-any.whl → 1.1.387__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.
@@ -24,6 +24,7 @@ class AzureOperations:
24
24
  self.billing_client = BillingManagementClient(credential=self.__default_creds,
25
25
  subscription_id=self.subscription_id)
26
26
  self.__account_id = self.__environment_variables_dict.get('AZURE_ACCOUNT_ID')
27
+ self.global_tags = self.__environment_variables_dict.get('GLOBAL_TAGS')
27
28
  self.cloud_name = 'AZURE'
28
29
  self.scope = f'subscriptions/{self.subscription_id}'
29
30
 
@@ -70,7 +70,7 @@ class EnvironmentVariables:
70
70
  self._environment_variables_dict['account'] = EnvironmentVariables.get_env('account', '').upper().strip()
71
71
  self._environment_variables_dict['AWS_DEFAULT_REGION'] = EnvironmentVariables.get_env('AWS_DEFAULT_REGION', '')
72
72
  self._environment_variables_dict['log_level'] = EnvironmentVariables.get_env('log_level', 'INFO')
73
-
73
+ self._environment_variables_dict['GLOBAL_TAGS'] = literal_eval(EnvironmentVariables.get_env('GLOBAL_TAGS', "{}"))
74
74
  self._environment_variables_dict['DAYS_TO_TAKE_ACTION'] = int(
75
75
  EnvironmentVariables.get_env('DAYS_TO_TAKE_ACTION', "7"))
76
76
  if not hasattr(self, 'POLICIES_LIST'):
@@ -108,6 +108,7 @@ class EnvironmentVariables:
108
108
  'cost_explorer_payer_billings', 'spot_savings_analysis']
109
109
  self._environment_variables_dict['ibm_policies'] = ['tag_baremetal', 'tag_vm', 'ibm_cost_report',
110
110
  'ibm_cost_over_usage']
111
+ self._environment_variables_dict['azure_policies'] = ['tag_azure_resource_group']
111
112
  if self._environment_variables_dict['policy'] in self._environment_variables_dict['cost_policies']:
112
113
  es_index = 'cloud-governance-global-cost-billing-index'
113
114
 
@@ -150,10 +151,9 @@ class EnvironmentVariables:
150
151
  self._environment_variables_dict['AZURE_ACCOUNT_ID'] = EnvironmentVariables.get_env('AZURE_ACCOUNT_ID', '')
151
152
  self._environment_variables_dict['AZURE_CLIENT_ID'] = EnvironmentVariables.get_env('AZURE_CLIENT_ID', '')
152
153
  self._environment_variables_dict['AZURE_TENANT_ID'] = EnvironmentVariables.get_env('AZURE_TENANT_ID', '')
153
- self._environment_variables_dict['AZURE_CLIENT_SECRET'] = EnvironmentVariables.get_env('AZURE_CLIENT_SECRET',
154
- '')
155
- self._environment_variables_dict['AZURE_SUBSCRIPTION_ID'] = EnvironmentVariables.get_env(
156
- 'AZURE_SUBSCRIPTION_ID', '')
154
+ self._environment_variables_dict['AZURE_CLIENT_SECRET'] = EnvironmentVariables.get_env('AZURE_CLIENT_SECRET', '')
155
+ self._environment_variables_dict['AZURE_SUBSCRIPTION_ID'] = EnvironmentVariables.get_env('AZURE_SUBSCRIPTION_ID', '')
156
+ self._environment_variables_dict['AZURE_SUBSCRIPTION_ID'] = EnvironmentVariables.get_env('AZURE_SUBSCRIPTION_ID', '')
157
157
  if self._environment_variables_dict['AZURE_CLIENT_ID'] and self._environment_variables_dict['AZURE_TENANT_ID'] \
158
158
  and self._environment_variables_dict['AZURE_CLIENT_SECRET']:
159
159
  self._environment_variables_dict['PUBLIC_CLOUD_NAME'] = 'AZURE'
@@ -411,7 +411,6 @@ class EnvironmentVariables:
411
411
 
412
412
 
413
413
  environment_variables = EnvironmentVariables()
414
-
415
414
  # env vars examples
416
415
  # os.environ['AWS_DEFAULT_REGION'] = 'us-east-2'
417
416
  # os.environ['AWS_DEFAULT_REGION'] = 'all'
@@ -254,7 +254,7 @@ def main():
254
254
  if environment_variables_dict.get('PUBLIC_CLOUD_NAME') and environment_variables_dict.get(
255
255
  'PUBLIC_CLOUD_NAME').upper() == 'AZURE':
256
256
  azure_cost_policy_runner = None
257
- is_azure_policy_runner = policy in environment_variables_dict.get('cost_policies')
257
+ is_azure_policy_runner = policy in environment_variables_dict.get('cost_policies') or policy in environment_variables_dict.get('azure_policies')
258
258
  if is_azure_policy_runner:
259
259
  azure_cost_policy_runner = AzurePolicyRunner()
260
260
 
@@ -0,0 +1,84 @@
1
+ from azure.mgmt.resource import ResourceManagementClient
2
+ from cloud_governance.common.logger.init_logger import logger
3
+ from cloud_governance.common.clouds.azure.subscriptions.azure_operations import AzureOperations
4
+
5
+
6
+ class TagAzureResourceGroup:
7
+ def __init__(self):
8
+ """
9
+ Initialize Azure clients and set the tags to apply.
10
+ """
11
+ self.__azure_operations = AzureOperations()
12
+ self.__subscription_id = self.__azure_operations.subscription_id
13
+ self.__credential = self.__azure_operations._AzureOperations__default_creds # reuse credentials
14
+ self.resource_client = ResourceManagementClient(self.__credential, self.__subscription_id)
15
+ self.__tags_to_add = self.__azure_operations.global_tags
16
+ if not self.__tags_to_add:
17
+ raise ValueError("No tags provided to add. Please set GLOBAL_TAGS environment variable.")
18
+
19
+ def tag_all(self):
20
+ """
21
+ Tag all resource groups and their contained resources with the specified tags.
22
+ """
23
+ resource_groups = self.resource_client.resource_groups.list()
24
+
25
+ for rg in resource_groups:
26
+ logger.info(f"Processing resource group: {rg.name}")
27
+ # Tag the resource group
28
+ try:
29
+ self.resource_client.resource_groups.update(
30
+ resource_group_name=rg.name,
31
+ parameters={"tags": self.__tags_to_add}
32
+ )
33
+ logger.info(f"Tagged resource group: {rg.name}")
34
+ except Exception as e:
35
+ logger.error(f"Failed to tag resource group {rg.name}: {e}")
36
+ continue
37
+
38
+ # Tag all resources in the resource group
39
+ for resource in self.resource_client.resources.list_by_resource_group(rg.name):
40
+ logger.info(f"Tagging resource: {resource.name} ({resource.type})")
41
+
42
+ existing_tags = resource.tags or {}
43
+ updated_tags = {**existing_tags, **self.__tags_to_add}
44
+
45
+ try:
46
+ parts = resource.type.split('/')
47
+ provider_ns = parts[0]
48
+ resource_type_str = '/'.join(parts[1:])
49
+
50
+ provider = self.resource_client.providers.get(provider_ns)
51
+
52
+ # Some resource_type may not match exactly, use a relaxed matching
53
+ resource_type_info = next(
54
+ (rt for rt in provider.resource_types if rt.resource_type.lower() == resource_type_str.lower()),
55
+ None
56
+ )
57
+
58
+ if not resource_type_info:
59
+ logger.warning(f"Could not find exact match for resource type: {resource_type_str} in provider {provider_ns}")
60
+ continue
61
+
62
+ api_version = next(
63
+ (v for v in resource_type_info.api_versions if 'preview' not in v.lower()),
64
+ resource_type_info.api_versions[0]
65
+ )
66
+
67
+ poller = self.resource_client.resources.begin_update_by_id(
68
+ resource_id=resource.id,
69
+ api_version=api_version,
70
+ parameters={
71
+ 'location': resource.location,
72
+ 'tags': updated_tags
73
+ }
74
+ )
75
+ poller.result()
76
+ logger.info(f"Tagged resource: {resource.name}")
77
+ except Exception as e:
78
+ logger.error(f"Failed to tag resource {resource.name}: {e}")
79
+
80
+ def run(self):
81
+ """
82
+ This method tags all Azure resources.
83
+ """
84
+ self.tag_all()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloud-governance
3
- Version: 1.1.385
3
+ Version: 1.1.387
4
4
  Summary: Cloud Governance Tool
5
5
  Home-page: https://github.com/redhat-performance/cloud-governance
6
6
  Author: Red Hat
@@ -84,7 +84,7 @@ cloud_governance/common/clouds/azure/cost_management/cost_management_operations.
84
84
  cloud_governance/common/clouds/azure/monitor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
85
  cloud_governance/common/clouds/azure/monitor/monitor_management_operations.py,sha256=4PoqjTAyHW42F6KcxoYABogtsKMEfqYarzC6S-subl8,3353
86
86
  cloud_governance/common/clouds/azure/subscriptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
- cloud_governance/common/clouds/azure/subscriptions/azure_operations.py,sha256=IFqaKMu4vKaH_nrin4ks1FHcI_huyrDD7K9jIp5AL4o,2843
87
+ cloud_governance/common/clouds/azure/subscriptions/azure_operations.py,sha256=24XJB5Y_a5nI0pz6rzqYHlHT4edeMmd-4TzJ5CsdCs0,2923
88
88
  cloud_governance/common/clouds/cloudability/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
89
  cloud_governance/common/clouds/cloudability/cloudability_operations.py,sha256=HlqYt1ZCepTdi8_1bFoxz3RcBvUhV3Tlynqh1O1mDns,4345
90
90
  cloud_governance/common/clouds/cloudability/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -143,10 +143,10 @@ cloud_governance/common/utils/configs.py,sha256=shFxWt0Kc-GwzcZKYCkHm058ujwdTxn4
143
143
  cloud_governance/common/utils/json_datetime_encoder.py,sha256=_-jzRTe0UqAKTn2E9qaU8SYIxHUoRA5ElWuVA0Y54Xw,338
144
144
  cloud_governance/common/utils/utils.py,sha256=ZUsi4ax2XhDIV-EQ5kJt5Ppd72kmm2psqcg1cNDZrvc,4349
145
145
  cloud_governance/main/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
146
- cloud_governance/main/environment_variables.py,sha256=8OdeTmZNnjCJtXVKjQnqVR4_fnVCRxxW4mZ4Oirq09M,29564
146
+ cloud_governance/main/environment_variables.py,sha256=ZGGm6KDVCSx8Yps9jZph_lE3K9nbVk7yzOd8KFZLCHY,29792
147
147
  cloud_governance/main/environment_variables_exceptions.py,sha256=UR0Ith0P0oshsDZdJRlRq8ZUTt0h8jFvUtrnP4m4AIY,437
148
148
  cloud_governance/main/es_uploader.py,sha256=6Ify5CS2NtUF1xXZ-rMwpYxVzDKfEZhv2vogWFltt98,10656
149
- cloud_governance/main/main.py,sha256=4TBiCBO_1z8KpGXb8brPKBmv3jHBl8fl_-Sb80ctYno,18880
149
+ cloud_governance/main/main.py,sha256=y6k3SZs8mLEXqbsi-7NpkSxIIgGO19awQGWkaW_r8lQ,18942
150
150
  cloud_governance/main/main_common_operations.py,sha256=YbBJF6Smk3YKhEibnn-fIWu1oKP0pSGIM1WnSXFcBuo,366
151
151
  cloud_governance/main/run_cloud_resource_orchestration.py,sha256=Jo7-KDqxrIo8uioyTFCohUHse4uqdEt2ZFnHlX2u57g,776
152
152
  cloud_governance/main/main_oerations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -179,6 +179,7 @@ cloud_governance/policy/aws/monitor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQ
179
179
  cloud_governance/policy/aws/monitor/cluster_run.py,sha256=5NzJmnlCl520Qvkb8isqvFG7MooqF23P0qEIpAtvJck,7896
180
180
  cloud_governance/policy/azure/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
181
181
  cloud_governance/policy/azure/cost_billing_reports.py,sha256=FgHKqBTHgckCjsEbU9iMs5-ANcNCrsh4f0EjbtkpgW8,10865
182
+ cloud_governance/policy/azure/tag_azure_resource_group.py,sha256=RSEkH-zJNMxHSPWJfeR5TbWU17Wh9tqzZoX-HS6Pj-A,3703
182
183
  cloud_governance/policy/azure/cleanup/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
183
184
  cloud_governance/policy/azure/cleanup/instance_idle.py,sha256=xdcwRRDQt-B_IhCHFA6Maqjm8TI-bUOKK3avHJ5QPpY,3074
184
185
  cloud_governance/policy/azure/cleanup/instance_run.py,sha256=qoOBoVawHKMPBbtI6Pkb0ywOyE5N8OynRQHE_AKDNbE,4293
@@ -264,8 +265,8 @@ cloud_governance/policy/policy_runners/elasticsearch/__init__.py,sha256=47DEQpj8
264
265
  cloud_governance/policy/policy_runners/elasticsearch/upload_elastic_search.py,sha256=pOwUJWXjJbyTy8iv3Ap8xJGnqQe-5lZgoR8-vGfAVos,1881
265
266
  cloud_governance/policy/policy_runners/ibm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
266
267
  cloud_governance/policy/policy_runners/ibm/policy_runner.py,sha256=V0E_f7F3hXit0aSq4BlfX1Jd4vjR2NEvOWsJ5upvZ4o,1302
267
- cloud_governance-1.1.385.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
268
- cloud_governance-1.1.385.dist-info/METADATA,sha256=wFILoa8MAn9lRcJJAKLlN1RSFxhc9POysSEdFaBl35Q,11384
269
- cloud_governance-1.1.385.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
270
- cloud_governance-1.1.385.dist-info/top_level.txt,sha256=jfB1fgj7jvx3YZkZA4G6hFeS1RHO7J7XtnbjuMNMRww,17
271
- cloud_governance-1.1.385.dist-info/RECORD,,
268
+ cloud_governance-1.1.387.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
269
+ cloud_governance-1.1.387.dist-info/METADATA,sha256=ZyNs1j_P8ChFY6ewF3zZRTJkscP2gMTQSuNoE1vWJ_E,11384
270
+ cloud_governance-1.1.387.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
271
+ cloud_governance-1.1.387.dist-info/top_level.txt,sha256=jfB1fgj7jvx3YZkZA4G6hFeS1RHO7J7XtnbjuMNMRww,17
272
+ cloud_governance-1.1.387.dist-info/RECORD,,