packages feed

aws-sdk 0.2.0.0 → 0.3.0.0

raw patch · 27 files changed

+827/−414 lines, 27 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- AWS.EC2: ApNortheast1 :: EC2Endpoint
- AWS.EC2: EC2Context :: Manager -> EC2Endpoint -> Maybe Text -> EC2Context
- AWS.EC2: NextToken :: Text -> ResponseParserException
- AWS.EC2: UsEast1 :: EC2Endpoint
- AWS.EC2: data EC2 m a
- AWS.EC2: data EC2Context
- AWS.EC2: data EC2Endpoint
- AWS.EC2: data ResponseParserException
- AWS.EC2: endpoint :: EC2Context -> EC2Endpoint
- AWS.EC2: lastRequestId :: EC2Context -> Maybe Text
- AWS.EC2: manager :: EC2Context -> Manager
- AWS.EC2: setEndpoint :: (MonadResource m, MonadBaseControl IO m) => EC2Endpoint -> EC2 m ()
- AWS.EC2.Types: type Filter = (Text, [Text])
- AWS.Types: ApNortheast1 :: EC2Endpoint
- AWS.Types: UsEast1 :: EC2Endpoint
- AWS.Types: class Endpoint a
- AWS.Types: data EC2Endpoint
- AWS.Types: endpointStr :: Endpoint a => a -> ByteString
- AWS.Types: instance Endpoint EC2Endpoint
+ AWS: ClientError :: Text -> Text -> Text -> AWSException
+ AWS: NextToken :: Text -> AWSException
+ AWS: data AWS context m a
+ AWS: data AWSException
+ AWS: errorCode :: AWSException -> Text
+ AWS: errorMessage :: AWSException -> Text
+ AWS: errorRequestId :: AWSException -> Text
+ AWS.EC2: setRegion :: (MonadResource m, MonadBaseControl IO m) => Text -> EC2 m ()
+ AWS.EC2: type EC2 m a = AWS AWSContext m a
+ AWS.EC2.Types: UnknownState :: Int -> InstanceState
+ AWS.EC2.Util: asList :: Monad m => EC2 m (Source m a) -> EC2 m [a]
+ AWS.EC2.Util: each :: Monad m => EC2 m (Source m a) -> (a -> m b) -> EC2 m ()
+ AWS.EC2.Util: head :: Monad m => EC2 m (Source m a) -> EC2 m (Maybe a)
+ AWS.RDS: describeDBInstances :: (MonadBaseControl IO m, MonadResource m) => Maybe Text -> Maybe Int -> Maybe Text -> RDS m [DBInstance]
+ AWS.RDS: runRDS :: MonadIO m => Credential -> RDS m a -> m a
+ AWS.RDS: setRegion :: (MonadBaseControl IO m, MonadResource m) => Text -> RDS m ()
+ AWS.RDS: type RDS m a = AWS AWSContext m a
+ AWS.RDS.Types: AvailabilityZone :: Text -> Bool -> AvailabilityZone
+ AWS.RDS.Types: DBInstance :: Maybe Int -> Int -> Bool -> Text -> Text -> Text -> Text -> Maybe OptionGroupMembership -> Text -> Maybe UTCTime -> [Text] -> Text -> [PendingModifiedValue] -> Maybe Text -> Text -> Maybe DBSubnetGroup -> [DBParameterGroupStatus] -> Maybe Endpoint -> Text -> Maybe Text -> [DBSecurityGroupMembership] -> Maybe Text -> Bool -> Maybe UTCTime -> Int -> Text -> Text -> DBInstance
+ AWS.RDS.Types: DBParameterGroupStatus :: Text -> Text -> DBParameterGroupStatus
+ AWS.RDS.Types: DBSecurityGroupMembership :: Text -> Text -> DBSecurityGroupMembership
+ AWS.RDS.Types: DBSubnetGroup :: Text -> Text -> Text -> Text -> [Subnet] -> DBSubnetGroup
+ AWS.RDS.Types: Endpoint :: Int -> Text -> Endpoint
+ AWS.RDS.Types: OptionGroupMembership :: Text -> Text -> OptionGroupMembership
+ AWS.RDS.Types: PMVAllocatedStorage :: Int -> PendingModifiedValue
+ AWS.RDS.Types: PMVBackupRetentionPeriod :: Int -> PendingModifiedValue
+ AWS.RDS.Types: PMVDBInstanceClass :: Text -> PendingModifiedValue
+ AWS.RDS.Types: PMVEngineVersion :: Text -> PendingModifiedValue
+ AWS.RDS.Types: PMVIops :: Int -> PendingModifiedValue
+ AWS.RDS.Types: PMVMasterUserPassword :: Text -> PendingModifiedValue
+ AWS.RDS.Types: PMVMultiAZ :: Bool -> PendingModifiedValue
+ AWS.RDS.Types: PMVPort :: Int -> PendingModifiedValue
+ AWS.RDS.Types: Subnet :: Text -> Text -> AvailabilityZone -> Subnet
+ AWS.RDS.Types: azName :: AvailabilityZone -> Text
+ AWS.RDS.Types: azProvisionedIopsCapable :: AvailabilityZone -> Bool
+ AWS.RDS.Types: data AvailabilityZone
+ AWS.RDS.Types: data DBInstance
+ AWS.RDS.Types: data DBParameterGroupStatus
+ AWS.RDS.Types: data DBSecurityGroupMembership
+ AWS.RDS.Types: data DBSubnetGroup
+ AWS.RDS.Types: data Endpoint
+ AWS.RDS.Types: data OptionGroupMembership
+ AWS.RDS.Types: data PendingModifiedValue
+ AWS.RDS.Types: data Subnet
+ AWS.RDS.Types: dbiAllocatedStorage :: DBInstance -> Int
+ AWS.RDS.Types: dbiAutoMinorVersionUpgrade :: DBInstance -> Bool
+ AWS.RDS.Types: dbiAvailabilityZone :: DBInstance -> Text
+ AWS.RDS.Types: dbiBackupRetentionPeriod :: DBInstance -> Int
+ AWS.RDS.Types: dbiCharacterSetName :: DBInstance -> Maybe Text
+ AWS.RDS.Types: dbiDBInstanceClass :: DBInstance -> Text
+ AWS.RDS.Types: dbiDBInstanceIdentifier :: DBInstance -> Text
+ AWS.RDS.Types: dbiDBInstanceStatus :: DBInstance -> Text
+ AWS.RDS.Types: dbiDBName :: DBInstance -> Maybe Text
+ AWS.RDS.Types: dbiDBParameterGroups :: DBInstance -> [DBParameterGroupStatus]
+ AWS.RDS.Types: dbiEndpoint :: DBInstance -> Maybe Endpoint
+ AWS.RDS.Types: dbiEngine :: DBInstance -> Text
+ AWS.RDS.Types: dbiEngineVersion :: DBInstance -> Text
+ AWS.RDS.Types: dbiInstanceCreateTime :: DBInstance -> Maybe UTCTime
+ AWS.RDS.Types: dbiIops :: DBInstance -> Maybe Int
+ AWS.RDS.Types: dbiLatestRestorableTime :: DBInstance -> Maybe UTCTime
+ AWS.RDS.Types: dbiLicenseModel :: DBInstance -> Text
+ AWS.RDS.Types: dbiMasterUsername :: DBInstance -> Text
+ AWS.RDS.Types: dbiMultiAZ :: DBInstance -> Bool
+ AWS.RDS.Types: dbiOptionGroupMembership :: DBInstance -> Maybe OptionGroupMembership
+ AWS.RDS.Types: dbiPendingModifiedValues :: DBInstance -> [PendingModifiedValue]
+ AWS.RDS.Types: dbiPreferredBackupWindow :: DBInstance -> Text
+ AWS.RDS.Types: dbiPreferredMaintenanceWindow :: DBInstance -> Text
+ AWS.RDS.Types: dbiReadReplicaDBInstanceIdentifiers :: DBInstance -> [Text]
+ AWS.RDS.Types: dbiReadReplicaSourceDBInstanceIdentifier :: DBInstance -> Maybe Text
+ AWS.RDS.Types: dbiSecurityGroups :: DBInstance -> [DBSecurityGroupMembership]
+ AWS.RDS.Types: dbiSubnetGroup :: DBInstance -> Maybe DBSubnetGroup
+ AWS.RDS.Types: dbpgsDBParameterGroupName :: DBParameterGroupStatus -> Text
+ AWS.RDS.Types: dbpgsParameterApplyStatus :: DBParameterGroupStatus -> Text
+ AWS.RDS.Types: dbsgmDBSecurityGroupName :: DBSecurityGroupMembership -> Text
+ AWS.RDS.Types: dbsgmStatus :: DBSecurityGroupMembership -> Text
+ AWS.RDS.Types: dbsngDBSubnetGroupDescription :: DBSubnetGroup -> Text
+ AWS.RDS.Types: dbsngDBSubnetGroupName :: DBSubnetGroup -> Text
+ AWS.RDS.Types: dbsngSubnetGroupStatus :: DBSubnetGroup -> Text
+ AWS.RDS.Types: dbsngSubnets :: DBSubnetGroup -> [Subnet]
+ AWS.RDS.Types: dbsngVpcId :: DBSubnetGroup -> Text
+ AWS.RDS.Types: epAddress :: Endpoint -> Text
+ AWS.RDS.Types: epPort :: Endpoint -> Int
+ AWS.RDS.Types: instance Show AvailabilityZone
+ AWS.RDS.Types: instance Show DBInstance
+ AWS.RDS.Types: instance Show DBParameterGroupStatus
+ AWS.RDS.Types: instance Show DBSecurityGroupMembership
+ AWS.RDS.Types: instance Show DBSubnetGroup
+ AWS.RDS.Types: instance Show Endpoint
+ AWS.RDS.Types: instance Show OptionGroupMembership
+ AWS.RDS.Types: instance Show PendingModifiedValue
+ AWS.RDS.Types: instance Show Subnet
+ AWS.RDS.Types: ogmOptionGroupName :: OptionGroupMembership -> Text
+ AWS.RDS.Types: ogmStatus :: OptionGroupMembership -> Text
+ AWS.RDS.Types: subnetAvailabilityZone :: Subnet -> AvailabilityZone
+ AWS.RDS.Types: subnetIdentifier :: Subnet -> Text
+ AWS.RDS.Types: subnetStatus :: Subnet -> Text
- AWS.EC2: runEC2 :: MonadIO m => Credential -> EC2 m a -> m a
+ AWS.EC2: runEC2 :: MonadIO m => Credential -> AWS AWSContext m a -> m a

