Skip to content

Commit 1374708

Browse files
committed
Merge branch 'neo/env-token-configs' into 'master'
feat: support env token placeholders in DBLab configs Closes #707 See merge request postgres-ai/database-lab!1140
2 parents 646c0a3 + 362c7b0 commit 1374708

20 files changed

Lines changed: 410 additions & 30 deletions

engine/cmd/cli/commands/config/environment.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/urfave/cli/v2"
1010

1111
"gitlab.com/postgres-ai/database-lab/v3/cmd/cli/commands"
12+
"gitlab.com/postgres-ai/database-lab/v3/pkg/config/envvar"
1213
)
1314

1415
// DefaultBranch defines the name of data branch.
@@ -32,6 +33,14 @@ type Environment struct {
3233
Branching Branching `yaml:"branching" json:"branching"`
3334
}
3435

36+
// ResolvedToken returns the token with "${VAR}" / "$VAR" environment
37+
// references expanded. It returns an error if any referenced variable is unset
38+
// so a missing env var fails loudly instead of silently producing an empty
39+
// token that would be rejected by the API as unauthorized.
40+
func (e Environment) ResolvedToken() (string, error) {
41+
return envvar.ExpandStrict(e.Token)
42+
}
43+
3544
// Forwarding defines configuration for port forwarding.
3645
type Forwarding struct {
3746
ServerURL string `yaml:"server_url" json:"server_url"`
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package config
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func TestEnvironmentResolvedToken(t *testing.T) {
11+
t.Run("expands environment placeholders", func(t *testing.T) {
12+
t.Setenv("DBLAB_TOKEN", "secret-from-env")
13+
14+
env := Environment{Token: "${DBLAB_TOKEN}"}
15+
16+
got, err := env.ResolvedToken()
17+
require.NoError(t, err)
18+
assert.Equal(t, "secret-from-env", got)
19+
})
20+
21+
t.Run("preserves plain values", func(t *testing.T) {
22+
env := Environment{Token: "plain-secret"}
23+
24+
got, err := env.ResolvedToken()
25+
require.NoError(t, err)
26+
assert.Equal(t, "plain-secret", got)
27+
})
28+
29+
t.Run("empty token round-trips without lookup", func(t *testing.T) {
30+
env := Environment{Token: ""}
31+
32+
got, err := env.ResolvedToken()
33+
require.NoError(t, err)
34+
assert.Empty(t, got)
35+
})
36+
37+
t.Run("errors on unset variable", func(t *testing.T) {
38+
env := Environment{Token: "${DBLAB_TOKEN_MISSING}"}
39+
40+
_, err := env.ResolvedToken()
41+
require.Error(t, err)
42+
assert.Contains(t, err.Error(), `"DBLAB_TOKEN_MISSING" is not set`)
43+
})
44+
}

engine/cmd/cli/main.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,12 @@ func loadEnvironmentParams(c *cli.Context) error {
135135
}
136136

137137
if !c.IsSet(commands.TokenKey) {
138-
if err := c.Set(commands.TokenKey, env.Token); err != nil {
138+
token, err := env.ResolvedToken()
139+
if err != nil {
140+
return err
141+
}
142+
143+
if err := c.Set(commands.TokenKey, token); err != nil {
139144
return err
140145
}
141146
}

engine/configs/config.example.ci_checker.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ app:
1515
# If the integration with Postgres.ai Platform is configured
1616
# (see below, "platform: ..." configuration),
1717
# tokens (including personal) generated on the Platform may be used.
18-
verificationToken: "secret_token"
18+
verificationToken: "${CI_CHECKER_VERIFICATION_TOKEN}"
1919

2020
# Database Lab instance that starts clone to check DB migrations.
2121
dle:
2222
# URL of Database Lab API server
2323
url: "https://dblab.domain.com"
2424

2525
# Secret token used to communicate with the Database Lab Engine API.
26-
verificationToken: "checker_secret_token"
26+
verificationToken: "${DBLAB_VERIFICATION_TOKEN}"
2727

2828
# Integration with Postgres.ai Platform instance. It may be either
2929
# SaaS (https://postgres.ai) of self-managed instance (usually located inside
@@ -33,7 +33,7 @@ platform:
3333
url: "https://postgres.ai/api/general"
3434

3535
# Postgres.ai Platform API secret token.
36-
accessToken: "platform_access_token"
36+
accessToken: "${PGAI_PLATFORM_ACCESS_TOKEN}"
3737

3838
# Enable authorization with personal tokens of the organization's members.
3939
# If false: all users must use "verificationToken" value for any API request
@@ -47,7 +47,7 @@ source:
4747
type: "github"
4848

4949
# Access token for getting source code from version control system.
50-
token: "vcs_secret_token"
50+
token: "${VCS_ACCESS_TOKEN}"
5151

5252
runner:
5353
# Docker image containing tools for executing database migration commands.

engine/configs/config.example.logical_generic.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copy this configuration to: ~/.dblab/engine/configs/server.yml
22
# Configuration reference guide: https://postgres.ai/docs/reference-guides/database-lab-engine-configuration-reference
33
server:
4-
verificationToken: "secret_token" # Primary auth token; can be empty (not recommended); for multi-user mode, use DBLab EE
4+
verificationToken: "${DBLAB_VERIFICATION_TOKEN}" # Primary auth token; can be empty (not recommended); for multi-user mode, use DBLab EE
55
port: 2345 # API server port; default: "2345"
66
disableConfigModification: false # When true, configuration changes via API/CLI/UI are disabled; default: "false"
77

@@ -191,6 +191,6 @@ platform:
191191
#
192192
# projectName: "project_name" # Project name
193193
# orgKey: "org_key" # Organization key
194-
# accessToken: "platform_access_token" # Token for authorization in Platform API; get it at https://postgres.ai/console/YOUR_ORG_NAME/tokens
194+
# accessToken: "${PGAI_PLATFORM_ACCESS_TOKEN}" # Token for authorization in Platform API; get it at https://postgres.ai/console/YOUR_ORG_NAME/tokens
195195
# enablePersonalTokens: true # Enable authorization with personal tokens of the organization's members.
196196
#

engine/configs/config.example.logical_rds_iam.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copy this configuration to: ~/.dblab/engine/configs/server.yml
22
# Configuration reference guide: https://postgres.ai/docs/reference-guides/database-lab-engine-configuration-reference
33
server:
4-
verificationToken: "secret_token" # Primary auth token; can be empty (not recommended); for multi-user mode, use DBLab EE
4+
verificationToken: "${DBLAB_VERIFICATION_TOKEN}" # Primary auth token; can be empty (not recommended); for multi-user mode, use DBLab EE
55
port: 2345 # API server port; default: "2345"
66
disableConfigModification: false # When true, configuration changes via API/CLI/UI are disabled; default: "false"
77

@@ -191,6 +191,6 @@ platform:
191191
#
192192
# projectName: "project_name" # Project name
193193
# orgKey: "org_key" # Organization key
194-
# accessToken: "platform_access_token" # Token for authorization in Platform API; get it at https://postgres.ai/console/YOUR_ORG_NAME/tokens
194+
# accessToken: "${PGAI_PLATFORM_ACCESS_TOKEN}" # Token for authorization in Platform API; get it at https://postgres.ai/console/YOUR_ORG_NAME/tokens
195195
# enablePersonalTokens: true # Enable authorization with personal tokens of the organization's members.
196196
#

engine/configs/config.example.physical_generic.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copy this configuration to: ~/.dblab/engine/configs/server.yml
22
# Configuration reference guide: https://postgres.ai/docs/reference-guides/database-lab-engine-configuration-reference
33
server:
4-
verificationToken: "secret_token" # Primary auth token; can be empty (not recommended); for multi-user mode, use DBLab EE
4+
verificationToken: "${DBLAB_VERIFICATION_TOKEN}" # Primary auth token; can be empty (not recommended); for multi-user mode, use DBLab EE
55
port: 2345 # API server port; default: "2345"
66
disableConfigModification: false # When true, configuration changes via API/CLI/UI are disabled; default: "false"
77

@@ -172,6 +172,6 @@ platform:
172172
#
173173
# projectName: "project_name" # Project name
174174
# orgKey: "org_key" # Organization key
175-
# accessToken: "platform_access_token" # Token for authorization in Platform API; get it at https://postgres.ai/console/YOUR_ORG_NAME/tokens
175+
# accessToken: "${PGAI_PLATFORM_ACCESS_TOKEN}" # Token for authorization in Platform API; get it at https://postgres.ai/console/YOUR_ORG_NAME/tokens
176176
# enablePersonalTokens: true # Enable authorization with personal tokens of the organization's members.
177177
#

engine/configs/config.example.physical_pgbackrest.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copy this configuration to: ~/.dblab/engine/configs/server.yml
22
# Configuration reference guide: https://postgres.ai/docs/reference-guides/database-lab-engine-configuration-reference
33
server:
4-
verificationToken: "secret_token" # Primary auth token; can be empty (not recommended); for multi-user mode, use DBLab EE
4+
verificationToken: "${DBLAB_VERIFICATION_TOKEN}" # Primary auth token; can be empty (not recommended); for multi-user mode, use DBLab EE
55
port: 2345 # API server port; default: "2345"
66
disableConfigModification: false # When true, configuration changes via API/CLI/UI are disabled; default: "false"
77

@@ -202,6 +202,6 @@ platform:
202202
#
203203
# projectName: "project_name" # Project name
204204
# orgKey: "org_key" # Organization key
205-
# accessToken: "platform_access_token" # Token for authorization in Platform API; get it at https://postgres.ai/console/YOUR_ORG_NAME/tokens
205+
# accessToken: "${PGAI_PLATFORM_ACCESS_TOKEN}" # Token for authorization in Platform API; get it at https://postgres.ai/console/YOUR_ORG_NAME/tokens
206206
# enablePersonalTokens: true # Enable authorization with personal tokens of the organization's members.
207207
#

engine/configs/config.example.physical_walg.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Copy this configuration to: ~/.dblab/engine/configs/server.yml
22
# Configuration reference guide: https://postgres.ai/docs/reference-guides/database-lab-engine-configuration-reference
33
server:
4-
verificationToken: "secret_token" # Primary auth token; can be empty (not recommended); for multi-user mode, use DBLab EE
4+
verificationToken: "${DBLAB_VERIFICATION_TOKEN}" # Primary auth token; can be empty (not recommended); for multi-user mode, use DBLab EE
55
port: 2345 # API server port; default: "2345"
66
disableConfigModification: false # When true, configuration changes via API/CLI/UI are disabled; default: "false"
77

@@ -175,6 +175,6 @@ platform:
175175
#
176176
# projectName: "project_name" # Project name
177177
# orgKey: "org_key" # Organization key
178-
# accessToken: "platform_access_token" # Token for authorization in Platform API; get it at https://postgres.ai/console/YOUR_ORG_NAME/tokens
178+
# accessToken: "${PGAI_PLATFORM_ACCESS_TOKEN}" # Token for authorization in Platform API; get it at https://postgres.ai/console/YOUR_ORG_NAME/tokens
179179
# enablePersonalTokens: true # Enable authorization with personal tokens of the organization's members.
180180
#

engine/internal/runci/config.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
"gitlab.com/postgres-ai/database-lab/v3/internal/platform"
1515
"gitlab.com/postgres-ai/database-lab/v3/internal/runci/source"
16+
"gitlab.com/postgres-ai/database-lab/v3/pkg/config/envvar"
1617
"gitlab.com/postgres-ai/database-lab/v3/pkg/util"
1718
)
1819

@@ -67,5 +68,14 @@ func LoadConfiguration() (*Config, error) {
6768
return nil, errors.WithMessagef(err, "error parsing %s config", configPath)
6869
}
6970

71+
if err := envvar.ExpandFields([]envvar.Field{
72+
{Name: "app.verificationToken", Ptr: &cfg.App.VerificationToken},
73+
{Name: "dle.verificationToken", Ptr: &cfg.DLE.VerificationToken},
74+
{Name: "platform.accessToken", Ptr: &cfg.Platform.AccessToken},
75+
{Name: "source.token", Ptr: &cfg.Source.Token},
76+
}); err != nil {
77+
return nil, errors.Wrap(err, "failed to resolve environment placeholders")
78+
}
79+
7080
return cfg, nil
7181
}

0 commit comments

Comments
 (0)