diff --git a/config/setup.go b/config/setup.go index 9a44cc2..f0a6ee0 100644 --- a/config/setup.go +++ b/config/setup.go @@ -38,6 +38,9 @@ func MergeConfig(ctx *cli.Context, config *Config) { } mergeServerConfig(ctx, &config.Server) + mergeGiteaConfig(ctx, &config.Gitea) + mergeDatabaseConfig(ctx, &config.Database) + mergeACMEConfig(ctx, &config.ACME) } func mergeServerConfig(ctx *cli.Context, config *ServerConfig) { @@ -74,4 +77,49 @@ func mergeGiteaConfig(ctx *cli.Context, config *GiteaConfig) { if ctx.IsSet("gitea-root") { config.Root = ctx.String("gitea-root") } + if ctx.IsSet("gitea-api-token") { + config.Token = ctx.String("gitea-api-token") + } + if ctx.IsSet("enable-lfs-support") { + config.LFSEnabled = ctx.Bool("enable-lfs-support") + } + if ctx.IsSet("enable-symlink-support") { + config.FollowSymlinks = ctx.Bool("enable-symlink-support") + } +} + +func mergeDatabaseConfig(ctx *cli.Context, config *DatabaseConfig) { + if ctx.IsSet("db-type") { + config.Type = ctx.String("db-type") + } + if ctx.IsSet("db-conn") { + config.Conn = ctx.String("db-conn") + } +} + +func mergeACMEConfig(ctx *cli.Context, config *ACMEConfig) { + if ctx.IsSet("acme-email") { + config.Email = ctx.String("acme-email") + } + if ctx.IsSet("acme-api-endpoint") { + config.APIEndpoint = ctx.String("acme-api-endpoint") + } + if ctx.IsSet("acme-accept-terms") { + config.AcceptTerms = ctx.Bool("acme-accept-terms") + } + if ctx.IsSet("acme-use-rate-limits") { + config.UseRateLimits = ctx.Bool("acme-use-rate-limits") + } + if ctx.IsSet("acme-eab-hmac") { + config.EAB_HMAC = ctx.String("acme-eab-hmac") + } + if ctx.IsSet("acme-eab-kid") { + config.EAB_KID = ctx.String("acme-eab-kid") + } + if ctx.IsSet("dns-provider") { + config.DNSProvider = ctx.String("dns-provider") + } + if ctx.IsSet("acme-account-config") { + config.AccountConfigFile = ctx.String("acme-account-config") + } } diff --git a/config/setup_test.go b/config/setup_test.go index 97704c8..c08c056 100644 --- a/config/setup_test.go +++ b/config/setup_test.go @@ -59,6 +59,116 @@ func TestReadConfigShouldReturnConfigFromFileWhenConfigArgPresent(t *testing.T) ) } +func TestMergeConfigShouldReplaceAllExistingValuesGivenAllArgsExist(t *testing.T) { + runApp( + t, + func(ctx *cli.Context) error { + cfg := &Config{ + LogLevel: "original", + Server: ServerConfig{ + Host: "original", + Port: 8080, + HttpPort: 80, + HttpServerEnabled: false, + MainDomain: "original", + RawDomain: "original", + AllowedCorsDomains: []string{"original"}, + BlacklistedPaths: []string{"original"}, + }, + Gitea: GiteaConfig{ + Root: "original", + Token: "original", + LFSEnabled: false, + FollowSymlinks: false, + }, + Database: DatabaseConfig{ + Type: "original", + Conn: "original", + }, + ACME: ACMEConfig{ + Email: "original", + APIEndpoint: "original", + AcceptTerms: false, + UseRateLimits: false, + EAB_HMAC: "original", + EAB_KID: "original", + DNSProvider: "original", + AccountConfigFile: "original", + }, + } + + MergeConfig(ctx, cfg) + + expectedConfig := &Config{ + LogLevel: "changed", + Server: ServerConfig{ + Host: "changed", + Port: 8443, + HttpPort: 443, + HttpServerEnabled: true, + MainDomain: "changed", + RawDomain: "changed", + AllowedCorsDomains: []string{"changed"}, + BlacklistedPaths: append([]string{"changed"}, ALWAYS_BLACKLISTED_PATHS...), + }, + Gitea: GiteaConfig{ + Root: "changed", + Token: "changed", + LFSEnabled: true, + FollowSymlinks: true, + }, + Database: DatabaseConfig{ + Type: "changed", + Conn: "changed", + }, + ACME: ACMEConfig{ + Email: "changed", + APIEndpoint: "changed", + AcceptTerms: true, + UseRateLimits: true, + EAB_HMAC: "changed", + EAB_KID: "changed", + DNSProvider: "changed", + AccountConfigFile: "changed", + }, + } + + assert.Equal(t, expectedConfig, cfg) + + return nil + }, + []string{ + "--log-level", "changed", + // Server + "--pages-domain", "changed", + "--raw-domain", "changed", + "--allowed-cors-domains", "changed", + "--blacklisted-paths", "changed", + "--host", "changed", + "--port", "8443", + "--http-port", "443", + "--enable-http-server", + // Gitea + "--gitea-root", "changed", + "--gitea-api-token", "changed", + "--enable-lfs-support", + "--enable-symlink-support", + // Database + "--db-type", "changed", + "--db-conn", "changed", + // ACME + "--acme-email", "changed", + "--acme-api-endpoint", "changed", + "--acme-accept-terms", + "--acme-use-rate-limits", + "--acme-eab-hmac", "changed", + "--acme-eab-kid", "changed", + "--dns-provider", "changed", + "--acme-account-config", "changed", + }, + ) +} + func TestMergeServerConfigShouldAddDefaultBlacklistedPathsToBlacklistedPaths(t *testing.T) { runApp( t, @@ -132,8 +242,8 @@ func TestMergeServerConfigShouldReplaceOnlyOneValueExistingValueGivenOnlyOneArgE {args: []string{"--enable-http-server"}, callback: func(sc *ServerConfig) { sc.HttpServerEnabled = true }}, {args: []string{"--pages-domain", "changed"}, callback: func(sc *ServerConfig) { sc.MainDomain = "changed" }}, {args: []string{"--raw-domain", "changed"}, callback: func(sc *ServerConfig) { sc.RawDomain = "changed" }}, - {args: []string{"--allowed-cors-domains", "changed"}, callback: func(sc *ServerConfig) { sc.AllowedCorsDomains = []string{"changed", "changed"} }}, // don't ask why, the cli lib always adds two strings when running all tests and one when running a single test - {args: []string{"--blacklisted-paths", "changed"}, callback: func(sc *ServerConfig) { sc.BlacklistedPaths = []string{"changed", "changed"} }}, // same here + {args: []string{"--allowed-cors-domains", "changed"}, callback: func(sc *ServerConfig) { sc.AllowedCorsDomains = []string{"changed"} }}, + {args: []string{"--blacklisted-paths", "changed"}, callback: func(sc *ServerConfig) { sc.BlacklistedPaths = []string{"changed"} }}, } for _, pair := range testValuePairs { @@ -165,3 +275,223 @@ func TestMergeServerConfigShouldReplaceOnlyOneValueExistingValueGivenOnlyOneArgE ) } } + +func TestMergeGiteaConfigShouldReplaceAllExistingValuesGivenAllArgsExist(t *testing.T) { + runApp( + t, + func(ctx *cli.Context) error { + cfg := &GiteaConfig{ + Root: "original", + Token: "original", + LFSEnabled: false, + FollowSymlinks: false, + } + + mergeGiteaConfig(ctx, cfg) + + expectedConfig := &GiteaConfig{ + Root: "changed", + Token: "changed", + LFSEnabled: true, + FollowSymlinks: true, + } + + assert.Equal(t, expectedConfig, cfg) + + return nil + }, + []string{ + "--gitea-root", "changed", + "--gitea-api-token", "changed", + "--enable-lfs-support", + "--enable-symlink-support", + }, + ) +} + +func TestMergeGiteaConfigShouldReplaceOnlyOneValueExistingValueGivenOnlyOneArgExists(t *testing.T) { + type testValuePair struct { + args []string + callback func(*GiteaConfig) + } + testValuePairs := []testValuePair{ + {args: []string{"--gitea-root", "changed"}, callback: func(gc *GiteaConfig) { gc.Root = "changed" }}, + {args: []string{"--gitea-api-token", "changed"}, callback: func(gc *GiteaConfig) { gc.Token = "changed" }}, + {args: []string{"--enable-lfs-support"}, callback: func(gc *GiteaConfig) { gc.LFSEnabled = true }}, + {args: []string{"--enable-symlink-support"}, callback: func(gc *GiteaConfig) { gc.FollowSymlinks = true }}, + } + + for _, pair := range testValuePairs { + runApp( + t, + func(ctx *cli.Context) error { + cfg := GiteaConfig{ + Root: "original", + Token: "original", + LFSEnabled: false, + FollowSymlinks: false, + } + + expectedConfig := cfg + pair.callback(&expectedConfig) + + mergeGiteaConfig(ctx, &cfg) + + assert.Equal(t, expectedConfig, cfg) + + return nil + }, + pair.args, + ) + } +} + +func TestMergeDatabaseConfigShouldReplaceAllExistingValuesGivenAllArgsExist(t *testing.T) { + runApp( + t, + func(ctx *cli.Context) error { + cfg := &DatabaseConfig{ + Type: "original", + Conn: "original", + } + + mergeDatabaseConfig(ctx, cfg) + + expectedConfig := &DatabaseConfig{ + Type: "changed", + Conn: "changed", + } + + assert.Equal(t, expectedConfig, cfg) + + return nil + }, + []string{ + "--db-type", "changed", + "--db-conn", "changed", + }, + ) +} + +func TestMergeDatabaseConfigShouldReplaceOnlyOneValueExistingValueGivenOnlyOneArgExists(t *testing.T) { + type testValuePair struct { + args []string + callback func(*DatabaseConfig) + } + testValuePairs := []testValuePair{ + {args: []string{"--db-type", "changed"}, callback: func(gc *DatabaseConfig) { gc.Type = "changed" }}, + {args: []string{"--db-conn", "changed"}, callback: func(gc *DatabaseConfig) { gc.Conn = "changed" }}, + } + + for _, pair := range testValuePairs { + runApp( + t, + func(ctx *cli.Context) error { + cfg := DatabaseConfig{ + Type: "original", + Conn: "original", + } + + expectedConfig := cfg + pair.callback(&expectedConfig) + + mergeDatabaseConfig(ctx, &cfg) + + assert.Equal(t, expectedConfig, cfg) + + return nil + }, + pair.args, + ) + } +} + +func TestMergeACMEConfigShouldReplaceAllExistingValuesGivenAllArgsExist(t *testing.T) { + runApp( + t, + func(ctx *cli.Context) error { + cfg := &ACMEConfig{ + Email: "original", + APIEndpoint: "original", + AcceptTerms: false, + UseRateLimits: false, + EAB_HMAC: "original", + EAB_KID: "original", + DNSProvider: "original", + AccountConfigFile: "original", + } + + mergeACMEConfig(ctx, cfg) + + expectedConfig := &ACMEConfig{ + Email: "changed", + APIEndpoint: "changed", + AcceptTerms: true, + UseRateLimits: true, + EAB_HMAC: "changed", + EAB_KID: "changed", + DNSProvider: "changed", + AccountConfigFile: "changed", + } + + assert.Equal(t, expectedConfig, cfg) + + return nil + }, + []string{ + "--acme-email", "changed", + "--acme-api-endpoint", "changed", + "--acme-accept-terms", + "--acme-use-rate-limits", + "--acme-eab-hmac", "changed", + "--acme-eab-kid", "changed", + "--dns-provider", "changed", + "--acme-account-config", "changed", + }, + ) +} + +func TestMergeACMEConfigShouldReplaceOnlyOneValueExistingValueGivenOnlyOneArgExists(t *testing.T) { + type testValuePair struct { + args []string + callback func(*ACMEConfig) + } + testValuePairs := []testValuePair{ + {args: []string{"--acme-email", "changed"}, callback: func(gc *ACMEConfig) { gc.Email = "changed" }}, + {args: []string{"--acme-api-endpoint", "changed"}, callback: func(gc *ACMEConfig) { gc.APIEndpoint = "changed" }}, + {args: []string{"--acme-accept-terms"}, callback: func(gc *ACMEConfig) { gc.AcceptTerms = true }}, + {args: []string{"--acme-use-rate-limits"}, callback: func(gc *ACMEConfig) { gc.UseRateLimits = true }}, + {args: []string{"--acme-eab-hmac", "changed"}, callback: func(gc *ACMEConfig) { gc.EAB_HMAC = "changed" }}, + {args: []string{"--acme-eab-kid", "changed"}, callback: func(gc *ACMEConfig) { gc.EAB_KID = "changed" }}, + {args: []string{"--dns-provider", "changed"}, callback: func(gc *ACMEConfig) { gc.DNSProvider = "changed" }}, + {args: []string{"--acme-account-config", "changed"}, callback: func(gc *ACMEConfig) { gc.AccountConfigFile = "changed" }}, + } + + for _, pair := range testValuePairs { + runApp( + t, + func(ctx *cli.Context) error { + cfg := ACMEConfig{ + Email: "original", + APIEndpoint: "original", + AcceptTerms: false, + UseRateLimits: false, + EAB_HMAC: "original", + EAB_KID: "original", + DNSProvider: "original", + AccountConfigFile: "original", + } + + expectedConfig := cfg + pair.callback(&expectedConfig) + + mergeACMEConfig(ctx, &cfg) + + assert.Equal(t, expectedConfig, cfg) + + return nil + }, + pair.args, + ) + } +}