atlas-init 0.1.1__py3-none-any.whl → 0.1.8__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 (73) hide show
  1. atlas_init/__init__.py +3 -3
  2. atlas_init/atlas_init.yaml +18 -1
  3. atlas_init/cli.py +62 -70
  4. atlas_init/cli_cfn/app.py +40 -117
  5. atlas_init/cli_cfn/{cfn.py → aws.py} +129 -14
  6. atlas_init/cli_cfn/cfn_parameter_finder.py +89 -6
  7. atlas_init/cli_cfn/example.py +203 -0
  8. atlas_init/cli_cfn/files.py +63 -0
  9. atlas_init/cli_helper/run.py +18 -2
  10. atlas_init/cli_helper/tf_runner.py +4 -6
  11. atlas_init/cli_root/__init__.py +0 -0
  12. atlas_init/cli_root/trigger.py +153 -0
  13. atlas_init/cli_tf/app.py +211 -4
  14. atlas_init/cli_tf/changelog.py +103 -0
  15. atlas_init/cli_tf/debug_logs.py +221 -0
  16. atlas_init/cli_tf/debug_logs_test_data.py +253 -0
  17. atlas_init/cli_tf/github_logs.py +229 -0
  18. atlas_init/cli_tf/go_test_run.py +194 -0
  19. atlas_init/cli_tf/go_test_run_format.py +31 -0
  20. atlas_init/cli_tf/go_test_summary.py +144 -0
  21. atlas_init/cli_tf/hcl/__init__.py +0 -0
  22. atlas_init/cli_tf/hcl/cli.py +161 -0
  23. atlas_init/cli_tf/hcl/cluster_mig.py +348 -0
  24. atlas_init/cli_tf/hcl/parser.py +140 -0
  25. atlas_init/cli_tf/schema.py +222 -18
  26. atlas_init/cli_tf/schema_go_parser.py +236 -0
  27. atlas_init/cli_tf/schema_table.py +150 -0
  28. atlas_init/cli_tf/schema_table_models.py +155 -0
  29. atlas_init/cli_tf/schema_v2.py +599 -0
  30. atlas_init/cli_tf/schema_v2_api_parsing.py +298 -0
  31. atlas_init/cli_tf/schema_v2_sdk.py +361 -0
  32. atlas_init/cli_tf/schema_v3.py +222 -0
  33. atlas_init/cli_tf/schema_v3_sdk.py +279 -0
  34. atlas_init/cli_tf/schema_v3_sdk_base.py +68 -0
  35. atlas_init/cli_tf/schema_v3_sdk_create.py +216 -0
  36. atlas_init/humps.py +253 -0
  37. atlas_init/repos/cfn.py +6 -1
  38. atlas_init/repos/path.py +3 -3
  39. atlas_init/settings/config.py +14 -4
  40. atlas_init/settings/env_vars.py +16 -1
  41. atlas_init/settings/path.py +12 -1
  42. atlas_init/settings/rich_utils.py +2 -0
  43. atlas_init/terraform.yaml +77 -1
  44. atlas_init/tf/.terraform.lock.hcl +59 -83
  45. atlas_init/tf/always.tf +7 -0
  46. atlas_init/tf/main.tf +3 -0
  47. atlas_init/tf/modules/aws_s3/provider.tf +1 -1
  48. atlas_init/tf/modules/aws_vars/aws_vars.tf +2 -0
  49. atlas_init/tf/modules/aws_vpc/provider.tf +4 -1
  50. atlas_init/tf/modules/cfn/cfn.tf +47 -33
  51. atlas_init/tf/modules/cfn/kms.tf +54 -0
  52. atlas_init/tf/modules/cfn/resource_actions.yaml +1 -0
  53. atlas_init/tf/modules/cfn/variables.tf +31 -0
  54. atlas_init/tf/modules/cloud_provider/cloud_provider.tf +1 -0
  55. atlas_init/tf/modules/cloud_provider/provider.tf +1 -1
  56. atlas_init/tf/modules/cluster/cluster.tf +34 -24
  57. atlas_init/tf/modules/cluster/provider.tf +1 -1
  58. atlas_init/tf/modules/federated_vars/federated_vars.tf +3 -0
  59. atlas_init/tf/modules/federated_vars/provider.tf +1 -1
  60. atlas_init/tf/modules/project_extra/project_extra.tf +15 -1
  61. atlas_init/tf/modules/stream_instance/stream_instance.tf +1 -1
  62. atlas_init/tf/modules/vpc_peering/vpc_peering.tf +1 -1
  63. atlas_init/tf/modules/vpc_privatelink/versions.tf +1 -1
  64. atlas_init/tf/outputs.tf +11 -3
  65. atlas_init/tf/providers.tf +2 -1
  66. atlas_init/tf/variables.tf +12 -0
  67. atlas_init/typer_app.py +76 -0
  68. {atlas_init-0.1.1.dist-info → atlas_init-0.1.8.dist-info}/METADATA +36 -18
  69. atlas_init-0.1.8.dist-info/RECORD +91 -0
  70. {atlas_init-0.1.1.dist-info → atlas_init-0.1.8.dist-info}/WHEEL +1 -1
  71. atlas_init-0.1.1.dist-info/RECORD +0 -62
  72. /atlas_init/tf/modules/aws_vpc/{aws-vpc.tf → aws_vpc.tf} +0 -0
  73. {atlas_init-0.1.1.dist-info → atlas_init-0.1.8.dist-info}/entry_points.txt +0 -0
