cid-cmd 4.2.7__tar.gz → 4.3.1__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.
- {cid_cmd-4.2.7/cid_cmd.egg-info → cid_cmd-4.3.1}/PKG-INFO +14 -14
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/README.md +13 -13
- cid_cmd-4.3.1/cid/_version.py +2 -0
- cid_cmd-4.3.1/cid/builtin/core/data/permissions/data_set_rls_permissions.json +8 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/resources.yaml +10 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/cli.py +4 -1
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/common.py +61 -3
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/export.py +1 -1
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/athena.py +7 -4
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/cur.py +1 -1
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/quicksight/__init__.py +2 -1
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/quicksight/dashboard.py +3 -1
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/quicksight/dashboard_patching.py +18 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/quicksight/dataset.py +29 -8
- {cid_cmd-4.2.7 → cid_cmd-4.3.1/cid_cmd.egg-info}/PKG-INFO +14 -14
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid_cmd.egg-info/SOURCES.txt +1 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid_cmd.egg-info/top_level.txt +2 -1
- cid_cmd-4.2.7/cid/_version.py +0 -2
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/LICENSE +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/MANIFEST.in +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/__init__.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/base.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/__init__.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/__init__.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/cid/compute.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/cid/ec2_running_cost.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/cid/s3_view.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/cid/summary_view.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/co/dataset.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/cudos/hourly_view.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/cudos/resource_view.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/kpi/kpi_ebs_snap.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/kpi/kpi_ebs_storage_all.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/kpi/kpi_instance_all.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/kpi/kpi_s3_storage_all.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/kpi/kpi_tracker.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/shared/customer_all.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/tao/dataset.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/trends/daily_anomaly_detection.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/trends/monthly_anomaly_detection.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/trends/monthly_bill_by_account.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/permissions/dashboard_permissions.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/permissions/dashboard_permissions_namespace.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/permissions/data_set_permissions.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/permissions/data_source_permissions.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/permissions/folder_permissions.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/cid/compute_savings_plan_eligible_spend.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/cid/ec2_running_cost.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/cid/ri_sp_mapping.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/cid/s3.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/cid/summary_view.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/all_options.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/auto_scale.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/auto_scale_options.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/ebs_volume.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/ebs_volume_options.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/ec2_instance.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/ec2_instance_options.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/ecs_service.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/ecs_service_options.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/idle.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/idle_options.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/lambda.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/lambda_options.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/license.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/license_options.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/rds_database.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/rds_instance_options.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/co/rds_storage_options.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/cudos/hourly_view.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/cudos/resource_view.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/kpi/first_kpi_instance_mapping_view.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/kpi/kpi_ebs_snap_view.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/kpi/kpi_ebs_storage_view.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/kpi/kpi_instance_all_view.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/kpi/kpi_s3_storage_view.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/kpi/last_kpi_tracker_view.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/shared/account_map.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/shared/account_map_cur2.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/shared/account_map_dummy.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/shared/aws_accounts.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/shared/aws_regions.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/shared/aws_service_category_map.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/shared/business_units_map.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/shared/cur.yaml +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/shared/customer_all_unlimited.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/shared/payer_account_name_map.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/shared/ta_descriptions.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/tao/glue_table.json +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/tao/ta_org_view.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/trends/daily_anomaly_detection.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/trends/monthly_anomaly_detection.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/trends/monthly_bill_by_account.sql +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/commands/__init__.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/commands/command_base.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/commands/init_qs.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/exceptions.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/__init__.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/account_map.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/cloudformation.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/csv2view.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/cur_proxy.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/diff.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/glue.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/iam.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/organizations.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/parameter_store.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/quicksight/datasource.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/quicksight/definition.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/quicksight/resource.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/quicksight/template.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/quicksight/version.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/randtime.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/s3.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/helpers/timezone.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/logger.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/plugin.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/test/python/test_csv2view.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/test/python/test_isolated_parameters.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/test/python/test_merge.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/utils.py +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid_cmd.egg-info/dependency_links.txt +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid_cmd.egg-info/entry_points.txt +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid_cmd.egg-info/requires.txt +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/pyproject.toml +0 -0
- {cid_cmd-4.2.7 → cid_cmd-4.3.1}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cid-cmd
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.1
|
|
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
|
|
@@ -49,15 +49,15 @@ Dynamic: license-file
|
|
|
49
49
|
## Overview
|
|
50
50
|
The Cloud Intelligence Dashboards is an open-source framework, lovingly cultivated and maintained by a group of customer-obsessed AWSers, that gives customers the power to get high-level and granular insight into their cost and usage data. Supported by the Well-Architected framework, the dashboards can be deployed by any customer using a CloudFormation template or a command-line tool in their environment in under 30 minutes. These dashboards help you to drive financial accountability, optimize cost, track usage goals, implement best-practices for governance, and achieve operational excellence across all your organization.
|
|
51
51
|
|
|
52
|
-
Cloud Intelligence Dashboards Framework provides AWS customers with [more then 20 Dashboards](https://
|
|
52
|
+
Cloud Intelligence Dashboards Framework provides AWS customers with [more then 20 Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html).
|
|
53
53
|
* Foundational Dashboards - A set of main Dashboards that only require Cost and Usage Report(CUR)
|
|
54
54
|
* Advanced Dashboards - Require CID Data Collection and CUR
|
|
55
55
|
* Additional Dashboards - Require various custom datasources or created for very specific use cases.
|
|
56
56
|
|
|
57
|
-
We recommend starting with deployment of [Foundational Dashboards](https://
|
|
57
|
+
We recommend starting with deployment of [Foundational Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboard-foundational.html). Then deploy [Data Collection](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/data-collection.html) and [Advanced Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html#advanced-dashboards). Check for [Additional](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html#additional-dashboards) Dashboards.
|
|
58
58
|
|
|
59
59
|
|
|
60
|
-
[](https://
|
|
60
|
+
[](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/deployment-in-global-regions.html)
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
## Architecture of Foundational Dashboards
|
|
@@ -67,9 +67,9 @@ We recommend starting with deployment of [Foundational Dashboards](https://catal
|
|
|
67
67
|
2. [Amazon S3](https://aws.amazon.com/s3/) replication rule copies Export data to a dedicated Data Collection Account S3 bucket automatically.
|
|
68
68
|
3. [Amazon Athena](https://aws.amazon.com/athena/) allows querying data directly from the S3 bucket using an [AWS Glue](https://aws.amazon.com/glue/) table schema definition.
|
|
69
69
|
4. [Amazon QuickSight](https://aws.amazon.com/quicksight/) creates datasets from [Amazon Athena](https://aws.amazon.com/athena/), refreshes daily and caches in [SPICE](https://docs.aws.amazon.com/quicksight/latest/user/spice.html)(Super-fast, Parallel, In-memory Calculation Engine) for [Amazon QuickSight](https://aws.amazon.com/quicksight/)
|
|
70
|
-
5. User Teams (Executives, FinOps, Engineers) can access Cloud Intelligence Dashboards in [Amazon QuickSight](https://aws.amazon.com/quicksight/). Access is secured through [AWS IAM](https://aws.amazon.com/iam/), IIC ([AWS IAM Identity Center](https://aws.amazon.com/iam/identity-center/), formerly SSO), and optional [Row Level Security](https://
|
|
70
|
+
5. User Teams (Executives, FinOps, Engineers) can access Cloud Intelligence Dashboards in [Amazon QuickSight](https://aws.amazon.com/quicksight/). Access is secured through [AWS IAM](https://aws.amazon.com/iam/), IIC ([AWS IAM Identity Center](https://aws.amazon.com/iam/identity-center/), formerly SSO), and optional [Row Level Security](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/row-level-security.html).
|
|
71
71
|
|
|
72
|
-
This foundational architecture is recommended for starting and allows deployment of [Foundational Dashboards](https://
|
|
72
|
+
This foundational architecture is recommended for starting and allows deployment of [Foundational Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboard-foundational.html) like CUDOS, CID and KPI.
|
|
73
73
|
|
|
74
74
|
## Architecture of Advanced Dashboards
|
|
75
75
|

|
|
@@ -78,14 +78,14 @@ This foundational architecture is recommended for starting and allows deployment
|
|
|
78
78
|
2. [Amazon S3](https://aws.amazon.com/s3/) replication rule copies Export data to a dedicated Data Collection Account S3 bucket automatically.
|
|
79
79
|
3. [Amazon Athena](https://aws.amazon.com/athena/) allows querying data directly from the S3 bucket using an [AWS Glue](https://aws.amazon.com/glue/) table schema definition.
|
|
80
80
|
4. [Amazon QuickSight](https://aws.amazon.com/quicksight/) creates datasets from [Amazon Athena](https://aws.amazon.com/athena/), refreshes daily and caches in [SPICE](https://docs.aws.amazon.com/quicksight/latest/user/spice.html)(Super-fast, Parallel, In-memory Calculation Engine) for [Amazon QuickSight](https://aws.amazon.com/quicksight/)
|
|
81
|
-
5. User Teams (Executives, FinOps, Engineers) can access Cloud Intelligence Dashboards in [Amazon QuickSight](https://aws.amazon.com/quicksight/). Access is secured through [AWS IAM](https://aws.amazon.com/iam/), IIC ([AWS IAM Identity Center](https://aws.amazon.com/iam/identity-center/), formerly SSO), and optional [Row Level Security](https://
|
|
81
|
+
5. User Teams (Executives, FinOps, Engineers) can access Cloud Intelligence Dashboards in [Amazon QuickSight](https://aws.amazon.com/quicksight/). Access is secured through [AWS IAM](https://aws.amazon.com/iam/), IIC ([AWS IAM Identity Center](https://aws.amazon.com/iam/identity-center/), formerly SSO), and optional [Row Level Security](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/row-level-security.html).
|
|
82
82
|
6. Optionally, the Advanced data collection can be deployed to enable advanced dashboards based on [AWS Trusted Advisor](https://aws.amazon.com/premiumsupport/trustedadvisor/), [AWS Health](https://aws.amazon.com/premiumsupport/technology/aws-health-dashboard/) Events and other sources. Additional data is retrieved from [AWS Organizations](https://aws.amazon.com/organizations/) or Linked Accounts. In this case [Amazon EventBridge](https://aws.amazon.com/eventbridge/) rule triggers an [AWS Step Functions](https://aws.amazon.com/step-functions/) workflow for data collection modules on a configurable schedule.
|
|
83
83
|
7. The "Account Collector" [AWS Lambda](https://aws.amazon.com/lambda/) in AWS Step Functions retrieves linked account details using AWS Organizations API.
|
|
84
84
|
8. The "Data Collection" Lambda function in AWS Step Functions assumes role in each linked account to retrieve account-specific data via [AWS SDK](https://aws.amazon.com/developer/tools/).
|
|
85
85
|
9. Retrieved data is stored in a centralized Amazon S3 Bucket.
|
|
86
|
-
10. [Advanced Cloud Intelligence Dashboards](https://
|
|
86
|
+
10. [Advanced Cloud Intelligence Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html#advanced-dashboards) leverage Amazon Athena and Amazon QuickSight for comprehensive data analysis.
|
|
87
87
|
|
|
88
|
-
This advanced data collection architecture allows deployment of [Advanced Dashboards](https://
|
|
88
|
+
This advanced data collection architecture allows deployment of [Advanced Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html#advanced-dashboards) like Trusted Advisor Dashboard, Health, Graviton, Compute Optimizer Dashboard and many more.
|
|
89
89
|
|
|
90
90
|
|
|
91
91
|
## Cost
|
|
@@ -154,23 +154,23 @@ There are several ways we can deploy dashboards:
|
|
|
154
154
|
1. Using cid-cmd tool from command line
|
|
155
155
|
1. [CloudFormation Template](./cfn-templates/cid-cfn.yml) using cid-cmd tool in Amazon Lambda. (Recommended)
|
|
156
156
|
|
|
157
|
-
Please refer to the deployment documentation [here](https://
|
|
157
|
+
Please refer to the deployment documentation [here](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/deployment-in-global-regions.html).
|
|
158
158
|
|
|
159
|
-
[](https://
|
|
159
|
+
[](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/deployment-in-global-regions.html)
|
|
160
160
|
|
|
161
161
|
|
|
162
162
|
## Cleanup
|
|
163
|
-
Please refer to the documentation [here](https://
|
|
163
|
+
Please refer to the documentation [here](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboard-teardown.html).
|
|
164
164
|
|
|
165
165
|
## FAQ
|
|
166
|
-
Please refer to the documentation [here](https://
|
|
166
|
+
Please refer to the documentation [here](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/faq.html).
|
|
167
167
|
|
|
168
168
|
## Changelogs
|
|
169
169
|
For dashboards please check Change Logs [here](changes/)
|
|
170
170
|
For CID deployment tool, including Cli and CFN please check [Releases](/releases)
|
|
171
171
|
|
|
172
172
|
## Feedback
|
|
173
|
-
Please reference to [this page](https://
|
|
173
|
+
Please reference to [this page](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/feedback-support.html)
|
|
174
174
|
|
|
175
175
|
## Security
|
|
176
176
|
When you build systems on AWS infrastructure, security responsibilities are shared between you and AWS. This [shared responsibility
|
|
@@ -21,15 +21,15 @@
|
|
|
21
21
|
## Overview
|
|
22
22
|
The Cloud Intelligence Dashboards is an open-source framework, lovingly cultivated and maintained by a group of customer-obsessed AWSers, that gives customers the power to get high-level and granular insight into their cost and usage data. Supported by the Well-Architected framework, the dashboards can be deployed by any customer using a CloudFormation template or a command-line tool in their environment in under 30 minutes. These dashboards help you to drive financial accountability, optimize cost, track usage goals, implement best-practices for governance, and achieve operational excellence across all your organization.
|
|
23
23
|
|
|
24
|
-
Cloud Intelligence Dashboards Framework provides AWS customers with [more then 20 Dashboards](https://
|
|
24
|
+
Cloud Intelligence Dashboards Framework provides AWS customers with [more then 20 Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html).
|
|
25
25
|
* Foundational Dashboards - A set of main Dashboards that only require Cost and Usage Report(CUR)
|
|
26
26
|
* Advanced Dashboards - Require CID Data Collection and CUR
|
|
27
27
|
* Additional Dashboards - Require various custom datasources or created for very specific use cases.
|
|
28
28
|
|
|
29
|
-
We recommend starting with deployment of [Foundational Dashboards](https://
|
|
29
|
+
We recommend starting with deployment of [Foundational Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboard-foundational.html). Then deploy [Data Collection](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/data-collection.html) and [Advanced Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html#advanced-dashboards). Check for [Additional](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html#additional-dashboards) Dashboards.
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
[](https://
|
|
32
|
+
[](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/deployment-in-global-regions.html)
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
## Architecture of Foundational Dashboards
|
|
@@ -39,9 +39,9 @@ We recommend starting with deployment of [Foundational Dashboards](https://catal
|
|
|
39
39
|
2. [Amazon S3](https://aws.amazon.com/s3/) replication rule copies Export data to a dedicated Data Collection Account S3 bucket automatically.
|
|
40
40
|
3. [Amazon Athena](https://aws.amazon.com/athena/) allows querying data directly from the S3 bucket using an [AWS Glue](https://aws.amazon.com/glue/) table schema definition.
|
|
41
41
|
4. [Amazon QuickSight](https://aws.amazon.com/quicksight/) creates datasets from [Amazon Athena](https://aws.amazon.com/athena/), refreshes daily and caches in [SPICE](https://docs.aws.amazon.com/quicksight/latest/user/spice.html)(Super-fast, Parallel, In-memory Calculation Engine) for [Amazon QuickSight](https://aws.amazon.com/quicksight/)
|
|
42
|
-
5. User Teams (Executives, FinOps, Engineers) can access Cloud Intelligence Dashboards in [Amazon QuickSight](https://aws.amazon.com/quicksight/). Access is secured through [AWS IAM](https://aws.amazon.com/iam/), IIC ([AWS IAM Identity Center](https://aws.amazon.com/iam/identity-center/), formerly SSO), and optional [Row Level Security](https://
|
|
42
|
+
5. User Teams (Executives, FinOps, Engineers) can access Cloud Intelligence Dashboards in [Amazon QuickSight](https://aws.amazon.com/quicksight/). Access is secured through [AWS IAM](https://aws.amazon.com/iam/), IIC ([AWS IAM Identity Center](https://aws.amazon.com/iam/identity-center/), formerly SSO), and optional [Row Level Security](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/row-level-security.html).
|
|
43
43
|
|
|
44
|
-
This foundational architecture is recommended for starting and allows deployment of [Foundational Dashboards](https://
|
|
44
|
+
This foundational architecture is recommended for starting and allows deployment of [Foundational Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboard-foundational.html) like CUDOS, CID and KPI.
|
|
45
45
|
|
|
46
46
|
## Architecture of Advanced Dashboards
|
|
47
47
|

|
|
@@ -50,14 +50,14 @@ This foundational architecture is recommended for starting and allows deployment
|
|
|
50
50
|
2. [Amazon S3](https://aws.amazon.com/s3/) replication rule copies Export data to a dedicated Data Collection Account S3 bucket automatically.
|
|
51
51
|
3. [Amazon Athena](https://aws.amazon.com/athena/) allows querying data directly from the S3 bucket using an [AWS Glue](https://aws.amazon.com/glue/) table schema definition.
|
|
52
52
|
4. [Amazon QuickSight](https://aws.amazon.com/quicksight/) creates datasets from [Amazon Athena](https://aws.amazon.com/athena/), refreshes daily and caches in [SPICE](https://docs.aws.amazon.com/quicksight/latest/user/spice.html)(Super-fast, Parallel, In-memory Calculation Engine) for [Amazon QuickSight](https://aws.amazon.com/quicksight/)
|
|
53
|
-
5. User Teams (Executives, FinOps, Engineers) can access Cloud Intelligence Dashboards in [Amazon QuickSight](https://aws.amazon.com/quicksight/). Access is secured through [AWS IAM](https://aws.amazon.com/iam/), IIC ([AWS IAM Identity Center](https://aws.amazon.com/iam/identity-center/), formerly SSO), and optional [Row Level Security](https://
|
|
53
|
+
5. User Teams (Executives, FinOps, Engineers) can access Cloud Intelligence Dashboards in [Amazon QuickSight](https://aws.amazon.com/quicksight/). Access is secured through [AWS IAM](https://aws.amazon.com/iam/), IIC ([AWS IAM Identity Center](https://aws.amazon.com/iam/identity-center/), formerly SSO), and optional [Row Level Security](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/row-level-security.html).
|
|
54
54
|
6. Optionally, the Advanced data collection can be deployed to enable advanced dashboards based on [AWS Trusted Advisor](https://aws.amazon.com/premiumsupport/trustedadvisor/), [AWS Health](https://aws.amazon.com/premiumsupport/technology/aws-health-dashboard/) Events and other sources. Additional data is retrieved from [AWS Organizations](https://aws.amazon.com/organizations/) or Linked Accounts. In this case [Amazon EventBridge](https://aws.amazon.com/eventbridge/) rule triggers an [AWS Step Functions](https://aws.amazon.com/step-functions/) workflow for data collection modules on a configurable schedule.
|
|
55
55
|
7. The "Account Collector" [AWS Lambda](https://aws.amazon.com/lambda/) in AWS Step Functions retrieves linked account details using AWS Organizations API.
|
|
56
56
|
8. The "Data Collection" Lambda function in AWS Step Functions assumes role in each linked account to retrieve account-specific data via [AWS SDK](https://aws.amazon.com/developer/tools/).
|
|
57
57
|
9. Retrieved data is stored in a centralized Amazon S3 Bucket.
|
|
58
|
-
10. [Advanced Cloud Intelligence Dashboards](https://
|
|
58
|
+
10. [Advanced Cloud Intelligence Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html#advanced-dashboards) leverage Amazon Athena and Amazon QuickSight for comprehensive data analysis.
|
|
59
59
|
|
|
60
|
-
This advanced data collection architecture allows deployment of [Advanced Dashboards](https://
|
|
60
|
+
This advanced data collection architecture allows deployment of [Advanced Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html#advanced-dashboards) like Trusted Advisor Dashboard, Health, Graviton, Compute Optimizer Dashboard and many more.
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
## Cost
|
|
@@ -126,23 +126,23 @@ There are several ways we can deploy dashboards:
|
|
|
126
126
|
1. Using cid-cmd tool from command line
|
|
127
127
|
1. [CloudFormation Template](./cfn-templates/cid-cfn.yml) using cid-cmd tool in Amazon Lambda. (Recommended)
|
|
128
128
|
|
|
129
|
-
Please refer to the deployment documentation [here](https://
|
|
129
|
+
Please refer to the deployment documentation [here](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/deployment-in-global-regions.html).
|
|
130
130
|
|
|
131
|
-
[](https://
|
|
131
|
+
[](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/deployment-in-global-regions.html)
|
|
132
132
|
|
|
133
133
|
|
|
134
134
|
## Cleanup
|
|
135
|
-
Please refer to the documentation [here](https://
|
|
135
|
+
Please refer to the documentation [here](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboard-teardown.html).
|
|
136
136
|
|
|
137
137
|
## FAQ
|
|
138
|
-
Please refer to the documentation [here](https://
|
|
138
|
+
Please refer to the documentation [here](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/faq.html).
|
|
139
139
|
|
|
140
140
|
## Changelogs
|
|
141
141
|
For dashboards please check Change Logs [here](changes/)
|
|
142
142
|
For CID deployment tool, including Cli and CFN please check [Releases](/releases)
|
|
143
143
|
|
|
144
144
|
## Feedback
|
|
145
|
-
Please reference to [this page](https://
|
|
145
|
+
Please reference to [this page](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/feedback-support.html)
|
|
146
146
|
|
|
147
147
|
## Security
|
|
148
148
|
When you build systems on AWS infrastructure, security responsibilities are shared between you and AWS. This [shared responsibility
|
|
@@ -514,6 +514,8 @@ views:
|
|
|
514
514
|
summary_view:
|
|
515
515
|
File: queries/cid/summary_view.sql
|
|
516
516
|
dependsOn:
|
|
517
|
+
views:
|
|
518
|
+
- cur2_view
|
|
517
519
|
tags: json
|
|
518
520
|
cur2:
|
|
519
521
|
- bill_billing_entity
|
|
@@ -557,6 +559,14 @@ views:
|
|
|
557
559
|
- savings_plan_total_commitment_to_date
|
|
558
560
|
- savings_plan_used_commitment
|
|
559
561
|
|
|
562
|
+
cur2_view:
|
|
563
|
+
dependsOn:
|
|
564
|
+
cur2: True
|
|
565
|
+
data: |
|
|
566
|
+
CREATE VIEW "cur2_view" AS
|
|
567
|
+
SELECT *
|
|
568
|
+
FROM "${cur2_database}"."${cur2_table_name}"
|
|
569
|
+
|
|
560
570
|
ec2_running_cost:
|
|
561
571
|
File: queries/cid/ec2_running_cost.sql
|
|
562
572
|
dependsOn:
|
|
@@ -94,7 +94,6 @@ def map(ctx, **kwargs):
|
|
|
94
94
|
"""
|
|
95
95
|
ctx.obj.map(**kwargs)
|
|
96
96
|
|
|
97
|
-
|
|
98
97
|
@click.option('-v', '--verbose', count=True)
|
|
99
98
|
@click.option('-y', '--yes', help='confirm all', is_flag=True, default=False)
|
|
100
99
|
@cid_command
|
|
@@ -141,6 +140,8 @@ def deploy(ctx, **kwargs):
|
|
|
141
140
|
--catalog TEXT Comma separated list of catalog files or urls (ex: foundational,advanced )
|
|
142
141
|
--theme TEXT A QuickSight Theme (CLASSIC|MIDNIGHT|SEASIDE|RAINIER)
|
|
143
142
|
--currency TEXT A currency symbol instead of default USD (USD|GBP|EUR|JPY|KRW|DKK|TWD|INR)
|
|
143
|
+
--rls TEXT Desired RLS status (CLEAR|ENABLED|DISABLED) Clear = No RLS configuration.
|
|
144
|
+
--rls-dataset-id TEXT ID of RLS Dataset that will be used
|
|
144
145
|
--share-with-account (yes|no) Make dashboard visible to other users in the same account by default.
|
|
145
146
|
"""
|
|
146
147
|
ctx.obj.deploy(**kwargs)
|
|
@@ -210,6 +211,8 @@ def update(ctx, dashboard_id, force, recursive, **kwargs):
|
|
|
210
211
|
--on-drift (show|override) Action if a drift of view and dataset is discovered. 'override' = override drift(will destroy customization) or 'show' (default) = show a diff. In Unattended mode (without terminal on-drift will have allways override behaviour)
|
|
211
212
|
--theme TEXT A QuickSight Theme (CLASSIC|MIDNIGHT|SEASIDE|RAINIER)
|
|
212
213
|
--currency TEXT A currency symbol instead of default USD (USD|GBP|EUR|JPY|KRW|DKK|TWD|INR)
|
|
214
|
+
--rls TEXT Desired RLS status (CLEAR|ENABLED|DISABLED) Clear = No RLS configuration.
|
|
215
|
+
--rls-dataset-id TEXT ID of RLS Dataset that will be used
|
|
213
216
|
|
|
214
217
|
"""
|
|
215
218
|
ctx.obj.update(dashboard_id, force=force, recursive=recursive, **kwargs)
|
|
@@ -410,7 +410,7 @@ class Cid():
|
|
|
410
410
|
else:
|
|
411
411
|
if 'query' not in value:
|
|
412
412
|
raise CidCritical(f'Failed fetching parameter {prefix}{key}: parameter with type Athena must have query value.')
|
|
413
|
-
query = Template(value['query']).safe_substitute(others)
|
|
413
|
+
query = Template(value['query']).safe_substitute(params|others)
|
|
414
414
|
try:
|
|
415
415
|
res_list = self.athena.query(query)
|
|
416
416
|
except (self.athena.client.exceptions.ClientError, CidError, CidCritical) as exc:
|
|
@@ -1291,7 +1291,18 @@ class Cid():
|
|
|
1291
1291
|
# If there still datasets missing try automatic creation
|
|
1292
1292
|
if missing_datasets:
|
|
1293
1293
|
missing_str = ', '.join(missing_datasets)
|
|
1294
|
-
|
|
1294
|
+
cid_print(f'\nThere are still {len(missing_datasets)} datasets missing: {missing_str}')
|
|
1295
|
+
|
|
1296
|
+
# get rls status of existing datasets
|
|
1297
|
+
found_dataset_objects = [self.qs.describe_dataset(ds_id) for ds_id in found_datasets]
|
|
1298
|
+
rls_dataset_arns = [ds.rls_arn for ds in found_dataset_objects if ds.rls_arn]
|
|
1299
|
+
if rls_dataset_arns:
|
|
1300
|
+
rls_dataset_arn = max(set(rls_dataset_arns), key=rls_dataset_arns.count) #get the most frequent
|
|
1301
|
+
if not get_parameters().get('rls-dataset-id') and not get_parameters().get('rls'):
|
|
1302
|
+
rls_dataset_id = rls_dataset_arn.split('/')[-1]
|
|
1303
|
+
cid_print('Existing datasets are linked to RLS {rls_dataset_id}. We will reuse it for {missing_str} datasets.')
|
|
1304
|
+
set_parameters({'rls-dataset-id': rls_dataset_id})
|
|
1305
|
+
|
|
1295
1306
|
for dataset_name in missing_datasets[:]:
|
|
1296
1307
|
dataset_id = known_datasets.get(dataset_name)
|
|
1297
1308
|
print(f'Creating dataset: {dataset_name}')
|
|
@@ -1633,6 +1644,50 @@ class Cid():
|
|
|
1633
1644
|
compiled_dataset = Dataset.patch(dataset=compiled_dataset, custom_fields=custom_fields, athena=self.athena)
|
|
1634
1645
|
logger.trace(f"compiled_dataset = {json.dumps(compiled_dataset)}")
|
|
1635
1646
|
found_dataset = self.qs.describe_dataset(compiled_dataset.get('DataSetId'), timeout=0)
|
|
1647
|
+
|
|
1648
|
+
rls_dataset_id = get_parameters().get('rls-dataset-id')
|
|
1649
|
+
rls_dataset_status = get_parameters().get('rls')
|
|
1650
|
+
if rls_dataset_status == 'CLEAR':
|
|
1651
|
+
logger.debug('deleting rls')
|
|
1652
|
+
if "RowLevelPermissionDataSet" in compiled_dataset:
|
|
1653
|
+
del compiled_dataset["RowLevelPermissionDataSet"]
|
|
1654
|
+
if "RowLevelPermissionDataSet" in found_dataset:
|
|
1655
|
+
del found_dataset["RowLevelPermissionDataSet"]
|
|
1656
|
+
|
|
1657
|
+
if rls_dataset_id or rls_dataset_status:
|
|
1658
|
+
if not rls_dataset_id:
|
|
1659
|
+
for ds in self.qs.list_data_sets():
|
|
1660
|
+
print(ds)
|
|
1661
|
+
choices = {
|
|
1662
|
+
f"{ds.get('Name')}({ds.get('DataSetId')})":ds.get('DataSetId')
|
|
1663
|
+
for ds in self.qs.list_data_sets()
|
|
1664
|
+
if ds.get('UseAs') == 'RLS_RULES'
|
|
1665
|
+
}
|
|
1666
|
+
if not choices:
|
|
1667
|
+
raise CidCritical(f"Cannot find RLS DataSets")
|
|
1668
|
+
rls_dataset_id = get_parameter('rls-dataset-id', message='Select RLS dataset', choices=choices)
|
|
1669
|
+
rls_dataset = self.qs.describe_dataset(id=rls_dataset_id)
|
|
1670
|
+
if not rls_dataset:
|
|
1671
|
+
raise CidCritical(f"RLS DataSet {rls_dataset_id} not found")
|
|
1672
|
+
if not rls_dataset.is_rls:
|
|
1673
|
+
raise CidCritical(f"DataSet {rls_dataset_id} is not RLS")
|
|
1674
|
+
rls_permissions = {
|
|
1675
|
+
"Arn": rls_dataset.arn,
|
|
1676
|
+
"Status": (rls_dataset_status
|
|
1677
|
+
or (found_dataset and found_dataset.rls_status)
|
|
1678
|
+
or "ENABLED"
|
|
1679
|
+
),
|
|
1680
|
+
"PermissionPolicy": "GRANT_ACCESS",
|
|
1681
|
+
}
|
|
1682
|
+
cols = [c['Name'] for c in rls_dataset.columns]
|
|
1683
|
+
if 'UserName' in cols or 'GroupName' in cols:
|
|
1684
|
+
rls_permissions['FormatVersion'] = "VERSION_1"
|
|
1685
|
+
elif 'UserARN' in cols or 'GroupARN' in cols:
|
|
1686
|
+
rls_permissions['FormatVersion'] = "VERSION_2"
|
|
1687
|
+
else:
|
|
1688
|
+
raise CidCritical(f"DataSet {rls_dataset_id} must have 'UserName'/'GroupName' or 'UserARN'/'GroupARN' columns.")
|
|
1689
|
+
compiled_dataset["RowLevelPermissionDataSet"] = rls_permissions
|
|
1690
|
+
|
|
1636
1691
|
if isinstance(found_dataset, Dataset):
|
|
1637
1692
|
update_dataset = False
|
|
1638
1693
|
if update:
|
|
@@ -1861,7 +1916,10 @@ class Cid():
|
|
|
1861
1916
|
if not resource_tags:
|
|
1862
1917
|
return "'{}'"
|
|
1863
1918
|
logger.debug(f'selected_tag_names = {resource_tags}')
|
|
1864
|
-
array = ',\n '.join(
|
|
1919
|
+
array = ',\n '.join(
|
|
1920
|
+
[f"('{name}', {tags_and_names[name]})"
|
|
1921
|
+
for name in resource_tags]
|
|
1922
|
+
)
|
|
1865
1923
|
res = f'''
|
|
1866
1924
|
json_format(
|
|
1867
1925
|
CAST (
|
|
@@ -362,7 +362,7 @@ def export_analysis(qs, athena, glue):
|
|
|
362
362
|
# We can potentially reconsider this and use IDs at some point
|
|
363
363
|
'datasets': sorted(list(set(list(datasets.keys()) + resources_datasets)))
|
|
364
364
|
}
|
|
365
|
-
dashboard_resource['name'] = dashboard_resource.get('name')
|
|
365
|
+
dashboard_resource['name'] = dashboard_resource.get('name') or analysis['Name']
|
|
366
366
|
dashboard_resource['dashboardId'] = dashboard_id
|
|
367
367
|
dashboard_resource['category'] = get_parameters().get('category', dashboard_resource.get('category', 'Custom'))
|
|
368
368
|
|
|
@@ -601,7 +601,7 @@ class Athena(CidBase):
|
|
|
601
601
|
''')
|
|
602
602
|
|
|
603
603
|
def find_tables_with_columns(self, columns: list, database_name: str=None, catalog_name: str=None, max_items: int=10000):
|
|
604
|
-
"""
|
|
604
|
+
""" Returns an iterator that yields only tables containing all specified columns.
|
|
605
605
|
"""
|
|
606
606
|
iterator = self.client.get_paginator('list_table_metadata').paginate(
|
|
607
607
|
DatabaseName=database_name or self.DatabaseName,
|
|
@@ -610,6 +610,9 @@ class Athena(CidBase):
|
|
|
610
610
|
'MaxItems': max_items, # sometimes customers can have 1'000s of tables (due to a crawler going crazy for example)
|
|
611
611
|
},
|
|
612
612
|
)
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
613
|
+
# We cannot rely on search to find directly columns as there might be Nulls. So iterating old fashion.
|
|
614
|
+
for table in iterator.search('TableMetadataList'):
|
|
615
|
+
column_names = [c['Name'] for c in table.get('Columns', [])]
|
|
616
|
+
if all([(col in column_names) for col in columns]):
|
|
617
|
+
yield table
|
|
618
|
+
|
|
@@ -271,7 +271,7 @@ class CUR(AbstractCUR):
|
|
|
271
271
|
columns=self.cur_minimal_required_columns,
|
|
272
272
|
database_name=database,
|
|
273
273
|
)
|
|
274
|
-
all_cur_tables += [(database, table) for table in tables]
|
|
274
|
+
all_cur_tables += [(database, table['Name']) for table in tables]
|
|
275
275
|
except self.athena.client.exceptions.ClientError as exc:
|
|
276
276
|
if 'AccessDenied' in str(exc):
|
|
277
277
|
logger.info(f'Cannot read from athena database {database}')
|
|
@@ -14,7 +14,7 @@ from cid.base import CidBase
|
|
|
14
14
|
from cid.helpers import diff, timezone, randtime
|
|
15
15
|
from cid.helpers.quicksight.dashboard import Dashboard
|
|
16
16
|
from cid.helpers.quicksight.dataset import Dataset
|
|
17
|
-
from cid.helpers.quicksight.dashboard_patching import add_filter_to_dashboard_definition, patch_currency, patch_group_by
|
|
17
|
+
from cid.helpers.quicksight.dashboard_patching import add_filter_to_dashboard_definition, patch_currency, patch_group_by, patch_spaces
|
|
18
18
|
from cid.helpers.quicksight.datasource import Datasource
|
|
19
19
|
from cid.helpers.quicksight.template import Template as CidQsTemplate
|
|
20
20
|
from cid.helpers.quicksight.definition import Definition as CidQsDefinition
|
|
@@ -1340,6 +1340,7 @@ class QuickSight(CidBase):
|
|
|
1340
1340
|
create_parameters['Definition'],
|
|
1341
1341
|
currency_symbol=get_parameters().get('currency-symbol', 'USD')
|
|
1342
1342
|
)
|
|
1343
|
+
create_parameters['Definition'] = patch_spaces(create_parameters['Definition'])
|
|
1343
1344
|
dataset_references = []
|
|
1344
1345
|
for identifier, arn in definition.get('datasets', {}).items():
|
|
1345
1346
|
# Fetch dataset by name (preferably) OR by id
|
|
@@ -323,8 +323,10 @@ class Dashboard(CidQsResource):
|
|
|
323
323
|
if self.datasets:
|
|
324
324
|
cid_print(f" <BOLD>Datasets:<END>")
|
|
325
325
|
for dataset_name, dataset_id in sorted(self.datasets.items()):
|
|
326
|
+
ds = self.qs.describe_dataset(dataset_id)
|
|
327
|
+
rls = {'ENABLED': '🔐', 'DISABLED': '🔓', None: ' '}.get(ds.rls_status)
|
|
326
328
|
status = self.qs.get_dataset_last_ingestion(dataset_id) or '<BLUE>DIRECT<END>' #todo fix this Blue using dataset import type.
|
|
327
|
-
cid_print(f'
|
|
329
|
+
cid_print(f' {rls} {dataset_name: <36} ({dataset_id: <36}) {status}')
|
|
328
330
|
|
|
329
331
|
def display_url(self, url_template: str, launch: bool = False, **kwargs) -> None:
|
|
330
332
|
url = url_template.format(dashboard_id=self.id, **kwargs)
|
|
@@ -429,6 +429,24 @@ def detect_global_filter_fields(dashboard_definition):
|
|
|
429
429
|
cols.append(col_name)
|
|
430
430
|
|
|
431
431
|
|
|
432
|
+
def patch_spaces(definition):
|
|
433
|
+
''' put spaces in places
|
|
434
|
+
'''
|
|
435
|
+
def _patch(data):
|
|
436
|
+
"""Recursively set spaces in text fields"""
|
|
437
|
+
SPACE = '\u00A0' # special space: non-breaking space
|
|
438
|
+
if isinstance(data, dict):
|
|
439
|
+
return {k: _patch(v) if k not in ['Expression'] else v for k, v in data.items()} # skip patching code
|
|
440
|
+
elif isinstance(data, list):
|
|
441
|
+
return [_patch(item) for item in data]
|
|
442
|
+
elif isinstance(data, str):
|
|
443
|
+
text = re.sub(r'([^>\s])(\s*)(\s)(<[^/])', rf'\1{SPACE}\2\3\4', data, re.MULTILINE|re.DOTALL)
|
|
444
|
+
if text != data:
|
|
445
|
+
logger.trace(f'patch_spaces: {repr(text)} {repr(data)}')
|
|
446
|
+
return text
|
|
447
|
+
return data
|
|
448
|
+
return _patch(definition)
|
|
449
|
+
|
|
432
450
|
def patch_currency(definition, currency_symbol):
|
|
433
451
|
''' patch dashboard by adding currency symbol where the currency is configured already.
|
|
434
452
|
'''
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import uuid
|
|
1
2
|
import logging
|
|
2
|
-
from uuid import uuid4
|
|
3
3
|
from copy import deepcopy
|
|
4
4
|
|
|
5
5
|
import yaml
|
|
@@ -15,8 +15,14 @@ DATASET_PROPERTIES = [
|
|
|
15
15
|
]
|
|
16
16
|
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
def string_to_uuid(input_string):
|
|
19
|
+
"""Generate a UUID from a string using hash.
|
|
20
|
+
"""
|
|
21
|
+
return str(uuid.uuid5(uuid.NAMESPACE_DNS, input_string))
|
|
19
22
|
|
|
23
|
+
class Dataset(CidQsResource):
|
|
24
|
+
""" Dataset
|
|
25
|
+
"""
|
|
20
26
|
def __init__(self, raw: dict, qs=None, athena=None) -> None:
|
|
21
27
|
super().__init__(raw)
|
|
22
28
|
self.qs = qs
|
|
@@ -31,6 +37,19 @@ class Dataset(CidQsResource):
|
|
|
31
37
|
def id(self) -> str:
|
|
32
38
|
return self.get_property('DataSetId')
|
|
33
39
|
|
|
40
|
+
@property
|
|
41
|
+
def is_rls(self):
|
|
42
|
+
return self.get_property('UseAs') == 'RLS_RULES'
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def rls_status(self):
|
|
46
|
+
return (self.get_property('RowLevelPermissionDataSet') or {}).get('Status')
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def rls_arn(self):
|
|
50
|
+
return (self.get_property('RowLevelPermissionDataSet') or {}).get('Arn')
|
|
51
|
+
|
|
52
|
+
|
|
34
53
|
@property
|
|
35
54
|
def columns(self) -> list:
|
|
36
55
|
if not 'OutputColumns' in self.raw: self.describe()
|
|
@@ -121,11 +140,13 @@ class Dataset(CidQsResource):
|
|
|
121
140
|
renames[key] = dt["RenameColumnOperation"]['NewColumnName']
|
|
122
141
|
logger.trace(f'renames = {renames}')
|
|
123
142
|
|
|
124
|
-
projected_cols =
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
143
|
+
projected_cols = []
|
|
144
|
+
if root_lt.get('DataTransforms'):
|
|
145
|
+
projected_cols = next( # get the first DataTransform with ProjectOperation
|
|
146
|
+
ds['ProjectOperation']["ProjectedColumns"]
|
|
147
|
+
for ds in root_lt.get('DataTransforms', [])
|
|
148
|
+
if 'ProjectOperation' in ds
|
|
149
|
+
)
|
|
129
150
|
|
|
130
151
|
# Update each PhysicalTableMap with all columns from athena views
|
|
131
152
|
all_columns = []
|
|
@@ -179,7 +200,7 @@ class Dataset(CidQsResource):
|
|
|
179
200
|
"Columns": [
|
|
180
201
|
{
|
|
181
202
|
"ColumnName": col_name,
|
|
182
|
-
"ColumnId":
|
|
203
|
+
"ColumnId": string_to_uuid(dataset['Name'] + col_name),
|
|
183
204
|
"Expression": expression
|
|
184
205
|
}
|
|
185
206
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cid-cmd
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.1
|
|
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
|
|
@@ -49,15 +49,15 @@ Dynamic: license-file
|
|
|
49
49
|
## Overview
|
|
50
50
|
The Cloud Intelligence Dashboards is an open-source framework, lovingly cultivated and maintained by a group of customer-obsessed AWSers, that gives customers the power to get high-level and granular insight into their cost and usage data. Supported by the Well-Architected framework, the dashboards can be deployed by any customer using a CloudFormation template or a command-line tool in their environment in under 30 minutes. These dashboards help you to drive financial accountability, optimize cost, track usage goals, implement best-practices for governance, and achieve operational excellence across all your organization.
|
|
51
51
|
|
|
52
|
-
Cloud Intelligence Dashboards Framework provides AWS customers with [more then 20 Dashboards](https://
|
|
52
|
+
Cloud Intelligence Dashboards Framework provides AWS customers with [more then 20 Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html).
|
|
53
53
|
* Foundational Dashboards - A set of main Dashboards that only require Cost and Usage Report(CUR)
|
|
54
54
|
* Advanced Dashboards - Require CID Data Collection and CUR
|
|
55
55
|
* Additional Dashboards - Require various custom datasources or created for very specific use cases.
|
|
56
56
|
|
|
57
|
-
We recommend starting with deployment of [Foundational Dashboards](https://
|
|
57
|
+
We recommend starting with deployment of [Foundational Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboard-foundational.html). Then deploy [Data Collection](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/data-collection.html) and [Advanced Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html#advanced-dashboards). Check for [Additional](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html#additional-dashboards) Dashboards.
|
|
58
58
|
|
|
59
59
|
|
|
60
|
-
[](https://
|
|
60
|
+
[](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/deployment-in-global-regions.html)
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
## Architecture of Foundational Dashboards
|
|
@@ -67,9 +67,9 @@ We recommend starting with deployment of [Foundational Dashboards](https://catal
|
|
|
67
67
|
2. [Amazon S3](https://aws.amazon.com/s3/) replication rule copies Export data to a dedicated Data Collection Account S3 bucket automatically.
|
|
68
68
|
3. [Amazon Athena](https://aws.amazon.com/athena/) allows querying data directly from the S3 bucket using an [AWS Glue](https://aws.amazon.com/glue/) table schema definition.
|
|
69
69
|
4. [Amazon QuickSight](https://aws.amazon.com/quicksight/) creates datasets from [Amazon Athena](https://aws.amazon.com/athena/), refreshes daily and caches in [SPICE](https://docs.aws.amazon.com/quicksight/latest/user/spice.html)(Super-fast, Parallel, In-memory Calculation Engine) for [Amazon QuickSight](https://aws.amazon.com/quicksight/)
|
|
70
|
-
5. User Teams (Executives, FinOps, Engineers) can access Cloud Intelligence Dashboards in [Amazon QuickSight](https://aws.amazon.com/quicksight/). Access is secured through [AWS IAM](https://aws.amazon.com/iam/), IIC ([AWS IAM Identity Center](https://aws.amazon.com/iam/identity-center/), formerly SSO), and optional [Row Level Security](https://
|
|
70
|
+
5. User Teams (Executives, FinOps, Engineers) can access Cloud Intelligence Dashboards in [Amazon QuickSight](https://aws.amazon.com/quicksight/). Access is secured through [AWS IAM](https://aws.amazon.com/iam/), IIC ([AWS IAM Identity Center](https://aws.amazon.com/iam/identity-center/), formerly SSO), and optional [Row Level Security](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/row-level-security.html).
|
|
71
71
|
|
|
72
|
-
This foundational architecture is recommended for starting and allows deployment of [Foundational Dashboards](https://
|
|
72
|
+
This foundational architecture is recommended for starting and allows deployment of [Foundational Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboard-foundational.html) like CUDOS, CID and KPI.
|
|
73
73
|
|
|
74
74
|
## Architecture of Advanced Dashboards
|
|
75
75
|

|
|
@@ -78,14 +78,14 @@ This foundational architecture is recommended for starting and allows deployment
|
|
|
78
78
|
2. [Amazon S3](https://aws.amazon.com/s3/) replication rule copies Export data to a dedicated Data Collection Account S3 bucket automatically.
|
|
79
79
|
3. [Amazon Athena](https://aws.amazon.com/athena/) allows querying data directly from the S3 bucket using an [AWS Glue](https://aws.amazon.com/glue/) table schema definition.
|
|
80
80
|
4. [Amazon QuickSight](https://aws.amazon.com/quicksight/) creates datasets from [Amazon Athena](https://aws.amazon.com/athena/), refreshes daily and caches in [SPICE](https://docs.aws.amazon.com/quicksight/latest/user/spice.html)(Super-fast, Parallel, In-memory Calculation Engine) for [Amazon QuickSight](https://aws.amazon.com/quicksight/)
|
|
81
|
-
5. User Teams (Executives, FinOps, Engineers) can access Cloud Intelligence Dashboards in [Amazon QuickSight](https://aws.amazon.com/quicksight/). Access is secured through [AWS IAM](https://aws.amazon.com/iam/), IIC ([AWS IAM Identity Center](https://aws.amazon.com/iam/identity-center/), formerly SSO), and optional [Row Level Security](https://
|
|
81
|
+
5. User Teams (Executives, FinOps, Engineers) can access Cloud Intelligence Dashboards in [Amazon QuickSight](https://aws.amazon.com/quicksight/). Access is secured through [AWS IAM](https://aws.amazon.com/iam/), IIC ([AWS IAM Identity Center](https://aws.amazon.com/iam/identity-center/), formerly SSO), and optional [Row Level Security](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/row-level-security.html).
|
|
82
82
|
6. Optionally, the Advanced data collection can be deployed to enable advanced dashboards based on [AWS Trusted Advisor](https://aws.amazon.com/premiumsupport/trustedadvisor/), [AWS Health](https://aws.amazon.com/premiumsupport/technology/aws-health-dashboard/) Events and other sources. Additional data is retrieved from [AWS Organizations](https://aws.amazon.com/organizations/) or Linked Accounts. In this case [Amazon EventBridge](https://aws.amazon.com/eventbridge/) rule triggers an [AWS Step Functions](https://aws.amazon.com/step-functions/) workflow for data collection modules on a configurable schedule.
|
|
83
83
|
7. The "Account Collector" [AWS Lambda](https://aws.amazon.com/lambda/) in AWS Step Functions retrieves linked account details using AWS Organizations API.
|
|
84
84
|
8. The "Data Collection" Lambda function in AWS Step Functions assumes role in each linked account to retrieve account-specific data via [AWS SDK](https://aws.amazon.com/developer/tools/).
|
|
85
85
|
9. Retrieved data is stored in a centralized Amazon S3 Bucket.
|
|
86
|
-
10. [Advanced Cloud Intelligence Dashboards](https://
|
|
86
|
+
10. [Advanced Cloud Intelligence Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html#advanced-dashboards) leverage Amazon Athena and Amazon QuickSight for comprehensive data analysis.
|
|
87
87
|
|
|
88
|
-
This advanced data collection architecture allows deployment of [Advanced Dashboards](https://
|
|
88
|
+
This advanced data collection architecture allows deployment of [Advanced Dashboards](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboards.html#advanced-dashboards) like Trusted Advisor Dashboard, Health, Graviton, Compute Optimizer Dashboard and many more.
|
|
89
89
|
|
|
90
90
|
|
|
91
91
|
## Cost
|
|
@@ -154,23 +154,23 @@ There are several ways we can deploy dashboards:
|
|
|
154
154
|
1. Using cid-cmd tool from command line
|
|
155
155
|
1. [CloudFormation Template](./cfn-templates/cid-cfn.yml) using cid-cmd tool in Amazon Lambda. (Recommended)
|
|
156
156
|
|
|
157
|
-
Please refer to the deployment documentation [here](https://
|
|
157
|
+
Please refer to the deployment documentation [here](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/deployment-in-global-regions.html).
|
|
158
158
|
|
|
159
|
-
[](https://
|
|
159
|
+
[](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/deployment-in-global-regions.html)
|
|
160
160
|
|
|
161
161
|
|
|
162
162
|
## Cleanup
|
|
163
|
-
Please refer to the documentation [here](https://
|
|
163
|
+
Please refer to the documentation [here](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/dashboard-teardown.html).
|
|
164
164
|
|
|
165
165
|
## FAQ
|
|
166
|
-
Please refer to the documentation [here](https://
|
|
166
|
+
Please refer to the documentation [here](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/faq.html).
|
|
167
167
|
|
|
168
168
|
## Changelogs
|
|
169
169
|
For dashboards please check Change Logs [here](changes/)
|
|
170
170
|
For CID deployment tool, including Cli and CFN please check [Releases](/releases)
|
|
171
171
|
|
|
172
172
|
## Feedback
|
|
173
|
-
Please reference to [this page](https://
|
|
173
|
+
Please reference to [this page](https://docs.aws.amazon.com/guidance/latest/cloud-intelligence-dashboards/feedback-support.html)
|
|
174
174
|
|
|
175
175
|
## Security
|
|
176
176
|
When you build systems on AWS infrastructure, security responsibilities are shared between you and AWS. This [shared responsibility
|
|
@@ -36,6 +36,7 @@ cid/builtin/core/data/datasets/trends/monthly_bill_by_account.json
|
|
|
36
36
|
cid/builtin/core/data/permissions/dashboard_permissions.json
|
|
37
37
|
cid/builtin/core/data/permissions/dashboard_permissions_namespace.json
|
|
38
38
|
cid/builtin/core/data/permissions/data_set_permissions.json
|
|
39
|
+
cid/builtin/core/data/permissions/data_set_rls_permissions.json
|
|
39
40
|
cid/builtin/core/data/permissions/data_source_permissions.json
|
|
40
41
|
cid/builtin/core/data/permissions/folder_permissions.json
|
|
41
42
|
cid/builtin/core/data/queries/cid/compute_savings_plan_eligible_spend.sql
|
cid_cmd-4.2.7/cid/_version.py
DELETED
|
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
|
{cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/trends/daily_anomaly_detection.json
RENAMED
|
File without changes
|
{cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/trends/monthly_anomaly_detection.json
RENAMED
|
File without changes
|
{cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/datasets/trends/monthly_bill_by_account.json
RENAMED
|
File without changes
|
{cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/permissions/dashboard_permissions.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/permissions/data_source_permissions.json
RENAMED
|
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
|
|
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
|
{cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/shared/aws_service_category_map.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/shared/customer_all_unlimited.sql
RENAMED
|
File without changes
|
{cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/shared/payer_account_name_map.sql
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/trends/daily_anomaly_detection.sql
RENAMED
|
File without changes
|
{cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/trends/monthly_anomaly_detection.sql
RENAMED
|
File without changes
|
{cid_cmd-4.2.7 → cid_cmd-4.3.1}/cid/builtin/core/data/queries/trends/monthly_bill_by_account.sql
RENAMED
|
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
|
|
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
|