fufu-cloud-cli 0.9.8__tar.gz → 0.10.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.
Files changed (63) hide show
  1. {fufu_cloud_cli-0.9.8/src/fufu_cloud_cli.egg-info → fufu_cloud_cli-0.10.1}/PKG-INFO +37 -9
  2. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/README.md +36 -8
  3. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/pyproject.toml +1 -1
  4. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/__init__.py +1 -1
  5. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/api_backend.py +7 -0
  6. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/aws_errors.py +1 -1
  7. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/capabilities.json +35 -19
  8. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/cli.py +9 -0
  9. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/control.py +2 -1
  10. fufu_cloud_cli-0.10.1/src/fufu_cloud_cli/infrastructure.py +283 -0
  11. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/pulumi_bridge.py +5 -3
  12. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/terraform_bridge/common.py +5 -1
  13. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/terraform_bridge/google.py +3 -0
  14. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/terraform_bridge/runner.py +42 -9
  15. fufu_cloud_cli-0.10.1/src/fufu_cloud_cli/terraform_bridge/storage.py +173 -0
  16. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1/src/fufu_cloud_cli.egg-info}/PKG-INFO +37 -9
  17. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli.egg-info/SOURCES.txt +2 -0
  18. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/LICENSE +0 -0
  19. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/MANIFEST.in +0 -0
  20. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/setup.cfg +0 -0
  21. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/__main__.py +0 -0
  22. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/aws_lambda.py +0 -0
  23. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/aws_output.py +0 -0
  24. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/bigquery.py +0 -0
  25. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/capacity.py +0 -0
  26. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/cloud_data.py +0 -0
  27. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/cloudflare.py +0 -0
  28. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/docker_backend.py +0 -0
  29. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/errors.py +0 -0
  30. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/gcloud_environment.py +0 -0
  31. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/gcloud_output.py +0 -0
  32. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/gcp_infra.py +0 -0
  33. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/gcp_sdk.py +0 -0
  34. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/gcs.py +0 -0
  35. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/http_runtime.py +0 -0
  36. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/iac_state.py +0 -0
  37. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/lambda_adapter.py +0 -0
  38. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/limits.py +0 -0
  39. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/manifest.py +0 -0
  40. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/object_transfer.py +0 -0
  41. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/observability.py +0 -0
  42. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/public_access.py +0 -0
  43. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/pubsub.py +0 -0
  44. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/pulumi-endpoints.json +0 -0
  45. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/remote_compute.py +0 -0
  46. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/runtime/functions/Dockerfile +0 -0
  47. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/runtime/ingress/Dockerfile +0 -0
  48. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/runtime/ingress/proxy.py +0 -0
  49. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/runtime_sdk.py +0 -0
  50. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/secrets.py +0 -0
  51. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/serverless.py +0 -0
  52. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/terraform_bridge/__init__.py +0 -0
  53. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/terraform_bridge/aws.py +0 -0
  54. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/terraform_bridge/aws_data.py +0 -0
  55. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/terraform_bridge/google_pubsub.py +0 -0
  56. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/terraform_bridge/remote_state.py +0 -0
  57. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/vendor/AWS-CLI-LICENSE.txt +0 -0
  58. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/vendor/__init__.py +0 -0
  59. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli/vendor/aws_text.py +0 -0
  60. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli.egg-info/dependency_links.txt +0 -0
  61. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli.egg-info/entry_points.txt +0 -0
  62. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli.egg-info/requires.txt +0 -0
  63. {fufu_cloud_cli-0.9.8 → fufu_cloud_cli-0.10.1}/src/fufu_cloud_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fufu-cloud-cli
3
- Version: 0.9.8
3
+ Version: 0.10.1
4
4
  Summary: FUFU Cloud CLI for tenant-scoped mock cloud development and deployment
5
5
  License-Expression: LicenseRef-Proprietary
6
6
  Requires-Python: >=3.10
