magic-pocket-cli 0.3.0__tar.gz → 0.5.0__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 (64) hide show
  1. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/PKG-INFO +2 -2
  2. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/mediator.py +48 -0
  3. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/neon.py +22 -1
  4. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pyproject.toml +2 -2
  5. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/.gitignore +0 -0
  6. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/__init__.py +0 -0
  7. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/__init__.py +0 -0
  8. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/aws_auth.py +0 -0
  9. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/awscontainer_cli.py +0 -0
  10. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/cloudfront_cli.py +0 -0
  11. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/cloudfront_keys_cli.py +0 -0
  12. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/cloudfront_waf_cli.py +0 -0
  13. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/deploy_cli.py +0 -0
  14. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/destroy_cli.py +0 -0
  15. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/dsql_cli.py +0 -0
  16. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/main_cli.py +0 -0
  17. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/migrate_cli.py +0 -0
  18. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/neon_cli.py +0 -0
  19. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/permissions_cli.py +0 -0
  20. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/rds_cli.py +0 -0
  21. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/runtime_config_cli.py +0 -0
  22. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/s3_cli.py +0 -0
  23. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/status_cli.py +0 -0
  24. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/tidb_cli.py +0 -0
  25. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/vpc_cli.py +0 -0
  26. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/cli/waf_cli.py +0 -0
  27. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/django_cli.py +0 -0
  28. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/__init__.py +0 -0
  29. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/aws/__init__.py +0 -0
  30. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/aws/builders/__init__.py +0 -0
  31. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/aws/builders/codebuild.py +0 -0
  32. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/aws/builders/depot.py +0 -0
  33. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/aws/builders/docker.py +0 -0
  34. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/aws/builders/dockerignore.py +0 -0
  35. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/aws/cloudformation.py +0 -0
  36. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/aws/ecr.py +0 -0
  37. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/aws/efs.py +0 -0
  38. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/aws/lambdahandler.py +0 -0
  39. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/aws/s3_utils.py +0 -0
  40. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/aws/state.py +0 -0
  41. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/awscontainer.py +0 -0
  42. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/cloudfront.py +0 -0
  43. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/cloudfront_acm.py +0 -0
  44. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/cloudfront_keys.py +0 -0
  45. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/cloudfront_waf.py +0 -0
  46. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/dsql.py +0 -0
  47. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/rds.py +0 -0
  48. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/s3.py +0 -0
  49. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/tidb.py +0 -0
  50. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/upstash.py +0 -0
  51. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/resources/vpc.py +0 -0
  52. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/templates/cloudformation/awscontainer.yaml +0 -0
  53. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/templates/cloudformation/cf_function_api_host.js +0 -0
  54. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/templates/cloudformation/cf_function_spa_auth.js +0 -0
  55. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/templates/cloudformation/cf_function_spa_fallback.js +0 -0
  56. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/templates/cloudformation/cloudfront.yaml +0 -0
  57. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/templates/cloudformation/cloudfront_acm.yaml +0 -0
  58. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/templates/cloudformation/cloudfront_keys.yaml +0 -0
  59. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/templates/cloudformation/cloudfront_waf.yaml +0 -0
  60. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/templates/cloudformation/vpc.yaml +0 -0
  61. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/templates/init/django-dotenv.env +0 -0
  62. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/templates/init/django-settings.py +0 -0
  63. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/templates/init/pocket.Dockerfile +0 -0
  64. {magic_pocket_cli-0.3.0 → magic_pocket_cli-0.5.0}/pocket_cli/templates/init/pocket_simple.toml +0 -0
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: magic-pocket-cli
3
- Version: 0.3.0
3
+ Version: 0.5.0
4
4
  Summary: CLI and deploy tools for magic-pocket.
5
5
  Requires-Python: >=3.10
6
6
  Requires-Dist: awscrt>=0.19.0
7
7
  Requires-Dist: click>=8.1.7
8
8
  Requires-Dist: deepdiff>=6.7.1
9
9
  Requires-Dist: jinja2>=3.1.3
10
- Requires-Dist: magic-pocket>=0.3.0
10
+ Requires-Dist: magic-pocket>=0.5.0
11
11
  Requires-Dist: pathspec>=1.0.4
12
12
  Requires-Dist: python-on-whales>=0.68.0
13
13
  Requires-Dist: pyyaml>=6.0.1
@@ -60,6 +60,7 @@ class Mediator:
60
60
  def ensure_pocket_managed_secrets(self):
61
61
  self.create_pocket_managed_secrets(exists="ignore")
62
62
  self._cleanup_orphaned_secrets()
63
+ self.verify_user_stored_secrets()
63
64
  if self.context.awscontainer and self.context.awscontainer.secrets:
