@@ -5,10 +5,10 @@
5{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5{-# LANGUAGE GeneralizedNewtypeDeriving #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
6{-# LANGUAGE MultiParamTypeClasses #-}
7-- {-# LANGUAGE NoMonomorphismRestriction #-}
7-- {-# LANGUAGE NoMonomorphismRestriction #-}
8+{-# LANGUAGE NamedFieldPuns #-}
8{-# LANGUAGE OverloadedStrings #-}
9{-# LANGUAGE OverloadedStrings #-}
9{-# LANGUAGE RecordWildCards #-}
10{-# LANGUAGE RecordWildCards #-}
10{-# LANGUAGE UndecidableInstances #-}
11{-# LANGUAGE UndecidableInstances #-}
11−{-# LANGUAGE NamedFieldPuns #-}
13-------------------------------------------------------------------------------
13-------------------------------------------------------------------------------
@@ -69,6 +69,9 @@ module Database.Bloodhound.Types
69 , AllocationPolicy(..)
69 , AllocationPolicy(..)
70 , ReplicaBounds(..)
70 , ReplicaBounds(..)
71 , Bytes(..)
71 , Bytes(..)
72 , FSType(..)
75 , FSType(..)
73 , InitialShardCount(..)
76 , InitialShardCount(..)
74 , NodeAttrFilter(..)
77 , NodeAttrFilter(..)
@@ -235,6 +238,38 @@ module Database.Bloodhound.Types
235 , CollectionMode(..)
238 , CollectionMode(..)
236 , TermOrder(..)
239 , TermOrder(..)
237 , TermInclusion(..)
240 , TermInclusion(..)
241+ , SnapshotRepoSelection(..)
242+ , GenericSnapshotRepo(..)
244+ , SnapshotRepoConversionError(..)
245+ , SnapshotRepoType(..)
246+ , GenericSnapshotRepoSettings(..)
247+ , SnapshotRepoUpdateSettings(..)
248+ , defaultSnapshotRepoUpdateSettings
249+ , SnapshotRepoName(..)
250+ , SnapshotRepoPattern(..)
251+ , SnapshotVerification(..)
252+ , SnapshotNodeVerification(..)
255+ , FsSnapshotRepo(..)
256+ , SnapshotCreateSettings(..)
257+ , defaultSnapshotCreateSettings
258+ , SnapshotSelection(..)
259+ , SnapshotPattern(..)
261+ , SnapshotShardFailure(..)
265+ , SnapshotRestoreSettings(..)
266+ , defaultSnapshotRestoreSettings
267+ , RestoreRenamePattern(..)
268+ , RestoreRenameToken(..)
272+ , RestoreIndexSettings(..)
239 , Aggregation(..)
274 , Aggregation(..)
240 , Aggregations
275 , Aggregations
@@ -275,7 +310,7 @@ module Database.Bloodhound.Types
275 , EsPassword(..)
310 , EsPassword(..)
278−import Control.Applicative
313+import Control.Applicative as A
279import Control.Monad.Catch
314import Control.Monad.Catch
280import Control.Monad.Except
315import Control.Monad.Except
281import Control.Monad.Reader
316import Control.Monad.Reader
@@ -283,7 +318,7 @@ import Control.Monad.State
283import Control.Monad.Writer
318import Control.Monad.Writer
284import Data.Aeson
319import Data.Aeson
285import Data.Aeson.Types (Pair, Parser, emptyObject,
320import Data.Aeson.Types (Pair, Parser, emptyObject,
286− parseMaybe)
321+ parseEither, parseMaybe)
287import qualified Data.ByteString.Lazy.Char8 as L
322import qualified Data.ByteString.Lazy.Char8 as L
288import Data.Char
323import Data.Char
289import Data.Hashable (Hashable)
324import Data.Hashable (Hashable)
@@ -332,7 +367,7 @@ mkBHEnv s m = BHEnv s m return
332newtype BH m a = BH {
367newtype BH m a = BH {
333 unBH :: ReaderT BHEnv m a
368 unBH :: ReaderT BHEnv m a
334 } deriving ( Functor
369 } deriving ( Functor
335− , Applicative
370+ , A.Applicative
337 , MonadIO
372 , MonadIO
338 , MonadState s
373 , MonadState s
@@ -483,8 +518,31 @@ data ReplicaBounds = ReplicasBounded Int Int
483 | ReplicasUnbounded
518 | ReplicasUnbounded
484 deriving (Eq, Read, Show, Generic, Typeable)
519 deriving (Eq, Read, Show, Generic, Typeable)
521+-- | A measure of bytes used for various configurations. You may want
522+-- to use smart constructors like 'gigabytes' for larger values.
486newtype Bytes = Bytes Int deriving (Eq, Read, Show, Generic, Typeable, Ord, ToJSON, FromJSON)
532newtype Bytes = Bytes Int deriving (Eq, Read, Show, Generic, Typeable, Ord, ToJSON, FromJSON)
534+gigabytes :: Int -> Bytes
535+gigabytes n = megabytes (1000 * n)
538+megabytes :: Int -> Bytes
539+megabytes n = kilobytes (1000 * n)
542+kilobytes :: Int -> Bytes
543+kilobytes n = Bytes (1000 * n)
488data FSType = FSSimple
546data FSType = FSSimple
489 | FSBuffered deriving (Eq, Read, Show, Generic, Typeable, Ord)
547 | FSBuffered deriving (Eq, Read, Show, Generic, Typeable, Ord)
@@ -803,6 +861,7 @@ newtype IndexName = IndexName Text deriving (Eq, Generic, Read, Show, ToJSON, Fr
803{-| 'IndexSelection' is used for APIs which take a single index, a list of
861{-| 'IndexSelection' is used for APIs which take a single index, a list of
804 indexes, or the special @_all@ index.
862 indexes, or the special @_all@ index.
864+--TODO: this does not fully support <https://www.elastic.co/guide/en/elasticsearch/reference/1.7/multi-index.html multi-index syntax>. It wouldn't be too hard to implement but you'd have to add the optional parameters (ignore_unavailable, allow_no_indices, expand_wildcards) to any APIs using it. Also would be a breaking API.
806data IndexSelection = IndexList (NonEmpty IndexName)
865data IndexSelection = IndexList (NonEmpty IndexName)
807 | AllIndexes deriving (Eq, Generic, Show, Typeable)
866 | AllIndexes deriving (Eq, Generic, Show, Typeable)
@@ -2947,7 +3006,7 @@ instance FromJSON UpdatableIndexSetting where
2947 <|> blocksWrite `taggedAt` ["blocks", "write"]
3006 <|> blocksWrite `taggedAt` ["blocks", "write"]
2948 <|> blocksMetaData `taggedAt` ["blocks", "metadata"]
3007 <|> blocksMetaData `taggedAt` ["blocks", "metadata"]
2949 where taggedAt f ks = taggedAt' f (Object o) ks
3008 where taggedAt f ks = taggedAt' f (Object o) ks
2950− taggedAt' f v [] = f =<< (parseJSON v <|> (parseJSON =<< unStringlyTypeJSON v))
3009+ taggedAt' f v [] = f =<< (parseJSON v <|> (parseJSON (unStringlyTypeJSON v)))
2951 taggedAt' f v (k:ks) = withObject "Object" (\o -> do v' <- o .: k
3010 taggedAt' f v (k:ks) = withObject "Object" (\o -> do v' <- o .: k
2952 taggedAt' f v' ks) v
3011 taggedAt' f v' ks) v
2953 numberOfReplicas = pure . NumberOfReplicas
3012 numberOfReplicas = pure . NumberOfReplicas
@@ -2989,18 +3048,17 @@ instance FromJSON IndexSettingsSummary where
2989 redundant (NumberOfReplicas _) = True
3048 redundant (NumberOfReplicas _) = True
2990 redundant _ = False
3049 redundant _ = False
2992−-- | For some reason in the settings API, all leaf values get returned
3051+-- | For some reason in several settings APIs, all leaf values get returned
2993-- as strings. This function attepmts to recover from this for all
3052-- as strings. This function attepmts to recover from this for all
2994−-- non-recursive JSON types. If nothing can be done or the same value
3053+-- non-recursive JSON types. If nothing can be done, the value is left alone.
2995−-- would be return, it returns 'mzero'
2996−unStringlyTypeJSON :: MonadPlus m => Value -> m Value
3054+unStringlyTypeJSON :: Value -> Value
2997−unStringlyTypeJSON (String "true") = return (Bool True)
3055+unStringlyTypeJSON (String "true") = Bool True
2998−unStringlyTypeJSON (String "false") = return (Bool False)
3056+unStringlyTypeJSON (String "false") = Bool False
2999−unStringlyTypeJSON (String "null") = return Null
3057+unStringlyTypeJSON (String "null") = Null
3000−unStringlyTypeJSON (String t) = case readMay (T.unpack t) of
3058+unStringlyTypeJSON v@(String t) = case readMay (T.unpack t) of
3001− Just n -> return (Number n)
3059+ Just n -> Number n
3002− Nothing -> mzero
3060+ Nothing -> v
3003−unStringlyTypeJSON _ = mzero
3061+unStringlyTypeJSON v = v
3006parseSettings :: Object -> Parser [UpdatableIndexSetting]
3064parseSettings :: Object -> Parser [UpdatableIndexSetting]
@@ -3625,3 +3683,418 @@ newtype EsUsername = EsUsername { esUsername :: Text } deriving (Read, Show, Eq)
3626-- | Password type used for HTTP Basic authentication. See 'basicAuthHook'.
3684-- | Password type used for HTTP Basic authentication. See 'basicAuthHook'.
3627newtype EsPassword = EsPassword { esPassword :: Text } deriving (Read, Show, Eq)
3685newtype EsPassword = EsPassword { esPassword :: Text } deriving (Read, Show, Eq)
3688+data SnapshotRepoSelection = SnapshotRepoList (NonEmpty SnapshotRepoPattern)
3689+ | AllSnapshotRepos deriving (Eq, Generic, Show, Typeable)
3692+-- | Either specifies an exact repo name or one with globs in it,
3693+-- e.g. @RepoPattern "foo*"@ __NOTE__: Patterns are not supported on ES < 1.7
3694+data SnapshotRepoPattern = ExactRepo SnapshotRepoName
3696+ deriving (Eq, Generic, Show, Typeable)
3698+-- | The unique name of a snapshot repository.
3699+newtype SnapshotRepoName = SnapshotRepoName { snapshotRepoName :: Text }
3700+ deriving (Eq, Ord, Generic, Show, Typeable, ToJSON, FromJSON)
3703+-- | A generic representation of a snapshot repo. This is what gets
3704+-- sent to and parsed from the server. For repo types enabled by
3705+-- plugins that aren't exported by this library, consider making a
3706+-- custom type which implements 'SnapshotRepo'. If it is a common repo
3707+-- type, consider submitting a pull request to have it included in the
3709+data GenericSnapshotRepo = GenericSnapshotRepo {
3710+ gSnapshotRepoName :: SnapshotRepoName
3711+ , gSnapshotRepoType :: SnapshotRepoType
3712+ , gSnapshotRepoSettings :: GenericSnapshotRepoSettings
3713+ } deriving (Eq, Generic, Show, Typeable)
3716+instance SnapshotRepo GenericSnapshotRepo where
3717+ toGSnapshotRepo = id
3718+ fromGSnapshotRepo = Right
3721+newtype SnapshotRepoType = SnapshotRepoType { snapshotRepoType :: Text }
3722+ deriving (Eq, Ord, Generic, Show, Typeable, ToJSON, FromJSON)
3725+-- | Opaque representation of snapshot repo settings. Instances of
3726+-- 'SnapshotRepo' will produce this.
3727+newtype GenericSnapshotRepoSettings = GenericSnapshotRepoSettings { gSnapshotRepoSettingsObject :: Object }
3728+ deriving (Eq, Generic, Show, Typeable, ToJSON)
3731+ -- Regardless of whether you send strongly typed json, my version of
3732+ -- ES sends back stringly typed json in the settings, e.g. booleans
3733+ -- as strings, so we'll try to convert them.
3734+instance FromJSON GenericSnapshotRepoSettings where
3735+ parseJSON = fmap (GenericSnapshotRepoSettings . fmap unStringlyTypeJSON). parseJSON
3737+-- | The result of running 'verifySnapshotRepo'.
3738+newtype SnapshotVerification = SnapshotVerification { snapshotNodeVerifications :: [SnapshotNodeVerification] }
3739+ deriving (Eq, Generic, Show, Typeable)
3742+instance FromJSON SnapshotVerification where
3743+ parseJSON = withObject "SnapshotVerification" parse
3747+ SnapshotVerification <$> mapM (uncurry parse') (HM.toList o2)
3748+ parse' rawFullId = withObject "SnapshotNodeVerification" $ \o ->
3749+ SnapshotNodeVerification (FullNodeId rawFullId) <$> o .: "name"
3752+-- | A node that has verified a snapshot
3753+data SnapshotNodeVerification = SnapshotNodeVerification {
3754+ snvFullId :: FullNodeId
3755+ , snvNodeName :: NodeName
3756+ } deriving (Eq, Generic, Show, Typeable)
3759+-- | Unique, automatically-generated name assigned to nodes that are
3760+-- usually returned in node-oriented APIs.
3761+newtype FullNodeId = FullNodeId { fullNodeId :: Text }
3762+ deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
3765+-- | A human-readable node name that is supplied by the user in the
3766+-- node config or automatically generated by ElasticSearch.
3767+newtype NodeName = NodeName { nodeName :: Text }
3768+ deriving (Eq, Ord, Generic, Show, Typeable, FromJSON)
3771+data SnapshotRepoUpdateSettings = SnapshotRepoUpdateSettings {
3772+ repoUpdateVerify :: Bool
3773+ -- ^ After creation/update, synchronously check that nodes can
3774+ -- write to this repo. Defaults to True. You may use False if you
3775+ -- need a faster response and plan on verifying manually later
3776+ -- with 'verifySnapshotRepo'.
3777+ } deriving (Eq, Show, Generic, Typeable)
3780+-- | Reasonable defaults for repo creation/update
3782+-- * repoUpdateVerify True
3783+defaultSnapshotRepoUpdateSettings :: SnapshotRepoUpdateSettings
3784+defaultSnapshotRepoUpdateSettings = SnapshotRepoUpdateSettings True
3787+-- | A filesystem-based snapshot repo that ships with
3788+-- ElasticSearch. This is an instance of 'SnapshotRepo' so it can be
3789+-- used with 'updateSnapshotRepo'
3790+data FsSnapshotRepo = FsSnapshotRepo {
3791+ fsrName :: SnapshotRepoName
3792+ , fsrLocation :: FilePath
3793+ , fsrCompressMetadata :: Bool
3794+ , fsrChunkSize :: Maybe Bytes
3795+ -- ^ Size by which to split large files during snapshotting.
3796+ , fsrMaxRestoreBytesPerSec :: Maybe Bytes
3797+ -- ^ Throttle node restore rate. If not supplied, defaults to 40mb/sec
3798+ , fsrMaxSnapshotBytesPerSec :: Maybe Bytes
3799+ -- ^ Throttle node snapshot rate. If not supplied, defaults to 40mb/sec
3800+ } deriving (Eq, Generic, Show, Typeable)
3803+instance SnapshotRepo FsSnapshotRepo where
3804+ toGSnapshotRepo FsSnapshotRepo {..} =
3805+ GenericSnapshotRepo fsrName fsRepoType (GenericSnapshotRepoSettings settings)
3807+ Object settings = object $ [ "location" .= fsrLocation
3808+ , "compress" .= fsrCompressMetadata
3810+ optionalPairs = catMaybes [ ("chunk_size" .=) <$> fsrChunkSize
3811+ , ("max_restore_bytes_per_sec" .=) <$> fsrMaxRestoreBytesPerSec
3812+ , ("max_snapshot_bytes_per_sec" .=) <$> fsrMaxSnapshotBytesPerSec
3814+ fromGSnapshotRepo GenericSnapshotRepo {..}
3815+ | gSnapshotRepoType == fsRepoType = do
3816+ let o = gSnapshotRepoSettingsObject gSnapshotRepoSettings
3818+ FsSnapshotRepo gSnapshotRepoName <$> o .: "location"
3819+ <*> o .:? "compress" .!= False
3820+ <*> o .:? "chunk_size"
3821+ <*> o .:? "max_restore_bytes_per_sec"
3822+ <*> o .:? "max_snapshot_bytes_per_sec"
3823+ | otherwise = Left (RepoTypeMismatch fsRepoType gSnapshotRepoType)
3826+parseRepo :: Parser a -> Either SnapshotRepoConversionError a
3827+parseRepo parser = case parseEither (const parser) () of
3828+ Left e -> Left (OtherRepoConversionError (T.pack e))
3832+fsRepoType :: SnapshotRepoType
3833+fsRepoType = SnapshotRepoType "fs"
3835+-- | Law: fromGSnapshotRepo (toGSnapshotRepo r) == Right r
3836+class SnapshotRepo r where
3837+ toGSnapshotRepo :: r -> GenericSnapshotRepo
3838+ fromGSnapshotRepo :: GenericSnapshotRepo -> Either SnapshotRepoConversionError r
3841+data SnapshotRepoConversionError = RepoTypeMismatch SnapshotRepoType SnapshotRepoType
3842+ -- ^ Expected type and actual type
3843+ | OtherRepoConversionError Text
3844+ deriving (Show, Eq, Generic, Typeable)
3847+instance Exception SnapshotRepoConversionError
3850+data SnapshotCreateSettings = SnapshotCreateSettings {
3851+ snapWaitForCompletion :: Bool
3852+ -- ^ Should the API call return immediately after initializing
3853+ -- the snapshot or wait until completed? Note that if this is
3854+ -- enabled it could wait a long time, so you should adjust your
3855+ -- 'ManagerSettings' accordingly to set long timeouts or
3856+ -- explicitly handle timeouts.
3857+ , snapIndices :: Maybe IndexSelection
3858+ -- ^ Nothing will snapshot all indices. Just [] is permissable and
3859+ -- will essentially be a no-op snapshot.
3860+ , snapIgnoreUnavailable :: Bool
3861+ -- ^ If set to True, any matched indices that don't exist will be
3862+ -- ignored. Otherwise it will be an error and fail.
3863+ , snapIncludeGlobalState :: Bool
3864+ , snapPartial :: Bool
3865+ -- ^ If some indices failed to snapshot (e.g. if not all primary
3866+ -- shards are available), should the process proceed?
3867+ } deriving (Eq, Generic, Show, Typeable)
3870+-- | Reasonable defaults for snapshot creation
3872+-- * snapWaitForCompletion False
3873+-- * snapIndices Nothing
3874+-- * snapIgnoreUnavailable False
3875+-- * snapIncludeGlobalState True
3876+-- * snapPartial False
3877+defaultSnapshotCreateSettings :: SnapshotCreateSettings
3878+defaultSnapshotCreateSettings = SnapshotCreateSettings {
3879+ snapWaitForCompletion = False
3880+ , snapIndices = Nothing
3881+ , snapIgnoreUnavailable = False
3882+ , snapIncludeGlobalState = True
3883+ , snapPartial = False
3887+data SnapshotSelection = SnapshotList (NonEmpty SnapshotPattern)
3888+ | AllSnapshots deriving (Eq, Generic, Show, Typeable)
3891+-- | Either specifies an exact snapshot name or one with globs in it,
3892+-- e.g. @SnapPattern "foo*"@ __NOTE__: Patterns are not supported on
3894+data SnapshotPattern = ExactSnap SnapshotName
3896+ deriving (Eq, Generic, Show, Typeable)
3899+-- | General information about the state of a snapshot. Has some
3900+-- redundancies with 'SnapshotStatus'
3901+data SnapshotInfo = SnapshotInfo {
3902+ snapInfoShards :: ShardResult
3903+ , snapInfoFailures :: [SnapshotShardFailure]
3904+ , snapInfoDuration :: NominalDiffTime
3905+ , snapInfoEndTime :: UTCTime
3906+ , snapInfoStartTime :: UTCTime
3907+ , snapInfoState :: SnapshotState
3908+ , snapInfoIndices :: [IndexName]
3909+ , snapInfoName :: SnapshotName
3910+ } deriving (Eq, Generic, Show, Typeable)
3913+instance FromJSON SnapshotInfo where
3914+ parseJSON = withObject "SnapshotInfo" parse
3916+ parse o = SnapshotInfo <$> o .: "shards"
3917+ <*> o .: "failures"
3918+ <*> (unMS <$> o .: "duration_in_millis")
3919+ <*> (posixMS <$> o .: "end_time_in_millis")
3920+ <*> (posixMS <$> o .: "start_time_in_millis")
3923+ <*> o .: "snapshot"
3925+data SnapshotShardFailure = SnapshotShardFailure {
3926+ snapShardFailureIndex :: IndexName
3927+ , snapShardFailureNodeId :: Maybe NodeName -- I'm not 100% sure this isn't actually 'FullNodeId'
3928+ , snapShardFailureReason :: Text
3929+ , snapShardFailureShardId :: ShardId
3930+ } deriving (Eq, Show, Generic, Typeable)
3933+instance FromJSON SnapshotShardFailure where
3934+ parseJSON = withObject "SnapshotShardFailure" parse
3936+ parse o = SnapshotShardFailure <$> o .: "index"
3937+ <*> o .:? "node_id"
3939+ <*> o .: "shard_id"
3942+newtype ShardId = ShardId { shardId :: Int }
3943+ deriving (Eq, Show, Generic, Typeable, FromJSON)
3946+newtype MS = MS NominalDiffTime
3949+-- keeps the unexported constructor warnings at bay
3950+unMS :: MS -> NominalDiffTime
3954+instance FromJSON MS where
3955+ parseJSON = withScientific "MS" (return . MS . parse)
3957+ parse n = fromInteger ((truncate n) * 1000)
3960+data SnapshotState = SnapshotInit
3967+ deriving (Show, Eq, Generic, Typeable)
3969+instance FromJSON SnapshotState where
3970+ parseJSON = withText "SnapshotState" parse
3972+ parse "INIT" = return SnapshotInit
3973+ parse "STARTED" = return SnapshotStarted
3974+ parse "SUCCESS" = return SnapshotSuccess
3975+ parse "FAILED" = return SnapshotFailed
3976+ parse "ABORTED" = return SnapshotAborted
3977+ parse "MISSING" = return SnapshotMissing
3978+ parse "WAITING" = return SnapshotWaiting
3979+ parse t = fail ("Invalid snapshot state " <> T.unpack t)
3982+newtype SnapshotName = SnapshotName { snapshotName :: Text }
3983+ deriving (Show, Eq, Ord, Generic, Typeable, ToJSON, FromJSON)
3986+data SnapshotRestoreSettings = SnapshotRestoreSettings {
3987+ snapRestoreWaitForCompletion :: Bool
3988+ -- ^ Should the API call return immediately after initializing
3989+ -- the restore or wait until completed? Note that if this is
3990+ -- enabled, it could wait a long time, so you should adjust your
3991+ -- 'ManagerSettings' accordingly to set long timeouts or
3992+ -- explicitly handle timeouts.
3993+ , snapRestoreIndices :: Maybe IndexSelection
3994+ -- ^ Nothing will restore all indices in the snapshot. Just [] is
3995+ -- permissable and will essentially be a no-op restore.
3996+ , snapRestoreIgnoreUnavailable :: Bool
3997+ -- ^ If set to True, any indices that do not exist will be ignored
3998+ -- during snapshot rather than failing the restore.
3999+ , snapRestoreIncludeGlobalState :: Bool
4000+ -- ^ If set to false, will ignore any global state in the snapshot
4001+ -- and will not restore it.
4002+ , snapRestoreRenamePattern :: Maybe RestoreRenamePattern
4003+ -- ^ A regex pattern for matching indices. Used with
4004+ -- 'snapRestoreRenameReplacement', the restore can reference the
4005+ -- matched index and create a new index name upon restore.
4006+ , snapRestoreRenameReplacement :: Maybe (NonEmpty RestoreRenameToken)
4007+ -- ^ Expression of how index renames should be constructed.
4008+ , snapRestorePartial :: Bool
4009+ -- ^ If some indices fail to restore, should the process proceed?
4010+ , snapRestoreIncludeAliases :: Bool
4011+ -- ^ Should the restore also restore the aliases captured in the
4013+ , snapRestoreIndexSettingsOverrides :: Maybe RestoreIndexSettings
4014+ -- ^ Settings to apply during the restore process. __NOTE:__ This
4015+ -- option is not supported in ES < 1.5 and should be set to
4016+ -- Nothing in that case.
4017+ , snapRestoreIgnoreIndexSettings :: Maybe (NonEmpty Text)
4018+ -- ^ This type could be more rich but it isn't clear which
4019+ -- settings are allowed to be ignored during restore, so we're
4020+ -- going with including this feature in a basic form rather than
4021+ -- omitting it. One example here would be
4022+ -- "index.refresh_interval". Any setting specified here will
4023+ -- revert back to the server default during the restore process.
4024+ } deriving (Eq, Generic, Show, Typeable)
4026+-- | Regex-stype pattern, e.g. "index_(.+)" to match index names
4027+newtype RestoreRenamePattern = RestoreRenamePattern { rrPattern :: Text }
4028+ deriving (Show, Eq, Generic, Typeable, Ord, ToJSON)
4031+-- | A single token in a index renaming scheme for a restore. These
4032+-- are concatenated into a string before being sent to
4033+-- ElasticSearch. Check out these Java
4034+-- <https://docs.oracle.com/javase/7/docs/api/java/util/regex/Matcher.html docs> to find out more if you're into that sort of thing.
4035+data RestoreRenameToken = RRTLit Text
4036+ -- ^ Just a literal string of characters
4038+ -- ^ Equivalent to $0. The entire matched pattern, not any subgroup
4039+ | RRSubGroup RRGroupRefNum
4040+ -- ^ A specific reference to a group number
4041+ deriving (Show, Eq, Generic, Typeable)
4044+-- | A group number for regex matching. Only values from 1-9 are
4045+-- supported. Construct with 'mkRRGroupRefNum'
4046+newtype RRGroupRefNum = RRGroupRefNum { rrGroupRefNum :: Int }
4047+ deriving (Show, Eq, Generic, Typeable, Ord)
4049+instance Bounded RRGroupRefNum where
4050+ minBound = RRGroupRefNum 1
4051+ maxBound = RRGroupRefNum 9
4054+-- | Only allows valid group number references (1-9).
4055+mkRRGroupRefNum :: Int -> Maybe RRGroupRefNum
4057+ | i >= (rrGroupRefNum minBound) && i <= (rrGroupRefNum maxBound) =
4058+ Just $ RRGroupRefNum i
4059+ | otherwise = Nothing
4062+-- | Reasonable defaults for snapshot restores
4064+-- * snapRestoreWaitForCompletion False
4065+-- * snapRestoreIndices Nothing
4066+-- * snapRestoreIgnoreUnavailable False
4067+-- * snapRestoreIncludeGlobalState True
4068+-- * snapRestoreRenamePattern Nothing
4069+-- * snapRestoreRenameReplacement Nothing
4070+-- * snapRestorePartial False
4071+-- * snapRestoreIncludeAliases True
4072+-- * snapRestoreIndexSettingsOverrides Nothing
4073+-- * snapRestoreIgnoreIndexSettings Nothing
4074+defaultSnapshotRestoreSettings :: SnapshotRestoreSettings
4075+defaultSnapshotRestoreSettings = SnapshotRestoreSettings {
4076+ snapRestoreWaitForCompletion = False
4077+ , snapRestoreIndices = Nothing
4078+ , snapRestoreIgnoreUnavailable = False
4079+ , snapRestoreIncludeGlobalState = True
4080+ , snapRestoreRenamePattern = Nothing
4081+ , snapRestoreRenameReplacement = Nothing
4082+ , snapRestorePartial = False
4083+ , snapRestoreIncludeAliases = True
4084+ , snapRestoreIndexSettingsOverrides = Nothing
4085+ , snapRestoreIgnoreIndexSettings = Nothing
4089+-- | Index settings that can be overridden. The docs only mention you
4090+-- can update number of replicas, but there may be more. You
4091+-- definitely cannot override shard count.
4092+data RestoreIndexSettings = RestoreIndexSettings {
4093+ restoreOverrideReplicas :: Maybe ReplicaCount
4094+ } deriving (Show, Eq, Generic, Typeable)
4097+instance ToJSON RestoreIndexSettings where
4098+ toJSON RestoreIndexSettings {..} = object prs
4100+ prs = catMaybes [("index.number_of_replicas" .=) <$> restoreOverrideReplicas]