@@ -27,10 +27,37 @@ Dynamic: license-file
27
27
  `gcloud-fufu`、`az-fufu`、`wrangler-fufu`、`bq-fufu`。這是 AWS、Google Cloud、Azure 與 Cloudflare 的**明確子集**,
28
28
  只供 FUFU mock 環境使用;不會把部署轉送到正式雲端。
29
29
 
30
- 2026-09-10 後續原始碼與 Cloud Shell 新增 GKE、firewall、五類 global LB 與 Redis
31
- 配置命令,typed configuration 合計 22 類;都有 `MOCK ONLY` 提示、引用存在性與
32
- 相依刪除檢查,不建立 Kubernetes、VM、Redis 或網路資料面,也未增加 IaC 資源。
33
- 這批包含在 0.9.8;需要配套的 FUFU Console 與運算服務。
30
+ 0.10.1 新增官方 Terraform/OpenTofu/Pulumi 的 S3/GCS bucket 生命週期與
31
+ S3 bucket tags。需配套 FUFU API;不支援 bucket versioning、retention、
32
+ KMS、bucket IAM、GCS bucket labels 或 force destroy。
33
+
34
+ 0.10.0 新增 Compute Engine/EC2 VM 與 GKE/EKS 介面的實際運算命令。
35
+ 需要啟用相應 infrastructure backend 的 FUFU 服務端;VM 使用 KVM/KubeVirt,
36
+ 叢集使用獨立 Kubernetes API 與共用節點,均不是官方雲端資源。
37
+ 支援 VM 建立、SSH 指令、停止/啟動與刪除,以及叢集建立、查詢、
38
+ get-credentials/update-kubeconfig、waiter 與刪除。
39
+ 取得憑證後可使用標準 kubectl 部署 Deployment、Service、Job 及受管 GPU 容器。
40
+ 工作站需另安裝 kubectl;配套 Cloud Shell 已提供。
41
+
42
+ VM 尚無公開 IP、複寫儲存、live migration 或自助 GPU passthrough;
43
+ 叢集尚無 workload PVC、公開 LoadBalancer、互動式 exec/attach/port-forward。
44
+ 這批新 VM/cluster API 尚未支援官方 Terraform/OpenTofu/Pulumi provider。
45
+ 原有 firewall、global LB、Redis 等 typed configuration 仍明示 `MOCK ONLY`,
46
+ 不代表已建立相應網路或 Redis 資料面。
47
+
48
+ ```bash
49
+ gcloud-fufu compute instances create demo-vm --image-family=debian-12
50
+ gcloud-fufu compute ssh demo-vm --command='uname -s; nproc'
51
+ gcloud-fufu container clusters create demo-gke
52
+ gcloud-fufu container clusters get-credentials demo-gke
53
+ kubectl get pods -A
54
+ aws-fufu eks create-cluster --name demo-eks
55
+ aws-fufu eks wait cluster-active --name demo-eks
56
+ aws-fufu eks update-kubeconfig --name demo-eks
57
+ ```
58
+
59
+ 這些操作需要 FUFU credential;不使用官方雲端金鑰。資源以租戶隔離,配額不足
60
+ 會明確回覆 RESOURCE_EXHAUSTED。測試後請刪除所建 VM/cluster 以釋放資源。
34
61
 
35
62
  0.9.8 提供 Cloud Run/Functions 的原生形式日誌查詢、CloudWatch Logs
36
63
  tail/follow,以及 `fufu observability` 的日誌、請求指標與追蹤查詢。
@@ -73,9 +100,10 @@ insertAll/SELECT 與持久化日誌。`fufu_cloud_cli.gcp_sdk` 提供官方 Py
73
100
  BigQuery、Cloud Tasks、Logging SDK 的明確 REST factory;可用 `[gcp]` extra
74
101
  安裝已驗收相依。需要對應的新後端,並非透明 ADC 或所有 Google SDK 替換。
