magic-pocket-cli 0.2.0__py3-none-any.whl

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 (65) hide show
  1. magic_pocket_cli-0.2.0.dist-info/METADATA +14 -0
  2. magic_pocket_cli-0.2.0.dist-info/RECORD +65 -0
  3. magic_pocket_cli-0.2.0.dist-info/WHEEL +4 -0
  4. magic_pocket_cli-0.2.0.dist-info/entry_points.txt +2 -0
  5. pocket_cli/__init__.py +0 -0
  6. pocket_cli/cli/__init__.py +0 -0
  7. pocket_cli/cli/aws_auth.py +48 -0
  8. pocket_cli/cli/awscontainer_cli.py +328 -0
  9. pocket_cli/cli/cloudfront_cli.py +116 -0
  10. pocket_cli/cli/cloudfront_keys_cli.py +68 -0
  11. pocket_cli/cli/cloudfront_waf_cli.py +68 -0
  12. pocket_cli/cli/deploy_cli.py +274 -0
  13. pocket_cli/cli/destroy_cli.py +358 -0
  14. pocket_cli/cli/dsql_cli.py +60 -0
  15. pocket_cli/cli/main_cli.py +91 -0
  16. pocket_cli/cli/migrate_cli.py +148 -0
  17. pocket_cli/cli/neon_cli.py +97 -0
  18. pocket_cli/cli/permissions_cli.py +46 -0
  19. pocket_cli/cli/rds_cli.py +63 -0
  20. pocket_cli/cli/runtime_config_cli.py +185 -0
  21. pocket_cli/cli/s3_cli.py +69 -0
  22. pocket_cli/cli/status_cli.py +56 -0
  23. pocket_cli/cli/tidb_cli.py +73 -0
  24. pocket_cli/cli/vpc_cli.py +92 -0
  25. pocket_cli/cli/waf_cli.py +182 -0
  26. pocket_cli/django_cli.py +412 -0
  27. pocket_cli/mediator.py +220 -0
  28. pocket_cli/resources/__init__.py +0 -0
  29. pocket_cli/resources/aws/__init__.py +0 -0
  30. pocket_cli/resources/aws/builders/__init__.py +57 -0
  31. pocket_cli/resources/aws/builders/codebuild.py +363 -0
  32. pocket_cli/resources/aws/builders/depot.py +84 -0
  33. pocket_cli/resources/aws/builders/docker.py +34 -0
  34. pocket_cli/resources/aws/builders/dockerignore.py +44 -0
  35. pocket_cli/resources/aws/cloudformation.py +790 -0
  36. pocket_cli/resources/aws/ecr.py +145 -0
  37. pocket_cli/resources/aws/efs.py +138 -0
  38. pocket_cli/resources/aws/lambdahandler.py +182 -0
  39. pocket_cli/resources/aws/s3_utils.py +58 -0
  40. pocket_cli/resources/aws/state.py +74 -0
  41. pocket_cli/resources/awscontainer.py +265 -0
  42. pocket_cli/resources/cloudfront.py +491 -0
  43. pocket_cli/resources/cloudfront_acm.py +55 -0
  44. pocket_cli/resources/cloudfront_keys.py +81 -0
  45. pocket_cli/resources/cloudfront_waf.py +67 -0
  46. pocket_cli/resources/dsql.py +142 -0
  47. pocket_cli/resources/neon.py +353 -0
  48. pocket_cli/resources/rds.py +680 -0
  49. pocket_cli/resources/s3.py +307 -0
  50. pocket_cli/resources/tidb.py +298 -0
  51. pocket_cli/resources/upstash.py +152 -0
  52. pocket_cli/resources/vpc.py +67 -0
  53. pocket_cli/templates/cloudformation/awscontainer.yaml +516 -0
  54. pocket_cli/templates/cloudformation/cf_function_api_host.js +5 -0
  55. pocket_cli/templates/cloudformation/cf_function_spa_auth.js +28 -0
  56. pocket_cli/templates/cloudformation/cf_function_spa_fallback.js +8 -0
  57. pocket_cli/templates/cloudformation/cloudfront.yaml +309 -0
  58. pocket_cli/templates/cloudformation/cloudfront_acm.yaml +43 -0
  59. pocket_cli/templates/cloudformation/cloudfront_keys.yaml +32 -0
  60. pocket_cli/templates/cloudformation/cloudfront_waf.yaml +97 -0
  61. pocket_cli/templates/cloudformation/vpc.yaml +213 -0
  62. pocket_cli/templates/init/django-dotenv.env +3 -0
  63. pocket_cli/templates/init/django-settings.py +140 -0
  64. pocket_cli/templates/init/pocket.Dockerfile +26 -0
  65. pocket_cli/templates/init/pocket_simple.toml +31 -0
