Skip to content

Commit f9d3d8b

Browse files
committed
Get secret from config
This adds parsing if the `secret_file` from YAML. And reads the contents of the configured file. If no file is configured, we fall back to the `.gitlab_shell_secret` in the root dir of the configuration. If the configured path does not start with a `/` we start looking for the file relative to the root dir of the configuration.
1 parent 2a51ab3 commit f9d3d8b

File tree

8 files changed

+182
-87
lines changed

8 files changed

+182
-87
lines changed

go/internal/config/config.go

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@ import (
55
"net/url"
66
"os"
77
"path"
8+
"path/filepath"
89
"strings"
910

1011
yaml "gopkg.in/yaml.v2"
1112
)
1213

1314
const (
14-
configFile = "config.yml"
15-
logFile = "gitlab-shell.log"
15+
configFile = "config.yml"
16+
logFile = "gitlab-shell.log"
17+
defaultSecretFileName = ".gitlab_shell_secret"
1618
)
1719

1820
type MigrationConfig struct {
@@ -21,12 +23,14 @@ type MigrationConfig struct {
2123
}
2224

2325
type Config struct {
24-
RootDir string
25-
LogFile string `yaml:"log_file"`
26-
LogFormat string `yaml:"log_format"`
27-
Migration MigrationConfig `yaml:"migration"`
28-
GitlabUrl string `yaml:"gitlab_url"`
29-
GitlabTracing string `yaml:"gitlab_tracing"`
26+
RootDir string
27+
LogFile string `yaml:"log_file"`
28+
LogFormat string `yaml:"log_format"`
29+
Migration MigrationConfig `yaml:"migration"`
30+
GitlabUrl string `yaml:"gitlab_url"`
31+
GitlabTracing string `yaml:"gitlab_tracing"`
32+
SecretFilePath string `yaml:"secret_file"`
33+
Secret string `yaml:"secret"`
3034
}
3135

3236
func New() (*Config, error) {
@@ -102,5 +106,32 @@ func parseConfig(configBytes []byte, cfg *Config) error {
102106
cfg.GitlabUrl = unescapedUrl
103107
}
104108

109+
if err := parseSecret(cfg); err != nil {
110+
return err
111+
}
112+
113+
return nil
114+
}
115+
116+
func parseSecret(cfg *Config) error {
117+
// The secret was parsed from yaml no need to read another file
118+
if cfg.Secret != "" {
119+
return nil
120+
}
121+
122+
if cfg.SecretFilePath == "" {
123+
cfg.SecretFilePath = defaultSecretFileName
124+
}
125+
126+
if !filepath.IsAbs(cfg.SecretFilePath) {
127+
cfg.SecretFilePath = path.Join(cfg.RootDir, cfg.SecretFilePath)
128+
}
129+
130+
secretFileContent, err := ioutil.ReadFile(cfg.SecretFilePath)
131+
if err != nil {
132+
return err
133+
}
134+
cfg.Secret = string(secretFileContent)
135+
105136
return nil
106137
}

go/internal/config/config_test.go

Lines changed: 68 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,63 +2,105 @@ package config
22

33
import (
44
"fmt"
5-
"strings"
5+
"path"
66
"testing"
77

88
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
10+
"gitlab.com/gitlab-org/gitlab-shell/go/internal/testhelper"
11+
)
12+
13+
const (
14+
customSecret = "custom/my-contents-is-secret"
15+
)
16+
17+
var (
18+
testRoot = testhelper.TestRoot
919
)
1020

1121
func TestParseConfig(t *testing.T) {
12-
testRoot := "/foo/bar"
22+
cleanup, err := testhelper.PrepareTestRootDir()
23+
require.NoError(t, err)
24+
defer cleanup()
25+
1326
testCases := []struct {
1427
yaml string
1528
path string
1629
format string
1730
gitlabUrl string
1831
migration MigrationConfig
32+
secret string
1933
}{
20-
{path: "/foo/bar/gitlab-shell.log", format: "text"},
21-
{yaml: "log_file: my-log.log", path: "/foo/bar/my-log.log", format: "text"},
22-
{yaml: "log_file: /qux/my-log.log", path: "/qux/my-log.log", format: "text"},
23-
{yaml: "log_format: json", path: "/foo/bar/gitlab-shell.log", format: "json"},
34+
{
35+
path: path.Join(testRoot, "gitlab-shell.log"),
36+
format: "text",
37+
secret: "default-secret-content",
38+
},
39+
{
40+
yaml: "log_file: my-log.log",
41+
path: path.Join(testRoot, "my-log.log"),
42+
format: "text",
43+
secret: "default-secret-content",
44+
},
45+
{
46+
yaml: "log_file: /qux/my-log.log",
47+
path: "/qux/my-log.log",
48+
format: "text",
49+
secret: "default-secret-content",
50+
},
51+
{
52+
yaml: "log_format: json",
53+
path: path.Join(testRoot, "gitlab-shell.log"),
54+
format: "json",
55+
secret: "default-secret-content",
56+
},
2457
{
2558
yaml: "migration:\n enabled: true\n features:\n - foo\n - bar",
26-
path: "/foo/bar/gitlab-shell.log",
59+
path: path.Join(testRoot, "gitlab-shell.log"),
2760
format: "text",
2861
migration: MigrationConfig{Enabled: true, Features: []string{"foo", "bar"}},
62+
secret: "default-secret-content",
2963
},
3064
{
3165
yaml: "gitlab_url: http+unix://%2Fpath%2Fto%2Fgitlab%2Fgitlab.socket",
32-
path: "/foo/bar/gitlab-shell.log",
66+
path: path.Join(testRoot, "gitlab-shell.log"),
3367
format: "text",
3468
gitlabUrl: "http+unix:///path/to/gitlab/gitlab.socket",
69+
secret: "default-secret-content",
70+
},
71+
{
72+
yaml: fmt.Sprintf("secret_file: %s", customSecret),
73+
path: path.Join(testRoot, "gitlab-shell.log"),
74+
format: "text",
75+
secret: "custom-secret-content",
76+
},
77+
{
78+
yaml: fmt.Sprintf("secret_file: %s", path.Join(testRoot, customSecret)),
79+
path: path.Join(testRoot, "gitlab-shell.log"),
80+
format: "text",
81+
secret: "custom-secret-content",
82+
},
83+
{
84+
yaml: "secret: an inline secret",
85+
path: path.Join(testRoot, "gitlab-shell.log"),
86+
format: "text",
87+
secret: "an inline secret",
3588
},
3689
}
3790

3891
for _, tc := range testCases {
3992
t.Run(fmt.Sprintf("yaml input: %q", tc.yaml), func(t *testing.T) {
4093
cfg := Config{RootDir: testRoot}
41-
if err := parseConfig([]byte(tc.yaml), &cfg); err != nil {
42-
t.Fatal(err)
43-
}
44-
45-
if cfg.Migration.Enabled != tc.migration.Enabled {
46-
t.Fatalf("migration.enabled: expected %v, got %v", tc.migration.Enabled, cfg.Migration.Enabled)
47-
}
48-
49-
if strings.Join(cfg.Migration.Features, ":") != strings.Join(tc.migration.Features, ":") {
50-
t.Fatalf("migration.features: expected %#v, got %#v", tc.migration.Features, cfg.Migration.Features)
51-
}
52-
53-
if cfg.LogFile != tc.path {
54-
t.Fatalf("expected %q, got %q", tc.path, cfg.LogFile)
55-
}
5694

57-
if cfg.LogFormat != tc.format {
58-
t.Fatalf("expected %q, got %q", tc.format, cfg.LogFormat)
59-
}
95+
err := parseConfig([]byte(tc.yaml), &cfg)
96+
require.NoError(t, err)
6097

98+
assert.Equal(t, tc.migration.Enabled, cfg.Migration.Enabled, "migration.enabled not equal")
99+
assert.Equal(t, tc.migration.Features, cfg.Migration.Features, "migration.features not equal")
100+
assert.Equal(t, tc.path, cfg.LogFile)
101+
assert.Equal(t, tc.format, cfg.LogFormat)
61102
assert.Equal(t, tc.gitlabUrl, cfg.GitlabUrl)
103+
assert.Equal(t, tc.secret, cfg.Secret)
62104
})
63105
}
64106
}

go/internal/handler/exec_test.go

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@ package handler
33
import (
44
"context"
55
"fmt"
6-
"io/ioutil"
7-
"os"
8-
"path/filepath"
96
"testing"
107

118
"github.com/stretchr/testify/require"
9+
"gitlab.com/gitlab-org/gitlab-shell/go/internal/testhelper"
1210
"google.golang.org/grpc"
1311
)
1412

@@ -88,7 +86,7 @@ func TestInteralRunHandler(t *testing.T) {
8886
currentTest = nil
8987
}()
9088

91-
done, err := createEnv()
89+
done, err := testhelper.PrepareTestRootDir()
9290
defer done()
9391
require.NoError(t, err)
9492

@@ -103,51 +101,3 @@ func TestInteralRunHandler(t *testing.T) {
103101
})
104102
}
105103
}
106-
107-
// createEnv sets up an environment for `config.New()`.
108-
func createEnv() (func(), error) {
109-
var dir string
110-
var oldWd string
111-
closer := func() {
112-
if oldWd != "" {
113-
err := os.Chdir(oldWd)
114-
if err != nil {
115-
panic(err)
116-
}
117-
}
118-
119-
if dir != "" {
120-
err := os.RemoveAll(dir)
121-
if err != nil {
122-
panic(err)
123-
}
124-
}
125-
}
126-
127-
dir, err := ioutil.TempDir("", "test")
128-
if err != nil {
129-
return closer, err
130-
}
131-
132-
err = ioutil.WriteFile(filepath.Join(dir, "config.yml"), []byte{}, 0644)
133-
if err != nil {
134-
return closer, err
135-
}
136-
137-
err = ioutil.WriteFile(filepath.Join(dir, "gitlab-shell.log"), []byte{}, 0644)
138-
if err != nil {
139-
return closer, err
140-
}
141-
142-
oldWd, err = os.Getwd()
143-
if err != nil {
144-
return closer, err
145-
}
146-
147-
err = os.Chdir(dir)
148-
if err != nil {
149-
return closer, err
150-
}
151-
152-
return closer, err
153-
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
default-secret-content

go/internal/testhelper/testdata/testroot/config.yml

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
custom-secret-content

go/internal/testhelper/testdata/testroot/gitlab-shell.log

Whitespace-only changes.

go/internal/testhelper/testhelper.go

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
package testhelper
22

3-
import "os"
3+
import (
4+
"fmt"
5+
"io/ioutil"
6+
"os"
7+
"path"
8+
"runtime"
9+
10+
"github.com/otiai10/copy"
11+
)
12+
13+
var (
14+
TestRoot, _ = ioutil.TempDir("", "test-gitlab-shell")
15+
)
416

517
func TempEnv(env map[string]string) func() {
618
var original = make(map[string]string)
@@ -15,3 +27,61 @@ func TempEnv(env map[string]string) func() {
1527
}
1628
}
1729
}
30+
31+
func PrepareTestRootDir() (func(), error) {
32+
if err := os.MkdirAll(TestRoot, 0700); err != nil {
33+
return nil, err
34+
}
35+
36+
var oldWd string
37+
cleanup := func() {
38+
if oldWd != "" {
39+
err := os.Chdir(oldWd)
40+
if err != nil {
41+
panic(err)
42+
}
43+
}
44+
45+
if err := os.RemoveAll(TestRoot); err != nil {
46+
panic(err)
47+
}
48+
}
49+
50+
if err := copyTestData(); err != nil {
51+
cleanup()
52+
return nil, err
53+
}
54+
55+
oldWd, err := os.Getwd()
56+
if err != nil {
57+
cleanup()
58+
return nil, err
59+
}
60+
61+
if err := os.Chdir(TestRoot); err != nil {
62+
cleanup()
63+
return nil, err
64+
}
65+
66+
return cleanup, nil
67+
}
68+
69+
func copyTestData() error {
70+
testDataDir, err := getTestDataDir()
71+
if err != nil {
72+
return err
73+
}
74+
75+
testdata := path.Join(testDataDir, "testroot")
76+
77+
return copy.Copy(testdata, TestRoot)
78+
}
79+
80+
func getTestDataDir() (string, error) {
81+
_, currentFile, _, ok := runtime.Caller(0)
82+
if !ok {
83+
return "", fmt.Errorf("Could not get caller info")
84+
}
85+
86+
return path.Join(path.Dir(currentFile), "testdata"), nil
87+
}

0 commit comments

Comments
 (0)