75
102
 
76
- `fufu infrastructure` 提供 14 類 typed configuration mock。Compute Engine、
77
- Cloud SQL、App Engine、DNS、VPC、Artifact Registry、Cloud Build、Gemini、
78
- VM Manager、Eventarc 等設定不會啟動 VM/SQL/registry/網路/推論。
103
+ `fufu infrastructure` 另保留 typed configuration mock 目錄,包含 Cloud SQL、
104
+ App Engine、DNS、VPC、Artifact Registry、Cloud Build、Gemini、VM Manager、
105
+ Eventarc 等。這個目錄只保存配置,不啟動 SQL/registry/網路/推論;
106
+ 實際 VM/Kubernetes 請使用上述 compute/ec2/container/eks 指令。
79
107
  UI 顯示僅設定,CLI stderr 保留 MOCK ONLY,不因輸出投影而隱藏。
80
108
  新服務尚未接入 Terraform/OpenTofu/Pulumi;單機背景投遞不是雲端 HA。
81
109
 
@@ -107,7 +135,7 @@ Python 預設識別而遇到 Cloudflare HTTP 403/1010。識別標頭不取代
107
135
  ## Cloudflare 前端部署與 R2
108
136
 
109
137
  ```bash
110
- pip install 'fufu-cloud-cli==0.9.8'
138
+ pip install 'fufu-cloud-cli==0.10.1'
111
139
  export FUFU_CLOUDFLARE_CREDENTIAL_FILE=/run/secrets/fufu-cloudflare.json
112
140
  wrangler-fufu capabilities
113
141
  wrangler-fufu pages project create frontend --production-branch main
@@ -4,10 +4,37 @@
4
4
  `gcloud-fufu`、`az-fufu`、`wrangler-fufu`、`bq-fufu`。這是 AWS、Google Cloud、Azure 與 Cloudflare 的**明確子集**,
5
5
  只供 FUFU mock 環境使用;不會把部署轉送到正式雲端。
6
6
 
7
- 2026-09-10 後續原始碼與 Cloud Shell 新增 GKE、firewall、五類 global LB 與 Redis
8
- 配置命令,typed configuration 合計 22 類;都有 `MOCK ONLY` 提示、引用存在性與
9
- 相依刪除檢查,不建立 Kubernetes、VM、Redis 或網路資料面,也未增加 IaC 資源。
10
- 這批包含在 0.9.8;需要配套的 FUFU Console 與運算服務。
7
+ 0.10.1 新增官方 Terraform/OpenTofu/Pulumi 的 S3/GCS bucket 生命週期與
8
+ S3 bucket tags。需配套 FUFU API;不支援 bucket versioning、retention、
9
+ KMS、bucket IAM、GCS bucket labels 或 force destroy。
10
+
11
+ 0.10.0 新增 Compute Engine/EC2 VM 與 GKE/EKS 介面的實際運算命令。
12
+ 需要啟用相應 infrastructure backend 的 FUFU 服務端;VM 使用 KVM/KubeVirt,
13
+ 叢集使用獨立 Kubernetes API 與共用節點,均不是官方雲端資源。
14
+ 支援 VM 建立、SSH 指令、停止/啟動與刪除,以及叢集建立、查詢、
15
+ get-credentials/update-kubeconfig、waiter 與刪除。
16
+ 取得憑證後可使用標準 kubectl 部署 Deployment、Service、Job 及受管 GPU 容器。
17
+ 工作站需另安裝 kubectl;配套 Cloud Shell 已提供。
18
+
19
+ VM 尚無公開 IP、複寫儲存、live migration 或自助 GPU passthrough;
20
+ 叢集尚無 workload PVC、公開 LoadBalancer、互動式 exec/attach/port-forward。
21
+ 這批新 VM/cluster API 尚未支援官方 Terraform/OpenTofu/Pulumi provider。
22
+ 原有 firewall、global LB、Redis 等 typed configuration 仍明示 `MOCK ONLY`,
23
+ 不代表已建立相應網路或 Redis 資料面。
24
+
25
+ ```bash
26
+ gcloud-fufu compute instances create demo-vm --image-family=debian-12
27
+ gcloud-fufu compute ssh demo-vm --command='uname -s; nproc'
28
+ gcloud-fufu container clusters create demo-gke
29
+ gcloud-fufu container clusters get-credentials demo-gke
30
+ kubectl get pods -A
31
+ aws-fufu eks create-cluster --name demo-eks
32
+ aws-fufu eks wait cluster-active --name demo-eks
33
+ aws-fufu eks update-kubeconfig --name demo-eks
34
+ ```
35
+
36
+ 這些操作需要 FUFU credential;不使用官方雲端金鑰。資源以租戶隔離,配額不足
37
+ 會明確回覆 RESOURCE_EXHAUSTED。測試後請刪除所建 VM/cluster 以釋放資源。
11
38
 
12
39
  0.9.8 提供 Cloud Run/Functions 的原生形式日誌查詢、CloudWatch Logs
13
40
  tail/follow,以及 `fufu observability` 的日誌、請求指標與追蹤查詢。
@@ -50,9 +77,10 @@ insertAll/SELECT 與持久化日誌。`fufu_cloud_cli.gcp_sdk` 提供官方 Py
50
77
  BigQuery、Cloud Tasks、Logging SDK 的明確 REST factory;可用 `[gcp]` extra
51
78
  安裝已驗收相依。需要對應的新後端,並非透明 ADC 或所有 Google SDK 替換。
52
79
 
53
- `fufu infrastructure` 提供 14 類 typed configuration mock。Compute Engine、
54
- Cloud SQL、App Engine、DNS、VPC、Artifact Registry、Cloud Build、Gemini、
55
- VM Manager、Eventarc 等設定不會啟動 VM/SQL/registry/網路/推論。
80
+ `fufu infrastructure` 另保留 typed configuration mock 目錄,包含 Cloud SQL、
81
+ App Engine、DNS、VPC、Artifact Registry、Cloud Build、Gemini、VM Manager、
82
+ Eventarc 等。這個目錄只保存配置,不啟動 SQL/registry/網路/推論;
83
+ 實際 VM/Kubernetes 請使用上述 compute/ec2/container/eks 指令。
56
84
  UI 顯示僅設定,CLI stderr 保留 MOCK ONLY,不因輸出投影而隱藏。
57
85
  新服務尚未接入 Terraform/OpenTofu/Pulumi;單機背景投遞不是雲端 HA。
58
86
 
@@ -84,7 +112,7 @@ Python 預設識別而遇到 Cloudflare HTTP 403/1010。識別標頭不取代
84
112
  ## Cloudflare 前端部署與 R2
85
113
 
86
114
  ```bash
