Skip to content
This repository was archived by the owner on Feb 6, 2024. It is now read-only.

Commit 209e715

Browse files
Merge remote-tracking branch 'origin/master'
2 parents f42a4e6 + 6e292a8 commit 209e715

File tree

15 files changed

+594
-173
lines changed

15 files changed

+594
-173
lines changed

infra/default.nix

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@ rec
66
''
77
cp ${pkgs.wai-lambda.wai-lambda-js-wrapper} main.js
88
# Can't be called 'main' otherwise lambda tries to load it
9-
cp "${handlerStatic}/bin/handler" main_hs
10-
cp ${./google-public-keys.json} google-public-keys.json
9+
cp "${handler}/bin/handler" main_hs
1110
mkdir $out
12-
${pkgs.zip}/bin/zip \
13-
-r $out/function.zip \
14-
main.js main_hs google-public-keys.json
11+
${pkgs.zip}/bin/zip -r $out/function.zip main.js main_hs
1512
'';
1613

1714
# TODO: move all other builders to this
@@ -25,7 +22,22 @@ rec
2522
''
2623
cp ${pkgs.wai-lambda.wai-lambda-js-wrapper} main.js
2724
# Can't be called 'main' otherwise lambda tries to load it
28-
cp "${unsplashProxyStatic}/bin/unsplash-proxy" main_hs
25+
cp "${unsplashProxy}/bin/unsplash-proxy" main_hs
26+
mkdir $out
27+
${pkgs.zip}/bin/zip -r $out/function.zip main.js main_hs
28+
'';
29+
30+
function-google-key-updater-path =
31+
{ path = builtins.seq
32+
(builtins.readDir function-google-key-updater) "${function-google-key-updater}/function.zip";
33+
} ;
34+
35+
function-google-key-updater =
36+
pkgs.runCommand "build-lambda" {}
37+
''
38+
cp ${pkgs.wai-lambda.wai-lambda-js-wrapper} main.js
39+
# Can't be called 'main' otherwise lambda tries to load it
40+
cp "${googleKeyUpdater}/bin/google-key-updater" main_hs
2941
mkdir $out
3042
${pkgs.zip}/bin/zip -r $out/function.zip main.js main_hs
3143
'';
@@ -40,7 +52,7 @@ rec
4052
''
4153
cp ${pkgs.wai-lambda.wai-lambda-js-wrapper} main.js
4254
# Can't be called 'main' otherwise lambda tries to load it
43-
cp "${handlerStatic}/bin/presenter" main_hs
55+
cp "${handler}/bin/presenter" main_hs
4456
cp ${deckdeckgo-starter-dist}/dist.tar dist.tar
4557
mkdir -p $out
4658
${pkgs.zip}/bin/zip -r $out/function.zip main.js main_hs dist.tar
@@ -49,7 +61,7 @@ rec
4961
deckdeckgo-starter-dist =
5062
with
5163
{ napalm = import pkgs.sources.napalm { inherit pkgs;} ; };
52-
pkgs.runCommand "deckdeckgo-starter" { buildInputs = [ pkgs.nodejs-10_x ]; }
64+
pkgs.runCommand "deckdeckgo-starter" { buildInputs = [ pkgs.nodejs ]; }
5365
''
5466
cp -r ${napalm.buildPackage pkgs.sources.deckdeckgo-starter {}}/* .
5567
chmod +w -R _napalm-install
@@ -67,7 +79,9 @@ rec
6779
{ pkg = pkgs.haskellPackages.developPackage { root = ./handler; } ; };
6880
pkg.overrideAttrs(attr: {
6981
buildInputs = with pkgs;
70-
[ niv terraform awscli postgresql moreutils minio ];
82+
[ terraform awscli postgresql moreutils minio ];
83+
LANG = "en_US.UTF-8";
84+
LOCALE_ARCHIVE = "${pkgs.glibcLocales}/lib/locale/locale-archive";
7185
shellHook =
7286
let
7387
pgutil = pkgs.callPackage ./pgutil.nix {};
@@ -156,19 +170,23 @@ rec
156170
ghci -Wall unsplash-proxy/Main.hs
157171
}
158172
173+
function repl_google_key_updater() {
174+
ghci -Wall google-key-updater/Main.hs
175+
}
176+
159177
function repl() {
160178
repl_handler
161179
}
162180
163181
'';
164182
});
165183

166-
handlerStatic = pkgs.haskellPackagesStatic.deckdeckgo-handler;
167184
handler = pkgs.haskellPackages.deckdeckgo-handler;
168185

169-
unsplashProxyStatic = pkgs.haskellPackagesStatic.unsplash-proxy;
170186
unsplashProxy = pkgs.haskellPackages.unsplash-proxy;
171187

188+
googleKeyUpdater = pkgs.haskellPackages.google-key-updater;
189+
172190
dynamoJar = pkgs.runCommand "dynamodb-jar" { buildInputs = [ pkgs.gnutar ]; }
173191
''
174192
mkdir -p $out
@@ -243,9 +261,7 @@ rec
243261
${pgutil.start_pg}
244262
245263
echo "Running tests"
246-
NIX_REDIRECTS=/etc/protocols=${pkgs.iana-etc}/etc/protocols \
247-
LD_PRELOAD="${pkgs.libredirect}/lib/libredirect.so" \
248-
GOOGLE_PUBLIC_KEYS="${pkgs.writeText "google-x509" (builtins.toJSON googleResp)}" \
264+
GOOGLE_PUBLIC_KEYS="${pkgs.writeText "google-x509" (builtins.toJSON googleResp)}" \
249265
FIREBASE_PROJECT_ID="my-project-id" \
250266
FIREBASE_PROJECT_ID="my-project-id" \
251267
AWS_DEFAULT_REGION=us-east-1 \

infra/google-key-updater/Main.hs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
{-# LANGUAGE TypeOperators #-}
2+
{-# LANGUAGE OverloadedStrings #-}
3+
{-# LANGUAGE LambdaCase #-}
4+
{-# LANGUAGE DerivingStrategies #-}
5+
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
6+
{-# LANGUAGE DataKinds #-}
7+
8+
9+
module Main (main) where
10+
11+
import qualified Network.AWS.Data.Body as Body
12+
import Control.Monad
13+
import Data.Aeson ((.:))
14+
import System.Environment (getEnv)
15+
import UnliftIO
16+
import qualified Data.Aeson as Aeson
17+
import qualified Data.Aeson.Internal as Aeson
18+
import qualified Data.Aeson.Parser as Aeson
19+
import qualified Data.Aeson.Parser.Internal as Aeson
20+
import qualified Data.Aeson.Types as Aeson
21+
import qualified Data.ByteString as BS
22+
import qualified Data.ByteString.Char8 as BS8
23+
import qualified Data.ByteString.Lazy as BL
24+
import qualified Data.Text as T
25+
import qualified Network.AWS as Aws
26+
import qualified Network.AWS.S3 as S3
27+
import qualified Network.HTTP.Simple as HTTP
28+
import qualified Network.Wai.Handler.Lambda as Lambda
29+
30+
main :: IO ()
31+
main = do
32+
hSetBuffering stdin LineBuffering
33+
hSetBuffering stdout LineBuffering
34+
35+
liftIO $ putStrLn "Booting..."
36+
env <- Aws.newEnv Aws.Discover
37+
38+
bucketName <- getEnv "META_BUCKET_NAME"
39+
let bucket = S3.BucketName (T.pack bucketName)
40+
putStrLn $ "Bucket is: " <> show bucket
41+
42+
liftIO $ putStrLn "Booted!"
43+
44+
45+
putStrLn "entering loop..."
46+
forever $ do
47+
line <- BS8.getLine
48+
putStrLn $ "Got line!: " <> show line
49+
case decodeInput (pure . const ()) line of
50+
Right (fp, ()) -> do
51+
putStrLn $ "Got input!"
52+
keys <- HTTP.getResponseBody <$>
53+
HTTP.httpBS ( HTTP.parseRequest_
54+
"https://www.googleapis.com/robot/v1/metadata/x509/[email protected]"
55+
)
56+
57+
print keys
58+
59+
let body = Body.toBody keys
60+
let okey = "google-public-keys"
61+
62+
runAWS env (
63+
Aws.send $ S3.putObject bucket okey body
64+
) >>= \case
65+
Right {} -> do
66+
putStrLn $ "uploaded new keys"
67+
Left e -> error $ "Error in put: " <> show e
68+
69+
Lambda.writeFileAtomic fp (BL.toStrict $ Aeson.encode ())
70+
Left e -> error $ show e
71+
72+
decodeInput
73+
:: (Aeson.Value -> Aeson.Parser a)
74+
-> BS.ByteString
75+
-> Either (Aeson.JSONPath, String) (FilePath, a)
76+
decodeInput parseEvent =
77+
Aeson.eitherDecodeStrictWith Aeson.jsonEOF $ Aeson.iparse $
78+
Aeson.withObject "input" $ \obj ->
79+
(,) <$>
80+
obj .: "responseFile" <*>
81+
(obj .: "request" >>= parseEvent)
82+
-- main = putStrLn "hello!"
83+
-- main =
84+
-- runAWS env (
85+
-- Aws.send $ S3.putObject bucket okey body
86+
-- ) >>= \case
87+
-- Right {} -> do
88+
-- putStrLn $ "uploaded new keys"
89+
-- Left e -> error $ "Error in put: " <> show e
90+
-- where
91+
-- okey = undefined
92+
-- bucket = undefined
93+
-- body = undefined
94+
-- env = undefined
95+
96+
97+
runAWS :: MonadIO m => Aws.Env -> Aws.AWS a -> m (Either SomeException a)
98+
runAWS env =
99+
liftIO .
100+
tryAny .
101+
Aws.runResourceT .
102+
Aws.runAWS env .
103+
Aws.within Aws.NorthVirginia
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: google-key-updater
2+
license: AGPL-3
3+
4+
executable:
5+
main: Main.hs
6+
7+
dependencies:
8+
- aeson
9+
- base
10+
- bytestring
11+
- http-client
12+
- http-client-tls
13+
- http-conduit
14+
- http-types
15+
- servant
16+
- servant-client
17+
- servant-server
18+
- text
19+
- wai
20+
- wai-cors
21+
- unliftio
22+
- wai-lambda
23+
- warp
24+
- amazonka
25+
- amazonka-core
26+
- amazonka-s3

infra/google-public-keys.json

Lines changed: 0 additions & 4 deletions
This file was deleted.

infra/google_key_updater.tf

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
variable "meta-bucket-name" {
2+
type = "string"
3+
default = "deckdeckgo-beta-meta"
4+
}
5+
6+
resource "aws_s3_bucket" "meta" {
7+
bucket = "${var.meta-bucket-name}"
8+
}
9+
10+
11+
resource "aws_lambda_function" "google_key_updater" {
12+
function_name = "deckdeckgo-google-key-updater-lambda"
13+
filename = "${data.external.build-function-google-key-updater.result.path}"
14+
15+
# TODO: need a big *ss timeout on this one
16+
timeout = 5
17+
handler = "main.handler"
18+
runtime = "nodejs8.10"
19+
20+
role = "${aws_iam_role.iam_for_lambda_google_key_updater.arn}"
21+
22+
environment {
23+
variables = {
24+
META_BUCKET_NAME = "${aws_s3_bucket.meta.bucket}"
25+
}
26+
}
27+
}
28+
29+
data "external" "build-function-google-key-updater" {
30+
program = [
31+
"nix", "eval",
32+
"(import ./default.nix).function-google-key-updater-path", "--json"
33+
]
34+
}
35+
36+
resource "aws_iam_role" "iam_for_lambda_google_key_updater" {
37+
name = "deckdeckgo-google-key-updater-lambda-iam"
38+
39+
assume_role_policy = <<EOF
40+
{
41+
"Version": "2012-10-17",
42+
"Statement": [
43+
{
44+
"Action": "sts:AssumeRole",
45+
"Principal": {
46+
"Service": "lambda.amazonaws.com"
47+
},
48+
"Effect": "Allow",
49+
"Sid": ""
50+
}
51+
]
52+
}
53+
EOF
54+
55+
}
56+
57+
#resource "aws_lambda_event_source_mapping" "google_key_updater" {
58+
#event_source_arn = "${aws_sqs_queue.presentation_deploy.arn}"
59+
#enabled = true
60+
#function_name = "${aws_lambda_function.presenter.function_name}"
61+
#batch_size = 1
62+
#}
63+
64+
65+
# TODO: needed as well, but later on, when we actually hit PG
66+
#resource "aws_iam_role_policy_attachment" "role_attach_lambdavpc" {
67+
#role = "${aws_iam_role.iam_for_lambda.name}"
68+
#policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
69+
#}
70+
71+
# XXX: looks like Lambda needs to be redeploy for the policy to take effect
72+
# TODO: auto redeploy on policy change
73+
data "aws_iam_policy_document" "policy_for_lambda_google_key_updater" {
74+
75+
# Give access to CloudWatch
76+
statement {
77+
actions = [
78+
"logs:CreateLogStream",
79+
"logs:PutLogEvents",
80+
]
81+
82+
resources = ["${aws_cloudwatch_log_group.google-key-updater.arn}"]
83+
}
84+
85+
# Give access to CloudWatch
86+
statement {
87+
actions = [
88+
"ec2:DescribeInstances",
89+
"ec2:CreateNetworkInterface",
90+
"ec2:AttachNetworkInterface",
91+
"ec2:DescribeNetworkInterfaces",
92+
"ec2:DeleteNetworkInterface"
93+
]
94+
95+
resources = [ "*" ]
96+
}
97+
98+
# TODO
99+
#statement {
100+
#actions = [
101+
#"s3:ListBucket",
102+
#]
103+
104+
#resources = [ "${aws_s3_bucket.presentations.arn}" ]
105+
#}
106+
107+
statement {
108+
actions = [
109+
"s3:PutObject",
110+
"s3:DeleteObject",
111+
]
112+
113+
resources = [ "${aws_s3_bucket.meta.arn}/*" ]
114+
}
115+
116+
}
117+
118+
resource "aws_iam_role_policy" "policy_for_lambda_google_key_updater" {
119+
name = "deckdeckgo-google-key-updater-lambda-policy"
120+
role = "${aws_iam_role.iam_for_lambda_google_key_updater.id}"
121+
policy = "${data.aws_iam_policy_document.policy_for_lambda_google_key_updater.json}"
122+
}
123+
124+
resource "aws_cloudwatch_log_group" "google-key-updater" {
125+
name = "/aws/lambda/${aws_lambda_function.google_key_updater.function_name}"
126+
retention_in_days = "7"
127+
}
128+
129+
resource "aws_cloudwatch_event_rule" "every_five_minutes" {
130+
name = "every-five-minutes"
131+
description = "Fires every five minutes"
132+
schedule_expression = "rate(5 minutes)"
133+
}
134+
135+
resource "aws_cloudwatch_event_target" "update_google_keys_every_five_minutes" {
136+
rule = "${aws_cloudwatch_event_rule.every_five_minutes.name}"
137+
target_id = "google_key_updater"
138+
arn = "${aws_lambda_function.google_key_updater.arn}"
139+
}
140+
141+
resource "aws_lambda_permission" "allow_cloudwatch_to_call_google_key_updater" {
142+
statement_id = "AllowExecutionFromCloudWatch"
143+
action = "lambda:InvokeFunction"
144+
function_name = "${aws_lambda_function.google_key_updater.function_name}"
145+
principal = "events.amazonaws.com"
146+
source_arn = "${aws_cloudwatch_event_rule.every_five_minutes.arn}"
147+
}

0 commit comments

Comments
 (0)