qontract-reconcile 0.10.2.dev303__py3-none-any.whl → 0.10.2.dev314__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.
- {qontract_reconcile-0.10.2.dev303.dist-info → qontract_reconcile-0.10.2.dev314.dist-info}/METADATA +1 -1
- {qontract_reconcile-0.10.2.dev303.dist-info → qontract_reconcile-0.10.2.dev314.dist-info}/RECORD +30 -30
- reconcile/gql_definitions/common/aws_vpc_requests.py +4 -1
- reconcile/gql_definitions/fragments/aws_vpc_request.py +3 -0
- reconcile/gql_definitions/introspection.json +36 -12
- reconcile/gql_definitions/status_board/status_board.py +0 -20
- reconcile/prometheus_rules_tester/integration.py +1 -1
- reconcile/rhidp/common.py +2 -0
- reconcile/status_board.py +9 -133
- reconcile/terraform_tgw_attachments.py +1 -1
- reconcile/terraform_users.py +3 -1
- reconcile/terraform_vpc_peerings.py +1 -1
- reconcile/terraform_vpc_resources/integration.py +19 -1
- reconcile/typed_queries/status_board.py +8 -43
- reconcile/utils/ocm/base.py +10 -0
- reconcile/utils/ocm/status_board.py +0 -13
- reconcile/utils/openssl.py +2 -2
- reconcile/utils/repo_owners.py +21 -29
- reconcile/utils/runtime/meta.py +2 -1
- reconcile/utils/sharding.py +1 -1
- reconcile/utils/sqs_gateway.py +14 -10
- reconcile/utils/structs.py +3 -3
- reconcile/utils/terraform_client.py +27 -25
- reconcile/utils/terrascript_aws_client.py +487 -372
- reconcile/utils/throughput.py +1 -1
- reconcile/vpc_peerings_validator.py +2 -2
- tools/qontract_cli.py +1 -1
- tools/sre_checkpoints/util.py +5 -3
- {qontract_reconcile-0.10.2.dev303.dist-info → qontract_reconcile-0.10.2.dev314.dist-info}/WHEEL +0 -0
- {qontract_reconcile-0.10.2.dev303.dist-info → qontract_reconcile-0.10.2.dev314.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,6 @@
|
|
1
1
|
# ruff: noqa: N801
|
2
|
+
from __future__ import annotations
|
3
|
+
|
2
4
|
import base64
|
3
5
|
import enum
|
4
6
|
import json
|
@@ -9,7 +11,6 @@ import re
|
|
9
11
|
import string
|
10
12
|
import tempfile
|
11
13
|
from collections import Counter
|
12
|
-
from collections.abc import Iterable, Mapping, MutableMapping
|
13
14
|
from dataclasses import dataclass, field
|
14
15
|
from ipaddress import (
|
15
16
|
ip_address,
|
@@ -18,7 +19,10 @@ from ipaddress import (
|
|
18
19
|
from json import JSONDecodeError
|
19
20
|
from threading import Lock
|
20
21
|
from typing import (
|
22
|
+
TYPE_CHECKING,
|
21
23
|
Any,
|
24
|
+
Self,
|
25
|
+
TypeAlias,
|
22
26
|
cast,
|
23
27
|
)
|
24
28
|
|
@@ -34,12 +38,14 @@ from terrascript import (
|
|
34
38
|
Backend,
|
35
39
|
Block,
|
36
40
|
Data,
|
41
|
+
Locals,
|
37
42
|
Module,
|
38
43
|
Output,
|
39
44
|
Provider,
|
40
45
|
Resource,
|
41
46
|
Terraform,
|
42
47
|
Terrascript,
|
48
|
+
Variable,
|
43
49
|
data,
|
44
50
|
provider,
|
45
51
|
)
|
@@ -143,9 +149,6 @@ import reconcile.utils.aws_helper as awsh
|
|
143
149
|
from reconcile import queries
|
144
150
|
from reconcile.cli import TERRAFORM_VERSION
|
145
151
|
from reconcile.github_org import get_default_config
|
146
|
-
from reconcile.gql_definitions.fragments.aws_vpc_request import (
|
147
|
-
VPCRequest,
|
148
|
-
)
|
149
152
|
from reconcile.gql_definitions.terraform_resources.terraform_resources_namespaces import (
|
150
153
|
NamespaceTerraformResourceLifecycleV1,
|
151
154
|
)
|
@@ -168,10 +171,6 @@ from reconcile.utils.exceptions import (
|
|
168
171
|
FetchResourceError,
|
169
172
|
PrintToFileInGitRepositoryError,
|
170
173
|
)
|
171
|
-
from reconcile.utils.external_resource_spec import (
|
172
|
-
ExternalResourceSpec,
|
173
|
-
ExternalResourceSpecInventory,
|
174
|
-
)
|
175
174
|
from reconcile.utils.external_resources import (
|
176
175
|
PROVIDER_AWS,
|
177
176
|
get_external_resource_specs,
|
@@ -180,7 +179,6 @@ from reconcile.utils.git import is_file_in_git_repo
|
|
180
179
|
from reconcile.utils.gitlab_api import GitLabApi
|
181
180
|
from reconcile.utils.jenkins_api import JenkinsApi
|
182
181
|
from reconcile.utils.jinja2.utils import process_extracurlyjinja2_template
|
183
|
-
from reconcile.utils.ocm import OCMMap
|
184
182
|
from reconcile.utils.password_validator import (
|
185
183
|
PasswordPolicy,
|
186
184
|
PasswordValidator,
|
@@ -189,6 +187,25 @@ from reconcile.utils.secret_reader import SecretReader, SecretReaderBase
|
|
189
187
|
from reconcile.utils.terraform import safe_resource_id
|
190
188
|
from reconcile.utils.vcs import VCS
|
191
189
|
|
190
|
+
if TYPE_CHECKING:
|
191
|
+
from collections.abc import Iterable, Mapping, MutableMapping
|
192
|
+
|
193
|
+
from reconcile.gql_definitions.fragments.aws_vpc_request import (
|
194
|
+
VPCRequest,
|
195
|
+
)
|
196
|
+
from reconcile.terraform_tgw_attachments import DesiredStateItem
|
197
|
+
from reconcile.terraform_users import Role
|
198
|
+
from reconcile.utils.external_resource_spec import (
|
199
|
+
ExternalResourceSpec,
|
200
|
+
ExternalResourceSpecInventory,
|
201
|
+
)
|
202
|
+
from reconcile.utils.ocm import OCMMap
|
203
|
+
|
204
|
+
|
205
|
+
TFResource: TypeAlias = type[
|
206
|
+
Resource | Data | Module | Provider | Variable | Output | Locals | Terraform
|
207
|
+
]
|
208
|
+
|
192
209
|
GH_BASE_URL = os.environ.get("GITHUB_API", "https://api.github.com")
|
193
210
|
ROSA_AUTH_LOGTOES_RELEASE = "repos/app-sre/logs-to-elasticsearch-lambda/releases/latest"
|
194
211
|
ROSA_AUTH_KINESIS_TO_OS_RELEASE = (
|
@@ -304,9 +321,12 @@ AWS_US_GOV_ELB_ACCOUNT_IDS = {
|
|
304
321
|
"us-gov-east-1": "190560391635",
|
305
322
|
}
|
306
323
|
|
324
|
+
VPC_REQUEST_DEFAULT_PRIVATE_SUBNET_TAGS = {"kubernetes.io/role/internal-elb": "1"}
|
325
|
+
VPC_REQUEST_DEFAULT_PUBLIC_SUBNET_TAGS = {"kubernetes.io/role/elb": "1"}
|
326
|
+
|
307
327
|
|
308
328
|
class OutputResourceNameNotUniqueError(Exception):
|
309
|
-
def __init__(self, namespace, duplicates):
|
329
|
+
def __init__(self, namespace: str | None, duplicates: Iterable[str]) -> None:
|
310
330
|
self.namespace, self.duplicates = namespace, duplicates
|
311
331
|
super().__init__(
|
312
332
|
str.format(
|
@@ -326,7 +346,7 @@ class StateInaccessibleError(Exception):
|
|
326
346
|
|
327
347
|
|
328
348
|
class UnknownProviderError(Exception):
|
329
|
-
def __init__(self, msg):
|
349
|
+
def __init__(self, msg: str) -> None:
|
330
350
|
super().__init__("unknown provider error: " + str(msg))
|
331
351
|
|
332
352
|
|
@@ -453,9 +473,9 @@ class TerrascriptClient:
|
|
453
473
|
integration: str,
|
454
474
|
integration_prefix: str,
|
455
475
|
thread_pool_size: int,
|
456
|
-
accounts: Iterable[
|
476
|
+
accounts: Iterable[MutableMapping[str, Any]],
|
457
477
|
settings: Mapping[str, Any] | None = None,
|
458
|
-
prefetch_resources_by_schemas:
|
478
|
+
prefetch_resources_by_schemas: Iterable[str] | None = None,
|
459
479
|
secret_reader: SecretReaderBase | None = None,
|
460
480
|
) -> None:
|
461
481
|
self.integration = integration
|
@@ -541,10 +561,10 @@ class TerrascriptClient:
|
|
541
561
|
self.accounts = {a["name"]: a for a in filtered_accounts}
|
542
562
|
self.uids = {a["name"]: a["uid"] for a in filtered_accounts}
|
543
563
|
# default_regions info is needed in populate_tf_resource_rds, even in disabled accounts
|
544
|
-
self.default_regions = {
|
564
|
+
self.default_regions: dict[str, str] = {
|
545
565
|
a["name"]: a["resourcesDefaultRegion"] for a in accounts
|
546
566
|
}
|
547
|
-
self.partitions = {
|
567
|
+
self.partitions: dict[str, str] = {
|
548
568
|
a["name"]: a.get("partition") or "aws" for a in filtered_accounts
|
549
569
|
}
|
550
570
|
self.rosa_auth_logtoes_zip = ""
|
@@ -566,19 +586,19 @@ class TerrascriptClient:
|
|
566
586
|
for schema in prefetch_resources_by_schemas:
|
567
587
|
self._resource_cache.update(self.prefetch_resources(schema))
|
568
588
|
|
569
|
-
def __enter__(self):
|
589
|
+
def __enter__(self) -> Self:
|
570
590
|
return self
|
571
591
|
|
572
|
-
def __exit__(self, *exc):
|
592
|
+
def __exit__(self, *exc: Any) -> None:
|
573
593
|
self.cleanup()
|
574
594
|
|
575
|
-
def cleanup(self):
|
595
|
+
def cleanup(self) -> None:
|
576
596
|
if self.gitlab is not None:
|
577
597
|
self.gitlab.cleanup()
|
578
598
|
|
579
599
|
@staticmethod
|
580
600
|
def state_bucket_for_account(
|
581
|
-
integration: str, account_name: str, config:
|
601
|
+
integration: str, account_name: str, config: Mapping[str, Any]
|
582
602
|
) -> Backend:
|
583
603
|
# creds
|
584
604
|
access_key_backend_value = config["aws_access_key_id"]
|
@@ -643,7 +663,7 @@ class TerrascriptClient:
|
|
643
663
|
f.write(r.content)
|
644
664
|
return zip_file
|
645
665
|
|
646
|
-
def get_logtoes_zip(self, release_url):
|
666
|
+
def get_logtoes_zip(self, release_url: str) -> str:
|
647
667
|
if not self.rosa_auth_logtoes_zip:
|
648
668
|
with self.rosa_auth_logtoes_zip_lock:
|
649
669
|
# this may have already happened, so we check again
|
@@ -656,7 +676,7 @@ class TerrascriptClient:
|
|
656
676
|
return self.rosa_auth_logtoes_zip
|
657
677
|
return self.download_logtoes_zip(release_url)
|
658
678
|
|
659
|
-
def download_logtoes_zip(self, release_url):
|
679
|
+
def download_logtoes_zip(self, release_url: str) -> str:
|
660
680
|
headers = {"Authorization": "token " + self.token}
|
661
681
|
r = requests.get(GH_BASE_URL + "/" + release_url, headers=headers, timeout=60)
|
662
682
|
r.raise_for_status()
|
@@ -670,7 +690,7 @@ class TerrascriptClient:
|
|
670
690
|
f.write(r.content)
|
671
691
|
return zip_file
|
672
692
|
|
673
|
-
def get_rosa_auth_pre_signup_zip(self, release_url):
|
693
|
+
def get_rosa_auth_pre_signup_zip(self, release_url: str) -> str:
|
674
694
|
if not self.rosa_auth_pre_signup_zip:
|
675
695
|
with self.rosa_auth_pre_signup_zip_lock:
|
676
696
|
# this may have already happened, so we check again
|
@@ -685,7 +705,7 @@ class TerrascriptClient:
|
|
685
705
|
return self.rosa_auth_pre_signup_zip
|
686
706
|
return self.download_rosa_auth_pre_signup_zip(release_url)
|
687
707
|
|
688
|
-
def download_rosa_auth_pre_signup_zip(self, release_url):
|
708
|
+
def download_rosa_auth_pre_signup_zip(self, release_url: str) -> str:
|
689
709
|
headers = {"Authorization": "token " + self.token}
|
690
710
|
r = requests.get(GH_BASE_URL + "/" + release_url, headers=headers, timeout=60)
|
691
711
|
r.raise_for_status()
|
@@ -699,7 +719,7 @@ class TerrascriptClient:
|
|
699
719
|
f.write(r.content)
|
700
720
|
return zip_file
|
701
721
|
|
702
|
-
def get_rosa_auth_pre_token_zip(self, release_url):
|
722
|
+
def get_rosa_auth_pre_token_zip(self, release_url: str) -> str:
|
703
723
|
if not self.rosa_auth_pre_token_zip:
|
704
724
|
with self.rosa_auth_pre_token_zip_lock:
|
705
725
|
# this may have already happened, so we check again
|
@@ -714,7 +734,7 @@ class TerrascriptClient:
|
|
714
734
|
return self.rosa_auth_pre_token_zip
|
715
735
|
return self.download_rosa_auth_pre_token_zip(release_url)
|
716
736
|
|
717
|
-
def download_rosa_auth_pre_token_zip(self, release_url):
|
737
|
+
def download_rosa_auth_pre_token_zip(self, release_url: str) -> str:
|
718
738
|
headers = {"Authorization": "token " + self.token}
|
719
739
|
r = requests.get(GH_BASE_URL + "/" + release_url, headers=headers, timeout=60)
|
720
740
|
r.raise_for_status()
|
@@ -744,7 +764,7 @@ class TerrascriptClient:
|
|
744
764
|
self.gitlab = GitLabApi(instance, secret_reader=self.secret_reader)
|
745
765
|
return self.gitlab
|
746
766
|
|
747
|
-
def init_jenkins(self, instance:
|
767
|
+
def init_jenkins(self, instance: Mapping[str, Any]) -> JenkinsApi:
|
748
768
|
instance_name = instance["name"]
|
749
769
|
if not self.jenkins_map.get(instance_name):
|
750
770
|
with self.jenkins_lock:
|
@@ -758,8 +778,8 @@ class TerrascriptClient:
|
|
758
778
|
return self.jenkins_map[instance_name]
|
759
779
|
|
760
780
|
def filter_disabled_accounts(
|
761
|
-
self, accounts: Iterable[
|
762
|
-
) -> list[
|
781
|
+
self, accounts: Iterable[MutableMapping[str, Any]]
|
782
|
+
) -> list[MutableMapping[str, Any]]:
|
763
783
|
filtered_accounts = []
|
764
784
|
for account in accounts:
|
765
785
|
integration = self.integration.replace("_", "-")
|
@@ -767,7 +787,7 @@ class TerrascriptClient:
|
|
767
787
|
filtered_accounts.append(account)
|
768
788
|
return filtered_accounts
|
769
789
|
|
770
|
-
def populate_configs(self, accounts: Iterable[awsh.Account]):
|
790
|
+
def populate_configs(self, accounts: Iterable[awsh.Account]) -> None:
|
771
791
|
results = threaded.run(
|
772
792
|
awsh.get_tf_secrets,
|
773
793
|
accounts,
|
@@ -781,14 +801,14 @@ class TerrascriptClient:
|
|
781
801
|
config["terraformState"] = account["terraformState"]
|
782
802
|
self.configs[account_name] = config
|
783
803
|
|
784
|
-
def _get_partition(self, account):
|
804
|
+
def _get_partition(self, account: str) -> str:
|
785
805
|
return self.partitions.get(account) or "aws"
|
786
806
|
|
787
807
|
@staticmethod
|
788
|
-
def get_tf_iam_group(group_name):
|
808
|
+
def get_tf_iam_group(group_name: str) -> aws_iam_group:
|
789
809
|
return aws_iam_group(group_name, name=group_name)
|
790
810
|
|
791
|
-
def get_tf_iam_user(self, user_name):
|
811
|
+
def get_tf_iam_user(self, user_name: str) -> aws_iam_user:
|
792
812
|
return aws_iam_user(
|
793
813
|
user_name,
|
794
814
|
name=user_name,
|
@@ -796,8 +816,8 @@ class TerrascriptClient:
|
|
796
816
|
tags={"managed_by_integration": self.integration},
|
797
817
|
)
|
798
818
|
|
799
|
-
def populate_iam_groups(self, roles):
|
800
|
-
groups = {}
|
819
|
+
def populate_iam_groups(self, roles: Iterable[Role]) -> dict[str, dict[str, str]]:
|
820
|
+
groups: dict[str, dict[str, str]] = {}
|
801
821
|
for role in roles:
|
802
822
|
users = role["users"]
|
803
823
|
if len(users) == 0:
|
@@ -840,7 +860,7 @@ class TerrascriptClient:
|
|
840
860
|
return groups
|
841
861
|
|
842
862
|
@staticmethod
|
843
|
-
def _get_aws_username(user):
|
863
|
+
def _get_aws_username(user: Mapping[str, str]) -> str:
|
844
864
|
return user.get("aws_username") or user["org_username"]
|
845
865
|
|
846
866
|
@staticmethod
|
@@ -865,10 +885,10 @@ class TerrascriptClient:
|
|
865
885
|
|
866
886
|
def populate_iam_users(
|
867
887
|
self,
|
868
|
-
roles,
|
869
|
-
skip_reencrypt_accounts:
|
888
|
+
roles: Iterable[Role],
|
889
|
+
skip_reencrypt_accounts: Iterable[str],
|
870
890
|
appsre_pgp_key: str | None,
|
871
|
-
):
|
891
|
+
) -> bool:
|
872
892
|
error = False
|
873
893
|
for role in roles:
|
874
894
|
users = role["users"]
|
@@ -997,10 +1017,10 @@ class TerrascriptClient:
|
|
997
1017
|
|
998
1018
|
def populate_users(
|
999
1019
|
self,
|
1000
|
-
roles,
|
1001
|
-
skip_reencrypt_accounts:
|
1020
|
+
roles: Iterable[Role],
|
1021
|
+
skip_reencrypt_accounts: Iterable[str],
|
1002
1022
|
appsre_pgp_key: str | None = None,
|
1003
|
-
):
|
1023
|
+
) -> bool:
|
1004
1024
|
self.populate_iam_groups(roles)
|
1005
1025
|
err = self.populate_iam_users(
|
1006
1026
|
roles,
|
@@ -1019,7 +1039,7 @@ class TerrascriptClient:
|
|
1019
1039
|
|
1020
1040
|
@staticmethod
|
1021
1041
|
def get_resource_lifecycle(
|
1022
|
-
common_values:
|
1042
|
+
common_values: Mapping[str, Any],
|
1023
1043
|
) -> dict[str, Any] | None:
|
1024
1044
|
if lifecycle := common_values.get("lifecycle"):
|
1025
1045
|
lifecycle = NamespaceTerraformResourceLifecycleV1(**lifecycle)
|
@@ -1036,7 +1056,9 @@ class TerrascriptClient:
|
|
1036
1056
|
return lifecycle.dict(by_alias=True) | {"ignore_changes": ignore_changes}
|
1037
1057
|
return None
|
1038
1058
|
|
1039
|
-
def populate_additional_providers(
|
1059
|
+
def populate_additional_providers(
|
1060
|
+
self, infra_account_name: str, accounts: Iterable[Mapping[str, Any]]
|
1061
|
+
) -> None:
|
1040
1062
|
for account in accounts:
|
1041
1063
|
account_name = account["name"]
|
1042
1064
|
assume_role = account.get("assume_role")
|
@@ -1067,7 +1089,7 @@ class TerrascriptClient:
|
|
1067
1089
|
)
|
1068
1090
|
|
1069
1091
|
def populate_route53(
|
1070
|
-
self, desired_state: Iterable[
|
1092
|
+
self, desired_state: Iterable[Mapping[str, Any]], default_ttl: int = 300
|
1071
1093
|
) -> None:
|
1072
1094
|
for zone in desired_state:
|
1073
1095
|
acct_name = zone["account_name"]
|
@@ -1086,10 +1108,10 @@ class TerrascriptClient:
|
|
1086
1108
|
def populate_route53_records(
|
1087
1109
|
self,
|
1088
1110
|
acct_name: str,
|
1089
|
-
zone:
|
1111
|
+
zone: Mapping[str, Any],
|
1090
1112
|
zone_resource: aws_route53_zone,
|
1091
1113
|
default_ttl: int = 300,
|
1092
|
-
):
|
1114
|
+
) -> None:
|
1093
1115
|
counts = {}
|
1094
1116
|
for record in zone.get("records") or []:
|
1095
1117
|
record_fqdn = f"{record['name']}.{zone['name']}"
|
@@ -1166,7 +1188,7 @@ class TerrascriptClient:
|
|
1166
1188
|
record_resource = aws_route53_record(record_id, **record_values)
|
1167
1189
|
self.add_resource(acct_name, record_resource)
|
1168
1190
|
|
1169
|
-
def populate_vpc_peerings(self, desired_state):
|
1191
|
+
def populate_vpc_peerings(self, desired_state: Iterable[Mapping[str, Any]]) -> None:
|
1170
1192
|
for item in desired_state:
|
1171
1193
|
if item["deleted"]:
|
1172
1194
|
continue
|
@@ -1187,7 +1209,7 @@ class TerrascriptClient:
|
|
1187
1209
|
|
1188
1210
|
# Requester's side of the connection - the cluster's account
|
1189
1211
|
identifier = f"{requester['vpc_id']}-{accepter['vpc_id']}"
|
1190
|
-
values = {
|
1212
|
+
values: dict[str, Any] = {
|
1191
1213
|
# adding the alias to the provider will add this resource
|
1192
1214
|
# to the cluster's AWS account
|
1193
1215
|
"provider": "aws." + req_alias,
|
@@ -1308,25 +1330,32 @@ class TerrascriptClient:
|
|
1308
1330
|
"version": vpc_module_version,
|
1309
1331
|
"name": request.identifier,
|
1310
1332
|
"cidr": request.cidr_block.network_address,
|
1311
|
-
"private_subnet_tags": {"kubernetes.io/role/internal-elb": "1"},
|
1312
|
-
"public_subnet_tags": {"kubernetes.io/role/elb": "1"},
|
1313
1333
|
"create_database_subnet_group": False,
|
1314
1334
|
"enable_dns_hostnames": True,
|
1335
|
+
"vpc_tags": request.vpc_tags or {},
|
1315
1336
|
"tags": {
|
1316
1337
|
"managed_by_integration": self.integration,
|
1317
1338
|
},
|
1318
1339
|
}
|
1319
1340
|
|
1320
|
-
if request.subnets
|
1321
|
-
|
1322
|
-
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1341
|
+
if request.subnets:
|
1342
|
+
if request.subnets.public:
|
1343
|
+
vpc_module_values["public_subnets"] = request.subnets.public
|
1344
|
+
vpc_module_values["public_subnet_tags"] = (
|
1345
|
+
VPC_REQUEST_DEFAULT_PUBLIC_SUBNET_TAGS
|
1346
|
+
| (request.subnets.public_subnet_tags or {})
|
1347
|
+
)
|
1348
|
+
if request.subnets.private:
|
1349
|
+
vpc_module_values["private_subnets"] = request.subnets.private
|
1350
|
+
vpc_module_values["private_subnet_tags"] = (
|
1351
|
+
VPC_REQUEST_DEFAULT_PRIVATE_SUBNET_TAGS
|
1352
|
+
| (request.subnets.private_subnet_tags or {})
|
1353
|
+
)
|
1354
|
+
if request.subnets.availability_zones:
|
1355
|
+
vpc_module_values["azs"] = request.subnets.availability_zones
|
1356
|
+
# We only want to enable nat_gateway if we have public and private subnets
|
1357
|
+
if request.subnets.public and request.subnets.private:
|
1358
|
+
vpc_module_values["enable_nat_gateway"] = True
|
1330
1359
|
|
1331
1360
|
aws_account = request.account.name
|
1332
1361
|
vpc_module = Module(request.identifier, **vpc_module_values)
|
@@ -1367,21 +1396,24 @@ class TerrascriptClient:
|
|
1367
1396
|
)
|
1368
1397
|
self.add_resource(aws_account, vpc_cidr_block_output)
|
1369
1398
|
|
1370
|
-
if request.subnets
|
1371
|
-
|
1372
|
-
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1399
|
+
if request.subnets:
|
1400
|
+
if request.subnets.private:
|
1401
|
+
private_subnets_output = Output(
|
1402
|
+
f"{request.identifier}-private_subnets",
|
1403
|
+
value=f"${{module.{request.identifier}.private_subnets}}",
|
1404
|
+
)
|
1405
|
+
self.add_resource(aws_account, private_subnets_output)
|
1376
1406
|
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1407
|
+
if request.subnets.public:
|
1408
|
+
public_subnets_output = Output(
|
1409
|
+
f"{request.identifier}-public_subnets",
|
1410
|
+
value=f"${{module.{request.identifier}.public_subnets}}",
|
1411
|
+
)
|
1412
|
+
self.add_resource(aws_account, public_subnets_output)
|
1383
1413
|
|
1384
|
-
def populate_tgw_attachments(
|
1414
|
+
def populate_tgw_attachments(
|
1415
|
+
self, desired_state: Iterable[DesiredStateItem]
|
1416
|
+
) -> None:
|
1385
1417
|
for item in desired_state:
|
1386
1418
|
if item.deleted:
|
1387
1419
|
continue
|
@@ -1404,30 +1436,32 @@ class TerrascriptClient:
|
|
1404
1436
|
|
1405
1437
|
tags = {"managed_by_integration": self.integration, "Name": connection_name}
|
1406
1438
|
# add resource share
|
1407
|
-
|
1439
|
+
values_share: dict[str, Any] = {
|
1408
1440
|
"name": connection_name,
|
1409
1441
|
"allow_external_principals": True,
|
1410
1442
|
"tags": tags,
|
1411
1443
|
}
|
1412
1444
|
if self._multiregion_account(req_account_name):
|
1413
|
-
|
1414
|
-
tf_resource_share = aws_ram_resource_share(connection_name, **
|
1445
|
+
values_share["provider"] = "aws." + requester.region
|
1446
|
+
tf_resource_share = aws_ram_resource_share(connection_name, **values_share)
|
1415
1447
|
self.add_resource(infra_account_name, tf_resource_share)
|
1416
1448
|
|
1417
1449
|
# share with accepter aws account
|
1418
|
-
|
1450
|
+
values_resource_principal_association: dict[str, str] = {
|
1419
1451
|
"principal": acc_uid,
|
1420
1452
|
"resource_share_arn": "${" + tf_resource_share.arn + "}",
|
1421
1453
|
}
|
1422
1454
|
if self._multiregion_account(req_account_name):
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1455
|
+
values_resource_principal_association["provider"] = (
|
1456
|
+
"aws." + requester.region
|
1457
|
+
)
|
1458
|
+
tf_resource_principal_association = aws_ram_principal_association(
|
1459
|
+
connection_name, **values_resource_principal_association
|
1426
1460
|
)
|
1427
|
-
self.add_resource(infra_account_name,
|
1461
|
+
self.add_resource(infra_account_name, tf_resource_principal_association)
|
1428
1462
|
|
1429
1463
|
# accept resource share from accepter aws account
|
1430
|
-
|
1464
|
+
values_share_resource_accepter: dict[str, Any] = {
|
1431
1465
|
"provider": "aws." + acc_alias,
|
1432
1466
|
"share_arn": "${" + tf_resource_share.arn + "}",
|
1433
1467
|
"depends_on": [
|
@@ -1436,7 +1470,7 @@ class TerrascriptClient:
|
|
1436
1470
|
],
|
1437
1471
|
}
|
1438
1472
|
tf_resource_share_accepter = aws_ram_resource_share_accepter(
|
1439
|
-
connection_name, **
|
1473
|
+
connection_name, **values_share_resource_accepter
|
1440
1474
|
)
|
1441
1475
|
self.add_resource(infra_account_name, tf_resource_share_accepter)
|
1442
1476
|
|
@@ -1446,20 +1480,23 @@ class TerrascriptClient:
|
|
1446
1480
|
|
1447
1481
|
# tgw share association
|
1448
1482
|
identifier = f"{requester.tgw_id}-{accepter.vpc_id}"
|
1449
|
-
|
1483
|
+
values_resource_association: dict[str, str] = {
|
1450
1484
|
"resource_arn": requester.tgw_arn,
|
1451
1485
|
"resource_share_arn": "${" + tf_resource_share.arn + "}",
|
1452
1486
|
}
|
1453
1487
|
if self._multiregion_account(req_account_name):
|
1454
|
-
|
1455
|
-
tf_resource_association = aws_ram_resource_association(
|
1488
|
+
values_resource_association["provider"] = "aws." + requester.region
|
1489
|
+
tf_resource_association = aws_ram_resource_association(
|
1490
|
+
identifier, **values_resource_association
|
1491
|
+
)
|
1456
1492
|
self.add_resource(infra_account_name, tf_resource_association)
|
1457
1493
|
|
1458
1494
|
# now that the tgw is shared to the cluster's aws account
|
1459
1495
|
# we can create a vpc attachment to the tgw
|
1460
1496
|
subnets_id_az = accepter.subnets_id_az
|
1497
|
+
assert subnets_id_az is not None # make mypy happy
|
1461
1498
|
subnets = self.get_az_unique_subnet_ids(subnets_id_az)
|
1462
|
-
|
1499
|
+
values_resource_attachment: dict[str, Any] = {
|
1463
1500
|
"provider": "aws." + acc_alias,
|
1464
1501
|
"subnet_ids": subnets,
|
1465
1502
|
"transit_gateway_id": requester.tgw_id,
|
@@ -1471,20 +1508,22 @@ class TerrascriptClient:
|
|
1471
1508
|
"tags": tags,
|
1472
1509
|
}
|
1473
1510
|
tf_resource_attachment = aws_ec2_transit_gateway_vpc_attachment(
|
1474
|
-
identifier, **
|
1511
|
+
identifier, **values_resource_attachment
|
1475
1512
|
)
|
1476
1513
|
# we send the attachment from the cluster's aws account
|
1477
1514
|
self.add_resource(infra_account_name, tf_resource_attachment)
|
1478
1515
|
|
1479
1516
|
# and accept the attachment in the non cluster's aws account
|
1480
|
-
|
1517
|
+
values_attachment_accepter = {
|
1481
1518
|
"transit_gateway_attachment_id": "${" + tf_resource_attachment.id + "}",
|
1482
1519
|
"tags": tags,
|
1483
1520
|
}
|
1484
1521
|
if self._multiregion_account(req_account_name):
|
1485
|
-
|
1522
|
+
values_attachment_accepter["provider"] = "aws." + requester.region
|
1486
1523
|
tf_resource_attachment_accepter = (
|
1487
|
-
aws_ec2_transit_gateway_vpc_attachment_accepter(
|
1524
|
+
aws_ec2_transit_gateway_vpc_attachment_accepter(
|
1525
|
+
identifier, **values_attachment_accepter
|
1526
|
+
)
|
1488
1527
|
)
|
1489
1528
|
self.add_resource(infra_account_name, tf_resource_attachment_accepter)
|
1490
1529
|
|
@@ -1530,16 +1569,16 @@ class TerrascriptClient:
|
|
1530
1569
|
+ f"unsupported region: {route_region}"
|
1531
1570
|
)
|
1532
1571
|
continue
|
1533
|
-
|
1572
|
+
values_gateway_router = {
|
1534
1573
|
"destination_cidr_block": route["cidr_block"],
|
1535
1574
|
"transit_gateway_attachment_id": route["tgw_attachment_id"],
|
1536
1575
|
"transit_gateway_route_table_id": route["tgw_route_table_id"],
|
1537
1576
|
}
|
1538
1577
|
if self._multiregion_account(req_account_name):
|
1539
|
-
|
1578
|
+
values_gateway_router["provider"] = "aws." + route_region
|
1540
1579
|
route_identifier = f"{identifier}-{route['tgw_id']}"
|
1541
1580
|
tf_resource = aws_ec2_transit_gateway_route(
|
1542
|
-
route_identifier, **
|
1581
|
+
route_identifier, **values_gateway_router
|
1543
1582
|
)
|
1544
1583
|
self.add_resource(infra_account_name, tf_resource)
|
1545
1584
|
|
@@ -1569,7 +1608,7 @@ class TerrascriptClient:
|
|
1569
1608
|
+ f"unsupported region: {rule_region}"
|
1570
1609
|
)
|
1571
1610
|
continue
|
1572
|
-
|
1611
|
+
values_rule = {
|
1573
1612
|
"type": "ingress",
|
1574
1613
|
"from_port": 0,
|
1575
1614
|
"to_port": 0,
|
@@ -1578,31 +1617,37 @@ class TerrascriptClient:
|
|
1578
1617
|
"security_group_id": rule["security_group_id"],
|
1579
1618
|
}
|
1580
1619
|
if self._multiregion_account(req_account_name):
|
1581
|
-
|
1620
|
+
values_rule["provider"] = "aws." + rule_region
|
1582
1621
|
rule_identifier = f"{identifier}-{rule['vpc_id']}"
|
1583
|
-
tf_resource = aws_security_group_rule(
|
1622
|
+
tf_resource = aws_security_group_rule(
|
1623
|
+
rule_identifier, **values_rule
|
1624
|
+
)
|
1584
1625
|
self.add_resource(infra_account_name, tf_resource)
|
1585
1626
|
|
1586
1627
|
for zone in requester.hostedzones or []:
|
1587
1628
|
id = f"{identifier}-{zone}"
|
1588
|
-
|
1629
|
+
values_authorization = {
|
1589
1630
|
"vpc_id": accepter.vpc_id,
|
1590
1631
|
"vpc_region": accepter.region,
|
1591
1632
|
"zone_id": zone,
|
1592
1633
|
}
|
1593
|
-
authorization = aws_route53_vpc_association_authorization(
|
1634
|
+
authorization = aws_route53_vpc_association_authorization(
|
1635
|
+
id, **values_authorization
|
1636
|
+
)
|
1594
1637
|
self.add_resource(infra_account_name, authorization)
|
1595
|
-
|
1638
|
+
values_association = {
|
1596
1639
|
"provider": "aws." + acc_alias,
|
1597
1640
|
"vpc_id": f"${{aws_route53_vpc_association_authorization.{id}.vpc_id}}",
|
1598
1641
|
"vpc_region": accepter.region,
|
1599
1642
|
"zone_id": f"${{aws_route53_vpc_association_authorization.{id}.zone_id}}",
|
1600
1643
|
}
|
1601
|
-
association = aws_route53_zone_association(id, **
|
1644
|
+
association = aws_route53_zone_association(id, **values_association)
|
1602
1645
|
self.add_resource(infra_account_name, association)
|
1603
1646
|
|
1604
1647
|
@staticmethod
|
1605
|
-
def get_az_unique_subnet_ids(
|
1648
|
+
def get_az_unique_subnet_ids(
|
1649
|
+
subnets_id_az: Iterable[Mapping[str, str]],
|
1650
|
+
) -> list[str]:
|
1606
1651
|
"""returns a list of subnet ids which are unique per az"""
|
1607
1652
|
results = []
|
1608
1653
|
azs = []
|
@@ -1710,7 +1755,9 @@ class TerrascriptClient:
|
|
1710
1755
|
|
1711
1756
|
self.resource_spec_inventory[spec.id_object()] = spec
|
1712
1757
|
|
1713
|
-
def populate_tf_resources(
|
1758
|
+
def populate_tf_resources(
|
1759
|
+
self, spec: ExternalResourceSpec, ocm_map: OCMMap | None = None
|
1760
|
+
) -> None:
|
1714
1761
|
if spec.provision_provider != PROVIDER_AWS:
|
1715
1762
|
raise UnknownProviderError(spec.provision_provider)
|
1716
1763
|
|
@@ -1769,13 +1816,13 @@ class TerrascriptClient:
|
|
1769
1816
|
else:
|
1770
1817
|
raise UnknownProviderError(provider)
|
1771
1818
|
|
1772
|
-
def populate_tf_resource_rds(self, spec):
|
1819
|
+
def populate_tf_resource_rds(self, spec: ExternalResourceSpec) -> None:
|
1773
1820
|
account = spec.provisioner_name
|
1774
1821
|
identifier = spec.identifier
|
1775
1822
|
values = self.init_values(spec)
|
1776
1823
|
output_prefix = spec.output_prefix
|
1777
1824
|
|
1778
|
-
tf_resources = []
|
1825
|
+
tf_resources: list[TFResource] = []
|
1779
1826
|
self.init_common_outputs(tf_resources, spec)
|
1780
1827
|
|
1781
1828
|
# we want to allow an empty name, so we
|
@@ -1804,7 +1851,9 @@ class TerrascriptClient:
|
|
1804
1851
|
# To get the provider we should use, we get the region
|
1805
1852
|
# and use that as an alias in the provider definition
|
1806
1853
|
if az:
|
1807
|
-
|
1854
|
+
region_az = self._region_from_availability_zone(az)
|
1855
|
+
assert region_az # make mypy happy
|
1856
|
+
provider = "aws." + region_az
|
1808
1857
|
values["provider"] = provider
|
1809
1858
|
if region:
|
1810
1859
|
provider_region = f"aws.{region}"
|
@@ -1844,7 +1893,7 @@ class TerrascriptClient:
|
|
1844
1893
|
# 'deps' should contain a list of terraform resource names
|
1845
1894
|
# (not full objects) that must be created
|
1846
1895
|
# before the actual RDS instance should be created
|
1847
|
-
deps = []
|
1896
|
+
deps: list[str] = []
|
1848
1897
|
|
1849
1898
|
parameter_group = values.pop("parameter_group", None)
|
1850
1899
|
if parameter_group:
|
@@ -1905,14 +1954,14 @@ class TerrascriptClient:
|
|
1905
1954
|
role_res_name = self.get_dependencies([role_tf_resource])[0]
|
1906
1955
|
deps.append(role_res_name)
|
1907
1956
|
|
1908
|
-
|
1957
|
+
em_values_attachment: dict[str, Any] = {
|
1909
1958
|
"role": role_tf_resource.name,
|
1910
1959
|
"policy_arn": f"arn:{self._get_partition(account)}:iam::aws:policy/service-role/"
|
1911
1960
|
+ "AmazonRDSEnhancedMonitoringRole",
|
1912
1961
|
"depends_on": self.get_dependencies([role_tf_resource]),
|
1913
1962
|
}
|
1914
1963
|
attachment_tf_resource = aws_iam_role_policy_attachment(
|
1915
|
-
em_identifier, **
|
1964
|
+
em_identifier, **em_values_attachment
|
1916
1965
|
)
|
1917
1966
|
tf_resources.append(attachment_tf_resource)
|
1918
1967
|
|
@@ -1930,9 +1979,8 @@ class TerrascriptClient:
|
|
1930
1979
|
if reset_password:
|
1931
1980
|
password = self.generate_random_password()
|
1932
1981
|
else:
|
1933
|
-
|
1934
|
-
|
1935
|
-
password = self.generate_random_password()
|
1982
|
+
db_password = spec.get_secret_field("db.password")
|
1983
|
+
password = db_password or self.generate_random_password()
|
1936
1984
|
else:
|
1937
1985
|
password = ""
|
1938
1986
|
values["password"] = password
|
@@ -2024,7 +2072,7 @@ class TerrascriptClient:
|
|
2024
2072
|
# to a provider version with this bug fix.
|
2025
2073
|
# https://github.com/hashicorp/terraform-provider-aws/pull/20926
|
2026
2074
|
if enhanced_monitoring and replica_source:
|
2027
|
-
sleep_vals = {}
|
2075
|
+
sleep_vals: dict[str, Any] = {}
|
2028
2076
|
sleep_vals["depends_on"] = [attachment_res_name]
|
2029
2077
|
sleep_vals["create_duration"] = "30s"
|
2030
2078
|
|
@@ -2117,7 +2165,7 @@ class TerrascriptClient:
|
|
2117
2165
|
|
2118
2166
|
self.add_resources(account, tf_resources)
|
2119
2167
|
|
2120
|
-
def _multiregion_account(self, name):
|
2168
|
+
def _multiregion_account(self, name: str) -> bool:
|
2121
2169
|
if name not in self.configs:
|
2122
2170
|
return False
|
2123
2171
|
|
@@ -2134,11 +2182,11 @@ class TerrascriptClient:
|
|
2134
2182
|
return spec
|
2135
2183
|
return None
|
2136
2184
|
|
2137
|
-
def _get_db_name_from_values(self, values:
|
2185
|
+
def _get_db_name_from_values(self, values: Mapping[str, Any]) -> str:
|
2138
2186
|
return values.get("name") or values.get("db_name") or ""
|
2139
2187
|
|
2140
2188
|
@staticmethod
|
2141
|
-
def _region_from_availability_zone(az):
|
2189
|
+
def _region_from_availability_zone(az: str) -> str | None:
|
2142
2190
|
# Find the region by removing the last character from the
|
2143
2191
|
# availability zone. Availability zone is defined like
|
2144
2192
|
# us-east-1a, us-east-1b, etc. If there is no availability
|
@@ -2148,39 +2196,38 @@ class TerrascriptClient:
|
|
2148
2196
|
return None
|
2149
2197
|
|
2150
2198
|
@staticmethod
|
2151
|
-
def _db_needs_auth(config):
|
2152
|
-
return
|
2153
|
-
"replicate_source_db" not in config
|
2154
|
-
and config.get("replica_source", None) is None
|
2199
|
+
def _db_needs_auth(config: Mapping[str, Any]) -> bool:
|
2200
|
+
return (
|
2201
|
+
"replicate_source_db" not in config and config.get("replica_source") is None
|
2155
2202
|
)
|
2156
2203
|
|
2157
2204
|
@staticmethod
|
2158
|
-
def validate_db_name(name):
|
2205
|
+
def validate_db_name(name: str) -> bool:
|
2159
2206
|
"""Handle for Error creating DB Instance:
|
2160
2207
|
InvalidParameterValue: DBName must begin with a letter
|
2161
2208
|
and contain only alphanumeric characters."""
|
2162
2209
|
pattern = r"^[a-zA-Z][a-zA-Z0-9_]+$"
|
2163
|
-
return re.search(pattern, name)
|
2210
|
+
return len(name) < 64 and re.search(pattern, name) is not None
|
2164
2211
|
|
2165
2212
|
@staticmethod
|
2166
|
-
def generate_random_password(string_length=20):
|
2213
|
+
def generate_random_password(string_length: int = 20) -> str:
|
2167
2214
|
"""Generate a random string of letters and digits"""
|
2168
2215
|
letters_and_digits = string.ascii_letters + string.digits
|
2169
2216
|
return "".join(random.choice(letters_and_digits) for i in range(string_length))
|
2170
2217
|
|
2171
|
-
def populate_tf_resource_s3(self, spec):
|
2218
|
+
def populate_tf_resource_s3(self, spec: ExternalResourceSpec) -> aws_s3_bucket:
|
2172
2219
|
account = spec.provisioner_name
|
2173
2220
|
identifier = spec.identifier
|
2174
2221
|
common_values = self.init_values(spec)
|
2175
2222
|
output_prefix = spec.output_prefix
|
2176
2223
|
|
2177
|
-
tf_resources = []
|
2224
|
+
tf_resources: list[TFResource] = []
|
2178
2225
|
self.init_common_outputs(tf_resources, spec)
|
2179
2226
|
|
2180
2227
|
# s3 bucket
|
2181
2228
|
# Terraform resource reference:
|
2182
2229
|
# https://www.terraform.io/docs/providers/aws/r/s3_bucket.html
|
2183
|
-
values = {}
|
2230
|
+
values: dict[str, Any] = {}
|
2184
2231
|
values["bucket"] = identifier
|
2185
2232
|
versioning = common_values.get("versioning", True)
|
2186
2233
|
values["versioning"] = {"enabled": versioning}
|
@@ -2307,7 +2354,7 @@ class TerrascriptClient:
|
|
2307
2354
|
|
2308
2355
|
rc_values.clear()
|
2309
2356
|
rc_values["name"] = config["rule_name"] + "_iam_policy"
|
2310
|
-
policy = {
|
2357
|
+
policy: dict[str, Any] = {
|
2311
2358
|
"Version": "2012-10-17",
|
2312
2359
|
"Statement": [
|
2313
2360
|
{
|
@@ -2374,6 +2421,7 @@ class TerrascriptClient:
|
|
2374
2421
|
if len(deps) > 0:
|
2375
2422
|
values["depends_on"] = self.get_dependencies(deps)
|
2376
2423
|
region = common_values.get("region") or self.default_regions.get(account)
|
2424
|
+
assert region # make mypy happy
|
2377
2425
|
if self._multiregion_account(account):
|
2378
2426
|
values["provider"] = "aws." + region
|
2379
2427
|
bucket_tf_resource = aws_s3_bucket(identifier, **values)
|
@@ -2508,10 +2556,12 @@ class TerrascriptClient:
|
|
2508
2556
|
# https://www.terraform.io/docs/providers/aws/r/iam_access_key.html
|
2509
2557
|
|
2510
2558
|
# iam user for bucket
|
2511
|
-
values = {
|
2512
|
-
|
2513
|
-
|
2514
|
-
|
2559
|
+
values = {
|
2560
|
+
"name": identifier,
|
2561
|
+
"tags": common_values["tags"],
|
2562
|
+
"depends_on": self.get_dependencies([bucket_tf_resource]),
|
2563
|
+
}
|
2564
|
+
|
2515
2565
|
user_tf_resource = aws_iam_user(identifier, **values)
|
2516
2566
|
tf_resources.append(user_tf_resource)
|
2517
2567
|
|
@@ -2521,8 +2571,7 @@ class TerrascriptClient:
|
|
2521
2571
|
)
|
2522
2572
|
|
2523
2573
|
# iam user policy for bucket
|
2524
|
-
values = {}
|
2525
|
-
values["name"] = identifier
|
2574
|
+
values = {"name": identifier}
|
2526
2575
|
|
2527
2576
|
action = ["s3:*Object*"]
|
2528
2577
|
if common_values.get("acl", "private") == "public-read":
|
@@ -2566,7 +2615,7 @@ class TerrascriptClient:
|
|
2566
2615
|
|
2567
2616
|
return bucket_tf_resource
|
2568
2617
|
|
2569
|
-
def populate_tf_resource_elasticache(self, spec):
|
2618
|
+
def populate_tf_resource_elasticache(self, spec: ExternalResourceSpec) -> None:
|
2570
2619
|
account = spec.provisioner_name
|
2571
2620
|
identifier = spec.identifier
|
2572
2621
|
values = self.init_values(spec)
|
@@ -2574,7 +2623,7 @@ class TerrascriptClient:
|
|
2574
2623
|
values.setdefault("replication_group_id", values["identifier"])
|
2575
2624
|
values.pop("identifier", None)
|
2576
2625
|
|
2577
|
-
tf_resources = []
|
2626
|
+
tf_resources: list[TFResource] = []
|
2578
2627
|
self.init_common_outputs(tf_resources, spec)
|
2579
2628
|
|
2580
2629
|
default_region = self.default_regions.get(account)
|
@@ -2654,19 +2703,23 @@ class TerrascriptClient:
|
|
2654
2703
|
|
2655
2704
|
self.add_resources(account, tf_resources)
|
2656
2705
|
|
2657
|
-
def populate_tf_resource_service_account(
|
2706
|
+
def populate_tf_resource_service_account(
|
2707
|
+
self, spec: ExternalResourceSpec, ocm_map: OCMMap | None = None
|
2708
|
+
) -> None:
|
2658
2709
|
account = spec.provisioner_name
|
2659
2710
|
identifier = spec.identifier
|
2660
2711
|
common_values = self.init_values(spec)
|
2661
2712
|
output_prefix = spec.output_prefix
|
2662
2713
|
|
2663
|
-
tf_resources = []
|
2714
|
+
tf_resources: list[TFResource] = []
|
2664
2715
|
self.init_common_outputs(tf_resources, spec)
|
2665
2716
|
|
2666
2717
|
# iam user for bucket
|
2667
|
-
values = {
|
2668
|
-
|
2669
|
-
|
2718
|
+
values = {
|
2719
|
+
"name": identifier,
|
2720
|
+
"tags": common_values["tags"],
|
2721
|
+
}
|
2722
|
+
|
2670
2723
|
user_tf_resource = aws_iam_user(identifier, **values)
|
2671
2724
|
tf_resources.append(user_tf_resource)
|
2672
2725
|
|
@@ -2750,13 +2803,15 @@ class TerrascriptClient:
|
|
2750
2803
|
|
2751
2804
|
self.add_resources(account, tf_resources)
|
2752
2805
|
|
2753
|
-
def populate_tf_resource_secrets_manager_sa(
|
2806
|
+
def populate_tf_resource_secrets_manager_sa(
|
2807
|
+
self, spec: ExternalResourceSpec
|
2808
|
+
) -> None:
|
2754
2809
|
account = spec.provisioner_name
|
2755
2810
|
identifier = spec.identifier
|
2756
2811
|
common_values = self.init_values(spec)
|
2757
2812
|
output_prefix = spec.output_prefix
|
2758
2813
|
|
2759
|
-
tf_resources = []
|
2814
|
+
tf_resources: list[TFResource] = []
|
2760
2815
|
self.init_common_outputs(tf_resources, spec)
|
2761
2816
|
|
2762
2817
|
secrets_prefix = common_values["secrets_prefix"]
|
@@ -2780,7 +2835,7 @@ class TerrascriptClient:
|
|
2780
2835
|
|
2781
2836
|
tf_resources.extend(
|
2782
2837
|
self.get_tf_iam_service_user(
|
2783
|
-
|
2838
|
+
None, identifier, policy, common_values["tags"], output_prefix
|
2784
2839
|
)
|
2785
2840
|
)
|
2786
2841
|
|
@@ -2790,20 +2845,20 @@ class TerrascriptClient:
|
|
2790
2845
|
|
2791
2846
|
self.add_resources(account, tf_resources)
|
2792
2847
|
|
2793
|
-
def populate_tf_resource_role(self, spec):
|
2848
|
+
def populate_tf_resource_role(self, spec: ExternalResourceSpec) -> None:
|
2794
2849
|
account = spec.provisioner_name
|
2795
2850
|
identifier = spec.identifier
|
2796
2851
|
common_values = self.init_values(spec)
|
2797
2852
|
output_prefix = spec.output_prefix
|
2798
2853
|
|
2799
|
-
tf_resources = []
|
2854
|
+
tf_resources: list[TFResource] = []
|
2800
2855
|
self.init_common_outputs(tf_resources, spec)
|
2801
2856
|
|
2802
2857
|
assume_role = common_values["assume_role"]
|
2803
2858
|
assume_role = {k: v for k, v in assume_role.items() if v is not None}
|
2804
2859
|
assume_action = common_values.get("assume_action") or "AssumeRole"
|
2805
2860
|
# assume role policy
|
2806
|
-
assume_role_policy = {
|
2861
|
+
assume_role_policy: dict[str, Any] = {
|
2807
2862
|
"Version": "2012-10-17",
|
2808
2863
|
"Statement": [
|
2809
2864
|
{
|
@@ -2818,7 +2873,7 @@ class TerrascriptClient:
|
|
2818
2873
|
assume_role_policy["Statement"][0]["Condition"] = assume_condition
|
2819
2874
|
|
2820
2875
|
# iam role
|
2821
|
-
values = {
|
2876
|
+
values: dict[str, Any] = {
|
2822
2877
|
"name": identifier,
|
2823
2878
|
"tags": common_values["tags"],
|
2824
2879
|
"assume_role_policy": json.dumps(assume_role_policy),
|
@@ -2871,7 +2926,9 @@ class TerrascriptClient:
|
|
2871
2926
|
|
2872
2927
|
self.add_resources(account, tf_resources)
|
2873
2928
|
|
2874
|
-
def populate_iam_policy(
|
2929
|
+
def populate_iam_policy(
|
2930
|
+
self, account: str, name: str, policy: Mapping[str, Any]
|
2931
|
+
) -> None:
|
2875
2932
|
tf_aws_iam_policy = aws_iam_policy(
|
2876
2933
|
f"{account}-{name}", name=name, policy=json.dumps(policy)
|
2877
2934
|
)
|
@@ -2882,8 +2939,8 @@ class TerrascriptClient:
|
|
2882
2939
|
account: str,
|
2883
2940
|
name: str,
|
2884
2941
|
saml_provider_name: str,
|
2885
|
-
aws_managed_policies:
|
2886
|
-
customer_managed_policies:
|
2942
|
+
aws_managed_policies: Iterable[str],
|
2943
|
+
customer_managed_policies: Iterable[str] | None = None,
|
2887
2944
|
max_session_duration_hours: int = 1,
|
2888
2945
|
) -> None:
|
2889
2946
|
"""Manage the an IAM role needed for SAML authentication."""
|
@@ -2921,17 +2978,19 @@ class TerrascriptClient:
|
|
2921
2978
|
)
|
2922
2979
|
self.add_resource(account, role_tf_resource)
|
2923
2980
|
|
2924
|
-
def populate_tf_resource_sqs(self, spec):
|
2981
|
+
def populate_tf_resource_sqs(self, spec: ExternalResourceSpec) -> None:
|
2925
2982
|
account = spec.provisioner_name
|
2926
2983
|
identifier = spec.identifier
|
2927
2984
|
common_values = self.init_values(spec)
|
2928
2985
|
output_prefix = spec.output_prefix
|
2929
2986
|
uid = self.uids.get(account)
|
2930
2987
|
|
2931
|
-
tf_resources = []
|
2988
|
+
tf_resources: list[TFResource] = []
|
2932
2989
|
self.init_common_outputs(tf_resources, spec)
|
2933
2990
|
region = common_values.get("region") or self.default_regions.get(account)
|
2991
|
+
assert region # make mypy happy
|
2934
2992
|
specs = common_values.get("specs")
|
2993
|
+
assert specs is not None # make mypy happy
|
2935
2994
|
all_queues_per_spec = []
|
2936
2995
|
kms_keys = set()
|
2937
2996
|
for _spec in specs:
|
@@ -3005,9 +3064,11 @@ class TerrascriptClient:
|
|
3005
3064
|
# https://www.terraform.io/docs/providers/aws/r/iam_access_key.html
|
3006
3065
|
|
3007
3066
|
# iam user for queue
|
3008
|
-
values = {
|
3009
|
-
|
3010
|
-
|
3067
|
+
values = {
|
3068
|
+
"name": identifier,
|
3069
|
+
"tags": common_values["tags"],
|
3070
|
+
}
|
3071
|
+
|
3011
3072
|
user_tf_resource = aws_iam_user(identifier, **values)
|
3012
3073
|
tf_resources.append(user_tf_resource)
|
3013
3074
|
|
@@ -3021,9 +3082,9 @@ class TerrascriptClient:
|
|
3021
3082
|
policy_identifier = f"{identifier}-{policy_index}"
|
3022
3083
|
if len(all_queues_per_spec) == 1:
|
3023
3084
|
policy_identifier = identifier
|
3024
|
-
values = {}
|
3025
|
-
|
3026
|
-
policy = {
|
3085
|
+
values = {"name": policy_identifier}
|
3086
|
+
|
3087
|
+
policy: dict[str, Any] = {
|
3027
3088
|
"Version": "2012-10-17",
|
3028
3089
|
"Statement": [
|
3029
3090
|
{
|
@@ -3049,27 +3110,29 @@ class TerrascriptClient:
|
|
3049
3110
|
tf_resources.append(policy_tf_resource)
|
3050
3111
|
|
3051
3112
|
# iam user policy attachment
|
3052
|
-
values = {
|
3053
|
-
|
3054
|
-
|
3055
|
-
|
3056
|
-
|
3057
|
-
|
3058
|
-
|
3113
|
+
values = {
|
3114
|
+
"user": identifier,
|
3115
|
+
"policy_arn": "${" + policy_tf_resource.arn + "}",
|
3116
|
+
"depends_on": self.get_dependencies([
|
3117
|
+
user_tf_resource,
|
3118
|
+
policy_tf_resource,
|
3119
|
+
]),
|
3120
|
+
}
|
3121
|
+
|
3059
3122
|
tf_resource = aws_iam_user_policy_attachment(policy_identifier, **values)
|
3060
3123
|
tf_resources.append(tf_resource)
|
3061
3124
|
|
3062
3125
|
self.add_resources(account, tf_resources)
|
3063
3126
|
|
3064
|
-
def populate_tf_resource_sns(self, spec):
|
3127
|
+
def populate_tf_resource_sns(self, spec: ExternalResourceSpec) -> None:
|
3065
3128
|
account = spec.provisioner_name
|
3066
3129
|
identifier = spec.identifier
|
3067
3130
|
common_values = self.init_values(spec)
|
3068
3131
|
output_prefix = spec.output_prefix
|
3069
3132
|
policy = common_values.get("inline_policy")
|
3070
3133
|
region = common_values.get("region") or self.default_regions.get(account)
|
3071
|
-
|
3072
|
-
values = {}
|
3134
|
+
assert region # make mypy happy
|
3135
|
+
values: dict[str, Any] = {}
|
3073
3136
|
fifo_topic = common_values.get("fifo_topic", False)
|
3074
3137
|
topic_name = identifier + ".fifo" if fifo_topic else identifier
|
3075
3138
|
|
@@ -3077,16 +3140,18 @@ class TerrascriptClient:
|
|
3077
3140
|
values["policy"] = policy
|
3078
3141
|
values["fifo_topic"] = fifo_topic
|
3079
3142
|
|
3080
|
-
tf_resources = []
|
3143
|
+
tf_resources: list[TFResource] = []
|
3081
3144
|
self.init_common_outputs(tf_resources, spec)
|
3082
3145
|
tf_resource = aws_sns_topic(identifier, **values)
|
3083
3146
|
tf_resources.append(tf_resource)
|
3084
3147
|
|
3085
3148
|
if "subscriptions" in common_values:
|
3086
|
-
subscriptions = common_values
|
3149
|
+
subscriptions = common_values["subscriptions"]
|
3087
3150
|
for index, sub in enumerate(subscriptions):
|
3088
|
-
sub_values = {
|
3089
|
-
|
3151
|
+
sub_values = {
|
3152
|
+
"topic_arn": "${aws_sns_topic" + "." + identifier + ".arn}"
|
3153
|
+
}
|
3154
|
+
|
3090
3155
|
protocol = sub["protocol"]
|
3091
3156
|
endpoint = sub["endpoint"]
|
3092
3157
|
if protocol == "email" and not EMAIL_REGEX.match(endpoint):
|
@@ -3111,17 +3176,19 @@ class TerrascriptClient:
|
|
3111
3176
|
tf_resources.append(Output(output_name, value=output_value))
|
3112
3177
|
self.add_resources(account, tf_resources)
|
3113
3178
|
|
3114
|
-
def populate_tf_resource_dynamodb(self, spec):
|
3179
|
+
def populate_tf_resource_dynamodb(self, spec: ExternalResourceSpec) -> None:
|
3115
3180
|
account = spec.provisioner_name
|
3116
3181
|
identifier = spec.identifier
|
3117
3182
|
common_values = self.init_values(spec)
|
3118
3183
|
output_prefix = spec.output_prefix
|
3119
3184
|
uid = self.uids.get(account)
|
3120
3185
|
|
3121
|
-
tf_resources = []
|
3186
|
+
tf_resources: list[TFResource] = []
|
3122
3187
|
self.init_common_outputs(tf_resources, spec)
|
3123
3188
|
region = common_values.get("region") or self.default_regions.get(account)
|
3189
|
+
assert region # make mypy happy
|
3124
3190
|
specs = common_values.get("specs")
|
3191
|
+
assert specs is not None # make mypy happy
|
3125
3192
|
all_tables = []
|
3126
3193
|
for _spec in specs:
|
3127
3194
|
defaults = self.get_values(_spec["defaults"])
|
@@ -3135,9 +3202,11 @@ class TerrascriptClient:
|
|
3135
3202
|
# Terraform resource reference:
|
3136
3203
|
# https://www.terraform.io/docs/providers/aws/r/
|
3137
3204
|
# dynamodb_table.html
|
3138
|
-
values = {
|
3139
|
-
|
3140
|
-
|
3205
|
+
values = {
|
3206
|
+
"name": table,
|
3207
|
+
"tags": common_values["tags"],
|
3208
|
+
}
|
3209
|
+
|
3141
3210
|
values.update(defaults)
|
3142
3211
|
values["attribute"] = attributes
|
3143
3212
|
if self._multiregion_account(account):
|
@@ -3158,9 +3227,11 @@ class TerrascriptClient:
|
|
3158
3227
|
# https://www.terraform.io/docs/providers/aws/r/iam_access_key.html
|
3159
3228
|
|
3160
3229
|
# iam user for table
|
3161
|
-
values = {
|
3162
|
-
|
3163
|
-
|
3230
|
+
values = {
|
3231
|
+
"name": identifier,
|
3232
|
+
"tags": common_values["tags"],
|
3233
|
+
}
|
3234
|
+
|
3164
3235
|
user_tf_resource = aws_iam_user(identifier, **values)
|
3165
3236
|
tf_resources.append(user_tf_resource)
|
3166
3237
|
|
@@ -3200,23 +3271,24 @@ class TerrascriptClient:
|
|
3200
3271
|
|
3201
3272
|
self.add_resources(account, tf_resources)
|
3202
3273
|
|
3203
|
-
def populate_tf_resource_ecr(self, spec):
|
3274
|
+
def populate_tf_resource_ecr(self, spec: ExternalResourceSpec) -> None:
|
3204
3275
|
account = spec.provisioner_name
|
3205
3276
|
identifier = spec.identifier
|
3206
3277
|
common_values = self.init_values(spec)
|
3207
3278
|
output_prefix = spec.output_prefix
|
3208
3279
|
|
3209
|
-
tf_resources = []
|
3280
|
+
tf_resources: list[TFResource] = []
|
3210
3281
|
self.init_common_outputs(tf_resources, spec)
|
3211
3282
|
|
3212
3283
|
# ecr repository
|
3213
3284
|
# Terraform resource reference:
|
3214
3285
|
# https://www.terraform.io/docs/providers/aws/r/ecr_repository.html
|
3215
|
-
values = {}
|
3286
|
+
values: dict[str, Any] = {}
|
3216
3287
|
values["name"] = identifier
|
3217
3288
|
values["tags"] = common_values["tags"]
|
3218
3289
|
|
3219
3290
|
region = common_values.get("region") or self.default_regions.get(account)
|
3291
|
+
assert region # make mypy happy
|
3220
3292
|
if self._multiregion_account(account):
|
3221
3293
|
values["provider"] = "aws." + region
|
3222
3294
|
ecr_tf_resource = aws_ecr_repository(identifier, **values)
|
@@ -3242,11 +3314,12 @@ class TerrascriptClient:
|
|
3242
3314
|
# https://www.terraform.io/docs/providers/aws/r/iam_access_key.html
|
3243
3315
|
|
3244
3316
|
# iam user for repository
|
3245
|
-
|
3246
|
-
|
3247
|
-
|
3248
|
-
|
3249
|
-
|
3317
|
+
values_iam_user: dict[str, Any] = {
|
3318
|
+
"name": identifier,
|
3319
|
+
"tags": common_values["tags"],
|
3320
|
+
"depends_on": self.get_dependencies([ecr_tf_resource]),
|
3321
|
+
}
|
3322
|
+
user_tf_resource = aws_iam_user(identifier, **values_iam_user)
|
3250
3323
|
tf_resources.append(user_tf_resource)
|
3251
3324
|
|
3252
3325
|
# iam access key for user
|
@@ -3255,8 +3328,7 @@ class TerrascriptClient:
|
|
3255
3328
|
)
|
3256
3329
|
|
3257
3330
|
# iam user policy for bucket
|
3258
|
-
|
3259
|
-
values["name"] = identifier
|
3331
|
+
values_policy: dict[str, Any] = {"name": identifier}
|
3260
3332
|
policy = {
|
3261
3333
|
"Version": "2012-10-17",
|
3262
3334
|
"Statement": [
|
@@ -3293,10 +3365,10 @@ class TerrascriptClient:
|
|
3293
3365
|
},
|
3294
3366
|
],
|
3295
3367
|
}
|
3296
|
-
|
3297
|
-
|
3368
|
+
values_policy["policy"] = json.dumps(policy, sort_keys=True)
|
3369
|
+
values_policy["depends_on"] = self.get_dependencies([user_tf_resource])
|
3298
3370
|
|
3299
|
-
tf_aws_iam_policy = aws_iam_policy(identifier, **
|
3371
|
+
tf_aws_iam_policy = aws_iam_policy(identifier, **values_policy)
|
3300
3372
|
tf_resources.append(tf_aws_iam_policy)
|
3301
3373
|
|
3302
3374
|
tf_aws_iam_user_policy_attachment = aws_iam_user_policy_attachment(
|
@@ -3309,7 +3381,7 @@ class TerrascriptClient:
|
|
3309
3381
|
|
3310
3382
|
self.add_resources(account, tf_resources)
|
3311
3383
|
|
3312
|
-
def populate_tf_resource_s3_cloudfront(self, spec):
|
3384
|
+
def populate_tf_resource_s3_cloudfront(self, spec: ExternalResourceSpec) -> None:
|
3313
3385
|
account = spec.provisioner_name
|
3314
3386
|
identifier = spec.identifier
|
3315
3387
|
common_values = self.init_values(spec)
|
@@ -3317,17 +3389,15 @@ class TerrascriptClient:
|
|
3317
3389
|
|
3318
3390
|
bucket_tf_resource = self.populate_tf_resource_s3(spec)
|
3319
3391
|
|
3320
|
-
tf_resources = []
|
3392
|
+
tf_resources: list[TFResource] = []
|
3321
3393
|
|
3322
3394
|
# cloudfront origin access identity
|
3323
|
-
values = {}
|
3324
|
-
values["comment"] = f"{identifier}-cf-identity"
|
3395
|
+
values = {"comment": f"{identifier}-cf-identity"}
|
3325
3396
|
cf_oai_tf_resource = aws_cloudfront_origin_access_identity(identifier, **values)
|
3326
3397
|
tf_resources.append(cf_oai_tf_resource)
|
3327
3398
|
|
3328
3399
|
# bucket policy for cloudfront
|
3329
|
-
|
3330
|
-
values["bucket"] = identifier
|
3400
|
+
values_policy: dict[str, Any] = {"bucket": identifier}
|
3331
3401
|
policy = {
|
3332
3402
|
"Version": "2012-10-17",
|
3333
3403
|
"Statement": [
|
@@ -3345,26 +3415,27 @@ class TerrascriptClient:
|
|
3345
3415
|
}
|
3346
3416
|
],
|
3347
3417
|
}
|
3348
|
-
|
3349
|
-
|
3418
|
+
values_policy["policy"] = json.dumps(policy, sort_keys=True)
|
3419
|
+
values_policy["depends_on"] = self.get_dependencies([bucket_tf_resource])
|
3350
3420
|
region = common_values.get("region") or self.default_regions.get(account)
|
3421
|
+
assert region # make mypy happy
|
3351
3422
|
if self._multiregion_account(account):
|
3352
|
-
|
3353
|
-
bucket_policy_tf_resource = aws_s3_bucket_policy(identifier, **
|
3423
|
+
values_policy["provider"] = "aws." + region
|
3424
|
+
bucket_policy_tf_resource = aws_s3_bucket_policy(identifier, **values_policy)
|
3354
3425
|
tf_resources.append(bucket_policy_tf_resource)
|
3355
3426
|
|
3356
|
-
|
3427
|
+
distribution_config = common_values.get("distribution_config", {})
|
3357
3428
|
# aws_s3_bucket_acl
|
3358
|
-
if "logging_config" in
|
3429
|
+
if "logging_config" in distribution_config:
|
3359
3430
|
# we could set this at a global level with a standard name like "cloudfront"
|
3360
3431
|
# but we need all aws accounts upgraded to aws provider >3.60 first
|
3361
3432
|
tf_resources.append(
|
3362
3433
|
aws_cloudfront_log_delivery_canonical_user_id(identifier)
|
3363
3434
|
)
|
3364
3435
|
|
3365
|
-
logging_config_bucket =
|
3436
|
+
logging_config_bucket = distribution_config["logging_config"]
|
3366
3437
|
acl_values = {}
|
3367
|
-
access_control_policy = {
|
3438
|
+
access_control_policy: dict[str, Any] = {
|
3368
3439
|
"owner": {
|
3369
3440
|
"id": "${data.aws_canonical_user_id.current.id}",
|
3370
3441
|
},
|
@@ -3388,7 +3459,7 @@ class TerrascriptClient:
|
|
3388
3459
|
}
|
3389
3460
|
external_account_id = logging_config_bucket.pop("external_account_id", None)
|
3390
3461
|
if external_account_id:
|
3391
|
-
external_account_policy = {
|
3462
|
+
external_account_policy: dict[str, Any] = {
|
3392
3463
|
"grantee": {
|
3393
3464
|
"id": external_account_id,
|
3394
3465
|
"type": "CanonicalUser",
|
@@ -3403,13 +3474,15 @@ class TerrascriptClient:
|
|
3403
3474
|
tf_resources.append(aws_s3_bucket_acl_resource)
|
3404
3475
|
|
3405
3476
|
# cloud front distribution
|
3406
|
-
|
3407
|
-
|
3477
|
+
distribution_config["tags"] = common_values["tags"]
|
3478
|
+
distribution_config.setdefault("default_cache_behavior", {}).setdefault(
|
3408
3479
|
"target_origin_id", "default"
|
3409
3480
|
)
|
3410
3481
|
origin = {
|
3411
3482
|
"domain_name": "${" + bucket_tf_resource.bucket_domain_name + "}",
|
3412
|
-
"origin_id":
|
3483
|
+
"origin_id": distribution_config["default_cache_behavior"][
|
3484
|
+
"target_origin_id"
|
3485
|
+
],
|
3413
3486
|
"s3_origin_config": {
|
3414
3487
|
"origin_access_identity": "origin-access-identity/cloudfront/"
|
3415
3488
|
+ "${"
|
@@ -3417,8 +3490,10 @@ class TerrascriptClient:
|
|
3417
3490
|
+ "}"
|
3418
3491
|
},
|
3419
3492
|
}
|
3420
|
-
|
3421
|
-
cf_distribution_tf_resource = aws_cloudfront_distribution(
|
3493
|
+
distribution_config["origin"] = [origin]
|
3494
|
+
cf_distribution_tf_resource = aws_cloudfront_distribution(
|
3495
|
+
identifier, **distribution_config
|
3496
|
+
)
|
3422
3497
|
tf_resources.append(cf_distribution_tf_resource)
|
3423
3498
|
|
3424
3499
|
# outputs
|
@@ -3443,7 +3518,7 @@ class TerrascriptClient:
|
|
3443
3518
|
|
3444
3519
|
self.add_resources(account, tf_resources)
|
3445
3520
|
|
3446
|
-
def populate_tf_resource_s3_sqs(self, spec):
|
3521
|
+
def populate_tf_resource_s3_sqs(self, spec: ExternalResourceSpec) -> None:
|
3447
3522
|
account = spec.provisioner_name
|
3448
3523
|
identifier = spec.identifier
|
3449
3524
|
common_values = self.init_values(spec)
|
@@ -3453,12 +3528,13 @@ class TerrascriptClient:
|
|
3453
3528
|
bucket_tf_resource = self.populate_tf_resource_s3(spec)
|
3454
3529
|
|
3455
3530
|
region = common_values.get("region") or self.default_regions.get(account)
|
3531
|
+
assert region # make mypy happy
|
3456
3532
|
provider = ""
|
3457
3533
|
if self._multiregion_account(account):
|
3458
3534
|
provider = "aws." + region
|
3459
|
-
tf_resources = []
|
3535
|
+
tf_resources: list[TFResource] = []
|
3460
3536
|
sqs_identifier = f"{identifier}-sqs"
|
3461
|
-
sqs_values = {"name": sqs_identifier}
|
3537
|
+
sqs_values: dict[str, Any] = {"name": sqs_identifier}
|
3462
3538
|
|
3463
3539
|
sqs_values["visibility_timeout_seconds"] = int(
|
3464
3540
|
common_values.get("visibility_timeout_seconds", 30)
|
@@ -3491,15 +3567,15 @@ class TerrascriptClient:
|
|
3491
3567
|
if kms_encryption:
|
3492
3568
|
kms_identifier = f"{identifier}-kms"
|
3493
3569
|
kms_values = {
|
3494
|
-
"description": "app-interface created KMS key for" + sqs_identifier
|
3570
|
+
"description": "app-interface created KMS key for" + sqs_identifier,
|
3571
|
+
"key_usage": str(
|
3572
|
+
common_values.get("key_usage", "ENCRYPT_DECRYPT")
|
3573
|
+
).upper(),
|
3574
|
+
"customer_master_key_spec": str(
|
3575
|
+
common_values.get("customer_master_key_spec", "SYMMETRIC_DEFAULT")
|
3576
|
+
).upper(),
|
3577
|
+
"is_enabled": common_values.get("is_enabled", True),
|
3495
3578
|
}
|
3496
|
-
kms_values["key_usage"] = str(
|
3497
|
-
common_values.get("key_usage", "ENCRYPT_DECRYPT")
|
3498
|
-
).upper()
|
3499
|
-
kms_values["customer_master_key_spec"] = str(
|
3500
|
-
common_values.get("customer_master_key_spec", "SYMMETRIC_DEFAULT")
|
3501
|
-
).upper()
|
3502
|
-
kms_values["is_enabled"] = common_values.get("is_enabled", True)
|
3503
3579
|
|
3504
3580
|
kms_policy = {
|
3505
3581
|
"Version": "2012-10-17",
|
@@ -3575,16 +3651,16 @@ class TerrascriptClient:
|
|
3575
3651
|
# https://www.terraform.io/docs/providers/aws/r/iam_access_key.html
|
3576
3652
|
|
3577
3653
|
# iam user for queue
|
3578
|
-
values = {}
|
3579
|
-
values["name"] = sqs_identifier
|
3654
|
+
values: dict[str, Any] = {"name": sqs_identifier}
|
3580
3655
|
user_tf_resource = aws_iam_user(sqs_identifier, **values)
|
3581
3656
|
tf_resources.append(user_tf_resource)
|
3582
3657
|
|
3583
3658
|
# iam access key for user
|
3584
|
-
|
3585
|
-
|
3586
|
-
|
3587
|
-
|
3659
|
+
values_key: dict[str, Any] = {
|
3660
|
+
"user": sqs_identifier,
|
3661
|
+
"depends_on": self.get_dependencies([user_tf_resource]),
|
3662
|
+
}
|
3663
|
+
access_key_tf_resource = aws_iam_access_key(sqs_identifier, **values_key)
|
3588
3664
|
tf_resources.append(access_key_tf_resource)
|
3589
3665
|
# outputs
|
3590
3666
|
# sqs_aws_access_key_id
|
@@ -3597,9 +3673,8 @@ class TerrascriptClient:
|
|
3597
3673
|
tf_resources.append(Output(output_name, value=output_value, sensitive=True))
|
3598
3674
|
|
3599
3675
|
# iam policy for queue
|
3600
|
-
|
3601
|
-
|
3602
|
-
policy = {
|
3676
|
+
values_policy: dict[str, Any] = {"name": sqs_identifier}
|
3677
|
+
policy: dict[str, Any] = {
|
3603
3678
|
"Version": "2012-10-17",
|
3604
3679
|
"Statement": [
|
3605
3680
|
{
|
@@ -3620,20 +3695,21 @@ class TerrascriptClient:
|
|
3620
3695
|
"Resource": [sqs_values["kms_master_key_id"]],
|
3621
3696
|
}
|
3622
3697
|
policy["Statement"].append(kms_statement)
|
3623
|
-
|
3624
|
-
policy_tf_resource = aws_iam_policy(sqs_identifier, **
|
3698
|
+
values_policy["policy"] = json.dumps(policy, sort_keys=True)
|
3699
|
+
policy_tf_resource = aws_iam_policy(sqs_identifier, **values_policy)
|
3625
3700
|
tf_resources.append(policy_tf_resource)
|
3626
3701
|
|
3627
3702
|
# iam user policy attachment
|
3628
|
-
|
3629
|
-
|
3630
|
-
|
3631
|
-
|
3632
|
-
|
3633
|
-
|
3634
|
-
|
3703
|
+
values_user_policy: dict[str, Any] = {
|
3704
|
+
"user": sqs_identifier,
|
3705
|
+
"policy_arn": "${" + policy_tf_resource.arn + "}",
|
3706
|
+
"depends_on": self.get_dependencies([
|
3707
|
+
user_tf_resource,
|
3708
|
+
policy_tf_resource,
|
3709
|
+
]),
|
3710
|
+
}
|
3635
3711
|
user_policy_attachment_tf_resource = aws_iam_user_policy_attachment(
|
3636
|
-
sqs_identifier, **
|
3712
|
+
sqs_identifier, **values_user_policy
|
3637
3713
|
)
|
3638
3714
|
tf_resources.append(user_policy_attachment_tf_resource)
|
3639
3715
|
|
@@ -3644,13 +3720,13 @@ class TerrascriptClient:
|
|
3644
3720
|
|
3645
3721
|
self.add_resources(account, tf_resources)
|
3646
3722
|
|
3647
|
-
def populate_tf_resource_cloudwatch(self, spec):
|
3723
|
+
def populate_tf_resource_cloudwatch(self, spec: ExternalResourceSpec) -> None:
|
3648
3724
|
account = spec.provisioner_name
|
3649
3725
|
identifier = spec.identifier
|
3650
3726
|
common_values = self.init_values(spec)
|
3651
3727
|
output_prefix = spec.output_prefix
|
3652
3728
|
|
3653
|
-
tf_resources = []
|
3729
|
+
tf_resources: list[TFResource] = []
|
3654
3730
|
self.init_common_outputs(tf_resources, spec)
|
3655
3731
|
|
3656
3732
|
# ecr repository
|
@@ -3666,6 +3742,7 @@ class TerrascriptClient:
|
|
3666
3742
|
}
|
3667
3743
|
|
3668
3744
|
region = common_values.get("region") or self.default_regions.get(account)
|
3745
|
+
assert region # make mypy happy
|
3669
3746
|
provider = ""
|
3670
3747
|
if self._multiregion_account(account):
|
3671
3748
|
provider = "aws." + region
|
@@ -3741,29 +3818,26 @@ class TerrascriptClient:
|
|
3741
3818
|
"filename": zip_file,
|
3742
3819
|
"source_code_hash": '${filebase64sha256("' + zip_file + '")}',
|
3743
3820
|
"role": "${" + role_tf_resource.arn + "}",
|
3744
|
-
|
3745
|
-
|
3746
|
-
|
3747
|
-
|
3748
|
-
|
3749
|
-
|
3750
|
-
|
3751
|
-
|
3752
|
-
lambda_values["vpc_config"] = {
|
3753
|
-
"subnet_ids": "${data.aws_elasticsearch_domain."
|
3754
|
-
+ es_identifier
|
3755
|
-
+ ".vpc_options.0.subnet_ids}",
|
3756
|
-
"security_group_ids": "${data.aws_elasticsearch_domain."
|
3757
|
-
+ es_identifier
|
3758
|
-
+ ".vpc_options.0.security_group_ids}",
|
3759
|
-
}
|
3760
|
-
|
3761
|
-
lambda_values["environment"] = {
|
3762
|
-
"variables": {
|
3763
|
-
"es_endpoint": "${data.aws_elasticsearch_domain."
|
3821
|
+
"function_name": lambda_identifier,
|
3822
|
+
"runtime": common_values.get("runtime", "nodejs18.x"),
|
3823
|
+
"timeout": common_values.get("timeout", 30),
|
3824
|
+
"handler": common_values.get("handler", "index.handler"),
|
3825
|
+
"memory_size": common_values.get("memory_size", 128),
|
3826
|
+
"vpc_config": {
|
3827
|
+
"subnet_ids": "${data.aws_elasticsearch_domain."
|
3764
3828
|
+ es_identifier
|
3765
|
-
+ ".
|
3766
|
-
|
3829
|
+
+ ".vpc_options.0.subnet_ids}",
|
3830
|
+
"security_group_ids": "${data.aws_elasticsearch_domain."
|
3831
|
+
+ es_identifier
|
3832
|
+
+ ".vpc_options.0.security_group_ids}",
|
3833
|
+
},
|
3834
|
+
"environment": {
|
3835
|
+
"variables": {
|
3836
|
+
"es_endpoint": "${data.aws_elasticsearch_domain."
|
3837
|
+
+ es_identifier
|
3838
|
+
+ ".endpoint}"
|
3839
|
+
}
|
3840
|
+
},
|
3767
3841
|
}
|
3768
3842
|
|
3769
3843
|
if provider:
|
@@ -3869,13 +3943,13 @@ class TerrascriptClient:
|
|
3869
3943
|
|
3870
3944
|
self.add_resources(account, tf_resources)
|
3871
3945
|
|
3872
|
-
def populate_tf_resource_kms(self, spec):
|
3946
|
+
def populate_tf_resource_kms(self, spec: ExternalResourceSpec) -> None:
|
3873
3947
|
account = spec.provisioner_name
|
3874
3948
|
identifier = spec.identifier
|
3875
3949
|
values = self.init_values(spec)
|
3876
3950
|
output_prefix = spec.output_prefix
|
3877
3951
|
|
3878
|
-
tf_resources = []
|
3952
|
+
tf_resources: list[TFResource] = []
|
3879
3953
|
self.init_common_outputs(tf_resources, spec)
|
3880
3954
|
values.pop("identifier", None)
|
3881
3955
|
|
@@ -3892,6 +3966,7 @@ class TerrascriptClient:
|
|
3892
3966
|
if key in values:
|
3893
3967
|
values[key] = values[key].upper()
|
3894
3968
|
region = values.pop("region", None) or self.default_regions.get(account)
|
3969
|
+
assert region # make mypy happy
|
3895
3970
|
if self._multiregion_account(account):
|
3896
3971
|
values["provider"] = "aws." + region
|
3897
3972
|
|
@@ -3903,9 +3978,10 @@ class TerrascriptClient:
|
|
3903
3978
|
output_value = "${" + tf_resource.key_id + "}"
|
3904
3979
|
tf_resources.append(Output(output_name, value=output_value))
|
3905
3980
|
|
3906
|
-
alias_values = {
|
3907
|
-
|
3908
|
-
|
3981
|
+
alias_values = {
|
3982
|
+
"name": "alias/" + identifier,
|
3983
|
+
"target_key_id": "${aws_kms_key." + identifier + ".key_id}",
|
3984
|
+
}
|
3909
3985
|
if self._multiregion_account(account):
|
3910
3986
|
alias_values["provider"] = "aws." + region
|
3911
3987
|
tf_resource = aws_kms_alias(identifier, **alias_values)
|
@@ -3913,28 +3989,30 @@ class TerrascriptClient:
|
|
3913
3989
|
|
3914
3990
|
self.add_resources(account, tf_resources)
|
3915
3991
|
|
3916
|
-
def populate_tf_resource_kinesis(self, spec):
|
3992
|
+
def populate_tf_resource_kinesis(self, spec: ExternalResourceSpec) -> None:
|
3917
3993
|
account = spec.provisioner_name
|
3918
3994
|
identifier = spec.identifier
|
3919
3995
|
common_values = self.init_values(spec)
|
3920
3996
|
output_prefix = spec.output_prefix
|
3921
3997
|
|
3922
|
-
tf_resources = []
|
3998
|
+
tf_resources: list[TFResource] = []
|
3923
3999
|
self.init_common_outputs(tf_resources, spec)
|
3924
4000
|
|
3925
|
-
tags = common_values["tags"]
|
3926
|
-
kinesis_values = {
|
4001
|
+
tags: dict[str, str] = common_values["tags"]
|
4002
|
+
kinesis_values: dict[str, Any] = {
|
3927
4003
|
"name": identifier,
|
3928
4004
|
"tags": tags,
|
4005
|
+
"shard_count": common_values.get("shard_count"),
|
4006
|
+
"retention_period": common_values.get("retention_period", 24),
|
4007
|
+
"encryption_type": common_values.get("encryption_type", None),
|
3929
4008
|
}
|
3930
|
-
|
3931
|
-
kinesis_values["retention_period"] = common_values.get("retention_period", 24)
|
3932
|
-
kinesis_values["encryption_type"] = common_values.get("encryption_type", None)
|
4009
|
+
|
3933
4010
|
if kinesis_values["encryption_type"] == "KMS":
|
3934
4011
|
kinesis_values["kms_key_id"] = common_values.get("kms_key_id")
|
3935
4012
|
|
3936
4013
|
# get region and set provider if required
|
3937
4014
|
region = common_values.get("region") or self.default_regions.get(account)
|
4015
|
+
assert region # make mypy happy
|
3938
4016
|
provider = ""
|
3939
4017
|
if self._multiregion_account(account):
|
3940
4018
|
provider = "aws." + region
|
@@ -4054,34 +4132,31 @@ class TerrascriptClient:
|
|
4054
4132
|
"source_code_hash": '${filebase64sha256("' + zip_file + '")}',
|
4055
4133
|
"role": "${" + role_tf_resource.arn + "}",
|
4056
4134
|
"tags": tags,
|
4057
|
-
|
4058
|
-
|
4059
|
-
|
4060
|
-
|
4061
|
-
|
4062
|
-
|
4063
|
-
|
4064
|
-
)
|
4065
|
-
lambda_values["memory_size"] = common_values.get("memory_size", 128)
|
4066
|
-
|
4067
|
-
lambda_values["vpc_config"] = {
|
4068
|
-
"subnet_ids": "${data.aws_elasticsearch_domain."
|
4069
|
-
+ es_identifier
|
4070
|
-
+ ".vpc_options.0.subnet_ids}",
|
4071
|
-
"security_group_ids": "${data.aws_elasticsearch_domain."
|
4072
|
-
+ es_identifier
|
4073
|
-
+ ".vpc_options.0.security_group_ids}",
|
4074
|
-
}
|
4075
|
-
|
4076
|
-
index_prefix = common_values.get("index_prefix", f"{identifier}-")
|
4077
|
-
lambda_values["environment"] = {
|
4078
|
-
"variables": {
|
4079
|
-
"es_endpoint": "${data.aws_elasticsearch_domain."
|
4135
|
+
"function_name": lambda_identifier,
|
4136
|
+
"runtime": common_values.get("runtime", "python3.9"),
|
4137
|
+
"timeout": common_values.get("timeout", 30),
|
4138
|
+
"handler": common_values.get("handler", "lambda_function.handler"),
|
4139
|
+
"memory_size": common_values.get("memory_size", 128),
|
4140
|
+
"vpc_config": {
|
4141
|
+
"subnet_ids": "${data.aws_elasticsearch_domain."
|
4080
4142
|
+ es_identifier
|
4081
|
-
+ ".
|
4082
|
-
"
|
4083
|
-
|
4143
|
+
+ ".vpc_options.0.subnet_ids}",
|
4144
|
+
"security_group_ids": "${data.aws_elasticsearch_domain."
|
4145
|
+
+ es_identifier
|
4146
|
+
+ ".vpc_options.0.security_group_ids}",
|
4147
|
+
},
|
4148
|
+
"environment": {
|
4149
|
+
"variables": {
|
4150
|
+
"es_endpoint": "${data.aws_elasticsearch_domain."
|
4151
|
+
+ es_identifier
|
4152
|
+
+ ".endpoint}",
|
4153
|
+
"index_prefix": common_values.get(
|
4154
|
+
"index_prefix", f"{identifier}-"
|
4155
|
+
),
|
4156
|
+
}
|
4157
|
+
},
|
4084
4158
|
}
|
4159
|
+
|
4085
4160
|
secret_name = es_resource.get_secret_field("secret_name")
|
4086
4161
|
if secret_name:
|
4087
4162
|
lambda_values["environment"]["variables"]["secret_name"] = secret_name
|
@@ -4160,7 +4235,9 @@ class TerrascriptClient:
|
|
4160
4235
|
self.add_resources(account, tf_resources)
|
4161
4236
|
|
4162
4237
|
@staticmethod
|
4163
|
-
def _get_retention_in_days(
|
4238
|
+
def _get_retention_in_days(
|
4239
|
+
values: Mapping[str, Any], account: str, identifier: str
|
4240
|
+
) -> int:
|
4164
4241
|
default_retention_in_days = 14
|
4165
4242
|
allowed_retention_in_days = [
|
4166
4243
|
1,
|
@@ -4194,17 +4271,21 @@ class TerrascriptClient:
|
|
4194
4271
|
return retention_in_days
|
4195
4272
|
|
4196
4273
|
def get_tf_iam_service_user(
|
4197
|
-
self,
|
4198
|
-
|
4274
|
+
self,
|
4275
|
+
dep_tf_resource: TFResource | None,
|
4276
|
+
identifier: str,
|
4277
|
+
policy: Mapping[str, Any],
|
4278
|
+
tags: Mapping[str, str],
|
4279
|
+
output_prefix: str,
|
4280
|
+
) -> list[TFResource]:
|
4199
4281
|
# iam resources
|
4200
4282
|
# Terraform resource reference:
|
4201
4283
|
# https://www.terraform.io/docs/providers/aws/r/iam_access_key.html
|
4202
|
-
tf_resources = []
|
4284
|
+
tf_resources: list[TFResource] = []
|
4203
4285
|
|
4204
4286
|
# iam user
|
4205
|
-
values = {}
|
4206
|
-
|
4207
|
-
values["tags"] = tags
|
4287
|
+
values: dict[str, Any] = {"name": identifier, "tags": tags}
|
4288
|
+
|
4208
4289
|
if dep_tf_resource:
|
4209
4290
|
values["depends_on"] = self.get_dependencies([dep_tf_resource])
|
4210
4291
|
user_tf_resource = aws_iam_user(identifier, **values)
|
@@ -4216,12 +4297,13 @@ class TerrascriptClient:
|
|
4216
4297
|
)
|
4217
4298
|
|
4218
4299
|
# iam user policy
|
4219
|
-
|
4220
|
-
|
4221
|
-
|
4222
|
-
|
4300
|
+
values_policy: dict[str, Any] = {
|
4301
|
+
"name": identifier,
|
4302
|
+
"policy": json.dumps(policy, sort_keys=True),
|
4303
|
+
"depends_on": self.get_dependencies([user_tf_resource]),
|
4304
|
+
}
|
4223
4305
|
|
4224
|
-
tf_aws_iam_policy = aws_iam_policy(identifier, **
|
4306
|
+
tf_aws_iam_policy = aws_iam_policy(identifier, **values_policy)
|
4225
4307
|
tf_resources.append(tf_aws_iam_policy)
|
4226
4308
|
|
4227
4309
|
tf_aws_iam_user_policy_attachment = aws_iam_user_policy_attachment(
|
@@ -4234,11 +4316,15 @@ class TerrascriptClient:
|
|
4234
4316
|
|
4235
4317
|
return tf_resources
|
4236
4318
|
|
4237
|
-
def get_tf_iam_access_key(
|
4238
|
-
|
4239
|
-
|
4240
|
-
|
4241
|
-
values[
|
4319
|
+
def get_tf_iam_access_key(
|
4320
|
+
self, user_tf_resource: aws_iam_user, identifier: str, output_prefix: str
|
4321
|
+
) -> list[TFResource]:
|
4322
|
+
tf_resources: list[TFResource] = []
|
4323
|
+
values: dict[str, Any] = {
|
4324
|
+
"user": identifier,
|
4325
|
+
"depends_on": self.get_dependencies([user_tf_resource]),
|
4326
|
+
}
|
4327
|
+
|
4242
4328
|
tf_resource = aws_iam_access_key(identifier, **values)
|
4243
4329
|
tf_resources.append(tf_resource)
|
4244
4330
|
# outputs
|
@@ -4253,11 +4339,11 @@ class TerrascriptClient:
|
|
4253
4339
|
|
4254
4340
|
return tf_resources
|
4255
4341
|
|
4256
|
-
def add_resources(self, account, tf_resources):
|
4342
|
+
def add_resources(self, account: str, tf_resources: Iterable[TFResource]) -> None:
|
4257
4343
|
for r in tf_resources:
|
4258
4344
|
self.add_resource(account, r)
|
4259
4345
|
|
4260
|
-
def add_resource(self, account, tf_resource):
|
4346
|
+
def add_resource(self, account: str, tf_resource: TFResource) -> None:
|
4261
4347
|
if account not in self.locks:
|
4262
4348
|
logging.debug(
|
4263
4349
|
f"integration {self.integration} is disabled for account {account}. "
|
@@ -4267,7 +4353,7 @@ class TerrascriptClient:
|
|
4267
4353
|
with self.locks[account]:
|
4268
4354
|
self.tss[account].add(tf_resource)
|
4269
4355
|
|
4270
|
-
def add_moved(self, account: str, moved: Moved):
|
4356
|
+
def add_moved(self, account: str, moved: Moved) -> None:
|
4271
4357
|
if account not in self.locks:
|
4272
4358
|
logging.debug(
|
4273
4359
|
f"integration {self.integration} is disabled for account {account}. "
|
@@ -4336,7 +4422,9 @@ class TerrascriptClient:
|
|
4336
4422
|
for name, ts in self.tss.items()
|
4337
4423
|
}
|
4338
4424
|
|
4339
|
-
def init_values(
|
4425
|
+
def init_values(
|
4426
|
+
self, spec: ExternalResourceSpec, init_tags: bool = True
|
4427
|
+
) -> dict[str, Any]:
|
4340
4428
|
"""
|
4341
4429
|
Initialize the values of the terraform resource and merge the defaults and
|
4342
4430
|
overrides.
|
@@ -4389,7 +4477,7 @@ class TerrascriptClient:
|
|
4389
4477
|
return values
|
4390
4478
|
|
4391
4479
|
@staticmethod
|
4392
|
-
def aggregate_values(values):
|
4480
|
+
def aggregate_values(values: dict[str, Any]) -> None:
|
4393
4481
|
split_char = "."
|
4394
4482
|
copy = values.copy()
|
4395
4483
|
for k, v in copy.items():
|
@@ -4403,18 +4491,17 @@ class TerrascriptClient:
|
|
4403
4491
|
values.pop(k, None)
|
4404
4492
|
|
4405
4493
|
@staticmethod
|
4406
|
-
def override_values(values, overrides):
|
4494
|
+
def override_values(values: dict[str, Any], overrides: str | None) -> None:
|
4407
4495
|
if overrides is None:
|
4408
4496
|
return
|
4409
4497
|
data = json.loads(overrides)
|
4410
|
-
|
4411
|
-
values[k] = v
|
4498
|
+
values.update(data)
|
4412
4499
|
|
4413
4500
|
def init_common_outputs(
|
4414
4501
|
self,
|
4415
|
-
tf_resources: list[
|
4502
|
+
tf_resources: list[TFResource],
|
4416
4503
|
spec: ExternalResourceSpec,
|
4417
|
-
):
|
4504
|
+
) -> None:
|
4418
4505
|
output_format = "{}__{}_{}"
|
4419
4506
|
# cluster
|
4420
4507
|
output_name = output_format.format(
|
@@ -4449,11 +4536,11 @@ class TerrascriptClient:
|
|
4449
4536
|
output_value = base64.b64encode(anno_json).decode()
|
4450
4537
|
tf_resources.append(Output(output_name, value=output_value))
|
4451
4538
|
|
4452
|
-
def prefetch_resources(self, schema) -> dict[str, dict[str, str]]:
|
4539
|
+
def prefetch_resources(self, schema: str) -> dict[str, dict[str, str]]:
|
4453
4540
|
gqlapi = gql.get_api()
|
4454
4541
|
return {r["path"]: r for r in gqlapi.get_resources_by_schema(schema)}
|
4455
4542
|
|
4456
|
-
def get_raw_values(self, path) -> dict[str, str]:
|
4543
|
+
def get_raw_values(self, path: str) -> dict[str, str]:
|
4457
4544
|
if path in self._resource_cache:
|
4458
4545
|
return self._resource_cache[path]
|
4459
4546
|
|
@@ -4482,7 +4569,7 @@ class TerrascriptClient:
|
|
4482
4569
|
]
|
4483
4570
|
|
4484
4571
|
@staticmethod
|
4485
|
-
def get_elasticsearch_service_role_tf_resource():
|
4572
|
+
def get_elasticsearch_service_role_tf_resource() -> aws_iam_service_linked_role:
|
4486
4573
|
"""Service role for ElasticSearch."""
|
4487
4574
|
service_role = {
|
4488
4575
|
"aws_service_name": "es.amazonaws.com",
|
@@ -4490,7 +4577,7 @@ class TerrascriptClient:
|
|
4490
4577
|
return aws_iam_service_linked_role("elasticsearch", **service_role)
|
4491
4578
|
|
4492
4579
|
@staticmethod
|
4493
|
-
def is_elasticsearch_domain_name_valid(name):
|
4580
|
+
def is_elasticsearch_domain_name_valid(name: str) -> bool:
|
4494
4581
|
"""Handle for Error creating Elasticsearch:
|
4495
4582
|
InvalidParameterValue: Elasticsearch domain name must start with a
|
4496
4583
|
lowercase letter and must be between 3 and 28 characters. Valid
|
@@ -4498,7 +4585,7 @@ class TerrascriptClient:
|
|
4498
4585
|
if len(name) < 3 or len(name) > 28:
|
4499
4586
|
return False
|
4500
4587
|
pattern = r"^[a-z][a-z0-9-]+$"
|
4501
|
-
return re.search(pattern, name)
|
4588
|
+
return re.search(pattern, name) is not None
|
4502
4589
|
|
4503
4590
|
@staticmethod
|
4504
4591
|
def elasticsearch_log_group_identifier(
|
@@ -4600,7 +4687,7 @@ class TerrascriptClient:
|
|
4600
4687
|
resource: Mapping[str, Any],
|
4601
4688
|
values: Mapping[str, Any],
|
4602
4689
|
output_prefix: str,
|
4603
|
-
) -> tuple[list[
|
4690
|
+
) -> tuple[list[TFResource], list[dict[str, object]]]:
|
4604
4691
|
"""
|
4605
4692
|
Generate cloud_watch_log_group terraform_resources
|
4606
4693
|
for the given resource. Further, generate
|
@@ -4608,7 +4695,7 @@ class TerrascriptClient:
|
|
4608
4695
|
by the consumer.
|
4609
4696
|
"""
|
4610
4697
|
es_log_group_retention_days = 90
|
4611
|
-
tf_resources = []
|
4698
|
+
tf_resources: list[TFResource] = []
|
4612
4699
|
publishing_options = []
|
4613
4700
|
|
4614
4701
|
# res.get('', []) won't work, as publish_log_types is
|
@@ -4711,13 +4798,13 @@ class TerrascriptClient:
|
|
4711
4798
|
|
4712
4799
|
return advanced_security_options
|
4713
4800
|
|
4714
|
-
def populate_tf_resource_elasticsearch(self, spec):
|
4801
|
+
def populate_tf_resource_elasticsearch(self, spec: ExternalResourceSpec) -> None:
|
4715
4802
|
account = spec.provisioner_name
|
4716
4803
|
identifier = spec.identifier
|
4717
4804
|
values = self.init_values(spec)
|
4718
4805
|
output_prefix = spec.output_prefix
|
4719
4806
|
|
4720
|
-
tf_resources = []
|
4807
|
+
tf_resources: list[TFResource] = []
|
4721
4808
|
self.init_common_outputs(tf_resources, spec)
|
4722
4809
|
|
4723
4810
|
if not self.is_elasticsearch_domain_name_valid(values["identifier"]):
|
@@ -4730,10 +4817,11 @@ class TerrascriptClient:
|
|
4730
4817
|
)
|
4731
4818
|
|
4732
4819
|
tags = values["tags"]
|
4733
|
-
es_values = {
|
4734
|
-
|
4735
|
-
|
4736
|
-
|
4820
|
+
es_values: dict[str, Any] = {
|
4821
|
+
"domain_name": identifier,
|
4822
|
+
"tags": tags,
|
4823
|
+
"elasticsearch_version": values.get("elasticsearch_version"),
|
4824
|
+
}
|
4737
4825
|
|
4738
4826
|
(
|
4739
4827
|
log_group_resources,
|
@@ -4919,6 +5007,7 @@ class TerrascriptClient:
|
|
4919
5007
|
es_values["access_policies"] = json.dumps(access_policies, sort_keys=True)
|
4920
5008
|
|
4921
5009
|
region = values.get("region") or self.default_regions.get(account)
|
5010
|
+
assert region # make mypy happy
|
4922
5011
|
provider = ""
|
4923
5012
|
if self._multiregion_account(account):
|
4924
5013
|
provider = "aws." + region
|
@@ -5057,8 +5146,8 @@ class TerrascriptClient:
|
|
5057
5146
|
|
5058
5147
|
# TODO: @fishi0x01 remove this function after migration APPSRE-3409
|
5059
5148
|
def _build_es_advanced_security_options_deprecated(
|
5060
|
-
self, advanced_security_options:
|
5061
|
-
) ->
|
5149
|
+
self, advanced_security_options: dict[str, Any]
|
5150
|
+
) -> dict[str, Any]:
|
5062
5151
|
master_user_options = advanced_security_options.pop("master_user_options", {})
|
5063
5152
|
|
5064
5153
|
if master_user_options:
|
@@ -5079,13 +5168,13 @@ class TerrascriptClient:
|
|
5079
5168
|
|
5080
5169
|
return advanced_security_options
|
5081
5170
|
|
5082
|
-
def populate_tf_resource_acm(self, spec):
|
5171
|
+
def populate_tf_resource_acm(self, spec: ExternalResourceSpec) -> None:
|
5083
5172
|
account = spec.provisioner_name
|
5084
5173
|
identifier = spec.identifier
|
5085
5174
|
common_values = self.init_values(spec)
|
5086
5175
|
output_prefix = spec.output_prefix
|
5087
5176
|
|
5088
|
-
tf_resources = []
|
5177
|
+
tf_resources: list[TFResource] = []
|
5089
5178
|
self.init_common_outputs(tf_resources, spec)
|
5090
5179
|
|
5091
5180
|
values = {}
|
@@ -5124,6 +5213,7 @@ class TerrascriptClient:
|
|
5124
5213
|
values["subject_alternative_names"] = alt_names
|
5125
5214
|
|
5126
5215
|
region = common_values.get("region") or self.default_regions.get(account)
|
5216
|
+
assert region # make mypy happy
|
5127
5217
|
if self._multiregion_account(account):
|
5128
5218
|
values["provider"] = "aws." + region
|
5129
5219
|
|
@@ -5165,13 +5255,15 @@ class TerrascriptClient:
|
|
5165
5255
|
|
5166
5256
|
self.add_resources(account, tf_resources)
|
5167
5257
|
|
5168
|
-
def populate_tf_resource_s3_cloudfront_public_key(
|
5258
|
+
def populate_tf_resource_s3_cloudfront_public_key(
|
5259
|
+
self, spec: ExternalResourceSpec
|
5260
|
+
) -> None:
|
5169
5261
|
account = spec.provisioner_name
|
5170
5262
|
identifier = spec.identifier
|
5171
5263
|
common_values = self.init_values(spec)
|
5172
5264
|
output_prefix = spec.output_prefix
|
5173
5265
|
|
5174
|
-
tf_resources = []
|
5266
|
+
tf_resources: list[TFResource] = []
|
5175
5267
|
self.init_common_outputs(tf_resources, spec)
|
5176
5268
|
|
5177
5269
|
values = {"name": identifier, "comment": "managed by app-interface"}
|
@@ -5213,8 +5305,13 @@ class TerrascriptClient:
|
|
5213
5305
|
self.add_resources(account, tf_resources)
|
5214
5306
|
|
5215
5307
|
def _get_alb_target_ips_by_openshift_service(
|
5216
|
-
self,
|
5217
|
-
|
5308
|
+
self,
|
5309
|
+
identifier: str,
|
5310
|
+
openshift_service: str,
|
5311
|
+
account_name: str,
|
5312
|
+
namespace_info: Mapping[str, Any],
|
5313
|
+
ocm_map: OCMMap,
|
5314
|
+
) -> set[str]:
|
5218
5315
|
account = self.accounts[account_name]
|
5219
5316
|
cluster = namespace_info["cluster"]
|
5220
5317
|
ocm = ocm_map.get(cluster["name"])
|
@@ -5240,7 +5337,9 @@ class TerrascriptClient:
|
|
5240
5337
|
return ips
|
5241
5338
|
|
5242
5339
|
@staticmethod
|
5243
|
-
def _get_alb_rule_condition_value(
|
5340
|
+
def _get_alb_rule_condition_value(
|
5341
|
+
condition: Mapping[str, Any],
|
5342
|
+
) -> dict[str, dict[str, str]]:
|
5244
5343
|
condition_type = condition["type"]
|
5245
5344
|
condition_type_key = SUPPORTED_ALB_LISTENER_RULE_CONDITION_TYPE_MAPPING.get(
|
5246
5345
|
condition_type
|
@@ -5250,7 +5349,7 @@ class TerrascriptClient:
|
|
5250
5349
|
return {condition_type_key: {"values": condition[condition_type_key]}}
|
5251
5350
|
|
5252
5351
|
@staticmethod
|
5253
|
-
def _get_principal_for_s3_bucket_policy(region: str) ->
|
5352
|
+
def _get_principal_for_s3_bucket_policy(region: str) -> dict[str, str]:
|
5254
5353
|
if region in AWS_ELB_ACCOUNT_IDS:
|
5255
5354
|
return {"AWS": f"arn:aws:iam::{AWS_ELB_ACCOUNT_IDS[region]}:root"}
|
5256
5355
|
if region in AWS_US_GOV_ELB_ACCOUNT_IDS:
|
@@ -5259,16 +5358,18 @@ class TerrascriptClient:
|
|
5259
5358
|
}
|
5260
5359
|
return {"Service": "logdelivery.elasticloadbalancing.amazonaws.com"}
|
5261
5360
|
|
5262
|
-
def populate_tf_resource_alb(
|
5361
|
+
def populate_tf_resource_alb(
|
5362
|
+
self, spec: ExternalResourceSpec, ocm_map: OCMMap | None = None
|
5363
|
+
) -> None:
|
5263
5364
|
account = spec.provisioner_name
|
5264
5365
|
identifier = spec.identifier
|
5265
5366
|
common_values = self.init_values(spec)
|
5266
5367
|
output_prefix = spec.output_prefix
|
5267
|
-
tf_resources = []
|
5368
|
+
tf_resources: list[TFResource] = []
|
5268
5369
|
namespace_info = spec.namespace
|
5269
5370
|
self.init_common_outputs(tf_resources, spec)
|
5270
5371
|
|
5271
|
-
default_region = self.default_regions
|
5372
|
+
default_region = self.default_regions[account]
|
5272
5373
|
cluster_region = namespace_info["cluster"]["spec"]["region"]
|
5273
5374
|
|
5274
5375
|
if self._multiregion_account(account):
|
@@ -5421,6 +5522,10 @@ class TerrascriptClient:
|
|
5421
5522
|
t_protocol_version = t.get("protocol_version") or "HTTP1"
|
5422
5523
|
|
5423
5524
|
if t_openshift_service:
|
5525
|
+
if ocm_map is None:
|
5526
|
+
raise ValueError(
|
5527
|
+
"ocm_map should be not none raising exception to make mypy happy"
|
5528
|
+
)
|
5424
5529
|
target_ips = self._get_alb_target_ips_by_openshift_service(
|
5425
5530
|
identifier, t_openshift_service, account, namespace_info, ocm_map
|
5426
5531
|
)
|
@@ -5593,7 +5698,7 @@ class TerrascriptClient:
|
|
5593
5698
|
for rule_num, rule in enumerate(resource["rules"]):
|
5594
5699
|
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener_rule#type
|
5595
5700
|
action = rule["action"]
|
5596
|
-
action_values = {}
|
5701
|
+
action_values: dict[str, Any] = {}
|
5597
5702
|
action_type = action.get("type")
|
5598
5703
|
if action_type == "forward":
|
5599
5704
|
action_values = {
|
@@ -5679,18 +5784,19 @@ class TerrascriptClient:
|
|
5679
5784
|
|
5680
5785
|
self.add_resources(account, tf_resources)
|
5681
5786
|
|
5682
|
-
def populate_tf_resource_secrets_manager(self, spec):
|
5787
|
+
def populate_tf_resource_secrets_manager(self, spec: ExternalResourceSpec) -> None:
|
5683
5788
|
account = spec.provisioner_name
|
5684
5789
|
identifier = spec.identifier
|
5685
5790
|
common_values = self.init_values(spec)
|
5686
5791
|
output_prefix = spec.output_prefix
|
5687
5792
|
|
5688
|
-
tf_resources = []
|
5793
|
+
tf_resources: list[TFResource] = []
|
5689
5794
|
self.init_common_outputs(tf_resources, spec)
|
5690
5795
|
|
5691
5796
|
values = {"name": identifier}
|
5692
5797
|
|
5693
5798
|
region = common_values.get("region") or self.default_regions.get(account)
|
5799
|
+
assert region # make mypy happy
|
5694
5800
|
if self._multiregion_account(account):
|
5695
5801
|
values["provider"] = "aws." + region
|
5696
5802
|
|
@@ -5698,9 +5804,10 @@ class TerrascriptClient:
|
|
5698
5804
|
tf_resources.append(aws_secret_resource)
|
5699
5805
|
|
5700
5806
|
secret = common_values.get("secret")
|
5807
|
+
assert secret # make mypy happy
|
5701
5808
|
secret_data = self.secret_reader.read_all(secret)
|
5702
5809
|
|
5703
|
-
version_values = {
|
5810
|
+
version_values: dict[str, Any] = {
|
5704
5811
|
"secret_id": "${" + aws_secret_resource.id + "}",
|
5705
5812
|
"secret_string": json.dumps(secret_data, sort_keys=True),
|
5706
5813
|
}
|
@@ -5781,7 +5888,7 @@ class TerrascriptClient:
|
|
5781
5888
|
return True
|
5782
5889
|
return False
|
5783
5890
|
|
5784
|
-
def populate_tf_resource_asg(self, spec) -> None:
|
5891
|
+
def populate_tf_resource_asg(self, spec: ExternalResourceSpec) -> None:
|
5785
5892
|
account = spec.provisioner_name
|
5786
5893
|
identifier = spec.identifier
|
5787
5894
|
common_values = self.init_values(spec)
|
@@ -5868,7 +5975,7 @@ class TerrascriptClient:
|
|
5868
5975
|
template_resource = aws_launch_template(identifier, **template_values)
|
5869
5976
|
tf_resources.append(template_resource)
|
5870
5977
|
|
5871
|
-
asg_value = {
|
5978
|
+
asg_value: dict[str, Any] = {
|
5872
5979
|
"name": identifier,
|
5873
5980
|
"max_size": common_values.get("max_size"),
|
5874
5981
|
"min_size": common_values.get("min_size"),
|
@@ -5924,12 +6031,12 @@ class TerrascriptClient:
|
|
5924
6031
|
|
5925
6032
|
self.add_resources(account, tf_resources)
|
5926
6033
|
|
5927
|
-
def populate_tf_resource_route53_zone(self, spec):
|
6034
|
+
def populate_tf_resource_route53_zone(self, spec: ExternalResourceSpec) -> None:
|
5928
6035
|
account = spec.provisioner_name
|
5929
6036
|
identifier = spec.identifier
|
5930
6037
|
common_values = self.init_values(spec)
|
5931
6038
|
output_prefix = spec.output_prefix
|
5932
|
-
tf_resources = []
|
6039
|
+
tf_resources: list[TFResource] = []
|
5933
6040
|
self.init_common_outputs(tf_resources, spec)
|
5934
6041
|
|
5935
6042
|
# https://www.terraform.io/docs/providers/aws/r/route53_zone.html
|
@@ -5973,16 +6080,20 @@ class TerrascriptClient:
|
|
5973
6080
|
|
5974
6081
|
self.add_resources(account, tf_resources)
|
5975
6082
|
|
5976
|
-
def populate_tf_resource_rosa_authenticator(
|
6083
|
+
def populate_tf_resource_rosa_authenticator(
|
6084
|
+
self, spec: ExternalResourceSpec
|
6085
|
+
) -> None:
|
5977
6086
|
account = spec.provisioner_name
|
5978
6087
|
identifier = spec.identifier
|
5979
6088
|
common_values = self.init_values(spec)
|
5980
|
-
tf_resources = []
|
6089
|
+
tf_resources: list[TFResource] = []
|
5981
6090
|
self.init_common_outputs(tf_resources, spec)
|
5982
6091
|
|
5983
6092
|
# Prepare consts
|
5984
6093
|
region = common_values.get("region") or self.default_regions.get(account)
|
6094
|
+
assert region # make mypy happy
|
5985
6095
|
bucket_name = common_values.get("cognito_callback_bucket_name")
|
6096
|
+
assert bucket_name # make mypy happy
|
5986
6097
|
bucket_url = f"https://{bucket_name}.s3.{region}.amazonaws.com"
|
5987
6098
|
lambda_managed_policy_arn = (
|
5988
6099
|
"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
|
@@ -5992,6 +6103,7 @@ class TerrascriptClient:
|
|
5992
6103
|
vpc_id = common_values.get("vpc_id")
|
5993
6104
|
subnet_ids = common_values.get("subnet_ids")
|
5994
6105
|
network_interface_ids = common_values.get("network_interface_ids")
|
6106
|
+
assert network_interface_ids is not None # make mypy happy
|
5995
6107
|
certificate_arn = common_values.get("certificate_arn")
|
5996
6108
|
domain_name = common_values.get("domain_name")
|
5997
6109
|
openshift_ingress_load_balancer_arn = common_values.get(
|
@@ -6868,15 +6980,18 @@ class TerrascriptClient:
|
|
6868
6980
|
|
6869
6981
|
self.add_resources(account, tf_resources)
|
6870
6982
|
|
6871
|
-
def populate_tf_resource_rosa_authenticator_vpce(
|
6983
|
+
def populate_tf_resource_rosa_authenticator_vpce(
|
6984
|
+
self, spec: ExternalResourceSpec
|
6985
|
+
) -> None:
|
6872
6986
|
account = spec.provisioner_name
|
6873
6987
|
identifier = spec.identifier
|
6874
6988
|
common_values = self.init_values(spec)
|
6875
|
-
tf_resources = []
|
6989
|
+
tf_resources: list[TFResource] = []
|
6876
6990
|
self.init_common_outputs(tf_resources, spec)
|
6877
6991
|
|
6878
6992
|
vpc_id = common_values.get("vpc_id")
|
6879
6993
|
subnet_ids = common_values.get("subnet_ids")
|
6994
|
+
assert subnet_ids is not None # make mypy happy
|
6880
6995
|
vpce_security_group_rule_common_args = common_values.get(
|
6881
6996
|
"vpce_security_group_rule_common_properties", None
|
6882
6997
|
)
|
@@ -6935,11 +7050,11 @@ class TerrascriptClient:
|
|
6935
7050
|
|
6936
7051
|
self.add_resources(account, tf_resources)
|
6937
7052
|
|
6938
|
-
def populate_tf_resource_msk(self, spec):
|
7053
|
+
def populate_tf_resource_msk(self, spec: ExternalResourceSpec) -> None:
|
6939
7054
|
account = spec.provisioner_name
|
6940
7055
|
values = self.init_values(spec)
|
6941
7056
|
output_prefix = spec.output_prefix
|
6942
|
-
tf_resources = []
|
7057
|
+
tf_resources: list[TFResource] = []
|
6943
7058
|
resource_id = spec.identifier
|
6944
7059
|
|
6945
7060
|
del values["identifier"]
|