Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Route53 #25

Open
wants to merge 64 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
be41526
Initial bits for Route53
Apr 21, 2012
a909780
Fix aws.cabal add missing Aws/Route53.hs
Apr 21, 2012
047c8dc
Aws/Query: add instance Show SignedQuery
Apr 22, 2012
5d12ef0
Route53: Proof of concept by ListHostedZones
Apr 22, 2012
e4dc974
Route53/Commands: Add GetDate and GetHostedZone.
Apr 22, 2012
f21bad2
Aws/Route53/Query: Add a TODO comment
Apr 22, 2012
fa4ba9f
Route53/GetHostedZone: Fail Gracefully if there is no HostedZone in t…
Apr 22, 2012
e215c2c
Route53: add route53ApiVersion to Route53Info
Apr 22, 2012
2e9c862
Route53: add class Route53Parseable, add types for ResourceRecordSets.
Apr 23, 2012
552b9fc
Route53: small code cleanup in Commands.ListHostedZones
Apr 23, 2012
0677bfc
Route53: added command GET ListResourceRecordSets
Apr 23, 2012
212d4ac
Route53: improve documentation
Apr 24, 2012
bdf814f
Route53: add command GetChange
Apr 24, 2012
57a5819
Route53: make Method a query parameter
Apr 24, 2012
bfdf885
Route53: add command DeleteHostedZone
Apr 24, 2012
32cf87e
Route53: add command CreateHosted Zone; some code cleanup
Apr 25, 2012
ecfac96
Route53: add crude proof of concept implementation of ChangeResourceR…
Apr 25, 2012
6dc3d7f
Route53: introduce class Route53Id and newtype wrappers for HostedZon…
May 1, 2012
08caa3c
Route53: fix nameing of record fields in ListResourceRecordSets
May 1, 2012
5701f77
Route53: export Route53Id and use it in ListResourceRecordSets.
May 4, 2012
06342bd
Merge
May 4, 2012
45111b4
Route53: convert to new module layout scheme
May 4, 2012
953284f
Route53: fix Aws.Route53 to not export the modules of the old scheme
May 4, 2012
00ae58d
Route53: fix prefix in Route53Id instance of ChangeId
May 4, 2012
69f613d
Route53: more pointless encoding of resource in ListResourceRecordSet…
May 4, 2012
1caec01
Route53: actually use ChangeId in GetChange
May 4, 2012
9a7dd34
Route35: use HostedZoneId in GetHostedZone and ChangeResourceRecordSets
May 4, 2012
911aa8a
Route53: Fix xmlns in ChangeResourceRecordSets request body
May 4, 2012
36a4466
Route53: remove dependency on Network.DNS.Types and fix xmlns in requ…
May 5, 2012
aa8e755
Route53: fix spelling of request body xml namespace.
May 5, 2012
2062c62
Route53: code usage examples for Aws.Route53 module.
May 5, 2012
ddb7cec
ghci.hs: import Aws.Route53
May 5, 2012
a627017
Route53: fix formating of LANGUAGE pragma
May 5, 2012
348f9b1
Route53: add copyright notice to all file in Aws/Route53
May 5, 2012
3af90f1
Route53: some cleanup of comments
May 5, 2012
578c26a
Merge
May 31, 2012
6cbaccd
Merge
May 31, 2012
d7b0991
Merge
May 31, 2012
5905227
Merge
May 31, 2012
65c492d
Route53: Add missing language pragma in Core.hs
Jun 1, 2012
8be9806
Merge
Jul 12, 2012
b9b16ba
Add Route53.Commands.ChangeResourceRecordSets to Exposed-modules
Jul 12, 2012
5bad4e3
Assign Route53 Copyright to AlephCloud Systems, Inc.
Jul 13, 2012
c9d683b
Fix and clean up Route53 example.
Jul 13, 2012
7ae14f9
Some Route53 code cleanup.
Jul 13, 2012
815be70
Route53: minor code cleanup in Route53.Samples.
Jul 13, 2012
316e5c8
Merge
Jul 13, 2012
4e9288d
Merge
Jul 18, 2012
caaf0fd
Route53Examples: Add setARecord and a slightly improved exception han…
Jul 20, 2012
433ebef
Port Route53Examples to use IteratedTransaction.
Jul 20, 2012
2a0f584
Add DynDNS client as Route53 example. Move Route53 into subdirectory.
Jul 24, 2012
88527cf
Add AlephCloud copyright to Route53 DynDNS example
Jul 24, 2012
2e62ce9
Examples.Route53: allow to choose AWS key on the command line
Jul 24, 2012
ecbff2e
Examples.Route53: Add log-file argument to DynDNS.
Jul 25, 2012
9c14e77
Examples.Route53: Rename DynDNS into r53-dyndns.
Jul 28, 2012
731969d
Examples.Route53: cabalize r53-dyndns.
Jul 28, 2012
53d73f2
Examples.Route53: Add missing upstart script for r53-dyndns.
Jul 28, 2012
ca59ed2
Examples.Route53: Fix r53-dyndns startup script.
Jul 29, 2012
8178a17
Examples.Route53: make subdomain arg of r53-dyndns optional
Jul 30, 2012
3933df0
Examples.Route53: fix typo in r53-dyndns startup script
Jul 30, 2012
be4d821
Examples.Route53: fix r53-dyndns to not deleted the wrong DNS records.
Aug 9, 2012
29ccfba
Examples.Route53: more bug fixes and cleanup for r53-dyndns.
Aug 9, 2012
9325a69
Examples.Route53: add TOCO section to README.md
Aug 9, 2012
44aee75
merge
Aug 9, 2012
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Aws/Route53.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- ------------------------------------------------------ --
-- Copyright © 2012 AlephCloud Systems, Inc.
-- ------------------------------------------------------ --

module Aws.Route53
( module Aws.Route53.Commands
, module Aws.Route53.Core
)
where

import Aws.Route53.Commands
import Aws.Route53.Core
30 changes: 30 additions & 0 deletions Aws/Route53/Commands.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-- ------------------------------------------------------ --
-- Copyright © 2012 AlephCloud Systems, Inc.
-- ------------------------------------------------------ --

module Aws.Route53.Commands
( -- * Actions on Hosted Zones
module Aws.Route53.Commands.CreateHostedZone
, module Aws.Route53.Commands.GetHostedZone
, module Aws.Route53.Commands.DeleteHostedZone
, module Aws.Route53.Commands.ListHostedZones

-- * Actions on Resource Record Sets
, module Aws.Route53.Commands.ChangeResourceRecordSets
, module Aws.Route53.Commands.ListResourceRecordSets
, module Aws.Route53.Commands.GetChange

-- * Other Commands
, module Aws.Route53.Commands.GetDate
)
where

import Aws.Route53.Commands.CreateHostedZone
import Aws.Route53.Commands.GetHostedZone
import Aws.Route53.Commands.DeleteHostedZone
import Aws.Route53.Commands.ListHostedZones
import Aws.Route53.Commands.ChangeResourceRecordSets
import Aws.Route53.Commands.ListResourceRecordSets
import Aws.Route53.Commands.GetChange
import Aws.Route53.Commands.GetDate

67 changes: 67 additions & 0 deletions Aws/Route53/Commands/ChangeResourceRecordSets.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
-- ------------------------------------------------------ --
-- Copyright © 2012 AlephCloud Systems, Inc.
-- ------------------------------------------------------ --

-- | POST ChangeResourceRecordSetrs
--
-- Creates, changes, or deletes resource records sets.
--
-- <http://docs.amazonwebservices.com/Route53/latest/APIReference/API_ChangeResourceRecordSets.html>
--
module Aws.Route53.Commands.ChangeResourceRecordSets where

import Aws.Route53.Core
import Aws.Core
import Text.Hamlet.XML (xml)
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import Data.Map (empty)
import qualified Text.XML as XML
import qualified Data.ByteString as B

data ACTION = CREATE | DELETE
deriving (Show)

-- TODO enforce constrains either via type or dynamically on creation or usage
data ChangeResourceRecordSets = ChangeResourceRecordSets
{ crrHostedZoneId :: HostedZoneId
, crrComment :: Maybe T.Text
, crrsChanges :: [(ACTION, ResourceRecordSet)]
} deriving (Show)

data ChangeResourceRecordSetsResponse = ChangeResourceRecordSetsResponse
{ crrsrChangeInfo :: ChangeInfo
} deriving (Show)

-- | ServiceConfiguration: 'Route53Configuration'
instance SignQuery ChangeResourceRecordSets where
type ServiceConfiguration ChangeResourceRecordSets = Route53Configuration
signQuery ChangeResourceRecordSets{..} = route53SignQuery method resource query body
where
method = Post
resource = (T.encodeUtf8 . qualifiedIdText) crrHostedZoneId `B.append` "/rrset"
query = []
body = Just $ XML.Element "ChangeResourceRecordSetsRequest" empty
[xml|
<ChangeBatch>
$maybe c <- crrComment
<Comment>#{c}
<Changes>
$forall change <- crrsChanges
<Change>
<Action>#{T.pack (show (fst change))}
^{[XML.NodeElement (toXml (snd change))]}
|]

instance ResponseConsumer r ChangeResourceRecordSetsResponse where
type ResponseMetadata ChangeResourceRecordSetsResponse = Route53Metadata

responseConsumer _ = route53ResponseConsumer parse
where
parse cursor = do
route53CheckResponseType () "ChangeResourceRecordSetsResponse" cursor
changeInfo <- r53Parse cursor
return $ ChangeResourceRecordSetsResponse changeInfo

instance Transaction ChangeResourceRecordSets ChangeResourceRecordSetsResponse

64 changes: 64 additions & 0 deletions Aws/Route53/Commands/CreateHostedZone.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
-- ------------------------------------------------------ --
-- Copyright © 2012 AlephCloud Systems, Inc.
-- ------------------------------------------------------ --

-- | POST CreateHostedZone
--
-- Create a new Route53 hosted zone.
--
-- <http://docs.amazonwebservices.com/Route53/latest/APIReference/API_CreateHostedZone.html>
--
module Aws.Route53.Commands.CreateHostedZone where

import Aws.Core
import Aws.Route53.Core
import Text.Hamlet.XML (xml)
import qualified Data.Text as T
import Data.Map (empty)
import qualified Text.XML as XML

data CreateHostedZone = CreateHostedZone
{ chzName :: Domain
, chzCallerReference :: T.Text
, chzComment :: T.Text
} deriving (Show)

data CreateHostedZoneResponse = CreateHostedZoneResponse
{ chzrHostedZone :: HostedZone
, chzrChangeInfo :: ChangeInfo
, chzrDelegationSet :: DelegationSet
} deriving (Show)

createHostedZone :: Domain -> T.Text -> T.Text -> CreateHostedZone
createHostedZone name callerReference comment = CreateHostedZone name callerReference comment

-- | ServiceConfiguration: 'Route53Configuration'
instance SignQuery CreateHostedZone where
type ServiceConfiguration CreateHostedZone = Route53Configuration
signQuery CreateHostedZone{..} = route53SignQuery method resource query body
where
method = Post
resource = "/hostedzone"
query = []
body = Just $ XML.Element "CreateHostedZoneRequest" empty
[xml|
<Name>#{dText chzName}
<CallerReference>#{chzCallerReference}
<HostedZoneConfig>
<Comment>#{chzComment}
|]

instance ResponseConsumer r CreateHostedZoneResponse where
type ResponseMetadata CreateHostedZoneResponse = Route53Metadata

responseConsumer _ = route53ResponseConsumer parse
where
parse cursor = do
route53CheckResponseType () "GetHostedZoneResponse" cursor
zone <- r53Parse cursor
changeInfo <- r53Parse cursor
delegationSet <- r53Parse cursor
return $ CreateHostedZoneResponse zone changeInfo delegationSet

instance Transaction CreateHostedZone CreateHostedZoneResponse

