mirror of
https://github.com/Mic92/sops-nix.git
synced 2024-12-14 11:57:52 +00:00
Merge pull request #262 from lucasew/feat/type-dotenv
format type: add dotenv and ini
This commit is contained in:
commit
415302126e
9 changed files with 125 additions and 28 deletions
|
@ -25,7 +25,7 @@ environment variables that can be passed to sops.
|
||||||
- Atomic upgrades: New secrets are written to a new directory which replaces the old directory atomically.
|
- Atomic upgrades: New secrets are written to a new directory which replaces the old directory atomically.
|
||||||
- Rollback support: If sops files are added to the Nix store, old secrets can be rolled back. This is optional.
|
- Rollback support: If sops files are added to the Nix store, old secrets can be rolled back. This is optional.
|
||||||
- Fast time-to-deploy: Unlike solutions implemented by NixOps, krops and morph, no extra steps are required to upload secrets.
|
- Fast time-to-deploy: Unlike solutions implemented by NixOps, krops and morph, no extra steps are required to upload secrets.
|
||||||
- A variety of storage formats: Secrets can be stored in YAML, JSON or binary.
|
- A variety of storage formats: Secrets can be stored in YAML, dotenv, INI, JSON or binary.
|
||||||
- Minimizes configuration errors: sops files are checked against the configuration at evaluation time.
|
- Minimizes configuration errors: sops files are checked against the configuration at evaluation time.
|
||||||
|
|
||||||
## Demo
|
## Demo
|
||||||
|
@ -603,7 +603,7 @@ As users are not created yet, it's not possible to set an owner for these secret
|
||||||
|
|
||||||
## Different file formats
|
## Different file formats
|
||||||
|
|
||||||
At the moment we support the following file formats: YAML, JSON, and binary.
|
At the moment we support the following file formats: YAML, JSON, INI, dotenv and binary.
|
||||||
|
|
||||||
sops-nix allows specifying multiple sops files in different file formats:
|
sops-nix allows specifying multiple sops files in different file formats:
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{ pkgs ? import <nixpkgs> {} }: let
|
{ pkgs ? import <nixpkgs> {} }: let
|
||||||
vendorSha256 = "sha256-7DHISMAs7i6Yow0/ORiC8gLLfFeuSeiP8QchnJe3M+M=";
|
vendorSha256 = "sha256-ZAHshOBbvwOC1618bi7IqOan+YtDT7DJNsLzV/4OBSg=";
|
||||||
|
|
||||||
buildGoModule = if pkgs.lib.versionOlder pkgs.go.version "1.18" then pkgs.buildGo118Module else pkgs.buildGoModule;
|
buildGoModule = if pkgs.lib.versionOlder pkgs.go.version "1.18" then pkgs.buildGo118Module else pkgs.buildGoModule;
|
||||||
sops-install-secrets = pkgs.callPackage ./pkgs/sops-install-secrets {
|
sops-install-secrets = pkgs.callPackage ./pkgs/sops-install-secrets {
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -18,6 +18,7 @@ require (
|
||||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||||
github.com/hashicorp/vault/api v1.7.2 // indirect
|
github.com/hashicorp/vault/api v1.7.2 // indirect
|
||||||
github.com/hashicorp/vault/sdk v0.5.2 // indirect
|
github.com/hashicorp/vault/sdk v0.5.2 // indirect
|
||||||
|
github.com/joho/godotenv v1.4.0 // indirect
|
||||||
github.com/lib/pq v1.10.6 // indirect
|
github.com/lib/pq v1.10.6 // indirect
|
||||||
github.com/mozilla-services/yaml v0.0.0-20201007153854-c369669a6625
|
github.com/mozilla-services/yaml v0.0.0-20201007153854-c369669a6625
|
||||||
go.mozilla.org/sops/v3 v3.7.3
|
go.mozilla.org/sops/v3 v3.7.3
|
||||||
|
|
3
go.sum
3
go.sum
|
@ -403,6 +403,8 @@ github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9Y
|
||||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
|
||||||
|
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
|
||||||
|
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
@ -758,7 +760,6 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
|
|
@ -41,7 +41,7 @@ let
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
format = mkOption {
|
format = mkOption {
|
||||||
type = types.enum ["yaml" "json" "binary"];
|
type = types.enum ["yaml" "json" "binary" "dotenv" "ini"];
|
||||||
default = cfg.defaultSopsFormat;
|
default = cfg.defaultSopsFormat;
|
||||||
description = ''
|
description = ''
|
||||||
File format used to decrypt the sops secret.
|
File format used to decrypt the sops secret.
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
"github.com/mozilla-services/yaml"
|
"github.com/mozilla-services/yaml"
|
||||||
"go.mozilla.org/sops/v3/decrypt"
|
"go.mozilla.org/sops/v3/decrypt"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
|
"github.com/joho/godotenv"
|
||||||
)
|
)
|
||||||
|
|
||||||
type secret struct {
|
type secret struct {
|
||||||
|
@ -73,8 +74,23 @@ const (
|
||||||
Yaml FormatType = "yaml"
|
Yaml FormatType = "yaml"
|
||||||
Json FormatType = "json"
|
Json FormatType = "json"
|
||||||
Binary FormatType = "binary"
|
Binary FormatType = "binary"
|
||||||
|
Dotenv FormatType = "dotenv"
|
||||||
|
Ini FormatType = "ini"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func IsValidFormat(format string) bool {
|
||||||
|
switch format {
|
||||||
|
case string(Yaml),
|
||||||
|
string(Json),
|
||||||
|
string(Binary),
|
||||||
|
string(Dotenv),
|
||||||
|
string(Ini):
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (f *FormatType) UnmarshalJSON(b []byte) error {
|
func (f *FormatType) UnmarshalJSON(b []byte) error {
|
||||||
var s string
|
var s string
|
||||||
if err := json.Unmarshal(b, &s); err != nil {
|
if err := json.Unmarshal(b, &s); err != nil {
|
||||||
|
@ -84,7 +100,7 @@ func (f *FormatType) UnmarshalJSON(b []byte) error {
|
||||||
switch t {
|
switch t {
|
||||||
case "":
|
case "":
|
||||||
*f = Yaml
|
*f = Yaml
|
||||||
case Yaml, Json, Binary:
|
case Yaml, Json, Binary, Dotenv, Ini:
|
||||||
*f = t
|
*f = t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,23 +286,26 @@ func decryptSecret(s *secret, sourceFiles map[string]plainData) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to decrypt '%s': %w", s.SopsFile, err)
|
return fmt.Errorf("Failed to decrypt '%s': %w", s.SopsFile, err)
|
||||||
}
|
}
|
||||||
if s.Format == Binary {
|
|
||||||
|
switch s.Format {
|
||||||
|
case Binary, Dotenv, Ini:
|
||||||
sourceFile.binary = plain
|
sourceFile.binary = plain
|
||||||
} else {
|
case Yaml:
|
||||||
if s.Format == Yaml {
|
if err := yaml.Unmarshal(plain, &sourceFile.data); err != nil {
|
||||||
if err := yaml.Unmarshal(plain, &sourceFile.data); err != nil {
|
return fmt.Errorf("Cannot parse yaml of '%s': %w", s.SopsFile, err)
|
||||||
return fmt.Errorf("Cannot parse yaml of '%s': %w", s.SopsFile, err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := json.Unmarshal(plain, &sourceFile.data); err != nil {
|
|
||||||
return fmt.Errorf("Cannot parse json of '%s': %w", s.SopsFile, err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
case Json:
|
||||||
|
if err := json.Unmarshal(plain, &sourceFile.data); err != nil {
|
||||||
|
return fmt.Errorf("Cannot parse json of '%s': %w", s.SopsFile, err)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("Secret of type %s in %s is not supported", s.Format, s.SopsFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.Format == Binary {
|
switch s.Format {
|
||||||
|
case Binary, Dotenv, Ini:
|
||||||
s.value = sourceFile.binary
|
s.value = sourceFile.binary
|
||||||
} else {
|
case Yaml, Json:
|
||||||
strVal, err := recurseSecretKey(sourceFile.data, s.Key)
|
strVal, err := recurseSecretKey(sourceFile.data, s.Key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("secret %s in %s is not valid: %w", s.Name, s.SopsFile, err)
|
return fmt.Errorf("secret %s in %s is not valid: %w", s.Name, s.SopsFile, err)
|
||||||
|
@ -410,19 +429,30 @@ func (app *appContext) loadSopsFile(s *secret) (*secretFile, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var keys map[string]interface{}
|
var keys map[string]interface{}
|
||||||
if s.Format == Binary {
|
|
||||||
|
switch s.Format {
|
||||||
|
case Binary:
|
||||||
if err := json.Unmarshal(cipherText, &keys); err != nil {
|
if err := json.Unmarshal(cipherText, &keys); err != nil {
|
||||||
return nil, fmt.Errorf("Cannot parse json of '%s': %w", s.SopsFile, err)
|
return nil, fmt.Errorf("Cannot parse json of '%s': %w", s.SopsFile, err)
|
||||||
}
|
}
|
||||||
return &secretFile{cipherText: cipherText, firstSecret: s}, nil
|
return &secretFile{cipherText: cipherText, firstSecret: s}, nil
|
||||||
}
|
case Yaml:
|
||||||
|
|
||||||
if s.Format == Yaml {
|
|
||||||
if err := yaml.Unmarshal(cipherText, &keys); err != nil {
|
if err := yaml.Unmarshal(cipherText, &keys); err != nil {
|
||||||
return nil, fmt.Errorf("Cannot parse yaml of '%s': %w", s.SopsFile, err)
|
return nil, fmt.Errorf("Cannot parse yaml of '%s': %w", s.SopsFile, err)
|
||||||
}
|
}
|
||||||
} else if err := json.Unmarshal(cipherText, &keys); err != nil {
|
case Dotenv:
|
||||||
return nil, fmt.Errorf("Cannot parse json of '%s': %w", s.SopsFile, err)
|
env, err := godotenv.Unmarshal(string(cipherText))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Cannot parse dotenv of '%s': %w", s.SopsFile, err)
|
||||||
|
}
|
||||||
|
keys = map[string]interface{}{}
|
||||||
|
for k, v := range env {
|
||||||
|
keys[k] = v
|
||||||
|
}
|
||||||
|
case Json:
|
||||||
|
if err := json.Unmarshal(cipherText, &keys); err != nil {
|
||||||
|
return nil, fmt.Errorf("Cannot parse json of '%s': %w", s.SopsFile, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &secretFile{
|
return &secretFile{
|
||||||
|
@ -439,7 +469,7 @@ func (app *appContext) validateSopsFile(s *secret, file *secretFile) error {
|
||||||
s.Name, s.SopsFile, s.Format,
|
s.Name, s.SopsFile, s.Format,
|
||||||
file.firstSecret.Format, file.firstSecret.Name)
|
file.firstSecret.Format, file.firstSecret.Name)
|
||||||
}
|
}
|
||||||
if app.checkMode != Manifest && s.Format != Binary {
|
if app.checkMode != Manifest && (!(s.Format == Binary || s.Format == Dotenv || s.Format == Ini )) {
|
||||||
_, err := recurseSecretKey(file.keys, s.Key)
|
_, err := recurseSecretKey(file.keys, s.Key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("secret %s in %s is not valid: %w", s.Name, s.SopsFile, err)
|
return fmt.Errorf("secret %s in %s is not valid: %w", s.Name, s.SopsFile, err)
|
||||||
|
@ -485,7 +515,7 @@ func (app *appContext) validateSecret(secret *secret) error {
|
||||||
secret.Format = "yaml"
|
secret.Format = "yaml"
|
||||||
}
|
}
|
||||||
|
|
||||||
if secret.Format != "yaml" && secret.Format != "json" && secret.Format != "binary" {
|
if !IsValidFormat(string(secret.Format)) {
|
||||||
return fmt.Errorf("Unsupported format %s for secret %s", secret.Format, secret.Name)
|
return fmt.Errorf("Unsupported format %s for secret %s", secret.Format, secret.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -110,7 +111,7 @@ func testGPG(t *testing.T) {
|
||||||
ReloadUnits: []string{"affected-reload-service"},
|
ReloadUnits: []string{"affected-reload-service"},
|
||||||
}
|
}
|
||||||
|
|
||||||
var jsonSecret, binarySecret secret
|
var jsonSecret, binarySecret, dotenvSecret, iniSecret secret
|
||||||
// should not create a symlink
|
// should not create a symlink
|
||||||
jsonSecret = yamlSecret
|
jsonSecret = yamlSecret
|
||||||
jsonSecret.Name = "test2"
|
jsonSecret.Name = "test2"
|
||||||
|
@ -127,8 +128,25 @@ func testGPG(t *testing.T) {
|
||||||
binarySecret.SopsFile = path.Join(assets, "secrets.bin")
|
binarySecret.SopsFile = path.Join(assets, "secrets.bin")
|
||||||
binarySecret.Path = path.Join(testdir.secretsPath, "test3")
|
binarySecret.Path = path.Join(testdir.secretsPath, "test3")
|
||||||
|
|
||||||
|
dotenvSecret = yamlSecret
|
||||||
|
dotenvSecret.Name = "test4"
|
||||||
|
dotenvSecret.Owner = "root"
|
||||||
|
dotenvSecret.Group = "root"
|
||||||
|
dotenvSecret.Format = "dotenv"
|
||||||
|
dotenvSecret.SopsFile = path.Join(assets, "secrets.env")
|
||||||
|
dotenvSecret.Path = path.Join(testdir.secretsPath, "test4")
|
||||||
|
|
||||||
|
iniSecret = yamlSecret
|
||||||
|
iniSecret.Name = "test5"
|
||||||
|
iniSecret.Owner = "root"
|
||||||
|
iniSecret.Group = "root"
|
||||||
|
iniSecret.Format = "ini"
|
||||||
|
iniSecret.SopsFile = path.Join(assets, "secrets.ini")
|
||||||
|
iniSecret.Path = path.Join(testdir.secretsPath, "test5")
|
||||||
|
|
||||||
|
|
||||||
manifest := manifest{
|
manifest := manifest{
|
||||||
Secrets: []secret{yamlSecret, jsonSecret, binarySecret},
|
Secrets: []secret{yamlSecret, jsonSecret, binarySecret, dotenvSecret, iniSecret},
|
||||||
SecretsMountPoint: testdir.secretsPath,
|
SecretsMountPoint: testdir.secretsPath,
|
||||||
SymlinkPath: testdir.symlinkPath,
|
SymlinkPath: testdir.symlinkPath,
|
||||||
GnupgHome: gpgHome,
|
GnupgHome: gpgHome,
|
||||||
|
@ -321,3 +339,17 @@ func TestValidateManifest(t *testing.T) {
|
||||||
ok(t, installSecrets([]string{"sops-install-secrets", "-check-mode=manifest", path}))
|
ok(t, installSecrets([]string{"sops-install-secrets", "-check-mode=manifest", path}))
|
||||||
ok(t, installSecrets([]string{"sops-install-secrets", "-check-mode=sopsfile", path}))
|
ok(t, installSecrets([]string{"sops-install-secrets", "-check-mode=sopsfile", path}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestIsValidFormat(t *testing.T) {
|
||||||
|
generateCase := func(input string, mustBe bool) {
|
||||||
|
result := IsValidFormat(input)
|
||||||
|
if result != mustBe {
|
||||||
|
t.Errorf("input %s must return %v but returned %v", input, mustBe, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, format := range []string{string(Yaml), string(Json), string(Binary), string(Dotenv)} {
|
||||||
|
generateCase(format, true)
|
||||||
|
generateCase(strings.Title(format), false)
|
||||||
|
generateCase(strings.ToUpper(format), false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
15
pkgs/sops-install-secrets/test-assets/secrets.env
Normal file
15
pkgs/sops-install-secrets/test-assets/secrets.env
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ENC[AES256_GCM,data:TfdJsqJ9p/3tnClpyPQbfvbmYUmjryiSGA==,iv:YXiEYlAdzco3hZ7T+X6dOUb17ByZeyGXlimfD+yaTa0=,tag:67TgtX4Zn6Ft7ww+J5AjTQ==,type:comment]
|
||||||
|
hello=ENC[AES256_GCM,data:Y8BU+riqE9DInBi1iALx8iNG2Z5iAGFOgNhZg/wFtwqcLXFBTP1vouIewDdWfQ==,iv:dPftz1CxGYi81lSUbg0iRhXpFP4blmyRn5qKPnWUF0k=,tag:VzKiYYhNDSJsZ8q1A+EpMg==,type:str]
|
||||||
|
example_key=ENC[AES256_GCM,data:C8+6JSN7MbRpizcF9A==,iv:ODsEI46iuAT81Q/8r83tCfKpU9x2zJ3rzV4FhJmj+Xs=,tag:Mc4l4Kvzg0VvmzcvU3w1tA==,type:str]
|
||||||
|
example_multiline=ENC[AES256_GCM,data:M6QISEHpqpyUVC0=,iv:uow+EKFgOuSv84hCqtox4r8nvVRFC11xG7or7iMdNkg=,tag:AC5aoWP1LgALV1/YPZMplg==,type:str]
|
||||||
|
never_gonna=ENC[AES256_GCM,data:PrjZGWkgmmrT6Ms=,iv:ZaSHmgdKf0EUFehl+z4Xj2ouiw6T17xhqwsCGP8fdgQ=,tag:5YRX6obm4G9RUQIqECMf5A==,type:str]
|
||||||
|
sops_pgp__list_1__map_enc=-----BEGIN PGP MESSAGE-----\n\nhQGMA3ulPRkZxd/UAQwAtsL/Gdj32m81J5k3q4Vz+ev5B+zF/53hB+3FuJtUlWez\naNxQs6RxGC1JtlluMX0syzz8yoAspnfbKxPylMf/A81dhqnMVpZyktBtavb6K07E\nl2gOjgkq6SfOzqeVQdxjvi4VoZ86+KueQCPlALQWxVMGlCMjhGwd7HLWFbJt6O2G\nNCNa7HBABYUDQf8lND+7YtBKX4KyxJviQGpdlOvx7Xkw7hafYMxA79Jp7uLso5d4\n+IKhidKqR2ZWhNgcgKCesRS4hIAzqMmBiSNYHuM23Pe+jPzOvbADWPJEj/rV3qvo\ni8ehS/cGB4rRnLdfW6frQpC+cVKhxuZTJmoBXFazIB15fz32iuDZ8FBiJJXYrVJT\nIphOJt9NcnpoK4M5mQvKB6otZfZRfQYjbJ4Q7n5u4AD/TvMByRgG2B7XkaEXRbrx\ngNuSpaLtwTYpqzq/AynR3h4K5D0izhoviIrhyv6Y5EskDim5ulqbcW+lPAISkohE\nhqWx76/SyA0ehj9jqTrW0lgBXQDsnqgS5C0LZFLsPyDvEG0q03/eoUKSbYyVU5kh\nwy8yHcJmsDqgU+f5TjyNdXpOc+xfbGqfWmeWjSPDyx7lEZxXcBXqAVCpJo3QL9JX\n+VDTtrwqJ2Ho\n=nthm\n-----END PGP MESSAGE-----\n
|
||||||
|
sops_mac=ENC[AES256_GCM,data:onO42qeKMXa4Jl6Vt06zaoET+6WKzSGd8ak/LyXq1xABAtbVpt25tBdVKlfCD/lzDkOylexQfOBdRAqRPZ1ex3Q4ILZcjmPBkFsMbAs/7L1EzSXskWgeh7NuDXtNKsTmGp9BVcICh3O1+kECQSRZGcefUhV+HYMjRxh2Xxm8r5E=,iv:C8m3Ffbe12LSv0bsPmsxfhOjXNoJ0+75Q+sCYpqchJA=,tag:pahCk/P1Ig71xgvxVIZyPg==,type:str]
|
||||||
|
sops_version=3.7.3
|
||||||
|
sops_unencrypted_suffix=_unencrypted
|
||||||
|
sops_pgp__list_1__map_fp=2504791468B153B8A3963CC97BA53D1919C5DFD4
|
||||||
|
sops_pgp__list_0__map_fp=7FB89715AADA920D65D25E63F9BA9DEBD03F57C0
|
||||||
|
sops_pgp__list_0__map_created_at=2023-01-17T12:32:47Z
|
||||||
|
sops_lastmodified=2023-01-17T12:33:06Z
|
||||||
|
sops_pgp__list_0__map_enc=-----BEGIN PGP MESSAGE-----\n\nhQEMA/m6nevQP1fAAQf/cGIbOAVh6dy2xDztWHmOPfhBsEFJRzih25cVNbVqo6EC\nxAY31eEZpibKDhAxNKSQbUXjwpCY2Bw5iyRznvjy2kuwDxjyqbGVsNKJuLvlqZ/f\n8Pfs5xvI0A3nc4PRwm3U8n0UhrII9zMl9VB2THw7CP5ZnJy0mjEygxI7ml7k63Go\nSAukABD6QW1sIluP2Q7A6Cy7nXf8QcXI0O5cMJbQos8OOEIiRWoD33i5Uf9KNh9c\nwhNNvpfh1cMZ5StlaWlNXW3ZH/pOJWCLnmmQ/DgcR+LiMA01moykE9ewtwkXfwED\nRzNYZhFD2NKn9Y+smUQ2XaXwMeBw7wlCY7568wK3wtJeAVAEJHbFS7CXI1x3zRRL\nkEy3AI85MobyjGdWIi0+v1K3TqbABUNyg9O+6XpSkn3zPtneY1w4EgJqEvMMJoxN\nxGahyyxYhT2VDO7gPrlkITE6mo0jwyfCGjZERpQFiw==\n=X2R+\n-----END PGP MESSAGE-----\n
|
||||||
|
sops_pgp__list_1__map_created_at=2023-01-17T12:32:47Z
|
18
pkgs/sops-install-secrets/test-assets/secrets.ini
Normal file
18
pkgs/sops-install-secrets/test-assets/secrets.ini
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
; ENC[AES256_GCM,data:Q3CfbslIuolYPK9yZIgPdgnmYSuwBG9E,iv:d51C4MXhAa0pOMSTDtSzNyxgRd3IkHPW4+tCyTpHxbY=,tag:LzXKrOg72Td9PAhb4UdKMA==,type:comment]
|
||||||
|
[Welcome!]
|
||||||
|
hello = ENC[AES256_GCM,data:NjaXxfkFK25JFGiPNJBDX0NfsZN70ltV4OCLR52PCFU880dw5NU8O2yvQQ2kUQ==,iv:eSYE2Pwu8J7Wdq0t80Dx1OKfq8B5nCkX8FqFnVqOSSM=,tag:gqf3oczxJM4V9/L48/PFAg==,type:str]
|
||||||
|
example_key = ENC[AES256_GCM,data:aYmYszjMLR+eEW0ZZw==,iv:K6qCGzVu56gjUWXtEad7QYRh/6OpytdkoyzOjp/1lMw=,tag:HqMQ0ckO7uVyOiZbOtbxkA==,type:str]
|
||||||
|
never_gonna = ENC[AES256_GCM,data:Q4xcNZE1R6tiXh4=,iv:7BgJXn3avu+7Mc9FRPqW0VtRiK7nUpA6cHfhzEWV+TA=,tag:/4YjMUA2la3/E71lgNcqIw==,type:str]
|
||||||
|
|
||||||
|
[sops]
|
||||||
|
pgp__list_0__map_created_at = 2023-01-17T13:06:50Z
|
||||||
|
mac = ENC[AES256_GCM,data:jCYesEFva/ptI23sBcOHxMhGsyF9E5w3tdsEONKtJj+7KbkG76f7e3AEQyjpURNuv6QVHwCwABJRJObl4VHXOoI/yb/AKSGSYPTM/nRYWXG8vrX1HHwFYWmQfZtm6G8bc8bhWjHh3nt6cV63VhfNB+5L3oaTdkrKfZhNrLI5ztI=,iv:VSbopP0E+ocMbsaM6jwkiG4K/H6N5JUv+3kKtU2jI6Q=,tag:TTjz2JifWiNSs8sComn5Ew==,type:str]
|
||||||
|
version = 3.7.3
|
||||||
|
pgp__list_0__map_enc = -----BEGIN PGP MESSAGE-----\n\nhQEMA/m6nevQP1fAAQf/S9ggtaO8grsEYyicoQnrM0279m0+t5d6VP2bQoelneOw\nPEZOdKnwWw939rdUz5pNMWIdEL2mHE1Yu99lmal9TmMXf0kDoryDgHtChM6UyA/u\n0mqbEoASaebwAikWJcidhoWbTLr0eqpohVr+Y0wT3MjkX4sUZzPRapIT2rv/jecm\nq357aSy0kzmKnIal+h9Bqbl3tkiMvhdILRsN1Xlp7xa3H681D1EeRfw3BbR8h4Ui\ng9m9kBVRVmyLl46C4a1etcQgvU5jFUloDIaVV3XGErdEz8bL7B5jPuH5xJCAmVOM\nrouo1n6xJGxEq1lUoWTf/wfnsCCJzpPktsikeprj+9JeAT5DsZdnHr3nmgNYEgLp\neUTTB4aoKHsjehHV+aTpJSKPtzkAkA4mEregUes4T20WOYgurg2lf9a1TYQ+W5ve\ngrI2jdYYxVkWRJvuZRW3umKKQZhx96AP7RczbWL5BA==\n=WuNZ\n-----END PGP MESSAGE-----\n
|
||||||
|
lastmodified = 2023-01-17T13:07:01Z
|
||||||
|
unencrypted_suffix = _unencrypted
|
||||||
|
pgp__list_1__map_created_at = 2023-01-17T13:06:50Z
|
||||||
|
pgp__list_1__map_enc = -----BEGIN PGP MESSAGE-----\n\nhQGMA3ulPRkZxd/UAQv9FFWTbfSQoC6OVhfIEk5+6t35rAAaJAEGyYPLDqRu0xQk\nd80jcsCmvFo8NqKQfBsC6GTsvbnAOuErIYcltKDya0mULDgskbCDQmrwF6AL0Bp9\noVnJ60tuMc72yGYgKTu7yll2DUJuas/qltvI/aA7SMFltltIqnPv7byZfH3BAJIY\nVpnNO1a9M1S7YrS8GtuLSdXfUWqpzoE2bVhsJCfQy4yxkyyMsEnObb6xTTSD2iio\nZXU50fR8JqXma1Z2XuVUmWLS7mp03iqIzwrBCIVuhfSYmy3gF36rToJ5EFgEhP6f\nB8S4xZyWN9Pp6r3keaKK4cYybKrk9rDUb1JcKiP0K/lGsX52M+IR0x0peTVp0ciq\nfYKOd9leEI8nsBpeMuvQnKhE+XHWiQBghmUCeK35O9oYJGKLrsKVXfMke7LUE5Zm\nQQ1CjvvVovAnuX/8/1+NscixBgXZXZgTqoRE84Qta+ohRZqmNGIv2VeEZx/jQxXG\nhiA5G+ylnlTZPGck8V5D0lgB++OQoiZVryFH1aVr1AHO0j2lCa3ckftLKkQ5vQIi\n1JHbPHZ1MHBut761L/RSnBmTVr3B3XW54NH78LeWS0y7z+8mXjWy7Cjl4cyst1b0\n/byCrk2EqPQP\n=LZBU\n-----END PGP MESSAGE-----\n
|
||||||
|
pgp__list_1__map_fp = 2504791468B153B8A3963CC97BA53D1919C5DFD4
|
||||||
|
pgp__list_0__map_fp = 7FB89715AADA920D65D25E63F9BA9DEBD03F57C0
|
||||||
|
|
Loading…
Reference in a new issue