git.iko.soy/distributed-process
on master help sign in
Parse hosted services XML
commit65b475e556a38cb00e1500e6e143afbf95f35663 authorEdsko de Vries <edsko@edsko.net> dateWed 25 Jul 2012, 17:16 (14 years ago) parent956b995
3 files changed+102−25
azure-service-api/azure-service-api.cabal+3−1 azure-service-api/src/Network/Azure/ServiceManagement.hs+93−15 azure-service-api/src/Network/Azure/ServiceManagement/CommandLine.hs+6−9
azure-service-api/azure-service-api.cabal+3−1
@@ -23,7 +23,8 @@ Library
2323 tls-extra >= 0.5 && < 0.6,
2424 bytestring >= 0.9 && < 1.0,
2525 certificate >= 1.2 && < 1.3,
26− case-insensitive >= 0.4 && < 0.5
26+ case-insensitive >= 0.4 && < 0.5,
27+ hxt >= 9.2 && < 9.3
2728 HS-Source-Dirs: src
2829 ghc-options: -Wall
2930
@@ -39,6 +40,7 @@ Executable hs-azure-service-api
3940 utf8-string >= 0.3 && < 0.4,
4041 filepath >= 1.3 && < 1.4,
4142 azure-service-api >= 0.1 && < 0.2,
43+ hxt,
4244 libssh2
4345 Extensions: ScopedTypeVariables
4446 ghc-options: -Wall -rtsopts
azure-service-api/src/Network/Azure/ServiceManagement.hs+93−15
@@ -1,13 +1,20 @@
1+{-# LANGUAGE Arrows #-}
12module Network.Azure.ServiceManagement
2− ( -- * Submitting requests
3− azureRequest
4− -- * Re-export functionality from TLS
5− , fileReadCertificate
6− , fileReadPrivateKey
3+ ( -- * Setup
4+ AzureSetup(..)
5+ , azureSetup
6+ -- * High-level API
7+ , hostedServices
8+ -- * Low-level API
9+ , azureRequest
10+ , azureRawRequest
711 ) where
812
13+import Prelude hiding (id)
14+import Control.Category (id, (>>>))
915import Data.ByteString.Lazy (ByteString)
1016import Data.ByteString.Char8 as BSC (pack)
17+import Data.ByteString.Lazy.Char8 as BSLC (unpack)
1118import Network.TLS (PrivateKey)
1219import Network.TLS.Extra (fileReadCertificate, fileReadPrivateKey)
1320import Data.Certificate.X509 (X509)
@@ -20,22 +27,93 @@ import Network.HTTP.Conduit
2027 , httpLbs
2128 )
2229import Data.CaseInsensitive as CI (mk)
30+import Text.XML.HXT.Core
31+ ( runX
32+ , readString
33+ , withValidate
34+ , no
35+ , XmlTree
36+ , IOSArrow
37+ , XNode
38+ , ArrowXml
39+ , deep
40+ , hasName
41+ , getText
42+ )
43+
44+--------------------------------------------------------------------------------
45+-- Setup --
46+--------------------------------------------------------------------------------
47+
48+-- | Azure setup
49+data AzureSetup = AzureSetup
50+ { subscriptionId :: String
51+ , certificate :: X509
52+ , privateKey :: PrivateKey
53+ , baseURL :: String
54+ }
55+
56+-- | Initialize Azure
57+azureSetup :: String -- ^ Subscription ID
58+ -> String -- ^ Path to certificate
59+ -> String -- ^ Path to private key
60+ -> IO AzureSetup
61+azureSetup sid certPath pkeyPath = do
62+ cert <- fileReadCertificate certPath
63+ pkey <- fileReadPrivateKey pkeyPath
64+ return AzureSetup {
65+ subscriptionId = sid
66+ , certificate = cert
67+ , privateKey = pkey
68+ , baseURL = "https://management.core.windows.net"
69+ }
70+
71+--------------------------------------------------------------------------------
72+-- High-level API --
73+--------------------------------------------------------------------------------
2374
24−-- ^ Execute an Azure request
25−azureRequest :: String -- ^ Subscription ID
26− -> X509 -- ^ X509 certificate
27− -> PrivateKey -- ^ Private key
28− -> String -- ^ Relative path
29− -> String -- ^ Version
30− -> IO ByteString
31−azureRequest sid cert pkey subURL version = do
32− req <- parseUrl $ "https://management.core.windows.net/" ++ sid++ subURL
75+hostedServices :: AzureSetup -> IO [(String, String)]
76+hostedServices setup =
77+ azureRequest setup "/services/hostedservices" "2012-03-01" $ proc xml -> do
78+ hostedService <- deep (hasName "HostedService") -< xml
79+ url <- getTextNode "Url" -< hostedService
80+ serviceName <- getTextNode "ServiceName" -< hostedService
81+ id -< (url, serviceName)
82+
83+--------------------------------------------------------------------------------
84+-- Low-level API --
85+--------------------------------------------------------------------------------
86+
87+-- | Execute an Azure request and parse the XML data
88+azureRequest :: AzureSetup
89+ -> String
90+ -> String
91+ -> IOSArrow XmlTree c
92+ -> IO [c]
93+azureRequest setup subURL version f = do
94+ raw <- azureRawRequest setup subURL version
95+ runX $ readString [withValidate no] (BSLC.unpack raw) >>> f
96+
97+-- | Execute an Azure request and return the raw data
98+azureRawRequest :: AzureSetup
99+ -> String -- ^ Relative path
100+ -> String -- ^ Version
101+ -> IO ByteString
102+azureRawRequest setup subURL version = do
103+ req <- parseUrl $ baseURL setup ++ "/" ++ subscriptionId setup ++ "/" ++ subURL
33104 withManager $ \manager -> do
34105 let req' = req {
35− clientCertificates = [ (cert, Just pkey) ]
106+ clientCertificates = [ (certificate setup, Just $ privateKey setup) ]
36107 , requestHeaders = [ (CI.mk $ BSC.pack "x-ms-version", BSC.pack version)
37108 , (CI.mk $ BSC.pack "content-type", BSC.pack "application/xml")
38109 ]
39110 }
40111 Response _ _ _ lbs <- httpLbs req' manager
41112 return lbs
113+
114+--------------------------------------------------------------------------------
115+-- XML convenience functions --
116+--------------------------------------------------------------------------------
117+
118+getTextNode :: ArrowXml a => String -> a XmlTree String
119+getTextNode node = deep (hasName node) >>> deep getText
azure-service-api/src/Network/Azure/ServiceManagement/CommandLine.hs+6−9
@@ -1,15 +1,12 @@
11-- Base
2−import Prelude hiding (catch)
32import System.Environment (getArgs, getEnv)
43import System.FilePath ((</>))
54import System.Posix.Types (Fd)
6−import qualified Data.ByteString.Lazy.Char8 as BSLC (putStrLn)
75
86-- SSL
97import Network.Azure.ServiceManagement
10− ( azureRequest
11− , fileReadCertificate
12− , fileReadPrivateKey
8+ ( azureSetup
9+ , hostedServices
1310 )
1411
1512-- SSH
@@ -68,7 +65,7 @@ ssh login host port actions = do
6865
6966tryConnectToAzure :: String -> String -> String -> IO ()
7067tryConnectToAzure sid pathToCert pathToKey = do
71− cert <- fileReadCertificate pathToCert
72− key <- fileReadPrivateKey pathToKey
73− outp <- azureRequest sid cert key "/services/hostedservices" "2012-03-01"
74− BSLC.putStrLn outp
68+ setup <- azureSetup sid pathToCert pathToKey
69+ services <- hostedServices setup
70+ mapM_ print services
71+