87
- pip install 'fufu-cloud-cli==0.9.8'
115
+ pip install 'fufu-cloud-cli==0.10.1'
88
116
  export FUFU_CLOUDFLARE_CREDENTIAL_FILE=/run/secrets/fufu-cloudflare.json
89
117
  wrangler-fufu capabilities
90
118
  wrangler-fufu pages project create frontend --production-branch main
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "fufu-cloud-cli"
7
- version = "0.9.8"
7
+ version = "0.10.1"
8
8
  description = "FUFU Cloud CLI for tenant-scoped mock cloud development and deployment"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,3 +1,3 @@
1
1
  """FUFU CLI 與本機部署工具;相容範圍見 capabilities.json。"""
2
2
 
3
- __version__ = "0.9.8"
3
+ __version__ = "0.10.1"
@@ -184,6 +184,13 @@ class ApiClient:
184
184
  return json.loads(raw)
185
185
  except HTTPError as exc:
186
186
  status = exc.code
187
+ if '/infrastructure/' in path and status == 429:
188
+ try:
189
+ value = json.loads(exc.read(4096))
190
+ if isinstance(value, dict) and value.get('code') == 'RESOURCE_EXHAUSTED':
191
+ raise FufuError('RESOURCE_EXHAUSTED', 'FUFU 租戶資源配額或主機容量已滿;請刪除不需要的資源,或調整平台資源配額後再重試。') from None
192
+ except (ValueError, OSError): pass
193
+ finally: exc.close()
187
194
  if self.provider == 'aws' and '/compute/' in path and status in {400, 412}:
