Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/5-internal/sts-expiry-metrics
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add AWS security token metrics to brig
19 changes: 19 additions & 0 deletions services/brig/src/Brig/AWS.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ module Brig.AWS
-- * AWS
exec,
execCatch,
readAuthExpiration,
isAuthARef,
)
where

Expand All @@ -62,6 +64,7 @@ import Data.ByteString.Builder (toLazyByteString)
import qualified Data.ByteString.Lazy as BL
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import Data.Time
import Data.UUID hiding (null)
import Imports hiding (group)
import Network.HTTP.Client (HttpException (..), HttpExceptionContent (..), Manager)
Expand Down Expand Up @@ -270,3 +273,19 @@ canRetry (Left e) = case e of

retry5x :: (Monad m) => RetryPolicyM m
retry5x = limitRetries 5 <> exponentialBackoff 100000

readAuthExpiration :: AWS.Env -> IO (Maybe NominalDiffTime)
readAuthExpiration env = do
authEnv <-
case runIdentity (AWS.envAuth env) of
AWS.Auth authEnv -> pure authEnv
AWS.Ref _ ref -> do
readIORef ref
now <- getCurrentTime
pure $ ((`diffUTCTime` now) . AWS.fromTime) <$> (AWS._authExpiration authEnv)

isAuthARef :: AWS.Env -> Bool
isAuthARef env =
case runIdentity (AWS.envAuth env) of
AWS.Auth _ -> False
AWS.Ref _ _ -> True
20 changes: 19 additions & 1 deletion services/brig/src/Brig/Run.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import Brig.API.Handler
import qualified Brig.API.Internal as IAPI
import Brig.API.Public (SwaggerDocsAPI, servantSitemap, swaggerDocsAPI)
import qualified Brig.API.User as API
import Brig.AWS (sesQueue)
import Brig.AWS (amazonkaEnv, sesQueue)
import qualified Brig.AWS as AWS
import qualified Brig.AWS.SesNotification as SesNotification
import Brig.App
Expand All @@ -49,10 +49,12 @@ import Control.Monad.Random (randomRIO)
import qualified Data.Aeson as Aeson
import Data.Default (Default (def))
import Data.Id (RequestId (..))
import Data.Metrics (gaugeSet, path)
import qualified Data.Metrics.Servant as Metrics
import Data.Proxy (Proxy (Proxy))
import Data.String.Conversions (cs)
import Data.Text (unpack)
import Data.Time (NominalDiffTime)
import Imports hiding (head)
import qualified Network.HTTP.Media as HTTPMedia
import qualified Network.HTTP.Types as HTTP
Expand Down Expand Up @@ -94,6 +96,7 @@ run o = do
AWS.listen throttleMillis q (runAppT e . SesNotification.onEvent)
sftDiscovery <- forM (e ^. sftEnv) $ Async.async . Calling.startSFTServiceDiscovery (e ^. applog)
turnDiscovery <- Calling.startTurnDiscovery (e ^. applog) (e ^. fsWatcher) (e ^. turnEnv)
authMetrics <- Async.async (runAppT e collectAuthMetrics)
pendingActivationCleanupAsync <- Async.async (runAppT e pendingActivationCleanup)

runSettingsWithShutdown s app 5 `finally` do
Expand All @@ -102,6 +105,7 @@ run o = do
mapM_ Async.cancel sftDiscovery
Async.cancel pendingActivationCleanupAsync
mapM_ Async.cancel turnDiscovery
Async.cancel authMetrics
closeEnv e
where
endpoint = brig o
Expand Down Expand Up @@ -230,3 +234,17 @@ pendingActivationCleanup = do

hours :: Double -> Timeout
hours n = realToFrac (n * 60 * 60)

collectAuthMetrics :: forall r. AppT r ()
collectAuthMetrics = do
m <- view metrics
env <- view (awsEnv . amazonkaEnv)

forever $ do
t <- toSeconds . fromMaybe 0 <$$> liftIO $ AWS.readAuthExpiration env
gaugeSet t (path "aws_auth.token_secs_remaining") m
gaugeSet (if AWS.isAuthARef env then 1.0 else 0.0) (path "aws_auth.token_is_reference") m
liftIO $ threadDelay 1_000_000
where
toSeconds :: NominalDiffTime -> Double
toSeconds = fromRational . toRational