@@ -0,0 +1,152 @@
1
+ from __future__ import annotations
2
+
3
+ from functools import cached_property
4
+ from typing import TYPE_CHECKING
5
+
6
+ import requests
7
+ from pydantic import BaseModel
8
+
9
+ from pocket.resources.base import ResourceStatus
10
+ from pocket.utils import echo
11
+
12
+ if TYPE_CHECKING:
13
+ from pocket.context import UpstashContext
14
+
15
+
16
+ class UpstashResourceIsNotReady(Exception):
17
+ pass
18
+
19
+
20
+ class UpstashDatabase(BaseModel):
21
+ database_id: str
22
+ database_name: str
23
+ endpoint: str
24
+ port: int
25
+ password: str
26
+ tls: bool
27
+ state: str
28
+
29
+
30
+ class UpstashApi:
31
+ base_url = "https://api.upstash.com/v2/redis"
32
+
33
+ def __init__(self, email: str, api_key: str) -> None:
34
+ self.auth = (email, api_key)
35
+
36
+ def get(self, path: str) -> requests.Response:
37
+ res = requests.get(f"{self.base_url}/{path}", auth=self.auth)
38
+ if 200 <= res.status_code < 300:
39
+ return res
40
+ raise RuntimeError("Upstash API error: %s %s" % (res.status_code, res.text))
41
+
42
+ def post(self, path: str, data: dict) -> requests.Response:
43
+ res = requests.post(f"{self.base_url}/{path}", auth=self.auth, json=data)
44
+ if 200 <= res.status_code < 300:
45
+ return res
46
+ raise RuntimeError("Upstash API error: %s %s" % (res.status_code, res.text))
47
+
48
+ def delete(self, path: str) -> requests.Response:
49
+ res = requests.delete(f"{self.base_url}/{path}", auth=self.auth)
50
+ if 200 <= res.status_code < 300:
51
+ return res
52
+ raise RuntimeError("Upstash API error: %s %s" % (res.status_code, res.text))
53
+
54
+
55
+ class Upstash:
56
+ context: UpstashContext
57
+
58
+ def __init__(self, context: UpstashContext) -> None:
59
+ self.context = context
60
+
61
+ @property
62
+ def api(self) -> UpstashApi:
63
+ if not self.context.email or not self.context.api_key:
64
+ raise UpstashResourceIsNotReady(
65
+ "UPSTASH_EMAIL と UPSTASH_API_KEY を設定してください"
66
+ )
67
+ return UpstashApi(self.context.email, self.context.api_key)
68
+
69
+ @cached_property
70
+ def database(self) -> UpstashDatabase | None:
71
+ res = self.api.get("databases")
72
+ for db in res.json():
73
+ if db["database_name"] == self.context.database_name:
74
+ return UpstashDatabase(
75
+ **{k: db[k] for k in UpstashDatabase.model_fields if k in db}
76
+ )
77
+ return None
78
+
79
+ @property
80
+ def redis_url(self) -> str:
81
+ if self.database is None:
82
+ raise UpstashResourceIsNotReady("データベースが見つかりません")
83
+ if self.database.state != "active":
84
+ raise UpstashResourceIsNotReady(
85
+ "データベースが active ではありません: %s" % self.database.state
86
+ )
87
+ protocol = "rediss" if self.database.tls else "redis"
88
+ return "%s://default:%s@%s:%d" % (
89
+ protocol,
90
+ self.database.password,
91
+ self.database.endpoint,
92
+ self.database.port,
93
+ )
94
+
95
+ @property
96
+ def status(self) -> ResourceStatus:
97
+ if self.context.skip_check_existing:
98
+ # 存在確認の Upstash API call を skip し COMPLETED 固定 (settings 参照)。
99
+ return "COMPLETED"
100
+ if self.database and self.database.state == "active":
101
+ return "COMPLETED"
102
+ return "NOEXIST"
103
+
104
+ @property
105
+ def description(self):
106
+ return "Create Upstash Redis database: %s" % self.context.database_name
107
+
108
+ def state_info(self):
109
+ return {
110
+ "upstash": {
111
+ "database_name": self.context.database_name,
112
+ }
113
+ }
114
+
115
+ def deploy_init(self):
116
+ pass
117
+
118
+ def create(self):
119
+ if self.database is not None:
120
+ echo.info(
121
+ "Upstash データベース '%s' は既に存在します"
122
+ % self.context.database_name
123
+ )
124
+ return
125
+ echo.log("Upstash データベースを作成します: %s" % self.context.database_name)
126
+ self.api.post(
127
+ "database",
128
+ {
129
+ "database_name": self.context.database_name,
130
+ "platform": "aws",
131
+ "primary_region": "ap-southeast-1",
132
+ "plan": "payg",
133
+ "budget": self.context.budget,
134
+ "tls": True,
135
+ "eviction": True,
136
+ },
137
+ )
138
+ if hasattr(self, "database"):
139
+ del self.database
140
+ echo.success(
141
+ "Upstash データベースを作成しました: %s" % self.context.database_name
142
+ )
143
+
144
+ def delete_database(self):
145
+ if self.database is None:
146
+ echo.warning("Upstash データベースが見つかりません")
147
+ return
148
+ echo.log("Upstash データベースを削除します: %s" % self.context.database_name)
149
+ self.api.delete("database/%s" % self.database.database_id)
150
+ if hasattr(self, "database"):
151
+ del self.database
152
+ echo.success("Upstash データベースを削除しました")
@@ -0,0 +1,67 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from pocket.resources.base import ResourceStatus
6
+ from pocket_cli.resources.aws.cloudformation import VpcStack
7
+ from pocket_cli.resources.aws.efs import Efs
8
+
9
+ if TYPE_CHECKING:
10
+ from pocket.general_context import VpcContext
11
+
12
+
13
+ class Vpc:
14
+ context: VpcContext
15
+
16
+ def __init__(self, context: VpcContext):
17
+ self.context = context
18
+ self.main_context = context
19
+
20
+ @property
21
+ def stack(self):
22
+ return VpcStack(self.context)
23
+
24
+ @property
25
+ def efs(self):
26
+ if self.context.efs:
27
+ return Efs(self.context.efs)
28
+
29
+ @property
30
+ def status(self) -> ResourceStatus:
31
+ return self.stack.status
32
+
33
+ @property
34
+ def vpc_id(self):
35
+ if self.stack.output:
36
+ return self.stack.output[self.stack.export["vpc_id"]]
37
+
38
+ @property
39
+ def description(self):
40
+ description = "Create aws cloudformation stack: %s" % self.stack.name
41
+ if self.efs:
42
+ description += "\nCreate efs: %s" % self.efs.context.name
43
+ return description
44
+
45
+ def state_info(self):
46
+ if self.context.efs:
47
+ return {"efs": {"name": self.context.efs.name}}
48
+ return {}
49
+
50
+ def deploy_init(self):
51
+ if self.efs:
52
+ self.efs.ensure_exists()
53
+
54
+ def create(self):
55
+ print("Creating cloudformation stack for vpc ...")
56
+ self.stack.create()
57
+
58
+ def delete(self):
59
+ if self.stack.status != "NOEXIST":
60
+ self.stack.delete()
61
+ self.stack.wait_status("NOEXIST", timeout=300, interval=10)
62
+ if self.efs and self.efs.exists():
63
+ self.efs.delete()
64
+
65
+ def update(self):
66
+ if not self.stack.yaml_synced:
67
+ self.stack.update()