Omit empty fields from bootstrap config output
probod-bootstrap was writing empty strings and stub blocks such as
`esign: {}` into generated YAML. The post-marshal prune pass caused
part of that by stripping empty leaf strings while leaving empty
parent maps behind.
Drop the prune round-trip in WriteConfig and rely on struct-level
omitzero/omitempty tags plus custom IsZero() helpers on probodconfig.
Only include LLM providers when an API key is set, use a nil map for
extra API headers, and extend the dev-config Makefile recipe with the
local dev defaults already documented in .env.example.
Config loading is unchanged: omitted keys still decode to Go zero
values.
Signed-off-by: Ludovic Vielle <ludovic@probo.com>
This commit is contained in:
@@ -15,11 +15,19 @@
|
||||
package probodconfig
|
||||
|
||||
type CorsConfig struct {
|
||||
AllowedOrigins []string `json:"allowed-origins"`
|
||||
AllowedOrigins []string `json:"allowed-origins,omitzero,omitempty"`
|
||||
}
|
||||
|
||||
func (c CorsConfig) IsZero() bool {
|
||||
return len(c.AllowedOrigins) == 0
|
||||
}
|
||||
|
||||
type ProxyProtocolConfig struct {
|
||||
TrustedProxies []string `json:"trusted-proxies"`
|
||||
TrustedProxies []string `json:"trusted-proxies,omitzero,omitempty"`
|
||||
}
|
||||
|
||||
func (c ProxyProtocolConfig) IsZero() bool {
|
||||
return len(c.TrustedProxies) == 0
|
||||
}
|
||||
|
||||
type GraphQLConfig struct {
|
||||
@@ -30,9 +38,9 @@ type GraphQLConfig struct {
|
||||
}
|
||||
|
||||
type APIConfig struct {
|
||||
Addr string `json:"addr"`
|
||||
ProxyProtocol ProxyProtocolConfig `json:"proxy-protocol"`
|
||||
Cors CorsConfig `json:"cors"`
|
||||
ExtraHeaderFields map[string]string `json:"extra-header-fields"`
|
||||
GraphQL GraphQLConfig `json:"graphql"`
|
||||
Addr string `json:"addr,omitempty"`
|
||||
ProxyProtocol ProxyProtocolConfig `json:"proxy-protocol,omitzero"`
|
||||
Cors CorsConfig `json:"cors,omitzero"`
|
||||
ExtraHeaderFields map[string]string `json:"extra-header-fields,omitzero,omitempty"`
|
||||
GraphQL GraphQLConfig `json:"graphql,omitzero"`
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ type AuthConfig struct {
|
||||
PasswordResetTokenValidity int `json:"password-reset-token-validity"`
|
||||
MagicLinkTokenValidity int `json:"magic-link-token-validity"`
|
||||
SAML SAMLConfig `json:"saml"`
|
||||
Google OIDCProviderConfig `json:"google"`
|
||||
Microsoft OIDCProviderConfig `json:"microsoft"`
|
||||
Google OIDCProviderConfig `json:"google,omitzero"`
|
||||
Microsoft OIDCProviderConfig `json:"microsoft,omitzero"`
|
||||
OAuth2Server OAuth2ServerConfig `json:"oauth2-server"`
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ type OAuth2ServerConfig struct {
|
||||
RefreshTokenDuration int `json:"refresh-token-duration"`
|
||||
AuthorizationCodeDuration int `json:"authorization-code-duration"`
|
||||
DeviceCodeDuration int `json:"device-code-duration"`
|
||||
CIMDAllowedClientIDs []string `json:"cimd-allowed-client-ids"`
|
||||
CIMDAllowedClientIDs []string `json:"cimd-allowed-client-ids,omitempty"`
|
||||
}
|
||||
|
||||
type OAuth2SigningKeyConfig struct {
|
||||
@@ -48,10 +48,10 @@ type OAuth2SigningKeyConfig struct {
|
||||
}
|
||||
|
||||
type CookieConfig struct {
|
||||
Domain string `json:"domain"`
|
||||
Domain string `json:"domain,omitempty"`
|
||||
Secret string `json:"secret"`
|
||||
Duration int `json:"duration"`
|
||||
Name string `json:"name"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Secure bool `json:"secure"`
|
||||
}
|
||||
|
||||
|
||||
@@ -15,10 +15,10 @@
|
||||
package probodconfig
|
||||
|
||||
type AWSConfig struct {
|
||||
Region string `json:"region"`
|
||||
Bucket string `json:"bucket"`
|
||||
AccessKeyID string `json:"access-key-id"`
|
||||
SecretAccessKey string `json:"secret-access-key"`
|
||||
Endpoint string `json:"endpoint"`
|
||||
Region string `json:"region,omitempty"`
|
||||
Bucket string `json:"bucket,omitempty"`
|
||||
AccessKeyID string `json:"access-key-id,omitempty"`
|
||||
SecretAccessKey string `json:"secret-access-key,omitempty"`
|
||||
Endpoint string `json:"endpoint,omitempty"`
|
||||
UsePathStyle bool `json:"use-path-style"`
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ type (
|
||||
|
||||
// TracingConfig contains tracing configuration.
|
||||
TracingConfig struct {
|
||||
Addr string `json:"addr"`
|
||||
Addr string `json:"addr,omitempty"`
|
||||
MaxBatchSize int `json:"max-batch-size"`
|
||||
BatchTimeout int `json:"batch-timeout"`
|
||||
ExportTimeout int `json:"export-timeout"`
|
||||
@@ -44,12 +44,12 @@ type (
|
||||
|
||||
// ESignConfig contains electronic signature configuration.
|
||||
ESignConfig struct {
|
||||
TSAURL string `json:"tsa-url"`
|
||||
TSAURL string `json:"tsa-url,omitempty"`
|
||||
}
|
||||
|
||||
// Config represents the probod application configuration.
|
||||
Config struct {
|
||||
BaseURL string `json:"base-url"`
|
||||
BaseURL string `json:"base-url,omitempty"`
|
||||
EncryptionKey string `json:"encryption-key"`
|
||||
Pg PgConfig `json:"pg"`
|
||||
Api APIConfig `json:"api"`
|
||||
@@ -57,7 +57,7 @@ type (
|
||||
TrustCenter TrustCenterConfig `json:"trust-center"`
|
||||
AWS AWSConfig `json:"aws"`
|
||||
Notifications NotificationsConfig `json:"notifications"`
|
||||
Connectors []ConnectorConfig `json:"connectors"`
|
||||
Connectors []ConnectorConfig `json:"connectors,omitempty"`
|
||||
Agents AgentsConfig `json:"llm"`
|
||||
EvidenceDescriber EvidenceDescriberConfig `json:"evidence-describer"`
|
||||
ThirdPartyVetting ThirdPartyVettingWorkerConfig `json:"third-party-vetting-worker"`
|
||||
@@ -66,17 +66,17 @@ type (
|
||||
CommonPatternEnrichmentWorker CommonPatternEnrichmentWorkerConfig `json:"common-pattern-enrichment-worker"`
|
||||
CommonThirdPartyEnrichmentWorker CommonThirdPartyEnrichmentWorkerConfig `json:"common-third-party-enrichment-worker"`
|
||||
|
||||
ChromeDPAddr string `json:"chrome-dp-addr"`
|
||||
ChromeDPAddr string `json:"chrome-dp-addr,omitempty"`
|
||||
CustomDomains CustomDomainsConfig `json:"custom-domains"`
|
||||
SCIMBridge SCIMBridgeConfig `json:"scim-bridge"`
|
||||
ESign ESignConfig `json:"esign"`
|
||||
ESign ESignConfig `json:"esign,omitzero"`
|
||||
Branding bool `json:"branding"`
|
||||
}
|
||||
|
||||
// TrustCenterConfig contains trust center server configuration.
|
||||
TrustCenterConfig struct {
|
||||
HTTPAddr string `json:"http-addr"`
|
||||
HTTPSAddr string `json:"https-addr"`
|
||||
ProxyProtocol ProxyProtocolConfig `json:"proxy-protocol"`
|
||||
HTTPAddr string `json:"http-addr,omitempty"`
|
||||
HTTPSAddr string `json:"https-addr,omitempty"`
|
||||
ProxyProtocol ProxyProtocolConfig `json:"proxy-protocol,omitzero"`
|
||||
}
|
||||
)
|
||||
|
||||
@@ -17,16 +17,16 @@ package probodconfig
|
||||
type CustomDomainsConfig struct {
|
||||
RenewalInterval int `json:"renewal-interval"`
|
||||
ProvisionInterval int `json:"provision-interval"`
|
||||
ResolverAddr string `json:"resolver-addr"`
|
||||
ResolverAddr string `json:"resolver-addr,omitempty"`
|
||||
CnameTarget string `json:"cname-target"`
|
||||
CAAIssuerDomain string `json:"caa-issuer-domain"`
|
||||
ACME ACMEConfig `json:"acme"`
|
||||
ACME ACMEConfig `json:"acme,omitzero"`
|
||||
}
|
||||
|
||||
type ACMEConfig struct {
|
||||
Directory string `json:"directory"`
|
||||
Email string `json:"email"`
|
||||
KeyType string `json:"key-type"`
|
||||
AccountKey string `json:"account-key"`
|
||||
RootCA string `json:"root-ca"`
|
||||
Directory string `json:"directory,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
KeyType string `json:"key-type,omitempty"`
|
||||
AccountKey string `json:"account-key,omitempty"`
|
||||
RootCA string `json:"root-ca,omitempty"`
|
||||
}
|
||||
|
||||
@@ -18,17 +18,17 @@ type (
|
||||
// LLMProviderConfig holds authentication and connection settings for an
|
||||
// LLM provider (e.g. OpenAI, Anthropic).
|
||||
LLMProviderConfig struct {
|
||||
Type string `json:"type"` // "openai", "anthropic", "bedrock"
|
||||
APIKey string `json:"api-key"` // for OpenAI and Anthropic
|
||||
Type string `json:"type"` // "openai", "anthropic", "bedrock"
|
||||
APIKey string `json:"api-key,omitempty"` // for OpenAI and Anthropic
|
||||
}
|
||||
|
||||
// LLMAgentConfig holds model parameters for a single agent. Provider
|
||||
// references one of the keys in AgentsConfig.Providers.
|
||||
LLMAgentConfig struct {
|
||||
Provider string `json:"provider"` // key into AgentsConfig.Providers
|
||||
ModelName string `json:"model-name"`
|
||||
Temperature *float64 `json:"temperature"`
|
||||
MaxTokens *int `json:"max-tokens"`
|
||||
Provider string `json:"provider,omitempty"` // key into AgentsConfig.Providers
|
||||
ModelName string `json:"model-name,omitempty"`
|
||||
Temperature *float64 `json:"temperature,omitempty"`
|
||||
MaxTokens *int `json:"max-tokens,omitempty"`
|
||||
}
|
||||
|
||||
// EvidenceDescriberConfig holds worker-side tuning for the evidence
|
||||
@@ -95,26 +95,38 @@ type (
|
||||
// AgentToolsConfig holds API keys and settings for external tools
|
||||
// that agents can use (web search, scraping, etc.).
|
||||
AgentToolsConfig struct {
|
||||
FirecrawlAPIKey string `json:"firecrawl-api-key"`
|
||||
FirecrawlAPIKey string `json:"firecrawl-api-key,omitempty"`
|
||||
}
|
||||
|
||||
// AgentsConfig groups LLM provider credentials and per-agent model
|
||||
// settings. Default is used as a fallback when an agent-specific field
|
||||
// is zero-valued.
|
||||
AgentsConfig struct {
|
||||
Providers map[string]LLMProviderConfig `json:"providers"`
|
||||
Providers map[string]LLMProviderConfig `json:"providers,omitempty"`
|
||||
Default LLMAgentConfig `json:"defaults"`
|
||||
Probo LLMAgentConfig `json:"probo"`
|
||||
EvidenceDescriber LLMAgentConfig `json:"evidence-describer"`
|
||||
ThirdPartyVetter LLMAgentConfig `json:"third-party-vetter"`
|
||||
ThirdPartyDisambiguation LLMAgentConfig `json:"third-party-disambiguation"`
|
||||
TrackerMapping LLMAgentConfig `json:"tracker-mapping"`
|
||||
TrackerEnrichment LLMAgentConfig `json:"tracker-enrichment"`
|
||||
CommonThirdPartyEnrichment LLMAgentConfig `json:"common-third-party-enrichment"`
|
||||
Tools AgentToolsConfig `json:"tools"`
|
||||
Probo LLMAgentConfig `json:"probo,omitzero"`
|
||||
EvidenceDescriber LLMAgentConfig `json:"evidence-describer,omitzero"`
|
||||
ThirdPartyVetter LLMAgentConfig `json:"third-party-vetter,omitzero"`
|
||||
ThirdPartyDisambiguation LLMAgentConfig `json:"third-party-disambiguation,omitzero"`
|
||||
TrackerMapping LLMAgentConfig `json:"tracker-mapping,omitzero"`
|
||||
TrackerEnrichment LLMAgentConfig `json:"tracker-enrichment,omitzero"`
|
||||
CommonThirdPartyEnrichment LLMAgentConfig `json:"common-third-party-enrichment,omitzero"`
|
||||
Tools AgentToolsConfig `json:"tools,omitzero"`
|
||||
}
|
||||
)
|
||||
|
||||
func (c LLMProviderConfig) IsZero() bool {
|
||||
return c.APIKey == ""
|
||||
}
|
||||
|
||||
func (c LLMAgentConfig) IsZero() bool {
|
||||
return c.Provider == "" && c.ModelName == ""
|
||||
}
|
||||
|
||||
func (c AgentToolsConfig) IsZero() bool {
|
||||
return c.FirecrawlAPIKey == ""
|
||||
}
|
||||
|
||||
// ResolveAgent returns a fully populated LLMAgentConfig by filling in
|
||||
// zero-valued fields from the default config.
|
||||
func (c *AgentsConfig) ResolveAgent(agent LLMAgentConfig) LLMAgentConfig {
|
||||
|
||||
@@ -16,15 +16,15 @@ package probodconfig
|
||||
|
||||
type MailerConfig struct {
|
||||
MailerInterval int `json:"mailer-interval"`
|
||||
SenderName string `json:"sender-name"`
|
||||
SenderEmail string `json:"sender-email"`
|
||||
SMTP SMTPConfig `json:"smtp"`
|
||||
SenderName string `json:"sender-name,omitempty"`
|
||||
SenderEmail string `json:"sender-email,omitempty"`
|
||||
SMTP SMTPConfig `json:"smtp,omitzero"`
|
||||
}
|
||||
|
||||
type SMTPConfig struct {
|
||||
Addr string `json:"addr"`
|
||||
User string `json:"user"`
|
||||
Password string `json:"password"`
|
||||
Addr string `json:"addr,omitempty"`
|
||||
User string `json:"user,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
TLSRequired bool `json:"tls-required"`
|
||||
HelloName string `json:"hello-name"`
|
||||
HelloName string `json:"hello-name,omitempty"`
|
||||
}
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
package probodconfig
|
||||
|
||||
type OIDCProviderConfig struct {
|
||||
ClientID string `json:"client-id"`
|
||||
ClientSecret string `json:"client-secret"`
|
||||
Enabled bool `json:"enabled"`
|
||||
ClientID string `json:"client-id,omitempty"`
|
||||
ClientSecret string `json:"client-secret,omitempty"`
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
}
|
||||
|
||||
func (c OIDCProviderConfig) IsZero() bool {
|
||||
return c.ClientID == "" && c.ClientSecret == ""
|
||||
}
|
||||
|
||||
@@ -23,17 +23,17 @@ import (
|
||||
)
|
||||
|
||||
type PgConfig struct {
|
||||
Addr string `json:"addr"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
Database string `json:"database"`
|
||||
Addr string `json:"addr,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Database string `json:"database,omitempty"`
|
||||
PoolSize int32 `json:"pool-size"`
|
||||
MinPoolSize int32 `json:"min-pool-size"`
|
||||
MaxConnIdleTimeSeconds int `json:"max-conn-idle-time-seconds"`
|
||||
MaxConnLifetimeSeconds int `json:"max-conn-lifetime-seconds"`
|
||||
MaxConnLifetimeJitterSeconds int `json:"max-conn-lifetime-jitter-seconds"`
|
||||
HealthCheckPeriodSeconds int `json:"health-check-period-seconds"`
|
||||
CACertBundle string `json:"ca-cert-bundle"`
|
||||
CACertBundle string `json:"ca-cert-bundle,omitempty"`
|
||||
Debug bool `json:"debug"`
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ type SAMLConfig struct {
|
||||
Certificate string `json:"certificate"`
|
||||
PrivateKey string `json:"private-key"`
|
||||
DomainVerificationIntervalSeconds int `json:"domain-verification-interval-seconds"`
|
||||
DomainVerificationResolverAddr string `json:"domain-verification-resolver-addr"`
|
||||
DomainVerificationResolverAddr string `json:"domain-verification-resolver-addr,omitempty"`
|
||||
}
|
||||
|
||||
func (c SAMLConfig) SessionDurationTime() time.Duration {
|
||||
|
||||
@@ -16,5 +16,5 @@ package probodconfig
|
||||
|
||||
type SlackConfig struct {
|
||||
SenderInterval int `json:"sender-interval"`
|
||||
SigningSecret string `json:"signing-secret"`
|
||||
SigningSecret string `json:"signing-secret,omitempty"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user