atlas-init 0.1.8__py3-none-any.whl → 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.
atlas_init/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  from pathlib import Path
2
2
 
3
- VERSION = "0.1.8"
3
+ VERSION = "0.2.0"
4
4
 
5
5
 
6
6
  def running_in_repo() -> bool:
atlas_init/cli_args.py CHANGED
@@ -1,8 +1,11 @@
1
1
  from typing import Any
2
2
 
3
+ import typer
3
4
  from model_lib import parse_payload
4
5
  from zero_3rdparty.iter_utils import key_equal_value_to_dict
5
6
 
7
+ option_sdk_repo_path = typer.Option("", "-sdk", "--sdk-repo-path", help="the path to the sdk repo")
8
+
6
9
 
7
10
  def parse_key_values(params: list[str]) -> dict[str, str]:
8
11
  return key_equal_value_to_dict(params)
atlas_init/cli_tf/app.py CHANGED
@@ -9,6 +9,7 @@ import typer
9
9
  from zero_3rdparty.datetime_utils import utc_now
10
10
  from zero_3rdparty.file_utils import clean_dir
11
11
 
12
+ from atlas_init.cli_args import option_sdk_repo_path
12
13
  from atlas_init.cli_helper.run import (
13
14
  add_to_clipboard,
14
15
  run_binary_command_is_ok,
@@ -27,6 +28,7 @@ from atlas_init.cli_tf.go_test_summary import (
27
28
  create_detailed_summary,
28
29
  create_short_summary,
29
30
  )
31
+ from atlas_init.cli_tf.mock_tf_log import mock_tf_log_cmd
30
32
  from atlas_init.cli_tf.schema import (
31
33
  download_admin_api,
32
34
  dump_generator_config,
@@ -45,6 +47,7 @@ from atlas_init.settings.env_vars import init_settings
45
47
  from atlas_init.settings.interactive import confirm
46
48
 
47
49
  app = typer.Typer(no_args_is_help=True)
50
+ app.command(name="mock-tf-log")(mock_tf_log_cmd)
48
51
  logger = logging.getLogger(__name__)
49
52
 
50
53
 
@@ -224,7 +227,7 @@ def schema2(
224
227
  ),
225
228
  config_path: Path = typer.Option("", "-c", "--config", help="the path to the SchemaV2 config"),
226
229
  replace: bool = typer.Option(False, "-r", "--replace", help="replace the existing schema file"),
227
- sdk_repo_path_str: str = typer.Option("", "-sdk", "--sdk-repo-path", help="the path to the sdk repo"),
230
+ sdk_repo_path_str: str = option_sdk_repo_path,
228
231
  ):
229
232
  repo_path = current_repo_path(Repo.TF)
230
233
  config_path = config_path or repo_path / "schema_v2.yaml"
@@ -2,6 +2,7 @@ import json
2
2
  import logging
3
3
  import re
4
4
  from contextlib import suppress
5
+ from functools import total_ordering
5
6
  from typing import Any, NamedTuple, Self
6
7
 
7
8
  from model_lib import Entity
@@ -83,6 +84,7 @@ def extract_version(content_type: str) -> str:
83
84
  raise ValueError(f"Could not extract version from {content_type} header")
84
85
 
85
86
 
87
+ @total_ordering
86
88
  class SDKRoundtrip(Entity):
87
89
  request: PathHeadersPayload
88
90
  response: StatusHeadersResponse
@@ -112,6 +114,11 @@ class SDKRoundtrip(Entity):
112
114
  raise ValueError(f"Expected list response but got dict: {resp.text}")
113
115
  return self
114
116
 
117
+ def __lt__(self, other) -> bool:
118
+ if not isinstance(other, SDKRoundtrip):
119
+ raise TypeError
120
+ return self.resp_index < other.resp_index
121
+
115
122
 
116
123
  MARKER_END = "-----------------------------------"
117
124
  MARKER_REQUEST_START = "---[ REQUEST ]"
@@ -126,6 +133,19 @@ class FileRef(NamedTuple):
126
133
  line_end: int
127
134
 
128
135
 
136
+ _name_extract = re.compile(r"test_name=(\S+)")
137
+
138
+
139
+ def parse_test_name(logs: str) -> str:
140
+ test_count = logs.count(MARKER_TEST)
141
+ assert test_count == 1, f"Only one test is supported, found {test_count}"
142
+ test_start = logs.index(MARKER_TEST)
143
+ full_line = logs[test_start:].split("\n", maxsplit=1)[0]
144
+ if match := _name_extract.search(full_line):
145
+ return match.group(1)
146
+ raise ValueError(f"Could not extract test name from {full_line}")
147
+
148
+
129
149
  def parse_http_requests(logs: str) -> list[SDKRoundtrip]:
130
150
  """
131
151
  Problem: With requests that are done in parallel.
@@ -138,8 +158,8 @@ def parse_http_requests(logs: str) -> list[SDKRoundtrip]:
138
158
  Method: (accepted)
139
159
  Can say that expected payload is either a list or a dict and if it ends with an identifier it is higher chance for a dict
140
160
  """
141
- test_count = logs.count(MARKER_TEST)
142
- assert test_count == 1, f"Only one test is supported, found {test_count}"
161
+ test_name = parse_test_name(logs)
162
+ logger.info(f"Finding http requests for test name: {test_name}")
143
163
  requests, responses = parse_raw_req_responses(logs)
144
164
  tf_step_starts = [i for i, line in enumerate(logs.splitlines()) if MARKER_START_STEP in line]
145
165
  used_responses: set[int] = set()
@@ -149,7 +169,7 @@ def parse_http_requests(logs: str) -> list[SDKRoundtrip]:
149
169
  roundtrip = match_request(used_responses, responses_list, ref, request, tf_step_starts)
150
170
  sdk_roundtrips.append(roundtrip)
151
171
  used_responses.add(roundtrip.resp_index)
152
- return sdk_roundtrips
172
+ return sorted(sdk_roundtrips)
153
173
 
154
174
 
155
175
  def find_step_number(ref: FileRef, step_starts: list[int]) -> int:
@@ -172,7 +192,12 @@ def match_request(
172
192
  continue
173
193
  with suppress(ValidationError):
174
194
  step_number = find_step_number(ref, step_starts)
175
- return SDKRoundtrip(request=request, response=response, resp_index=i, step_number=step_number)
195
+ return SDKRoundtrip(
196
+ request=request,
197
+ response=response,
198
+ resp_index=i,
199
+ step_number=step_number,
200
+ )
176
201
  remaining_responses = [resp for i, resp in enumerate(responses_list) if i not in used_responses]
177
202
  err_msg = f"Could not match request {ref} with any response\n\n{request}\n\n\nThere are #{len(remaining_responses)} responses left that doesn't match\n{'-'*80}\n{'\n'.join(r.text for r in remaining_responses)}"
178
203
  raise ValueError(err_msg)
@@ -12,8 +12,10 @@ logger = logging.getLogger(__name__)
12
12
 
13
13
 
14
14
  class StatusText(Entity):
15
+ response_index: int
15
16
  status: int
16
17
  text: str
18
+ duplicate_responses: int | None = None
17
19
 
18
20
  @property
19
21
  def id(self):
@@ -21,9 +23,9 @@ class StatusText(Entity):
21
23
 
22
24
 
23
25
  class RequestInfo(Entity):
24
- version: str
25
- method: str
26
26
  path: str
27
+ method: str
28
+ version: str
27
29
  text: str
28
30
  responses: list[StatusText] = Field(default_factory=list)
29
31
 
@@ -43,6 +45,10 @@ class StepRequests(Entity):
43
45
  diff_requests: list[RequestInfo] = Field(default_factory=list)
44
46
  request_responses: list[RequestInfo] = Field(default_factory=list)
45
47
 
48
+ @property
49
+ def all_requests(self):
50
+ return self.diff_requests + self.request_responses
51
+
46
52
  def existing_request(self, info: RequestInfo) -> RequestInfo | None:
47
53
  return next((r for r in self.request_responses if r.id == info.id), None)
48
54
 
@@ -55,8 +61,9 @@ class StepRequests(Entity):
55
61
  text: str,
56
62
  text_response: str,
57
63
  is_diff: bool,
64
+ response_index: int,
58
65
  ):
59
- status_text = StatusText(status=status, text=text_response)
66
+ status_text = StatusText(status=status, text=text_response, response_index=response_index)
60
67
  info = RequestInfo(
61
68
  path=path,
62
69
  method=method,
@@ -111,6 +118,7 @@ class MockRequestData(Entity):
111
118
  normalized_text,
112
119
  normalized_response_text,
113
120
  is_diff,
121
+ rt.resp_index,
114
122
  )
115
123
 
116
124
  def update_variables(self, variables: dict[str, str]) -> None:
@@ -139,21 +147,32 @@ class MockRequestData(Entity):
139
147
  if changes:
140
148
  raise VariablesChangedError(changes)
141
149
 
150
+ def replace_text_variables(self):
151
+ for step in self.steps:
152
+ for request in step.all_requests:
153
+ request.text = normalize_text(request.text, self.variables)
154
+ for response in request.responses:
155
+ response.text = normalize_text(response.text, self.variables)
156
+
142
157
  def prune_duplicate_responses(self):
143
158
  for step in self.steps:
144
159
  for request in step.request_responses:
145
160
  pruned_responses = []
146
- seen_response_ids = set()
161
+ seen_response_ids: dict[str, StatusText] = {}
147
162
  before_len = len(request.responses)
148
163
  for response in request.responses:
149
- if response.id in seen_response_ids:
164
+ if existing_response := seen_response_ids.get(response.id):
165
+ if existing_response.duplicate_responses is None:
166
+ existing_response.duplicate_responses = 0
167
+ existing_response.duplicate_responses += 1
150
168
  continue
151
- seen_response_ids.add(response.id)
169
+ seen_response_ids[response.id] = response
152
170
  pruned_responses.append(response)
153
171
  request.responses = pruned_responses
154
172
  after_len = len(request.responses)
155
- if before_len != after_len:
156
- logger.info(f"Pruned {before_len - after_len} duplicate responses from {request.id}")
173
+ duplicate_responses = before_len - after_len
174
+ if duplicate_responses > 0:
175
+ logger.info(f"Pruned {duplicate_responses} duplicate responses from {request.id}")
157
176
 
158
177
 
159
178
  class ApiSpecPath(Entity):
@@ -204,7 +223,7 @@ def normalize_text(text: str, variables: dict[str, str]) -> str:
204
223
 
205
224
 
206
225
  def default_is_diff(rt: SDKRoundtrip) -> bool:
207
- return rt.request.method not in {"DELETE", "GET"}
226
+ return rt.request.method not in {"GET"}
208
227
 
209
228
 
210
229
  class VariableChange(NamedTuple):
@@ -225,6 +244,8 @@ def create_mock_data(
225
244
  api_spec_paths: dict[str, list[ApiSpecPath]],
226
245
  is_diff: Callable[[SDKRoundtrip], bool] | None = None,
227
246
  modifiers: list[RTModifier] | None = None,
247
+ *,
248
+ prune_duplicates: bool = True,
228
249
  ) -> MockRequestData:
229
250
  steps = max(rt.step_number for rt in roundtrips)
230
251
  mock_data = MockRequestData(step_count=steps)
@@ -246,8 +267,10 @@ def create_mock_data(
246
267
  for modifier in modifiers:
247
268
  if modifier.match(rt, normalized_path):
248
269
  modifier.modification(rt)
249
- normalized_text = normalize_text(rt.request.text, rt_variables)
250
- normalized_response_text = normalize_text(rt.response.text, rt_variables)
270
+ normalized_text = normalize_text(rt.request.text, mock_data.variables)
271
+ normalized_response_text = normalize_text(rt.response.text, mock_data.variables)
251
272
  mock_data.add_roundtrip(rt, normalized_path, normalized_text, normalized_response_text, is_diff(rt))
252
- # requests.prune_duplicate_responses() better to keep duplicates to stay KISS
273
+ mock_data.replace_text_variables()
274
+ if prune_duplicates:
275
+ mock_data.prune_duplicate_responses() # better to keep duplicates to stay KISS
253
276
  return mock_data
@@ -0,0 +1,85 @@
1
+ import json
2
+ import logging
3
+ from pathlib import Path
4
+ from typing import Self
5
+
6
+ import typer
7
+ from model_lib import Entity, dump
8
+ from pydantic import Field, model_validator
9
+ from zero_3rdparty import file_utils
10
+
11
+ from atlas_init.cli_args import option_sdk_repo_path
12
+ from atlas_init.cli_tf.debug_logs import (
13
+ SDKRoundtrip,
14
+ parse_http_requests,
15
+ parse_test_name,
16
+ )
17
+ from atlas_init.cli_tf.debug_logs_test_data import create_mock_data, default_is_diff
18
+ from atlas_init.repos.go_sdk import parse_api_spec_paths
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ class MockTFLog(Entity):
24
+ log_path: Path
25
+ output_dir: Path
26
+ sdk_path: Path
27
+ diff_skip_suffixes: list[str] = Field(default_factory=list)
28
+ keep_duplicates: bool = False
29
+
30
+ @model_validator(mode="after")
31
+ def ensure_paths_exist(self) -> Self:
32
+ if not self.log_path.exists():
33
+ raise ValueError(f"log_path: {self.log_path} doesn't exist")
34
+ if not self.sdk_path.exists():
35
+ raise ValueError(f"sdk_path: {self.sdk_path} doesn't exist")
36
+ if not self.output_dir.exists():
37
+ raise ValueError(f"output_dir: {self.output_dir} doesn't exist")
38
+ assert self.output_dir.name == "testdata", "output_path should be a directory named testdata"
39
+ return self
40
+
41
+ def differ(self, rt: SDKRoundtrip) -> bool:
42
+ return default_is_diff(rt) and not any(rt.request.path.endswith(suffix) for suffix in self.diff_skip_suffixes)
43
+
44
+
45
+ def mock_tf_log(req: MockTFLog) -> None:
46
+ log_file_text = req.log_path.read_text()
47
+ test_name = parse_test_name(log_file_text)
48
+ roundtrips = parse_http_requests(log_file_text)
49
+ api_spec_paths = parse_api_spec_paths(req.sdk_path)
50
+ data = create_mock_data(
51
+ roundtrips,
52
+ api_spec_paths,
53
+ is_diff=req.differ,
54
+ prune_duplicates=not req.keep_duplicates,
55
+ )
56
+ # avoid anchors
57
+ data_yaml = dump(json.loads(dump(data, "json")), "yaml")
58
+ output_path = req.output_dir / f"{test_name}.yaml"
59
+ logger.info(f"Writing to {output_path}")
60
+ file_utils.ensure_parents_write_text(output_path, data_yaml)
61
+
62
+
63
+ def mock_tf_log_cmd(
64
+ log_path: str = typer.Argument(..., help="the path to the log file generated with TF_LOG_PATH"),
65
+ sdk_repo_path_str: str = option_sdk_repo_path,
66
+ output_testdir: str = typer.Option(
67
+ "",
68
+ "-o",
69
+ "--output-testdir",
70
+ help="the path to the output test directory, for example: internal/service/advancedclustertpf/testdata/",
71
+ ),
72
+ diff_skip_suffixes: list[str] = typer.Option(..., "-s", "--skip-suffixes", default_factory=list),
73
+ keep_duplicates: bool = typer.Option(False, "-keep", "--keep-duplicates", help="keep duplicate requests"),
74
+ ):
75
+ cwd = Path.cwd()
76
+ default_sdk_path = cwd.parent / "atlas-sdk-go"
77
+ default_testdir = cwd.parent / "testdata"
78
+ event_in = MockTFLog(
79
+ log_path=Path(log_path),
80
+ output_dir=Path(output_testdir) if output_testdir else default_testdir,
81
+ sdk_path=Path(sdk_repo_path_str) if sdk_repo_path_str else default_sdk_path,
82
+ diff_skip_suffixes=diff_skip_suffixes,
83
+ keep_duplicates=keep_duplicates,
84
+ )
85
+ mock_tf_log(event_in)
@@ -1,5 +1,11 @@
1
+ from collections import defaultdict
1
2
  from pathlib import Path
2
3
 
4
+ from model_lib import parse_model
5
+
6
+ from atlas_init.cli_tf.debug_logs_test_data import ApiSpecPath
7
+ from atlas_init.cli_tf.schema_v2_api_parsing import OpenapiSchema
8
+
3
9
 
4
10
  def go_sdk_breaking_changes(repo_path: Path, go_sdk_rel_path: str = "../atlas-sdk-go") -> Path:
5
11
  rel_path = "tools/releaser/breaking_changes"
@@ -7,3 +13,13 @@ def go_sdk_breaking_changes(repo_path: Path, go_sdk_rel_path: str = "../atlas-sd
7
13
  breaking_changes_dir = breaking_changes_dir.absolute()
8
14
  assert breaking_changes_dir.exists(), f"not found breaking_changes={breaking_changes_dir}"
9
15
  return breaking_changes_dir
16
+
17
+
18
+ def parse_api_spec_paths(sdk_repo_path: Path) -> dict[str, list[ApiSpecPath]]:
19
+ api_spec_path = sdk_repo_path / "openapi/atlas-api-transformed.yaml"
20
+ model = parse_model(api_spec_path, t=OpenapiSchema)
21
+ paths: dict[str, list[ApiSpecPath]] = defaultdict(list)
22
+ for path, path_dict in model.paths.items():
23
+ for method in path_dict:
24
+ paths[method.upper()].append(ApiSpecPath(path=path))
25
+ return paths
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: atlas-init
3
- Version: 0.1.8
3
+ Version: 0.2.0
4
4
  Project-URL: Documentation, https://github.com/EspenAlbert/atlas-init#readme
5
5
  Project-URL: Issues, https://github.com/EspenAlbert/atlas-init/issues
6
6
  Project-URL: Source, https://github.com/EspenAlbert/atlas-init
@@ -1,8 +1,8 @@
1
- atlas_init/__init__.py,sha256=iuwrP7v_WWz_sVz-k0_a5k5HduJTimtVRY4WP2RNiz4,372
1
+ atlas_init/__init__.py,sha256=bW9zb8obruloS6_54VzQHbSGtnnhhbEBuu5fipDvPcc,372
2
2
  atlas_init/__main__.py,sha256=dY1dWWvwxRZMmnOFla6RSfti-hMeLeKdoXP7SVYqMUc,52
3
3
  atlas_init/atlas_init.yaml,sha256=GMyJVhKKRc7WzEu7fafmWgeTsDaExTLv7QvXOmE_Brg,1907
4
4
  atlas_init/cli.py,sha256=IiOEC_Jry6vrSDH3_OvsU50F-_3iVIS4tV6-R7659fY,9642
5
- atlas_init/cli_args.py,sha256=6ucjRGLGde1XcZIfUCGrWbmQLJB9bWZaXxyAsYXMSSw,427
5
+ atlas_init/cli_args.py,sha256=tiwUYAE0JBSl9lHV6VJ41vFCU90ChBZ4mKvi-YoF_HY,541
6
6
  atlas_init/humps.py,sha256=l0ZXXuI34wwd9TskXhCjULfGbUyK-qNmiyC6_2ow6kU,7339
7
7
  atlas_init/terraform.yaml,sha256=qPrnbzBEP-JAQVkYadHsggRnDmshrOJyiv0ckyZCxwY,2734
8
8
  atlas_init/typer_app.py,sha256=irgBK7WSewg7on25KKHY9FNUDvmXgavmc0Z39yhYNjI,2507
@@ -21,14 +21,15 @@ atlas_init/cli_helper/tf_runner.py,sha256=OYdC-Y6i-xRh8_LCudKdtP7CEYEO9e67nVhhol
21
21
  atlas_init/cli_root/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
22
  atlas_init/cli_root/trigger.py,sha256=oEgqb_l25tyYgUaFHEuChcOCJA7k3mnRa4D-Myz-Igs,5789
23
23
  atlas_init/cli_tf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- atlas_init/cli_tf/app.py,sha256=2lrlbuXPSfgL_k4BeZ4jiWNkRuSemCp5xle1yxCiU4I,11255
24
+ atlas_init/cli_tf/app.py,sha256=-50lyNwG5eh8nVCN6mCcIB_b4xd5aJjhEoK-XVHD8XU,11359
25
25
  atlas_init/cli_tf/changelog.py,sha256=biWYKf1pZvXZ-jEgcZ5q9sY7nTGrL2PuI0h9mCILf_g,3181
26
- atlas_init/cli_tf/debug_logs.py,sha256=J8MLryNNkRivo2-Z3fnqf5pjPit9xndbsqNSbATTtUg,8047
27
- atlas_init/cli_tf/debug_logs_test_data.py,sha256=AOysldCVSBtqW8ZhRnxcOPctng9OodQy0zWWcYbmpoA,8577
26
+ atlas_init/cli_tf/debug_logs.py,sha256=lnB5BpcEooVzGd2RLxbwAVQs0ZYXzRKy5sHa0hftHI8,8799
27
+ atlas_init/cli_tf/debug_logs_test_data.py,sha256=CP1FbRvaFXOOr5m0u-Y6YAvWpqn6WzH-XoPYBJZN0bE,9594
28
28
  atlas_init/cli_tf/github_logs.py,sha256=VD7qhlXNuG21eTuJ5VI7rsflp5WHSodfngkRVgQlumw,8114
29
29
  atlas_init/cli_tf/go_test_run.py,sha256=ZoQSvIasmWauFxZJrWL0ObFX-P0k-D3c_ep3OnPY4zs,5842
30
30
  atlas_init/cli_tf/go_test_run_format.py,sha256=OUd6QPHDeTzbwVuh6MhP-xXgjOOGP9W_sCLJ8KylBTs,1201
31
31
  atlas_init/cli_tf/go_test_summary.py,sha256=agr4SITgxchjgOzRpScoTUk-iG38QDLkpnsMtTW9GTY,5382
32
+ atlas_init/cli_tf/mock_tf_log.py,sha256=tefWI5mS5lwOWCUidI_p7LeTaoyYCQl951LFgLYGEy8,3157
32
33
  atlas_init/cli_tf/schema.py,sha256=q0RUHb-6ORbQ41u2bZXaWWQLB-xE8Q_O7U1AFq2Gfng,12398
33
34
  atlas_init/cli_tf/schema_go_parser.py,sha256=PiRfFFVnkhltxcGFfOCgH53wwzIEynw2BXmSfaINLL8,8294
34
35
  atlas_init/cli_tf/schema_inspection.py,sha256=ujLvGfg3baByND4nRD0drZoI45STxo3VfYvim-PfVOc,1764
@@ -49,7 +50,7 @@ atlas_init/cloud/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
49
50
  atlas_init/cloud/aws.py,sha256=97kkURWHFAKDIw4704aFmyoeAfQKL11IXMyaQbZUt80,2473
50
51
  atlas_init/repos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
52
  atlas_init/repos/cfn.py,sha256=rjyVVxRhWL65tdAbEHT72UReK2h99Bj6RA4O2pBO-bc,2466
52
- atlas_init/repos/go_sdk.py,sha256=6_ENYMP6yQufo1dXJbLJFDxCuq-8oeTYiGAPC61Uauc,424
53
+ atlas_init/repos/go_sdk.py,sha256=nh3lw9iw4lDGdHnhC8KK0PZTDMUGKvCHTMTuEtIUKNg,1058
53
54
  atlas_init/repos/path.py,sha256=wrT8e01OBoAHj8iMrxqutgqWu-BHPe9-bEWtcZRu238,4187
54
55
  atlas_init/settings/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
56
  atlas_init/settings/config.py,sha256=HIytZom8RRvpLGy6u8CpZ83tmFXI6v1tO3iSiuo08kc,6259
@@ -85,7 +86,7 @@ atlas_init/tf/modules/vpc_peering/vpc_peering.tf,sha256=hJ3KJdGbLpOQednUpVuiJ0Cq
85
86
  atlas_init/tf/modules/vpc_privatelink/atlas-privatelink.tf,sha256=FloaaX1MNDvoMZxBnEopeLKyfIlq6kaX2dmx8WWlXNU,1298
86
87
  atlas_init/tf/modules/vpc_privatelink/variables.tf,sha256=gktHCDYD4rz6CEpLg5aiXcFbugw4L5S2Fqc52QYdJyc,255
87
88
  atlas_init/tf/modules/vpc_privatelink/versions.tf,sha256=G0u5V_Hvvrkux_tqfOY05pA-GzSp_qILpfx1dZaTGDc,237
88
- atlas_init-0.1.8.dist-info/METADATA,sha256=rY36JD0IN5OQGE9wpSx8uIdtFfkJOBZu6mg3DJzQF5A,6167
89
- atlas_init-0.1.8.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
90
- atlas_init-0.1.8.dist-info/entry_points.txt,sha256=6Ycq_NZ7cym1BCA9YiVhYylJzy6woREjt7QSCSLm-1o,54
91
- atlas_init-0.1.8.dist-info/RECORD,,
89
+ atlas_init-0.2.0.dist-info/METADATA,sha256=DY-E8A0r-DLm9H9hX4Nc60Wjb1fcLs0QWLU-vdJ8LjA,6167
90
+ atlas_init-0.2.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
91
+ atlas_init-0.2.0.dist-info/entry_points.txt,sha256=6Ycq_NZ7cym1BCA9YiVhYylJzy6woREjt7QSCSLm-1o,54
92
+ atlas_init-0.2.0.dist-info/RECORD,,