cloudwright-ai 0.3.2__tar.gz → 0.3.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.
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/PKG-INFO +1 -1
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/__init__.py +1 -1
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/cost.py +206 -10
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/importer/__init__.py +23 -2
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/importer/cloudformation.py +40 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/importer/terraform_state.py +77 -1
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_cfn_importer.py +2 -2
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/.gitignore +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/README.md +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/adapters/__init__.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/adapters/aws.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/adapters/azure.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/adapters/databricks.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/adapters/gcp.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/analyzer.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/architect.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/ascii_diagram.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/catalog/__init__.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/catalog/formula.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/catalog/refresh.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/catalog/store.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/catalog.db +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/_generate_icons.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/alb.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/api_gateway.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/cloudfront.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/cloudtrail.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/cloudwatch.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/cognito.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/dynamodb.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/ebs.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/ec2.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/ecr.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/ecs.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/eks.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/elasticache.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/emr.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/glue.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/guardduty.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/kinesis.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/kms.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/lambda.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/nlb.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/rds.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/redshift.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/route53.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/s3.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/sagemaker.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/sns.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/sqs.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/step_functions.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/aws/waf.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/azure/aks.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/azure/app_gateway.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/azure/azure_cache.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/azure/azure_functions.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/azure/azure_sql.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/azure/blob_storage.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/azure/cosmos_db.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/azure/service_bus.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/azure/virtual_machines.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/gcp/bigquery.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/gcp/cloud_cdn.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/gcp/cloud_functions.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/gcp/cloud_load_balancing.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/gcp/cloud_run.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/gcp/cloud_sql.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/gcp/cloud_storage.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/gcp/compute_engine.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/gcp/gke.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/gcp/memorystore.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/gcp/pub_sub.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/generic/cache.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/generic/cdn.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/generic/compute.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/generic/database.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/generic/firewall.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/generic/internet.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/generic/load_balancer.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/generic/queue.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/generic/storage.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/generic/user.svg +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/analytics.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/cache.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/compute.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/containers.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/database_nosql.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/database_relational.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/messaging.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/ml.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/networking_api.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/networking_cdn.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/networking_dns.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/networking_lb.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/orchestration.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/security_auth.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/security_waf.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/serverless.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/storage_block.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/storage_object.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/registry/streaming.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/_index.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/azure-microservices.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/azure-serverless-api.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/azure-three-tier-web.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/batch-processing.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/data-lake.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/databricks-lakehouse.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/databricks-ml-platform.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/event-driven.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/gcp-microservices.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/gcp-serverless-api.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/gcp-three-tier-web.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/microservices.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/ml_pipeline.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/serverless_api.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/static-site.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/templates/three_tier_web.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/differ.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/drift.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/evolution.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/exporter/__init__.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/exporter/aibom.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/exporter/ascii.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/exporter/c4.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/exporter/cloudformation.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/exporter/compliance_report.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/exporter/d2.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/exporter/diff_diagram.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/exporter/mermaid.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/exporter/presentation.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/exporter/renderer.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/exporter/sbom.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/exporter/terraform.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/icons.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/importer/utils.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/layout.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/linter.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/llm/__init__.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/llm/anthropic.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/llm/base.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/llm/openai.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/plugins.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/policy.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/providers/__init__.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/providers/aws.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/providers/azure.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/providers/databricks.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/providers/gcp.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/py.typed +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/registry.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/scorer.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/security.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/spec.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/templates.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/validator.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/pyproject.toml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/conftest.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/fixtures/aws.tfstate +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/fixtures/aws_serverless.tfstate +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/fixtures/azure.tfstate +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/fixtures/cloudformation_template.json +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/fixtures/gcp.tfstate +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/fixtures/serverless_api.json +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/fixtures/three_tier.yaml +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_adapter_aws.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_adapter_azure.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_adapter_databricks.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_adapter_gcp.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_adr.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_analyzer.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_architect.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_architect_chat.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_ascii_diagram.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_c4_exporter.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_catalog.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_constraint_propagation.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_cost.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_databricks.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_diff_viz.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_differ.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_drift.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_e2e.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_evolution.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_exporter.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_formula.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_icons.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_importer.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_importer_cfn.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_layout_engine.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_linter.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_packaging.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_plugins.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_policy.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_presentation.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_refresh.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_registry.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_renderer.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_scorer.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_security.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_spec.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_validator.py +0 -0
- {cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/tests/test_validator_fedramp_gdpr.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cloudwright-ai
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: Architecture intelligence for cloud engineers — design, cost, compare, export
|
|
5
5
|
Project-URL: Homepage, https://github.com/xmpuspus/cloudwright
|
|
6
6
|
Project-URL: Repository, https://github.com/xmpuspus/cloudwright
|
|
@@ -4,6 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
import logging
|
|
6
6
|
from datetime import date
|
|
7
|
+
from typing import Any
|
|
7
8
|
|
|
8
9
|
from cloudwright.catalog import _PRICING_MULTIPLIERS, Catalog
|
|
9
10
|
from cloudwright.catalog.formula import PRICING_FORMULAS, default_managed_price
|
|
@@ -40,20 +41,202 @@ _SERVICE_EGRESS_OVERRIDES = {
|
|
|
40
41
|
}
|
|
41
42
|
_DEFAULT_EGRESS_RATE = 0.09
|
|
42
43
|
|
|
44
|
+
# ---------------------------------------------------------------------------
|
|
45
|
+
# Workload profiles — realistic sizing defaults per environment tier
|
|
46
|
+
# ---------------------------------------------------------------------------
|
|
47
|
+
|
|
48
|
+
# Config overrides applied to components when a workload profile is active.
|
|
49
|
+
# Only fills in missing config keys; never overwrites explicit values.
|
|
50
|
+
_PROFILE_DEFAULTS: dict[str, dict[str, dict[str, Any]]] = {
|
|
51
|
+
"small": {
|
|
52
|
+
# Serverless
|
|
53
|
+
"lambda": {"monthly_requests": 5_000_000, "avg_duration_ms": 300, "memory_mb": 512},
|
|
54
|
+
"cloud_functions": {"monthly_requests": 5_000_000, "avg_duration_ms": 300, "memory_mb": 512},
|
|
55
|
+
"azure_functions": {"monthly_requests": 5_000_000, "avg_duration_ms": 300, "memory_mb": 512},
|
|
56
|
+
# Databases
|
|
57
|
+
"rds": {"storage_gb": 50},
|
|
58
|
+
"aurora": {"storage_gb": 50},
|
|
59
|
+
"cloud_sql": {"storage_gb": 50},
|
|
60
|
+
"azure_sql": {"storage_gb": 50},
|
|
61
|
+
"dynamodb": {"monthly_requests": 5_000_000},
|
|
62
|
+
# Storage
|
|
63
|
+
"s3": {"storage_gb": 100},
|
|
64
|
+
"cloud_storage": {"storage_gb": 100},
|
|
65
|
+
"blob_storage": {"storage_gb": 100},
|
|
66
|
+
# CDN
|
|
67
|
+
"cloudfront": {"estimated_gb": 200},
|
|
68
|
+
"cloud_cdn": {"estimated_gb": 200},
|
|
69
|
+
"azure_cdn": {"estimated_gb": 200},
|
|
70
|
+
# Analytics
|
|
71
|
+
"bigquery": {"monthly_query_tb": 2, "storage_gb": 200},
|
|
72
|
+
"redshift": {"num_nodes": 2, "storage_gb": 500},
|
|
73
|
+
"synapse": {"num_nodes": 2, "storage_gb": 500},
|
|
74
|
+
},
|
|
75
|
+
"medium": {
|
|
76
|
+
# Serverless
|
|
77
|
+
"lambda": {"monthly_requests": 50_000_000, "avg_duration_ms": 400, "memory_mb": 1024},
|
|
78
|
+
"cloud_functions": {"monthly_requests": 50_000_000, "avg_duration_ms": 400, "memory_mb": 1024},
|
|
79
|
+
"azure_functions": {"monthly_requests": 50_000_000, "avg_duration_ms": 400, "memory_mb": 1024},
|
|
80
|
+
# Databases
|
|
81
|
+
"rds": {"storage_gb": 200, "multi_az": True},
|
|
82
|
+
"aurora": {"storage_gb": 200, "multi_az": True},
|
|
83
|
+
"cloud_sql": {"storage_gb": 200},
|
|
84
|
+
"azure_sql": {"storage_gb": 200},
|
|
85
|
+
"dynamodb": {"monthly_requests": 50_000_000},
|
|
86
|
+
# Storage
|
|
87
|
+
"s3": {"storage_gb": 500},
|
|
88
|
+
"cloud_storage": {"storage_gb": 500},
|
|
89
|
+
"blob_storage": {"storage_gb": 500},
|
|
90
|
+
# Compute
|
|
91
|
+
"ec2": {"count": 3},
|
|
92
|
+
"compute_engine": {"count": 3},
|
|
93
|
+
"virtual_machines": {"count": 3},
|
|
94
|
+
# Container orchestration
|
|
95
|
+
"eks": {"node_count": 6},
|
|
96
|
+
"gke": {"node_count": 6},
|
|
97
|
+
"aks": {"node_count": 6},
|
|
98
|
+
"ecs": {"count": 4},
|
|
99
|
+
# CDN
|
|
100
|
+
"cloudfront": {"estimated_gb": 1000},
|
|
101
|
+
"cloud_cdn": {"estimated_gb": 1000},
|
|
102
|
+
"azure_cdn": {"estimated_gb": 1000},
|
|
103
|
+
# Analytics
|
|
104
|
+
"bigquery": {"monthly_query_tb": 10, "storage_gb": 1000},
|
|
105
|
+
"redshift": {"num_nodes": 4, "storage_gb": 2000},
|
|
106
|
+
"synapse": {"num_nodes": 4, "storage_gb": 2000},
|
|
107
|
+
# Cache
|
|
108
|
+
"elasticache": {"memory_gb": 13},
|
|
109
|
+
"memorystore": {"memory_gb": 13},
|
|
110
|
+
"azure_cache": {"memory_gb": 13},
|
|
111
|
+
},
|
|
112
|
+
"large": {
|
|
113
|
+
# Serverless
|
|
114
|
+
"lambda": {"monthly_requests": 500_000_000, "avg_duration_ms": 500, "memory_mb": 2048},
|
|
115
|
+
"cloud_functions": {"monthly_requests": 500_000_000, "avg_duration_ms": 500, "memory_mb": 2048},
|
|
116
|
+
"azure_functions": {"monthly_requests": 500_000_000, "avg_duration_ms": 500, "memory_mb": 2048},
|
|
117
|
+
# Databases
|
|
118
|
+
"rds": {"storage_gb": 1000, "multi_az": True},
|
|
119
|
+
"aurora": {"storage_gb": 1000, "multi_az": True},
|
|
120
|
+
"cloud_sql": {"storage_gb": 1000},
|
|
121
|
+
"azure_sql": {"storage_gb": 1000},
|
|
122
|
+
"dynamodb": {"monthly_requests": 200_000_000},
|
|
123
|
+
# Storage
|
|
124
|
+
"s3": {"storage_gb": 5000},
|
|
125
|
+
"cloud_storage": {"storage_gb": 5000},
|
|
126
|
+
"blob_storage": {"storage_gb": 5000},
|
|
127
|
+
# Compute
|
|
128
|
+
"ec2": {"count": 6},
|
|
129
|
+
"compute_engine": {"count": 6},
|
|
130
|
+
"virtual_machines": {"count": 6},
|
|
131
|
+
# Container orchestration
|
|
132
|
+
"eks": {"node_count": 15},
|
|
133
|
+
"gke": {"node_count": 15},
|
|
134
|
+
"aks": {"node_count": 15},
|
|
135
|
+
"ecs": {"count": 10},
|
|
136
|
+
# CDN
|
|
137
|
+
"cloudfront": {"estimated_gb": 5000},
|
|
138
|
+
"cloud_cdn": {"estimated_gb": 5000},
|
|
139
|
+
"azure_cdn": {"estimated_gb": 5000},
|
|
140
|
+
# Analytics
|
|
141
|
+
"bigquery": {"monthly_query_tb": 50, "storage_gb": 5000},
|
|
142
|
+
"redshift": {"num_nodes": 8, "storage_gb": 10000},
|
|
143
|
+
"synapse": {"num_nodes": 8, "storage_gb": 10000},
|
|
144
|
+
# Cache
|
|
145
|
+
"elasticache": {"memory_gb": 52},
|
|
146
|
+
"memorystore": {"memory_gb": 52},
|
|
147
|
+
"azure_cache": {"memory_gb": 52},
|
|
148
|
+
},
|
|
149
|
+
"enterprise": {
|
|
150
|
+
# Serverless
|
|
151
|
+
"lambda": {"monthly_requests": 2_000_000_000, "avg_duration_ms": 600, "memory_mb": 3072},
|
|
152
|
+
"cloud_functions": {"monthly_requests": 2_000_000_000, "avg_duration_ms": 600, "memory_mb": 3072},
|
|
153
|
+
"azure_functions": {"monthly_requests": 2_000_000_000, "avg_duration_ms": 600, "memory_mb": 3072},
|
|
154
|
+
# Databases
|
|
155
|
+
"rds": {"storage_gb": 5000, "multi_az": True},
|
|
156
|
+
"aurora": {"storage_gb": 5000, "multi_az": True},
|
|
157
|
+
"cloud_sql": {"storage_gb": 5000},
|
|
158
|
+
"azure_sql": {"storage_gb": 5000},
|
|
159
|
+
"dynamodb": {"monthly_requests": 1_000_000_000},
|
|
160
|
+
# Storage
|
|
161
|
+
"s3": {"storage_gb": 50000},
|
|
162
|
+
"cloud_storage": {"storage_gb": 50000},
|
|
163
|
+
"blob_storage": {"storage_gb": 50000},
|
|
164
|
+
# Compute
|
|
165
|
+
"ec2": {"count": 20},
|
|
166
|
+
"compute_engine": {"count": 20},
|
|
167
|
+
"virtual_machines": {"count": 20},
|
|
168
|
+
# Container orchestration
|
|
169
|
+
"eks": {"node_count": 50},
|
|
170
|
+
"gke": {"node_count": 50},
|
|
171
|
+
"aks": {"node_count": 50},
|
|
172
|
+
"ecs": {"count": 30},
|
|
173
|
+
# CDN
|
|
174
|
+
"cloudfront": {"estimated_gb": 50000},
|
|
175
|
+
"cloud_cdn": {"estimated_gb": 50000},
|
|
176
|
+
"azure_cdn": {"estimated_gb": 50000},
|
|
177
|
+
# Analytics
|
|
178
|
+
"bigquery": {"monthly_query_tb": 200, "storage_gb": 50000},
|
|
179
|
+
"redshift": {"num_nodes": 16, "storage_gb": 50000},
|
|
180
|
+
"synapse": {"num_nodes": 16, "storage_gb": 50000},
|
|
181
|
+
# Cache
|
|
182
|
+
"elasticache": {"memory_gb": 200},
|
|
183
|
+
"memorystore": {"memory_gb": 200},
|
|
184
|
+
"azure_cache": {"memory_gb": 200},
|
|
185
|
+
},
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
# Default data transfer (GB/month) per connection when a workload profile is active
|
|
189
|
+
# but the connection has no explicit estimated_monthly_gb.
|
|
190
|
+
_PROFILE_TRANSFER_DEFAULTS: dict[str, float] = {
|
|
191
|
+
"small": 50.0,
|
|
192
|
+
"medium": 200.0,
|
|
193
|
+
"large": 1000.0,
|
|
194
|
+
"enterprise": 5000.0,
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
VALID_WORKLOAD_PROFILES = set(_PROFILE_DEFAULTS.keys())
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def _apply_profile(comp: Component, profile: str) -> Component:
|
|
201
|
+
"""Return a copy of the component with profile defaults merged into its config.
|
|
202
|
+
|
|
203
|
+
Profile defaults only fill in missing keys — explicit config always wins.
|
|
204
|
+
"""
|
|
205
|
+
svc_defaults = _PROFILE_DEFAULTS.get(profile, {}).get(comp.service)
|
|
206
|
+
if not svc_defaults:
|
|
207
|
+
return comp
|
|
208
|
+
merged = dict(svc_defaults)
|
|
209
|
+
merged.update(comp.config or {})
|
|
210
|
+
return comp.model_copy(update={"config": merged})
|
|
211
|
+
|
|
43
212
|
|
|
44
213
|
class CostEngine:
|
|
45
214
|
def __init__(self, catalog: Catalog | None = None, registry: ServiceRegistry | None = None):
|
|
46
215
|
self.catalog = catalog or Catalog()
|
|
47
216
|
self.registry = registry or get_registry()
|
|
48
217
|
|
|
49
|
-
def estimate(
|
|
50
|
-
|
|
218
|
+
def estimate(
|
|
219
|
+
self,
|
|
220
|
+
spec: ArchSpec,
|
|
221
|
+
pricing_tier: str = "on_demand",
|
|
222
|
+
workload_profile: str | None = None,
|
|
223
|
+
) -> CostEstimate:
|
|
224
|
+
"""Price every component in an ArchSpec and return a full breakdown.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
spec: The architecture specification to price.
|
|
228
|
+
pricing_tier: Pricing model — on_demand, reserved_1yr, reserved_3yr, spot.
|
|
229
|
+
workload_profile: Optional sizing profile — small, medium, large, enterprise.
|
|
230
|
+
When set, applies realistic defaults for request volumes, storage sizes,
|
|
231
|
+
node counts, and data transfer that match production workloads.
|
|
232
|
+
"""
|
|
51
233
|
breakdown: list[ComponentCost] = []
|
|
52
234
|
|
|
53
235
|
for comp in spec.components:
|
|
54
|
-
|
|
236
|
+
effective = _apply_profile(comp, workload_profile) if workload_profile else comp
|
|
237
|
+
monthly = self._price_component(effective, spec.provider, spec.region, pricing_tier)
|
|
55
238
|
hourly = round(monthly / 730, 4) if monthly > 0 else None
|
|
56
|
-
notes = self._cost_notes(
|
|
239
|
+
notes = self._cost_notes(effective)
|
|
57
240
|
breakdown.append(
|
|
58
241
|
ComponentCost(
|
|
59
242
|
component_id=comp.id,
|
|
@@ -65,7 +248,7 @@ class CostEngine:
|
|
|
65
248
|
)
|
|
66
249
|
|
|
67
250
|
component_total = round(sum(c.monthly for c in breakdown), 2)
|
|
68
|
-
data_transfer = self._estimate_data_transfer(spec)
|
|
251
|
+
data_transfer = self._estimate_data_transfer(spec, workload_profile=workload_profile)
|
|
69
252
|
total = round(component_total + data_transfer, 2)
|
|
70
253
|
|
|
71
254
|
return CostEstimate(
|
|
@@ -76,12 +259,22 @@ class CostEngine:
|
|
|
76
259
|
as_of=date.today().isoformat(),
|
|
77
260
|
)
|
|
78
261
|
|
|
79
|
-
def price(
|
|
262
|
+
def price(
|
|
263
|
+
self,
|
|
264
|
+
spec: ArchSpec,
|
|
265
|
+
pricing_tier: str = "on_demand",
|
|
266
|
+
workload_profile: str | None = None,
|
|
267
|
+
) -> ArchSpec:
|
|
80
268
|
"""Estimate costs and return a new ArchSpec with cost_estimate attached."""
|
|
81
|
-
estimate = self.estimate(spec, pricing_tier=pricing_tier)
|
|
269
|
+
estimate = self.estimate(spec, pricing_tier=pricing_tier, workload_profile=workload_profile)
|
|
82
270
|
return spec.model_copy(update={"cost_estimate": estimate})
|
|
83
271
|
|
|
84
|
-
def compare_providers(
|
|
272
|
+
def compare_providers(
|
|
273
|
+
self,
|
|
274
|
+
spec: ArchSpec,
|
|
275
|
+
providers: list[str],
|
|
276
|
+
workload_profile: str | None = None,
|
|
277
|
+
) -> list[Alternative]:
|
|
85
278
|
"""Price the architecture across multiple cloud providers."""
|
|
86
279
|
alternatives: list[Alternative] = []
|
|
87
280
|
|
|
@@ -117,7 +310,7 @@ class CostEngine:
|
|
|
117
310
|
"components": mapped_components,
|
|
118
311
|
}
|
|
119
312
|
)
|
|
120
|
-
alt_estimate = self.estimate(alt_spec)
|
|
313
|
+
alt_estimate = self.estimate(alt_spec, workload_profile=workload_profile)
|
|
121
314
|
|
|
122
315
|
alternatives.append(
|
|
123
316
|
Alternative(
|
|
@@ -216,13 +409,16 @@ class CostEngine:
|
|
|
216
409
|
|
|
217
410
|
return round(base, 2)
|
|
218
411
|
|
|
219
|
-
def _estimate_data_transfer(self, spec: ArchSpec) -> float:
|
|
412
|
+
def _estimate_data_transfer(self, spec: ArchSpec, workload_profile: str | None = None) -> float:
|
|
220
413
|
"""Estimate monthly data transfer (egress) costs from connections."""
|
|
221
414
|
total = 0.0
|
|
222
415
|
component_map = {c.id: c for c in spec.components}
|
|
416
|
+
profile_default_gb = _PROFILE_TRANSFER_DEFAULTS.get(workload_profile or "", 0.0)
|
|
223
417
|
|
|
224
418
|
for conn in spec.connections:
|
|
225
419
|
gb = conn.estimated_monthly_gb
|
|
420
|
+
if not gb and profile_default_gb:
|
|
421
|
+
gb = profile_default_gb
|
|
226
422
|
if not gb:
|
|
227
423
|
continue
|
|
228
424
|
source = component_map.get(conn.source)
|
|
@@ -30,6 +30,25 @@ class ImporterPlugin(ABC):
|
|
|
30
30
|
...
|
|
31
31
|
|
|
32
32
|
|
|
33
|
+
def _apply_import_defaults(spec: "ArchSpec") -> "ArchSpec":
|
|
34
|
+
_ENCRYPT_SERVICES = {"rds", "aurora", "cloud_sql", "azure_sql", "s3", "cloud_storage", "blob_storage"}
|
|
35
|
+
|
|
36
|
+
updated = []
|
|
37
|
+
changed = False
|
|
38
|
+
for comp in spec.components:
|
|
39
|
+
if comp.service in _ENCRYPT_SERVICES and not comp.config.get("encryption"):
|
|
40
|
+
new_config = dict(comp.config)
|
|
41
|
+
new_config["encryption"] = True
|
|
42
|
+
updated.append(comp.model_copy(update={"config": new_config}))
|
|
43
|
+
changed = True
|
|
44
|
+
else:
|
|
45
|
+
updated.append(comp)
|
|
46
|
+
|
|
47
|
+
if changed:
|
|
48
|
+
return spec.model_copy(update={"components": updated})
|
|
49
|
+
return spec
|
|
50
|
+
|
|
51
|
+
|
|
33
52
|
def import_spec(path: str, fmt: str = "auto", design_spec: "ArchSpec | None" = None) -> ArchSpec:
|
|
34
53
|
"""Import an ArchSpec from an infrastructure state file.
|
|
35
54
|
|
|
@@ -46,12 +65,14 @@ def import_spec(path: str, fmt: str = "auto", design_spec: "ArchSpec | None" = N
|
|
|
46
65
|
if fmt == "terraform":
|
|
47
66
|
from cloudwright.importer.terraform_state import TerraformStateImporter
|
|
48
67
|
|
|
49
|
-
|
|
68
|
+
spec = TerraformStateImporter().do_import(path, design_spec=design_spec)
|
|
69
|
+
return _apply_import_defaults(spec)
|
|
50
70
|
|
|
51
71
|
if fmt in ("cloudformation", "cfn"):
|
|
52
72
|
from cloudwright.importer.cloudformation import CloudFormationImporter
|
|
53
73
|
|
|
54
|
-
|
|
74
|
+
spec = CloudFormationImporter().do_import(path, design_spec=design_spec)
|
|
75
|
+
return _apply_import_defaults(spec)
|
|
55
76
|
|
|
56
77
|
raise ValueError(f"Unknown import format: {fmt!r}. Supported: terraform, cloudformation")
|
|
57
78
|
|
|
@@ -61,6 +61,34 @@ _CFN_TYPE_MAP: dict[str, str] = {
|
|
|
61
61
|
# ML
|
|
62
62
|
"AWS::SageMaker::Endpoint": "sagemaker",
|
|
63
63
|
"AWS::SageMaker::Model": "sagemaker",
|
|
64
|
+
# IAM
|
|
65
|
+
"AWS::IAM::Role": "iam",
|
|
66
|
+
"AWS::IAM::Policy": "iam",
|
|
67
|
+
"AWS::IAM::InstanceProfile": "iam",
|
|
68
|
+
# Networking
|
|
69
|
+
"AWS::EC2::VPC": "vpc",
|
|
70
|
+
"AWS::EC2::Subnet": "vpc",
|
|
71
|
+
"AWS::EC2::SecurityGroup": "vpc",
|
|
72
|
+
"AWS::EC2::NatGateway": "nat_gateway",
|
|
73
|
+
"AWS::EC2::InternetGateway": "vpc",
|
|
74
|
+
"AWS::EC2::RouteTable": "vpc",
|
|
75
|
+
# Monitoring
|
|
76
|
+
"AWS::CloudWatch::Alarm": "cloudwatch",
|
|
77
|
+
"AWS::Logs::LogGroup": "cloudwatch",
|
|
78
|
+
"AWS::CloudTrail::Trail": "cloudtrail",
|
|
79
|
+
# Kinesis
|
|
80
|
+
"AWS::Kinesis::Stream": "kinesis",
|
|
81
|
+
# Step Functions
|
|
82
|
+
"AWS::StepFunctions::StateMachine": "step_functions",
|
|
83
|
+
# Secrets
|
|
84
|
+
"AWS::SecretsManager::Secret": "secrets_manager",
|
|
85
|
+
"AWS::KMS::Key": "kms",
|
|
86
|
+
# ECR
|
|
87
|
+
"AWS::ECR::Repository": "ecr",
|
|
88
|
+
# MSK
|
|
89
|
+
"AWS::MSK::Cluster": "msk",
|
|
90
|
+
# EventBridge (additional)
|
|
91
|
+
"AWS::Scheduler::Schedule": "eventbridge",
|
|
64
92
|
}
|
|
65
93
|
|
|
66
94
|
_TIER = {
|
|
@@ -70,10 +98,15 @@ _TIER = {
|
|
|
70
98
|
"route53": 1,
|
|
71
99
|
"api_gateway": 1,
|
|
72
100
|
"cognito": 1,
|
|
101
|
+
"iam": 1,
|
|
102
|
+
"vpc": 1,
|
|
103
|
+
"nat_gateway": 1,
|
|
73
104
|
"ec2": 2,
|
|
74
105
|
"lambda": 2,
|
|
75
106
|
"ecs": 2,
|
|
76
107
|
"eks": 2,
|
|
108
|
+
"step_functions": 2,
|
|
109
|
+
"sagemaker": 2,
|
|
77
110
|
"rds": 3,
|
|
78
111
|
"aurora": 3,
|
|
79
112
|
"dynamodb": 3,
|
|
@@ -82,8 +115,15 @@ _TIER = {
|
|
|
82
115
|
"sns": 3,
|
|
83
116
|
"eventbridge": 3,
|
|
84
117
|
"redshift": 3,
|
|
118
|
+
"kinesis": 3,
|
|
119
|
+
"msk": 3,
|
|
85
120
|
"s3": 4,
|
|
86
121
|
"ebs": 4,
|
|
122
|
+
"cloudwatch": 4,
|
|
123
|
+
"cloudtrail": 4,
|
|
124
|
+
"secrets_manager": 4,
|
|
125
|
+
"kms": 4,
|
|
126
|
+
"ecr": 4,
|
|
87
127
|
}
|
|
88
128
|
|
|
89
129
|
|
|
@@ -81,6 +81,81 @@ _TIER = {
|
|
|
81
81
|
"managed_disks": 4,
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
_HARDCODED_TF_MAP: dict[str, str] = {
|
|
85
|
+
# AWS
|
|
86
|
+
"aws_instance": "ec2",
|
|
87
|
+
"aws_launch_template": "ec2",
|
|
88
|
+
"aws_autoscaling_group": "ec2",
|
|
89
|
+
"aws_ecs_cluster": "ecs",
|
|
90
|
+
"aws_ecs_service": "ecs",
|
|
91
|
+
"aws_ecs_task_definition": "ecs",
|
|
92
|
+
"aws_eks_cluster": "eks",
|
|
93
|
+
"aws_eks_node_group": "eks",
|
|
94
|
+
"aws_lambda_function": "lambda",
|
|
95
|
+
"aws_db_instance": "rds",
|
|
96
|
+
"aws_rds_cluster": "aurora",
|
|
97
|
+
"aws_dynamodb_table": "dynamodb",
|
|
98
|
+
"aws_s3_bucket": "s3",
|
|
99
|
+
"aws_lb": "alb",
|
|
100
|
+
"aws_alb": "alb",
|
|
101
|
+
"aws_lb_target_group": "alb",
|
|
102
|
+
"aws_cloudfront_distribution": "cloudfront",
|
|
103
|
+
"aws_route53_zone": "route53",
|
|
104
|
+
"aws_api_gateway_rest_api": "api_gateway",
|
|
105
|
+
"aws_apigatewayv2_api": "api_gateway",
|
|
106
|
+
"aws_wafv2_web_acl": "waf",
|
|
107
|
+
"aws_cognito_user_pool": "cognito",
|
|
108
|
+
"aws_elasticache_cluster": "elasticache",
|
|
109
|
+
"aws_elasticache_replication_group": "elasticache",
|
|
110
|
+
"aws_sqs_queue": "sqs",
|
|
111
|
+
"aws_sns_topic": "sns",
|
|
112
|
+
"aws_kinesis_stream": "kinesis",
|
|
113
|
+
"aws_redshift_cluster": "redshift",
|
|
114
|
+
"aws_sagemaker_endpoint": "sagemaker",
|
|
115
|
+
"aws_nat_gateway": "nat_gateway",
|
|
116
|
+
"aws_iam_role": "iam",
|
|
117
|
+
"aws_iam_policy": "iam",
|
|
118
|
+
"aws_kms_key": "kms",
|
|
119
|
+
"aws_secretsmanager_secret": "secrets_manager",
|
|
120
|
+
"aws_ecr_repository": "ecr",
|
|
121
|
+
"aws_msk_cluster": "msk",
|
|
122
|
+
"aws_sfn_state_machine": "step_functions",
|
|
123
|
+
"aws_cloudwatch_log_group": "cloudwatch",
|
|
124
|
+
"aws_cloudtrail": "cloudtrail",
|
|
125
|
+
"aws_ebs_volume": "ebs",
|
|
126
|
+
# GCP
|
|
127
|
+
"google_compute_instance": "compute_engine",
|
|
128
|
+
"google_container_cluster": "gke",
|
|
129
|
+
"google_container_node_pool": "gke",
|
|
130
|
+
"google_cloud_run_service": "cloud_run",
|
|
131
|
+
"google_cloudfunctions_function": "cloud_functions",
|
|
132
|
+
"google_cloudfunctions2_function": "cloud_functions",
|
|
133
|
+
"google_sql_database_instance": "cloud_sql",
|
|
134
|
+
"google_storage_bucket": "cloud_storage",
|
|
135
|
+
"google_compute_backend_service": "cloud_load_balancing",
|
|
136
|
+
"google_pubsub_topic": "pub_sub",
|
|
137
|
+
"google_bigquery_dataset": "bigquery",
|
|
138
|
+
"google_redis_instance": "memorystore",
|
|
139
|
+
"google_spanner_instance": "spanner",
|
|
140
|
+
"google_compute_address": "compute_engine",
|
|
141
|
+
# Azure
|
|
142
|
+
"azurerm_virtual_machine": "virtual_machines",
|
|
143
|
+
"azurerm_linux_virtual_machine": "virtual_machines",
|
|
144
|
+
"azurerm_windows_virtual_machine": "virtual_machines",
|
|
145
|
+
"azurerm_kubernetes_cluster": "aks",
|
|
146
|
+
"azurerm_function_app": "azure_functions",
|
|
147
|
+
"azurerm_mssql_server": "azure_sql",
|
|
148
|
+
"azurerm_mssql_database": "azure_sql",
|
|
149
|
+
"azurerm_cosmosdb_account": "cosmos_db",
|
|
150
|
+
"azurerm_storage_account": "blob_storage",
|
|
151
|
+
"azurerm_redis_cache": "azure_cache",
|
|
152
|
+
"azurerm_application_gateway": "app_gateway",
|
|
153
|
+
"azurerm_lb": "azure_lb",
|
|
154
|
+
"azurerm_cdn_profile": "azure_cdn",
|
|
155
|
+
"azurerm_servicebus_namespace": "service_bus",
|
|
156
|
+
"azurerm_eventhub_namespace": "event_hubs",
|
|
157
|
+
}
|
|
158
|
+
|
|
84
159
|
_REGISTRY_DIR = Path(__file__).parent.parent / "data" / "registry"
|
|
85
160
|
|
|
86
161
|
|
|
@@ -120,7 +195,8 @@ class TerraformStateImporter:
|
|
|
120
195
|
"""Parses Terraform state files (v3 and v4) into ArchSpec."""
|
|
121
196
|
|
|
122
197
|
def __init__(self) -> None:
|
|
123
|
-
self._tf_map =
|
|
198
|
+
self._tf_map = dict(_HARDCODED_TF_MAP) # start with hardcoded fallbacks
|
|
199
|
+
self._tf_map.update(_build_terraform_map()) # registry overrides take precedence
|
|
124
200
|
|
|
125
201
|
@property
|
|
126
202
|
def format_name(self) -> str:
|
|
@@ -166,7 +166,7 @@ class TestInlineTemplate:
|
|
|
166
166
|
"AWSTemplateFormatVersion": "2010-09-09",
|
|
167
167
|
"Resources": {
|
|
168
168
|
"CustomResource": {"Type": "Custom::MyThing", "Properties": {}},
|
|
169
|
-
"
|
|
169
|
+
"UnknownWidget": {"Type": "AWS::Foo::Bar", "Properties": {}},
|
|
170
170
|
"Web": {"Type": "AWS::EC2::Instance", "Properties": {}},
|
|
171
171
|
},
|
|
172
172
|
}
|
|
@@ -174,6 +174,6 @@ class TestInlineTemplate:
|
|
|
174
174
|
p.write_text(json.dumps(template))
|
|
175
175
|
|
|
176
176
|
spec = import_spec(str(p), fmt="cloudformation")
|
|
177
|
-
#
|
|
177
|
+
# Custom::* and unknown AWS types should be skipped
|
|
178
178
|
assert len(spec.components) == 1
|
|
179
179
|
assert spec.components[0].service == "ec2"
|
|
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
|
|
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
|
{cloudwright_ai-0.3.2 → cloudwright_ai-0.3.4}/cloudwright/data/icons/azure/azure_functions.svg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|