343 lines
16 KiB
Go
343 lines
16 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
// ReservedArgumentNamePrefix is reserved for OliveTin-injected system arguments.
|
|
const ReservedArgumentNamePrefix = "ot_"
|
|
|
|
// JustificationRequiredNoTemplate requires a manual justification with no prefilled template.
|
|
const JustificationRequiredNoTemplate = " "
|
|
|
|
// Action represents the core functionality of OliveTin - commands that show up
|
|
// as buttons in the UI.
|
|
type Action struct {
|
|
ID string `koanf:"id"`
|
|
Title string `koanf:"title"`
|
|
Icon string `koanf:"icon"`
|
|
Shell string `koanf:"shell"`
|
|
Exec []string `koanf:"exec"`
|
|
ShellAfterCompleted string `koanf:"shellAfterCompleted"`
|
|
Timeout int `koanf:"timeout"`
|
|
Acls []string `koanf:"acls"`
|
|
Entity string `koanf:"entity"`
|
|
Hidden bool `koanf:"hidden"`
|
|
ExecOnStartup bool `koanf:"execOnStartup"`
|
|
ExecOnCron []string `koanf:"execOnCron"`
|
|
ExecOnFileCreatedInDir []string `koanf:"execOnFileCreatedInDir"`
|
|
ExecOnFileChangedInDir []string `koanf:"execOnFileChangedInDir"`
|
|
ExecOnCalendarFile string `koanf:"execOnCalendarFile"`
|
|
ExecOnWebhook []WebhookConfig `koanf:"execOnWebhook"`
|
|
Triggers []string `koanf:"triggers"`
|
|
MaxConcurrent int `koanf:"maxConcurrent"`
|
|
MaxRate []RateSpec `koanf:"maxRate"`
|
|
Arguments []ActionArgument `koanf:"arguments"`
|
|
OnClick string `koanf:"onclick"`
|
|
PopupOnStart string `koanf:"popupOnStart"`
|
|
SaveLogs SaveLogsConfig `koanf:"saveLogs"`
|
|
EnabledExpression string `koanf:"enabledExpression"`
|
|
Groups []string `koanf:"groups"`
|
|
Justification string `koanf:"justification"`
|
|
}
|
|
|
|
func (action *Action) RequiresJustification() bool {
|
|
return action != nil && action.Justification != ""
|
|
}
|
|
|
|
func (action *Action) JustificationTemplateText() string {
|
|
if !action.RequiresJustification() {
|
|
return ""
|
|
}
|
|
|
|
return action.Justification
|
|
}
|
|
|
|
// ActionGroup defines shared limits and metadata for a set of actions.
|
|
type ActionGroup struct {
|
|
MaxConcurrent int `koanf:"maxConcurrent"`
|
|
QueueSize int `koanf:"queueSize"`
|
|
Icon string `koanf:"icon"`
|
|
}
|
|
|
|
// ActionArgument objects appear on Actions.
|
|
type ActionArgument struct {
|
|
Name string `koanf:"name"`
|
|
Title string `koanf:"title"`
|
|
Description string `koanf:"description"`
|
|
Type string `koanf:"type"`
|
|
Default string `koanf:"default"`
|
|
Choices []ActionArgumentChoice `koanf:"choices"`
|
|
Entity string `koanf:"entity"`
|
|
RejectNull bool `koanf:"rejectNull"`
|
|
Suggestions map[string]string `koanf:"suggestions"`
|
|
SuggestionsBrowserKey string `koanf:"suggestionsBrowserKey"`
|
|
}
|
|
|
|
// ActionArgumentChoice represents a predefined choice for an argument.
|
|
type ActionArgumentChoice struct {
|
|
Value string `koanf:"value"`
|
|
Title string `koanf:"title"`
|
|
}
|
|
|
|
// RateSpec allows you to set a max frequency for an action.
|
|
type RateSpec struct {
|
|
Limit int `koanf:"limit"`
|
|
Duration string `koanf:"duration"`
|
|
}
|
|
|
|
// WebhookConfig defines configuration for generic webhook triggers.
|
|
type WebhookConfig struct {
|
|
Secret string `koanf:"secret"` // Optional: secret for signature verification
|
|
AuthType string `koanf:"authType"` // Optional: "hmac-sha256", "hmac-sha1", "bearer", "basic", "none"
|
|
AuthHeader string `koanf:"authHeader"` // Optional: custom header name for auth (default: "X-Webhook-Signature")
|
|
MatchHeaders map[string]string `koanf:"matchHeaders"` // Match HTTP headers
|
|
MatchPath string `koanf:"matchPath"` // JSONPath expression to match in request body (format: "jsonpath=value" or just "jsonpath")
|
|
MatchQuery map[string]string `koanf:"matchQuery"` // Match URL query parameters
|
|
Extract map[string]string `koanf:"extract"` // Map action argument names to JSONPath expressions
|
|
Template string `koanf:"template"` // Optional: template name (e.g., "github-push", "github-pr")
|
|
Justification string `koanf:"justification"` // Optional JSONPath to extract justification from webhook body
|
|
}
|
|
|
|
// Entity represents a "thing" that can have multiple actions associated with it.
|
|
// for example, a media player with a start and stop action.
|
|
type EntityFile struct {
|
|
File string `koanf:"file"`
|
|
Name string `koanf:"name"`
|
|
Icon string `koanf:"icon"`
|
|
}
|
|
|
|
// PermissionsList defines what users can do with an action.
|
|
type PermissionsList struct {
|
|
View bool `koanf:"view"`
|
|
Exec bool `koanf:"exec"`
|
|
Logs bool `koanf:"logs"`
|
|
Kill bool `koanf:"kill"`
|
|
}
|
|
|
|
// AccessControlList defines what permissions apply to a user or user group.
|
|
type AccessControlList struct {
|
|
Name string `koanf:"name"`
|
|
AddToEveryAction bool `koanf:"addToEveryAction"`
|
|
MatchUsergroups []string `koanf:"matchUsergroups"`
|
|
MatchUsernames []string `koanf:"matchUsernames"`
|
|
Permissions PermissionsList `koanf:"permissions"`
|
|
Policy ConfigurationPolicy `koanf:"policy"`
|
|
}
|
|
|
|
// ConfigurationPolicy defines global settings which are overridden with an ACL.
|
|
type ConfigurationPolicy struct {
|
|
ShowDiagnostics bool `koanf:"showDiagnostics"`
|
|
ShowLogList bool `koanf:"showLogList"`
|
|
ShowVersionNumber bool `koanf:"showVersionNumber"`
|
|
}
|
|
|
|
type PrometheusConfig struct {
|
|
Enabled bool `koanf:"enabled"`
|
|
DefaultGoMetrics bool `koanf:"defaultGoMetrics"`
|
|
}
|
|
|
|
// SecurityConfig allows users to fine tune the security related HTTP headers and cookie options.
|
|
type SecurityConfig struct {
|
|
HeaderContentSecurityPolicy bool `koanf:"headerContentSecurityPolicy"`
|
|
ContentSecurityPolicy string `koanf:"contentSecurityPolicy"`
|
|
HeaderXContentTypeOptions bool `koanf:"headerXContentTypeOptions"`
|
|
HeaderXFrameOptions bool `koanf:"headerXFrameOptions"`
|
|
XFrameOptions string `koanf:"xFrameOptions"`
|
|
ForceSecureCookies bool `koanf:"forceSecureCookies"`
|
|
}
|
|
|
|
// Config is the global config used through the whole app.
|
|
type Config struct {
|
|
UseSingleHTTPFrontend bool `koanf:"useSingleHTTPFrontend"`
|
|
ThemeName string `koanf:"themeName"`
|
|
ThemeCacheDisabled bool `koanf:"themeCacheDisabled"`
|
|
ListenAddressSingleHTTPFrontend string `koanf:"listenAddressSingleHTTPFrontend"`
|
|
ListenAddressWebUI string `koanf:"listenAddressWebUI"`
|
|
ListenAddressRestActions string `koanf:"listenAddressRestActions"`
|
|
ListenAddressPrometheus string `koanf:"listenAddressPrometheus"`
|
|
ExternalRestAddress string `koanf:"externalRestAddress"`
|
|
LogLevel string `koanf:"logLevel"`
|
|
LogDebugOptions LogDebugOptions `koanf:"logDebugOptions"`
|
|
LogHistoryPageSize int64 `koanf:"logHistoryPageSize"`
|
|
ActionGroups map[string]*ActionGroup `koanf:"actionGroups"`
|
|
Actions []*Action `koanf:"actions"`
|
|
Entities []*EntityFile `koanf:"entities"`
|
|
Dashboards []*DashboardComponent `koanf:"dashboards"`
|
|
CheckForUpdates bool `koanf:"checkForUpdates"`
|
|
PageTitle string `koanf:"pageTitle"`
|
|
ShowFooter bool `koanf:"showFooter"`
|
|
ShowNavigation bool `koanf:"showNavigation"`
|
|
ShowNewVersions bool `koanf:"showNewVersions"`
|
|
ShowNavigateOnStartIcons bool `koanf:"showNavigateOnStartIcons"`
|
|
EnableCustomJs bool `koanf:"enableCustomJs"`
|
|
AuthJwtCookieName string `koanf:"authJwtCookieName"`
|
|
AuthJwtHeader string `koanf:"authJwtHeader"`
|
|
AuthJwtAud string `koanf:"authJwtAud"`
|
|
AuthJwtDomain string `koanf:"authJwtDomain"`
|
|
AuthJwtCertsURL string `koanf:"authJwtCertsUrl"`
|
|
AuthJwtHmacSecret string `koanf:"authJwtHmacSecret"` // mutually exclusive with pub key config fields
|
|
AuthJwtClaimUsername string `koanf:"authJwtClaimUsername"`
|
|
AuthJwtClaimUserGroup string `koanf:"authJwtClaimUserGroup"`
|
|
AuthJwtPubKeyPath string `koanf:"authJwtPubKeyPath"` // will read pub key from file on disk
|
|
AuthHttpHeaderUsername string `koanf:"authHttpHeaderUsername"`
|
|
AuthHttpHeaderUserGroup string `koanf:"authHttpHeaderUserGroup"`
|
|
AuthHttpHeaderUserGroupSep string `koanf:"authHttpHeaderUserGroupSep"`
|
|
AuthLocalUsers AuthLocalUsersConfig `koanf:"authLocalUsers"`
|
|
AuthLoginUrl string `koanf:"authLoginUrl"`
|
|
AuthRequireGuestsToLogin bool `koanf:"authRequireGuestsToLogin"`
|
|
AuthOAuth2RedirectURL string `koanf:"authOAuth2RedirectUrl"`
|
|
AuthOAuth2Providers map[string]*OAuth2Provider `koanf:"authOAuth2Providers"`
|
|
DefaultPermissions PermissionsList `koanf:"defaultPermissions"`
|
|
DefaultPolicy ConfigurationPolicy `koanf:"defaultPolicy"`
|
|
AccessControlLists []*AccessControlList `koanf:"accessControlLists"`
|
|
WebUIDir string `koanf:"webUIDir"`
|
|
CronSupportForSeconds bool `koanf:"cronSupportForSeconds"`
|
|
SectionNavigationStyle string `koanf:"sectionNavigationStyle"`
|
|
DefaultOnClick string `koanf:"defaultOnClick"`
|
|
DefaultPopupOnStart string `koanf:"defaultPopupOnStart"`
|
|
InsecureAllowDumpOAuth2UserData bool `koanf:"insecureAllowDumpOAuth2UserData"`
|
|
InsecureAllowDumpVars bool `koanf:"insecureAllowDumpVars"`
|
|
InsecureAllowDumpSos bool `koanf:"insecureAllowDumpSos"`
|
|
InsecureAllowDumpActionMap bool `koanf:"insecureAllowDumpActionMap"`
|
|
InsecureAllowDumpJwtClaims bool `koanf:"insecureAllowDumpJwtClaims"`
|
|
Prometheus PrometheusConfig `koanf:"prometheus"`
|
|
Security SecurityConfig `koanf:"security"`
|
|
SaveLogs SaveLogsConfig `koanf:"saveLogs"`
|
|
ServiceLogs ServiceLogsConfig `koanf:"serviceLogs"`
|
|
DefaultIconForActions string `koanf:"defaultIconForActions"`
|
|
DefaultIconForDirectories string `koanf:"defaultIconForDirectories"`
|
|
DefaultIconForBack string `koanf:"defaultIconForBack"`
|
|
AdditionalNavigationLinks []*NavigationLink `koanf:"additionalNavigationLinks"`
|
|
ServiceHostMode string `koanf:"serviceHostMode"`
|
|
StyleMods []string `koanf:"styleMods"`
|
|
BannerMessage string `koanf:"bannerMessage"`
|
|
BannerCSS string `koanf:"bannerCss"`
|
|
Include string `koanf:"include"`
|
|
|
|
sourceFiles []string
|
|
}
|
|
|
|
type AuthLocalUsersConfig struct {
|
|
Enabled bool `koanf:"enabled"`
|
|
Users []*LocalUser `koanf:"users"`
|
|
}
|
|
|
|
type LocalUser struct {
|
|
Username string `koanf:"username"`
|
|
Usergroup string `koanf:"usergroup"`
|
|
Password string `koanf:"password"`
|
|
ApiKey string `koanf:"apiKey"`
|
|
}
|
|
|
|
type OAuth2Provider struct {
|
|
Name string `koanf:"name"`
|
|
Title string `koanf:"title"`
|
|
ClientID string `koanf:"clientId"`
|
|
ClientSecret string `koanf:"clientSecret"`
|
|
Icon string `koanf:"icon"`
|
|
Scopes []string `koanf:"scopes"`
|
|
AuthUrl string `koanf:"authUrl"`
|
|
TokenUrl string `koanf:"tokenUrl"`
|
|
WhoamiUrl string `koanf:"whoamiUrl"`
|
|
UsernameField string `koanf:"usernameField"`
|
|
UserGroupField string `koanf:"userGroupField"`
|
|
InsecureSkipVerify bool `koanf:"insecureSkipVerify"`
|
|
CallbackTimeout int `koanf:"callbackTimeout"`
|
|
CertBundlePath string `koanf:"certBundlePath"`
|
|
AddToUsergroup string `koanf:"addToUsergroup"`
|
|
}
|
|
|
|
type NavigationLink struct {
|
|
Title string `koanf:"title"`
|
|
Url string `koanf:"url"`
|
|
Target string `koanf:"target"`
|
|
}
|
|
|
|
type SaveLogsConfig struct {
|
|
ResultsDirectory string `koanf:"resultsDirectory"`
|
|
OutputDirectory string `koanf:"outputDirectory"`
|
|
}
|
|
|
|
type ServiceLogsConfig struct {
|
|
Directory string `koanf:"directory"`
|
|
}
|
|
|
|
type LogDebugOptions struct {
|
|
SingleFrontendRequests bool `koanf:"singleFrontendRequests"`
|
|
SingleFrontendRequestHeaders bool `koanf:"singleFrontendRequestHeaders"`
|
|
AclCheckStarted bool `koanf:"aclCheckStarted"`
|
|
AclMatched bool `koanf:"aclMatched"`
|
|
AclNotMatched bool `koanf:"aclNotMatched"`
|
|
AclNoneMatched bool `koanf:"aclNoneMatched"`
|
|
}
|
|
|
|
type DashboardComponent struct {
|
|
Title string `koanf:"title"`
|
|
Type string `koanf:"type"`
|
|
Entity string `koanf:"entity"`
|
|
Icon string `koanf:"icon"`
|
|
CssClass string `koanf:"cssClass"`
|
|
InlineAction *Action `koanf:"inlineAction"`
|
|
Contents []*DashboardComponent `koanf:"contents"`
|
|
}
|
|
|
|
func DefaultConfig() *Config {
|
|
return DefaultConfigWithBasePort(1337)
|
|
}
|
|
|
|
// DefaultConfig gets a new Config structure with sensible default values.
|
|
func DefaultConfigWithBasePort(basePort int) *Config {
|
|
config := Config{}
|
|
config.UseSingleHTTPFrontend = true
|
|
config.PageTitle = "OliveTin"
|
|
config.ShowFooter = true
|
|
config.ShowNavigation = true
|
|
config.ShowNewVersions = true
|
|
config.ShowNavigateOnStartIcons = true
|
|
config.EnableCustomJs = false
|
|
config.ExternalRestAddress = "."
|
|
config.LogLevel = "INFO"
|
|
config.LogHistoryPageSize = 10
|
|
config.CheckForUpdates = false
|
|
config.DefaultPermissions.Exec = true
|
|
config.DefaultPermissions.View = true
|
|
config.DefaultPermissions.Logs = true
|
|
config.DefaultPermissions.Kill = true
|
|
config.AuthJwtClaimUsername = "name"
|
|
config.AuthJwtClaimUserGroup = "group"
|
|
config.AuthRequireGuestsToLogin = false
|
|
config.WebUIDir = "./webui"
|
|
config.CronSupportForSeconds = false
|
|
config.SectionNavigationStyle = "sidebar"
|
|
config.DefaultOnClick = "nothing"
|
|
config.DefaultPopupOnStart = "nothing"
|
|
config.InsecureAllowDumpVars = false
|
|
config.InsecureAllowDumpSos = false
|
|
config.InsecureAllowDumpActionMap = false
|
|
config.InsecureAllowDumpJwtClaims = false
|
|
config.Prometheus.Enabled = false
|
|
config.Prometheus.DefaultGoMetrics = false
|
|
config.Security.HeaderContentSecurityPolicy = true
|
|
config.Security.ContentSecurityPolicy = ContentSecurityPolicyDefault
|
|
config.Security.HeaderXContentTypeOptions = true
|
|
config.Security.HeaderXFrameOptions = true
|
|
config.Security.XFrameOptions = "DENY"
|
|
config.DefaultIconForActions = "hugeicons:CommandLineIcon"
|
|
config.DefaultIconForDirectories = "📁"
|
|
config.DefaultIconForBack = "«"
|
|
config.ThemeCacheDisabled = false
|
|
config.ServiceHostMode = ""
|
|
|
|
config.ListenAddressSingleHTTPFrontend = fmt.Sprintf("0.0.0.0:%d", basePort)
|
|
config.ListenAddressRestActions = fmt.Sprintf("localhost:%d", basePort+1)
|
|
config.ListenAddressWebUI = fmt.Sprintf("localhost:%d", basePort+3)
|
|
config.ListenAddressPrometheus = fmt.Sprintf("localhost:%d", basePort+4)
|
|
|
|
config.DefaultPolicy.ShowDiagnostics = true
|
|
config.DefaultPolicy.ShowLogList = true
|
|
config.DefaultPolicy.ShowVersionNumber = true
|
|
|
|
return &config
|
|
}
|