cid-cmd 4.4.2__tar.gz → 4.4.4__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 (123) hide show
  1. {cid_cmd-4.4.2/cid_cmd.egg-info → cid_cmd-4.4.4}/PKG-INFO +1 -1
  2. cid_cmd-4.4.4/cid/_version.py +2 -0
  3. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/common.py +4 -1
  4. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/athena.py +19 -16
  5. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/iam.py +2 -2
  6. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/quicksight/__init__.py +1 -1
  7. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/quicksight/dashboard.py +53 -15
  8. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/quicksight/definition.py +6 -6
  9. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/quicksight/version.py +3 -0
  10. {cid_cmd-4.4.2 → cid_cmd-4.4.4/cid_cmd.egg-info}/PKG-INFO +1 -1
  11. cid_cmd-4.4.2/cid/_version.py +0 -2
  12. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/LICENSE +0 -0
  13. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/MANIFEST.in +0 -0
  14. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/README.md +0 -0
  15. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/__init__.py +0 -0
  16. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/base.py +0 -0
  17. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/__init__.py +0 -0
  18. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/__init__.py +0 -0
  19. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/cid/compute.json +0 -0
  20. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/cid/ec2_running_cost.json +0 -0
  21. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/cid/s3_view.json +0 -0
  22. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/cid/summary_view.json +0 -0
  23. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/co/dataset.json +0 -0
  24. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/cudos/hourly_view.json +0 -0
  25. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/cudos/resource_view.json +0 -0
  26. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/kpi/kpi_ebs_snap.json +0 -0
  27. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/kpi/kpi_ebs_storage_all.json +0 -0
  28. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/kpi/kpi_instance_all.json +0 -0
  29. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/kpi/kpi_s3_storage_all.json +0 -0
  30. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/kpi/kpi_tracker.json +0 -0
  31. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/shared/customer_all.json +0 -0
  32. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/trends/daily_anomaly_detection.json +0 -0
  33. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/trends/monthly_anomaly_detection.json +0 -0
  34. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/datasets/trends/monthly_bill_by_account.json +0 -0
  35. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/permissions/dashboard_permissions.json +0 -0
  36. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/permissions/dashboard_permissions_namespace.json +0 -0
  37. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/permissions/data_set_permissions.json +0 -0
  38. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/permissions/data_set_rls_permissions.json +0 -0
  39. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/permissions/data_source_permissions.json +0 -0
  40. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/permissions/folder_permissions.json +0 -0
  41. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/cid/compute_savings_plan_eligible_spend.sql +0 -0
  42. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/cid/ec2_running_cost.sql +0 -0
  43. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/cid/ri_sp_mapping.sql +0 -0
  44. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/cid/s3.sql +0 -0
  45. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/cid/summary_view.sql +0 -0
  46. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/all_options.sql +0 -0
  47. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/auto_scale.json +0 -0
  48. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/auto_scale_options.sql +0 -0
  49. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/ebs_volume.json +0 -0
  50. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/ebs_volume_options.sql +0 -0
  51. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/ec2_instance.json +0 -0
  52. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/ec2_instance_options.sql +0 -0
  53. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/ecs_service.json +0 -0
  54. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/ecs_service_options.sql +0 -0
  55. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/idle.json +0 -0
  56. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/idle_options.sql +0 -0
  57. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/lambda.json +0 -0
  58. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/lambda_options.sql +0 -0
  59. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/license.json +0 -0
  60. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/license_options.sql +0 -0
  61. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/rds_database.json +0 -0
  62. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/rds_instance_options.sql +0 -0
  63. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/co/rds_storage_options.sql +0 -0
  64. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/cudos/hourly_view.sql +0 -0
  65. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/cudos/resource_view.sql +0 -0
  66. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/kpi/first_kpi_instance_mapping_view.sql +0 -0
  67. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/kpi/kpi_ebs_snap_view.sql +0 -0
  68. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/kpi/kpi_ebs_storage_view.sql +0 -0
  69. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/kpi/kpi_instance_all_view.sql +0 -0
  70. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/kpi/kpi_s3_storage_view.sql +0 -0
  71. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/kpi/last_kpi_tracker_view.sql +0 -0
  72. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/shared/account_map.sql +0 -0
  73. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/shared/account_map_cur2.sql +0 -0
  74. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/shared/account_map_dummy.sql +0 -0
  75. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/shared/aws_accounts.sql +0 -0
  76. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/shared/aws_regions.sql +0 -0
  77. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/shared/aws_service_category_map.sql +0 -0
  78. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/shared/business_units_map.sql +0 -0
  79. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/shared/cur.yaml +0 -0
  80. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/shared/customer_all_unlimited.sql +0 -0
  81. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/shared/payer_account_name_map.sql +0 -0
  82. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/shared/ta_descriptions.sql +0 -0
  83. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/trends/daily_anomaly_detection.sql +0 -0
  84. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/trends/monthly_anomaly_detection.sql +0 -0
  85. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/queries/trends/monthly_bill_by_account.sql +0 -0
  86. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/builtin/core/data/resources.yaml +0 -0
  87. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/cli.py +0 -0
  88. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/commands/__init__.py +0 -0
  89. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/commands/command_base.py +0 -0
  90. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/commands/init_qs.py +0 -0
  91. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/exceptions.py +0 -0
  92. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/export.py +0 -0
  93. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/__init__.py +0 -0
  94. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/account_map.py +0 -0
  95. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/cloudformation.py +0 -0
  96. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/csv2view.py +0 -0
  97. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/cur.py +0 -0
  98. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/cur_proxy.py +0 -0
  99. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/diff.py +0 -0
  100. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/glue.py +0 -0
  101. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/organizations.py +0 -0
  102. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/parameter_store.py +0 -0
  103. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/quicksight/dashboard_patching.py +0 -0
  104. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/quicksight/dataset.py +0 -0
  105. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/quicksight/datasource.py +0 -0
  106. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/quicksight/resource.py +0 -0
  107. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/quicksight/template.py +0 -0
  108. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/randtime.py +0 -0
  109. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/s3.py +0 -0
  110. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/helpers/timezone.py +0 -0
  111. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/logger.py +0 -0
  112. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/plugin.py +0 -0
  113. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/test/python/test_csv2view.py +0 -0
  114. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/test/python/test_isolated_parameters.py +0 -0
  115. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/test/python/test_merge.py +0 -0
  116. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid/utils.py +0 -0
  117. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid_cmd.egg-info/SOURCES.txt +0 -0
  118. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid_cmd.egg-info/dependency_links.txt +0 -0
  119. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid_cmd.egg-info/entry_points.txt +0 -0
  120. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid_cmd.egg-info/requires.txt +0 -0
  121. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/cid_cmd.egg-info/top_level.txt +0 -0
  122. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/pyproject.toml +0 -0
  123. {cid_cmd-4.4.2 → cid_cmd-4.4.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cid-cmd
3
- Version: 4.4.2
3
+ Version: 4.4.4
4
4
  Summary: Cloud Intelligence Dashboards deployment helper tool
5
5
  Home-page: https://github.com/aws-samples/aws-cudos-framework-deployment
6
6
  Author: AWS CUDOS Team
@@ -0,0 +1,2 @@
1
+ __version__ = '4.4.4'
2
+
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import re
2
3
  import json
3
4
  import urllib
4
5
  import logging
@@ -1937,8 +1938,10 @@ class Cid():
1937
1938
  if not resource_tags:
1938
1939
  return "'{}'"
1939
1940
  logger.debug(f'selected_tag_names = {resource_tags}')
1941
+ pattern = r"\W"
1940
1942
  array = ',\n '.join(
1941
- [f"('{name}', {tags_and_names[name]})"
1943
+ # replace all special characters with _ to allow QS read from this json (QS parseJson does not like special characters)
1944
+ [f"""('{re.sub(pattern, "_", name)}', {tags_and_names[name]})"""
1942
1945
  for name in resource_tags]
1943
1946
  )
1944
1947
  res = f'''
@@ -82,9 +82,11 @@ class Athena(CidBase):
82
82
 
83
83
  # check if we have a default database
84
84
  logger.info(f'athena_databases = {athena_databases}')
85
- default_databases = [database for database in athena_databases if database == self.defaults.get('DatabaseName')]
85
+ default_database = None
86
86
  if 'cid_cur' in athena_databases:
87
- default_databases = ['cid_cur']
87
+ default_database = 'cid_cur'
88
+ elif self.defaults.get('DatabaseName') in athena_databases:
89
+ default_database = self.defaults.get('DatabaseName')
88
90
 
89
91
  # Ask user
90
92
  choices = list(athena_databases)
@@ -92,9 +94,9 @@ class Athena(CidBase):
92
94
  choices.append(self.defaults.get('DatabaseName') + ' (CREATE NEW)')
93
95
  self._DatabaseName = get_parameter(
94
96
  param_name='athena-database',
95
- message="Select AWS Athena database to use as default",
97
+ message="Select AWS Athena database to use as default for queries and views. " + (f"Use {default_database} if not sure." if default_database else ''),
96
98
  choices=choices,
97
- default=default_databases[0] if default_databases else None,
99
+ default=default_database,
98
100
  )
99
101
  if self._DatabaseName.endswith( ' (CREATE NEW)'):
100
102
  self._DatabaseName = self.defaults.get('DatabaseName')
@@ -118,25 +120,26 @@ class Athena(CidBase):
118
120
  self.WorkGroup = self._ensure_workgroup(name=get_parameters().get('athena-workgroup'))
119
121
  return self._WorkGroup
120
122
  logger.info('Selecting Athena workgroup...')
121
- workgroups = self.list_work_groups()
122
- logger.info(f'Found {len(workgroups)} workgroups: {", ".join([wg.get("Name") for wg in workgroups])}')
123
- # if len(workgroups) == 0:
123
+ work_group_names = [wgr['Name'] for wgr in self.list_work_groups()]
124
+ logger.debug(f'Found {len(work_group_names)} work_groups: {work_group_names}')
125
+ # if len(work_group_names) == 0:
124
126
  # self.WorkGroup = self._ensure_workgroup(name=self.defaults.get('WorkGroup'))
125
- # elif len(workgroups) == 1:
127
+ # elif len(work_group_names) == 1:
126
128
  # # Silently choose the only workgroup that is available
127
- # self.WorkGroup = self._ensure_workgroup(name=workgroups.pop().get('Name'))
129
+ # self.WorkGroup = self._ensure_workgroup(name=work_group_names[0])
128
130
  # else:
129
131
  # Select default workgroup if present
130
- if self.defaults.get('WorkGroup') not in {wgr['Name'] for wgr in workgroups}:
131
- workgroups.append({'Name': f"{self.defaults.get('WorkGroup')} (create new)"})
132
- default_workgroup = next(iter([wgr.get('Name') for wgr in workgroups if self.defaults.get('WorkGroup') in wgr['Name']]), None)
133
- if default_workgroup:
134
- logger.info(f'Found "{default_workgroup}" as a default workgroup')
132
+ if self.defaults.get('WorkGroup') not in work_group_names:
133
+ work_group_names.append(f"{self.defaults.get('WorkGroup')} (create new)")
134
+ default_workgroup = None
135
+ if self.defaults.get('WorkGroup') in work_group_names:
136
+ default_workgroup = self.defaults.get('WorkGroup')
137
+ logger.debug(f'Found "{default_workgroup}" as a default workgroup')
135
138
  # Ask user
136
139
  selected_workgroup = get_parameter(
137
140
  param_name='athena-workgroup',
138
- message="Select Amazon Athena workgroup to use",
139
- choices=[wgr['Name'] for wgr in workgroups],
141
+ message="Select Amazon Athena workgroup to use. " + (f"Use {default_workgroup} if not sure." if default_workgroup else ''),
142
+ choices=work_group_names,
140
143
  default=default_workgroup,
141
144
  fuzzy=False,
142
145
  )
@@ -55,7 +55,7 @@ class IAM(CidBase):
55
55
  return
56
56
 
57
57
  if role_name in ['aws-quicksight-service-role-v0']:
58
- logger.warning(f'{role_name} is a managed role. Please manage it in QuickSight UI. Make sure that equivalent of those polices is configured: {policies_arns}')
58
+ logger.info(f'{role_name} is a managed role. Please manage it in QuickSight UI. Make sure that equivalent of those polices is configured: {policies_arns}')
59
59
  return
60
60
 
61
61
  try:
@@ -73,7 +73,7 @@ class IAM(CidBase):
73
73
  )
74
74
  logger.info(f'Attached {policy_arn} to the role {role_name}')
75
75
  except self.client.exceptions.ClientError as exc:
76
- logger.warning(f'Unable to attach policy {policy_arn} to {role_name}: {exc}')
76
+ logger.info(f'Unable to attach policy {policy_arn} to {role_name}: {exc}')
77
77
 
78
78
 
79
79
  def ensure_role_for_crawler(self, s3bucket, database, table, role_name: str='CidCmdCrawlerRole', policy_name: str="CidCmdGlueCrawlerPolicy") -> None:
@@ -341,7 +341,7 @@ class QuickSight(CidBase):
341
341
  self._principal_arn = group.get('Arn')
342
342
 
343
343
  if not self._principal_arn:
344
- raise CidCritical('Cannot find principal_arn. Please provide --quicksight-username or --quicksight-groupname')
344
+ raise CidCritical('Cannot find principal_arn. Please provide --quicksight-user or --quicksight-group')
345
345
  return self._principal_arn
346
346
 
347
347
 
@@ -11,13 +11,16 @@ from cid.helpers.quicksight.template import Template as CidQsTemplate
11
11
  from cid.utils import cid_print, get_yesno_parameter
12
12
  from cid.helpers.quicksight.resource import CidQsResource
13
13
  from cid.helpers.quicksight.dataset import Dataset
14
- from cid.helpers.quicksight.version import CidVersion
14
+ from cid.helpers.quicksight.version import CidVersion, DEFAULT_VERSION
15
15
 
16
16
 
17
17
  logger = logging.getLogger(__name__)
18
18
 
19
19
 
20
20
  class Dashboard(CidQsResource):
21
+ # Dashboards with known invalid v1.0.0 tags
22
+ DASHBOARDS_WITH_INVALID_V1_TAGS = {'ta-organizational-view', 'resiliencevue'}
23
+
21
24
  def __init__(self, raw: dict, qs=None) -> None:
22
25
  super().__init__(raw)
23
26
  # Initialize properties
@@ -212,22 +215,57 @@ class Dashboard(CidQsResource):
212
215
 
213
216
  @property
214
217
  def deployed_cid_version(self):
218
+ """Get the deployed CID version from tags, template, or definition."""
215
219
  if self._cid_version:
216
- return self._cid_version
217
- tag_version = (self.qs.get_tags(self.arn) or {}).get('cid_version_tag')
218
- #print(f'{self.id}: {tag_version}')
219
- if tag_version:
220
- logger.trace(f'version of {self.arn} from tag = {tag_version}')
221
- self._cid_version = CidVersion(tag_version)
222
- else:
223
- if self.deployed_template:
224
- self._cid_version = self.deployed_template.cid_version
225
- elif self.deployed_definition:
226
- self._cid_version = self.deployed_definition.cid_version
227
- if self._cid_version:
228
- logger.trace(f'setting tag of {self.arn} to cid_version_tag = {self._cid_version}')
229
- self.qs.set_tags(self.arn, cid_version_tag=self._cid_version)
220
+ return self._cid_version
221
+
222
+ try:
223
+ tag_version = self._get_version_from_tags()
224
+ if self._is_valid_tag_version(tag_version):
225
+ logger.debug(f'Using version from tag for {self.id}: {tag_version}')
226
+ self._cid_version = CidVersion(tag_version)
227
+ else:
228
+ self._cid_version = self._get_version_from_sources()
229
+ if self._cid_version:
230
+ self._update_version_tag()
231
+ except Exception as exc:
232
+ logger.warning(f'Failed to determine CID version for {self.id}: {exc}')
233
+ self._cid_version = None
234
+
230
235
  return self._cid_version
236
+
237
+ def _get_version_from_tags(self):
238
+ """Extract version from dashboard tags."""
239
+ tags = self.qs.get_tags(self.arn) or {}
240
+ return tags.get('cid_version_tag')
241
+
242
+ def _is_valid_tag_version(self, tag_version):
243
+ """Check if tag version is valid and not a known invalid default."""
244
+ if not tag_version or tag_version == DEFAULT_VERSION:
245
+ return False
246
+
247
+ # v1.0.0 is invalid only for specific dashboards with incorrect defaults
248
+ if tag_version == 'v1.0.0' and self.id in self.DASHBOARDS_WITH_INVALID_V1_TAGS:
249
+ logger.debug(f'Ignoring invalid v1.0.0 tag for dashboard {self.id}')
250
+ return False
251
+
252
+ return True
253
+
254
+ def _get_version_from_sources(self):
255
+ """Get version from template or definition as fallback."""
256
+ if self.deployed_template:
257
+ return self.deployed_template.cid_version
258
+ elif self.deployed_definition:
259
+ return self.deployed_definition.cid_version
260
+ return None
261
+
262
+ def _update_version_tag(self):
263
+ """Update the version tag if we found a version from other sources."""
264
+ try:
265
+ logger.debug(f'Setting version tag for {self.arn}: {self._cid_version}')
266
+ self.qs.set_tags(self.arn, cid_version_tag=self._cid_version)
267
+ except Exception as exc:
268
+ logger.warning(f'Failed to update version tag for {self.id}: {exc}')
231
269
 
232
270
 
233
271
  @property
@@ -2,7 +2,7 @@ import logging
2
2
  import re
3
3
  from typing import Dict
4
4
  from cid.helpers.quicksight.resource import CidQsResource
5
- from cid.helpers.quicksight.version import CidVersion
5
+ from cid.helpers.quicksight.version import CidVersion, DEFAULT_VERSION
6
6
 
7
7
  logger = logging.getLogger(__name__)
8
8
 
@@ -21,7 +21,7 @@ class Definition:
21
21
  except TypeError as e:
22
22
  logger.debug(f"Could not resolve CID version. Raw version value '{self._raw_version}' does not conform to CID version format vmajor.minor.build e.g. v.1.0.1")
23
23
 
24
- return CidVersion("v1.0.0")
24
+ return CidVersion(DEFAULT_VERSION)
25
25
 
26
26
  def resolve_version(self, raw: dict):
27
27
  about_content = []
@@ -38,13 +38,13 @@ class Definition:
38
38
  if about_content:
39
39
  all_about_content = " | ".join(about_content)
40
40
  # find first string that looks like vx.y.z using a regular expression where x, y and z are numbers
41
- version_matches = re.findall(r"(v\d+?\.\d+?\.\d+?)", all_about_content)
41
+ version_matches = re.findall(r"([vV]\d+?\.\d+?\.\d+?)", all_about_content)
42
42
  if version_matches:
43
- return version_matches[0]
43
+ return version_matches[0].lower() # normalize to lowercase
44
44
  else:
45
- version_matches = re.findall(r"(v\d+?\.\d+?)", all_about_content)
45
+ version_matches = re.findall(r"([vV]\d+?\.\d+?)", all_about_content)
46
46
  if version_matches:
47
- return f"{version_matches[0]}.0"
47
+ return f"{version_matches[0].lower()}.0" # normalize to lowercase
48
48
 
49
49
  return None
50
50
 
@@ -6,6 +6,9 @@ import logging
6
6
 
7
7
  logger = logging.getLogger(__name__)
8
8
 
9
+ # Default version used when version cannot be determined
10
+ DEFAULT_VERSION = "v0.0.0"
11
+
9
12
  class CidVersion:
10
13
  """ Semantic version of dashboards in CID
11
14
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cid-cmd
3
- Version: 4.4.2
3
+ Version: 4.4.4
4
4
  Summary: Cloud Intelligence Dashboards deployment helper tool
5
5
  Home-page: https://github.com/aws-samples/aws-cudos-framework-deployment
6
6
  Author: AWS CUDOS Team
@@ -1,2 +0,0 @@
1
- __version__ = '4.4.2'
2
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes