pangea 0.0.57 → 0.1.0
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.
- checksums.yaml +4 -4
- data/.claude/skills/pangea-cloud-resource-creation/SKILL.md +169 -0
- data/.claude/skills/pangea-cloud-resource-creation/references/hetzner-volume-example.md +133 -0
- data/.claude/skills/pangea-cloud-resource-creation/references/patterns-antipatterns.md +149 -0
- data/.claude/skills/pangea-cloud-resource-creation/references/resource-templates.md +288 -0
- data/.claude/skills/pangea-cloud-resource-creation/references/tracker-cli.md +77 -0
- data/.claude/skills/pangea-cloud-resource-creation/references/type-system.md +105 -0
- data/.claude/skills/pangea-infrastructure/SKILL.md +300 -0
- data/.claude/skills/pangea-infrastructure/references/kubernetes-integration.md +149 -0
- data/.claude/skills/pangea-infrastructure/references/resource-patterns.md +206 -0
- data/.claude/skills/pangea-infrastructure/references/troubleshooting.md +86 -0
- data/.claude/skills/pangea-infrastructure/references/workflow-examples.md +98 -0
- data/.claude/skills/pangea-refactoring/SKILL.md +478 -0
- data/.claude/skills/pangea-resource-testing/SKILL.md +256 -0
- data/.claude/skills/pangea-rspec-resource-testing/SKILL.md +258 -0
- data/.claude/skills/pangea-rspec-resource-testing/references/cloudflare-zone-example.md +57 -0
- data/.claude/skills/pangea-rspec-resource-testing/references/common-patterns.md +109 -0
- data/.claude/skills/pangea-rspec-resource-testing/references/debugging.md +63 -0
- data/.claude/skills/pangea-rspec-resource-testing/references/integration-tests.md +55 -0
- data/.claude/skills/pangea-rspec-resource-testing/references/synthesis-tests.md +169 -0
- data/.claude/skills/pangea-rspec-resource-testing/references/troubleshooting.md +129 -0
- data/.claude/skills/pangea-rspec-resource-testing/references/type-validation-tests.md +92 -0
- data/.github/ISSUE_TEMPLATE/bug_report.yml +114 -0
- data/.github/ISSUE_TEMPLATE/feature_request.yml +67 -0
- data/.github/ISSUE_TEMPLATE/question.yml +44 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +69 -0
- data/.github/workflows/ci.yml +80 -0
- data/.github/workflows/release.yml +43 -0
- data/.gitignore +89 -1
- data/.rspec_status +278 -0
- data/AGENT_GUIDE.md +349 -0
- data/CHANGELOG.md +67 -0
- data/CONTRIBUTING.md +143 -0
- data/Dockerfile +20 -4
- data/EXAMPLES.md +376 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +252 -70
- data/LICENSE +1 -1
- data/README.md +217 -40
- data/README_backend_configuration.md +181 -0
- data/Rakefile +146 -23
- data/SECURITY.md +90 -0
- data/Steepfile +33 -0
- data/bin/generate-hetzner-resource +204 -0
- data/bin/hetzner-tracker +280 -0
- data/bin/pangea +15 -2
- data/bin/pangea-compiler +15 -0
- data/bin/pangea-compiler-server +133 -0
- data/docker-compose.test.yml +31 -0
- data/docs/KUBERNETES_OPERATOR_PLAN.md +2626 -0
- data/docs/RESOURCES.md +456 -0
- data/exe/pangea +37 -0
- data/flake.lock +751 -9
- data/flake.nix +346 -6
- data/gemset.nix +620 -103
- data/guides/README.md +157 -0
- data/guides/advanced-patterns.md +1196 -0
- data/guides/cicd-integration.md +1047 -0
- data/guides/getting-started.md +399 -0
- data/guides/migration-from-terraform.md +924 -0
- data/guides/multi-environment-management.md +769 -0
- data/guides/template-isolation.md +673 -0
- data/guides/type-safe-infrastructure.md +695 -0
- data/lib/pangea/agent/analysis.rb +128 -0
- data/lib/pangea/agent/compilation.rb +62 -0
- data/lib/pangea/agent/helpers.rb +29 -0
- data/lib/pangea/agent/listing.rb +108 -0
- data/lib/pangea/agent.rb +30 -0
- data/lib/pangea/architecture_registry.rb +94 -0
- data/lib/pangea/architectures.rb +24 -0
- data/lib/pangea/backends/base.rb +77 -0
- data/lib/pangea/backends/local.rb +159 -0
- data/lib/pangea/backends/s3/dynamodb_lock.rb +115 -0
- data/lib/pangea/backends/s3.rb +129 -0
- data/lib/pangea/backends.rb +51 -0
- data/lib/pangea/cli/application/command_router.rb +143 -0
- data/lib/pangea/cli/application/options.rb +128 -0
- data/lib/pangea/cli/application.rb +130 -0
- data/lib/pangea/cli/commands/agent/analysis.rb +107 -0
- data/lib/pangea/cli/commands/agent/complexity.rb +67 -0
- data/lib/pangea/cli/commands/agent/cost.rb +59 -0
- data/lib/pangea/cli/commands/agent/dependencies.rb +63 -0
- data/lib/pangea/cli/commands/agent/explanation.rb +81 -0
- data/lib/pangea/cli/commands/agent/security.rb +69 -0
- data/lib/pangea/cli/commands/agent/suggestions.rb +55 -0
- data/lib/pangea/cli/commands/agent/validation.rb +77 -0
- data/lib/pangea/cli/commands/agent.rb +85 -0
- data/lib/pangea/cli/commands/apply.rb +116 -0
- data/lib/pangea/cli/commands/base_command.rb +120 -0
- data/lib/pangea/cli/commands/destroy.rb +112 -0
- data/lib/pangea/cli/commands/import/import_command_generator.rb +71 -0
- data/lib/pangea/cli/commands/import/resource_analyzer.rb +72 -0
- data/lib/pangea/cli/commands/import.rb +146 -0
- data/lib/pangea/cli/commands/init.rb +92 -0
- data/lib/pangea/cli/commands/inspect/config_inspection.rb +130 -0
- data/lib/pangea/cli/commands/inspect/resource_inspection.rb +105 -0
- data/lib/pangea/cli/commands/inspect/template_analysis.rb +124 -0
- data/lib/pangea/cli/commands/inspect.rb +95 -0
- data/lib/pangea/cli/commands/new_project.rb +266 -0
- data/lib/pangea/cli/commands/plan.rb +93 -0
- data/lib/pangea/cli/commands/sync.rb +95 -0
- data/lib/pangea/cli/error_handler.rb +169 -0
- data/lib/pangea/cli/errors.rb +57 -0
- data/lib/pangea/cli/formatters/json_formatter.rb +195 -0
- data/lib/pangea/cli/presenters/apply_presenter.rb +264 -0
- data/lib/pangea/cli/presenters/base_presenter.rb +142 -0
- data/lib/pangea/cli/presenters/destroy_presenter.rb +100 -0
- data/lib/pangea/cli/presenters/plan_presenter.rb +456 -0
- data/lib/pangea/cli/services/template_service.rb +96 -0
- data/lib/pangea/cli/services/workspace_service.rb +94 -0
- data/lib/pangea/cli/ui/README.md +255 -0
- data/lib/pangea/cli/ui/banner/operation_summary.rb +106 -0
- data/lib/pangea/cli/ui/banner.rb +80 -0
- data/lib/pangea/cli/ui/diff/formatting.rb +53 -0
- data/lib/pangea/cli/ui/diff/plan_parser.rb +84 -0
- data/lib/pangea/cli/ui/diff.rb +147 -0
- data/lib/pangea/cli/ui/logger/display_helpers.rb +87 -0
- data/lib/pangea/cli/ui/logger/info_panels.rb +88 -0
- data/lib/pangea/cli/ui/logger/resource_display.rb +54 -0
- data/lib/pangea/cli/ui/logger/styles.rb +21 -0
- data/lib/pangea/cli/ui/logger.rb +83 -0
- data/lib/pangea/cli/ui/output_formatter/constants.rb +22 -0
- data/lib/pangea/cli/ui/output_formatter/display.rb +157 -0
- data/lib/pangea/cli/ui/output_formatter/formatting.rb +44 -0
- data/lib/pangea/cli/ui/output_formatter.rb +23 -0
- data/lib/pangea/cli/ui/progress/animations.rb +69 -0
- data/lib/pangea/cli/ui/progress/wrappers.rb +100 -0
- data/lib/pangea/cli/ui/progress.rb +78 -0
- data/lib/pangea/cli/ui/spinner.rb +147 -0
- data/lib/pangea/cli/ui/table/formatters.rb +125 -0
- data/lib/pangea/cli/ui/table.rb +114 -0
- data/lib/pangea/cli/ui/visualizer/cost.rb +37 -0
- data/lib/pangea/cli/ui/visualizer/display.rb +92 -0
- data/lib/pangea/cli/ui/visualizer/graph.rb +89 -0
- data/lib/pangea/cli/ui/visualizer/statistics.rb +58 -0
- data/lib/pangea/cli/ui/visualizer.rb +167 -0
- data/lib/pangea/compilation/backend_injector.rb +78 -0
- data/lib/pangea/compilation/compilation_helpers.rb +128 -0
- data/lib/pangea/compilation/template_compiler.rb +123 -0
- data/lib/pangea/compilation/template_extractor.rb +81 -0
- data/lib/pangea/compilation/template_validator.rb +47 -0
- data/lib/pangea/compilation/validator.rb +133 -0
- data/lib/pangea/components.rb +27 -0
- data/lib/pangea/configuration/config_loader.rb +86 -0
- data/lib/pangea/configuration/defaults.rb +58 -0
- data/lib/pangea/configuration/namespace_manager.rb +95 -0
- data/lib/pangea/configuration/types/backends.rb +95 -0
- data/lib/pangea/configuration/types/base.rb +33 -0
- data/lib/pangea/configuration/types/configuration_schema.rb +105 -0
- data/lib/pangea/configuration/types/settings.rb +56 -0
- data/lib/pangea/configuration/types/state.rb +91 -0
- data/lib/pangea/configuration/types.rb +21 -0
- data/lib/pangea/configuration.rb +108 -0
- data/lib/pangea/entities.rb +18 -0
- data/lib/pangea/execution/terraform_command_builder.rb +87 -0
- data/lib/pangea/execution/terraform_command_executor.rb +152 -0
- data/lib/pangea/execution/terraform_executor.rb +140 -0
- data/lib/pangea/execution/terraform_operations.rb +91 -0
- data/lib/pangea/execution/terraform_output_parser.rb +129 -0
- data/lib/pangea/execution/terraform_retry.rb +99 -0
- data/lib/pangea/execution/workspace_manager.rb +164 -0
- data/lib/pangea/resources/templates/resource_template.rb.erb +56 -0
- data/lib/pangea/resources/validators/shared_validators.rb +48 -0
- data/lib/pangea/resources.rb +20 -0
- data/lib/pangea/types.rb +64 -0
- data/lib/pangea/utilities/cli/README.md +11 -0
- data/lib/pangea/utilities/cli/command.rb +98 -0
- data/lib/pangea/utilities/cli/commands/cost_command.rb +117 -0
- data/lib/pangea/utilities/cli/commands/drift_command.rb +127 -0
- data/lib/pangea/utilities/cli/commands/state_command.rb +119 -0
- data/lib/pangea/utilities/cost/README.md +12 -0
- data/lib/pangea/utilities/cost/calculator.rb +174 -0
- data/lib/pangea/utilities/cost.rb +29 -0
- data/lib/pangea/utilities/drift/README.md +12 -0
- data/lib/pangea/utilities/drift/detector.rb +122 -0
- data/lib/pangea/utilities/drift/report.rb +100 -0
- data/lib/pangea/utilities/drift.rb +29 -0
- data/lib/pangea/utilities/ip_discovery.rb +109 -0
- data/lib/pangea/utilities/remote_state/README.md +12 -0
- data/lib/pangea/utilities/remote_state/dependency_manager.rb +99 -0
- data/lib/pangea/utilities/remote_state/dsl_extensions.rb +109 -0
- data/lib/pangea/utilities/remote_state/output_registry.rb +119 -0
- data/lib/pangea/utilities/remote_state/reference.rb +77 -0
- data/lib/pangea/utilities/remote_state.rb +28 -0
- data/lib/pangea/utilities/visualization/README.md +12 -0
- data/lib/pangea/utilities/visualization/graph.rb +112 -0
- data/lib/pangea/utilities/visualization/mermaid_exporter.rb +149 -0
- data/lib/pangea/utilities/visualization.rb +28 -0
- data/lib/pangea/utilities.rb +34 -0
- data/lib/pangea/version.rb +15 -1
- data/lib/pangea.rb +38 -16
- data/pangea.gemspec +39 -34
- data/pangea.rb +14 -0
- data/pangea.yaml.example +87 -0
- data/pangea.yml.example +76 -0
- data/pkgs/products/pangea/deploy/configmap.yaml +67 -0
- data/pkgs/products/pangea/deploy/crds/infrastructuretemplates.yaml +395 -0
- data/pkgs/products/pangea/deploy/crds/pangeanamespaces.yaml +286 -0
- data/pkgs/products/pangea/deploy/kustomization.yaml +54 -0
- data/pkgs/products/pangea/deploy/namespace.yaml +6 -0
- data/pkgs/products/pangea/deploy/operator-deployment.yaml +138 -0
- data/pkgs/products/pangea/deploy/operator-service.yaml +23 -0
- data/pkgs/products/pangea/deploy/rbac/role.yaml +106 -0
- data/pkgs/products/pangea/deploy/rbac/rolebinding.yaml +15 -0
- data/pkgs/products/pangea/deploy/rbac/serviceaccount.yaml +7 -0
- data/pkgs/products/pangea/deploy/web-deployment.yaml +64 -0
- data/pkgs/products/pangea/deploy/web-service.yaml +19 -0
- data/rbs_collection.yaml +37 -0
- data/release.sh +32 -0
- data/scripts/add_copyright_headers.rb +65 -0
- data/scripts/analyze_resource_structure.rb +127 -0
- data/scripts/audit_vpc_resources.rb +36 -0
- data/scripts/discover_resources.rb +53 -0
- data/scripts/find_untested_resources.rb +115 -0
- data/scripts/generate_vpc_tests.rb +21 -0
- data/scripts/prioritize_resources.rb +72 -0
- data/scripts/synthesis_coverage_report.json +3723 -0
- data/scripts/synthesis_coverage_report.rb +284 -0
- data/scripts/synthesis_coverage_summary.rb +233 -0
- data/scripts/synthesis_enhancement_tasks.json +74 -0
- data/scripts/verify_implementation.rb +146 -0
- data/scripts/verify_utilities.rb +185 -0
- data/sig/pangea/architectures.rbs +260 -0
- data/sig/pangea/entities/namespace.rbs +37 -0
- data/sig/pangea/resources/aws.rbs +254 -0
- data/sig/pangea/resources/aws_acm_certificate.rbs +23 -0
- data/sig/pangea/resources/aws_acm_certificate_validation.rbs +20 -0
- data/sig/pangea/resources/aws_api_gateway_deployment.rbs +49 -0
- data/sig/pangea/resources/aws_api_gateway_method.rbs +51 -0
- data/sig/pangea/resources/aws_api_gateway_resource.rbs +33 -0
- data/sig/pangea/resources/aws_api_gateway_rest_api.rbs +60 -0
- data/sig/pangea/resources/aws_api_gateway_stage.rbs +89 -0
- data/sig/pangea/resources/aws_appstream_fleet.rbs +58 -0
- data/sig/pangea/resources/aws_batch_compute_environment.rbs +54 -0
- data/sig/pangea/resources/aws_batch_job_definition.rbs +69 -0
- data/sig/pangea/resources/aws_batch_job_queue.rbs +65 -0
- data/sig/pangea/resources/aws_braket_device.rbs +114 -0
- data/sig/pangea/resources/aws_braket_quantum_task.rbs +32 -0
- data/sig/pangea/resources/aws_budgets_budget.rbs +130 -0
- data/sig/pangea/resources/aws_budgets_budget_action.rbs +95 -0
- data/sig/pangea/resources/aws_cloudfront_cache_policy.rbs +18 -0
- data/sig/pangea/resources/aws_cloudfront_distribution.rbs +124 -0
- data/sig/pangea/resources/aws_cloudfront_origin_access_control.rbs +27 -0
- data/sig/pangea/resources/aws_cloudfront_origin_request_policy.rbs +17 -0
- data/sig/pangea/resources/aws_cloudwatch_composite_alarm.rbs +34 -0
- data/sig/pangea/resources/aws_cloudwatch_dashboard.rbs +69 -0
- data/sig/pangea/resources/aws_cloudwatch_event_rule.rbs +34 -0
- data/sig/pangea/resources/aws_cloudwatch_event_target.rbs +80 -0
- data/sig/pangea/resources/aws_cloudwatch_log_destination.rbs +26 -0
- data/sig/pangea/resources/aws_cloudwatch_log_destination_policy.rbs +27 -0
- data/sig/pangea/resources/aws_cloudwatch_log_group.rbs +28 -0
- data/sig/pangea/resources/aws_cloudwatch_log_metric_filter.rbs +43 -0
- data/sig/pangea/resources/aws_cloudwatch_log_stream.rbs +25 -0
- data/sig/pangea/resources/aws_cloudwatch_log_subscription_filter.rbs +28 -0
- data/sig/pangea/resources/aws_codeartifact_domain.rbs +29 -0
- data/sig/pangea/resources/aws_codeartifact_repository.rbs +46 -0
- data/sig/pangea/resources/aws_codestar_connection.rbs +36 -0
- data/sig/pangea/resources/aws_cognito_identity_pool.rbs +56 -0
- data/sig/pangea/resources/aws_cognito_identity_provider.rbs +46 -0
- data/sig/pangea/resources/aws_cognito_user.rbs +36 -0
- data/sig/pangea/resources/aws_cognito_user_group.rbs +34 -0
- data/sig/pangea/resources/aws_cognito_user_pool.rbs +176 -0
- data/sig/pangea/resources/aws_cognito_user_pool_client.rbs +75 -0
- data/sig/pangea/resources/aws_cognito_user_pool_domain.rbs +46 -0
- data/sig/pangea/resources/aws_datasync_on_snow_location.rbs +12 -0
- data/sig/pangea/resources/aws_datasync_on_snow_task.rbs +12 -0
- data/sig/pangea/resources/aws_datasync_snow_ball_edge.rbs +12 -0
- data/sig/pangea/resources/aws_db_parameter_group.rbs +81 -0
- data/sig/pangea/resources/aws_db_subnet_group.rbs +42 -0
- data/sig/pangea/resources/aws_ec2_carrier_gateway.rbs +12 -0
- data/sig/pangea/resources/aws_ec2_local_gateway.rbs +12 -0
- data/sig/pangea/resources/aws_ec2_local_gateway_route.rbs +12 -0
- data/sig/pangea/resources/aws_ec2_local_gateway_route_table.rbs +12 -0
- data/sig/pangea/resources/aws_ec2_local_gateway_route_table_vpc_association.rbs +12 -0
- data/sig/pangea/resources/aws_ec2_local_gateway_virtual_interface_group_association.rbs +12 -0
- data/sig/pangea/resources/aws_ecr_lifecycle_policy.rbs +28 -0
- data/sig/pangea/resources/aws_ecr_replication_configuration.rbs +42 -0
- data/sig/pangea/resources/aws_ecr_repository.rbs +36 -0
- data/sig/pangea/resources/aws_ecr_repository_policy.rbs +27 -0
- data/sig/pangea/resources/aws_ecs_cluster.rbs +86 -0
- data/sig/pangea/resources/aws_ecs_cluster_capacity_providers.rbs +59 -0
- data/sig/pangea/resources/aws_ecs_service.rbs +238 -0
- data/sig/pangea/resources/aws_ecs_task_definition.rbs +334 -0
- data/sig/pangea/resources/aws_efs_access_point.rbs +33 -0
- data/sig/pangea/resources/aws_efs_file_system.rbs +34 -0
- data/sig/pangea/resources/aws_efs_mount_target.rbs +29 -0
- data/sig/pangea/resources/aws_eks_addon.rbs +50 -0
- data/sig/pangea/resources/aws_eks_cluster.rbs +79 -0
- data/sig/pangea/resources/aws_eks_fargate_profile.rbs +43 -0
- data/sig/pangea/resources/aws_eks_node_group.rbs +106 -0
- data/sig/pangea/resources/aws_elasticache_cluster.rbs +39 -0
- data/sig/pangea/resources/aws_elasticache_parameter_group.rbs +18 -0
- data/sig/pangea/resources/aws_elasticache_subnet_group.rbs +17 -0
- data/sig/pangea/resources/aws_elemental_data_plane_channel.rbs +18 -0
- data/sig/pangea/resources/aws_emrcontainers_virtual_cluster.rbs +39 -0
- data/sig/pangea/resources/aws_frauddetector_detector.rbs +76 -0
- data/sig/pangea/resources/aws_groundstation_antenna_downlink_config.rbs +12 -0
- data/sig/pangea/resources/aws_groundstation_antenna_uplink_config.rbs +12 -0
- data/sig/pangea/resources/aws_groundstation_config.rbs +12 -0
- data/sig/pangea/resources/aws_groundstation_contact.rbs +12 -0
- data/sig/pangea/resources/aws_groundstation_dataflow_endpoint_group.rbs +12 -0
- data/sig/pangea/resources/aws_groundstation_mission_profile.rbs +12 -0
- data/sig/pangea/resources/aws_groundstation_tracking_config.rbs +12 -0
- data/sig/pangea/resources/aws_healthlake_fhir_datastore.rbs +80 -0
- data/sig/pangea/resources/aws_iam_group.rbs +71 -0
- data/sig/pangea/resources/aws_iam_policy.rbs +62 -0
- data/sig/pangea/resources/aws_iam_role_policy_attachment.rbs +88 -0
- data/sig/pangea/resources/aws_iam_user.rbs +56 -0
- data/sig/pangea/resources/aws_kms_alias.rbs +16 -0
- data/sig/pangea/resources/aws_kms_key.rbs +23 -0
- data/sig/pangea/resources/aws_lambda_event_source_mapping.rbs +116 -0
- data/sig/pangea/resources/aws_lambda_function.rbs +137 -0
- data/sig/pangea/resources/aws_lambda_layer_version.rbs +48 -0
- data/sig/pangea/resources/aws_lambda_permission.rbs +44 -0
- data/sig/pangea/resources/aws_lightsail_bucket.rbs +12 -0
- data/sig/pangea/resources/aws_lightsail_certificate.rbs +12 -0
- data/sig/pangea/resources/aws_lightsail_database.rbs +12 -0
- data/sig/pangea/resources/aws_lightsail_disk.rbs +12 -0
- data/sig/pangea/resources/aws_lightsail_disk_attachment.rbs +12 -0
- data/sig/pangea/resources/aws_lightsail_domain.rbs +12 -0
- data/sig/pangea/resources/aws_lightsail_instance.rbs +12 -0
- data/sig/pangea/resources/aws_lightsail_key_pair.rbs +12 -0
- data/sig/pangea/resources/aws_lightsail_load_balancer.rbs +12 -0
- data/sig/pangea/resources/aws_lightsail_load_balancer_attachment.rbs +12 -0
- data/sig/pangea/resources/aws_lightsail_static_ip.rbs +12 -0
- data/sig/pangea/resources/aws_lightsail_static_ip_attachment.rbs +12 -0
- data/sig/pangea/resources/aws_lookoutequipment_dataset.rbs +73 -0
- data/sig/pangea/resources/aws_managedblockchain_member.rbs +73 -0
- data/sig/pangea/resources/aws_managedblockchain_network.rbs +102 -0
- data/sig/pangea/resources/aws_managedblockchain_node.rbs +71 -0
- data/sig/pangea/resources/aws_media_convert_queue.rbs +20 -0
- data/sig/pangea/resources/aws_media_live_channel.rbs +67 -0
- data/sig/pangea/resources/aws_media_live_input.rbs +68 -0
- data/sig/pangea/resources/aws_media_package_channel.rbs +35 -0
- data/sig/pangea/resources/aws_media_package_origin_endpoint.rbs +29 -0
- data/sig/pangea/resources/aws_media_store_container.rbs +13 -0
- data/sig/pangea/resources/aws_outposts_asset.rbs +12 -0
- data/sig/pangea/resources/aws_outposts_capacity_task.rbs +12 -0
- data/sig/pangea/resources/aws_outposts_connection.rbs +12 -0
- data/sig/pangea/resources/aws_outposts_order.rbs +12 -0
- data/sig/pangea/resources/aws_outposts_outpost.rbs +12 -0
- data/sig/pangea/resources/aws_outposts_outpost_instance_type.rbs +12 -0
- data/sig/pangea/resources/aws_outposts_site.rbs +12 -0
- data/sig/pangea/resources/aws_outposts_supported_hardware_type.rbs +12 -0
- data/sig/pangea/resources/aws_qldb_ledger.rbs +37 -0
- data/sig/pangea/resources/aws_qldb_stream.rbs +53 -0
- data/sig/pangea/resources/aws_rds_cluster.rbs +193 -0
- data/sig/pangea/resources/aws_rds_cluster_instance.rbs +128 -0
- data/sig/pangea/resources/aws_route53_health_check.rbs +34 -0
- data/sig/pangea/resources/aws_route53_record.rbs +63 -0
- data/sig/pangea/resources/aws_route53_zone.rbs +26 -0
- data/sig/pangea/resources/aws_s3_bucket_cors_configuration.rbs +42 -0
- data/sig/pangea/resources/aws_s3_bucket_inventory.rbs +78 -0
- data/sig/pangea/resources/aws_s3_bucket_lifecycle_configuration.rbs +94 -0
- data/sig/pangea/resources/aws_s3_bucket_notification.rbs +65 -0
- data/sig/pangea/resources/aws_s3_bucket_object_lock_configuration.rbs +51 -0
- data/sig/pangea/resources/aws_s3_bucket_replication_configuration.rbs +107 -0
- data/sig/pangea/resources/aws_s3_bucket_website_configuration.rbs +74 -0
- data/sig/pangea/resources/aws_sagemaker_feature_group.rbs +58 -0
- data/sig/pangea/resources/aws_secretsmanager_secret.rbs +29 -0
- data/sig/pangea/resources/aws_secretsmanager_secret_version.rbs +21 -0
- data/sig/pangea/resources/aws_sfn_activity.rbs +36 -0
- data/sig/pangea/resources/aws_sfn_state_machine.rbs +54 -0
- data/sig/pangea/resources/aws_snowball_cluster.rbs +12 -0
- data/sig/pangea/resources/aws_snowball_job.rbs +12 -0
- data/sig/pangea/resources/aws_snowcone_device.rbs +12 -0
- data/sig/pangea/resources/aws_snowcone_job.rbs +12 -0
- data/sig/pangea/resources/aws_snowmobile_job.rbs +12 -0
- data/sig/pangea/resources/aws_sns_subscription.rbs +49 -0
- data/sig/pangea/resources/aws_sns_topic.rbs +78 -0
- data/sig/pangea/resources/aws_sqs_queue.rbs +67 -0
- data/sig/pangea/resources/aws_sqs_queue_policy.rbs +29 -0
- data/sig/pangea/resources/aws_wavelength_application_deployment.rbs +12 -0
- data/sig/pangea/resources/aws_wavelength_deployment.rbs +12 -0
- data/sig/pangea/resources/aws_wavelength_edge_location_mapping.rbs +12 -0
- data/sig/pangea/resources/aws_wavelength_network_interface.rbs +12 -0
- data/sig/pangea/resources/aws_wavelength_workload.rbs +12 -0
- data/sig/pangea/resources/aws_workspaces_bundle.rbs +50 -0
- data/sig/pangea/resources/aws_workspaces_directory.rbs +63 -0
- data/sig/pangea/resources/aws_workspaces_ip_group.rbs +41 -0
- data/sig/pangea/resources/aws_workspaces_workspace.rbs +40 -0
- data/sig/pangea/structures/namespace.rbs +28 -0
- data/sig/pangea/structures/project.rbs +20 -0
- data/sig/pangea/types.rbs +76 -0
- data/sig/pangea.rbs +13 -0
- data/synthesizer-tests.yaml +72 -0
- data/test_infrastructure/infrastructure.rb +510 -0
- data/test_infrastructure/main.tf.json +15 -0
- data/test_infrastructure/multi_template_infrastructure.rb +125 -0
- data/test_infrastructure/pangea.yml +35 -0
- data/test_infrastructure/simple_infrastructure.rb +82 -0
- data/test_infrastructure/test_multi_workspaces.rb +90 -0
- data/test_infrastructure/test_template_workspaces.rb +62 -0
- data/test_infrastructure/workspace_compute.tf.json +46 -0
- data/test_infrastructure/workspace_local_resources.tf.json +41 -0
- data/test_infrastructure/workspace_networking.tf.json +32 -0
- data/test_infrastructure/workspace_storage.tf.json +34 -0
- metadata +673 -147
- data/example/config/README.md +0 -3
- data/example/config/sample.rb +0 -20
- data/lib/pangea/cli/config.rb +0 -99
- data/lib/pangea/cli/constants.rb +0 -33
- data/lib/pangea/cli/subcommands/config.rb +0 -212
- data/lib/pangea/cli/subcommands/infra.rb +0 -311
- data/lib/pangea/cli/subcommands/main.rb +0 -58
- data/lib/pangea/cli/subcommands/pangea.rb +0 -18
- data/lib/pangea/cli/subcommands/state.rb +0 -30
- data/lib/pangea/cli.rb +0 -73
- data/lib/pangea/config.rb +0 -35
- data/lib/pangea/docker.rb +0 -104
- data/lib/pangea/errors/incorrect_subcommand_error.rb +0 -2
- data/lib/pangea/errors/namespace_not_found_error.rb +0 -2
- data/lib/pangea/errors/no_infra_target_error.rb +0 -2
- data/lib/pangea/errors/project_not_found_error.rb +0 -2
- data/lib/pangea/errors/site_not_found_error.rb +0 -2
- data/lib/pangea/executor.rb +0 -10
- data/lib/pangea/log/init.rb +0 -2
- data/lib/pangea/modcache.rb +0 -79
- data/lib/pangea/module.rb +0 -17
- data/lib/pangea/modules.rb +0 -134
- data/lib/pangea/processor.rb +0 -104
- data/lib/pangea/renderer.rb +0 -85
- data/lib/pangea/sandbox.rb +0 -90
- data/lib/pangea/say/init.rb +0 -27
- data/lib/pangea/shell/README.md +0 -1
- data/lib/pangea/shell/terraform.rb +0 -21
- data/lib/pangea/shell.rb +0 -27
- data/lib/pangea/stack.rb +0 -11
- data/lib/pangea/state.rb +0 -96
- data/lib/pangea/structures/README.md +0 -3
- data/lib/pangea/structures/abstract.rb +0 -2
- data/lib/pangea/structures/namespace.rb +0 -4
- data/lib/pangea/structures/project.rb +0 -4
- data/lib/pangea/structures/site.rb +0 -4
- data/lib/pangea/synthesizer/config.rb +0 -38
- data/lib/pangea/utils.rb +0 -32
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4ea21a75b0c516b27bb6a7bd07273509323c5343809d5b0379e17842e2952e05
|
|
4
|
+
data.tar.gz: 0e5f2f1bcd36111e0bb22a62e5689e60063aeef306fb7ee1f27a1da8e03e4c65
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c8a3df832621cbf6f8703b2f0285e0df4bec5b923ce6e88084d1b4658434437379d7f849adc3c1ad75f2c164562e5507686d6c01dcc8434b8a87b37afe2f7ee5
|
|
7
|
+
data.tar.gz: 99eea2be7e31503322c467f69483e6d70ccd578fbcc0cf6924a9e83bfc6da75f233961d7806afd60ec23a980293c2817d54853149d2caed360846d2fa55abdd5
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pangea-cloud-resource-creation
|
|
3
|
+
description: Creates cloud provider resources for Pangea using Dry::Struct types, terraform-synthesizer integration, and RSpec tests. Use when adding support for new cloud providers (AWS, Hetzner, Cloudflare, GCP, Azure, DigitalOcean, etc.) to Pangea. Covers type definitions, resource functions, synthesis specs, tracker creation, and batch implementation patterns. Apply when implementing resources from provider documentation, adding new cloud integrations, or standardizing resource creation workflows.
|
|
4
|
+
metadata:
|
|
5
|
+
version: "1.0.0"
|
|
6
|
+
last_verified: "2025-12-27"
|
|
7
|
+
research_version: "2025-12-27"
|
|
8
|
+
domain_keywords:
|
|
9
|
+
- "terraform"
|
|
10
|
+
- "cloud-providers"
|
|
11
|
+
- "infrastructure-as-code"
|
|
12
|
+
- "resource-synthesis"
|
|
13
|
+
- "ruby-infrastructure"
|
|
14
|
+
- "dry-struct"
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Pangea Cloud Provider Resource Creation
|
|
18
|
+
|
|
19
|
+
## Overview
|
|
20
|
+
|
|
21
|
+
Standardized pattern for adding cloud provider resources to Pangea. Production-tested with Cloudflare (29 resources) and Hetzner Cloud (25 resources).
|
|
22
|
+
|
|
23
|
+
**Location**: `pkgs/tools/ruby/pangea/`
|
|
24
|
+
|
|
25
|
+
## Core Pattern
|
|
26
|
+
|
|
27
|
+
Each cloud provider resource requires **exactly three files**:
|
|
28
|
+
|
|
29
|
+
| File | Location | Purpose |
|
|
30
|
+
|------|----------|---------|
|
|
31
|
+
| `types.rb` | `lib/pangea/resources/{resource}/types.rb` | Dry::Struct attribute validation |
|
|
32
|
+
| `resource.rb` | `lib/pangea/resources/{resource}/resource.rb` | terraform-synthesizer + ResourceReference |
|
|
33
|
+
| `synthesis_spec.rb` | `spec/resources/{resource}/synthesis_spec.rb` | RSpec tests for Terraform JSON |
|
|
34
|
+
|
|
35
|
+
**Critical**: All three files must follow exact patterns. Deviations break synthesis or testing.
|
|
36
|
+
|
|
37
|
+
## File Structure
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
pkgs/tools/ruby/pangea/
|
|
41
|
+
├── lib/pangea/resources/
|
|
42
|
+
│ ├── types.rb # Central type definitions for ALL providers
|
|
43
|
+
│ ├── {resource_name}/
|
|
44
|
+
│ │ ├── types.rb # Resource-specific Dry::Struct
|
|
45
|
+
│ │ └── resource.rb # Resource function
|
|
46
|
+
├── spec/resources/
|
|
47
|
+
│ └── {resource_name}/
|
|
48
|
+
│ └── synthesis_spec.rb # Synthesis tests
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Implementation Workflow
|
|
52
|
+
|
|
53
|
+
### Phase 1: Planning
|
|
54
|
+
|
|
55
|
+
1. **Research** - Review Terraform provider documentation
|
|
56
|
+
2. **Create Tracker** - `PROVIDER_IMPLEMENTATION.json` with batches
|
|
57
|
+
3. **Design Types** - Add provider types to central `types.rb`
|
|
58
|
+
|
|
59
|
+
### Phase 2: Resource Implementation
|
|
60
|
+
|
|
61
|
+
For each resource, create the three required files:
|
|
62
|
+
|
|
63
|
+
1. **types.rb** - Dry::Struct with `transform_keys(&:to_sym)`
|
|
64
|
+
2. **resource.rb** - Resource function with conditionals for optional fields
|
|
65
|
+
3. **synthesis_spec.rb** - Tests with `TerraformSynthesizer.new`
|
|
66
|
+
|
|
67
|
+
### Phase 3: Batch Execution
|
|
68
|
+
|
|
69
|
+
1. Implement all types first
|
|
70
|
+
2. Complete each batch (all 3 files per resource)
|
|
71
|
+
3. Update tracker: `bin/tracker update resource_name all`
|
|
72
|
+
4. Commit with batch completion message
|
|
73
|
+
|
|
74
|
+
## Quick Reference
|
|
75
|
+
|
|
76
|
+
### Attribute Patterns (types.rb)
|
|
77
|
+
|
|
78
|
+
| Pattern | Syntax |
|
|
79
|
+
|---------|--------|
|
|
80
|
+
| Required | `attribute :name, Type` |
|
|
81
|
+
| Optional with default | `attribute :name, Type.default(value)` |
|
|
82
|
+
| Optional no default | `attribute :name, Type.optional.default(nil)` |
|
|
83
|
+
| Arrays | `attribute :items, Array.of(Type).default([].freeze)` |
|
|
84
|
+
| Hashes | `attribute :labels, Hash.default({}.freeze)` |
|
|
85
|
+
|
|
86
|
+
### Resource Patterns (resource.rb)
|
|
87
|
+
|
|
88
|
+
| Pattern | Syntax |
|
|
89
|
+
|---------|--------|
|
|
90
|
+
| Required field | `field_name attrs.field` |
|
|
91
|
+
| Optional field | `field_name attrs.field if attrs.field` |
|
|
92
|
+
| Default field | `field_name attrs.field` (always include) |
|
|
93
|
+
| Nested block | `block_name do ... end` inside conditional |
|
|
94
|
+
| Array blocks | `attrs.items.each do \|item\| ... end` |
|
|
95
|
+
|
|
96
|
+
### Test Requirements (synthesis_spec.rb)
|
|
97
|
+
|
|
98
|
+
- Basic resource with defaults
|
|
99
|
+
- Resource with all options
|
|
100
|
+
- Nested blocks/arrays
|
|
101
|
+
- Resource references (interpolation)
|
|
102
|
+
- Resource composition (parent-child)
|
|
103
|
+
|
|
104
|
+
## Decision Table
|
|
105
|
+
|
|
106
|
+
| Scenario | Action |
|
|
107
|
+
|----------|--------|
|
|
108
|
+
| Add new cloud provider | Create tracker, implement all batches |
|
|
109
|
+
| Add single resource | Create 3 files, update tracker |
|
|
110
|
+
| Review implementation | Check against anti-patterns |
|
|
111
|
+
| Debug synthesis | Run individual spec, check conditionals |
|
|
112
|
+
| Type validation error | Check `transform_keys`, attribute syntax |
|
|
113
|
+
|
|
114
|
+
## Anti-Patterns (Quick Check)
|
|
115
|
+
|
|
116
|
+
| Issue | Fix |
|
|
117
|
+
|-------|-----|
|
|
118
|
+
| Missing `transform_keys(&:to_sym)` | Add to Dry::Struct class |
|
|
119
|
+
| Hardcoded values in resource | Use `attrs.field` |
|
|
120
|
+
| Optional without conditional | Add `if attrs.field` |
|
|
121
|
+
| Missing auto-registration | Add `ResourceRegistry.register_module(...)` |
|
|
122
|
+
| Tests without synthesizer | Use `TerraformSynthesizer.new` |
|
|
123
|
+
|
|
124
|
+
## Testing
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
cd pkgs/tools/ruby/pangea
|
|
128
|
+
|
|
129
|
+
# Single resource
|
|
130
|
+
rspec spec/resources/hcloud_volume/synthesis_spec.rb
|
|
131
|
+
|
|
132
|
+
# All provider resources
|
|
133
|
+
rspec spec/resources/hcloud_*
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## When to Use This Skill
|
|
137
|
+
|
|
138
|
+
- Adding new cloud provider to Pangea
|
|
139
|
+
- Implementing resources from Terraform provider docs
|
|
140
|
+
- Creating resource tracker for new provider
|
|
141
|
+
- Reviewing resource implementation quality
|
|
142
|
+
- User asks: "add support for {cloud provider}"
|
|
143
|
+
- User asks: "implement {terraform resource}"
|
|
144
|
+
|
|
145
|
+
## Success Criteria
|
|
146
|
+
|
|
147
|
+
- 100% resource coverage for target provider
|
|
148
|
+
- All resources follow three-file pattern
|
|
149
|
+
- All tests use terraform-synthesizer
|
|
150
|
+
- ResourceReference enables composition
|
|
151
|
+
- Tracker shows 100% completion
|
|
152
|
+
|
|
153
|
+
## Detailed References
|
|
154
|
+
|
|
155
|
+
| Reference | Content |
|
|
156
|
+
|-----------|---------|
|
|
157
|
+
| [{baseDir}/references/resource-templates.md](references/resource-templates.md) | Full templates for types.rb, resource.rb, synthesis_spec.rb |
|
|
158
|
+
| [{baseDir}/references/type-system.md](references/type-system.md) | Type definitions, categories, tracker JSON template |
|
|
159
|
+
| [{baseDir}/references/hetzner-volume-example.md](references/hetzner-volume-example.md) | Complete end-to-end implementation example |
|
|
160
|
+
| [{baseDir}/references/tracker-cli.md](references/tracker-cli.md) | Tracker CLI script implementation |
|
|
161
|
+
| [{baseDir}/references/patterns-antipatterns.md](references/patterns-antipatterns.md) | Common patterns, anti-patterns, testing, git workflow |
|
|
162
|
+
|
|
163
|
+
## Related Resources
|
|
164
|
+
|
|
165
|
+
- **Hetzner Implementation**: 25 resources (100% complete)
|
|
166
|
+
- **Cloudflare Implementation**: 29 resources (100% complete)
|
|
167
|
+
- **Type System**: `lib/pangea/resources/types.rb`
|
|
168
|
+
- **Synthesizer**: `lib/terraform-synthesizer.rb`
|
|
169
|
+
- **Testing Skill**: `.claude/skills/pangea-rspec-resource-testing.md`
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Complete Example: Hetzner Volume
|
|
2
|
+
|
|
3
|
+
End-to-end implementation of `hcloud_volume` resource.
|
|
4
|
+
|
|
5
|
+
## 1. Type Definition in types.rb
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
# lib/pangea/resources/types.rb (ADD at end before closing 'end')
|
|
9
|
+
|
|
10
|
+
# Hetzner volume filesystem formats
|
|
11
|
+
HetznerVolumeFormat = String.enum('xfs', 'ext4')
|
|
12
|
+
|
|
13
|
+
# Hetzner volume size validation (10-10000 GB)
|
|
14
|
+
HetznerVolumeSize = Integer.constrained(gteq: 10, lteq: 10000)
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 2. Resource Types
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
# lib/pangea/resources/hcloud_volume/types.rb
|
|
21
|
+
# frozen_string_literal: true
|
|
22
|
+
# Copyright 2025 The Pangea Authors
|
|
23
|
+
|
|
24
|
+
require 'dry-struct'
|
|
25
|
+
require 'pangea/resources/types'
|
|
26
|
+
|
|
27
|
+
module Pangea
|
|
28
|
+
module Resources
|
|
29
|
+
module Hetzner
|
|
30
|
+
module Types
|
|
31
|
+
class VolumeAttributes < Dry::Struct
|
|
32
|
+
transform_keys(&:to_sym)
|
|
33
|
+
|
|
34
|
+
# Required
|
|
35
|
+
attribute :name, Resources::Types::String
|
|
36
|
+
attribute :size, HetznerVolumeSize
|
|
37
|
+
|
|
38
|
+
# Optional
|
|
39
|
+
attribute :location, HetznerLocation.optional.default(nil)
|
|
40
|
+
attribute :format, HetznerVolumeFormat.optional.default(nil)
|
|
41
|
+
attribute :labels, HetznerLabels.default({}.freeze)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 3. Resource Function
|
|
50
|
+
|
|
51
|
+
```ruby
|
|
52
|
+
# lib/pangea/resources/hcloud_volume/resource.rb
|
|
53
|
+
# frozen_string_literal: true
|
|
54
|
+
# Copyright 2025 The Pangea Authors
|
|
55
|
+
|
|
56
|
+
require 'pangea/resources/base'
|
|
57
|
+
require 'pangea/resources/reference'
|
|
58
|
+
require 'pangea/resources/hcloud_volume/types'
|
|
59
|
+
require 'pangea/resource_registry'
|
|
60
|
+
|
|
61
|
+
module Pangea
|
|
62
|
+
module Resources
|
|
63
|
+
module HcloudVolume
|
|
64
|
+
def hcloud_volume(name, attributes = {})
|
|
65
|
+
volume_attrs = Hetzner::Types::VolumeAttributes.new(attributes)
|
|
66
|
+
|
|
67
|
+
resource(:hcloud_volume, name) do
|
|
68
|
+
name volume_attrs.name
|
|
69
|
+
size volume_attrs.size
|
|
70
|
+
location volume_attrs.location if volume_attrs.location
|
|
71
|
+
format volume_attrs.format if volume_attrs.format
|
|
72
|
+
labels volume_attrs.labels
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
ResourceReference.new(
|
|
76
|
+
type: 'hcloud_volume',
|
|
77
|
+
name: name,
|
|
78
|
+
resource_attributes: volume_attrs.to_h,
|
|
79
|
+
outputs: {
|
|
80
|
+
id: "${hcloud_volume.#{name}.id}",
|
|
81
|
+
size: "${hcloud_volume.#{name}.size}",
|
|
82
|
+
linux_device: "${hcloud_volume.#{name}.linux_device}"
|
|
83
|
+
}
|
|
84
|
+
)
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
module Hetzner
|
|
89
|
+
include HcloudVolume
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
Pangea::ResourceRegistry.register_module(Pangea::Resources::Hetzner)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## 4. Synthesis Spec
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
# spec/resources/hcloud_volume/synthesis_spec.rb
|
|
101
|
+
# frozen_string_literal: true
|
|
102
|
+
# Copyright 2025 The Pangea Authors
|
|
103
|
+
|
|
104
|
+
require 'spec_helper'
|
|
105
|
+
require 'terraform-synthesizer'
|
|
106
|
+
require 'pangea/resources/hcloud_volume/resource'
|
|
107
|
+
|
|
108
|
+
RSpec.describe 'hcloud_volume synthesis' do
|
|
109
|
+
include Pangea::Resources::Hetzner
|
|
110
|
+
|
|
111
|
+
let(:synthesizer) { TerraformSynthesizer.new }
|
|
112
|
+
|
|
113
|
+
it 'synthesizes volume' do
|
|
114
|
+
synthesizer.instance_eval do
|
|
115
|
+
extend Pangea::Resources::Hetzner
|
|
116
|
+
hcloud_volume(:data, {
|
|
117
|
+
name: "web-data",
|
|
118
|
+
size: 100,
|
|
119
|
+
location: "fsn1",
|
|
120
|
+
format: "ext4"
|
|
121
|
+
})
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
result = synthesizer.synthesis
|
|
125
|
+
volume = result[:resource][:hcloud_volume][:data]
|
|
126
|
+
|
|
127
|
+
expect(volume[:name]).to eq("web-data")
|
|
128
|
+
expect(volume[:size]).to eq(100)
|
|
129
|
+
expect(volume[:location]).to eq("fsn1")
|
|
130
|
+
expect(volume[:format]).to eq("ext4")
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
```
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# Patterns, Anti-Patterns, and Testing
|
|
2
|
+
|
|
3
|
+
## Common Patterns
|
|
4
|
+
|
|
5
|
+
### Nested Blocks
|
|
6
|
+
|
|
7
|
+
```ruby
|
|
8
|
+
# In resource.rb
|
|
9
|
+
if attrs.health_check
|
|
10
|
+
health_check do
|
|
11
|
+
protocol attrs.health_check[:protocol]
|
|
12
|
+
port attrs.health_check[:port]
|
|
13
|
+
interval attrs.health_check[:interval] if attrs.health_check[:interval]
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
### Array of Nested Blocks
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
# In resource.rb
|
|
22
|
+
attrs.rules.each do |rule|
|
|
23
|
+
rule_block do
|
|
24
|
+
direction rule[:direction]
|
|
25
|
+
protocol rule[:protocol]
|
|
26
|
+
port rule[:port] if rule[:port]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Conditional Optional Fields
|
|
32
|
+
|
|
33
|
+
```ruby
|
|
34
|
+
# In resource.rb
|
|
35
|
+
description attrs.description if attrs.description
|
|
36
|
+
location attrs.location if attrs.location
|
|
37
|
+
|
|
38
|
+
# DON'T: if attrs.optional_field.nil? ... (wrong)
|
|
39
|
+
# DO: if attrs.optional_field ... (correct)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Computed Properties
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
# In types.rb
|
|
46
|
+
class ServerAttributes < Dry::Struct
|
|
47
|
+
attribute :server_type, HetznerServerType
|
|
48
|
+
|
|
49
|
+
def is_arm?
|
|
50
|
+
server_type.start_with?('cax')
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def cpu_type
|
|
54
|
+
is_arm? ? 'arm64' : 'x86_64'
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# In resource.rb
|
|
59
|
+
resource(:hcloud_server, name) do
|
|
60
|
+
server_type attrs.server_type
|
|
61
|
+
cpu_architecture attrs.cpu_type # Use computed property
|
|
62
|
+
end
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Anti-Patterns
|
|
66
|
+
|
|
67
|
+
| Anti-Pattern | Problem | Fix |
|
|
68
|
+
|--------------|---------|-----|
|
|
69
|
+
| Missing `transform_keys` | Symbol/string key errors | Add `transform_keys(&:to_sym)` |
|
|
70
|
+
| Hardcoded values in resource | Values should come from attrs | Use `attrs.field` |
|
|
71
|
+
| No conditionals for optional | Includes nil in Terraform | `field attrs.val if attrs.val` |
|
|
72
|
+
| Missing auto-registration | Resource unavailable | Add `ResourceRegistry.register_module(...)` |
|
|
73
|
+
| Tests without synthesizer | Doesn't test Terraform generation | Use `TerraformSynthesizer.new` |
|
|
74
|
+
|
|
75
|
+
## Testing Strategy
|
|
76
|
+
|
|
77
|
+
### Run Commands
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
cd pkgs/tools/ruby/pangea
|
|
81
|
+
|
|
82
|
+
# Individual resource
|
|
83
|
+
rspec spec/resources/hcloud_volume/synthesis_spec.rb
|
|
84
|
+
|
|
85
|
+
# All provider resources
|
|
86
|
+
rspec spec/resources/hcloud_*
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Validate Types in IRB
|
|
90
|
+
|
|
91
|
+
```ruby
|
|
92
|
+
require 'pangea/resources/hcloud_volume/types'
|
|
93
|
+
|
|
94
|
+
# Valid input
|
|
95
|
+
attrs = Pangea::Resources::Hetzner::Types::VolumeAttributes.new(
|
|
96
|
+
name: "test",
|
|
97
|
+
size: 100,
|
|
98
|
+
format: "ext4"
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
# Invalid input (should raise error)
|
|
102
|
+
attrs = Pangea::Resources::Hetzner::Types::VolumeAttributes.new(
|
|
103
|
+
name: "test",
|
|
104
|
+
size: 5 # Too small, should fail
|
|
105
|
+
)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Git Commit Messages
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
# Type definitions
|
|
112
|
+
git commit -m "feat(pangea): add Hetzner Cloud type definitions (12 types)"
|
|
113
|
+
|
|
114
|
+
# Batch implementation
|
|
115
|
+
git commit -m "feat(pangea): complete Batch 1 - Core Infrastructure (5/5 resources)
|
|
116
|
+
|
|
117
|
+
Resources implemented:
|
|
118
|
+
- hcloud_ssh_key: SSH key management
|
|
119
|
+
- hcloud_network: Private VPC networks
|
|
120
|
+
- hcloud_firewall: Stateful firewalls
|
|
121
|
+
- hcloud_server: Virtual servers
|
|
122
|
+
- hcloud_network_subnet: Network subnets
|
|
123
|
+
|
|
124
|
+
All resources include:
|
|
125
|
+
- Dry::Struct type validation
|
|
126
|
+
- terraform-synthesizer integration
|
|
127
|
+
- RSpec synthesis tests
|
|
128
|
+
"
|
|
129
|
+
|
|
130
|
+
# Completion
|
|
131
|
+
git commit -m "docs(pangea): add Provider implementation completion report
|
|
132
|
+
|
|
133
|
+
100% coverage (XX/XX resources)
|
|
134
|
+
All batches complete
|
|
135
|
+
"
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Completion Checklist
|
|
139
|
+
|
|
140
|
+
Before marking a resource complete:
|
|
141
|
+
|
|
142
|
+
- [ ] Type definitions added to types.rb
|
|
143
|
+
- [ ] types.rb created with Dry::Struct
|
|
144
|
+
- [ ] resource.rb created with resource() function
|
|
145
|
+
- [ ] synthesis_spec.rb created with TerraformSynthesizer tests
|
|
146
|
+
- [ ] All tests pass
|
|
147
|
+
- [ ] Resource auto-registers via ResourceRegistry
|
|
148
|
+
- [ ] Tracker updated
|
|
149
|
+
- [ ] Committed with descriptive message
|