188
195
  try:
189
196
  value = json.loads(exc.read(4096))
@@ -1,6 +1,6 @@
1
1
  """Only documented provider error codes may cross the public transport boundary."""
2
2
  AWS_ERRORS = frozenset('''ConditionalCheckFailedException ResourceNotFoundException ResourceInUseException ResourceAlreadyExistsException ValidationException
3
- NoSuchKey NoSuchBucket NotFound NotModified ParameterNotFound ParameterAlreadyExists ParameterVersionNotFound QueueDoesNotExist
3
+ NoSuchKey NoSuchBucket NoSuchTagSet BucketAlreadyExists BucketAlreadyOwnedByYou BucketNotEmpty NotFound NotModified ParameterNotFound ParameterAlreadyExists ParameterVersionNotFound QueueDoesNotExist
4
4
  PreconditionFailed InvalidRange InvalidParameterException InvalidParameterValue InvalidAttributeName InvalidAttributeValue QueueNameExists
5
5
  PurgeQueueInProgress ReceiptHandleIsInvalid BatchEntryIdsNotDistinct EmptyBatchRequest BatchRequestTooLong InvalidBatchEntryId
6
6
  TooManyEntriesInBatchRequest InvalidMessageContents AWS.SimpleQueueService.NonExistentQueue TooManyRequestsException InvalidRequestContentException'''.split())
@@ -27,11 +27,11 @@
27
27
  "backend": "api",
28
28
  "compatibility": "official-provider-subset",
29
29
  "providers": { "hashicorp/aws": "6.63.0", "hashicorp/google": "8.1.0" },
30
- "resources": ["aws_iam_role", "aws_iam_role_policy", "aws_lambda_function", "aws_lambda_function_url", "aws_lambda_permission", "google_service_account", "google_cloud_run_v2_service", "google_cloud_run_v2_service_iam_member", "aws_sqs_queue", "aws_ssm_parameter", "google_pubsub_topic", "google_pubsub_subscription"],
30
+ "resources": ["aws_iam_role", "aws_iam_role_policy", "aws_lambda_function", "aws_lambda_function_url", "aws_lambda_permission", "google_service_account", "google_cloud_run_v2_service", "google_cloud_run_v2_service_iam_member", "aws_sqs_queue", "aws_ssm_parameter", "google_pubsub_topic", "google_pubsub_subscription", "aws_s3_bucket", "google_storage_bucket"],
31
31
  "operations": ["init", "plan", "saved-plan-apply", "refresh", "update", "import", "destroy"],
32
- "engines": { "terraform": "1.16.1", "opentofu": "1.12.6" },
32
+ "engines": { "terraform": "1.16.2", "opentofu": "1.12.6" },
33
33
  "state": ["isolated-local", "tenant-remote-http", "context-binding"],
34
- "limitations": ["Linux-amd64-verified", "terraform-extra-required", "root-default-providers-only", "OpenTofu-data-resources-verified-compute-not-retested", "no-full-cloud-IAM-or-runtime-equivalence", "no-Terraform-storage-or-Functions-Gen1-Gen2", "PubSub-requires-patched-emulator", "unsupported-APIs-and-fields-fail-explicitly"]
34
+ "limitations": ["Linux-amd64-verified", "terraform-extra-required", "root-default-providers-only", "OpenTofu-data-resources-verified-compute-not-retested", "no-full-cloud-IAM-or-runtime-equivalence", "no-VM-cluster-Functions-Gen1-Gen2-IaC", "storage-bucket-lifecycle-and-S3-tags-only", "no-force-destroy-retention-versioning-bucket-IAM-KMS", "PubSub-requires-patched-emulator", "unsupported-APIs-and-fields-fail-explicitly"]
35
35
  },
