-- | -- Module: PowerDNS.Client -- Description: Servant client functions and utilities to interact with a PowerDNS Server -- -- All the endpoints provide only a very slim wrapper around the PowerDNS API preserving -- its idiosyncracies. {-# LANGUAGE OverloadedStrings #-} module PowerDNS.Client ( -- * Authentication applyXApiKey -- * Version , listVersions , Version(..) -- * Zones -- -- | See documentation at [PowerDNS Zones API](https://doc.powerdns.com/authoritative/http-api/zone.html) -- -- Because the required fields of a 'Zone' differs between various requests and responses, every field -- is wrapped with Maybe. It is the users responsibility to check with the PowerDNS API to know when a -- field must be specified. For convenience 'empty' can be used to generate a value of 'Zone' with all -- fields set to 'Nothing'. -- -- @ -- let zone = empty { zone_name = Just "some.domain." -- , zone_kind = Just Native -- , zone_type = Just "zone" } -- -- in createZone "localhost" -- Server ID -- Nothing -- Show RRsets in response -- zone -- The zone we are creating -- @ , listZones , createZone , getZone , deleteZone , updateRecords , updateZone , triggerAxfr , notifySlaves , getZoneAxfr , rectifyZone -- ** Data types , Zone(..) , Kind(..) , RRSets(..) , RRSet(..) , Record(..) , Comment(..) , ChangeType(..) , RecordType(..) -- * Cryptokeys -- | See documentation at [PowerDNS Cryptokeys API](https://doc.powerdns.com/authoritative/http-api/cryptokey.html) , listCryptoKeys , createCryptokey , getCryptokey , updateCryptokey , deleteCryptokey -- ** Data types , Cryptokey -- * Servers -- | See documentation at [PowerDNS Servers API](https://doc.powerdns.com/authoritative/http-api/server.html) -- -- Also contains [PowerDNS Search API](https://doc.powerdns.com/authoritative/http-api/search.html) -- and [PowerDNS Cache API](https://doc.powerdns.com/authoritative/http-api/cache.html) , listServers , getServer , search , flushCache , statistics -- ** Data types , Server(..) , SearchResult(..) , ObjectType(..) , CacheFlushResult(..) -- * Metadata -- | See documentation at [PowerDNS Metadata API](https://doc.powerdns.com/authoritative/http-api/metadata.html) , listMetadata , createMetadata , getMetadata , updateMetadata , deleteMetadata -- ** Data types , Metadata(..) -- * TSIGKeys -- | See documentation at [PowerDNS TSIGKeys API](https://doc.powerdns.com/authoritative/http-api/metadata.html) -- as well as related [TSIG documentation](https://doc.powerdns.com/authoritative/tsig.html) , listTSIGKeys , createTSIGKey , getTSIGKey , updateTSIGKey , deleteTSIGKey -- ** Data types , TSIGKey(..) , TSIGAlgorithm(..) -- * Utilities , empty ) where import qualified Data.CaseInsensitive as CI import Data.Sequence ((|>)) import qualified Data.Text as T import qualified Data.Text.Encoding as T import Servant.API (NoContent) import Servant.API.Generic (fromServant) import Servant.Client (ClientEnv(..), ClientM, client) import Servant.Client.Core.Request (Request, requestHeaders) import Servant.Client.Generic (AsClientT) import PowerDNS.API import PowerDNS.Internal.Utils (empty) -- | Causes all requests with this 'ClientEnv' to be sent with the specified key embedded in a X-API-Key header. applyXApiKey :: T.Text -- ^ API key -> ClientEnv -> ClientEnv applyXApiKey key env = env { makeClientRequest = modified } where modified url = makeClientRequest env url . applyXApiKeyHeader key applyXApiKeyHeader :: T.Text -> Request -> Request applyXApiKeyHeader key req = req { requestHeaders = requestHeaders req |> authHeader } where authHeader = (CI.mk "X-API-Key", T.encodeUtf8 key) ---------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------- pdnsClient :: PowerDNS (AsClientT ClientM) pdnsClient = fromServant (client api) ---------------------------------------------------------------------------------------- versionsClient :: VersionsAPI (AsClientT ClientM) versionsClient = fromServant (versions pdnsClient) -- | List the API versions and urls from the server. This is an undocumented endpoint. listVersions :: ClientM [Version] listVersions = apiListVersions versionsClient ---------------------------------------------------------------------------------------- zonesClient :: ZonesAPI (AsClientT ClientM) zonesClient = fromServant (zones pdnsClient) -- | List all zones for the server. See [Zones API Documentation](https://doc.powerdns.com/authoritative/http-api/zone.html#get--servers-server_id-zones) listZones :: T.Text -- ^ Server name -> Maybe T.Text -- ^ Limit to zone -> Maybe Bool -- ^ Whether or not to include dnssec and edited_serial fields -> ClientM [Zone] listZones = apiListZones zonesClient -- | Create a new zone. See [Zones API Documentation](https://doc.powerdns.com/authoritative/http-api/zone.html#post--servers-server_id-zones) -- -- 'empty' with record update syntax is useful avoid having to specify Nothing -- for unwanted fields. createZone :: T.Text -- ^ Server name -> Maybe Bool -- ^ Whether or not to include RRsets in the response -> Zone -- ^ The zone to create -> ClientM Zone createZone = apiCreateZone zonesClient -- | Get details for zone. See [Zones API Documentation](https://doc.powerdns.com/authoritative/http-api/zone.html#get--servers-server_id-zones-zone_id) getZone :: T.Text -- ^ Server name -> T.Text -- ^ Zone ID -> Maybe Bool -- ^ Wheher or not to include RRsets in the response -> ClientM Zone getZone = apiGetZone zonesClient -- | Delete a given zone by id. See [Zones API Documentation](https://doc.powerdns.com/authoritative/http-api/zone.html#delete--servers-server_id-zones-zone_id) deleteZone :: T.Text -- ^ Server name -> T.Text -- ^ Zone ID -> ClientM NoContent deleteZone = apiDeleteZone zonesClient -- | Update records of a zone. See [Zones API Documentation](https://doc.powerdns.com/authoritative/http-api/zone.html#patch--servers-server_id-zones-zone_id) -- -- __Caution__: If rrset_records or rrset_comments is set to @Just []@ on a 'Delete' changetype, -- this will delete all existing records or comments respectively for the domain. updateRecords :: T.Text -- ^ Server name -> T.Text -- ^ Zone ID -> RRSets -- ^ The RRsets to create, update or delete. -> ClientM NoContent updateRecords = apiUpdateRecords zonesClient -- | Modify zone. See [Zones API Documentation](https://doc.powerdns.com/authoritative/http-api/zone.html#put--servers-server_id-zones-zone_id) -- -- 'empty' with record update syntax is useful avoid having to specify Nothing -- for unwanted fields. updateZone :: T.Text -- ^ Server name -> T.Text -- ^ Zone ID -> Zone -- ^ Patch record. Fields with Just are changed, Nothing are ignored -> ClientM NoContent updateZone = apiUpdateZone zonesClient -- | Trigger zone transfer on a slave. See [Zones API Documentation](https://doc.powerdns.com/authoritative/http-api/zone.html#put--servers-server_id-zones-zone_id-axfr-retrieve) triggerAxfr :: T.Text -- ^ Server name -> T.Text -- ^ Zone ID -> ClientM NoContent triggerAxfr = apiTriggerAxfr zonesClient -- | Send DNS notify to slaves. See [Zones API Documentation](https://doc.powerdns.com/authoritative/http-api/zone.html#put--servers-server_id-zones-zone_id-notify) notifySlaves :: T.Text -- ^ Server name -> T.Text -- ^ Zone ID -> ClientM NoContent notifySlaves = apiNotifySlaves zonesClient -- | Return zone in AXFR format. See [Zones API Documentation](https://doc.powerdns.com/authoritative/http-api/zone.html#get--servers-server_id-zones-zone_id-export) getZoneAxfr :: T.Text -- ^ Server name -> T.Text -- ^ Zone ID -> ClientM T.Text -- ^ Zone in AXFR format getZoneAxfr = apiGetZoneAxfr zonesClient -- | Rectify the zone data. See [Zones API Documentation](https://doc.powerdns.com/authoritative/http-api/zone.html#put--servers-server_id-zones-zone_id-rectify) rectifyZone :: T.Text -- ^ Server name -> T.Text -- ^ Zone ID -> ClientM T.Text rectifyZone = apiRectifyZone zonesClient ---------------------------------------------------------------------------------------- cryptokeysClient :: CryptokeysAPI (AsClientT ClientM) cryptokeysClient = fromServant (cryptokeys pdnsClient) -- | List all crypto keys. See [Cryptokeys API Documentation](https://doc.powerdns.com/authoritative/http-api/cryptokey.html#get--servers-server_id-zones-zone_id-cryptokeys) listCryptoKeys :: T.Text -- ^ Server name -> T.Text -- ^ Zone ID -> ClientM [Cryptokey] listCryptoKeys = apiListCryptokeys cryptokeysClient -- | Create a new crypto key. See [Cryptokeys API Documentation](https://doc.powerdns.com/authoritative/http-api/cryptokey.html#post--servers-server_id-zones-zone_id-cryptokeys) createCryptokey :: T.Text -- ^ Server name -> T.Text -- ^ Zone ID -> Cryptokey -- ^ Cryptokey to create -> ClientM Cryptokey -- ^ Created cryptokey createCryptokey = apiCreateCryptokey cryptokeysClient -- | Get existing crypto key. See [Cryptokeys API Documentation](https://doc.powerdns.com/authoritative/http-api/cryptokey.html#post--servers-server_id-zones-zone_id-cryptokeys) getCryptokey :: T.Text -- ^ Server name -> T.Text -- ^ Zone ID -> T.Text -- ^ Cryptokey ID -> ClientM Cryptokey getCryptokey = apiGetCryptokey cryptokeysClient -- | Update existing crypto key. See [Cryptokeys API Documentation](https://doc.powerdns.com/authoritative/http-api/cryptokey.html#put--servers-server_id-zones-zone_id-cryptokeys-cryptokey_id) updateCryptokey :: T.Text -- ^ Server name -> T.Text -- ^ Zone ID -> T.Text -- ^ Cryptokey ID -> Cryptokey -- ^ Patch record. Fields with Just are changed, Nothing are ignored -> ClientM NoContent updateCryptokey = apiUpdateCryptokey cryptokeysClient -- | Delete existing crypto key. See [Cryptokeys API Documentation](https://doc.powerdns.com/authoritative/http-api/cryptokey.html#delete--servers-server_id-zones-zone_id-cryptokeys-cryptokey_id) deleteCryptokey :: T.Text -- ^ Server name -> T.Text -- ^ Zone ID -> T.Text -- ^ Cryptokey ID -> ClientM NoContent deleteCryptokey = apiDeleteCryptokey cryptokeysClient ---------------------------------------------------------------------------------------- serversClient :: ServersAPI (AsClientT ClientM) serversClient = fromServant (servers pdnsClient) -- | List available servers. See [Servers API Documentation](https://doc.powerdns.com/authoritative/http-api/server.html#get--servers) listServers :: ClientM [Server] listServers = apiListServers serversClient -- | Get existing server. See [Servers API Documentation](https://doc.powerdns.com/authoritative/http-api/server.html#get--servers-server_id) getServer :: T.Text -- ^ Server ID -> ClientM Server getServer = apiGetServer serversClient -- | Searches in various object types for an arbitrary string. See [Search API Documentation](https://doc.powerdns.com/authoritative/http-api/search.html#get--servers-server_id-search-data) search :: T.Text -- ^ Server ID -> T.Text -- ^ String to search for -> Integer -- ^ Maximum number of results -> Maybe ObjectType -- ^ Limit results to specified object type, if any. -> ClientM [SearchResult] search = apiSearch serversClient -- | Flushes a domain from the cache. See [Cache API Documentation](https://doc.powerdns.com/authoritative/http-api/cache.html#put--servers-server_id-cache-flush) flushCache :: T.Text -- ^ Server ID -> T.Text -- ^ Domain -> ClientM CacheFlushResult flushCache = apiFlushCache serversClient -- | Get server wide statistics. See [Cache API Documentation](https://doc.powerdns.com/authoritative/http-api/statistics.html) statistics :: T.Text -- ^ Server ID -> Maybe T.Text -- ^ Only return statistic items with this name. -> Maybe Bool -- ^ Whether or not to return ring items. -> ClientM [AnyStatisticItem] statistics = apiStatistics serversClient ---------------------------------------------------------------------------------------- metadataClient :: MetadataAPI (AsClientT ClientM) metadataClient = fromServant (metadata pdnsClient) -- | List metadata for existing zone. See [Metadata API Documentation](https://doc.powerdns.com/authoritative/http-api/metadata.html#get--servers-server_id-zones-zone_id-metadata) listMetadata :: T.Text -- ^ Server ID -> T.Text -- ^ Zone ID -> ClientM [Metadata] listMetadata = apiListMetadata metadataClient -- | Create metadata for zone. See [Metadata API Documentation](https://doc.powerdns.com/authoritative/http-api/metadata.html#post--servers-server_id-zones-zone_id-metadata) createMetadata :: T.Text -- ^ Server ID -> T.Text -- ^ Zone ID -> Metadata -> ClientM NoContent createMetadata = apiCreateMetadata metadataClient -- | Get metadata for zone by kind. See [Metadata API Documentation](https://doc.powerdns.com/authoritative/http-api/metadata.html#get--servers-server_id-zones-zone_id-metadata-metadata_kind) getMetadata :: T.Text -- ^ Server ID -> T.Text -- ^ Zone ID -> T.Text -- ^ Kind -> ClientM Metadata getMetadata = apiGetMetadata metadataClient -- | Update metadata for zone by kind. See [Metadata API Documentation](https://doc.powerdns.com/authoritative/http-api/metadata.html#put--servers-server_id-zones-zone_id-metadata-metadata_kind) updateMetadata :: T.Text -- ^ Server ID -> T.Text -- ^ Zone ID -> T.Text -- ^ Kind -> Metadata -> ClientM Metadata updateMetadata = apiUpdateMetadata metadataClient -- | Delete metadata for zone by kind. See [Metadata API Documentation](https://doc.powerdns.com/authoritative/http-api/metadata.html#delete--servers-server_id-zones-zone_id-metadata-metadata_kind) deleteMetadata :: T.Text -- ^ Server ID -> T.Text -- ^ Zone ID -> T.Text -- ^ Kind -> ClientM NoContent deleteMetadata = apiDeleteMetadata metadataClient ---------------------------------------------------------------------------------------- tsigkeysClient :: TSIGKeysAPI (AsClientT ClientM) tsigkeysClient = fromServant (tsigkeys pdnsClient) -- | List all TSIG keys. See [TSIGKeys API Documentation](https://doc.powerdns.com/authoritative/http-api/tsigkey.html#get--servers-server_id-tsigkeys) listTSIGKeys :: T.Text -> ClientM [TSIGKey] listTSIGKeys = apiListTSIGKeys tsigkeysClient -- | Create a new TSIG key. If the key is left empty, the server will generate one. See [TSIGKeys API Documentation](https://doc.powerdns.com/authoritative/http-api/tsigkey.html#post--servers-server_id-tsigkeys) createTSIGKey :: T.Text -> TSIGKey -> ClientM TSIGKey createTSIGKey = apiCreateTSIGKey tsigkeysClient -- | Get TSIG key by its id. See [TSIGKeys API Documentation](https://doc.powerdns.com/authoritative/http-api/tsigkey.html#get--servers-server_id-tsigkeys-tsigkey_id) getTSIGKey :: T.Text -> T.Text -> ClientM TSIGKey getTSIGKey = apiGetTSIGKey tsigkeysClient -- | Update existig TSIG key. See [TSIGKeys API Documentation](https://doc.powerdns.com/authoritative/http-api/tsigkey.html#put--servers-server_id-tsigkeys-tsigkey_id) updateTSIGKey :: T.Text -> T.Text -> TSIGKey -> ClientM TSIGKey updateTSIGKey = apiUpdateTSIGKey tsigkeysClient -- | Delete existing TSIG key. See [TSIGKeys API Documentation](https://doc.powerdns.com/authoritative/http-api/tsigkey.html#delete--servers-server_id-tsigkeys-tsigkey_id) deleteTSIGKey :: T.Text -> T.Text -> ClientM NoContent deleteTSIGKey = apiDeleteTSIGKey tsigkeysClient ----------------------------------------------------------------------------------------