module Main (main) where import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteString.Lazy as BL import Crypto.Hash (Digest, SHA256, hash) import qualified Data.ByteArray as BA import qualified Data.ByteString.Base16 as B16 import qualified Data.Text as Text import qualified Data.Text.Encoding as TextEncoding import Database.PostgreSQL.Simple (Only (..)) import Nuthatch.Config (loadConfig) import qualified Nuthatch.Db as Db import Nuthatch.Probe.Assert import Nuthatch.Probe.Curl import Nuthatch.Redis import Nuthatch.S3 import Nuthatch.Types import System.Environment (setEnv) main :: IO () main = do profile <- requireEnv "NUTHATCH_FIXTURE_PROFILE" lane <- requireEnv "NUTHATCH_FIXTURE_LANE" pgConnection <- requireEnv "NUTHATCH_PG_CONN" setEnv "NUTHATCH_JWT_SECRET" "synthetic-fixture-session-secret" setEnv "NUTHATCH_PUBLIC_BASE_URL" ("https://nuthatch-" <> lane <> ":8080") setEnv "NUTHATCH_OIDC_CLIENT_SECRET" "synthetic-fixture-client-secret" config <- loadConfig verifyProfileFile profile lane pgConnection Db.withDb config $ \database -> do _ <- Db.execute_ database "CREATE TEMP TABLE lane_canary (value text NOT NULL)" _ <- Db.execute database "INSERT INTO lane_canary VALUES (?)" (Only (Text.pack profile)) pure () withRedis config $ \redis -> do cacheSet redis "lane-canary" 60 (B8.pack profile) cacheGet redis "lane-canary" >>= assertEqual "coordination lane canary" (Just (B8.pack profile)) issuer <- requireEnv "NUTHATCH_OIDC_ISSUER" discovery <- curl [issuer <> "/.well-known/openid-configuration"] assertEqual "OIDC discovery status" 200 (curlStatus discovery) assertContains "OIDC discovery issuer" "\"issuer\"" (curlBody discovery) store <- newS3 config let key = ObjectKey "lane-canary" body = BL.fromStrict (B8.pack profile) digest = ContentSha256 (TextEncoding.decodeUtf8 (sha256Hex (BL.toStrict body))) putObject store key (toInteger (BL.length body)) (Just digest) body >>= assertEqual "target lane canary put" (Right ()) getObjectBytes store key >>= assertEqual "target lane canary get" (Right body) putStrLn "Fixture lane passed" verifyProfileFile :: String -> String -> String -> IO () verifyProfileFile profile lane pgConnection = do contents <- lines <$> readFile "/run/nuthatch-fixture/profile.env" mapM_ (\name -> do value <- requireEnv name assert (name <> " missing from mounted lane profile") $ name <> "=" <> value `elem` contents) [ "NUTHATCH_FIXTURE_PROFILE" , "NUTHATCH_COORDINATION_PROVIDER" , "NUTHATCH_OIDC_PROVIDER" , "NUTHATCH_TARGET_PROVIDER" ] bucket <- requireEnv "NUTHATCH_S3_BUCKET" assertEqual "lane bucket" ("nuthatch-lane-" <> lane) bucket assertContains "lane database" (B8.pack ("dbname=nuthatch_lane_" <> lane)) (B8.pack pgConnection) assertEqual "mounted profile name" profile =<< requireEnv "NUTHATCH_FIXTURE_PROFILE" sha256Hex :: B8.ByteString -> B8.ByteString sha256Hex input = B16.encode (BA.convert (hash input :: Digest SHA256))