36
36
  "iac-remote-state": {
37
37
  "status": "implemented", "backend": "api", "mode": "simplified",
@@ -41,7 +41,7 @@
41
41
  "pulumi-data": {
42
42
  "status": "implemented", "backend": "api", "compatibility": "official-provider-subset",
43
43
  "providers": { "pulumi": "3.261.0", "aws": "7.45.0", "gcp": "9.36.1" },
44
- "resources": ["aws:sqs/queue:Queue", "aws:ssm/parameter:Parameter", "gcp:pubsub/topic:Topic", "gcp:pubsub/subscription:Subscription"],
44
+ "resources": ["aws:sqs/queue:Queue", "aws:ssm/parameter:Parameter", "gcp:pubsub/topic:Topic", "gcp:pubsub/subscription:Subscription", "aws:s3/bucket:Bucket", "gcp:storage/bucket:Bucket"],
45
45
  "operations": ["preview", "up", "refresh", "update", "import", "destroy"],
46
46
  "limitations": ["Node.js-runtime", "default-providers", "separate-local-DIY-state", "external-passphrase-required", "secret-fields-encrypted-not-whole-state", "no-remote-backend", "no-compute-resource-acceptance", "trusted-programs-only"]
47
47
  },
@@ -197,7 +197,8 @@
197
197
  "metadata-describe-update-merge-delete",
198
198
  "paginated-object-list",
199
199
  "binary-cat",
200
- "UTF8-preview"
200
+ "UTF8-preview",
201
+ "Terraform-OpenTofu-Pulumi-bucket-lifecycle"
201
202
  ],
202
203
  "limitations": [
203
204
  "object-5TiB-policy-subject-to-host-disk-capacity",
@@ -209,7 +210,8 @@
209
210
  "single-writer-per-volume",
210
211
  "no-signed-URLs",
211
212
  "no-versioning-retention-ACL-KMS",
212
- "no-GCS-Terraform-or-Pulumi-resource-adapter"
213
+ "no-bucket-labels-IAM-PATCH-force-destroy",
214
+ "bucket-current-tenant-location-STANDARD-only"
213
215
  ]
214
216
  },
215
217
  "azure-catalog-api": {
@@ -270,7 +272,11 @@
270
272
  "rb",
271
273
  "ls",
272
274
  "cp-upload-download",
273
- "rm"
275
+ "rm",
276
+ "get-bucket-tagging",
277
+ "put-bucket-tagging",
278
+ "delete-bucket-tagging",
279
+ "Terraform-OpenTofu-Pulumi-bucket-lifecycle"
274
280
  ],
275
281
  "limitations": [
276
282
  "object-10000-parts-of-up-to-5GiB-subject-to-host-disk-capacity",
@@ -534,21 +540,23 @@
534
540
  },
535
541
  "gcp-compute-engine": {
536
542
  "name": "Compute Engine",
537
- "status": "mock-only",
543
+ "status": "implemented",
538
544
  "backend": "api",
539
- "mode": "mock-only",
545
+ "mode": "simplified",
540
546
  "operations": [
541
- "typed-instance-configuration-crud"
547
+ "create-list-describe-delete", "stop-start", "guest-ssh-command"
542
548
  ],
543
- "reason": "僅保存設定;無 VM、disk、SSH、guest OS 或 hypervisor。"
549
+ "limitations": ["requires-FUFU-infrastructure-backend", "Debian-12-only", "private-network", "single-node-disk", "no-self-service-GPU-passthrough", "no-official-IaC-provider"],
550
+ "reason": "實際 KVM/KubeVirt VM、持久磁碟與 SSH 指令;原生風格指令子集,無官方雲端資源。"
544
551
  },