Files

AWS.hs view
@@ -17,14 +17,14 @@ -- >  -- > import AWS -- > import AWS.EC2+-- > import qualified AWS.EC2.Util as Util -- >  -- > main :: IO () -- > main = do -- >     cred <- loadCredential--- >     doc <- runResourceT $ do--- >         runEC2 cred $ do--- >             response <- describeInstances [] []--- >             lift $ response $$ CL.consume+-- >     doc <- runResourceT $+-- >         runEC2 cred $+-- >             Util.asList $ describeInstances [] [] -- >     print doc -- >     putStr "Length: " -- >     print $ length doc@@ -33,6 +33,10 @@     ( -- * Credentials       Credential     , loadCredential+      -- * Environment+    , AWS+    , AWSException(..)     ) where  import AWS.Credential+import AWS.Class
+ AWS/Class.hs view
@@ -0,0 +1,101 @@+{-# LANGUAGE GeneralizedNewtypeDeriving+ , TypeFamilies+ , FlexibleInstances+ , MultiParamTypeClasses+ , UndecidableInstances+ , DeriveDataTypeable+ #-}++module AWS.Class+    ( AWS+    , runAWS+    , AWSException(..)+    , AWSContext(..)+    ) where++import Control.Monad.State (StateT(..), MonadState)+import qualified Control.Monad.State as S+import Control.Monad.Reader (ReaderT(..), MonadReader)+import qualified Control.Monad.Reader as R+import Control.Applicative+import Control.Monad (liftM)+import Control.Monad.Base (MonadBase)+import Control.Monad.IO.Class (MonadIO, liftIO)+import Control.Monad.Trans.Class (MonadTrans, lift)+import Control.Monad.Trans.Control+    ( MonadBaseControl(..)+    , MonadTransControl(..)+    , ComposeSt+    , defaultLiftBaseWith+    , defaultRestoreM+    )+import Control.Exception (Exception)+import Data.Typeable (Typeable)++import qualified Network.HTTP.Conduit as HTTP+import Data.Text (Text)+import Data.ByteString (ByteString)+import Data.ByteString.Char8 ()++import AWS.Credential++data AWSException+    = ClientError+        { errorCode :: Text+        , errorMessage :: Text+        , errorRequestId :: Text+        } -- ^ This error is caused by client requests.+    | NextToken Text -- ^ This response has next token.+  deriving (Show, Typeable)++instance Exception AWSException++data AWSContext = AWSContext+    { manager :: HTTP.Manager+    , endpoint :: ByteString+    , lastRequestId :: Maybe Text+    }++newtype AWS context m a = AWST+    { runAWST :: StateT context (ReaderT Credential m) a+    } deriving+    ( Monad+    , Applicative+    , Functor+    , MonadIO+    , MonadState context+    , MonadReader Credential+    , MonadBase base+    )++instance MonadTrans (AWS c)+  where+    lift = AWST . lift . lift++instance MonadTransControl (AWS c)+  where+    newtype StT (AWS c) a = StAWS { unStAWS :: (a, c) }+    liftWith f = AWST . StateT $ \s -> ReaderT $ \r ->+        liftM (\x -> (x, s))+            (f $ \a -> liftM StAWS+                (R.runReaderT (S.runStateT (runAWST a) s) r))+    restoreT+        = AWST . StateT . const . ReaderT . const . liftM unStAWS++instance MonadBaseControl base m => MonadBaseControl base (AWS c m)+  where+    newtype StM (AWS c m) a+        = StMAWS { unStMAWS :: ComposeSt (AWS c) m a }+    liftBaseWith = defaultLiftBaseWith StMAWS+    restoreM = defaultRestoreM unStMAWS++runAWS :: MonadIO m+    => (HTTP.Manager -> c)+    -> Credential+    -> AWS c m a+    -> m a+runAWS ctx cred app = do+    mgr <- liftIO $ HTTP.newManager HTTP.def+    R.runReaderT+        (S.evalStateT (runAWST app) $ ctx mgr)+        cred
AWS/EC2.hs view
@@ -3,9 +3,9 @@  module AWS.EC2     ( -- * EC2 Environment-      module AWS.EC2.Class-    , EC2Endpoint(..)-    , setEndpoint+      EC2+    , runEC2+    , setRegion       -- * Instances     , module AWS.EC2.Instance       -- * Images@@ -30,9 +30,12 @@ import Data.Conduit import Control.Monad.Trans.Control (MonadBaseControl) import qualified Control.Monad.State as State+import Data.Text (Text) -import AWS.Types-import AWS.EC2.Class+import AWS.Util+import AWS.EC2.Internal+import AWS.EC2.Types+import qualified AWS.EC2.Util as Util  import AWS.EC2.Image import AWS.EC2.Region@@ -45,9 +48,17 @@ import AWS.EC2.KeyPair import AWS.EC2.SecurityGroup -setEndpoint+-- | set endpoint to EC2 context.+setRegion     :: (MonadResource m, MonadBaseControl IO m)-    => EC2Endpoint -> EC2 m ()-setEndpoint ep = do+    => Text -- ^ RegionName+    -> EC2 m ()+setRegion name = do+    region <- Util.head $ describeRegions [name] []     ctx <- State.get-    State.put ctx { endpoint = ep }+    maybe+        (fail "region not found")+        (\r -> State.put ctx { endpoint = f r })+        region+  where+    f = textToBS . regionEndpoint
AWS/EC2/Address.hs view
@@ -17,8 +17,8 @@ import Control.Monad.Trans.Control (MonadBaseControl) import Control.Applicative +import AWS.EC2.Internal import AWS.EC2.Types-import AWS.EC2.Class import AWS.EC2.Query import AWS.EC2.Parser import AWS.Util
AWS/EC2/AvailabilityZone.hs view
@@ -11,8 +11,8 @@ import Control.Monad.Trans.Control (MonadBaseControl) import Control.Applicative +import AWS.EC2.Internal import AWS.EC2.Types-import AWS.EC2.Class import AWS.EC2.Query import AWS.EC2.Parser 
− AWS/EC2/Class.hs
@@ -1,93 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving- , TypeFamilies- , FlexibleInstances- , MultiParamTypeClasses- , UndecidableInstances- , DeriveDataTypeable- #-}--module AWS.EC2.Class-    ( EC2-    , runEC2-    , ResponseParserException(..)-    , EC2Context(..)-    ) where--import Control.Monad.State (StateT(..), MonadState)-import qualified Control.Monad.State as S-import Control.Monad.Reader (ReaderT(..), MonadReader)-import qualified Control.Monad.Reader as R-import Control.Applicative-import Control.Monad (liftM)-import Control.Monad.Base (MonadBase)-import Control.Monad.IO.Class (MonadIO, liftIO)-import Control.Monad.Trans.Class (MonadTrans, lift)-import Control.Monad.Trans.Control-    ( MonadBaseControl(..)-    , MonadTransControl(..)-    , ComposeSt-    , defaultLiftBaseWith-    , defaultRestoreM-    )-import Control.Exception (Exception)-import Data.Typeable (Typeable)--import qualified Network.HTTP.Conduit as HTTP-import Data.Text (Text)--import AWS.Types-import AWS.Credential--data EC2Context = EC2Context-    { manager :: HTTP.Manager-    , endpoint :: EC2Endpoint-    , lastRequestId :: Maybe Text-    }--initialEC2Context :: HTTP.Manager -> EC2Context-initialEC2Context mgr = EC2Context-    { manager = mgr-    , endpoint = UsEast1-    , lastRequestId = Nothing-    }--data ResponseParserException-    = NextToken Text-  deriving (Show, Typeable)--instance Exception ResponseParserException--newtype EC2 m a = EC2T-    { runEC2T :: StateT EC2Context (ReaderT Credential m) a-    } deriving-    ( Monad-    , Applicative-    , Functor-    , MonadIO-    , MonadState EC2Context-    , MonadReader Credential-    , MonadBase base-    )--instance MonadTrans EC2 where-    lift = EC2T . lift . lift--instance MonadTransControl EC2 where-    newtype StT EC2 a = StEC2 { unStEC2 :: (a, EC2Context) }-    liftWith f = EC2T . StateT $ \s -> ReaderT $ \r ->-        liftM (\x -> (x, s))-            (f $ \a -> liftM StEC2-                (R.runReaderT (S.runStateT (runEC2T a) s) r))-    restoreT = EC2T . StateT . const . ReaderT . const . liftM unStEC2--instance MonadBaseControl base m => MonadBaseControl base (EC2 m) where-    newtype StM (EC2 m) a = StMEC2 { unStMEC2 :: ComposeSt EC2 m a }-    liftBaseWith = defaultLiftBaseWith StMEC2-    restoreM = defaultRestoreM unStMEC2--runEC2 :: MonadIO m => Credential -> EC2 m a -> m a-runEC2 cred app = do-    mgr <- liftIO $ HTTP.newManager HTTP.def-    R.runReaderT-        (S.evalStateT (runEC2T app) $ initialEC2Context mgr)-        cred
AWS/EC2/Image.hs view
@@ -12,9 +12,9 @@ import Control.Monad.Trans.Control (MonadBaseControl) import Control.Applicative +import AWS.EC2.Internal import AWS.EC2.Types import AWS.EC2.Params-import AWS.EC2.Class import AWS.EC2.Query import AWS.EC2.Parser import AWS.Util
AWS/EC2/Instance.hs view
@@ -30,9 +30,9 @@ import Data.Maybe (fromJust) import qualified Data.Map as Map +import AWS.EC2.Internal import AWS.EC2.Types import AWS.EC2.Params-import AWS.EC2.Class import AWS.EC2.Query import AWS.EC2.Parser import AWS.Util
+ AWS/EC2/Internal.hs view
@@ -0,0 +1,26 @@+module AWS.EC2.Internal+    ( AWSContext(..)+    , EC2+    , runEC2+      -- re-export+    , AWSException(..)+    ) where++import Control.Monad.IO.Class (MonadIO)+import qualified Network.HTTP.Conduit as HTTP+import Data.ByteString.Char8 ()++import AWS.Class+import AWS.Credential++initialEC2Context :: HTTP.Manager -> AWSContext+initialEC2Context mgr = AWSContext+    { manager = mgr+    , endpoint = "ec2.amazonaws.com"+    , lastRequestId = Nothing+    }++type EC2 m a = AWS AWSContext m a++runEC2 :: MonadIO m => Credential -> AWS AWSContext m a -> m a+runEC2 = runAWS initialEC2Context
AWS/EC2/KeyPair.hs view
@@ -14,8 +14,8 @@ import Control.Monad.Trans.Control (MonadBaseControl) import Control.Applicative +import AWS.EC2.Internal import AWS.EC2.Types-import AWS.EC2.Class import AWS.EC2.Query import AWS.EC2.Parser import AWS.Util
AWS/EC2/Parser.hs view
@@ -1,5 +1,5 @@ module AWS.EC2.Parser-    ( module AWS.EC2.Parser.Internal+    ( module AWS.Lib.Parser     , resourceTagSink     , productCodeSink     , stateReasonSink@@ -12,7 +12,7 @@ import Data.XML.Types (Event)  import AWS.EC2.Types-import AWS.EC2.Parser.Internal+import AWS.Lib.Parser import AWS.Util  resourceTagSink :: MonadThrow m
− AWS/EC2/Parser/Internal.hs
@@ -1,117 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE RankNTypes #-}-module AWS.EC2.Parser.Internal where--import           Data.ByteString (ByteString)-import qualified Data.ByteString.Char8 as BSC-import           Data.ByteString.Lazy.Char8 ()--import Data.XML.Types (Event(..), Name(..))-import Data.Text (Text)-import qualified Data.Text as T-import Data.Conduit-import qualified Data.Conduit.List as CL-import qualified Text.XML.Stream.Parse as XML-import Control.Applicative-import Data.Monoid ((<>))--apiVersion :: ByteString-apiVersion = "2012-08-15"--itemConduit :: MonadThrow m-    => Text-    -> GLSink Event m o-    -> GLConduit Event m o-itemConduit tag inner = do-    maybe (()) id <$> elementM tag (items inner)-  where-    items :: MonadThrow m-        => Pipe Event Event o u m o-        -> Pipe Event Event o u m ()-    items p = awaitWhile isTag >>= maybe (return ()) (\e -> do-        leftover e-        if isBeginTagName "item" e-            then do-                element "item" $ p >>= yield-                items p-            else return ()-        )--itemsSet :: MonadThrow m-    => Text-    -> GLSink Event m o-    -> GLSink Event m [o]-itemsSet tag inner = itemConduit tag inner >+> CL.consume--isTag :: Event -> Bool-isTag (EventBeginElement _ _) =True-isTag (EventEndElement _) =True-isTag _ = False--isBeginTagName :: Text -> Event -> Bool-isBeginTagName name (EventBeginElement n _)-    | n == ec2Name name = True-    | otherwise         = False-isBeginTagName _ _ = False--awaitWhile :: Monad m-    => (i -> Bool)-    -> Pipe l i o u m (Maybe i)-awaitWhile f = await >>= g-  where-    g Nothing       = return Nothing-    g (Just a)-        | f a       = return $ Just a-        | otherwise = awaitWhile f--getF :: MonadThrow m-    => Text-    -> (Text -> b)-    -> Pipe Event Event o u m b-getF name f = tagContentF name >>= return . f--getT :: MonadThrow m-    => Text-    -> Pipe Event Event o u m Text-getT name = getF name id--getM :: MonadThrow m-    => Text-    -> (Maybe Text -> b)-    -> Pipe Event Event o u m b-getM name f = tagContent name >>= return . f--getMT :: MonadThrow m-    => Text-    -> Pipe Event Event o u m (Maybe Text)-getMT name = getM name id--elementM :: MonadThrow m-    => Text-    -> Pipe Event Event o u m a-    -> Pipe Event Event o u m (Maybe a)-elementM name inner = XML.tagNoAttr (ec2Name name) inner--element :: MonadThrow m-    => Text-    -> Pipe Event Event o u m a-    -> Pipe Event Event o u m a-element name inner = XML.force "parse error" $ elementM name inner--tagContent :: MonadThrow m-    => Text-    -> GLSink Event m (Maybe Text)-tagContent name = XML.tagNoAttr (ec2Name name) XML.content--tagContentF :: MonadThrow m-    => Text-    -> GLSink Event m Text-tagContentF = XML.force "parse error" . tagContent--ec2Name :: Text -> Name-ec2Name name = Name-    { nameLocalName = name-    , nameNamespace =-        Just $ "http://ec2.amazonaws.com/doc/" <> T.pack (BSC.unpack apiVersion) <> "/"-    , namePrefix = Nothing-    }
AWS/EC2/Query.hs view
@@ -1,49 +1,31 @@ {-# LANGUAGE FlexibleContexts, RankNTypes #-}-{-# LANGUAGE DeriveDataTypeable #-}  module AWS.EC2.Query     ( ec2Query     , ec2QuerySource     , ec2QuerySource'-    , ec2Request     , QueryParam(..)-    , EC2ClientException(..)+    , Filter     ) where  import           Data.ByteString (ByteString)-import qualified Data.ByteString as BS import           Data.ByteString.Lazy.Char8 ()-import qualified Data.ByteString.Char8 as BSC -import Data.Monoid-import Data.XML.Types (Event(..), Name(..))+import Data.XML.Types (Event(..)) import Data.Conduit import qualified Data.Conduit.List as CL import Control.Monad.Trans.Control (MonadBaseControl)-import qualified Network.HTTP.Conduit as HTTP import qualified Text.XML.Stream.Parse as XmlP-import Data.Time (UTCTime, formatTime, getCurrentTime)-import System.Locale (defaultTimeLocale, iso8601DateFormat)-import qualified Data.Map as Map-import Data.Map (Map)-import qualified Network.HTTP.Types as H-import qualified Data.Digest.Pure.SHA as SHA-import qualified Data.ByteString.Base64 as BASE-import Control.Monad.IO.Class (MonadIO, liftIO) import Control.Monad.Trans.Class (lift) import qualified Control.Monad.State as State import qualified Control.Monad.Reader as Reader import Control.Exception.Lifted as E import Data.Text (Text)-import Data.Typeable (Typeable) import Control.Applicative -import AWS.EC2.Types-import AWS.Types-import AWS.Util+import AWS.EC2.Internal import AWS.EC2.Parser-import AWS.EC2.Class-import AWS.Credential+import AWS.Lib.Query  {- Debug import Debug.Trace@@ -51,147 +33,25 @@ import System.IO (stdout) --} -data EC2ClientException-    = ClientError-        { errorCode :: Text-        , errorMessage :: Text-        , errorRequestId :: Text-        }-  deriving (Show, Typeable)-instance Exception EC2ClientException--data QueryParam-    = ArrayParams Text [Text]-    | FilterParams [Filter]-    | ValueParam Text Text-    | StructArrayParams Text [[(Text, Text)]]-  deriving (Show)--queryHeader :: ByteString -> UTCTime -> Credential -> [(ByteString, ByteString)]-queryHeader action time cred =-    [ ("Action", action)-    , ("Version", apiVersion)-    , ("SignatureVersion", "2")-    , ("SignatureMethod", "HmacSHA256")-    , ("Timestamp", H.urlEncode True $ awsTimeFormat time)-    , ("AWSAccessKeyId", accessKey cred)-    ]--mkUrl :: Endpoint end-      => end-      -> Credential-      -> UTCTime-      -> ByteString-      -> [QueryParam]-      -> ByteString-mkUrl ep cred time action params = mconcat-    [ "https://"-    , endpointStr ep-    , "/?"-    , qparam-    , "&Signature="-    , signature ep (secretAccessKey cred) qparam-    ]-  where-    qheader = Map.fromList $ queryHeader action time cred-    qparam = queryStr $ Map.unions (qheader : map toArrayParams params)--toArrayParams :: QueryParam -> Map ByteString ByteString-toArrayParams (ArrayParams name params) = Map.fromList -    [ (textToBS name <> "." <> bsShow i, textToBS param)-    | (i, param) <- zip ([1..]::[Int]) params--    ]-toArrayParams (FilterParams kvs) =-    Map.fromList . concat . map f1 $ zip ([1..]::[Int]) kvs-  where-    f1 (n, (key, vals)) = (filt n <> ".Name", textToBS key) :-        [ (filt n <> ".Value." <> bsShow i, textToBS param)-        | (i, param) <- zip ([1..]::[Int]) vals-        ]-    filt n = "Filter." <> bsShow n-toArrayParams (ValueParam k v) =-    Map.singleton (textToBS k) (textToBS v)-toArrayParams (StructArrayParams name vss) = Map.fromList l-  where-    bsName = textToBS name-    struct n (k, v) = (n <> "." <> textToBS k, textToBS v)-    l = mconcat-        [ map (struct (bsName <> "." <> bsShow i)) kvs-        | (i, kvs) <- zip ([1..]::[Int]) vss-        ]--queryStr :: Map ByteString ByteString -> ByteString-queryStr = BS.intercalate "&" . Map.foldrWithKey' concatWithEqual []-  where-    concatWithEqual key val acc = key <> "=" <> val : acc--awsTimeFormat :: UTCTime -> ByteString-awsTimeFormat = BSC.pack . formatTime defaultTimeLocale (iso8601DateFormat $ Just "%XZ")--signature :: Endpoint end -          => end -> SecretAccessKey -> ByteString -> ByteString-signature ep secret query = urlstr-  where-    stringToSign = "GET\n" <> endpointStr ep <> "\n/\n" <> query-    signedStr = toS . SHA.bytestringDigest $ SHA.hmacSha256 (toL secret) (toL stringToSign)-    urlstr = H.urlEncode True . BASE.encode $ signedStr+ec2Version :: ByteString+ec2Version = "2012-08-15"  sinkRequestId :: MonadThrow m     => GLSink Event m Text sinkRequestId = do     await -- EventBeginDocument     await -- EventBeginElement DescribeImagesResponse-    tagContentF "requestId"--checkStatus' ::-    H.Status -> H.ResponseHeaders -> Maybe SomeException-checkStatus' = \s@(H.Status sci _) hs ->-    if 200 <= sci && sci < 300 || sci == 400-        then Nothing-        else Just $ toException $ HTTP.StatusCodeException s hs+    getT "requestId" -sinkError :: MonadThrow m => GLSink Event m a-sinkError = do+sinkError :: MonadThrow m => Int -> GLSink Event m a+sinkError _ = do     await-    etag "Response" $ do-        (c,m) <- etag "Errors" $ etag "Error" $-            (,) <$> tagt "Code" <*> tagt "Message"-        r <- tagt "RequestID"+    element "Response" $ do+        (c,m) <- element "Errors" $ element "Error" $+            (,) <$> getT "Code" <*> getT "Message"+        r <- getT "RequestID"         lift $ monadThrow $ ClientError c m r-  where-    etag name inner = XmlP.force "error parse error"-        $ XmlP.tagNoAttr (errName name) inner-    tagt name = etag name XmlP.content-    errName n = Name n Nothing Nothing -clientError-    :: (MonadResource m, MonadBaseControl IO m)-    => ResumableSource m ByteString -> m a-clientError rsrc =-    rsrc $$+- XmlP.parseBytes XmlP.def =$ sinkError--ec2Request-    :: (MonadResource m, MonadBaseControl IO m)-    => Credential-    -> EC2Context-    -> ByteString-    -> [QueryParam]-    -> m (ResumableSource m ByteString)-ec2Request cred ctx action params = do-    let mgr = manager ctx-    let ep = endpoint ctx-    time <- liftIO getCurrentTime-    let url = mkUrl ep cred time action params-    request <- liftIO $ HTTP.parseUrl (BSC.unpack url)-    let req = request { HTTP.checkStatus = checkStatus' }-    response <- HTTP.http req mgr-    let body = HTTP.responseBody response-    if (H.statusCode $ HTTP.responseStatus response) == 400-        then clientError body-        else return ()-    return body- ec2Query     :: (MonadResource m, MonadBaseControl IO m)     => ByteString@@ -222,7 +82,7 @@     cred <- Reader.ask     ctx <- State.get     (src1, rid) <- lift $ do-        response <- ec2Request cred ctx action params'+        response <- requestQuery cred ctx action params' ec2Version sinkError         (res, _) <- unwrapResumable response --        res $$ CB.sinkFile "debug.txt" >>= fail "debug"         res $= XmlP.parseBytes XmlP.def $$+ sinkRequestId
AWS/EC2/Region.hs view
@@ -11,8 +11,8 @@ import Control.Monad.Trans.Control (MonadBaseControl) import Control.Applicative +import AWS.EC2.Internal import AWS.EC2.Types-import AWS.EC2.Class import AWS.EC2.Query import AWS.EC2.Parser 
AWS/EC2/SecurityGroup.hs view
@@ -20,8 +20,8 @@ import Control.Applicative import Data.Monoid +import AWS.EC2.Internal import AWS.EC2.Types-import AWS.EC2.Class import AWS.EC2.Query import AWS.EC2.Parser import AWS.Util
AWS/EC2/Snapshot.hs view
@@ -13,8 +13,8 @@ import Control.Monad.Trans.Control (MonadBaseControl) import Control.Applicative +import AWS.EC2.Internal import AWS.EC2.Types-import AWS.EC2.Class import AWS.EC2.Query import AWS.EC2.Parser import AWS.Util
AWS/EC2/Tag.hs view
@@ -12,8 +12,8 @@ import Control.Monad.Trans.Control (MonadBaseControl) import Control.Applicative +import AWS.EC2.Internal import AWS.EC2.Types-import AWS.EC2.Class import AWS.EC2.Query import AWS.EC2.Parser import AWS.Util
AWS/EC2/Types.hs view
@@ -6,8 +6,6 @@  import AWS.Util -type Filter = (Text, [Text])- data Image = Image     { imageId :: Text     , imageLocation :: Text@@ -298,6 +296,7 @@     | Terminated     | Stopping     | Stopped+    | UnknownState Int   deriving (Show)  instanceStateCodes :: [(Int, InstanceState)]@@ -312,7 +311,7 @@  codeToState :: Int -> InstanceState codeToState code = case lookup code instanceStateCodes of-    Nothing -> error "invalid state code"+    Nothing -> UnknownState code     Just st -> st  data Placement = Placement
+ AWS/EC2/Util.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE FlexibleContexts #-}++module AWS.EC2.Util+    ( asList+    , head+    , each+    ) where++import Data.Conduit+import qualified Data.Conduit.List as CL+import Control.Monad.Trans.Class (lift)+import Prelude hiding (head)++import AWS.EC2.Internal++asList+    :: Monad m+    => EC2 m (Source m a)+    -> EC2 m [a]+asList src = do+    s <- src+    lift $ s $$ CL.consume++head+    :: Monad m+    => EC2 m (Source m a)+    -> EC2 m (Maybe a)+head src = do+    s <- src+    lift $ s $$ CL.head++each+    :: Monad m+    => EC2 m (Source m a)+    -> (a -> m b)+    -> EC2 m ()+each src f = do+    s <- src+    (rsrc, _) <- lift $ s $$+ CL.take 0+    lift $ each' rsrc f++each'+    :: Monad m+    => ResumableSource m a+    -> (a -> m b)+    -> m ()+each' rsrc f = do+    (s', ma) <- rsrc $$++ CL.head+    case ma of+        Nothing -> return ()+        Just a  -> f a >> each' s' f
− AWS/EC2/Utils.hs
@@ -1,2 +0,0 @@-module AWS.EC2.Utils where-
AWS/EC2/Volume.hs view
@@ -14,8 +14,8 @@ import Control.Monad.Trans.Control (MonadBaseControl) import Control.Applicative +import AWS.EC2.Internal import AWS.EC2.Types-import AWS.EC2.Class import AWS.EC2.Query import AWS.EC2.Parser import AWS.Util
+ AWS/Lib/Parser.hs view
@@ -0,0 +1,124 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}+module AWS.Lib.Parser+    where++import Data.XML.Types (Event(..), Name(..))+import Data.Text (Text)+import qualified Data.Text as T+import Data.Conduit+import qualified Data.Conduit.List as CL+import qualified Text.XML.Stream.Parse as XML+import Control.Applicative++text :: MonadThrow m => GLSink Event m Text+text = XML.content++itemConduit :: MonadThrow m+    => Text+    -> GLSink Event m o+    -> GLConduit Event m o+itemConduit tag inner =+    maybe (()) id <$> elementM tag (listConduit "item" inner)++listConduit :: MonadThrow m+    => Text+    -> GLSink Event m o+    -> GLConduit Event m o+listConduit name p =+    awaitWhile isTag >>= maybe (return ()) (\e -> do+        leftover e+        if isBeginTagName name e+            then do+                element name $ p >>= yield+                listConduit name p+            else return ()+        )++listConsumer :: MonadThrow m+    => Text+    -> GLSink Event m o+    -> GLSink Event m [o]+listConsumer name p = listConduit name p >+> CL.consume++itemsSet :: MonadThrow m+    => Text+    -> GLSink Event m o+    -> GLSink Event m [o]+itemsSet tag inner = itemConduit tag inner >+> CL.consume++isTag :: Event -> Bool+isTag (EventBeginElement _ _) =True+isTag (EventEndElement _) =True+isTag _ = False++sinkDropWhile :: Monad m => (i -> Bool) -> GLSink i m ()+sinkDropWhile f = await >>= maybe (return ()) g+  where+      g i | f i       = sinkDropWhile f+              | otherwise = leftover i >> return ()++isBeginTagName :: Text -> Event -> Bool+isBeginTagName name (EventBeginElement n _)+    | nameLocalName n == name = True+    | otherwise               = False+isBeginTagName _ _ = False++awaitWhile :: Monad m+    => (i -> Bool)+    -> Pipe l i o u m (Maybe i)+awaitWhile f = await >>= g+  where+    g Nothing       = return Nothing+    g (Just a)+        | f a       = return $ Just a+        | otherwise = awaitWhile f++getF :: MonadThrow m+    => Text+    -> (Text -> b)+    -> Pipe Event Event o u m b+getF name f = tagContent name >>= return . f++getT :: MonadThrow m+    => Text+    -> Pipe Event Event o u m Text+getT name = getF name id++getM :: MonadThrow m+    => Text+    -> (Maybe Text -> b)+    -> Pipe Event Event o u m b+getM name f = tagContentM name >>= return . f++getMT :: MonadThrow m+    => Text+    -> Pipe Event Event o u m (Maybe Text)+getMT name = getM name id++elementM :: MonadThrow m+    => Text+    -> Pipe Event Event o u m a+    -> Pipe Event Event o u m (Maybe a)+elementM name inner = do+    sinkDropWhile $ not . isTag+    XML.tagPredicate g (return ()) $ const inner+  where+    g n = (nameLocalName n == name)++element :: MonadThrow m+    => Text+    -> Pipe Event Event o u m a+    -> Pipe Event Event o u m a+element name inner = XML.force "parse error" $ elementM name inner++tagContentM :: MonadThrow m+    => Text+    -> GLSink Event m (Maybe Text)+tagContentM name = elementM name text++tagContent :: MonadThrow m+    => Text+    -> GLSink Event m Text+tagContent name =+    XML.force ("parse error:" ++ T.unpack name) $ tagContentM name
+ AWS/Lib/Query.hs view
@@ -0,0 +1,165 @@+{-# LANGUAGE FlexibleContexts, RankNTypes #-}++module AWS.Lib.Query+    ( requestQuery+    , QueryParam(..)+    , Filter+    ) where++import           Data.ByteString (ByteString)+import qualified Data.ByteString as BS+import           Data.ByteString.Lazy.Char8 ()+import qualified Data.ByteString.Char8 as BSC++import Data.Monoid+import Data.XML.Types (Event(..))+import Data.Conduit+import Control.Monad.Trans.Control (MonadBaseControl)+import qualified Network.HTTP.Conduit as HTTP+import qualified Text.XML.Stream.Parse as XmlP+import Data.Time (UTCTime, formatTime, getCurrentTime)+import System.Locale (defaultTimeLocale, iso8601DateFormat)+import qualified Data.Map as Map+import Data.Map (Map)+import qualified Network.HTTP.Types as H+import qualified Data.Digest.Pure.SHA as SHA+import qualified Data.ByteString.Base64 as BASE+import Control.Monad.IO.Class (MonadIO, liftIO)+import Control.Exception.Lifted as E+import Data.Text (Text)++import AWS.Class+import AWS.Util+import AWS.EC2.Parser ()+import AWS.Credential++{- Debug+import Debug.Trace+import qualified Data.Conduit.Binary as CB+import System.IO (stdout)+--}++type Filter = (Text, [Text])++data QueryParam+    = ArrayParams Text [Text]+    | FilterParams [Filter]+    | ValueParam Text Text+    | StructArrayParams Text [[(Text, Text)]]+  deriving (Show)++queryHeader+    :: ByteString+    -> UTCTime+    -> Credential+    -> ByteString+    -> [(ByteString, ByteString)]+queryHeader action time cred ver =+    [ ("Action", action)+    , ("Version", ver)+    , ("SignatureVersion", "2")+    , ("SignatureMethod", "HmacSHA256")+    , ("Timestamp", H.urlEncode True $ awsTimeFormat time)+    , ("AWSAccessKeyId", accessKey cred)+    ]++mkUrl :: ByteString+      -> Credential+      -> UTCTime+      -> ByteString+      -> [QueryParam]+      -> ByteString+      -> ByteString+mkUrl ep cred time action params ver = mconcat+    [ "https://"+    , ep+    , "/?"+    , qparam+    , "&Signature="+    , signature ep (secretAccessKey cred) qparam+    ]+  where+    qheader = Map.fromList $ queryHeader action time cred ver+    qparam = queryStr $ Map.unions (qheader : map toArrayParams params)++toArrayParams :: QueryParam -> Map ByteString ByteString+toArrayParams (ArrayParams name params) = Map.fromList +    [ (textToBS name <> "." <> bsShow i, textToBS param)+    | (i, param) <- zip ([1..]::[Int]) params++    ]+toArrayParams (FilterParams kvs) =+    Map.fromList . concat . map f1 $ zip ([1..]::[Int]) kvs+  where+    f1 (n, (key, vals)) = (filt n <> ".Name", textToBS key) :+        [ (filt n <> ".Value." <> bsShow i, textToBS param)+        | (i, param) <- zip ([1..]::[Int]) vals+        ]+    filt n = "Filter." <> bsShow n+toArrayParams (ValueParam k v) =+    Map.singleton (textToBS k) (textToBS v)+toArrayParams (StructArrayParams name vss) = Map.fromList l+  where+    bsName = textToBS name+    struct n (k, v) = (n <> "." <> textToBS k, textToBS v)+    l = mconcat+        [ map (struct (bsName <> "." <> bsShow i)) kvs+        | (i, kvs) <- zip ([1..]::[Int]) vss+        ]++queryStr :: Map ByteString ByteString -> ByteString+queryStr = BS.intercalate "&" . Map.foldrWithKey' concatWithEqual []+  where+    concatWithEqual key val acc = key <> "=" <> val : acc++awsTimeFormat :: UTCTime -> ByteString+awsTimeFormat = BSC.pack . formatTime defaultTimeLocale (iso8601DateFormat $ Just "%XZ")++signature+    :: ByteString -> SecretAccessKey -> ByteString -> ByteString+signature ep secret query = urlstr+  where+    stringToSign = "GET\n" <> ep <> "\n/\n" <> query+    signedStr = toS . SHA.bytestringDigest $ SHA.hmacSha256 (toL secret) (toL stringToSign)+    urlstr = H.urlEncode True . BASE.encode $ signedStr++checkStatus' ::+    H.Status -> H.ResponseHeaders -> Maybe SomeException+checkStatus' = \s@(H.Status sci _) hs ->+    if 200 <= sci && sci < 300 || 400 <= sci+        then Nothing+        else Just $ toException $ HTTP.StatusCodeException s hs++clientError+    :: (MonadResource m, MonadBaseControl IO m)+    => Int+    -> ResumableSource m ByteString+    -> (Int -> GLSink Event m a)+    -> m a+clientError status rsrc errSink =+    rsrc $$+- XmlP.parseBytes XmlP.def =$ errSink status++requestQuery+    :: (MonadResource m, MonadBaseControl IO m)+    => Credential+    -> AWSContext+    -> ByteString+    -> [QueryParam]+    -> ByteString+    -> (Int -> GLSink Event m a)+    -> m (ResumableSource m ByteString)+requestQuery cred ctx action params ver errSink = do+    let mgr = manager ctx+    let ep = endpoint ctx+    time <- liftIO getCurrentTime+    let url = mkUrl ep cred time action params ver+    request <- liftIO $ HTTP.parseUrl (BSC.unpack url)+    let req = request { HTTP.checkStatus = checkStatus' }+    response <- HTTP.http req mgr+    let body = HTTP.responseBody response+    let st = H.statusCode $ HTTP.responseStatus response+    if st < 400+        then return body+        else do+            clientError st body errSink+            fail "not reached"
+ AWS/RDS.hs view
@@ -0,0 +1,202 @@+{-# LANGUAGE FlexibleContexts, RankNTypes #-}++module AWS.RDS+    ( -- * RDS Environment+      RDS+    , runRDS+    , setRegion+      -- * DBInstance+    , describeDBInstances+    ) where++import Data.ByteString (ByteString)+import Data.Text (Text)+import Data.Conduit+import Control.Applicative+import Control.Monad.Trans.Control (MonadBaseControl)+import Control.Monad.Trans.Class (lift)+import Control.Monad.IO.Class (MonadIO)+import qualified Control.Monad.State as State+import qualified Control.Monad.Reader as Reader+import qualified Network.HTTP.Conduit as HTTP+import Data.Monoid ((<>))+import qualified Text.XML.Stream.Parse as XML+import Data.XML.Types (Event(..))+import Data.Maybe (catMaybes)++import AWS.Class+import AWS.Util+import AWS.Lib.Query+import AWS.Lib.Parser++import AWS+import AWS.RDS.Types++--import qualified Data.Conduit.Binary as CB++apiVersion :: ByteString+apiVersion = "2012-09-17"++type RequestId = Text++type RDS m a = AWS AWSContext m a++initialRDSContext :: HTTP.Manager -> AWSContext+initialRDSContext mgr = AWSContext+    { manager = mgr+    , endpoint = "rds.amazonaws.com"+    , lastRequestId = Nothing+    }++runRDS :: MonadIO m => Credential -> RDS m a -> m a+runRDS = runAWS initialRDSContext++describeDBInstances+    :: (MonadBaseControl IO m, MonadResource m)+    => Maybe Text -- ^ DBInstanceIdentifier+    -> Maybe Int -- ^ MaxRecords+    -> Maybe Text -- ^ Marker+    -> RDS m [DBInstance]+describeDBInstances dbid maxRecords marker = do+    ctx <- State.get+    cred <- Reader.ask+    rs <- lift $ requestQuery cred ctx (textToBS action) params apiVersion undefined+--    lift $ rs $$+- CB.sinkFile "debug.txt" >> fail "debug"+    (res, rid) <- lift $ rs $$+- XML.parseBytes XML.def =$ do+        sinkResponse action $ sinkDBInstances+    State.put ctx { lastRequestId = Just rid }+    return res+  where+    action = "DescribeDBInstances"+    mk name = maybe [] (\a -> [ValueParam name a])+    params = uncurry mk =<<+        [ ("DBInstanceIdentifier", dbid)+        , ("MaxRecords", toText <$> maxRecords)+        , ("Marker", marker)+        ]++elements :: MonadThrow m+    => Text+    -> GLSink Event m a+    -> GLSink Event m [a]+elements name f = element (name <> "s") $ listConsumer name f++sinkDBInstances+    :: MonadThrow m+    => GLSink Event m [DBInstance]+sinkDBInstances = elements "DBInstance" $+    DBInstance+    <$> getM "Iops" (textToInt <$>)+    <*> getF "BackupRetentionPeriod" textToInt+    <*> getF "MultiAZ" textToBool+    <*> getT "DBInstanceStatus"+    <*> getT "DBInstanceIdentifier"+    <*> getT "PreferredBackupWindow"+    <*> getT "PreferredMaintenanceWindow"+    <*> elementM "OptionGroupMembership"+        (OptionGroupMembership+        <$> getT "OptionGroupName"+        <*> getT "Status"+        )+    <*> getT "AvailabilityZone"+    <*> getM "LatestRestorableTime" (textToTime <$>)+    <*> elements "ReadReplicaDBInstanceIdentifier" text+    <*> getT "Engine"+    <*> sinkPendingModifiedValues+    <*> getMT "CharacterSetName"+    <*> getT "LicenseModel"+    <*> elementM "DBSubnetGroup"+        (DBSubnetGroup+        <$> getT "VpcId"+        <*> getT "SubnetGroupStatus"+        <*> getT "DBSubnetGroupDescription"+        <*> getT "DBSubnetGroupName"+        <*> elements "Subnet"+            (Subnet+            <$> getT "SubnetStatus"+            <*> getT "SubnetIdentifier"+            <*> element "SubnetAvailabilityZone"+                (AvailabilityZone+                <$> getT "Name"+                <*> getF "ProvisionedIopsCapable" textToBool+                )+            )+        )+    <*> elements "DBParameterGroup"+        (DBParameterGroupStatus+        <$> getT "ParameterApplyStatus"+        <*> getT "DBParameterGroupName"+        )+    <*> elementM "Endpoint"+        (Endpoint+        <$> getF "Port" textToInt+        <*> getT "Address"+        )+    <*> getT "EngineVersion"+    <*> getMT "ReadReplicaSourceDBInstanceIdentifier"+    <*> elements "DBSecurityGroup"+        (DBSecurityGroupMembership+        <$> getT "Status"+        <*> getT "DBSecurityGroupName"+        )+    <*> getMT "DBName"+    <*> getF "AutoMinorVersionUpgrade" textToBool+    <*> getM "InstanceCreateTime" (textToTime <$>)+    <*> getF "AllocatedStorage" textToInt+    <*> getT "DBInstanceClass"+    <*> getT "MasterUsername" ++sinkPendingModifiedValues+    :: MonadThrow m+    => GLSink Event m [PendingModifiedValue]+sinkPendingModifiedValues = element "PendingModifiedValues" $+    catMaybes <$> sequence [ m "MasterUserPassword" PMVMasterUserPassword+        , m "Iops" (PMVIops . textToInt)+        , m "MultiAZ" (PMVMultiAZ . textToBool)+        , m "AllocatedStorage" (PMVAllocatedStorage . textToInt)+        , m "EngineVersion" PMVEngineVersion+        , m "DBInstanceClass" PMVDBInstanceClass+        , m "BackupRetentionPeriod"+            (PMVBackupRetentionPeriod . textToInt)+        , m "Port" (PMVPort . textToInt)+        ]+  where+    m t f = getM t (f <$>)++sinkResponse+    :: MonadThrow m+    => Text -- ^ Action+    -> GLSink Event m a+    -> GLSink Event m (a, RequestId)+sinkResponse action sink = do+    sinkEventBeginDocument+    element (action <> "Response") $ (,)+        <$> element (action <> "Result") sink -- XXX: parse Marker+        <*> sinkResponseMetadata++sinkResponseMetadata+    :: MonadThrow m+    => GLSink Event m Text+sinkResponseMetadata =+    element "ResponseMetadata" $+        getT "RequestId"++sinkEventBeginDocument+    :: MonadThrow m+    => GLSink Event m ()+sinkEventBeginDocument = do+    me <- await+    case me of+        Nothing -> return ()+        Just EventBeginDocument -> return ()+        Just _ -> fail $ "unexpected: " <> show me++setRegion+    :: (MonadBaseControl IO m, MonadResource m)+    => Text -> RDS m ()+setRegion region = do+    ctx <- State.get+    State.put+        ctx { endpoint =+            "rds." <> textToBS region <> ".amazonaws.com"+            }
+ AWS/RDS/Types.hs view
@@ -0,0 +1,93 @@+module AWS.RDS.Types+    where++import Data.Text (Text)+import Data.Time (UTCTime)++data DBInstance = DBInstance+    { dbiIops :: Maybe Int+    , dbiBackupRetentionPeriod :: Int+    , dbiMultiAZ :: Bool+    , dbiDBInstanceStatus :: Text+    , dbiDBInstanceIdentifier :: Text+    , dbiPreferredBackupWindow :: Text+    , dbiPreferredMaintenanceWindow :: Text+    , dbiOptionGroupMembership :: Maybe OptionGroupMembership+    , dbiAvailabilityZone :: Text+    , dbiLatestRestorableTime :: Maybe UTCTime+    , dbiReadReplicaDBInstanceIdentifiers :: [Text]+    , dbiEngine :: Text+    , dbiPendingModifiedValues :: [PendingModifiedValue]+    , dbiCharacterSetName :: Maybe Text+    , dbiLicenseModel :: Text+    , dbiSubnetGroup :: Maybe DBSubnetGroup+    , dbiDBParameterGroups :: [DBParameterGroupStatus]+    , dbiEndpoint :: Maybe Endpoint+    , dbiEngineVersion :: Text+    , dbiReadReplicaSourceDBInstanceIdentifier :: Maybe Text+    , dbiSecurityGroups :: [DBSecurityGroupMembership]+    , dbiDBName :: Maybe Text+    , dbiAutoMinorVersionUpgrade :: Bool+    , dbiInstanceCreateTime :: Maybe UTCTime+    , dbiAllocatedStorage :: Int -- ^ storage size in gigabytes+    , dbiDBInstanceClass :: Text+    , dbiMasterUsername :: Text+    }+  deriving (Show)++data DBParameterGroupStatus = DBParameterGroupStatus+    { dbpgsParameterApplyStatus :: Text+    , dbpgsDBParameterGroupName :: Text+    }+  deriving (Show)++data DBSecurityGroupMembership = DBSecurityGroupMembership+    { dbsgmStatus :: Text+    , dbsgmDBSecurityGroupName :: Text+    }+  deriving (Show)++data DBSubnetGroup = DBSubnetGroup+    { dbsngVpcId :: Text+    , dbsngSubnetGroupStatus :: Text+    , dbsngDBSubnetGroupDescription :: Text+    , dbsngDBSubnetGroupName :: Text+    , dbsngSubnets :: [Subnet]+    }+  deriving (Show)++data Subnet = Subnet+    { subnetStatus :: Text+    , subnetIdentifier :: Text+    , subnetAvailabilityZone :: AvailabilityZone+    }+  deriving (Show)++data AvailabilityZone = AvailabilityZone+    { azName :: Text+    , azProvisionedIopsCapable :: Bool+    }+  deriving (Show)++data Endpoint = Endpoint+    { epPort :: Int+    , epAddress :: Text+    }+  deriving (Show)++data OptionGroupMembership = OptionGroupMembership+    { ogmOptionGroupName :: Text+    , ogmStatus :: Text+    }+  deriving (Show)++data PendingModifiedValue+    = PMVAllocatedStorage Int+    | PMVBackupRetentionPeriod Int+    | PMVDBInstanceClass Text+    | PMVEngineVersion Text+    | PMVIops Int+    | PMVMasterUserPassword Text+    | PMVMultiAZ Bool+    | PMVPort Int+  deriving (Show)
AWS/Types.hs view
@@ -1,18 +1,3 @@ {-# LANGUAGE OverloadedStrings #-}-module AWS.Types-    ( Endpoint (..)-    , EC2Endpoint (..)-    ) where--import Data.ByteString (ByteString)-import Data.ByteString.Char8 ()--class Endpoint a where-    endpointStr :: a -> ByteString--data EC2Endpoint = UsEast1-                 | ApNortheast1+module AWS.Types where -instance Endpoint EC2Endpoint where-    endpointStr UsEast1      = "ec2.us-east-1.amazonaws.com"-    endpointStr ApNortheast1 = "ec2.ap-northeast-1.amazonaws.com"
aws-sdk.cabal view
@@ -1,5 +1,5 @@ name:                aws-sdk-version:             0.2.0.0+version:             0.3.0.0 synopsis:            AWS SDK for Haskell description:         An AWS(Amazon Web Services) liblary for Haskell. license:             BSD3@@ -17,9 +17,13 @@                    , AWS.Types                    , AWS.EC2                    , AWS.EC2.Types-                   , AWS.EC2.Utils+                   , AWS.EC2.Util+                   , AWS.RDS+                   , AWS.RDS.Types   other-modules:     AWS.Util                    , AWS.Credential+                   , AWS.Class+                   , AWS.EC2.Internal                    , AWS.EC2.Address                    , AWS.EC2.AvailabilityZone                    , AWS.EC2.Image@@ -32,10 +36,10 @@                    , AWS.EC2.Query                    , AWS.EC2.Region                    , AWS.EC2.Tag-                   , AWS.EC2.Class                    , AWS.EC2.Parser-                   , AWS.EC2.Parser.Internal                    , AWS.EC2.Params+                   , AWS.Lib.Parser+                   , AWS.Lib.Query   ghc-options:       -Wall                      -fno-warn-unused-do-bind   extensions: OverloadedStrings