vault-tool 0.1.0.0 → 0.1.0.1
raw patch · 3 files changed
+68/−25 lines, 3 filesdep ~basePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: base
API changes (from Hackage documentation)
- Network.VaultTool: [unVaultSecretPath] :: VaultSecretPath -> Text
- Network.VaultTool: instance (GHC.Classes.Eq b, GHC.Classes.Eq a) => GHC.Classes.Eq (Network.VaultTool.VaultMount a b)
- Network.VaultTool: instance (GHC.Classes.Ord b, GHC.Classes.Ord a) => GHC.Classes.Ord (Network.VaultTool.VaultMount a b)
- Network.VaultTool: instance (GHC.Show.Show b, GHC.Show.Show a) => GHC.Show.Show (Network.VaultTool.VaultMount a b)
+ Network.VaultTool: VaultMountedPath :: Text -> VaultMountedPath
+ Network.VaultTool: VaultSearchPath :: Text -> VaultSearchPath
+ Network.VaultTool: [unVaultMountedPath] :: VaultMountedPath -> Text
+ Network.VaultTool: [unVaultSearchPath] :: VaultSearchPath -> Text
+ Network.VaultTool: instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Network.VaultTool.VaultMount a b)
+ Network.VaultTool: instance (GHC.Classes.Ord a, GHC.Classes.Ord b) => GHC.Classes.Ord (Network.VaultTool.VaultMount a b)
+ Network.VaultTool: instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Network.VaultTool.VaultMount a b)
+ Network.VaultTool: newtype VaultMountedPath
+ Network.VaultTool: newtype VaultSearchPath
- Network.VaultTool: VaultSecretPath :: Text -> VaultSecretPath
+ Network.VaultTool: VaultSecretPath :: (VaultMountedPath, VaultSearchPath) -> VaultSecretPath
Files
- src/Network/VaultTool.hs +59/−22
- src/Network/VaultTool/Types.hs +7/−1
- vault-tool.cabal +2/−2
src/Network/VaultTool.hs view
@@ -51,6 +51,8 @@ , vaultNewMount , vaultUnmount + , VaultMountedPath(..)+ , VaultSearchPath(..) , VaultSecretPath(..) , VaultSecretMetadata(..) , vaultWrite@@ -79,6 +81,32 @@ import Network.VaultTool.Internal import Network.VaultTool.Types +data VaultAction+ = Create+ | ReadVersion+ | ReadMetadata+ | Update+ | UpdateMetadata+ | ListSecrets+ | DeleteLast+ | DeleteVersions+ | Undelete+ | Destroy+ | DeleteMetadata++vaultUrlPrefix :: VaultAction -> String+vaultUrlPrefix Create = "/data"+vaultUrlPrefix ReadVersion = "/data"+vaultUrlPrefix Update = "/data"+vaultUrlPrefix DeleteLast = "/data"+vaultUrlPrefix DeleteVersions = "/delete"+vaultUrlPrefix Undelete = "/undelete"+vaultUrlPrefix Destroy = "/destroy"+vaultUrlPrefix ListSecrets = "/metadata"+vaultUrlPrefix ReadMetadata = "/metadata"+vaultUrlPrefix UpdateMetadata = "/metadata"+vaultUrlPrefix DeleteMetadata = "/metadata"+ data VaultConnection = VaultConnection { _VaultConnection_AuthToken :: VaultAuthToken , _VaultConnection_VaultAddress :: VaultAddress@@ -110,6 +138,10 @@ vaultUrl :: VaultAddress -> String -> String vaultUrl (VaultAddress addr) path = T.unpack addr ++ "/v1" ++ path +vaultActionUrl :: VaultAction -> VaultAddress -> VaultMountedPath -> VaultSearchPath -> String+vaultActionUrl action (VaultAddress addr) (VaultMountedPath mountedPath) (VaultSearchPath searchPath) =+ T.unpack addr ++ "/v1/" ++ T.unpack mountedPath ++ (vaultUrlPrefix action) ++ "/" ++ T.unpack searchPath+ -- | https://www.vaultproject.io/docs/http/sys-health.html vaultHealth :: VaultAddress -> IO VaultHealth vaultHealth vaultAddress = do@@ -262,7 +294,7 @@ -- | <https://www.vaultproject.io/docs/auth/approle.html#via-the-api-1> vaultAuthEnable :: VaultConnection -> Text -> IO () vaultAuthEnable VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} authMethod = do- _ <- vaultRequest _VaultConnection_Manager "POST" (vaultUrl _VaultConnection_VaultAddress "/sys/auth/" ++ T.unpack authMethod) headers (Just reqBody) [204]+ _ <- vaultRequest _VaultConnection_Manager "POST" (vaultUrl _VaultConnection_VaultAddress "/sys/auth/" ++ T.unpack authMethod) headers (Just reqBody) [200] pure () where reqBody = object [ "type" .= authMethod ]@@ -271,7 +303,7 @@ -- | <https://www.vaultproject.io/api/system/policies.html#create-update-acl-policy> vaultPolicyCreate :: VaultConnection -> Text -> Text -> IO () vaultPolicyCreate VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} policyName policy = do- _ <- vaultRequest _VaultConnection_Manager "PUT" (vaultUrl _VaultConnection_VaultAddress "/sys/policies/acl/" ++ T.unpack policyName) headers (Just reqBody) [204]+ _ <- vaultRequest _VaultConnection_Manager "PUT" (vaultUrl _VaultConnection_VaultAddress "/sys/policies/acl/" ++ T.unpack policyName) headers (Just reqBody) [200] pure () where reqBody = object [ "policy" .= policy ]@@ -335,7 +367,7 @@ -- | <https://www.vaultproject.io/api/auth/approle/index.html#create-new-approle> vaultAppRoleCreate :: VaultConnection -> Text -> VaultAppRoleParameters -> IO () vaultAppRoleCreate VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} appRoleName varp = do- _ <- vaultRequest _VaultConnection_Manager "POST" (vaultUrl _VaultConnection_VaultAddress "/auth/approle/role/" ++ T.unpack appRoleName) headers (Just varp) [204]+ _ <- vaultRequest _VaultConnection_Manager "POST" (vaultUrl _VaultConnection_VaultAddress "/auth/approle/role/" ++ T.unpack appRoleName) headers (Just varp) [200] pure () where headers = [authTokenHeader _VaultConnection_AuthToken]@@ -377,7 +409,7 @@ vaultSeal :: VaultConnection -> IO () vaultSeal VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} = do- _ <- vaultRequest _VaultConnection_Manager "PUT" (vaultUrl _VaultConnection_VaultAddress "/sys/seal") headers (Nothing :: Maybe ()) [204]+ _ <- vaultRequest _VaultConnection_Manager "PUT" (vaultUrl _VaultConnection_VaultAddress "/sys/seal") headers (Nothing :: Maybe ()) [200] pure () where headers = [authTokenHeader _VaultConnection_AuthToken]@@ -487,7 +519,7 @@ vaultMountSetTune :: VaultConnection -> Text -> VaultMountConfigWrite -> IO () vaultMountSetTune VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} mountPoint mountConfig = do let reqBody = mountConfig- _ <- vaultRequest _VaultConnection_Manager "POST" (vaultUrl _VaultConnection_VaultAddress "/sys/mounts/" ++ T.unpack mountPoint ++ "/tune") headers (Just reqBody) [204]+ _ <- vaultRequest _VaultConnection_Manager "POST" (vaultUrl _VaultConnection_VaultAddress "/sys/mounts/" ++ T.unpack mountPoint ++ "/tune") headers (Just reqBody) [200] pure () where headers = [authTokenHeader _VaultConnection_AuthToken]@@ -496,7 +528,7 @@ vaultNewMount :: VaultConnection -> Text -> VaultMountWrite -> IO () vaultNewMount VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} mountPoint vaultMount = do let reqBody = vaultMount- _ <- vaultRequest _VaultConnection_Manager "POST" (vaultUrl _VaultConnection_VaultAddress "/sys/mounts/" ++ T.unpack mountPoint) headers (Just reqBody) [204]+ _ <- vaultRequest _VaultConnection_Manager "POST" (vaultUrl _VaultConnection_VaultAddress "/sys/mounts/" ++ T.unpack mountPoint) headers (Just reqBody) [200] pure () where headers = [authTokenHeader _VaultConnection_AuthToken]@@ -504,7 +536,7 @@ -- | <https://www.vaultproject.io/docs/http/sys-mounts.html> vaultUnmount :: VaultConnection -> Text -> IO () vaultUnmount VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} mountPoint = do- _ <- vaultRequest _VaultConnection_Manager "DELETE" (vaultUrl _VaultConnection_VaultAddress "/sys/mounts/" ++ T.unpack mountPoint) headers (Nothing :: Maybe ()) [204]+ _ <- vaultRequest _VaultConnection_Manager "DELETE" (vaultUrl _VaultConnection_VaultAddress "/sys/mounts/" ++ T.unpack mountPoint) headers (Nothing :: Maybe ()) [200] pure () where headers = [authTokenHeader _VaultConnection_AuthToken]@@ -528,9 +560,10 @@ -- -- The value that you give must encode as a JSON object vaultWrite :: ToJSON a => VaultConnection -> VaultSecretPath -> a -> IO ()-vaultWrite VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} (VaultSecretPath location) value = do+vaultWrite VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} (VaultSecretPath (mountedPath, searchPath)) value = do let reqBody = value- _ <- vaultRequest _VaultConnection_Manager "POST" (vaultUrl _VaultConnection_VaultAddress "/" ++ T.unpack location) headers (Just reqBody) [204]+ let path = vaultActionUrl Create _VaultConnection_VaultAddress mountedPath searchPath+ _ <- vaultRequest _VaultConnection_Manager "POST" path headers (Just reqBody) [200, 204] pure () where headers = [authTokenHeader _VaultConnection_AuthToken]@@ -554,8 +587,8 @@ -- the error message -- from the parse -- failure-vaultRead VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} (VaultSecretPath location) = do- let path = vaultUrl _VaultConnection_VaultAddress "/" ++ T.unpack location+vaultRead VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} (VaultSecretPath (mountedPath, searchPath)) = do+ let path = vaultActionUrl ReadMetadata _VaultConnection_VaultAddress mountedPath searchPath rspObj <- vaultRequestJSON _VaultConnection_Manager "GET" path headers (Nothing :: Maybe ()) [200] case parseEither parseJSON (Object rspObj) of Left err -> throwIO $ VaultException_ParseBodyError "GET" path (encode rspObj) err@@ -570,8 +603,9 @@ -- | <https://www.vaultproject.io/docs/secrets/generic/index.html> vaultDelete :: VaultConnection -> VaultSecretPath -> IO ()-vaultDelete VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} (VaultSecretPath location) = do- _ <- vaultRequest _VaultConnection_Manager "DELETE" (vaultUrl _VaultConnection_VaultAddress "/" ++ T.unpack location) headers (Nothing :: Maybe ()) [204]+vaultDelete VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} (VaultSecretPath (mountedPath, searchPath)) = do+ let path = vaultActionUrl DeleteMetadata _VaultConnection_VaultAddress mountedPath searchPath+ _ <- vaultRequest _VaultConnection_Manager "DELETE" path headers (Nothing :: Maybe ()) [204] pure () where headers = [authTokenHeader _VaultConnection_AuthToken]@@ -598,23 +632,26 @@ -- -- To recursively retrieve all of the secrets use 'vaultListRecursive' vaultList :: VaultConnection -> VaultSecretPath -> IO [VaultSecretPath]-vaultList VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} (VaultSecretPath location) = do- VaultListResult keys <- vaultRequestJSON _VaultConnection_Manager "LIST" (vaultUrl _VaultConnection_VaultAddress "/" ++ T.unpack location) headers (Nothing :: Maybe ()) [200]- pure $ map (VaultSecretPath . (withTrailingSlash `T.append`)) keys+vaultList VaultConnection{_VaultConnection_VaultAddress, _VaultConnection_Manager, _VaultConnection_AuthToken} (VaultSecretPath (VaultMountedPath mountedPath, VaultSearchPath searchPath)) = do+ let path = vaultActionUrl ListSecrets _VaultConnection_VaultAddress (VaultMountedPath mountedPath) (VaultSearchPath searchPath)+ VaultListResult keys <- vaultRequestJSON _VaultConnection_Manager "LIST" path headers (Nothing :: Maybe ()) [200]+ pure $ map (VaultSecretPath . fullSecretPath) keys where headers = [authTokenHeader _VaultConnection_AuthToken]+ fullSecretPath key = (VaultMountedPath mountedPath, VaultSearchPath (withTrailingSlash `T.append` key)) withTrailingSlash- | T.null location = "/"- | T.last location == '/' = location- | otherwise = location `T.snoc` '/'+ | T.null searchPath = "/"+ | T.last searchPath == '/' = searchPath+ | otherwise = searchPath `T.snoc` '/' + -- | Does the path end with a '/' character? -- -- Meant to be used on the results of 'vaultList' isFolder :: VaultSecretPath -> Bool-isFolder (VaultSecretPath path)- | T.null path = False- | otherwise = T.last path == '/'+isFolder (VaultSecretPath (_, VaultSearchPath searchPath))+ | T.null searchPath = False+ | otherwise = T.last searchPath == '/' -- | Recursively calls 'vaultList' to retrieve all of the secrets in a folder -- (including all subfolders and sub-subfolders, etc...)
src/Network/VaultTool/Types.hs view
@@ -22,7 +22,13 @@ text <- parseJSON j pure (VaultAuthToken text) -newtype VaultSecretPath = VaultSecretPath { unVaultSecretPath :: Text }+newtype VaultMountedPath = VaultMountedPath { unVaultMountedPath :: Text }+ deriving (Show, Eq, Ord)++newtype VaultSearchPath = VaultSearchPath { unVaultSearchPath :: Text }+ deriving (Show, Eq, Ord)++newtype VaultSecretPath = VaultSecretPath (VaultMountedPath, VaultSearchPath) deriving (Show, Eq, Ord) newtype VaultAppRoleId = VaultAppRoleId { unVaultAppRoleId :: Text }
vault-tool.cabal view
@@ -1,5 +1,5 @@ name: vault-tool-version: 0.1.0.0+version: 0.1.0.1 synopsis: Client library for HashiCorp's Vault tool (via HTTP API) description: Client library for HashiCorp's Vault tool (via HTTP API) license: MIT@@ -24,7 +24,7 @@ other-modules: Network.VaultTool.Internal, Network.VaultTool.Types - build-depends: base >=4.8 && <4.11,+ build-depends: base >=4.8 && < 5, text, bytestring, http-client,