545
552
  "gcp-gke": {
546
553
  "name": "GKE",
547
- "status": "mock-only",
554
+ "status": "implemented",
548
555
  "backend": "api",
549
- "mode": "mock-only",
550
- "operations": ["typed-cluster-configuration-crud", "network-reference-validation"],
551
- "reason": "僅保存叢集配置;無 Kubernetes API、nodes、kubectl、scheduler 或 workloads。"
556
+ "mode": "simplified",
557
+ "operations": ["create-list-describe-delete", "get-credentials", "kubectl-workloads", "GPU-container-jobs"],
558
+ "limitations": ["requires-FUFU-infrastructure-backend", "shared-workers", "single-control-plane-replica", "no-workload-PVC", "no-public-LoadBalancer", "no-interactive-exec-or-portforward", "no-official-IaC-provider"],
559
+ "reason": "獨立 vCluster Kubernetes API 與控制面資料;共用受管節點,支援標準 kubectl 工作負載子集。"
552
560
  },
553
561
  "gcp-vpc": {
554
562
  "name": "VPC / Firewall",
@@ -637,8 +645,12 @@
637
645
  },
638
646
  "aws-ec2": {
639
647
  "name": "EC2",
640
- "status": "mock-only",
641
- "reason": "明示 mock 目錄;VM 未執行,不能列為成功部署。"
648
+ "status": "implemented",
649
+ "backend": "api",
650
+ "mode": "simplified",
651
+ "operations": ["run-describe-terminate-instances", "stop-start", "instance-waiters"],
652
+ "limitations": ["requires-FUFU-infrastructure-backend", "Debian-12-only", "private-network", "single-node-disk", "no-self-service-GPU-passthrough", "no-official-IaC-provider"],
653
+ "reason": "實際 KVM/KubeVirt VM;支援生命週期與 scoped instance ID,無官方 EC2 網路或完整 API。"
642
654
  },
643
655
  "aws-ecs": {
644
656
  "name": "ECS / Fargate",
@@ -647,8 +659,12 @@
647
659
  },
648
660
  "aws-eks": {
649
661
  "name": "EKS",
650
- "status": "unsupported",
651
- "reason": "尚未實作可供 CLI 自動部署與驗證的服務契約。"
662
+ "status": "implemented",
663
+ "backend": "api",
664
+ "mode": "simplified",
665
+ "operations": ["create-list-describe-delete", "update-kubeconfig", "cluster-waiters", "kubectl-workloads", "GPU-container-jobs"],
666
+ "limitations": ["requires-FUFU-infrastructure-backend", "shared-workers", "single-control-plane-replica", "no-workload-PVC", "no-public-LoadBalancer", "no-interactive-exec-or-portforward", "no-official-IaC-provider"],
667
+ "reason": "獨立 vCluster Kubernetes API 與控制面資料;FUFU 短效認證,不是 AWS 原生 IAM 或託管控制面。"
652
668
  },
