@@ -39,7 +39,7 @@ data GCPAuth = GCPAuth { gcpAccessToken :: TVar(Maybe Text)
39
39
instance AuthMethod GCPAuth where
40
40
applyAuthMethod _ gcp req = do
41
41
token <- getToken gcp
42
- >>= either ( throwM . GCPGetTokenException ) pure
42
+ >>= either throwM pure
43
43
pure
44
44
$ setHeader req [(" Authorization" , " Bearer " <> (Text. encodeUtf8 token))]
45
45
& L. set rAuthTypesL []
@@ -50,19 +50,25 @@ gcpAuth AuthInfo{authProvider = Just(AuthProviderConfig "gcp" (Just cfg))} (tls,
50
50
= Just $ do
51
51
configOrErr <- parseGCPAuthInfo cfg
52
52
case configOrErr of
53
- Left e -> throwM $ GCPAuthParsingException e
53
+ Left e -> throwM e
54
54
Right gcp -> pure (tls, addAuthMethod kubecfg gcp)
55
55
gcpAuth _ _ = Nothing
56
56
57
- data GCPAuthParsingException = GCPAuthParsingException String
57
+ data GCPAuthParsingException = GCPAuthMissingInformation String
58
+ | GCPAuthInvalidExpiry String
59
+ | GCPAuthInvalidTokenJSONPath String
60
+ | GCPAuthInvalidExpiryJSONPath String
58
61
deriving Show
59
62
instance Exception GCPAuthParsingException
60
63
61
- data GCPGetTokenException = GCPGetTokenException String
64
+ data GCPGetTokenException = GCPCmdProducedInvalidJSON String
65
+ | GCPTokenNotFound String
66
+ | GCPTokenExpiryNotFound String
67
+ | GCPTokenExpiryInvalid String
62
68
deriving Show
63
69
instance Exception GCPGetTokenException
64
70
65
- getToken :: GCPAuth -> IO (Either String Text )
71
+ getToken :: GCPAuth -> IO (Either GCPGetTokenException Text )
66
72
getToken g@ (GCPAuth {.. }) = getCurrentToken g
67
73
>>= maybe (fetchToken g) (return . Right )
68
74
@@ -77,38 +83,49 @@ getCurrentToken (GCPAuth{..}) = do
77
83
then maybeToken
78
84
else Nothing
79
85
80
- -- TODO: log if parsed expiry is invalid
81
- fetchToken :: GCPAuth -> IO (Either String Text )
86
+ fetchToken :: GCPAuth -> IO (Either GCPGetTokenException Text )
82
87
fetchToken GCPAuth {.. } = do
83
88
(stdOut, _) <- readProcess_ gcpCmd
84
- let credsJSON = Aeson. eitherDecode stdOut
85
- token = runJSONPath gcpTokenKey =<< credsJSON
86
- expText = runJSONPath gcpExpiryKey =<< credsJSON
87
- expiry :: Either String (Maybe UTCTime )
88
- expiry = Just <$> (parseExpiryTime =<< expText)
89
- atomically $ do
90
- writeTVar gcpAccessToken (rightToMaybe token)
91
- writeTVar gcpTokenExpiry (either (const Nothing ) id expiry)
92
- return token
89
+ case parseTokenAndExpiry stdOut of
90
+ Right (token, expiry) -> do
91
+ atomically $ do
92
+ writeTVar gcpAccessToken (Just token)
93
+ writeTVar gcpTokenExpiry (Just expiry)
94
+ return $ Right token
95
+ Left x -> return $ Left x
96
+ where
97
+ parseTokenAndExpiry credsStr = do
98
+ credsJSON <- Aeson. eitherDecode credsStr
99
+ & mapLeft GCPCmdProducedInvalidJSON
100
+ token <- runJSONPath gcpTokenKey credsJSON
101
+ & mapLeft GCPTokenNotFound
102
+ expText <- runJSONPath gcpExpiryKey credsJSON
103
+ & mapLeft GCPTokenExpiryNotFound
104
+ expiry <- parseExpiryTime expText
105
+ & mapLeft GCPTokenExpiryInvalid
106
+ return (token, expiry)
93
107
94
- parseGCPAuthInfo :: Map Text Text -> IO (Either String GCPAuth )
108
+ parseGCPAuthInfo :: Map Text Text -> IO (Either GCPAuthParsingException GCPAuth )
95
109
parseGCPAuthInfo m = do
96
110
gcpAccessToken <- atomically $ newTVar $ Map. lookup " access-token" m
97
- case maybe (pure Nothing ) ((Just <$> ) . parseExpiryTime) $ Map. lookup " expiry" m of
98
- (Left e) -> return $ Left e
99
- Right t -> do
100
- gcpTokenExpiry <- atomically $ newTVar t
101
- return $ do
102
- cmdPath <- Text. unpack <$> lookupEither m " cmd-path"
103
- cmdArgs <- Text. splitOn " " <$> lookupEither m " cmd-args"
104
- gcpTokenKey <- readJSONPath m " token-key" [JSONPath [KeyChild " token_expiry" ]]
105
- gcpExpiryKey <- readJSONPath m " expiry-key" [JSONPath [KeyChild " access_token" ]]
106
- let gcpCmd = proc cmdPath (map Text. unpack cmdArgs)
107
- pure $ GCPAuth {.. }
108
-
109
- lookupEither :: (Show key , Ord key ) => Map key val -> key -> Either String val
110
- lookupEither m k = maybeToRight e $ Map. lookup k m
111
- where e = " Couldn't find key: " <> show k <> " in GCP auth info"
111
+ eitherGCPExpiryToken <- sequence $ fmap (atomically . newTVar) lookupAndParseExpiry
112
+ return $ do
113
+ gcpTokenExpiry <- mapLeft GCPAuthInvalidExpiry eitherGCPExpiryToken
114
+ cmdPath <- Text. unpack <$> lookupEither " cmd-path"
115
+ cmdArgs <- Text. splitOn " " <$> lookupEither " cmd-args"
116
+ gcpTokenKey <- readJSONPath m " token-key" [JSONPath [KeyChild " token_expiry" ]]
117
+ & mapLeft GCPAuthInvalidTokenJSONPath
118
+ gcpExpiryKey <- readJSONPath m " expiry-key" [JSONPath [KeyChild " access_token" ]]
119
+ & mapLeft GCPAuthInvalidExpiryJSONPath
120
+ let gcpCmd = proc cmdPath (map Text. unpack cmdArgs)
121
+ pure $ GCPAuth {.. }
122
+ where
123
+ lookupAndParseExpiry =
124
+ case Map. lookup " expiry" m of
125
+ Nothing -> Right Nothing
126
+ Just expiryText -> Just <$> parseExpiryTime expiryText
127
+ lookupEither key = Map. lookup key m
128
+ & maybeToRight (GCPAuthMissingInformation $ Text. unpack key)
112
129
113
130
parseExpiryTime :: Text -> Either String UTCTime
114
131
parseExpiryTime s = zonedTimeToUTC <$> parseTimeRFC3339 s
0 commit comments