64
65
  sc = self.context.awscontainer.secrets
65
66
  if hasattr(sc, "pocket_store"):
@@ -69,6 +70,53 @@ class Mediator:
69
70
  if hasattr(sc, "allowed_ssm_resources"):
70
71
  del sc.allowed_ssm_resources
71
72
 
73
+ def verify_user_stored_secrets(self):
74
+ """type 付き user secret (stored mode) が deploy 前に provision 済みか検証する。
75
+
76
+ computed (managed) と違い pocket は値を生成しないため、未 provision でも
77
+ deploy は通り runtime まで遅延して落ちる。それを避けるため deploy 時に store を
78
+ 引いて存在を確認し、無ければ正準名を示して止める。管理 API は叩かない。
79
+ """
80
+ if self.context.awscontainer is None:
81
+ return
82
+ if (sc := self.context.awscontainer.secrets) is None:
83
+ return
84
+ missing: list[str] = []
85
+ for key, spec in sc.user.items():
86
+ # type 付き = stored mode のみ対象。name は from_settings で導出済み。
87
+ if spec.type is None or spec.name is None:
88
+ continue
89
+ store = spec.store or sc.store
90
+ if not self._stored_secret_exists(spec.name, store, sc.region):
91
+ missing.append(
92
+ " - %s (type=%s, store=%s): %s"
93
+ % (key, spec.type, store, spec.name)
94
+ )
95
+ if missing:
96
+ raise RuntimeError(
97
+ "stored mode の user secret が見つかりません。"
98
+ "deploy 前に下記の secret を provision してください "
99
+ "(値は接続 URL):\n" + "\n".join(missing)
100
+ )
101
+
102
+ def _stored_secret_exists(self, name: str, store: str, region: str) -> bool:
103
+ import boto3
104
+ from botocore.exceptions import ClientError
105
+
106
+ try:
107
+ if store == "ssm":
108
+ boto3.client("ssm", region_name=region).get_parameter(Name=name)
109
+ else:
110
+ boto3.client("secretsmanager", region_name=region).describe_secret(
111
+ SecretId=name
112
+ )
113
+ return True
114
+ except ClientError as e:
115
+ code = e.response.get("Error", {}).get("Code", "")
116
+ if code in ("ParameterNotFound", "ResourceNotFoundException"):
117
+ return False
118
+ raise
119
+
72
120
  def _cleanup_orphaned_secrets(self):
73
121
  """SSM/SM にあるが managed 定義にないシークレットを削除する"""
74
122
  if self.context.awscontainer is None:
@@ -230,6 +230,25 @@ class Neon:
230
230
  if branch["name"] == self.context.branch_name:
231
231
  return Branch(**branch)
232
232
 
233
+ @cached_property
234
+ def parent_branch(self) -> Branch | None:
235
+ """branch を新規作成する際の親ブランチ。
236
+
237
+ context.parent_branch_name が未指定なら None (= create_branch が parent_id を
238
+ 送らず Neon の default ブランチから分岐)。指定があるのに project 内に該当
239
+ ブランチが無い場合はエラー (黙って default 分岐すると事故になるため)。
240
+ """
241
+ if not self.context.parent_branch_name:
242
+ return None
243
+ if self.project:
244
+ for branch in self.get("branches").json()["branches"]:
245
+ if branch["name"] == self.context.parent_branch_name:
246
+ return Branch(**branch)
247
+ raise ValueError(
248
+ f"Neon parent branch '{self.context.parent_branch_name}' not found "
249
+ f"in project '{self.context.project_name}'"
250
+ )
251
+
233
252
  @cached_property
234
253
  def database(self) -> Database | None:
235
254
  if self.branch:
@@ -293,7 +312,9 @@ class Neon:
293
312
  pass
294
313
 
295
314
  def create(self):
296
- self.create_branch()
315
+ # parent_branch_name 指定時はその親から分岐。未指定なら parent_branch=None で
316
+ # 従来通り Neon default ブランチから分岐する。
317
+ self.create_branch(self.parent_branch)
297
318
  self.ensure_role()
298
319
  self.ensure_database()
299
320
 
@@ -1,10 +1,10 @@
1
1
  [project]
2
2
  name = "magic-pocket-cli"
3
- version = "0.3.0"
3
+ version = "0.5.0"
4
4
  description = "CLI and deploy tools for magic-pocket."
5
5
  requires-python = ">=3.10"
6
6
  dependencies = [
7
- "magic-pocket>=0.3.0",
7
+ "magic-pocket>=0.5.0",
8
8
  "click>=8.1.7",
9
9
  "jinja2>=3.1.3",
10
10
  "python-on-whales>=0.68.0",