feat(config): [database] deployment 指向集群内的数据库
This commit is contained in:
2 files changed
+34
No files matched your search
@@ -20,6 +20,9 @@ import (
|
|||||||
// takes in its comma-separated --accept flag.
|
// takes in its comma-separated --accept flag.
|
||||||
var scanIDPattern = regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$`)
|
var scanIDPattern = regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$`)
|
||||||
|
|
||||||
|
// dnsLabel is a Kubernetes namespace or object name (RFC 1123 label).
|
||||||
|
var dnsLabel = regexp.MustCompile(`^[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?$`)
|
||||||
|
|
||||||
// Config is the parsed felis.toml.
|
// Config is the parsed felis.toml.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Server ServerConfig `toml:"server"`
|
Server ServerConfig `toml:"server"`
|
||||||
@@ -120,6 +123,12 @@ type ServerConfig struct {
|
|||||||
// DatabaseConfig is the [database] table.
|
// DatabaseConfig is the [database] table.
|
||||||
type DatabaseConfig struct {
|
type DatabaseConfig struct {
|
||||||
URL string `toml:"url"`
|
URL string `toml:"url"`
|
||||||
|
// Deployment is the k3s Deployment the database runs as, "namespace/name"
|
||||||
|
// ("felis/felis-postgres"), written into the host copy only. The host
|
||||||
|
// carries no PostgreSQL client, so `felis db backup`/`restore` and the
|
||||||
|
// pre-migration snapshot run pg_dump, pg_restore and psql inside its
|
||||||
|
// postgres container. Empty runs the tools on PATH against url.
|
||||||
|
Deployment string `toml:"deployment"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// VelocityConfig is the [velocity] table.
|
// VelocityConfig is the [velocity] table.
|
||||||
@@ -531,6 +540,12 @@ func (c *Config) Validate() error {
|
|||||||
if c.Database.URL == "" {
|
if c.Database.URL == "" {
|
||||||
return fmt.Errorf("config: [database] url is required")
|
return fmt.Errorf("config: [database] url is required")
|
||||||
}
|
}
|
||||||
|
if d := c.Database.Deployment; d != "" {
|
||||||
|
ns, name, ok := strings.Cut(d, "/")
|
||||||
|
if !ok || !dnsLabel.MatchString(ns) || !dnsLabel.MatchString(name) {
|
||||||
|
return fmt.Errorf("config: [database] deployment %q is not namespace/name", d)
|
||||||
|
}
|
||||||
|
}
|
||||||
if c.Server.RootDomain == "" {
|
if c.Server.RootDomain == "" {
|
||||||
return fmt.Errorf("config: [server] root_domain is required")
|
return fmt.Errorf("config: [server] root_domain is required")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -171,6 +171,25 @@ root_domain = "mc.example.net"
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLoadDatabaseDeployment(t *testing.T) {
|
||||||
|
withDeployment := func(v string) string {
|
||||||
|
return strings.Replace(validTOML, `url = "postgres://felis:secret@db:5432/felis"`,
|
||||||
|
`url = "postgres://felis:secret@db:5432/felis"`+"\ndeployment = \""+v+"\"", 1)
|
||||||
|
}
|
||||||
|
cfg, err := config.Load(writeTOML(t, withDeployment("felis/felis-postgres")))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Load: %v", err)
|
||||||
|
}
|
||||||
|
if cfg.Database.Deployment != "felis/felis-postgres" {
|
||||||
|
t.Fatalf("deployment = %q", cfg.Database.Deployment)
|
||||||
|
}
|
||||||
|
for _, bad := range []string{"felis-postgres", "felis/", "/felis-postgres", "Felis/pg", "felis/pg; rm -rf /", "a/b/c"} {
|
||||||
|
if _, err := config.Load(writeTOML(t, withDeployment(bad))); err == nil || !strings.Contains(err.Error(), "namespace/name") {
|
||||||
|
t.Errorf("deployment %q: err = %v, want a namespace/name refusal", bad, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestLoadRejectsMissingRootDomain(t *testing.T) {
|
func TestLoadRejectsMissingRootDomain(t *testing.T) {
|
||||||
_, err := config.Load(writeTOML(t, `
|
_, err := config.Load(writeTOML(t, `
|
||||||
[database]
|
[database]
|
||||||
|
|||||||
Reference in new issue
Block a user