From 0cc08daa1dd33073746393dec3d2c41c73c17b13 Mon Sep 17 00:00:00 2001 From: Johan Fleury Date: Mon, 5 Apr 2021 17:31:52 -0400 Subject: [PATCH] config: support setting age and PGP keys as a strings array --- age/keysource.go | 10 ++++------ age/keysource_test.go | 3 +-- cmd/sops/main.go | 14 +++++++------- config/config.go | 30 ++++++++++++++++++++++++++---- config/config_test.go | 6 +++--- pgp/keysource.go | 7 ++----- pgp/keysource_test.go | 2 +- 7 files changed, 44 insertions(+), 28 deletions(-) diff --git a/age/keysource.go b/age/keysource.go index c0b9c65611..dc30d684ee 100644 --- a/age/keysource.go +++ b/age/keysource.go @@ -155,14 +155,12 @@ func (key *MasterKey) ToMap() map[string]interface{} { // MasterKeysFromRecipients takes a comma-separated list of Bech32-encoded public keys and returns a // slice of new MasterKeys. -func MasterKeysFromRecipients(commaSeparatedRecipients string) ([]*MasterKey, error) { - if commaSeparatedRecipients == "" { - // otherwise Split returns [""] and MasterKeyFromRecipient is unhappy +func MasterKeysFromRecipients(recipients []string) ([]*MasterKey, error) { + var keys []*MasterKey + + if len(recipients) < 1 { return make([]*MasterKey, 0), nil } - recipients := strings.Split(commaSeparatedRecipients, ",") - - var keys []*MasterKey for _, recipient := range recipients { key, err := MasterKeyFromRecipient(recipient) diff --git a/age/keysource_test.go b/age/keysource_test.go index 2a3bebdfd3..51de61412b 100644 --- a/age/keysource_test.go +++ b/age/keysource_test.go @@ -12,8 +12,7 @@ import ( func TestMasterKeysFromRecipientsEmpty(t *testing.T) { assert := assert.New(t) - commaSeparatedRecipients := "" - recipients, err := MasterKeysFromRecipients(commaSeparatedRecipients) + recipients, err := MasterKeysFromRecipients([]string{}) assert.NoError(err) diff --git a/cmd/sops/main.go b/cmd/sops/main.go index 148daa7297..fe32cf3843 100644 --- a/cmd/sops/main.go +++ b/cmd/sops/main.go @@ -574,7 +574,7 @@ func main() { Usage: "comma separated list of vault's key URI (e.g. 'https://vault.example.org:8200/v1/transit/keys/dev')", EnvVar: "SOPS_VAULT_URIS", }, - cli.StringFlag{ + cli.StringSliceFlag{ Name: "pgp, p", Usage: "comma separated list of PGP fingerprints", EnvVar: "SOPS_PGP_FP", @@ -822,7 +822,7 @@ func main() { for _, k := range kms.MasterKeysFromArnString(c.String("add-kms"), kmsEncryptionContext, c.String("aws-profile")) { addMasterKeys = append(addMasterKeys, k) } - for _, k := range pgp.MasterKeysFromFingerprintString(c.String("add-pgp")) { + for _, k := range pgp.MasterKeysFromFingerprintString(c.StringSlice("add-pgp")) { addMasterKeys = append(addMasterKeys, k) } for _, k := range gcpkms.MasterKeysFromResourceIDString(c.String("add-gcp-kms")) { @@ -842,7 +842,7 @@ func main() { for _, k := range hcVaultKeys { addMasterKeys = append(addMasterKeys, k) } - ageKeys, err := age.MasterKeysFromRecipients(c.String("add-age")) + ageKeys, err := age.MasterKeysFromRecipients(c.StringSlice("add-age")) if err != nil { return err } @@ -854,7 +854,7 @@ func main() { for _, k := range kms.MasterKeysFromArnString(c.String("rm-kms"), kmsEncryptionContext, c.String("aws-profile")) { rmMasterKeys = append(rmMasterKeys, k) } - for _, k := range pgp.MasterKeysFromFingerprintString(c.String("rm-pgp")) { + for _, k := range pgp.MasterKeysFromFingerprintString(c.StringSlice("rm-pgp")) { rmMasterKeys = append(rmMasterKeys, k) } for _, k := range gcpkms.MasterKeysFromResourceIDString(c.String("rm-gcp-kms")) { @@ -874,7 +874,7 @@ func main() { for _, k := range hcVaultKeys { rmMasterKeys = append(rmMasterKeys, k) } - ageKeys, err = age.MasterKeysFromRecipients(c.String("rm-age")) + ageKeys, err = age.MasterKeysFromRecipients(c.StringSlice("rm-age")) if err != nil { return err } @@ -1111,12 +1111,12 @@ func keyGroups(c *cli.Context, file string) ([]sops.KeyGroup, error) { } } if c.String("pgp") != "" { - for _, k := range pgp.MasterKeysFromFingerprintString(c.String("pgp")) { + for _, k := range pgp.MasterKeysFromFingerprintString(c.StringSlice("pgp")) { pgpKeys = append(pgpKeys, k) } } if c.String("age") != "" { - ageKeys, err := age.MasterKeysFromRecipients(c.String("age")) + ageKeys, err := age.MasterKeysFromRecipients(c.StringSlice("age")) if err != nil { return nil, err } diff --git a/config/config.go b/config/config.go index e89336ddc5..d9596aa42f 100644 --- a/config/config.go +++ b/config/config.go @@ -23,6 +23,28 @@ import ( "gopkg.in/yaml.v3" ) +type CommaSeparatedValue []string + +func (a *CommaSeparatedValue) UnmarshalYAML(unmarshal func(interface{}) error) error { + var multi []string + if err := unmarshal(&multi); err != nil { + var single string + if err := unmarshal(&single); err != nil { + return err + } + + if single == "" { + *a = []string{} + } else { + *a = []string{single} + } + } else { + *a = multi + } + + return nil +} + var log *logrus.Logger func init() { @@ -110,9 +132,9 @@ type destinationRule struct { type creationRule struct { PathRegex string `yaml:"path_regex"` KMS string - AwsProfile string `yaml:"aws_profile"` - Age string `yaml:"age"` - PGP string + AwsProfile string `yaml:"aws_profile"` + Age CommaSeparatedValue `yaml:"age"` + PGP CommaSeparatedValue GCPKMS string `yaml:"gcp_kms"` AzureKeyVault string `yaml:"azure_keyvault"` VaultURI string `yaml:"hc_vault_transit_uri"` @@ -180,7 +202,7 @@ func getKeyGroupsFromCreationRule(cRule *creationRule, kmsEncryptionContext map[ } } else { var keyGroup sops.KeyGroup - if cRule.Age != "" { + if len(cRule.Age) > 0 { ageKeys, err := age.MasterKeysFromRecipients(cRule.Age) if err != nil { return nil, err diff --git a/config/config_test.go b/config/config_test.go index ac8aca6f38..6f217df1af 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -239,14 +239,14 @@ func TestLoadConfigFile(t *testing.T) { { PathRegex: "foobar*", KMS: "1", - PGP: "2", + PGP: []string{"2"}, GCPKMS: "3", VaultURI: "http://4:8200/v1/4/keys/4", }, { PathRegex: "", KMS: "foo", - PGP: "bar", + PGP: []string{"bar"}, GCPKMS: "baz", VaultURI: "http://127.0.1.1/v1/baz/keys/baz", }, @@ -265,7 +265,7 @@ func TestLoadConfigFileWithGroups(t *testing.T) { { PathRegex: "foobar*", KMS: "1", - PGP: "2", + PGP: []string{"2"}, }, { PathRegex: "", diff --git a/pgp/keysource.go b/pgp/keysource.go index f025c66a2d..fce9e0416d 100644 --- a/pgp/keysource.go +++ b/pgp/keysource.go @@ -268,12 +268,9 @@ func NewMasterKeyFromFingerprint(fingerprint string) *MasterKey { } // MasterKeysFromFingerprintString takes a comma separated list of PGP fingerprints and returns a slice of new MasterKeys with those fingerprints -func MasterKeysFromFingerprintString(fingerprint string) []*MasterKey { +func MasterKeysFromFingerprintString(fingerprints []string) []*MasterKey { var keys []*MasterKey - if fingerprint == "" { - return keys - } - for _, s := range strings.Split(fingerprint, ",") { + for _, s := range fingerprints { keys = append(keys, NewMasterKeyFromFingerprint(s)) } return keys diff --git a/pgp/keysource_test.go b/pgp/keysource_test.go index 0c10996d1e..cda16ed4bb 100644 --- a/pgp/keysource_test.go +++ b/pgp/keysource_test.go @@ -31,7 +31,7 @@ func TestPGP(t *testing.T) { } func TestPGPKeySourceFromString(t *testing.T) { - s := "C8C5 2C0A B2A4 8174 01E8 12C8 F3CC 3233 3FAD 9F1E, C8C5 2C0A B2A4 8174 01E8 12C8 F3CC 3233 3FAD 9F1E" + s := []string{"C8C5 2C0A B2A4 8174 01E8 12C8 F3CC 3233 3FAD 9F1E", "C8C5 2C0A B2A4 8174 01E8 12C8 F3CC 3233 3FAD 9F1E"} ks := MasterKeysFromFingerprintString(s) expected := "C8C52C0AB2A4817401E812C8F3CC32333FAD9F1E" if ks[0].Fingerprint != expected {