Skip to content

Commit e8b26be

Browse files
committed
Respect service-specific endpoint env variables
1 parent 7a34e4e commit e8b26be

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

lib/amazonka/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
### Changed
66

7+
- `amazonka`: Add support for `AWS_ENDPOINT_URL*` environment variables to override service-specific endpoints.
78
- The hooks interface is now much harder to misuse. [\#1042](https://github.com/brendanhay/amazonka/pull/1042)
89

910
It was previously extremely easy to write hook-using functions that typechecked but did not ever run. The main change is to provide specialised hook-changing functions named for each field in the `Hooks` record, so that it is much easier to get the types correct.

lib/amazonka/src/Amazonka/Env.hs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,15 @@ module Amazonka.Env
4343
where
4444

4545
import Amazonka.Core.Lens.Internal (Lens)
46+
import Amazonka.Data.Text (toText)
4647
import Amazonka.Env.Hooks (Hooks, addLoggingHooks, noHooks)
4748
import Amazonka.Logger (Logger)
4849
import Amazonka.Prelude
4950
import Amazonka.Types hiding (timeout)
51+
import qualified Amazonka.Endpoint as Endpoint
5052
import qualified Amazonka.Types as Service (Service (..))
5153
import qualified Data.Function as Function
54+
import qualified Data.List as List
5255
import qualified Data.Text as Text
5356
import qualified Network.HTTP.Client as Client
5457
import qualified Network.HTTP.Conduit as Client.Conduit
@@ -160,17 +163,62 @@ newEnvNoAuth =
160163
newEnvNoAuthFromManager :: (MonadIO m) => Client.Manager -> m EnvNoAuth
161164
newEnvNoAuthFromManager manager = do
162165
mRegion <- lookupRegion
166+
endpointOverrides <- customEndpoints
163167
pure
164168
Env
165169
{ region = fromMaybe NorthVirginia mRegion,
166170
logger = \_ _ -> pure (),
167171
hooks = addLoggingHooks noHooks,
168172
retryCheck = retryConnectionFailure 3,
169-
overrides = id,
173+
overrides = endpointOverrides,
170174
manager,
171175
auth = Proxy
172176
}
173177

178+
-- | Retrieve custom endpoints from environment variables:
179+
--
180+
-- * @AWS_ENDPOINT_URL@
181+
-- * @AWS_ENDPOINT_URL_<SERVICE>@
182+
--
183+
-- The latter takes precedence over the former.
184+
--
185+
-- If @AWS_IGNORE_CONFIGURED_ENDPOINT_URLS@ is set, all other custom endpoint
186+
-- settings are ignored.
187+
--
188+
-- See
189+
-- <https://docs.aws.amazon.com/sdkref/latest/guide/feature-ss-endpoints.html>
190+
customEndpoints :: (MonadIO m) => m (Service -> Service)
191+
customEndpoints = do
192+
environment <- liftIO Environment.getEnvironment
193+
pure $ case lookup "AWS_IGNORE_CONFIGURED_ENDPOINT_URLS" environment of
194+
Just _ -> id
195+
_ -> go environment
196+
where
197+
go environment =
198+
let globalUrl = lookup "AWS_ENDPOINT_URL" environment >>= Client.parseRequest
199+
serviceUrls = environment
200+
& mapMaybe getEndpoint
201+
& map (first (Text.toLower . Text.pack))
202+
override s =
203+
case lookup (Text.toLower . toText $ Service.abbrev s) serviceUrls of
204+
Just x -> setEndpointMaybe (Client.parseRequest x) s
205+
Nothing -> setEndpointMaybe globalUrl s
206+
in override
207+
208+
getEndpoint (k, v) = (,v) <$> removePrefix "AWS_ENDPOINT_URL_" k
209+
210+
removePrefix :: String -> String -> Maybe String
211+
removePrefix prefix s =
212+
if prefix `List.isPrefixOf` s
213+
then Just $ drop (length prefix) s
214+
else Nothing
215+
216+
setEndpointMaybe :: Maybe Client.Request -> Service -> Service
217+
setEndpointMaybe mreq s =
218+
case mreq of
219+
Just req -> Endpoint.setEndpoint (Client.secure req) (Client.host req) (Client.port req) s
220+
Nothing -> s
221+
174222
-- | Get "the" 'Auth' from an 'Env'', if we can.
175223
authMaybe :: (Foldable withAuth) => Env' withAuth -> Maybe Auth
176224
authMaybe = foldr (const . Just) Nothing . auth

0 commit comments

Comments
 (0)