Page MenuHomePhabricator

D12928.id43027.diff
No OneTemporary

D12928.id43027.diff

diff --git a/services/terraform/remote/aws_iam.tf b/services/terraform/remote/aws_iam.tf
--- a/services/terraform/remote/aws_iam.tf
+++ b/services/terraform/remote/aws_iam.tf
@@ -70,6 +70,18 @@
}
}
+# Role for keyserver service nodes
+# Allows for ecs exec
+resource "aws_iam_role" "keyserver_node_ecs_task_role" {
+ name = "ecs-iam_role"
+ description = "Allows to SSH into ECS containers"
+ assume_role_policy = data.aws_iam_policy_document.assume_role_ecs_ec2.json
+
+ managed_policy_arns = [
+ aws_iam_policy.allow_ecs_exec.arn,
+ ]
+}
+
# Allows ECS Exec to SSH into service task containers
resource "aws_iam_policy" "allow_ecs_exec" {
name = "allow-ecs-exec"
diff --git a/services/terraform/remote/secrets.json b/services/terraform/remote/secrets.json
--- a/services/terraform/remote/secrets.json
+++ b/services/terraform/remote/secrets.json
@@ -1,28 +1,95 @@
{
"accountIDs": {
- "production": "ENC[AES256_GCM,data:bFvAqsaeaK63a89t,iv:DItiKGCI6RPfkjQPSrUWhddvJQKOTnYEeyzgHfckrXw=,tag:5NTw9AuEXhU9eOKzd2wvtw==,type:str]",
- "staging": "ENC[AES256_GCM,data:qoJZWlb2BusLjLJV,iv:cRt9S8qKZ8qz3q41Xc1o+giTTHA0jWkTLQDFHUHFR2U=,tag:EbZKVX7NkxDmx1s1PIjIeg==,type:str]"
+ "production": "ENC[AES256_GCM,data:kuCCoz7IlxgvWF6W,iv:rOkSJ7i9rJKukhhP4Hkh12iXKCOVZGeErLFbu3mKY+w=,tag:GbsUj/IZt+oQL8Usg3xV5w==,type:str]",
+ "staging": "ENC[AES256_GCM,data:A/SixKIxXzDwgU58,iv:sVMlGpkdHWV/lWc308YkFgrZWZ6DjWOt7UQ/mRHMl6w=,tag:+xB9tswTcrw8tobrOuoSZQ==,type:str]"
},
- "keyserverPublicKey": "ENC[AES256_GCM,data:6QnxnmA21WMjsqFJHgSxh4UkzoR1LMQuoK+F4uj5cxZPqsvverDjf9OfJg==,iv:gScxT+OOcnIrnc32S/Skk1/y15k2yhMVkCjuCUkQ3Y8=,tag:ZzP+7sgxZoJHD/XpMwwxWg==,type:str]",
+ "keyserverPublicKey": "ENC[AES256_GCM,data:nVTl0xKmi2FI0CtzvJpRwrKf7eUiea2R/BFm+SFGO2MESTw/IawXxKwdWQ==,iv:HEDGp/9dLDdQtyVSa5e0dDmkVGVINdgNIl9mh/Kc6fE=,tag:r5nSo3v5m3o0kHsFPO6BvQ==,type:str]",
"emailConfig": {
- "postmarkToken": "ENC[AES256_GCM,data:9LHtrcnsPjSQ9taGbM984vHubERZZxvVrrEu0EmpSxA3fABH,iv:IGvphb6l6sCfeY6liOcmLaVsEtNKO97kSuB3YUMQVAg=,tag:+2F/or6vbv90kD1T1h+ZHA==,type:str]",
- "senderEmail": "ENC[AES256_GCM,data:TtXiJwxtgqSfJw8Lht1o89i0aNwjHLHO70v7SlAUJWJXg2sMoz8Weg==,iv:g9a/QNXyDorilDdh6GQjWmO4iZ8ngYqjMmws8O64T9M=,tag:5QrBdNY011OTvZPr9FVqEg==,type:str]",
+ "postmarkToken": "ENC[AES256_GCM,data:g6ZCrhUZAb61hsqpuLyp00/IOedGHhYhnjs7W3yjAJIhF93C,iv:rtWPRj1CCVJuP+XLKeWFbjFp1sJy/KRZDzo/+ipw/Vk=,tag:kk3JtY0ssqPtuvrMMf5rcg==,type:str]",
+ "senderEmail": "ENC[AES256_GCM,data:vsK91pGmIC3C8LlgQBkFfmyHSeX9k4gFV6mf4bgQGZ7/1e0cJrSzMg==,iv:u1NsWBYVujppzvzoL4YggavTMjTaLJgxwGRtbP6ZA24=,tag:jonR7QWhDwNsfv6J7u/cUQ==,type:str]",
"mailingGroups": {
- "inconsistencyReports": "ENC[AES256_GCM,data:WpfRg05ey0NqXD7xsJM4em2QxwBTZf1A/dhZJmll,iv:nSH3oPSmja6lvEqGLpNrpPqVmMrD8OqAU3gvMIlm68E=,tag:vIi5G+3F3eIoZP6zma7rZw==,type:str]",
- "mediaReports": "ENC[AES256_GCM,data:ayhONEdMxKQgJKtVzkcJUMWy30y/hw==,iv:Cr/vcQ/HObcbSfoKXZ8hiGwSdTETsAoohJCargaWadM=,tag:WCpfrV0SSBM+DoYIahIkpw==,type:str]",
- "errorReports": "ENC[AES256_GCM,data:5IfELwZmEvDgIalp3M4oxh8jgiJKuA==,iv:YCuAsQMiIE+ahatbc+GcJAwfr//aoGsfb6VCUeeXZh0=,tag:06RAnL4s2sFsvBJqH5IZuQ==,type:str]"
+ "inconsistencyReports": "ENC[AES256_GCM,data:hoblOUDXYEvfvsYTd9r87iyTOIRtgVaXl0ioaKM7,iv:HydsVHmutFcH1bM/S9q9cHzJ6Fi7wmBsc0GzIKRstAY=,tag:VDVYjNF/EFALq+sPNtEzEQ==,type:str]",
+ "mediaReports": "ENC[AES256_GCM,data:TLwloRlIOVHUmfIWDiLGtoaMu11mew==,iv:0C02916vp0achsYcwfQbuDYqPFCD7O97K/k1VIRvhjU=,tag:bzfgAWSR9kSJWZuDipp7Tw==,type:str]",
+ "errorReports": "ENC[AES256_GCM,data:5BxNT6CyqlXb4sqo2OaHDBW9nXt23g==,iv:14wasztkciqHKXhuqJW+TMMuWIETwdbMmxUgqxjJ/PM=,tag:7Tx+MKowFRa77pnJi0kSHw==,type:str]"
}
},
"amqpPassword": {
- "production": "ENC[AES256_GCM,data:HGWWEwKhNeIAYqqyzAo=,iv:JwsXBZwyrzvO7KvfmyE2RUmo23n+zXedS0HZpHUgg1U=,tag:CCk7MgUKbwREy9cSdJNtig==,type:str]",
- "staging": "ENC[AES256_GCM,data:DULoLDulN6rSeHVf+g0=,iv:DOPgUu1P+1c6YXYbYona3Q/rCN2X9Gs8sMiOaJgLu1A=,tag:h35i33gOmBgFAtbjFiQgWw==,type:str]"
+ "production": "ENC[AES256_GCM,data:apPbQzb3aI0LS26M4SM=,iv:FM66MLDyFysYnb+5/g7nHnv8SuhPx1l4l2ygYMEaPRE=,tag:njG4Sk1IM4+3CzAROIla4Q==,type:str]",
+ "staging": "ENC[AES256_GCM,data:Mc4lASnc3pBtAV0KfN8=,iv:rtej+MdNEgJQJWrgECdyrbXJZi2PeoW/y4RS+K15HtM=,tag:OaAwbt7xwgJb1lQdedpvnw==,type:str]"
+ },
+ "webappLandingEnvVars": {
+ "COMM_JSONCONFIG_facts_keyserver_url": {
+ "baseDomain": "ENC[AES256_GCM,data:YGf2hGjvvUrsX8pstqzHUSwxOo0=,iv:s6O6K++sMstnGYzFq9780V95xT9OrTpWSQgkfZ886hA=,tag:661Z6NUV1NdQ5x8RoYpl2A==,type:str]",
+ "basePath": "ENC[AES256_GCM,data:iQ==,iv:Yv49ymWtglxyforwMOqgcukp+x5bnQPamaB0JAYTbto=,tag:nlYBbftFYfXlYzadTpHdXw==,type:str]",
+ "baseRoutePath": "ENC[AES256_GCM,data:jA==,iv:GMCZzKWhb9WPc5MQ2Ett2xz6+NTHbtMGS44moubFRpI=,tag:3kQIXp5v+unjh4X2kqnjtQ==,type:str]",
+ "https": "ENC[AES256_GCM,data:9/rxwQ==,iv:IlzORxiWlJgJg4MxbxiPzr++Svuf5qfcAVkf6B95ctQ=,tag:sAeeP3GeVT0pKD/5q89eLA==,type:bool]",
+ "proxy": "ENC[AES256_GCM,data:jQwY,iv:lkhOmD8yUf4DZgL4he6zm0KWyseVswSZIxWXKz9vbAg=,tag:xa5dNdPFaxHl+/rGRCRhNw==,type:str]"
+ },
+ "COMM_JSONCONFIG_facts_webapp_url": {
+ "baseDomain": "ENC[AES256_GCM,data:K3KmxQpBtoZWD05BZtPVRXoljuk6,iv:oXkntWzV5TIgL5LYH454kCXbeSLmAfjmfLVWCcZBhd4=,tag:gXFuy8s6lHtApWWo13TUNQ==,type:str]",
+ "basePath": "ENC[AES256_GCM,data:4w==,iv:Fb3oM0UEbShwNtbiPR33zGv9hnQiqfYd7AoaDJSiots=,tag:VfB3QHzWs0c9m3IBcPZjBg==,type:str]",
+ "baseRoutePath": "ENC[AES256_GCM,data:MA==,iv:oBwDnDi5ZNTq58hq7CoXaEcmDAltslSBKLu9J9u3hnI=,tag:hlKKlclVcF/fn3OBrUwmiA==,type:str]",
+ "https": "ENC[AES256_GCM,data:+aL6eQ==,iv:aDou9cvd/e+h2uo/9VIt6yJbzhy6roLX/pRk7hASBXU=,tag:2tAo3UN46eFf8CCim5wppw==,type:bool]",
+ "proxy": "ENC[AES256_GCM,data:yaIq,iv:NRg4rnr2EO2UKB48Dq+21aJma9hzGQytzVpnQwwlE2Y=,tag:6gCH6plpKY39hHE67uzOMw==,type:str]"
+ },
+ "COMM_JSONCONFIG_facts_landing_url": {
+ "baseDomain": "ENC[AES256_GCM,data:Fsbo2xE3gTxvzsHT7P0scUisJnWM,iv:h3EDy1KaHsrPUhx3HV8oV+HSeU9149okPXqTAOjZ6kA=,tag:v3dYtMKuFLEj6+Gq4YSzaw==,type:str]",
+ "basePath": "ENC[AES256_GCM,data:Sg==,iv:TqbENv4Y3kFjGLhDnq3NUqhG1eSzHt6965OmspVE58k=,tag:ukmGtMYK//SIcJLnFFtndw==,type:str]",
+ "baseRoutePath": "ENC[AES256_GCM,data:iQ==,iv:vcrFHIQLa/7YB5MPW6hzCekelHUQprFlhrlaBaDgwdc=,tag:uzSdJjQWZm2FnmiexUM0og==,type:str]",
+ "https": "ENC[AES256_GCM,data:1mF6Sw==,iv:GWKdreVvZCD/9gMoEdbYlHL4HXsMJaT2zSopLvxrUuw=,tag:xeMk+AOcHPm7APhalOHwkw==,type:bool]"
+ },
+ "COMM_JSONCONFIG_secrets_alchemy": {
+ "key": "ENC[AES256_GCM,data:OJh3fnTACBGOQ6qrk7FcbbB5hy3ECsNxNAs6t0aHtjo=,iv:+DBjvhSKRn/QWrEfVJ3vtVmv3dxZH3NzZi1d1HQ+X8Q=,tag:pzo6qQF8JxYe0FPgQxideA==,type:str]"
+ },
+ "COMM_JSONCONFIG_secrets_walletconnect": {
+ "key": "ENC[AES256_GCM,data:cR5TVGZDKZng4nvbHzpwk+Nj0U3t8j54FLrn35Ckf9k=,iv:BI0ftkm6pzL/46GAA4BOOFPNcbqlsn6mr4z2lsHSjm4=,tag:1CReGDvhibkCsyLC3JnYKQ==,type:str]"
+ },
+ "COMM_JSONCONFIG_secrets_geoip_license": {
+ "key": "ENC[AES256_GCM,data:GAvcKVvU7bWUe8+idx7zNA==,iv:mHIS+xV7jDF+Dc89Hu/fwKZ7e9rodc5Za4qmKSbVekc=,tag:1rQuAnoxmhST7csMlkbQZg==,type:str]"
+ },
+ "COMM_JSONCONFIG_secrets_postmark": {
+ "apiToken": "ENC[AES256_GCM,data:aK4jAHXCjmPSLSVFoRDr9WJoy3po+IoBWxJFbr/nXW1+b18W,iv:QzDmUACPb2+TGBxi2DNt55V+eJmFOH5062siLoLDbEo=,tag:Jz7xJ8o1QzeLDulj6zHA7g==,type:str]"
+ },
+ "COMM_JSONCONFIG_secrets_neynar": {
+ "key": "ENC[AES256_GCM,data:+QpwbD+gcc9lfXT73eXAYpsJmaPkiEunRjulCwY+EVZah8jQ,iv:O0LwzvTh5R1EavIf4hujkTrXur6z8Ym+4HownchsCqE=,tag:mRGGOpPW7P5ljHwkcoGriw==,type:str]"
+ }
+ },
+ "webappLandingStagingEnvVars": {
+ "COMM_JSONCONFIG_facts_webapp_url": {
+ "baseDomain": "ENC[AES256_GCM,data:3far99kHAl0T66Bh7+MjK9hBFW+K,iv:PqnT5xPXsISW9zGA7r9vjs0Qu5bjnhxTJ9+GIf31Neo=,tag:pUxNSE8UGWvJBrNB5wTZ1Q==,type:str]",
+ "basePath": "ENC[AES256_GCM,data:8g==,iv:GV11qLKNvb69oOvPomesLNGlBGv+oDom4WXeH3fs3/I=,tag:kZ8VT0osJ9l0GtAxh+DLQQ==,type:str]",
+ "baseRoutePath": "ENC[AES256_GCM,data:3g==,iv:E6ohwF2ybKUYZv+jmSakv5F2CGZwRb2v0nLV2KjJMJ0=,tag:iFA2MCj33SkoSzvCqKCqCg==,type:str]",
+ "https": "ENC[AES256_GCM,data:VdNVtA==,iv:9JpBIx7mwriQsyQng3lMc1mhccp21fR1Cdw7vFXRuA0=,tag:hKDCTzaHdx42uu42HkOFzQ==,type:bool]",
+ "proxy": "ENC[AES256_GCM,data:pckR,iv:wyPFiqH4SvFIWeeBbbg7hrnF9JAAOCxFIhNHNwMQ2jQ=,tag:PilhWu9g5x2EeMk35eWPJg==,type:str]"
+ },
+ "COMM_JSONCONFIG_facts_landing_url": {
+ "baseDomain": "ENC[AES256_GCM,data:fz4xtBjtoQqNje2tFnyvqVKBy64q,iv:pJHBTWHzd6ZxcF9UdCUQey1rjsmLoX6bKBFW9ij5Nss=,tag:od835wpIyq4q09XSin9nBA==,type:str]",
+ "basePath": "ENC[AES256_GCM,data:sg==,iv:Yi2Cd9LeWJpdQpcYoTi8MC3yUVgEKy35l93m+5G4t9s=,tag:fUpQZIwQINvZJREJvZxuVA==,type:str]",
+ "baseRoutePath": "ENC[AES256_GCM,data:lQ==,iv:83pO4fpEtG/ShQthGrlog+NywZdkMItztSH4vL4zr3k=,tag:unlLT0kZwqfmJuNYdpeLJA==,type:str]",
+ "https": "ENC[AES256_GCM,data:xovX0Q==,iv:jE2OGF+xZZkG4W58Wtnfm8jqjGpVLmzQtNnNwAi96ao=,tag:1YkSq2kRr5is1muQom/Bsg==,type:bool]"
+ }
+ },
+ "webappLandingProdEnvVars": {
+ "COMM_JSONCONFIG_facts_webapp_url": {
+ "baseDomain": "ENC[AES256_GCM,data:X6fasqy0avZp+41kjH3Gr9HdDX8=,iv:rLPcJ3oXCGnm+rjJ+16sFh3+fEq4nQMzMV4L6Cx0Z1k=,tag:MNKo9gAojKPXKEl818hvTQ==,type:str]",
+ "basePath": "ENC[AES256_GCM,data:dw==,iv:iOAya1UQl4IZtVfD5i0LGpo+xEdwaAHL3dmPVWpR9g8=,tag:es1DIuRC+BCY71gPCzPgKw==,type:str]",
+ "baseRoutePath": "ENC[AES256_GCM,data:EA==,iv:7QyNHb6o6kSodvZBRNo7EoNXKZnol7330abxYeycdmU=,tag:+ORALMoe6qWy7GaQ7Gfy1w==,type:str]",
+ "https": "ENC[AES256_GCM,data:r+zk6g==,iv:OajjkuSLoP0pdIXBxCvQO5KAt89XdKOEXaZZxPgi/Zc=,tag:fq5gV/RZVcp558niDTv0rA==,type:bool]",
+ "proxy": "ENC[AES256_GCM,data:X8+T,iv:WyfpPRMYiif5H856RBNBklHJduU/jHMpR3L9jb6mZ1I=,tag:D7g5PtCYI4JPgw736phmpQ==,type:str]"
+ },
+ "COMM_JSONCONFIG_facts_landing_url": {
+ "baseDomain": "ENC[AES256_GCM,data:SQPXRiazlhAhX+rcXW8OOA==,iv:U7xS/5tsT9ojDegFLztnVeF0S2pp350TMGYxDjvpXJs=,tag:kI0wjoDjRLyYST7Is4RADA==,type:str]",
+ "basePath": "ENC[AES256_GCM,data:fg==,iv:j1ROfswvTTiy8bDrSps6shRvtt5mMQV+Z+3UPmir2GE=,tag:H2DJYu0XRXSPKc6udFvuTQ==,type:str]",
+ "baseRoutePath": "ENC[AES256_GCM,data:iA==,iv:uv5fqM5pWdVkRSEx+oaCPsW8ipV2zU4FrrlVWDIFb9M=,tag:+s+Nk20NsYpFWLCiRzBUqA==,type:str]",
+ "https": "ENC[AES256_GCM,data:jcHJLg==,iv:KK7anHrp5IR65O8Y7Pp6U5TQJCqQ2Z2rl7jwT5VPvIs=,tag:8j+TBZRWyKQXGU9/lORPEA==,type:bool]"
+ }
},
"sops": {
"kms": [
{
"arn": "arn:aws:kms:us-east-2:319076408221:key/2e54d528-50a2-489c-a4d7-d50c7c9f8303",
- "created_at": "2023-07-29T15:16:43Z",
- "enc": "AQICAHj+McP79InpW8dFM/rPPvaCljIlb0zq8qoMY/a2UlUSewFFXrO432X6dWZfZHFVsgoGAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQM0LAEze794jBZIKO/AgEQgDuVcwyViTDZoLwGj5icgKlABQFeUofitRD9e19i3Q+0ZyT7sSQ/4t2GuxvVo4cVEIkHCgTNH2RXLoqzPA==",
+ "created_at": "2024-08-01T16:22:06Z",
+ "enc": "AQICAHj+McP79InpW8dFM/rPPvaCljIlb0zq8qoMY/a2UlUSewGNNTDHmzVW5Awp7cm2AzUQAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMmElf2gcK2+5OM5nQAgEQgDvMwce1O589MVHM9smF0wZXHMq5WXxHpcv5+1D0ogdB9z0l81+bvMF7iNnl3+bfAFF1m68T0XxjbzkcEA==",
"aws_profile": ""
}
],
@@ -30,10 +97,10 @@
"azure_kv": null,
"hc_vault": null,
"age": null,
- "lastmodified": "2023-09-12T09:29:09Z",
- "mac": "ENC[AES256_GCM,data:q0leMf7J7MBHoQQ6h82eT4xUsIHC6j1DKolRYn/USJsZ4+rt2EEICzD7J8tLUIzv2IqHnTV9hYMt+8Q0qAfOl87Z8VI0TwzXiAx3b2pdAfCheozz6vE1F/94XVz8S6v/YZpVGT9u1lwPISdXYfd/7QqK3u8hZJM/PVVn5djNcj8=,iv:pb1Ii6BfZMgz6S3R+xEehycArHeBz2wzNHJLms9Jby0=,tag:s8sCtTexTs7Qb6magRWzSw==,type:str]",
+ "lastmodified": "2024-08-01T16:22:06Z",
+ "mac": "ENC[AES256_GCM,data:bmtRZOKvD2AQ7NuGIhzQxCempkFafvZNdPp+vpqk6KbYujy34EtmVY3icjAbnf4alY9NLLmKMa2h7uomLvsFSbUEao/6/5cKeC9lgS/jCf0WOEY7QsXZSmyk7J/dmHNGgz4lx7Rx2t7D/bH0EHbGOsuBkR/6pJGcFtsJI9vrIFg=,iv:l6jsCUvZNXVdxe3oDoF34Tj9VLNMMj/w61tNzxcH0dY=,tag:0zD9jq3XPtKLxn6/OFMg3w==,type:str]",
"pgp": null,
"unencrypted_suffix": "_unencrypted",
- "version": "3.7.3"
+ "version": "3.8.1"
}
}
diff --git a/services/terraform/remote/service_webapp.tf b/services/terraform/remote/service_webapp.tf
new file mode 100644
--- /dev/null
+++ b/services/terraform/remote/service_webapp.tf
@@ -0,0 +1,54 @@
+locals {
+ webapp_image_tag = "1.0.102"
+ webapp_service_image = "commapp/keyserver:${local.webapp_image_tag}"
+ webapp_container_name = "webapp"
+
+ webapp_run_server_config = jsonencode({
+ runKeyserver = false
+ runWebApp = true
+ runLanding = false
+ })
+
+ webapp_landing_environment_vars = local.secrets["webappLandingEnvVars"]
+
+ webapp_landing_environment_vars_encoded = {
+ for key, value in local.webapp_landing_environment_vars : key => jsonencode(value)
+ }
+
+ stage_specific_environment_vars = (local.is_staging ?
+ local.secrets["webappLandingStagingEnvVars"] :
+ local.secrets["webappLandingProdEnvVars"])
+
+ stage_specific_environment_vars_encoded = {
+ for key, value in local.stage_specific_environment_vars : key => jsonencode(value)
+ }
+
+ webapp_environment_vars = merge(
+ local.webapp_landing_environment_vars_encoded,
+ local.stage_specific_environment_vars_encoded,
+ {
+ "COMM_LISTEN_ADDR" = "0.0.0.0",
+ "COMM_NODE_ROLE" = "webapp",
+ "COMM_JSONCONFIG_facts_run_server_config" = local.webapp_run_server_config
+ })
+}
+
+module "webapp_service" {
+ source = "../modules/node_service"
+
+ container_name = "webapp"
+ image = local.webapp_service_image
+ service_name = "webapp"
+ cluster_id = aws_ecs_cluster.comm_services.id
+ domain_name = local.is_staging ? "comm.software" : "web.comm.app"
+ vpc_id = aws_vpc.default.id
+ vpc_subnets = [aws_subnet.public_a.id, aws_subnet.public_b.id]
+ region = "us-east-2"
+ environment_vars = local.webapp_environment_vars
+ ecs_task_role_arn = aws_iam_role.keyserver_node_ecs_task_role.arn
+ ecs_task_execution_role_arn = aws_iam_role.ecs_task_execution.arn
+}
+
+output "webapp_service_load_balancer_dns_name" {
+ value = module.webapp_service.service_load_balancer_dns_name
+}

File Metadata

Mime Type
text/plain
Expires
Fri, Sep 20, 10:16 AM (19 h, 57 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2148495
Default Alt Text
D12928.id43027.diff (14 KB)

Event Timeline