Skip to content

Commit 10c0abb

Browse files
authored
refactor: Structure to make it easier to extend and modify functionality (#195)
1 parent 7ae7295 commit 10c0abb

File tree

105 files changed

+2163
-1456
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+2163
-1456
lines changed

backend.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ import (
1212
"github.com/hashicorp/vault/sdk/framework"
1313
"github.com/hashicorp/vault/sdk/helper/locksutil"
1414
"github.com/hashicorp/vault/sdk/logical"
15+
16+
"github.com/ilijamt/vault-plugin-secrets-gitlab/internal/flags"
17+
g "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/gitlab"
18+
"github.com/ilijamt/vault-plugin-secrets-gitlab/internal/utils"
1519
)
1620

1721
const (
@@ -27,14 +31,14 @@ with the "^config/(?P<config_name>\w(([\w-.@]+)?\w)?)$" endpoints.
2731
`
2832
)
2933

30-
func Factory(flags Flags) logical.Factory {
34+
func Factory(flags flags.Flags) logical.Factory {
3135
return func(ctx context.Context, config *logical.BackendConfig) (logical.Backend, error) {
3236
return factory(ctx, config, flags)
3337
}
3438
}
3539

3640
// Factory returns expected new Backend as logical.Backend
37-
func factory(ctx context.Context, conf *logical.BackendConfig, flags Flags) (logical.Backend, error) {
41+
func factory(ctx context.Context, conf *logical.BackendConfig, flags flags.Flags) (logical.Backend, error) {
3842
var b = &Backend{
3943
roleLocks: locksutil.CreateLocks(),
4044
clients: sync.Map{},
@@ -82,7 +86,7 @@ func factory(ctx context.Context, conf *logical.BackendConfig, flags Flags) (log
8286
type Backend struct {
8387
*framework.Backend
8488

85-
flags Flags
89+
flags flags.Flags
8690

8791
// The client that we can use to create and revoke the access tokens
8892
clients sync.Map
@@ -180,8 +184,8 @@ func (b *Backend) getClient(ctx context.Context, s logical.Storage, name string)
180184
}
181185

182186
var httpClient *http.Client
183-
httpClient, _ = HttpClientFromContext(ctx)
184-
if client, _ = ClientFromContext(ctx); client == nil {
187+
httpClient, _ = utils.HttpClientFromContext(ctx)
188+
if client, _ = g.ClientFromContext(ctx); client == nil {
185189
if client, err = NewGitlabClient(config, httpClient, b.Logger()); err == nil {
186190
b.SetClient(client, name)
187191
}

cmd/vault-plugin-secrets-gitlab/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/hashicorp/vault/sdk/plugin"
99

1010
gat "github.com/ilijamt/vault-plugin-secrets-gitlab"
11+
f "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/flags"
1112
)
1213

1314
var (
@@ -17,7 +18,7 @@ var (
1718
func main() {
1819
apiClientMeta := &api.PluginAPIClientMeta{}
1920
flags := apiClientMeta.FlagSet()
20-
pf := &gat.Flags{}
21+
pf := &f.Flags{}
2122
pf.FlagSet(flags)
2223

2324
fatalIfError(flags.Parse(os.Args[1:]))

defs.go

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,9 @@
11
package gitlab
22

33
import (
4-
"context"
5-
"errors"
6-
"net/http"
74
"time"
85
)
96

10-
var (
11-
ErrNilValue = errors.New("nil value")
12-
ErrInvalidValue = errors.New("invalid value")
13-
ErrFieldRequired = errors.New("required field")
14-
ErrFieldInvalidValue = errors.New("invalid value for field")
15-
ErrBackendNotConfigured = errors.New("backend not configured")
16-
)
17-
18-
type contextKey string
19-
207
const (
218
DefaultConfigFieldAccessTokenMaxTTL = 7 * 24 * time.Hour
229
DefaultConfigFieldAccessTokenRotate = DefaultAutoRotateBeforeMinTTL
@@ -25,44 +12,5 @@ const (
2512
DefaultAccessTokenMaxPossibleTTL = 365 * 24 * time.Hour
2613
DefaultAutoRotateBeforeMinTTL = 24 * time.Hour
2714
DefaultAutoRotateBeforeMaxTTL = 730 * time.Hour
28-
ctxKeyHttpClient = contextKey("vpsg-ctx-key-http-client")
29-
ctxKeyGitlabClient = contextKey("vpsg-ctx-key-gitlab-client")
30-
ctxKeyTimeNow = contextKey("vpsg-ctx-key-time-now")
3115
DefaultConfigName = "default"
3216
)
33-
34-
func WithStaticTime(ctx context.Context, t time.Time) context.Context {
35-
return context.WithValue(ctx, ctxKeyTimeNow, t)
36-
}
37-
38-
func TimeFromContext(ctx context.Context) time.Time {
39-
t, ok := ctx.Value(ctxKeyTimeNow).(time.Time)
40-
if !ok {
41-
return time.Now()
42-
}
43-
return t
44-
}
45-
46-
func HttpClientNewContext(ctx context.Context, httpClient *http.Client) context.Context {
47-
return context.WithValue(ctx, ctxKeyHttpClient, httpClient)
48-
}
49-
50-
func HttpClientFromContext(ctx context.Context) (*http.Client, bool) {
51-
u, ok := ctx.Value(ctxKeyHttpClient).(*http.Client)
52-
if !ok {
53-
u = nil
54-
}
55-
return u, ok
56-
}
57-
58-
func ClientNewContext(ctx context.Context, client Client) context.Context {
59-
return context.WithValue(ctx, ctxKeyGitlabClient, client)
60-
}
61-
62-
func ClientFromContext(ctx context.Context) (Client, bool) {
63-
u, ok := ctx.Value(ctxKeyGitlabClient).(Client)
64-
if !ok {
65-
u = nil
66-
}
67-
return u, ok
68-
}

entry_config.go

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ import (
1111
"github.com/hashicorp/go-multierror"
1212
"github.com/hashicorp/vault/sdk/framework"
1313
"github.com/hashicorp/vault/sdk/logical"
14+
15+
"github.com/ilijamt/vault-plugin-secrets-gitlab/internal/errs"
16+
"github.com/ilijamt/vault-plugin-secrets-gitlab/internal/gitlab"
17+
"github.com/ilijamt/vault-plugin-secrets-gitlab/internal/utils"
1418
)
1519

1620
type EntryConfig struct {
@@ -22,7 +26,7 @@ type EntryConfig struct {
2226
TokenCreatedAt time.Time `json:"token_created_at" structs:"token_created_at" mapstructure:"token_created_at"`
2327
TokenExpiresAt time.Time `json:"token_expires_at" structs:"token_expires_at" mapstructure:"token_expires_at"`
2428
Scopes []string `json:"scopes" structs:"scopes" mapstructure:"scopes"`
25-
Type Type `json:"type" structs:"type" mapstructure:"type"`
29+
Type gitlab.Type `json:"type" structs:"type" mapstructure:"type"`
2630
Name string `json:"name" structs:"name" mapstructure:"name"`
2731
GitlabVersion string `json:"gitlab_version" structs:"gitlab_version" mapstructure:"gitlab_version"`
2832
GitlabRevision string `json:"gitlab_revision" structs:"gitlab_revision" mapstructure:"gitlab_revision"`
@@ -32,7 +36,7 @@ type EntryConfig struct {
3236
func (e *EntryConfig) Merge(data *framework.FieldData) (warnings []string, changes map[string]string, err error) {
3337
var er error
3438
if data == nil {
35-
return warnings, changes, multierror.Append(fmt.Errorf("data: %w", ErrNilValue))
39+
return warnings, changes, multierror.Append(fmt.Errorf("data: %w", errs.ErrNilValue))
3640
}
3741

3842
if err = data.Validate(); err != nil {
@@ -47,8 +51,8 @@ func (e *EntryConfig) Merge(data *framework.FieldData) (warnings []string, chang
4751
}
4852

4953
if typ, ok := data.GetOk("type"); ok {
50-
var pType Type
51-
if pType, er = TypeParse(typ.(string)); er != nil {
54+
var pType gitlab.Type
55+
if pType, er = gitlab.TypeParse(typ.(string)); er != nil {
5256
err = multierror.Append(err, er)
5357
} else {
5458
e.Type = pType
@@ -81,11 +85,11 @@ func (e *EntryConfig) Merge(data *framework.FieldData) (warnings []string, chang
8185

8286
func (e *EntryConfig) updateAutoRotateBefore(data *framework.FieldData) (warnings []string, err *multierror.Error) {
8387
if val, ok := data.GetOk("auto_rotate_before"); ok {
84-
atr, _ := convertToInt(val)
88+
atr, _ := utils.ConvertToInt(val)
8589
if atr > int(DefaultAutoRotateBeforeMaxTTL.Seconds()) {
86-
err = multierror.Append(err, fmt.Errorf("auto_rotate_token can not be bigger than %s: %w", DefaultAutoRotateBeforeMaxTTL, ErrInvalidValue))
90+
err = multierror.Append(err, fmt.Errorf("auto_rotate_token can not be bigger than %s: %w", DefaultAutoRotateBeforeMaxTTL, errs.ErrInvalidValue))
8791
} else if atr <= int(DefaultAutoRotateBeforeMinTTL.Seconds())-1 {
88-
err = multierror.Append(err, fmt.Errorf("auto_rotate_token can not be less than %s: %w", DefaultAutoRotateBeforeMinTTL, ErrInvalidValue))
92+
err = multierror.Append(err, fmt.Errorf("auto_rotate_token can not be less than %s: %w", DefaultAutoRotateBeforeMinTTL, errs.ErrInvalidValue))
8993
} else {
9094
e.AutoRotateBefore = time.Duration(atr) * time.Second
9195
}
@@ -98,7 +102,7 @@ func (e *EntryConfig) updateAutoRotateBefore(data *framework.FieldData) (warning
98102

99103
func (e *EntryConfig) UpdateFromFieldData(data *framework.FieldData) (warnings []string, err error) {
100104
if data == nil {
101-
return warnings, multierror.Append(fmt.Errorf("data: %w", ErrNilValue))
105+
return warnings, multierror.Append(fmt.Errorf("data: %w", errs.ErrNilValue))
102106
}
103107

104108
if err = data.Validate(); err != nil {
@@ -111,21 +115,21 @@ func (e *EntryConfig) UpdateFromFieldData(data *framework.FieldData) (warnings [
111115
if token, ok := data.GetOk("token"); ok && len(token.(string)) > 0 {
112116
e.Token = token.(string)
113117
} else {
114-
err = multierror.Append(err, fmt.Errorf("token: %w", ErrFieldRequired))
118+
err = multierror.Append(err, fmt.Errorf("token: %w", errs.ErrFieldRequired))
115119
}
116120

117121
if typ, ok := data.GetOk("type"); ok {
118-
if e.Type, er = TypeParse(typ.(string)); er != nil {
122+
if e.Type, er = gitlab.TypeParse(typ.(string)); er != nil {
119123
err = multierror.Append(err, er)
120124
}
121125
} else {
122-
err = multierror.Append(err, fmt.Errorf("gitlab type: %w", ErrFieldRequired))
126+
err = multierror.Append(err, fmt.Errorf("gitlab type: %w", errs.ErrFieldRequired))
123127
}
124128

125129
if baseUrl, ok := data.GetOk("base_url"); ok && len(baseUrl.(string)) > 0 {
126130
e.BaseURL = baseUrl.(string)
127131
} else {
128-
err = multierror.Append(err, fmt.Errorf("base_url: %w", ErrFieldRequired))
132+
err = multierror.Append(err, fmt.Errorf("base_url: %w", errs.ErrFieldRequired))
129133
}
130134

131135
{
@@ -173,7 +177,7 @@ func (e *EntryConfig) LogicalResponseData(includeToken bool) (data map[string]an
173177

174178
func getConfig(ctx context.Context, s logical.Storage, name string) (cfg *EntryConfig, err error) {
175179
if s == nil {
176-
return nil, fmt.Errorf("%w: local.Storage", ErrNilValue)
180+
return nil, fmt.Errorf("%w: local.Storage", errs.ErrNilValue)
177181
}
178182
var entry *logical.StorageEntry
179183
if entry, err = s.Get(ctx, fmt.Sprintf("%s/%s", PathConfigStorage, name)); err == nil {

entry_config_merge_test.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
"github.com/stretchr/testify/require"
1313

1414
gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab"
15+
"github.com/ilijamt/vault-plugin-secrets-gitlab/internal/errs"
16+
gitlab2 "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/gitlab"
1517
)
1618

1719
func TestEntryConfigMerge(t *testing.T) {
@@ -20,7 +22,7 @@ func TestEntryConfigMerge(t *testing.T) {
2022
warnings, changes, err := e.Merge(nil)
2123
require.Empty(t, warnings)
2224
require.Empty(t, changes)
23-
require.ErrorIs(t, err, gitlab.ErrNilValue)
25+
require.ErrorIs(t, err, errs.ErrNilValue)
2426
})
2527

2628
t.Run("unconvertible data type", func(t *testing.T) {
@@ -46,10 +48,10 @@ func TestEntryConfigMerge(t *testing.T) {
4648
}{
4749
{
4850
name: "update type only",
49-
originalConfig: &gitlab.EntryConfig{Type: gitlab.TypeSelfManaged},
50-
expectedConfig: &gitlab.EntryConfig{Type: gitlab.TypeSaaS},
51-
raw: map[string]interface{}{"type": gitlab.TypeSaaS},
52-
changes: map[string]string{"type": gitlab.TypeSaaS.String()},
51+
originalConfig: &gitlab.EntryConfig{Type: gitlab2.TypeSelfManaged},
52+
expectedConfig: &gitlab.EntryConfig{Type: gitlab2.TypeSaaS},
53+
raw: map[string]interface{}{"type": gitlab2.TypeSaaS},
54+
changes: map[string]string{"type": gitlab2.TypeSaaS.String()},
5355
},
5456
{
5557
name: "auto rotate token set to false",
@@ -67,12 +69,12 @@ func TestEntryConfigMerge(t *testing.T) {
6769
},
6870
{
6971
name: "update type with invalid type",
70-
originalConfig: &gitlab.EntryConfig{Type: gitlab.TypeSelfManaged},
71-
expectedConfig: &gitlab.EntryConfig{Type: gitlab.TypeSelfManaged},
72+
originalConfig: &gitlab.EntryConfig{Type: gitlab2.TypeSelfManaged},
73+
expectedConfig: &gitlab.EntryConfig{Type: gitlab2.TypeSelfManaged},
7274
raw: map[string]interface{}{"type": "test"},
7375
err: true,
7476
errMap: map[string]int{
75-
gitlab.ErrUnknownType.Error(): 1,
77+
gitlab2.ErrUnknownType.Error(): 1,
7678
},
7779
},
7880
{
@@ -95,15 +97,15 @@ func TestEntryConfigMerge(t *testing.T) {
9597
expectedConfig: &gitlab.EntryConfig{AutoRotateBefore: gitlab.DefaultAutoRotateBeforeMinTTL + time.Hour},
9698
raw: map[string]interface{}{"auto_rotate_before": "1h"},
9799
err: true,
98-
errMap: map[string]int{gitlab.ErrInvalidValue.Error(): 1},
100+
errMap: map[string]int{errs.ErrInvalidValue.Error(): 1},
99101
},
100102
{
101103
name: "auto rotate before invalid value higher than min",
102104
originalConfig: &gitlab.EntryConfig{AutoRotateBefore: gitlab.DefaultAutoRotateBeforeMinTTL + time.Hour},
103105
expectedConfig: &gitlab.EntryConfig{AutoRotateBefore: gitlab.DefaultAutoRotateBeforeMinTTL + time.Hour},
104106
raw: map[string]interface{}{"auto_rotate_before": (gitlab.DefaultAutoRotateBeforeMaxTTL + time.Hour).String()},
105107
err: true,
106-
errMap: map[string]int{gitlab.ErrInvalidValue.Error(): 1},
108+
errMap: map[string]int{errs.ErrInvalidValue.Error(): 1},
107109
},
108110
{
109111
name: "auto rotate with a valid value",

entry_config_update_form_field_data_test.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ import (
1111
"github.com/stretchr/testify/require"
1212

1313
gitlab "github.com/ilijamt/vault-plugin-secrets-gitlab"
14+
"github.com/ilijamt/vault-plugin-secrets-gitlab/internal/errs"
15+
gitlab2 "github.com/ilijamt/vault-plugin-secrets-gitlab/internal/gitlab"
1416
)
1517

1618
func TestEntryConfigUpdateFromFieldData(t *testing.T) {
1719
t.Run("nil data", func(t *testing.T) {
1820
e := new(gitlab.EntryConfig)
1921
_, err := e.UpdateFromFieldData(nil)
20-
require.ErrorIs(t, err, gitlab.ErrNilValue)
22+
require.ErrorIs(t, err, errs.ErrNilValue)
2123
})
2224

2325
var tests = []struct {
@@ -34,7 +36,7 @@ func TestEntryConfigUpdateFromFieldData(t *testing.T) {
3436
err: true,
3537
warnings: []string{"auto_rotate_token not specified setting to 24h0m0s"},
3638
errMap: map[string]int{
37-
gitlab.ErrFieldRequired.Error(): 3,
39+
errs.ErrFieldRequired.Error(): 3,
3840
},
3941
},
4042
{
@@ -47,8 +49,8 @@ func TestEntryConfigUpdateFromFieldData(t *testing.T) {
4749
warnings: []string{"auto_rotate_token not specified setting to 24h0m0s"},
4850
err: true,
4951
errMap: map[string]int{
50-
gitlab.ErrFieldRequired.Error(): 1,
51-
gitlab.ErrUnknownType.Error(): 1,
52+
errs.ErrFieldRequired.Error(): 1,
53+
gitlab2.ErrUnknownType.Error(): 1,
5254
},
5355
},
5456
{
@@ -64,15 +66,15 @@ func TestEntryConfigUpdateFromFieldData(t *testing.T) {
6466
name: "valid config",
6567
expectedConfig: &gitlab.EntryConfig{
6668
Token: "token",
67-
Type: gitlab.TypeSelfManaged,
69+
Type: gitlab2.TypeSelfManaged,
6870
AutoRotateToken: false,
6971
AutoRotateBefore: gitlab.DefaultAutoRotateBeforeMinTTL,
7072
BaseURL: "https://gitlab.com",
7173
},
7274
warnings: []string{"auto_rotate_token not specified setting to 24h0m0s"},
7375
raw: map[string]interface{}{
7476
"token": "token",
75-
"type": gitlab.TypeSelfManaged.String(),
77+
"type": gitlab2.TypeSelfManaged.String(),
7678
"base_url": "https://gitlab.com",
7779
},
7880
},

entry_role.go

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,28 @@ import (
66
"time"
77

88
"github.com/hashicorp/vault/sdk/logical"
9+
10+
"github.com/ilijamt/vault-plugin-secrets-gitlab/internal/token"
911
)
1012

1113
type EntryRole struct {
12-
RoleName string `json:"role_name" structs:"role_name" mapstructure:"role_name"`
13-
TTL time.Duration `json:"ttl" structs:"ttl" mapstructure:"ttl"`
14-
Path string `json:"path" structs:"path" mapstructure:"path"`
15-
Name string `json:"name" structs:"name" mapstructure:"name"`
16-
Scopes []string `json:"scopes" structs:"scopes" mapstructure:"scopes"`
17-
AccessLevel AccessLevel `json:"access_level" structs:"access_level" mapstructure:"access_level,omitempty"`
18-
TokenType TokenType `json:"token_type" structs:"token_type" mapstructure:"token_type"`
19-
GitlabRevokesTokens bool `json:"gitlab_revokes_token" structs:"gitlab_revokes_token" mapstructure:"gitlab_revokes_token"`
20-
ConfigName string `json:"config_name" structs:"config_name" mapstructure:"config_name"`
14+
RoleName string `json:"role_name" structs:"role_name" mapstructure:"role_name"`
15+
TTL time.Duration `json:"ttl" structs:"ttl" mapstructure:"ttl"`
16+
Path string `json:"path" structs:"path" mapstructure:"path"`
17+
Name string `json:"name" structs:"name" mapstructure:"name"`
18+
Scopes []string `json:"scopes" structs:"scopes" mapstructure:"scopes"`
19+
AccessLevel token.AccessLevel `json:"access_level" structs:"access_level" mapstructure:"access_level,omitempty"`
20+
TokenType token.Type `json:"token_type" structs:"token_type" mapstructure:"token_type"`
21+
GitlabRevokesTokens bool `json:"gitlab_revokes_token" structs:"gitlab_revokes_token" mapstructure:"gitlab_revokes_token"`
22+
ConfigName string `json:"config_name" structs:"config_name" mapstructure:"config_name"`
23+
}
24+
25+
func (e EntryRole) IsNil() bool {
26+
return false
27+
}
28+
29+
func (e EntryRole) GetName() string {
30+
return e.Name
2131
}
2232

2333
func (e EntryRole) LogicalResponseData() map[string]any {

0 commit comments

Comments
 (0)