57 changes: 57 additions & 0 deletions Aws/Route53/Commands/DeleteHostedZone.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
-- ------------------------------------------------------ --
-- Copyright © 2012 AlephCloud Systems, Inc.
-- ------------------------------------------------------ --

-- | DELETE DeleteHostedZone
--
-- Delete a particular Route53 hosted zone identified through its 'hostedZoneId'.
-- The HostedZoneId is obtained in the response to 'Aws.Route53.Commands.CreateHostedZone'
-- or 'Aws.Route53.Commands.ListHostedZones'
--
-- Note that the hosted zone can be delete only after deleting all resource records other than
-- the default SOA record and the NS records.
--
-- <http://docs.amazonwebservices.com/Route53/latest/APIReference/API_DeleteHostedZone.html>
--
module Aws.Route53.Commands.DeleteHostedZone where

import Aws.Core
import Aws.Route53.Core
import qualified Data.Text.Encoding as T

data DeleteHostedZone = DeleteHostedZone
{ dhzHostedZoneId :: HostedZoneId
} deriving (Show)

data DeleteHostedZoneResponse = DeleteHostedZoneResponse
{ dhzrChangeInfo :: ChangeInfo
} deriving (Show)

deleteHostedZone :: HostedZoneId -> DeleteHostedZone
deleteHostedZone hostedZoneId = DeleteHostedZone hostedZoneId

-- Delete add convenience methods:
-- * Delete non-empty hosted zone

-- | ServiceConfiguration: 'Route53Configuration'
instance SignQuery DeleteHostedZone where
type ServiceConfiguration DeleteHostedZone = Route53Configuration
signQuery DeleteHostedZone{..} = route53SignQuery method resource query body
where
method = Delete
resource = T.encodeUtf8 . qualifiedIdText $ dhzHostedZoneId
query = []
body = Nothing

instance ResponseConsumer r DeleteHostedZoneResponse where
type ResponseMetadata DeleteHostedZoneResponse = Route53Metadata

responseConsumer _ = route53ResponseConsumer parse
where
parse cursor = do
route53CheckResponseType () "DeleteHostedZoneResponse" cursor
changeInfo <- r53Parse cursor
return $ DeleteHostedZoneResponse changeInfo

instance Transaction DeleteHostedZone DeleteHostedZoneResponse

49 changes: 49 additions & 0 deletions Aws/Route53/Commands/GetChange.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
-- ------------------------------------------------------ --
-- Copyright © 2012 AlephCloud Systems, Inc.
-- ------------------------------------------------------ --

-- | GET GetChange
--
-- Returns the current status of change batch request.
--
-- <http://docs.amazonwebservices.com/Route53/latest/APIReference/API_GetChange.html>
--
module Aws.Route53.Commands.GetChange where

import Aws.Core
import Aws.Route53.Core
import qualified Data.Text.Encoding as T

data GetChange = GetChange
{ changeId :: ChangeId
} deriving (Show)

data GetChangeResponse = GetChangeResponse
{ gcrChangeInfo :: ChangeInfo
} deriving (Show)

getChange :: ChangeId -> GetChange
getChange changeId = GetChange changeId

-- | ServiceConfiguration: 'Route53Configuration'
instance SignQuery GetChange where
type ServiceConfiguration GetChange = Route53Configuration
signQuery GetChange{..} = route53SignQuery method resource query body
where
method = Get
resource = T.encodeUtf8 . qualifiedIdText $ changeId
query = []
body = Nothing

instance ResponseConsumer r GetChangeResponse where
type ResponseMetadata GetChangeResponse = Route53Metadata

responseConsumer _ = route53ResponseConsumer parse
where
parse cursor = do
route53CheckResponseType () "GetChangeResponse" cursor
changeInfo <- r53Parse cursor
return $ GetChangeResponse changeInfo

instance Transaction GetChange GetChangeResponse

61 changes: 61 additions & 0 deletions Aws/Route53/Commands/GetDate.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
-- ------------------------------------------------------ --
-- Copyright © 2012 AlephCloud Systems, Inc.
-- ------------------------------------------------------ --

