Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
c3ad476b1a
|
|||
|
1851797a3f
|
@@ -5,7 +5,7 @@
|
|||||||
## Install
|
## Install
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
go get git.campbellwireless.net/barkstack/barkfile-parser@v0.1.0
|
go get cloud.campbellwireless.net/git/barkstack/barkfile-parser@v1.0.0
|
||||||
```
|
```
|
||||||
|
|
||||||
The module requires Go 1.24 or later.
|
The module requires Go 1.24 or later.
|
||||||
@@ -21,7 +21,7 @@ if err != nil {
|
|||||||
|
|
||||||
`Load` reads, parses, and validates a file. `Parse` parses bytes when a caller owns file I/O; call `Config.Validate` before applying a parsed configuration.
|
`Load` reads, parses, and validates a file. `Parse` parses bytes when a caller owns file I/O; call `Config.Validate` before applying a parsed configuration.
|
||||||
|
|
||||||
The current schema defines one `pawsql` block with a listener, TLS certificate/key paths, and one or more `database` routes. A route has exactly one of:
|
The current schema defines one `pawsql` block with a listener, an optional TLS `cert`/`key` pair, and one or more `database` routes. A route has exactly one of:
|
||||||
|
|
||||||
- `upstream <host:port>` for an external PostgreSQL server.
|
- `upstream <host:port>` for an external PostgreSQL server.
|
||||||
- `postgres { ... }` for a managed PostgreSQL container. Its `image`, `volume`, and `password_env` directives are required. `idle_timeout` and `traffic_idle_timeout` accept Go duration strings.
|
- `postgres { ... }` for a managed PostgreSQL container. Its `image`, `volume`, and `password_env` directives are required. `idle_timeout` and `traffic_idle_timeout` accept Go duration strings.
|
||||||
@@ -80,4 +80,4 @@ Gitea Actions runs tests on each `main` push. The release job reads Conventional
|
|||||||
| `type!:` or `BREAKING CHANGE:` | major |
|
| `type!:` or `BREAKING CHANGE:` | major |
|
||||||
| other types | no release |
|
| other types | no release |
|
||||||
|
|
||||||
Go consumers update through standard module versions, for example `go get git.campbellwireless.net/barkstack/barkfile-parser@latest`.
|
Go consumers update through standard module versions, for example `go get cloud.campbellwireless.net/git/barkstack/barkfile-parser@latest`.
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -1,3 +1,3 @@
|
|||||||
module git.campbellwireless.net/barkstack/barkfile-parser
|
module cloud.campbellwireless.net/git/barkstack/barkfile-parser
|
||||||
|
|
||||||
go 1.24
|
go 1.24
|
||||||
|
|||||||
@@ -81,13 +81,59 @@ func TestValidateMissingFieldsAndDuplicateHostname(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("Validate() error = nil")
|
t.Fatal("Validate() error = nil")
|
||||||
}
|
}
|
||||||
for _, want := range []string{"TLS private key is required", "upstream or postgres is required", "duplicate hostname"} {
|
for _, want := range []string{"tls requires both cert and key", "upstream or postgres is required", "duplicate hostname"} {
|
||||||
if !strings.Contains(err.Error(), want) {
|
if !strings.Contains(err.Error(), want) {
|
||||||
t.Errorf("Validate() error = %q, missing %q", err, want)
|
t.Errorf("Validate() error = %q, missing %q", err, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidateAllowsConfigurationWithoutTLS(t *testing.T) {
|
||||||
|
cfg := Config{
|
||||||
|
Listen: ":5432",
|
||||||
|
Databases: []DatabaseConfig{{
|
||||||
|
Name: "analytics",
|
||||||
|
Upstream: "postgres-foo:5432",
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
if err := cfg.Validate(); err != nil {
|
||||||
|
t.Fatalf("Validate() error = %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseAndValidateWithoutTLSBlock(t *testing.T) {
|
||||||
|
cfg, err := Parse([]byte(`pawsql {
|
||||||
|
listen :5432
|
||||||
|
database analytics {
|
||||||
|
upstream postgres-foo:5432
|
||||||
|
}
|
||||||
|
}`))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Parse() error = %v", err)
|
||||||
|
}
|
||||||
|
if cfg.TLS.CertFile != "" || cfg.TLS.KeyFile != "" {
|
||||||
|
t.Errorf("TLS = %#v, want unset", cfg.TLS)
|
||||||
|
}
|
||||||
|
if err := cfg.Validate(); err != nil {
|
||||||
|
t.Fatalf("Validate() error = %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestValidateRejectsHalfConfiguredTLS(t *testing.T) {
|
||||||
|
cfg := Config{
|
||||||
|
Listen: ":5432",
|
||||||
|
TLS: TLSConfig{CertFile: "cert.pem"},
|
||||||
|
Databases: []DatabaseConfig{{
|
||||||
|
Name: "analytics",
|
||||||
|
Upstream: "postgres-foo:5432",
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
err := cfg.Validate()
|
||||||
|
if err == nil || !strings.Contains(err.Error(), "tls requires both cert and key") {
|
||||||
|
t.Fatalf("Validate() error = %v, want tls requires both cert and key", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestValidateRejectsMalformedUpstreamAddress(t *testing.T) {
|
func TestValidateRejectsMalformedUpstreamAddress(t *testing.T) {
|
||||||
cfg := Config{
|
cfg := Config{
|
||||||
Listen: ":5432",
|
Listen: ":5432",
|
||||||
|
|||||||
@@ -21,11 +21,10 @@ func (c Config) Validate() error {
|
|||||||
} else if err := validateListenAddress(c.Listen); err != nil {
|
} else if err := validateListenAddress(c.Listen); err != nil {
|
||||||
errs = append(errs, fmt.Errorf("listen address %q: %w", c.Listen, err))
|
errs = append(errs, fmt.Errorf("listen address %q: %w", c.Listen, err))
|
||||||
}
|
}
|
||||||
if strings.TrimSpace(c.TLS.CertFile) == "" {
|
certificateSet := strings.TrimSpace(c.TLS.CertFile) != ""
|
||||||
errs = append(errs, errors.New("TLS certificate is required"))
|
keySet := strings.TrimSpace(c.TLS.KeyFile) != ""
|
||||||
}
|
if certificateSet != keySet {
|
||||||
if strings.TrimSpace(c.TLS.KeyFile) == "" {
|
errs = append(errs, errors.New("tls requires both cert and key"))
|
||||||
errs = append(errs, errors.New("TLS private key is required"))
|
|
||||||
}
|
}
|
||||||
if len(c.Databases) == 0 {
|
if len(c.Databases) == 0 {
|
||||||
errs = append(errs, errors.New("at least one database route is required"))
|
errs = append(errs, errors.New("at least one database route is required"))
|
||||||
|
|||||||
Reference in New Issue
Block a user