653
669
  "aws-app-runner": {
654
670
  "name": "App Runner",
@@ -518,6 +518,9 @@ def entry(provider, argv=None):
518
518
  if provider == 'fufu' and argv[:1] == ['infrastructure']:
519
519
  from .gcp_infra import configuration_command
520
520
  emit(configuration_command(argv[1:], Parser)); return
521
+ if provider == 'fufu' and argv[:1] == ['kubernetes-token']:
522
+ from .infrastructure import token_command
523
+ emit(token_command(argv[1:], Parser)); return
521
524
  # Native global selectors are checked against the authenticated tenant scope.
522
525
  if provider in {'aws-fufu', 'gcloud-fufu'}:
523
526
  rest = []; i = 0; explicit_region = False
@@ -580,6 +583,12 @@ def entry(provider, argv=None):
580
583
  if output_format and argv[:2] == ['functions', 'call']:
581
584
  require(output_format == 'json', 'UNSUPPORTED_FORMAT', 'Functions call 目前只支援 JSON 回應。')
582
585
  from . import public_access
586
+ if provider == 'gcloud-fufu' and argv[:2] in [['compute', 'instances'], ['compute', 'ssh'], ['container', 'clusters']]:
587
+ from .infrastructure import gcp_command
588
+ emit(gcp_command(argv, Parser)); return
589
+ if provider == 'aws-fufu' and argv[:1] in [['ec2'], ['eks']]:
590
+ from .infrastructure import aws_command as infrastructure_aws_command
591
+ emit(infrastructure_aws_command(argv, Parser)); return
583
592
  if provider == 'gcloud-fufu' and argv and argv[0] in {'scheduler', 'tasks', 'logging', 'compute', 'sql', 'artifacts', 'dns', 'eventarc', 'container', 'redis'}:
584
593
  from .gcp_infra import command
585
594
  emit(command(argv, Parser)); return
@@ -28,6 +28,7 @@ AWS_OPERATIONS = {
28
28
  },
29
29
  's3api': {
30
30
  'CreateBucket': 'Bucket CreateBucketConfiguration', 'DeleteBucket': 'Bucket', 'ListBuckets': '', 'HeadBucket': 'Bucket', 'GetBucketLocation': 'Bucket',
31
+ 'GetBucketTagging': 'Bucket', 'PutBucketTagging': 'Bucket Tagging', 'DeleteBucketTagging': 'Bucket',
31
32
  'ListObjectsV2': 'Bucket Prefix MaxKeys ContinuationToken Delimiter StartAfter EncodingType', 'PutObject': 'Bucket Key Body ContentType Metadata',
32
33
  'GetObject': 'Bucket Key ChecksumMode Range IfMatch IfNoneMatch', 'HeadObject': 'Bucket Key ChecksumMode IfMatch IfNoneMatch', 'DeleteObject': 'Bucket Key',
33
34
  },
@@ -53,7 +54,7 @@ AWS_OPERATIONS = {
53
54
  'PutRetentionPolicy': 'logGroupName retentionInDays', 'DeleteRetentionPolicy': 'logGroupName',
54
55
  },
55
56
  }
56
- JSON_FIELDS = set('AssumeRolePolicyDocument PolicyDocument AttributeDefinitions KeySchema ProvisionedThroughput GlobalSecondaryIndexes LocalSecondaryIndexes StreamSpecification Item Key ExpressionAttributeNames ExpressionAttributeValues ExclusiveStartKey RequestItems CreateBucketConfiguration Metadata Attributes MessageAttributes Tags tags ParameterFilters Entries logEvents'.split())
57
+ JSON_FIELDS = set('AssumeRolePolicyDocument PolicyDocument AttributeDefinitions KeySchema ProvisionedThroughput GlobalSecondaryIndexes LocalSecondaryIndexes StreamSpecification Item Key ExpressionAttributeNames ExpressionAttributeValues ExclusiveStartKey RequestItems CreateBucketConfiguration Metadata Attributes MessageAttributes Tags tags Tagging ParameterFilters Entries logEvents'.split())
57
58
  LIST_FIELDS = set('ActionNames ResourceArns Names AttributeNames MessageAttributeNames MessageSystemAttributeNames TagKeys logStreamNames'.split())
58
59
  BOOL_FIELDS = set('ConsistentRead ScanIndexForward WithDecryption Overwrite Enabled Recursive descending startFromHead'.split())
59
60
  INT_FIELDS = set('Limit MaxKeys MaxResults MaxNumberOfMessages VisibilityTimeout WaitTimeSeconds DelaySeconds BatchSize limit startTime endTime retentionInDays'.split())