Add REST endpoints for handler flags

This commit is contained in:
2026-09-25 13:09:25 +03:00
parent c412435172
commit bd1402ab3a
2 changed files with 30 additions and 9 deletions
+1 -1
View File
@@ -119,7 +119,7 @@ defaultMain = withSocketsDo $ do
[ ("reader", readerAction host 8123 token ents bus) [ ("reader", readerAction host 8123 token ents bus)
, ("writer", writerAction writerLimiter bus) , ("writer", writerAction writerLimiter bus)
, ("metrics", HomeAssistant.Runtime.Metrics.metricsAction store rrdPath rrdtool) , ("metrics", HomeAssistant.Runtime.Metrics.metricsAction store rrdPath rrdtool)
, ("metrics-http", HttpServer.runHttpServer (busLogEnv bus) rrdPath rrdtool metricsPort) , ("metrics-http", HttpServer.runHttpServer (busLogEnv bus) rrdPath rrdtool (busFlags bus) metricsPort)
] ++ [ (name, runController rootPath bus c) | c@(Controller True name _) <- active ] ] ++ [ (name, runController rootPath bus c) | c@(Controller True name _) <- active ]
runKatipContextT (busLogEnv bus) () mempty $ runKatipContextT (busLogEnv bus) () mempty $
mapConcurrently_ (uncurry supervised) workers mapConcurrently_ (uncurry supervised) workers
+29 -8
View File
@@ -7,13 +7,17 @@ import Control.Monad.IO.Class (liftIO, MonadIO)
import qualified Data.ByteString as BS import qualified Data.ByteString as BS
import Data.Void (Void) import Data.Void (Void)
import Network.Wai.Handler.Warp (run) import Network.Wai.Handler.Warp (run)
import Servant.API ((:>), Capture, Get, QueryParam, (:-), MimeRender (..), Accept (..), NamedRoutes) import Servant.API ((:>), Capture, Get, QueryParam, (:-), MimeRender (..), Accept (..), NamedRoutes, JSON, ReqBody, Put)
import Data.ByteString (ByteString) import Data.ByteString (ByteString)
import GHC.Generics (Generic) import GHC.Generics (Generic)
import Servant (Handler, err404) import Servant (Handler, err404)
import Control.Monad.Catch (throwM, MonadCatch, MonadThrow) import Control.Monad.Catch (throwM, MonadCatch, MonadThrow)
import Servant.Server (err500, ServerT) import Servant.Server (err500, ServerT)
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import Data.Map.Strict (Map)
import qualified Data.Set as S
import Data.Text (Text)
import HomeAssistant.Runtime.Flags (Flags, allFlags, setEnabled, validNames)
import Control.Exception.Annotated (checkpoint, Annotation (Annotation)) import Control.Exception.Annotated (checkpoint, Annotation (Annotation))
import Servant.Server.Generic (genericServeT) import Servant.Server.Generic (genericServeT)
import Network.Wai (Application) import Network.Wai (Application)
@@ -30,12 +34,25 @@ instance Accept ImagePng where
contentType _ = "image" // "png" contentType _ = "image" // "png"
newtype API mode = API data API mode = API
{ getMetrics :: mode :- "metrics" :> Capture "graph" Graph :> QueryParam "range" Range :> Get '[ImagePng] ByteString { getMetrics :: mode :- "metrics" :> Capture "graph" Graph :> QueryParam "range" Range :> Get '[ImagePng] ByteString
, getFlags :: mode :- "flags" :> Get '[JSON] (Map Text Bool)
, putFlag :: mode :- "flags" :> Capture "name" Text :> ReqBody '[JSON] Bool :> Put '[JSON] (Map Text Bool)
} }
deriving Generic deriving Generic
getFlagsHandler :: Flags -> LoggingHandler (Map Text Bool)
getFlagsHandler flags = allFlags flags
putFlagHandler :: Flags -> Text -> Bool -> LoggingHandler (Map Text Bool)
putFlagHandler flags name val
| name `S.notMember` validNames flags = throwM err404
| otherwise = do
setEnabled flags name val
allFlags flags
getMetricsHandler :: FilePath -> FilePath -> Graph -> Maybe Range -> LoggingHandler ByteString getMetricsHandler :: FilePath -> FilePath -> Graph -> Maybe Range -> LoggingHandler ByteString
getMetricsHandler rrdPath rrdtool graphMode mRange = checkpoint (Annotation (graphMode, mRange)) $ do getMetricsHandler rrdPath rrdtool graphMode mRange = checkpoint (Annotation (graphMode, mRange)) $ do
case lookupGraph graphs graphMode of case lookupGraph graphs graphMode of
@@ -46,14 +63,18 @@ getMetricsHandler rrdPath rrdtool graphMode mRange = checkpoint (Annotation (gra
either (\e -> logFM ErrorS (ls e) >> throwM err500) pure g either (\e -> logFM ErrorS (ls e) >> throwM err500) pure g
-- server :: FilePath -> FilePath -> API AsServer -- server :: FilePath -> FilePath -> API AsServer
server :: FilePath -> FilePath -> ServerT (NamedRoutes API) LoggingHandler server :: FilePath -> FilePath -> Flags -> ServerT (NamedRoutes API) LoggingHandler
server rrdPath rrdtool = API { getMetrics = getMetricsHandler rrdPath rrdtool } server rrdPath rrdtool flags = API
{ getMetrics = getMetricsHandler rrdPath rrdtool
, getFlags = getFlagsHandler flags
, putFlag = putFlagHandler flags
}
servantApp :: LogEnv -> FilePath -> FilePath -> Application servantApp :: LogEnv -> FilePath -> FilePath -> Flags -> Application
servantApp le rrdPath rrdtool = genericServeT (toHandler le) (server rrdPath rrdtool) servantApp le rrdPath rrdtool flags = genericServeT (toHandler le) (server rrdPath rrdtool flags)
runHttpServer :: MonadIO m => LogEnv -> FilePath -> FilePath -> Int -> m Void runHttpServer :: MonadIO m => LogEnv -> FilePath -> FilePath -> Flags -> Int -> m Void
runHttpServer le rrdPath rrdtool port = liftIO $ forever $ run port (servantApp le rrdPath rrdtool) runHttpServer le rrdPath rrdtool flags port = liftIO $ forever $ run port (servantApp le rrdPath rrdtool flags)
newtype LoggingHandler a = LoggingHandler (KatipContextT Handler a) newtype LoggingHandler a = LoggingHandler (KatipContextT Handler a)
deriving (Functor, Applicative, Monad, MonadIO, Katip, KatipContext, MonadCatch, MonadThrow) via (KatipContextT Handler) deriving (Functor, Applicative, Monad, MonadIO, Katip, KatipContext, MonadCatch, MonadThrow) via (KatipContextT Handler)