cloud-dock-cli 0.1.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.
clouddock/prompts.py ADDED
@@ -0,0 +1,237 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Callable
4
+
5
+ from .config import (
6
+ CacheConfig,
7
+ CloudDockConfig,
8
+ ComputeConfig,
9
+ DatabaseConfig,
10
+ EnvironmentVariables,
11
+ validate_application_name,
12
+ validate_container_port,
13
+ validate_desired_count,
14
+ validate_image,
15
+ validate_positive_int,
16
+ validate_regions,
17
+ )
18
+
19
+
20
+ def prompt(
21
+ message: str,
22
+ default: str | None = None,
23
+ *,
24
+ validate: Callable[[str], str] | None = None,
25
+ ) -> str:
26
+ suffix = f" [{default}]" if default is not None else ""
27
+ while True:
28
+ value = input(f"{message}{suffix}: ")
29
+ if value == "" and default is not None:
30
+ return default
31
+ if value == "":
32
+ if validate is None:
33
+ return ""
34
+ try:
35
+ validate(value)
36
+ except ValueError as exc:
37
+ print(f"Error: {exc}")
38
+ continue
39
+ return value
40
+ if validate is not None:
41
+ try:
42
+ value = validate(value)
43
+ return value
44
+ except ValueError as exc:
45
+ print(f"Error: {exc}")
46
+ continue
47
+ return value
48
+
49
+
50
+ def prompt_yes_no(prompt_text: str) -> bool:
51
+ while True:
52
+ answer = input(f"{prompt_text} [Y/n]: ").strip().lower()
53
+ if answer in {"", "y", "yes"}:
54
+ return True
55
+ if answer in {"n", "no"}:
56
+ return False
57
+ print("Please answer yes or no.")
58
+
59
+
60
+ def prompt_regions() -> list[str]:
61
+ regions: list[str] = []
62
+ print("AWS regions:")
63
+ while True:
64
+ region = input("> ").strip()
65
+ if not region:
66
+ if regions:
67
+ break
68
+ print("Error: At least one region is required.")
69
+ continue
70
+ try:
71
+ regions.append(validate_regions([region])[0])
72
+ except ValueError as exc:
73
+ print(f"Error: {exc}")
74
+ continue
75
+ print(f"Added region: {region}")
76
+ return validate_regions(regions)
77
+
78
+
79
+ def prompt_compute_type() -> str:
80
+ while True:
81
+ print("Where do you want to run the application?")
82
+ print("> ECS Fargate")
83
+ print("> EKS")
84
+ choice = input("Choice: ").strip().lower()
85
+ if choice in {"ecs", "fargate", "ecs fargate"}:
86
+ return "ecs"
87
+ if choice in {"eks", "e k s"}:
88
+ return "eks"
89
+ print("Please choose ECS Fargate or EKS.")
90
+
91
+
92
+ def prompt_environment_variables() -> dict[str, str]:
93
+ values: dict[str, str] = {}
94
+ print("Environment variables")
95
+ print("Press Enter without a key to finish.")
96
+ while True:
97
+ key = input("Key: ").strip()
98
+ if not key:
99
+ break
100
+ value = input("Value: ").strip()
101
+ if not value:
102
+ value = ""
103
+ if not key:
104
+ raise ValueError("Environment variable keys cannot be empty.")
105
+ values[key] = value
106
+ return values
107
+
108
+
109
+ def collect_configuration() -> CloudDockConfig:
110
+ name = prompt("Application name:", validate=validate_application_name)
111
+ image = prompt("Docker image:", validate=validate_image)
112
+ port_input = prompt(
113
+ "Container port:",
114
+ default="8080",
115
+ validate=lambda value: str(validate_container_port(value)),
116
+ )
117
+ port = validate_container_port(port_input)
118
+
119
+ regions = prompt_regions()
120
+
121
+ compute_type = prompt_compute_type()
122
+ desired_count = prompt(
123
+ "Number of application instances:",
124
+ default="2",
125
+ validate=lambda value: str(validate_desired_count(value)),
126
+ )
127
+ cpu = prompt(
128
+ "CPU:",
129
+ default="256",
130
+ validate=lambda value: str(validate_positive_int(value, "CPU")),
131
+ )
132
+ memory = prompt(
133
+ "Memory (MB):",
134
+ default="512",
135
+ validate=lambda value: str(validate_positive_int(value, "Memory")),
136
+ )
137
+
138
+ database_enabled = prompt_yes_no("Do you need a database?")
139
+ database_type = None
140
+ if database_enabled:
141
+ while True:
142
+ db_choice = input(
143
+ "Database type [PostgreSQL/MySQL]: ").strip().lower()
144
+ if db_choice in {"postgres", "postgresql"}:
145
+ database_type = "postgres"
146
+ break
147
+ if db_choice in {"mysql"}:
148
+ database_type = "mysql"
149
+ break
150
+ print("Please choose PostgreSQL or MySQL.")
151
+
152
+ cache_enabled = prompt_yes_no("Do you need caching?")
153
+ cache_type = None
154
+ if cache_enabled:
155
+ while True:
156
+ cache_choice = input(
157
+ "Cache type [Redis/Memcached]: ").strip().lower()
158
+ if cache_choice in {"redis"}:
159
+ cache_type = "redis"
160
+ break
161
+ if cache_choice in {"memcached"}:
162
+ cache_type = "memcached"
163
+ break
164
+ print("Please choose Redis or Memcached.")
165
+
166
+ environment_variables = prompt_environment_variables()
167
+
168
+ return CloudDockConfig(
169
+ application_name=name,
170
+ image=image,
171
+ container_port=port,
172
+ regions=regions,
173
+ compute=ComputeConfig(
174
+ type=compute_type,
175
+ desired_count=int(desired_count),
176
+ cpu=int(cpu),
177
+ memory=int(memory),
178
+ ),
179
+ database=DatabaseConfig(enabled=database_enabled, type=database_type),
180
+ cache=CacheConfig(enabled=cache_enabled, type=cache_type),
181
+ environment_variables=EnvironmentVariables(environment_variables),
182
+ )
183
+
184
+
185
+ def display_name_for_compute(compute_type: str) -> str:
186
+ return "ECS Fargate" if compute_type == "ecs" else "EKS"
187
+
188
+
189
+ def display_name_for_database(database_type: str | None) -> str:
190
+ if database_type == "postgres":
191
+ return "PostgreSQL"
192
+ if database_type == "mysql":
193
+ return "MySQL"
194
+ return "Disabled"
195
+
196
+
197
+ def display_name_for_cache(cache_type: str | None) -> str:
198
+ if cache_type == "redis":
199
+ return "Redis"
200
+ if cache_type == "memcached":
201
+ return "Memcached"
202
+ return "Disabled"
203
+
204
+
205
+ def render_summary(config: CloudDockConfig) -> str:
206
+ lines = [
207
+ "CloudDock configuration",
208
+ "",
209
+ f"Application: {config.application_name}",
210
+ f"Image: {config.image}",
211
+ f"Port: {config.container_port}",
212
+ "",
213
+ "Regions:",
214
+ ]
215
+ for region in config.regions:
216
+ lines.append(f" - {region}")
217
+
218
+ lines.extend(
219
+ [
220
+ "",
221
+ "Compute:",
222
+ f" {display_name_for_compute(config.compute.type)}",
223
+ f" Instances: {config.compute.desired_count}",
224
+ f" CPU: {config.compute.cpu}",
225
+ f" Memory: {config.compute.memory} MB",
226
+ "",
227
+ "Database:",
228
+ f" {display_name_for_database(config.database.type) if config.database and config.database.enabled else 'Disabled'}",
229
+ "",
230
+ "Cache:",
231
+ f" {display_name_for_cache(config.cache.type) if config.cache and config.cache.enabled else 'Disabled'}",
232
+ "",
233
+ "Environment variables:",
234
+ f" {len(config.environment_variables.values)} configured",
235
+ ]
236
+ )
237
+ return "\n".join(lines)