@@ -12,7 +12,8 @@
1212-- information about your instance or project.
1313--
1414-- This module contains functions for retrieving various Compute metadata from an
15−-- instance's local metadata endpoint using 'MonadIO' and not the Google monad.
15+-- instance\'s local metadata endpoint using 'MonadIO', prior to initialisation
16+-- of the environment used by the "Network.Google" monad.
1617module Network.Google.Compute.Metadata
1718 (
1819 -- * Google Compute Instance Check
@@ -35,8 +36,8 @@ module Network.Google.Compute.Metadata
3536 -- * Raw Metadata Requests
3637 , metadataFlavorHeader
3738 , metadataFlavorDesired
38− , metadata
3939 , metadataRequest
40+ , getMetadata
4041 ) where
4142
4243import Control.Monad.Catch
@@ -55,7 +56,7 @@ import qualified Network.HTTP.Conduit as Client
5556import Network.HTTP.Types (HeaderName)
5657import System.Environment (lookupEnv)
5758
58−-- | @NO_GCE_CHECK@.
59+-- | The @NO_GCE_CHECK@ environment variable.
5960checkGCEVar :: String
6061checkGCEVar = "NO_GCE_CHECK"
6162
@@ -96,14 +97,14 @@ isGCE m = liftIO $ do
9697-- | A directory of custom metadata values that have been set for this project.
9798getProjectAttribute :: MonadIO m => Text -> Manager -> m (Maybe LBS.ByteString)
9899getProjectAttribute k =
99− metadataMaybe ("project/attributes/" <> Text.encodeUtf8 k)
100+ getMetadataMaybe ("project/attributes/" <> Text.encodeUtf8 k)
100101
101102-- | SSH keys that can connect to instances in the project. SSH keys for Compute
102103-- Engine use a specialized format where the keys are prepended with a username,
103104-- like so: @user1:ssh-rsa my-public-ssh-key user1@host.com@
104105getSSHKeys :: MonadIO m => Manager -> m [Text]
105106getSSHKeys m = do
106− mx <- metadataMaybe "project/attributes/sshKeys" m
107+ mx <- getMetadataMaybe "project/attributes/sshKeys" m
107108 case mx of
108109 Nothing -> pure []
109110 Just x -> pure
@@ -116,48 +117,48 @@ getSSHKeys m = do
116117-- the project-id metadata entry value. The project-id value is required for all
117118-- requests to the Compute Engine service.
118119getNumericProjectId :: MonadIO m => Manager -> m Text
119−getNumericProjectId = metadataText "project/numeric-project-id"
120+getNumericProjectId = getMetadataText "project/numeric-project-id"
120121
121122-- | The project ID.
122123getProjectId :: MonadIO m => Manager -> m Text
123−getProjectId = metadataText "project/project-id"
124+getProjectId = getMetadataText "project/project-id"
124125
125126-- | A directory of custom metadata values passed to the instance during startup
126127-- or shutdown.
127128getInstanceAttribute :: MonadIO m => Text -> Manager -> m (Maybe LBS.ByteString)
128129getInstanceAttribute k =
129− metadataMaybe ("instance/attributes/" <> Text.encodeUtf8 k)
130+ getMetadataMaybe ("instance/attributes/" <> Text.encodeUtf8 k)
130131
131132-- | The free-text description of an instance, assigned using the
132133-- @--description@ flag, or set in the API.
133134getDescription :: MonadIO m => Manager -> m Text
134−getDescription = metadataText "instance/description"
135+getDescription = getMetadataText "instance/description"
135136
136137-- | The host name of the instance.
137138getHostname :: MonadIO m => Manager -> m Text
138−getHostname = metadataText "instance/hostname"
139+getHostname = getMetadataText "instance/hostname"
139140
140141-- | The ID of the instance. This is a unique, numerical ID that is generated by
141142-- Google Compute Engine. This is useful for identifying instances if you do not
142143-- want to use instance names.
143144getInstanceId :: MonadIO m => Manager -> m Text
144−getInstanceId = metadataText "instance/id"
145+getInstanceId = getMetadataText "instance/id"
145146
146147-- | The fully-qualified machine type name of the instance's host machine.
147148getMachineType :: MonadIO m => Manager -> m Text
148−getMachineType = metadataText "instance/machine-type"
149+getMachineType = getMetadataText "instance/machine-type"
149150
150151-- | Any tags associated with the instance.
151152getTags :: MonadIO m => Manager -> m [Text]
152153getTags m = do
153− rs <- metadata "instance/tags" [] m
154+ rs <- getMetadata "instance/tags" [] m
154155 case eitherDecode' (Client.responseBody rs) of
155156 Left _ -> pure []
156157 Right xs -> pure xs
157158
158159-- | The instance's zone.
159160getZone :: MonadIO m => Manager -> m Text
160−getZone = metadataText "instance/zone"
161+getZone = getMetadataText "instance/zone"
161162
162163-- -- | A directory of disks attached to this instance.
163164-- getDisk ::
@@ -200,29 +201,29 @@ getZone = metadataText "instance/zone"
200201-- Metadata wait for change
201202-- curl "http://metadata.google.internal/computeMetadata/v1/instance/tags?wait_for_change=true"
202203
203−metadataMaybe :: MonadIO m
204+getMetadataMaybe :: MonadIO m
204205 => ByteString
205206 -> Manager
206207 -> m (Maybe LBS.ByteString)
207−metadataMaybe path m = do
208− rs <- metadata path [404] m
208+getMetadataMaybe path m = do
209+ rs <- getMetadata path [404] m
209210 if fromEnum (Client.responseStatus rs) == 404
210211 then pure Nothing
211212 else pure $ Just (Client.responseBody rs)
212213
213−metadataText :: MonadIO m
214+getMetadataText :: MonadIO m
214215 => ByteString
215216 -> Manager
216217 -> m Text
217−metadataText path m = LText.toStrict . LText.decodeUtf8 . Client.responseBody
218− <$> metadata path [] m
219−
220−metadata :: MonadIO m
221− => ByteString
222− -> [Int]
223− -> Manager
224− -> m (Client.Response LBS.ByteString)
225−metadata path ss m =
218+getMetadataText path m = LText.toStrict . LText.decodeUtf8 . Client.responseBody
219+ <$> getMetadata path [] m
220+
221+getMetadata :: MonadIO m
222+ => ByteString -- ^ The request path.
223+ -> [Int] -- ^ Acceptable status code responses.
224+ -> Manager
225+ -> m (Client.Response LBS.ByteString)
226+getMetadata path ss m =
226227 liftIO . flip Client.httpLbs m $ metadataRequest
227228 { Client.path = "/computeMetadata/v1/" <> path
228229 , Client.checkStatus = \s hs cj ->
@@ -232,6 +233,8 @@ metadata path ss m =
232233 else Just . toException $ StatusCodeException s hs cj
233234 }
234235
236+-- | A default @http-client@ 'Client.Request' with the host, port, and headers
237+-- set appropriately for @metadata.google.internal@ use.
235238metadataRequest :: Client.Request
236239metadataRequest = def
237240 { Client.host = "metadata.google.internal"