2022-08-17 04:07:44 +03:00
-- | The Arg Opt.Parser for the 'serve' subcommand.
2022-07-15 11:54:27 +03:00
module Hasura.Server.Init.Arg.Command.Serve
2022-08-17 04:07:44 +03:00
( -- * Opt.Parser
2022-08-05 03:28:49 +03:00
serveCommandParser ,
-- * Options
servePortOption ,
serveHostOption ,
pgStripesOption ,
pgConnsOption ,
pgTimeoutOption ,
pgConnLifetimeOption ,
pgUsePreparedStatementsOption ,
pgPoolTimeoutOption ,
txIsolationOption ,
adminSecretOption ,
accessKeyOption ,
authHookOption ,
authHookModeOption ,
jwtSecretOption ,
unAuthRoleOption ,
corsDomainOption ,
disableCorsOption ,
enableConsoleOption ,
consoleAssetsDirOption ,
enableTelemetryOption ,
wsReadCookieOption ,
stringifyNumOption ,
dangerousBooleanCollapseOption ,
enabledAPIsOption ,
mxRefetchDelayOption ,
mxBatchSizeOption ,
streamingMxRefetchDelayOption ,
streamingMxBatchSizeOption ,
enableAllowlistOption ,
enabledLogsOption ,
logLevelOption ,
graphqlDevModeOption ,
graphqlAdminInternalErrorsOption ,
graphqlEventsHttpPoolSizeOption ,
graphqlEventsFetchIntervalOption ,
asyncActionsFetchIntervalOption ,
enableRemoteSchemaPermsOption ,
webSocketCompressionOption ,
webSocketKeepAliveOption ,
inferFunctionPermsOption ,
enableMaintenanceModeOption ,
schemaPollIntervalOption ,
experimentalFeaturesOption ,
eventsFetchBatchSizeOption ,
gracefulShutdownOption ,
webSocketConnectionInitTimeoutOption ,
enableMetadataQueryLoggingOption ,
defaultNamingConventionOption ,
2022-08-09 14:42:12 +03:00
metadataDBExtensionsSchemaOption ,
2022-08-05 03:28:49 +03:00
-- * Pretty Printer
serveCmdFooter ,
2022-07-15 11:54:27 +03:00
)
where
--------------------------------------------------------------------------------
2022-08-17 04:07:44 +03:00
import Data.HashSet qualified as HashSet
import Data.Text qualified as Text
2022-07-15 11:54:27 +03:00
import Data.Time qualified as Time
import Database.PG.Query qualified as Query
2022-08-17 04:07:44 +03:00
import Hasura.Backends.Postgres.Connection.MonadTx qualified as MonadTx
import Hasura.Cache.Bounded qualified as Bounded
import Hasura.GraphQL.Execute.Subscription.Options qualified as Subscription . Options
import Hasura.GraphQL.Schema.NamingCase ( NamingCase )
2022-07-29 03:45:51 +03:00
import Hasura.GraphQL.Schema.Options qualified as Options
2022-08-17 04:07:44 +03:00
import Hasura.Logging qualified as Logging
2022-07-15 11:54:27 +03:00
import Hasura.Prelude
2022-08-17 04:07:44 +03:00
import Hasura.RQL.Types.Numeric qualified as Numeric
2022-07-15 11:54:27 +03:00
import Hasura.Server.Auth qualified as Auth
import Hasura.Server.Cors qualified as Cors
import Hasura.Server.Init.Arg.PrettyPrinter qualified as PP
import Hasura.Server.Init.Config qualified as Config
import Hasura.Server.Init.Env qualified as Env
2022-08-17 04:07:44 +03:00
import Hasura.Server.Logging qualified as Server . Logging
2022-07-15 11:54:27 +03:00
import Hasura.Server.Types qualified as Types
import Hasura.Session qualified as Session
import Network.Wai.Handler.Warp qualified as Warp
import Options.Applicative qualified as Opt
import Witch qualified
--------------------------------------------------------------------------------
-- Serve Command
2022-08-17 04:07:44 +03:00
serveCommandParser :: Logging . EnabledLogTypes impl => Opt . Parser ( Config . ServeOptionsRaw impl )
2022-07-15 11:54:27 +03:00
serveCommandParser =
2022-08-01 22:35:13 +03:00
Config . ServeOptionsRaw
2022-07-15 11:54:27 +03:00
<$> parseServerPort
<*> parseServerHost
<*> parseConnParams
<*> parseTxIsolation
<*> ( parseAdminSecret <|> parseAccessKey )
<*> parseAuthHook
<*> parseJwtSecret
<*> parseUnAuthRole
<*> parseCorsConfig
<*> parseEnableConsole
<*> parseConsoleAssetsDir
<*> parseEnableTelemetry
<*> parseWsReadCookie
<*> parseStringifyNum
<*> parseDangerousBooleanCollapse
<*> parseEnabledAPIs
<*> parseMxRefetchDelay
<*> parseMxBatchSize
<*> parseStreamingMxRefetchDelay
<*> parseStreamingMxBatchSize
<*> parseEnableAllowlist
<*> parseEnabledLogs
<*> parseLogLevel
<* parsePlanCacheSize -- parsed (for backwards compatibility reasons) but ignored
<*> parseGraphqlDevMode
<*> parseGraphqlAdminInternalErrors
<*> parseGraphqlEventsHttpPoolSize
<*> parseGraphqlEventsFetchInterval
<*> parseGraphqlAsyncActionsFetchInterval
<*> parseEnableRemoteSchemaPerms
<*> parseWebSocketCompression
<*> parseWebSocketKeepAlive
<*> parseInferFunctionPerms
<*> parseEnableMaintenanceMode
<*> parseSchemaPollInterval
<*> parseExperimentalFeatures
<*> parseEventsFetchBatchSize
<*> parseGracefulShutdownTimeout
<*> parseWebSocketConnectionInitTimeout
<*> parseEnableMetadataQueryLogging
<*> parseDefaultNamingConvention
2022-08-09 14:42:12 +03:00
<*> parseExtensionsSchema
2022-07-15 11:54:27 +03:00
--------------------------------------------------------------------------------
-- Serve Options
2022-08-17 04:07:44 +03:00
parseServerPort :: Opt . Parser ( Maybe Config . Port )
2022-07-15 11:54:27 +03:00
parseServerPort =
Opt . optional $
Opt . option
2022-08-17 04:07:44 +03:00
( Opt . eitherReader Env . fromEnv )
2022-07-15 11:54:27 +03:00
( Opt . long " server-port "
<> Opt . metavar " <PORT> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage servePortOption )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
servePortOption :: Config . Option Config . Port
2022-08-05 03:28:49 +03:00
servePortOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ _default = Config . unsafePort 8080 ,
2022-08-05 03:28:49 +03:00
_envVar = " HASURA_GRAPHQL_SERVER_PORT " ,
_helpMessage = " Port on which graphql-engine should be served (default: 8080) "
}
2022-07-15 11:54:27 +03:00
parseServerHost :: Opt . Parser ( Maybe Warp . HostPreference )
parseServerHost =
Opt . optional $
Opt . strOption
( Opt . long " server-host "
<> Opt . metavar " <HOST> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage serveHostOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
serveHostOption :: Config . Option Warp . HostPreference
serveHostOption =
Config . Option
{ _default = " * " ,
_envVar = " HASURA_GRAPHQL_SERVER_HOST " ,
_helpMessage = " Host on which graphql-engine will listen (default: *) "
}
2022-07-15 11:54:27 +03:00
2022-08-01 22:35:13 +03:00
parseConnParams :: Opt . Parser Config . ConnParamsRaw
2022-07-15 11:54:27 +03:00
parseConnParams =
2022-08-17 04:07:44 +03:00
Config . ConnParamsRaw <$> pgStripes <*> pgConns <*> pgIdleTimeout <*> pgConnLifetime <*> pgUsePreparedStatements <*> pgPoolTimeout
2022-07-15 11:54:27 +03:00
where
2022-08-17 04:07:44 +03:00
pgStripes :: Opt . Parser ( Maybe Numeric . NonNegativeInt )
2022-07-15 11:54:27 +03:00
pgStripes =
Opt . optional $
Opt . option
2022-08-17 04:07:44 +03:00
( Opt . eitherReader Env . fromEnv )
2022-07-15 11:54:27 +03:00
( Opt . long " stripes "
<> Opt . short 's'
<> Opt . metavar " <NO OF STRIPES> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage pgStripesOption )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
pgConns :: Opt . Parser ( Maybe Numeric . NonNegativeInt )
2022-07-15 11:54:27 +03:00
pgConns =
Opt . optional $
Opt . option
2022-08-17 04:07:44 +03:00
( Opt . eitherReader Env . fromEnv )
2022-07-15 11:54:27 +03:00
( Opt . long " connections "
<> Opt . short 'c'
<> Opt . metavar " <NO OF CONNS> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage pgConnsOption )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
pgIdleTimeout :: Opt . Parser ( Maybe Numeric . NonNegativeInt )
pgIdleTimeout =
2022-07-15 11:54:27 +03:00
Opt . optional $
Opt . option
2022-08-17 04:07:44 +03:00
( Opt . eitherReader Env . fromEnv )
2022-07-15 11:54:27 +03:00
( Opt . long " timeout "
<> Opt . metavar " <SECONDS> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage pgTimeoutOption )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
pgConnLifetime :: Opt . Parser ( Maybe ( Numeric . NonNegative Time . NominalDiffTime ) )
2022-07-15 11:54:27 +03:00
pgConnLifetime =
2022-08-17 04:07:44 +03:00
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " conn-lifetime "
<> Opt . metavar " <SECONDS> "
<> Opt . help ( Config . _helpMessage pgConnLifetimeOption )
)
2022-07-15 11:54:27 +03:00
2022-08-05 03:28:49 +03:00
pgUsePreparedStatements :: Opt . Parser ( Maybe Bool )
pgUsePreparedStatements =
2022-07-15 11:54:27 +03:00
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " use-prepared-statements "
<> Opt . metavar " <true|false> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage pgUsePreparedStatementsOption )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
pgPoolTimeout :: Opt . Parser ( Maybe ( Numeric . NonNegative Time . NominalDiffTime ) )
2022-07-15 11:54:27 +03:00
pgPoolTimeout =
2022-08-17 04:07:44 +03:00
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " pool-timeout "
<> Opt . metavar " <SECONDS> "
<> Opt . help ( Config . _helpMessage pgPoolTimeoutOption )
)
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
pgStripesOption :: Config . Option Numeric . NonNegativeInt
2022-08-05 03:28:49 +03:00
pgStripesOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ _default = Numeric . unsafeNonNegativeInt 1 ,
2022-08-05 03:28:49 +03:00
_envVar = " HASURA_GRAPHQL_PG_STRIPES " ,
_helpMessage =
" Number of stripes (distinct sub-pools) to maintain with Postgres (default: 1). "
<> " New connections will be taken from a particular stripe pseudo-randomly. "
}
2022-08-17 04:07:44 +03:00
pgConnsOption :: Config . Option Numeric . NonNegativeInt
2022-08-05 03:28:49 +03:00
pgConnsOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ _default = Numeric . unsafeNonNegativeInt 50 ,
2022-08-05 03:28:49 +03:00
_envVar = " HASURA_GRAPHQL_PG_CONNECTIONS " ,
_helpMessage =
" Maximum number of Postgres connections that can be opened per stripe (default: 50). "
<> " When the maximum is reached we will block until a new connection becomes available, "
<> " even if there is capacity in other stripes. "
}
2022-08-17 04:07:44 +03:00
pgTimeoutOption :: Config . Option Numeric . NonNegativeInt
2022-08-05 03:28:49 +03:00
pgTimeoutOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ _default = Numeric . unsafeNonNegativeInt 180 ,
2022-08-05 03:28:49 +03:00
_envVar = " HASURA_GRAPHQL_PG_TIMEOUT " ,
_helpMessage = " Each connection's idle time before it is closed (default: 180 sec) "
}
2022-08-17 04:07:44 +03:00
pgConnLifetimeOption :: Config . Option ( Numeric . NonNegative Time . NominalDiffTime )
2022-08-05 03:28:49 +03:00
pgConnLifetimeOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ _default = Numeric . unsafeNonNegative 600 ,
2022-08-05 03:28:49 +03:00
_envVar = " HASURA_GRAPHQL_PG_CONN_LIFETIME " ,
_helpMessage =
" Time from connection creation after which the connection should be destroyed and a new one "
<> " created. A value of 0 indicates we should never destroy an active connection. If 0 is "
<> " passed, memory from large query results may not be reclaimed. (default: 600 sec) "
}
pgUsePreparedStatementsOption :: Config . Option Bool
pgUsePreparedStatementsOption =
Config . Option
{ _default = True ,
_envVar = " HASURA_GRAPHQL_USE_PREPARED_STATEMENTS " ,
_helpMessage = " Use prepared statements for queries (default: true) "
}
pgPoolTimeoutOption :: Config . Option ()
pgPoolTimeoutOption =
Config . Option
{ _default = () ,
_envVar = " HASURA_GRAPHQL_PG_POOL_TIMEOUT " ,
_helpMessage = " How long to wait when acquiring a Postgres connection, in seconds (default: forever). "
}
2022-07-15 11:54:27 +03:00
parseTxIsolation :: Opt . Parser ( Maybe Query . TxIsolation )
parseTxIsolation =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " tx-iso "
<> Opt . short 'i'
<> Opt . metavar " <TXISO> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage txIsolationOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
txIsolationOption :: Config . Option Query . TxIsolation
txIsolationOption =
Config . Option
{ Config . _default = Query . ReadCommitted ,
Config . _envVar = " HASURA_GRAPHQL_TX_ISOLATION " ,
Config . _helpMessage = " transaction isolation. read-committed / repeatable-read / serializable (default: read-commited) "
}
2022-07-15 11:54:27 +03:00
parseAdminSecret :: Opt . Parser ( Maybe Auth . AdminSecretHash )
parseAdminSecret =
Opt . optional $
Auth . hashAdminSecret
<$> Opt . strOption
( Opt . long " admin-secret "
<> Opt . metavar " ADMIN SECRET KEY "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage adminSecretOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
adminSecretOption :: Config . Option ()
adminSecretOption =
Config . Option
{ Config . _default = () ,
Config . _envVar = " HASURA_GRAPHQL_ADMIN_SECRET " ,
Config . _helpMessage = " Admin Secret key, required to access this instance "
}
2022-07-15 11:54:27 +03:00
parseAccessKey :: Opt . Parser ( Maybe Auth . AdminSecretHash )
parseAccessKey =
Opt . optional $
Auth . hashAdminSecret
<$> Opt . strOption
( Opt . long " access-key "
<> Opt . metavar " ADMIN SECRET KEY (DEPRECATED: USE --admin-secret) "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage accessKeyOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
accessKeyOption :: Config . Option ()
accessKeyOption =
Config . Option
{ Config . _default = () ,
Config . _envVar = " HASURA_GRAPHQL_ACCESS_KEY " ,
Config . _helpMessage = " Admin secret key, required to access this instance (deprecated: use HASURA_GRAPHQL_ADMIN_SECRET instead) "
}
2022-07-15 11:54:27 +03:00
2022-08-01 22:35:13 +03:00
parseAuthHook :: Opt . Parser Config . AuthHookRaw
2022-07-15 11:54:27 +03:00
parseAuthHook =
2022-08-04 05:24:35 +03:00
Config . AuthHookRaw <$> url <*> urlType
2022-07-15 11:54:27 +03:00
where
url =
Opt . optional $
Opt . strOption
( Opt . long " auth-hook "
<> Opt . metavar " <WEB HOOK URL> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage authHookOption )
2022-07-15 11:54:27 +03:00
)
urlType =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " auth-hook-mode "
<> Opt . metavar " <GET|POST> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage authHookModeOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
authHookOption :: Config . Option ()
authHookOption =
Config . Option
{ Config . _default = () ,
Config . _envVar = " HASURA_GRAPHQL_AUTH_HOOK " ,
Config . _helpMessage = " URL of the authorization webhook required to authorize requests "
}
authHookModeOption :: Config . Option Auth . AuthHookType
authHookModeOption =
Config . Option
{ Config . _default = Auth . AHTGet ,
Config . _envVar = " HASURA_GRAPHQL_AUTH_HOOK_MODE " ,
Config . _helpMessage = " HTTP method to use for authorization webhook (default: GET) "
}
2022-07-15 11:54:27 +03:00
parseJwtSecret :: Opt . Parser ( Maybe Auth . JWTConfig )
parseJwtSecret =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " jwt-secret "
<> Opt . metavar " <JSON CONFIG> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage jwtSecretOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
jwtSecretOption :: Config . Option ()
jwtSecretOption =
Config . Option
{ Config . _default = () ,
Config . _envVar = " HASURA_GRAPHQL_JWT_SECRET " ,
Config . _helpMessage =
" The JSON containing type and the JWK used for verifying. e.g: "
<> " `{ \ " type \ " : \ " HS256 \ " , \ " key \ " : \ " <your-hmac-shared-secret> \ " , \ " claims_namespace \ " : \ " <optional-custom-claims-key-name> \ " }`, "
<> " `{ \ " type \ " : \ " RS256 \ " , \ " key \ " : \ " <your-PEM-RSA-public-key> \ " , \ " claims_namespace \ " : \ " <optional-custom-claims-key-name> \ " }` "
}
2022-07-15 11:54:27 +03:00
parseUnAuthRole :: Opt . Parser ( Maybe Session . RoleName )
parseUnAuthRole =
fmap mkRoleName $
Opt . optional $
Opt . strOption
( Opt . long " unauthorized-role "
<> Opt . metavar " <ROLE> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage unAuthRoleOption )
2022-07-15 11:54:27 +03:00
)
where
mkRoleName mText = mText >>= Session . mkRoleName
2022-08-05 03:28:49 +03:00
unAuthRoleOption :: Config . Option ()
unAuthRoleOption =
Config . Option
{ Config . _default = () ,
Config . _envVar = " HASURA_GRAPHQL_UNAUTHORIZED_ROLE " ,
Config . _helpMessage =
" Unauthorized role, used when admin-secret is not sent in admin-secret only mode "
++ " or \ " Authorization \ " header is absent in JWT mode "
}
2022-07-15 11:54:27 +03:00
parseCorsConfig :: Opt . Parser ( Maybe Cors . CorsConfig )
parseCorsConfig = mapCC <$> disableCors <*> corsDomain
where
corsDomain =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " cors-domain "
<> Opt . metavar " <DOMAINS> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage corsDomainOption )
2022-07-15 11:54:27 +03:00
)
disableCors =
Opt . switch
( Opt . long " disable-cors "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage disableCorsOption )
2022-07-15 11:54:27 +03:00
)
mapCC isDisabled domains =
bool domains ( Just $ Cors . CCDisabled False ) isDisabled
2022-08-05 03:28:49 +03:00
corsDomainOption :: Config . Option Cors . CorsConfig
corsDomainOption =
Config . Option
{ Config . _default = Cors . CCAllowAll ,
Config . _envVar = " HASURA_GRAPHQL_CORS_DOMAIN " ,
Config . _helpMessage =
" CSV of list of domains, excluding scheme (http/https) and including port, "
++ " to allow CORS for. Wildcard domains are allowed. See docs for details. "
}
disableCorsOption :: Config . Option Bool
disableCorsOption =
Config . Option
{ Config . _default = False ,
Config . _envVar = " HASURA_GRAPHQL_DISABLE_CORS " ,
Config . _helpMessage = " Disable CORS. Do not send any CORS headers on any request "
}
2022-07-15 11:54:27 +03:00
parseEnableConsole :: Opt . Parser Bool
parseEnableConsole =
Opt . switch
( Opt . long " enable-console "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage enableConsoleOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
enableConsoleOption :: Config . Option Bool
enableConsoleOption =
Config . Option
{ Config . _default = False ,
Config . _envVar = " HASURA_GRAPHQL_ENABLE_CONSOLE " ,
Config . _helpMessage = " Enable API Console (default: false) "
}
2022-07-15 11:54:27 +03:00
parseConsoleAssetsDir :: Opt . Parser ( Maybe Text )
parseConsoleAssetsDir =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " console-assets-dir "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage consoleAssetsDirOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
consoleAssetsDirOption :: Config . Option ()
consoleAssetsDirOption =
Config . Option
{ Config . _default = () ,
Config . _envVar = " HASURA_GRAPHQL_CONSOLE_ASSETS_DIR " ,
Config . _helpMessage =
" A directory from which static assets required for console is served at "
++ " '/console/assets' path. Can be set to '/srv/console-assets' on the "
++ " default docker image to disable loading assets from CDN. "
}
2022-07-15 11:54:27 +03:00
-- NOTE: Should this be an 'Opt.flag'?
parseEnableTelemetry :: Opt . Parser ( Maybe Bool )
parseEnableTelemetry =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " enable-telemetry "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage enableTelemetryOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
enableTelemetryOption :: Config . Option Bool
enableTelemetryOption =
Config . Option
{ _default = True ,
_envVar = " HASURA_GRAPHQL_ENABLE_TELEMETRY " ,
2022-08-17 04:07:44 +03:00
_helpMessage = " Enable anonymous telemetry on the server and console. For more information, see: https://hasura.io/docs/latest/guides/telemetry (default: true) "
2022-08-05 03:28:49 +03:00
}
2022-07-15 11:54:27 +03:00
parseWsReadCookie :: Opt . Parser Bool
parseWsReadCookie =
Opt . switch
( Opt . long " ws-read-cookie "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage wsReadCookieOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
wsReadCookieOption :: Config . Option Bool
wsReadCookieOption =
Config . Option
{ Config . _default = False ,
Config . _envVar = " HASURA_GRAPHQL_WS_READ_COOKIE " ,
Config . _helpMessage =
" Read cookie on WebSocket initial handshake, even when CORS is disabled. "
++ " This can be a potential security flaw! Please make sure you know "
++ " what you're doing. "
++ " This configuration is only applicable when CORS is disabled. "
}
2022-07-15 11:54:27 +03:00
2022-07-29 03:45:51 +03:00
parseStringifyNum :: Opt . Parser Options . StringifyNumbers
2022-07-15 11:54:27 +03:00
parseStringifyNum =
2022-07-29 03:45:51 +03:00
fmap ( bool Options . Don'tStringifyNumbers Options . StringifyNumbers ) $
Opt . switch
( Opt . long " stringify-numeric-types "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage stringifyNumOption )
2022-07-29 03:45:51 +03:00
)
2022-07-15 11:54:27 +03:00
2022-08-05 03:28:49 +03:00
stringifyNumOption :: Config . Option Options . StringifyNumbers
stringifyNumOption =
Config . Option
{ Config . _default = Options . Don'tStringifyNumbers ,
Config . _envVar = " HASURA_GRAPHQL_STRINGIFY_NUMERIC_TYPES " ,
Config . _helpMessage = " Stringify numeric types (default: false) "
}
2022-07-15 11:54:27 +03:00
2022-08-26 07:37:35 +03:00
parseDangerousBooleanCollapse :: Opt . Parser ( Maybe Options . DangerouslyCollapseBooleans )
2022-07-15 11:54:27 +03:00
parseDangerousBooleanCollapse =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " v1-boolean-null-collapse "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage dangerousBooleanCollapseOption )
2022-07-15 11:54:27 +03:00
)
2022-08-26 07:37:35 +03:00
dangerousBooleanCollapseOption :: Config . Option Options . DangerouslyCollapseBooleans
2022-08-05 03:28:49 +03:00
dangerousBooleanCollapseOption =
Config . Option
2022-08-26 07:37:35 +03:00
{ Config . _default = Options . Don'tDangerouslyCollapseBooleans ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_V1_BOOLEAN_NULL_COLLAPSE " ,
Config . _helpMessage =
" Emulate V1's behaviour re. boolean expression, where an explicit 'null' "
<> " value will be interpreted to mean that the field should be ignored "
<> " [DEPRECATED, WILL BE REMOVED SOON] (default: false) "
}
parseEnabledAPIs :: Opt . Parser ( Maybe ( HashSet Config . API ) )
2022-07-15 11:54:27 +03:00
parseEnabledAPIs =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " enabled-apis "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage enabledAPIsOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
enabledAPIsOption :: Config . Option ( HashSet Config . API )
enabledAPIsOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = HashSet . fromList [ Config . METADATA , Config . GRAPHQL , Config . PGDUMP , Config . CONFIG ] ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_ENABLED_APIS " ,
Config . _helpMessage = " Comma separated list of enabled APIs. (default: metadata,graphql,pgdump,config) "
}
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
parseMxRefetchDelay :: Opt . Parser ( Maybe Subscription . Options . RefetchInterval )
2022-07-15 11:54:27 +03:00
parseMxRefetchDelay =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " live-queries-multiplexed-refetch-interval "
<> Opt . metavar " <INTERVAL(ms)> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _envVar mxRefetchDelayOption )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
mxRefetchDelayOption :: Config . Option Subscription . Options . RefetchInterval
2022-08-05 03:28:49 +03:00
mxRefetchDelayOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = Subscription . Options . RefetchInterval 1 ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_REFETCH_INTERVAL " ,
Config . _helpMessage =
" results will only be sent once in this interval (in milliseconds) for "
<> " live queries which can be multiplexed. Default: 1000 (1sec) "
}
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
parseMxBatchSize :: Opt . Parser ( Maybe Subscription . Options . BatchSize )
2022-07-15 11:54:27 +03:00
parseMxBatchSize =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " live-queries-multiplexed-batch-size "
<> Opt . metavar " BATCH_SIZE "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage mxBatchSizeOption )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
mxBatchSizeOption :: Config . Option Subscription . Options . BatchSize
2022-08-05 03:28:49 +03:00
mxBatchSizeOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ _default = Subscription . Options . BatchSize $ Numeric . unsafeNonNegativeInt 100 ,
2022-08-05 03:28:49 +03:00
_envVar = " HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_BATCH_SIZE " ,
_helpMessage =
" multiplexed live queries are split into batches of the specified "
<> " size. Default 100. "
}
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
parseStreamingMxRefetchDelay :: Opt . Parser ( Maybe Subscription . Options . RefetchInterval )
2022-07-15 11:54:27 +03:00
parseStreamingMxRefetchDelay =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " streaming-queries-multiplexed-refetch-interval "
<> Opt . metavar " <INTERVAL(ms)> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage streamingMxRefetchDelayOption )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
streamingMxRefetchDelayOption :: Config . Option Subscription . Options . RefetchInterval
2022-08-05 03:28:49 +03:00
streamingMxRefetchDelayOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = Subscription . Options . RefetchInterval 1 ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_STREAMING_QUERIES_MULTIPLEXED_REFETCH_INTERVAL " ,
Config . _helpMessage =
" results will only be sent once in this interval (in milliseconds) for "
<> " streaming queries which can be multiplexed. Default: 1000 (1sec) "
}
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
parseStreamingMxBatchSize :: Opt . Parser ( Maybe Subscription . Options . BatchSize )
2022-07-15 11:54:27 +03:00
parseStreamingMxBatchSize =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " streaming-queries-multiplexed-batch-size "
<> Opt . metavar " BATCH_SIZE "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage streamingMxBatchSizeOption )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
streamingMxBatchSizeOption :: Config . Option Subscription . Options . BatchSize
2022-08-05 03:28:49 +03:00
streamingMxBatchSizeOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = Subscription . Options . BatchSize $ Numeric . unsafeNonNegativeInt 100 ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_STREAMING_QUERIES_MULTIPLEXED_BATCH_SIZE " ,
Config . _helpMessage =
" multiplexed live queries are split into batches of the specified "
<> " size. Default 100. "
}
2022-07-15 11:54:27 +03:00
parseEnableAllowlist :: Opt . Parser Bool
parseEnableAllowlist =
Opt . switch
( Opt . long " enable-allowlist "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage enableAllowlistOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
enableAllowlistOption :: Config . Option Bool
enableAllowlistOption =
Config . Option
{ Config . _default = False ,
Config . _envVar = " HASURA_GRAPHQL_ENABLE_ALLOWLIST " ,
Config . _helpMessage = " Only accept allowed GraphQL queries "
}
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
parseEnabledLogs :: forall impl . Logging . EnabledLogTypes impl => Opt . Parser ( Maybe ( HashSet ( Logging . EngineLogType impl ) ) )
2022-07-15 11:54:27 +03:00
parseEnabledLogs =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " enabled-log-types "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage ( enabledLogsOption @ impl ) )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
enabledLogsOption :: Logging . EnabledLogTypes impl => Config . Option ( HashSet ( Logging . EngineLogType impl ) )
2022-08-05 03:28:49 +03:00
enabledLogsOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = Logging . defaultEnabledLogTypes ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_ENABLED_LOG_TYPES " ,
Config . _helpMessage =
" Comma separated list of enabled log types "
<> " (default: "
<> defaultLogTypes
<> " ) "
<> " (all: "
<> allAllowedLogTypes
<> " ) "
}
2022-07-15 11:54:27 +03:00
where
2022-08-17 04:07:44 +03:00
defaultLogTypes = Text . unpack . Text . intercalate " , " $ Witch . into @ Text <$> HashSet . toList Logging . defaultEnabledEngineLogTypes
allAllowedLogTypes = Text . unpack . Text . intercalate " , " $ Witch . into @ Text <$> Logging . userAllowedLogTypes
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
parseLogLevel :: Opt . Parser ( Maybe Logging . LogLevel )
2022-07-15 11:54:27 +03:00
parseLogLevel =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " log-level "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage logLevelOption )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
logLevelOption :: Config . Option Logging . LogLevel
2022-08-05 03:28:49 +03:00
logLevelOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = Logging . LevelInfo ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_LOG_LEVEL " ,
Config . _helpMessage = " Server log level (default: info) (all: error, warn, info, debug) "
}
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
parsePlanCacheSize :: Opt . Parser ( Maybe Bounded . CacheSize )
2022-07-15 11:54:27 +03:00
parsePlanCacheSize =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " query-plan-cache-size "
<> Opt . help
( " [DEPRECATED: value ignored.] The maximum number of query plans "
<> " that can be cached, allowed values: 0-65535, "
<> " 0 disables the cache. Default 4000 "
)
)
parseGraphqlDevMode :: Opt . Parser Bool
parseGraphqlDevMode =
Opt . switch
( Opt . long " dev-mode "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage graphqlDevModeOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
graphqlDevModeOption :: Config . Option Bool
graphqlDevModeOption =
Config . Option
{ Config . _default = False ,
Config . _envVar = " HASURA_GRAPHQL_DEV_MODE " ,
Config . _helpMessage = " Set dev mode for GraphQL requests; include 'internal' key in the errors extensions (if required) of the response "
}
2022-07-15 11:54:27 +03:00
parseGraphqlAdminInternalErrors :: Opt . Parser ( Maybe Bool )
parseGraphqlAdminInternalErrors =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " admin-internal-errors "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage graphqlAdminInternalErrorsOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
graphqlAdminInternalErrorsOption :: Config . Option Bool
graphqlAdminInternalErrorsOption =
Config . Option
{ -- Default to `true` to enable backwards compatibility
Config . _default = True ,
Config . _envVar = " HASURA_GRAPHQL_ADMIN_INTERNAL_ERRORS " ,
Config . _helpMessage = " Enables including 'internal' information in an error response for requests made by an 'admin' (default: true) "
}
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
parseGraphqlEventsHttpPoolSize :: Opt . Parser ( Maybe Numeric . PositiveInt )
2022-07-15 11:54:27 +03:00
parseGraphqlEventsHttpPoolSize =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " events-http-pool-size "
2022-08-05 03:28:49 +03:00
<> Opt . metavar ( Config . _envVar graphqlEventsHttpPoolSizeOption )
<> Opt . help ( Config . _helpMessage graphqlEventsHttpPoolSizeOption )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
graphqlEventsHttpPoolSizeOption :: Config . Option Numeric . PositiveInt
2022-08-05 03:28:49 +03:00
graphqlEventsHttpPoolSizeOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = Numeric . unsafePositiveInt 100 ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_EVENTS_HTTP_POOL_SIZE " ,
Config . _helpMessage = " Max event processing threads (default: 100) "
}
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
parseGraphqlEventsFetchInterval :: Opt . Parser ( Maybe ( Numeric . NonNegative Milliseconds ) )
2022-07-15 11:54:27 +03:00
parseGraphqlEventsFetchInterval =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " events-fetch-interval "
2022-08-05 03:28:49 +03:00
<> Opt . metavar ( Config . _envVar graphqlEventsFetchIntervalOption )
<> Opt . help ( Config . _helpMessage graphqlEventsFetchIntervalOption )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
graphqlEventsFetchIntervalOption :: Config . Option ( Numeric . NonNegative Milliseconds )
2022-08-05 03:28:49 +03:00
graphqlEventsFetchIntervalOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = Numeric . unsafeNonNegative ( 1000 :: Milliseconds ) ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_EVENTS_FETCH_INTERVAL " ,
2022-08-10 22:17:05 +03:00
Config . _helpMessage = " Interval in milliseconds to sleep before trying to fetch events again after a fetch returned no events from postgres (default: 1 second). "
2022-08-05 03:28:49 +03:00
}
2022-07-15 11:54:27 +03:00
2022-07-29 03:45:51 +03:00
parseGraphqlAsyncActionsFetchInterval :: Opt . Parser ( Maybe Config . OptionalInterval )
2022-07-15 11:54:27 +03:00
parseGraphqlAsyncActionsFetchInterval =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " async-actions-fetch-interval "
2022-08-05 03:28:49 +03:00
<> Opt . metavar ( Config . _envVar asyncActionsFetchIntervalOption )
<> Opt . help ( Config . _helpMessage asyncActionsFetchIntervalOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
asyncActionsFetchIntervalOption :: Config . Option Config . OptionalInterval
asyncActionsFetchIntervalOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = Config . Interval $ Numeric . unsafeNonNegative ( 1000 :: Milliseconds ) ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_ASYNC_ACTIONS_FETCH_INTERVAL " ,
Config . _helpMessage =
" Interval in milliseconds to sleep before trying to fetch new async actions. "
++ " Value \ " 0 \ " implies completely disable fetching async actions from storage. "
++ " Default 1000 milliseconds "
}
2022-07-15 11:54:27 +03:00
2022-07-29 03:45:51 +03:00
parseEnableRemoteSchemaPerms :: Opt . Parser Options . RemoteSchemaPermissions
2022-07-15 11:54:27 +03:00
parseEnableRemoteSchemaPerms =
2022-07-29 03:45:51 +03:00
fmap ( bool Options . DisableRemoteSchemaPermissions Options . EnableRemoteSchemaPermissions ) $
Opt . switch
( Opt . long " enable-remote-schema-permissions "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage enableRemoteSchemaPermsOption )
2022-07-29 03:45:51 +03:00
)
2022-07-15 11:54:27 +03:00
2022-08-05 03:28:49 +03:00
enableRemoteSchemaPermsOption :: Config . Option Options . RemoteSchemaPermissions
enableRemoteSchemaPermsOption =
Config . Option
{ Config . _default = Options . DisableRemoteSchemaPermissions ,
Config . _envVar = " HASURA_GRAPHQL_ENABLE_REMOTE_SCHEMA_PERMISSIONS " ,
Config . _helpMessage = " Enables remote schema permissions (default: false) "
}
2022-07-15 11:54:27 +03:00
parseWebSocketCompression :: Opt . Parser Bool
parseWebSocketCompression =
Opt . switch
( Opt . long " websocket-compression "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage webSocketCompressionOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
webSocketCompressionOption :: Config . Option Bool
webSocketCompressionOption =
Config . Option
{ Config . _default = False ,
Config . _envVar = " HASURA_GRAPHQL_CONNECTION_COMPRESSION " ,
Config . _helpMessage = " Enable WebSocket permessage-deflate compression (default: false) "
}
2022-07-15 11:54:27 +03:00
2022-07-29 03:45:51 +03:00
parseWebSocketKeepAlive :: Opt . Parser ( Maybe Config . KeepAliveDelay )
2022-07-15 11:54:27 +03:00
parseWebSocketKeepAlive =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " websocket-keepalive "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage webSocketKeepAliveOption )
2022-07-15 11:54:27 +03:00
)
-- NOTE: this is purely used by Apollo-Subscription-Transport-WS
2022-08-05 03:28:49 +03:00
webSocketKeepAliveOption :: Config . Option Config . KeepAliveDelay
webSocketKeepAliveOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = Config . KeepAliveDelay $ Numeric . unsafeNonNegative ( 5 :: Seconds ) ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_WEBSOCKET_KEEPALIVE " ,
Config . _helpMessage = " Control websocket keep-alive timeout (default 5 seconds) "
}
2022-07-15 11:54:27 +03:00
2022-07-29 03:45:51 +03:00
parseInferFunctionPerms :: Opt . Parser ( Maybe Options . InferFunctionPermissions )
2022-07-15 11:54:27 +03:00
parseInferFunctionPerms =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " infer-function-permissions "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage inferFunctionPermsOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
inferFunctionPermsOption :: Config . Option Options . InferFunctionPermissions
inferFunctionPermsOption =
Config . Option
{ Config . _default = Options . InferFunctionPermissions ,
Config . _envVar = " HASURA_GRAPHQL_INFER_FUNCTION_PERMISSIONS " ,
Config . _helpMessage = " Infers function permissions (default: true) "
}
2022-07-15 11:54:27 +03:00
2022-07-29 03:45:51 +03:00
parseEnableMaintenanceMode :: Opt . Parser ( Types . MaintenanceMode () )
2022-07-15 11:54:27 +03:00
parseEnableMaintenanceMode =
2022-07-29 03:45:51 +03:00
fmap ( bool Types . MaintenanceModeDisabled ( Types . MaintenanceModeEnabled () ) ) $
Opt . switch
( Opt . long " enable-maintenance-mode "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage enableMaintenanceModeOption )
2022-07-29 03:45:51 +03:00
)
2022-07-15 11:54:27 +03:00
2022-08-05 03:28:49 +03:00
enableMaintenanceModeOption :: Config . Option ( Types . MaintenanceMode () )
enableMaintenanceModeOption =
Config . Option
{ Config . _default = Types . MaintenanceModeDisabled ,
Config . _envVar = " HASURA_GRAPHQL_ENABLE_MAINTENANCE_MODE " ,
Config . _helpMessage = " Flag to enable maintenance mode in the graphql-engine "
}
2022-07-15 11:54:27 +03:00
2022-08-05 03:28:49 +03:00
parseSchemaPollInterval :: Opt . Parser ( Maybe Config . OptionalInterval )
2022-07-15 11:54:27 +03:00
parseSchemaPollInterval =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " schema-sync-poll-interval "
2022-08-05 03:28:49 +03:00
<> Opt . metavar ( Config . _envVar schemaPollIntervalOption )
<> Opt . help ( Config . _helpMessage schemaPollIntervalOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
schemaPollIntervalOption :: Config . Option Config . OptionalInterval
schemaPollIntervalOption =
Config . Option
{ -- 1000 Milliseconds or 1 Second
2022-08-17 04:07:44 +03:00
Config . _default = Config . Interval $ Numeric . unsafeNonNegative ( 1000 :: Milliseconds ) ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_SCHEMA_SYNC_POLL_INTERVAL " ,
Config . _helpMessage = " Interval to poll metadata storage for updates in milliseconds - Default 1000 (1s) - Set to 0 to disable "
}
2022-07-15 11:54:27 +03:00
2022-08-05 03:28:49 +03:00
parseExperimentalFeatures :: Opt . Parser ( Maybe ( HashSet Types . ExperimentalFeature ) )
2022-07-15 11:54:27 +03:00
parseExperimentalFeatures =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " experimental-features "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage experimentalFeaturesOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
experimentalFeaturesOption :: Config . Option ( HashSet Types . ExperimentalFeature )
experimentalFeaturesOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = HashSet . empty ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_EXPERIMENTAL_FEATURES " ,
Config . _helpMessage =
" Comma separated list of experimental features. (all: inherited_roles,optimize_permission_filters and naming_convention, streaming_subscriptions, apollo_federation). "
<> " optimize_permission_filters: Use experimental SQL optimization "
<> " transformations for permission filters. "
<> " inherited_roles: ignored; inherited roles cannot be switched off "
<> " naming_convention: apply naming convention (graphql-default/hasura-default) based on source customization "
<> " apollo_federation: use hasura as a subgraph in an Apollo gateway "
<> " streaming_subscriptions: A streaming subscription streams the response according to the cursor provided by the user "
}
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
parseEventsFetchBatchSize :: Opt . Parser ( Maybe Numeric . NonNegativeInt )
2022-07-15 11:54:27 +03:00
parseEventsFetchBatchSize =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " events-fetch-batch-size "
2022-08-05 03:28:49 +03:00
<> Opt . metavar ( Config . _envVar eventsFetchBatchSizeOption )
<> Opt . help ( Config . _helpMessage eventsFetchBatchSizeOption )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
eventsFetchBatchSizeOption :: Config . Option Numeric . NonNegativeInt
2022-08-05 03:28:49 +03:00
eventsFetchBatchSizeOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = Numeric . unsafeNonNegativeInt 100 ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_EVENTS_FETCH_BATCH_SIZE " ,
Config . _helpMessage =
" The maximum number of events to be fetched from the events table in a single batch. Default 100 "
++ " Value \ " 0 \ " implies completely disable fetching events from events table. "
}
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
parseGracefulShutdownTimeout :: Opt . Parser ( Maybe ( Numeric . NonNegative Seconds ) )
2022-07-15 11:54:27 +03:00
parseGracefulShutdownTimeout =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " graceful-shutdown-timeout "
<> Opt . metavar " <INTERVAL (seconds)> "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage gracefulShutdownOption )
2022-07-15 11:54:27 +03:00
)
2022-08-17 04:07:44 +03:00
gracefulShutdownOption :: Config . Option ( Numeric . NonNegative Seconds )
2022-08-05 03:28:49 +03:00
gracefulShutdownOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = Numeric . unsafeNonNegative ( 60 :: Seconds ) ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_GRACEFUL_SHUTDOWN_TIMEOUT " ,
Config . _helpMessage =
" Timeout for graceful shutdown before which in-flight scheduled events, "
<> " cron events and async actions to complete (default: 60 seconds) "
}
2022-07-15 11:54:27 +03:00
2022-07-29 03:45:51 +03:00
parseWebSocketConnectionInitTimeout :: Opt . Parser ( Maybe Config . WSConnectionInitTimeout )
2022-07-15 11:54:27 +03:00
parseWebSocketConnectionInitTimeout =
Opt . optional $
Opt . option
2022-07-29 03:45:51 +03:00
( Opt . eitherReader Env . fromEnv )
2022-07-15 11:54:27 +03:00
( Opt . long " websocket-connection-init-timeout "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage webSocketConnectionInitTimeoutOption )
2022-07-15 11:54:27 +03:00
)
-- NOTE: this is purely used by GraphQL-WS
2022-08-05 03:28:49 +03:00
webSocketConnectionInitTimeoutOption :: Config . Option Config . WSConnectionInitTimeout
webSocketConnectionInitTimeoutOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = Config . WSConnectionInitTimeout $ Numeric . unsafeNonNegative 3 ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_WEBSOCKET_CONNECTION_INIT_TIMEOUT " , -- FIXME?: maybe a better name
Config . _helpMessage = " Control websocket connection_init timeout (default 3 seconds) "
}
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
parseEnableMetadataQueryLogging :: Opt . Parser Server . Logging . MetadataQueryLoggingMode
2022-07-15 11:54:27 +03:00
parseEnableMetadataQueryLogging =
2022-08-17 04:07:44 +03:00
fmap ( bool Server . Logging . MetadataQueryLoggingDisabled Server . Logging . MetadataQueryLoggingEnabled ) $
2022-07-29 03:45:51 +03:00
Opt . switch
( Opt . long " enable-metadata-query-logging "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage enableMetadataQueryLoggingOption )
2022-07-29 03:45:51 +03:00
)
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
enableMetadataQueryLoggingOption :: Config . Option Server . Logging . MetadataQueryLoggingMode
2022-08-05 03:28:49 +03:00
enableMetadataQueryLoggingOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = Server . Logging . MetadataQueryLoggingDisabled ,
2022-08-05 03:28:49 +03:00
Config . _envVar = " HASURA_GRAPHQL_ENABLE_METADATA_QUERY_LOGGING " ,
Config . _helpMessage = " Enables the query field in http-logs for metadata queries (default: false) "
}
2022-07-15 11:54:27 +03:00
2022-08-05 03:28:49 +03:00
-- TODO(SOLOMON): The defaulting behavior for this occurs inside the Engine. In
-- an isolated PR we should move that defaulting in the parsing stage.
2022-08-17 04:07:44 +03:00
parseDefaultNamingConvention :: Opt . Parser ( Maybe NamingCase )
2022-07-15 11:54:27 +03:00
parseDefaultNamingConvention =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " default-naming-convention "
2022-08-05 03:28:49 +03:00
<> Opt . help ( Config . _helpMessage defaultNamingConventionOption )
2022-07-15 11:54:27 +03:00
)
2022-08-05 03:28:49 +03:00
-- NOTE: This should be 'Config.Option NC.NamingCase' with a default
--of 'NC.HasuraCase' but 'ServeOptions' expects a 'Maybe
2022-08-17 04:07:44 +03:00
--NC.NamingCase' and HGE handles the defaulting explicitly. This
2022-08-05 03:28:49 +03:00
--should be changed in a subsequent PR.
defaultNamingConventionOption :: Config . Option ()
defaultNamingConventionOption =
Config . Option
{ Config . _default = () ,
Config . _envVar = " HASURA_GRAPHQL_DEFAULT_NAMING_CONVENTION " ,
Config . _helpMessage =
" Default naming convention for the auto generated graphql names. Possible values are "
<> " hasura-default: Use snake_case for all names. "
<> " graphql-default: Use camelCase for field names and PascalCase for type names. "
}
2022-07-15 11:54:27 +03:00
2022-08-17 04:07:44 +03:00
parseExtensionsSchema :: Opt . Parser ( Maybe MonadTx . ExtensionsSchema )
parseExtensionsSchema =
Opt . optional $
Opt . option
( Opt . eitherReader Env . fromEnv )
( Opt . long " metadata-database-extensions-schema "
<> Opt . help ( Config . _helpMessage metadataDBExtensionsSchemaOption )
)
metadataDBExtensionsSchemaOption :: Config . Option MonadTx . ExtensionsSchema
2022-08-09 14:42:12 +03:00
metadataDBExtensionsSchemaOption =
Config . Option
2022-08-17 04:07:44 +03:00
{ Config . _default = MonadTx . ExtensionsSchema " public " ,
2022-08-09 14:42:12 +03:00
Config . _envVar = " HASURA_GRAPHQL_METADATA_DATABASE_EXTENSIONS_SCHEMA " ,
Config . _helpMessage =
" Name of the schema where Hasura can install database extensions. Default: public "
}
2022-07-15 11:54:27 +03:00
--------------------------------------------------------------------------------
-- Pretty Printer
serveCmdFooter :: PP . Doc
serveCmdFooter =
examplesDoc PP .<$> PP . text " " PP .<$> envVarDoc
where
examplesDoc = PP . mkExamplesDoc examples
examples =
[ [ " # Start GraphQL Engine on default port (8080) with console enabled " ,
" graphql-engine --database-url <database-url> serve --enable-console "
] ,
[ " # Start GraphQL Engine on default port (8080) with console disabled " ,
" graphql-engine --database-url <database-url> serve "
] ,
[ " # Start GraphQL Engine on a different port (say 9090) with console disabled " ,
" graphql-engine --database-url <database-url> serve --server-port 9090 "
] ,
[ " # Start GraphQL Engine with admin secret key " ,
" graphql-engine --database-url <database-url> serve --admin-secret <adminsecretkey> "
] ,
[ " # Start GraphQL Engine with restrictive CORS policy (only allow https://example.com:8080) " ,
" graphql-engine --database-url <database-url> serve --cors-domain https://example.com:8080 "
] ,
[ " # Start GraphQL Engine with multiple domains for CORS (https://example.com, http://localhost:3000 and https://*.foo.bar.com) " ,
" graphql-engine --database-url <database-url> serve --cors-domain \ " https://example.com, https://*.foo.bar.com, http://localhost:3000 \ " "
] ,
[ " # Start GraphQL Engine with Authentication Webhook (GET) " ,
" graphql-engine --database-url <database-url> serve --admin-secret <adminsecretkey> "
<> " --auth-hook https://mywebhook.com/get "
] ,
[ " # Start GraphQL Engine with Authentication Webhook (POST) " ,
" graphql-engine --database-url <database-url> serve --admin-secret <adminsecretkey> "
<> " --auth-hook https://mywebhook.com/post --auth-hook-mode POST "
] ,
[ " # Start GraphQL Engine with telemetry enabled/disabled " ,
" graphql-engine --database-url <database-url> serve --enable-telemetry true|false "
] ,
[ " # Start GraphQL Engine with HTTP compression enabled for '/v1/query' and '/v1/graphql' endpoints " ,
" graphql-engine --database-url <database-url> serve --enable-compression "
] ,
[ " # Start GraphQL Engine with enable/disable including 'internal' information in an error response for the request made by an 'admin' " ,
" graphql-engine --database-url <database-url> serve --admin-internal-errors true|false "
]
]
envVarDoc = PP . mkEnvVarDoc $ envVars <> eventEnvs
envVars =
2022-08-05 03:28:49 +03:00
[ Config . optionPP servePortOption ,
Config . optionPP serveHostOption ,
Config . optionPP pgStripesOption ,
Config . optionPP pgConnsOption ,
Config . optionPP pgTimeoutOption ,
Config . optionPP pgConnLifetimeOption ,
Config . optionPP pgUsePreparedStatementsOption ,
Config . optionPP pgPoolTimeoutOption ,
Config . optionPP txIsolationOption ,
Config . optionPP adminSecretOption ,
Config . optionPP accessKeyOption ,
Config . optionPP authHookOption ,
Config . optionPP authHookModeOption ,
Config . optionPP jwtSecretOption ,
Config . optionPP unAuthRoleOption ,
Config . optionPP corsDomainOption ,
Config . optionPP disableCorsOption ,
Config . optionPP enableConsoleOption ,
Config . optionPP consoleAssetsDirOption ,
Config . optionPP enableTelemetryOption ,
Config . optionPP wsReadCookieOption ,
Config . optionPP stringifyNumOption ,
Config . optionPP dangerousBooleanCollapseOption ,
Config . optionPP enabledAPIsOption ,
Config . optionPP mxRefetchDelayOption ,
Config . optionPP mxBatchSizeOption ,
Config . optionPP streamingMxRefetchDelayOption ,
Config . optionPP streamingMxBatchSizeOption ,
Config . optionPP enableAllowlistOption ,
2022-08-17 04:07:44 +03:00
Config . optionPP ( enabledLogsOption @ Logging . Hasura ) ,
2022-08-05 03:28:49 +03:00
Config . optionPP logLevelOption ,
Config . optionPP graphqlDevModeOption ,
Config . optionPP graphqlAdminInternalErrorsOption ,
Config . optionPP graphqlEventsHttpPoolSizeOption ,
Config . optionPP graphqlEventsFetchIntervalOption ,
Config . optionPP asyncActionsFetchIntervalOption ,
Config . optionPP enableRemoteSchemaPermsOption ,
Config . optionPP webSocketCompressionOption ,
Config . optionPP webSocketKeepAliveOption ,
Config . optionPP inferFunctionPermsOption ,
Config . optionPP enableMaintenanceModeOption ,
Config . optionPP schemaPollIntervalOption ,
Config . optionPP experimentalFeaturesOption ,
Config . optionPP eventsFetchBatchSizeOption ,
Config . optionPP gracefulShutdownOption ,
Config . optionPP webSocketConnectionInitTimeoutOption ,
Config . optionPP enableMetadataQueryLoggingOption ,
2022-08-17 04:07:44 +03:00
Config . optionPP defaultNamingConventionOption ,
Config . optionPP metadataDBExtensionsSchemaOption
2022-07-15 11:54:27 +03:00
]
2022-08-05 03:28:49 +03:00
eventEnvs = [ Config . optionPP graphqlEventsHttpPoolSizeOption , Config . optionPP graphqlEventsFetchIntervalOption ]