Skip to content

Commit b5f751c

Browse files
committed
fix(config): allow usage of full config struct
Signed-off-by: Nicklas Frahm <nicklas.frahm@gmail.com>
1 parent 222a7f7 commit b5f751c

File tree

2 files changed

+58
-66
lines changed

2 files changed

+58
-66
lines changed

config/config.go

Lines changed: 43 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,11 @@ import (
1717
"github.com/getsops/sops/v3/gcpkms"
1818
"github.com/getsops/sops/v3/hcvault"
1919
"github.com/getsops/sops/v3/kms"
20-
"github.com/getsops/sops/v3/logging"
2120
"github.com/getsops/sops/v3/pgp"
2221
"github.com/getsops/sops/v3/publish"
23-
"github.com/sirupsen/logrus"
2422
"gopkg.in/yaml.v3"
2523
)
2624

27-
var log *logrus.Logger
28-
29-
func init() {
30-
log = logging.NewLogger("CONFIG")
31-
}
32-
3325
type fileSystem interface {
3426
Stat(name string) (os.FileInfo, error)
3527
}
@@ -87,40 +79,41 @@ type StoresConfig struct {
8779
YAML YAMLStoreConfig `yaml:"yaml"`
8880
}
8981

90-
type configFile struct {
91-
CreationRules []creationRule `yaml:"creation_rules"`
92-
DestinationRules []destinationRule `yaml:"destination_rules"`
82+
// ConfigFile is the struct representation of a full sops config file
83+
type ConfigFile struct {
84+
CreationRules []CreationRule `yaml:"creation_rules"`
85+
DestinationRules []CestinationRule `yaml:"destination_rules"`
9386
Stores StoresConfig `yaml:"stores"`
9487
}
9588

96-
type keyGroup struct {
97-
Merge []keyGroup
98-
KMS []kmsKey
99-
GCPKMS []gcpKmsKey `yaml:"gcp_kms"`
100-
AzureKV []azureKVKey `yaml:"azure_keyvault"`
89+
type KeyGroup struct {
90+
Merge []KeyGroup
91+
KMS []KmsKey
92+
GCPKMS []GcpKmsKey `yaml:"gcp_kms"`
93+
AzureKV []AzureKVKey `yaml:"azure_keyvault"`
10194
Vault []string `yaml:"hc_vault"`
10295
Age []string `yaml:"age"`
10396
PGP []string
10497
}
10598

106-
type gcpKmsKey struct {
99+
type GcpKmsKey struct {
107100
ResourceID string `yaml:"resource_id"`
108101
}
109102

110-
type kmsKey struct {
103+
type KmsKey struct {
111104
Arn string `yaml:"arn"`
112105
Role string `yaml:"role,omitempty"`
113106
Context map[string]*string `yaml:"context"`
114107
AwsProfile string `yaml:"aws_profile"`
115108
}
116109

117-
type azureKVKey struct {
110+
type AzureKVKey struct {
118111
VaultURL string `yaml:"vaultUrl"`
119112
Key string `yaml:"key"`
120113
Version string `yaml:"version"`
121114
}
122115

123-
type destinationRule struct {
116+
type CestinationRule struct {
124117
PathRegex string `yaml:"path_regex"`
125118
S3Bucket string `yaml:"s3_bucket"`
126119
S3Prefix string `yaml:"s3_prefix"`
@@ -130,11 +123,11 @@ type destinationRule struct {
130123
VaultAddress string `yaml:"vault_address"`
131124
VaultKVMountName string `yaml:"vault_kv_mount_name"`
132125
VaultKVVersion int `yaml:"vault_kv_version"`
133-
RecreationRule creationRule `yaml:"recreation_rule,omitempty"`
126+
RecreationRule CreationRule `yaml:"recreation_rule,omitempty"`
134127
OmitExtensions bool `yaml:"omit_extensions"`
135128
}
136129

137-
type creationRule struct {
130+
type CreationRule struct {
138131
PathRegex string `yaml:"path_regex"`
139132
KMS string
140133
AwsProfile string `yaml:"aws_profile"`
@@ -143,7 +136,7 @@ type creationRule struct {
143136
GCPKMS string `yaml:"gcp_kms"`
144137
AzureKeyVault string `yaml:"azure_keyvault"`
145138
VaultURI string `yaml:"hc_vault_transit_uri"`
146-
KeyGroups []keyGroup `yaml:"key_groups"`
139+
KeyGroups []KeyGroup `yaml:"key_groups"`
147140
ShamirThreshold int `yaml:"shamir_threshold"`
148141
UnencryptedSuffix string `yaml:"unencrypted_suffix"`
149142
EncryptedSuffix string `yaml:"encrypted_suffix"`
@@ -162,10 +155,10 @@ func NewStoresConfig() *StoresConfig {
162155
}
163156

164157
// Load loads a sops config file into a temporary struct
165-
func (f *configFile) load(bytes []byte) error {
158+
func (f *ConfigFile) load(bytes []byte) error {
166159
err := yaml.Unmarshal(bytes, f)
167160
if err != nil {
168-
return fmt.Errorf("Could not unmarshal config file: %s", err)
161+
return fmt.Errorf("could not unmarshal config file: %s", err)
169162
}
170163
return nil
171164
}
@@ -203,7 +196,7 @@ func deduplicateKeygroup(group sops.KeyGroup) sops.KeyGroup {
203196
return deduplicatedKeygroup
204197
}
205198

206-
func extractMasterKeys(group keyGroup) (sops.KeyGroup, error) {
199+
func extractMasterKeys(group KeyGroup) (sops.KeyGroup, error) {
207200
var keyGroup sops.KeyGroup
208201
for _, k := range group.Merge {
209202
subKeyGroup, err := extractMasterKeys(k)
@@ -244,7 +237,7 @@ func extractMasterKeys(group keyGroup) (sops.KeyGroup, error) {
244237
return deduplicateKeygroup(keyGroup), nil
245238
}
246239

247-
func getKeyGroupsFromCreationRule(cRule *creationRule, kmsEncryptionContext map[string]*string) ([]sops.KeyGroup, error) {
240+
func getKeyGroupsFromCreationRule(cRule *CreationRule, kmsEncryptionContext map[string]*string) ([]sops.KeyGroup, error) {
248241
var groups []sops.KeyGroup
249242
if len(cRule.KeyGroups) > 0 {
250243
for _, group := range cRule.KeyGroups {
@@ -294,12 +287,13 @@ func getKeyGroupsFromCreationRule(cRule *creationRule, kmsEncryptionContext map[
294287
return groups, nil
295288
}
296289

297-
func loadConfigFile(confPath string) (*configFile, error) {
290+
// LoadConfigFile loads a sops config file from a given path
291+
func LoadConfigFile(confPath string) (*ConfigFile, error) {
298292
confBytes, err := os.ReadFile(confPath)
299293
if err != nil {
300294
return nil, fmt.Errorf("could not read config file: %s", err)
301295
}
302-
conf := &configFile{}
296+
conf := &ConfigFile{}
303297
conf.Stores = *NewStoresConfig()
304298
err = conf.load(confBytes)
305299
if err != nil {
@@ -308,7 +302,7 @@ func loadConfigFile(confPath string) (*configFile, error) {
308302
return conf, nil
309303
}
310304

311-
func configFromRule(rule *creationRule, kmsEncryptionContext map[string]*string) (*Config, error) {
305+
func configFromRule(rule *CreationRule, kmsEncryptionContext map[string]*string) (*Config, error) {
312306
cryptRuleCount := 0
313307
if rule.UnencryptedSuffix != "" {
314308
cryptRuleCount++
@@ -351,9 +345,9 @@ func configFromRule(rule *creationRule, kmsEncryptionContext map[string]*string)
351345
}, nil
352346
}
353347

354-
func parseDestinationRuleForFile(conf *configFile, filePath string, kmsEncryptionContext map[string]*string) (*Config, error) {
355-
var rule *creationRule
356-
var dRule *destinationRule
348+
func parseDestinationRuleForFile(conf *ConfigFile, filePath string, kmsEncryptionContext map[string]*string) (*Config, error) {
349+
var rule *CreationRule
350+
var dRule *CestinationRule
357351

358352
if len(conf.DestinationRules) > 0 {
359353
for _, r := range conf.DestinationRules {
@@ -377,19 +371,17 @@ func parseDestinationRuleForFile(conf *configFile, filePath string, kmsEncryptio
377371
}
378372

379373
var dest publish.Destination
380-
if dRule != nil {
381-
if dRule.S3Bucket != "" && dRule.GCSBucket != "" && dRule.VaultPath != "" {
382-
return nil, fmt.Errorf("error loading config: more than one destinations were found in a single destination rule, you can only use one per rule")
383-
}
384-
if dRule.S3Bucket != "" {
385-
dest = publish.NewS3Destination(dRule.S3Bucket, dRule.S3Prefix)
386-
}
387-
if dRule.GCSBucket != "" {
388-
dest = publish.NewGCSDestination(dRule.GCSBucket, dRule.GCSPrefix)
389-
}
390-
if dRule.VaultPath != "" {
391-
dest = publish.NewVaultDestination(dRule.VaultAddress, dRule.VaultPath, dRule.VaultKVMountName, dRule.VaultKVVersion)
392-
}
374+
if dRule.S3Bucket != "" && dRule.GCSBucket != "" && dRule.VaultPath != "" {
375+
return nil, fmt.Errorf("error loading config: more than one destinations were found in a single destination rule, you can only use one per rule")
376+
}
377+
if dRule.S3Bucket != "" {
378+
dest = publish.NewS3Destination(dRule.S3Bucket, dRule.S3Prefix)
379+
}
380+
if dRule.GCSBucket != "" {
381+
dest = publish.NewGCSDestination(dRule.GCSBucket, dRule.GCSPrefix)
382+
}
383+
if dRule.VaultPath != "" {
384+
dest = publish.NewVaultDestination(dRule.VaultAddress, dRule.VaultPath, dRule.VaultKVMountName, dRule.VaultKVVersion)
393385
}
394386

395387
config, err := configFromRule(rule, kmsEncryptionContext)
@@ -402,7 +394,7 @@ func parseDestinationRuleForFile(conf *configFile, filePath string, kmsEncryptio
402394
return config, nil
403395
}
404396

405-
func parseCreationRuleForFile(conf *configFile, confPath, filePath string, kmsEncryptionContext map[string]*string) (*Config, error) {
397+
func parseCreationRuleForFile(conf *ConfigFile, confPath, filePath string, kmsEncryptionContext map[string]*string) (*Config, error) {
406398
// If config file doesn't contain CreationRules (it's empty or only contains DestionationRules), assume it does not exist
407399
if conf.CreationRules == nil {
408400
return nil, nil
@@ -416,7 +408,7 @@ func parseCreationRuleForFile(conf *configFile, confPath, filePath string, kmsEn
416408
// compare file path relative to path of config file
417409
filePath = strings.TrimPrefix(filePath, configDir+string(filepath.Separator))
418410

419-
var rule *creationRule
411+
var rule *CreationRule
420412

421413
for _, r := range conf.CreationRules {
422414
if r.PathRegex == "" {
@@ -449,7 +441,7 @@ func parseCreationRuleForFile(conf *configFile, confPath, filePath string, kmsEn
449441
// should be provided for configurations that do not contain key groups, as there's no way to specify context inside
450442
// a SOPS config file outside of key groups.
451443
func LoadCreationRuleForFile(confPath string, filePath string, kmsEncryptionContext map[string]*string) (*Config, error) {
452-
conf, err := loadConfigFile(confPath)
444+
conf, err := LoadConfigFile(confPath)
453445
if err != nil {
454446
return nil, err
455447
}
@@ -460,15 +452,15 @@ func LoadCreationRuleForFile(confPath string, filePath string, kmsEncryptionCont
460452
// LoadDestinationRuleForFile works the same as LoadCreationRuleForFile, but gets the "creation_rule" from the matching destination_rule's
461453
// "recreation_rule".
462454
func LoadDestinationRuleForFile(confPath string, filePath string, kmsEncryptionContext map[string]*string) (*Config, error) {
463-
conf, err := loadConfigFile(confPath)
455+
conf, err := LoadConfigFile(confPath)
464456
if err != nil {
465457
return nil, err
466458
}
467459
return parseDestinationRuleForFile(conf, filePath, kmsEncryptionContext)
468460
}
469461

470462
func LoadStoresConfig(confPath string) (*StoresConfig, error) {
471-
conf, err := loadConfigFile(confPath)
463+
conf, err := LoadConfigFile(confPath)
472464
if err != nil {
473465
return nil, err
474466
}

config/config_test.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -387,16 +387,16 @@ creation_rules:
387387
kms: default
388388
`)
389389

390-
func parseConfigFile(confBytes []byte, t *testing.T) *configFile {
391-
conf := &configFile{}
390+
func parseConfigFile(confBytes []byte, t *testing.T) *ConfigFile {
391+
conf := &ConfigFile{}
392392
err := conf.load(confBytes)
393393
assert.Nil(t, err)
394394
return conf
395395
}
396396

397397
func TestLoadConfigFile(t *testing.T) {
398-
expected := configFile{
399-
CreationRules: []creationRule{
398+
expected := ConfigFile{
399+
CreationRules: []CreationRule{
400400
{
401401
PathRegex: "foobar*",
402402
KMS: "1",
@@ -414,46 +414,46 @@ func TestLoadConfigFile(t *testing.T) {
414414
},
415415
}
416416

417-
conf := configFile{}
417+
conf := ConfigFile{}
418418
err := conf.load(sampleConfig)
419419
assert.Nil(t, err)
420420
assert.Equal(t, expected, conf)
421421
}
422422

423423
func TestLoadConfigFileWithGroups(t *testing.T) {
424-
expected := configFile{
425-
CreationRules: []creationRule{
424+
expected := ConfigFile{
425+
CreationRules: []CreationRule{
426426
{
427427
PathRegex: "foobar*",
428428
KMS: "1",
429429
PGP: "2",
430430
},
431431
{
432432
PathRegex: "",
433-
KeyGroups: []keyGroup{
433+
KeyGroups: []KeyGroup{
434434
{
435-
KMS: []kmsKey{{Arn: "foo", AwsProfile: "bar"}},
435+
KMS: []KmsKey{{Arn: "foo", AwsProfile: "bar"}},
436436
PGP: []string{"bar"},
437-
GCPKMS: []gcpKmsKey{{ResourceID: "foo"}},
438-
AzureKV: []azureKVKey{{VaultURL: "https://foo.vault.azure.net", Key: "foo-key", Version: "fooversion"}},
437+
GCPKMS: []GcpKmsKey{{ResourceID: "foo"}},
438+
AzureKV: []AzureKVKey{{VaultURL: "https://foo.vault.azure.net", Key: "foo-key", Version: "fooversion"}},
439439
Vault: []string{"https://foo.vault:8200/v1/foo/keys/foo-key"},
440440
},
441441
{
442-
KMS: []kmsKey{{Arn: "baz", AwsProfile: "foo"}},
442+
KMS: []KmsKey{{Arn: "baz", AwsProfile: "foo"}},
443443
PGP: []string{"qux"},
444-
GCPKMS: []gcpKmsKey{
444+
GCPKMS: []GcpKmsKey{
445445
{ResourceID: "bar"},
446446
{ResourceID: "baz"},
447447
},
448-
AzureKV: []azureKVKey{{VaultURL: "https://bar.vault.azure.net", Key: "bar-key", Version: "barversion"}},
448+
AzureKV: []AzureKVKey{{VaultURL: "https://bar.vault.azure.net", Key: "bar-key", Version: "barversion"}},
449449
Vault: []string{"https://baz.vault:8200/v1/baz/keys/baz-key"},
450450
},
451451
},
452452
},
453453
},
454454
}
455455

456-
conf := configFile{}
456+
conf := ConfigFile{}
457457
err := conf.load(sampleConfigWithGroups)
458458
assert.Nil(t, err)
459459
assert.Equal(t, expected, conf)

0 commit comments

Comments
 (0)