atlas_init/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from pathlib import Path
2
2
 
3
- VERSION = "0.1.1"
3
+ VERSION = "0.1.8"
4
4
 
5
5
 
6
6
  def running_in_repo() -> bool:
@@ -8,5 +8,5 @@ def running_in_repo() -> bool:
8
8
  if py_directory.name != "py":
9
9
  return False
10
10
  git_directory = py_directory.parent / ".git"
11
- fetch_head = git_directory / "FETCH_HEAD"
12
- return git_directory.exists() and fetch_head.exists() and "atlas-init" in fetch_head.read_text()
11
+ git_config = git_directory / "config"
12
+ return git_directory.exists() and git_config.exists() and "atlas-init" in git_config.read_text()
@@ -6,6 +6,9 @@ test_suites:
6
6
  repo_go_packages:
7
7
  cfn:
8
8
  - cfn-resources/cluster
9
+ - name: clusterm10
10
+ vars:
11
+ cluster_info_m10: true
9
12
  - name: federated
10
13
  repo_go_packages:
11
14
  tf:
@@ -26,8 +29,16 @@ test_suites:
26
29
  use_vpc_peering: true
27
30
  use_aws_vars: true
28
31
  use_aws_vpc: true
32
+ - name: private_endpoint_regional_mode
33
+ repo_go_packages:
34
+ tf:
35
+ - internal/service/privateendpointregionalmode
36
+ vars:
37
+ use_aws_vars: true
29
38
  - name: privatelink
30
39
  repo_go_packages:
40
+ cfn:
41
+ - cfn-resources/cfn-private-endpoint-aws
31
42
  tf:
32
43
  - internal/service/privatelinkendpointservice
33
44
  vars:
@@ -37,8 +48,14 @@ test_suites:
37
48
  repo_go_packages:
38
49
  cfn:
39
50
  - cfn-resources/project
51
+ tf:
52
+ - internal/service/project
40
53
  vars:
41
54
  use_project_extra: true
55
+ - name: resource_policy
56
+ repo_go_packages:
57
+ cfn:
58
+ - cfn-resources/resource-policy
42
59
  - name: s3
43
60
  repo_go_packages:
44
61
  tf:
@@ -65,5 +82,5 @@ test_suites:
65
82
  cfn:
66
83
  - cfn-resources/stream-connection
67
84
  vars:
68
- cluster_info: true
85
+ cluster_info_m10: true
69
86
  stream_instance: true
atlas_init/cli.py CHANGED
@@ -1,20 +1,19 @@
1
1
  import logging