-- | GET GetDate
--
-- Receive current date string from Route53 service that can be used as date string for
-- authenticating REST requests to Route53.
--
-- <http://docs.amazonwebservices.com/Route53/latest/DeveloperGuide/RESTAuthentication.html>
--
module Aws.Route53.Commands.GetDate where

import Aws.Core
import Aws.Route53.Core
import Data.Maybe
import Data.Time (UTCTime)
import Data.Time.Format (parseTime)
import System.Locale (defaultTimeLocale)
import Data.ByteString.Char8 (unpack)
import qualified Network.HTTP.Types as HTTP

data GetDate = GetDate deriving (Show)

newtype GetDateResponse = GetDateResponse { date :: UTCTime } deriving (Show)

-- | ServiceConfiguration: 'Route53Configuration'
instance SignQuery GetDate where
type ServiceConfiguration GetDate = Route53Configuration
signQuery GetDate info sd = SignedQuery
{ sqMethod = Get
, sqProtocol = route53Protocol info
, sqHost = route53Endpoint info
, sqPort = route53Port info
, sqPath = "/date/"
, sqQuery = []
, sqDate = Just $ signatureTime sd
, sqAuthorization = Nothing
, sqContentType = Nothing
, sqContentMd5 = Nothing
, sqAmzHeaders = []
, sqOtherHeaders = []
, sqBody = Nothing
, sqStringToSign = ""
}

instance ResponseConsumer r GetDateResponse where
type ResponseMetadata GetDateResponse = ()
responseConsumer _ _ _ headers _ = return $ GetDateResponse date
where
-- TODO add proper error handling
date = fromJust $ do
str <- findHeaderValue headers HTTP.hDate
-- FIXME: this is probably to restrictive. We should support full rfc1123
parseTime defaultTimeLocale "%a, %d %b %Y %H:%M:%S %Z" (unpack str)

getDate :: GetDate
getDate = GetDate

instance Transaction GetDate GetDateResponse

52 changes: 52 additions & 0 deletions Aws/Route53/Commands/GetHostedZone.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
-- ------------------------------------------------------ --
-- Copyright © 2012 AlephCloud Systems, Inc.
-- ------------------------------------------------------ --

-- | GET GetHostedZone
--
-- Get a particular Route53 hosted zone identified through its 'hostedZoneId'.
-- The HostedZoneId is obtained in the response to 'Aws.Route53.Commands.CreateHostedZone'
-- or 'Aws.Route53.Commands.ListHostedZones'
--
-- <http://docs.amazonwebservices.com/Route53/latest/APIReference/API_GetHostedZone.html>
--
module Aws.Route53.Commands.GetHostedZone where

import Aws.Core
import Aws.Route53.Core
import qualified Data.Text.Encoding as T

data GetHostedZone = GetHostedZone
{ hostedZoneId :: HostedZoneId
} deriving (Show)

data GetHostedZoneResponse = GetHostedZoneResponse
{ ghzrHostedZone :: HostedZone
, ghzrDelegationSet :: DelegationSet
} deriving (Show)

getHostedZone :: HostedZoneId -> GetHostedZone
getHostedZone hostedZoneId = GetHostedZone hostedZoneId

-- | ServiceConfiguration: 'Route53Configuration'
instance SignQuery GetHostedZone where
type ServiceConfiguration GetHostedZone = Route53Configuration
signQuery GetHostedZone{..} = route53SignQuery method resource query Nothing
where
method = Get
resource = T.encodeUtf8 . qualifiedIdText $ hostedZoneId
query = []

instance ResponseConsumer r GetHostedZoneResponse where
type ResponseMetadata GetHostedZoneResponse = Route53Metadata

responseConsumer _ = route53ResponseConsumer parse
where
parse cursor = do
route53CheckResponseType () "GetHostedZoneResponse" cursor
zone <- r53Parse cursor
delegationSet <- r53Parse cursor
return $ GetHostedZoneResponse zone delegationSet

instance Transaction GetHostedZone GetHostedZoneResponse

Loading