2
- import os
3
- import sys
4
2
  from collections.abc import Callable
5
- from functools import partial
3
+ from pathlib import Path
6
4
  from pydoc import locate
5
+ from typing import Literal
7
6
 
8
7
  import typer
8
+ from model_lib import dump, parse_payload
9
9
  from zero_3rdparty.file_utils import iter_paths
10
10
 
11
- from atlas_init import running_in_repo
12
- from atlas_init.cli_cfn.app import app as app_cfn
13
11
  from atlas_init.cli_helper import sdk_auto_changes
14
12
  from atlas_init.cli_helper.go import run_go_tests
15
13
  from atlas_init.cli_helper.run import (
16
14
  run_binary_command_is_ok,
17
15
  run_command_exit_on_failure,
16
+ run_command_receive_result,
18
17
  )
19
18
  from atlas_init.cli_helper.sdk import (
20
19
  SDK_VERSION_HELP,
@@ -33,7 +32,6 @@ from atlas_init.cli_helper.tf_runner import (
33
32
  get_tf_vars,
34
33
  run_terraform,
35
34
  )
36
- from atlas_init.cli_tf.app import app as app_tf
37
35
  from atlas_init.repos.go_sdk import go_sdk_breaking_changes
38
36
  from atlas_init.repos.path import (
39
37
  Repo,
@@ -45,11 +43,7 @@ from atlas_init.repos.path import (
45
43
  )
46
44
  from atlas_init.settings.config import RepoAliasNotFoundError
47
45
  from atlas_init.settings.env_vars import (
48
- DEFAULT_PROFILE,
49
- AtlasInitSettings,
50
46
  active_suites,
51
- as_env_var_name,
52
- env_var_names,
53
47
  init_settings,
54
48
  )
55
49
  from atlas_init.settings.path import (
@@ -57,58 +51,9 @@ from atlas_init.settings.path import (
57
51
  dump_vscode_dotenv,
58
52
  repo_path_rel_path,
59
53
  )
60
- from atlas_init.settings.rich_utils import configure_logging, hide_secrets
54
+ from atlas_init.typer_app import app, app_command, extra_root_commands
61
55
 
62
56
  logger = logging.getLogger(__name__)
63
- app = typer.Typer(name="atlas_init", invoke_without_command=True, no_args_is_help=True)
64
- app.add_typer(app_cfn, name="cfn")
65
- app.add_typer(app_tf, name="tf")
66
-
67
- app_command = partial(
68
- app.command,
69
- context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
70
- )
71
-
72
-
73
- @app.callback(invoke_without_command=True)
74
- def main(
75
- ctx: typer.Context,
76
- log_level: str = typer.Option("INFO", help="use one of [INFO, WARNING, ERROR, CRITICAL]"),
77
- profile: str = typer.Option(
78
- DEFAULT_PROFILE,
79
- "-p",
80
- "--profile",
81
- envvar=env_var_names("profile"),
82
- help="used to load .env_manual, store terraform state and variables, and dump .env files.",
83
- ),
84
- project_name: str = typer.Option(
85
- "",
86
- "--project",
87
- envvar=env_var_names("project_name"),
88
- help="atlas project name to create",
89
- ),
90
- ):
91
- explicit_env_vars: dict[str, str] = {}
92
- if project_name != "":
93
- explicit_env_vars[as_env_var_name("project_name")] = project_name
94
- log_handler = configure_logging(log_level)
95
- logger.info(f"running in repo: {running_in_repo()} python location:{sys.executable}")
96
- missing_env_vars, ambiguous_env_vars = AtlasInitSettings.check_env_vars(
97
- profile,
98
- required_extra_fields=["project_name"],
99
- explicit_env_vars=explicit_env_vars,
100
- )
101
- if missing_env_vars:
102
- typer.echo(f"missing env_vars: {missing_env_vars}")
103
- if ambiguous_env_vars:
104
- typer.echo(
105
- f"amiguous env_vars: {missing_env_vars} (specified both in cli & in .env-manual file with different values)"
106
- )
107
- if missing_env_vars or ambiguous_env_vars:
108
- raise typer.Exit(1)
109
- hide_secrets(log_handler, {**os.environ})
110
- command = ctx.invoked_subcommand
111
- logger.info(f"in the app callback, log-level: {log_level}, command: {command}")
112
57
 
113
58
 
114
59
  @app_command()
@@ -119,12 +64,19 @@ def init(context: typer.Context):
119
64
  run_terraform(settings, "init", extra_args)
120
65
 
121
66
 
67
+ @app_command()
68
+ def plan(context: typer.Context, *, skip_outputs: bool = False):
69
+ _plan_or_apply(context.args, "plan", skip_outputs=skip_outputs)
70
+
71
+
122
72
  @app_command()
123
73
  def apply(context: typer.Context, *, skip_outputs: bool = False):
74
+ _plan_or_apply(context.args, "apply", skip_outputs=skip_outputs)
75
+
76
+
77
+ def _plan_or_apply(extra_args: list[str], command: Literal["plan", "apply"], *, skip_outputs: bool):
124
78
  settings = init_settings()
125
- extra_args = context.args
126
- logger.info(f"apply extra args: {extra_args}")
127
- logger.info("in the apply command")
79
+ logger.info(f"using the '{command}' command, extra args: {extra_args}")
128
80
  try:
129
81
  suites = active_suites(settings)
130
82
  except (CwdIsNoRepoPathError, RepoAliasNotFoundError) as e:
@@ -135,7 +87,7 @@ def apply(context: typer.Context, *, skip_outputs: bool = False):
135
87
  dump_tf_vars(settings, tf_vars)
136
88
 
137
89
  try:
138
- run_terraform(settings, "apply", extra_args)
90
+ run_terraform(settings, command, extra_args)
139
91
  except TerraformRunError as e:
140
92
  logger.error(repr(e)) # noqa: TRY400
141
93
  raise typer.Exit(1) from e
@@ -198,8 +150,10 @@ def sdk_upgrade(
198
150
 
199
151
  sdk_breaking_changes_path = go_sdk_breaking_changes(repo_path)
200
152
  all_breaking_changes = parse_breaking_changes(sdk_breaking_changes_path, old, new)
201
- replace_in = f"go.mongodb.org/atlas-sdk/{old}/admin"
202
- replace_out = f"go.mongodb.org/atlas-sdk/{new}/admin"
153
+ replacements = {
154
+ f"go.mongodb.org/atlas-sdk/{old}/mockadmin": f"go.mongodb.org/atlas-sdk/{new}/mockadmin",
155
+ f"go.mongodb.org/atlas-sdk/{old}/admin": f"go.mongodb.org/atlas-sdk/{new}/admin",
156
+ }
203
157
  auto_modifier: Callable[[str, str], str] | None = None
204
158
  if auto_change_name:
205
159
  func_path = f"{sdk_auto_changes.__name__}.{auto_change_name}"
@@ -210,7 +164,7 @@ def sdk_upgrade(
210
164
  resources_breaking_changes: set[str] = set()
211
165
  for path in iter_paths(repo_path, "*.go", ".mockery.yaml"):
212
166
  text_old = path.read_text()
213
- if replace_in not in text_old:
167
+ if all(replace_in not in text_old for replace_in in replacements):
214
168
  continue
215
169
  r_name = resource_name(repo_path, path)
216
170
  if resource and resource != r_name:
@@ -222,7 +176,9 @@ def sdk_upgrade(
222
176
  logger.warning(f"found breaking changes: {changes_formatted}")
223
177
  if is_removed(breaking_changes):
224
178
  resources_breaking_changes.add(r_name)
225
- text_new = text_old.replace(replace_in, replace_out)
179
+ text_new = text_old
180
+ for replace_in, replace_out in replacements.items():
181
+ text_new = text_new.replace(replace_in, replace_out)
226
182
  if not dry_run:
227
183
  if auto_modifier:
228
184
  text_new = auto_modifier(text_new, old)
@@ -249,18 +205,22 @@ def sdk_upgrade(
249
205
  def pre_commit(
250
206
  skip_build: bool = typer.Option(default=False),
251
207
  skip_lint: bool = typer.Option(default=False),
208
+ max_issues: int = typer.Option(1000, "-m", "--max"),
252
209
  ):
210
+ golang_ci_lint_args = f"--max-same-issues {max_issues} --max-issues-per-linter {max_issues}"
253
211
  match current_repo():
254
212
  case Repo.CFN:
255
213
  repo_path, resource_path, r_name = find_paths()
256
214
  build_cmd = f"cd {resource_path} && make build"
257
215
  # TODO: understand why piping to grep doesn't work
258
216
  # f"golangci-lint run --path-prefix=./cfn-resources | grep {r_name}"
259
- format_cmd_str = "cd cfn-resources && golangci-lint run --path-prefix=./cfn-resources"
217
+ format_cmd_str = (
218
+ f"cd cfn-resources && golangci-lint run --path-prefix=./cfn-resources {golang_ci_lint_args}"
219
+ )
260
220
  case Repo.TF:
261
221
  repo_path = current_repo_path()
262
222
  build_cmd = "make build"
263
- format_cmd_str = "golangci-lint run"
223
+ format_cmd_str = f"golangci-lint run {golang_ci_lint_args}"
264
224
  case _:
265
225
  raise NotImplementedError
266
226
  if skip_build:
@@ -273,7 +233,39 @@ def pre_commit(
273
233
  run_command_exit_on_failure(format_cmd_str, cwd=repo_path, logger=logger)
274
234
 
275
235
 
236
+ @app_command()
237
+ def repo_dump():
238
+ code_root = Path.home() / "code"
239
+ path_urls = {}
240
+ for repo_git_path in iter_paths(code_root, ".git", exclude_folder_names=[".terraform"]):
241
+ repo_path = repo_git_path.parent
242
+ logger.info(f"repo: {repo_path}")
243
+ url = run_command_receive_result("git remote get-url origin", cwd=repo_path, logger=logger, can_fail=True)
244
+ if url.startswith("FAIL:"):
245
+ continue
246
+ path_urls[str(repo_path)] = url
247
+ out_path = code_root / "repos.json"
248
+ repos_json = dump(path_urls, "pretty_json")
249
+ out_path.write_text(repos_json)
250
+
251
+
252
+ @app_command()
253
+ def repo_clone():
254
+ repos_file = Path.home() / "code" / "repos.json"
255
+ repo_path_json: dict[str, str] = parse_payload(repos_file) # type: ignore
256
+ for repo_path_str, url in repo_path_json.items():
257
+ logger.info(f"cloning {url} @ {repo_path_str}")
258
+ repo_path = Path(repo_path_str)
259
+ parent_dir = repo_path.parent
260
+ parent_dir.mkdir(parents=True, exist_ok=True)
261
+ if repo_path.exists():
262
+ logger.warning(f"skipping {repo_path}, already exists")
263
+ continue
264
+ run_command_exit_on_failure(f"git clone {url} {repo_path.name}", cwd=parent_dir, logger=logger)
265
+
266
+
276
267
  def typer_main():
268
+ extra_root_commands()
277
269
  app()
278
270
 
279
271
 
atlas_init/cli_cfn/app.py CHANGED
@@ -1,42 +1,35 @@
1
1
  import logging
2
2
  import os
3
- from pathlib import Path
4
3
 
5
4
  import typer
6
- from model_lib import dump, parse_payload
7
- from rich import prompt
5
+ from model_lib import parse_payload
8
6
  from zero_3rdparty.file_utils import clean_dir
9
7
 
10
- from atlas_init.cli_args import parse_key_values, parse_key_values_any
11
- from atlas_init.cli_cfn.cfn import (
8
+ from atlas_init.cli_cfn.aws import (
12
9
  activate_resource_type,
13
- create_stack,
14
10
  deactivate_third_party_type,
15
- delete_stack,
16
11
  deregister_cfn_resource_type,
17
12
  get_last_cfn_type,
18
- update_stack,
13
+ wait_on_stack_ok,
14
+ )
15
+ from atlas_init.cli_cfn.aws import (
16
+ delete_stack as delete_stack_aws,
19
17
  )
20
18
  from atlas_init.cli_cfn.cfn_parameter_finder import (
21
- check_execution_role,
22
- decode_parameters,
23
- infer_template_path,
24
19
  read_execution_role,
25
20
  )
21
+ from atlas_init.cli_cfn.example import example_cmd
22
+ from atlas_init.cli_cfn.files import create_sample_file, has_md_link, iterate_schemas
26
23
  from atlas_init.cli_helper.run import run_command_is_ok
27
24
  from atlas_init.cloud.aws import run_in_regions
28
25
  from atlas_init.repos.cfn import (
29
- CfnOperation,
30
- CfnType,
31
- Operation,
32
- infer_cfn_type_name,
33
26
  validate_type_name_regions,
34
27
  )
35
- from atlas_init.repos.path import Repo, current_dir, find_paths
28
+ from atlas_init.repos.path import Repo, current_dir, find_paths, resource_root
36
29
  from atlas_init.settings.env_vars import active_suites, init_settings
37
- from atlas_init.settings.interactive import confirm
38
30
 
39
31
  app = typer.Typer(no_args_is_help=True)
32
+ app.command(name="example")(example_cmd)
40
33
  logger = logging.getLogger(__name__)
41
34
 
42
35
 
@@ -92,104 +85,6 @@ def dereg(
92
85
  run_in_regions(deactivate, regions)
93
86
 
94
87
 
95
- @app.command()
96
- def example(
97
- type_name: str = typer.Argument(default_factory=infer_cfn_type_name),
98
- region: str = typer.Argument(...),
99
- stack_name: str = typer.Argument(...),
100
- operation: str = typer.Argument(...),
101
- params: list[str] = typer.Option(..., "-p", default_factory=list),
102
- resource_params: list[str] = typer.Option(..., "-r", default_factory=list),
103
- stack_timeout_s: int = typer.Option(300, "-t", "--stack-timeout-s"),
104
- ):
105
- params_parsed: dict[str, str] = {}
106
- if params:
107
- params_parsed = parse_key_values(params)
108
- resource_params_parsed = {}
109
- if resource_params:
110
- resource_params_parsed = parse_key_values_any(resource_params)
111
- if resource_params_parsed:
112
- logger.info(f"using resource params: {resource_params_parsed}")
113
- logger.info(f"about to update stack {stack_name} for {type_name} in {region} with {operation}, params: {params}")
114
- settings = init_settings()
115
- type_name, region = CfnType.validate_type_region(type_name, region) # type: ignore
116
- CfnOperation(operaton=operation) # type: ignore
117
- repo_path, resource_path, _ = find_paths(Repo.CFN)
118
- env_vars_generated = settings.load_env_vars_generated()
119
- cfn_execution_role = check_execution_role(repo_path, env_vars_generated)
120
-
121
- cfn_type_details = get_last_cfn_type(type_name, region, is_third_party=False)
122
- logger.info(f"found cfn_type_details {cfn_type_details} for {type_name}")
123
- submit_cmd = f"cfn submit --verbose --set-default --region {region} --role-arn {cfn_execution_role}"
124
- if cfn_type_details is None and confirm(
125
- f"No existing {type_name} found, ok to run:\n{submit_cmd}\nsubmit?",
126
- is_interactive=settings.is_interactive,
127
- default=True,
128
- ):
129
- assert run_command_is_ok(cmd=submit_cmd.split(), env=None, cwd=resource_path, logger=logger)
130
- cfn_type_details = get_last_cfn_type(type_name, region, is_third_party=False)
131
- assert cfn_type_details, f"no cfn_type_details found for {type_name}"
132
-
133
- if operation == Operation.DELETE:
134
- delete_stack(region, stack_name)
135
- return
136
- template_path = infer_template_path(repo_path, type_name, stack_name)
137
- template_path, parameters, not_found = decode_parameters(
138
- exported_env_vars=env_vars_generated,
139
- template_path=template_path,
140
- stack_name=stack_name,
141
- force_params=params_parsed,
142
- resource_params=resource_params_parsed,
143
- type_name=type_name,
144
- )
145
- logger.info(f"parameters: {parameters}")
146
- if not_found:
147
- # TODO: support specifying these extra
148
- logger.critical(f"need to fill out parameters manually: {not_found} for {type_name}")
149
- raise typer.Exit(1)
150
- if not prompt.Confirm("parameters 👆looks good?")():
151
- raise typer.Exit(1)
152
- if operation == Operation.CREATE:
153
- create_stack(
154
- stack_name,
155
- template_str=template_path.read_text(),
156
- region_name=region,
157
- role_arn=cfn_execution_role,
158
- parameters=parameters,
159
- timeout_seconds=stack_timeout_s,
160
- )
161
- elif operation == Operation.UPDATE:
162
- update_stack(
163
- stack_name,
164
- template_str=template_path.read_text(),
165
- region_name=region,
166
- parameters=parameters,
167
- role_arn=cfn_execution_role,
168
- timeout_seconds=stack_timeout_s,
169
- )
170
- else:
171
- raise NotImplementedError
172
-
173
-
174
- def _create_sample_file(
175
- samples_file: Path,
176
- log_group_name: str,
177
- resource_state: dict,
178
- prev_resource_state: dict | None = None,
179
- ):
180
- logger.info(f"adding sample @ {samples_file}")
181
- assert isinstance(resource_state, dict)
182
- new_json = dump(
183
- {
184
- "providerLogGroupName": log_group_name,
185
- "previousResourceState": prev_resource_state or {},
186
- "desiredResourceState": resource_state,
187
- },
188
- "json",
189
- )
190
- samples_file.write_text(new_json)
191
-
192
-
193
88
  @app.command()
194
89
  def inputs(
195
90
  context: typer.Context,
@@ -240,11 +135,11 @@ def inputs(
240
135
  assert isinstance(resource_state, dict), f"input file with not a dict {resource_state}"
241
136
  samples_file = samples_dir / file.name
242
137
  if file.name.endswith("_create.json"):
243
- _create_sample_file(samples_file, log_group_name, resource_state)
138
+ create_sample_file(samples_file, log_group_name, resource_state)
244
139
  if file.name.endswith("_update.json"):
245
140
  prev_state_path = file.parent / file.name.replace("_update.json", "_create.json")
246
141
  prev_state: dict = parse_payload(prev_state_path) # type: ignore
247
- _create_sample_file(
142
+ create_sample_file(
248
143
  samples_file,
249
144
  log_group_name,
250
145
  resource_state,
@@ -256,3 +151,31 @@ def inputs(
256
151
  new_filename = inputs_dir / new_name
257
152
  file.rename(new_filename)
258
153
  logger.info(f"renamed from {file} -> {new_filename}")
154
+
155
+
156
+ @app.command()
157
+ def gen_docs():
158
+ repo_path, *_ = find_paths(Repo.CFN)
159
+ root = resource_root(repo_path)
160
+ for path, schema in iterate_schemas(root):
161
+ if has_md_link(schema.description):
162
+ logger.warning(f"found md link in {schema.type_name} in {path}")
163
+
164
+
165
+ @app.command()
166
+ def wait_on_stack(
167
+ stack_name: str = typer.Argument(...),
168
+ region: str = typer.Argument(...),
169
+ timeout_s: int = typer.Option(300, "-t", "--timeout-seconds"),
170
+ ):
171
+ wait_on_stack_ok(stack_name, region, timeout_seconds=timeout_s)
172
+ logger.info(f"stack {stack_name} in {region} is ready ✅")
173
+
174
+
175
+ @app.command()
176
+ def delete_stack(
177
+ stack_name: str = typer.Argument(...),
178
+ region: str = typer.Argument(...),
179
+ ):
180
+ delete_stack_aws(region, stack_name)
181
+ logger.info(f"stack {stack_name} in {region} is deleted ✅")