Skip to content

Commit

Permalink
Merge pull request #4 from argyle-engineering/krm-exec-change
Browse files Browse the repository at this point in the history
Major refactoring into KRM framework
  • Loading branch information
Nathan S. Martins authored Jan 13, 2023
2 parents 3b6e88b + b3891b2 commit c928ab0
Show file tree
Hide file tree
Showing 13 changed files with 1,641 additions and 227 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.idea/
67 changes: 45 additions & 22 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
@@ -1,30 +1,53 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
before:
hooks:
# You may remove this if you don't use go modules.
- go mod tidy
# you may remove this if you don't need go generate
- go generate ./...
project_name: argyle-kops
env:
- GO111MODULE=on
builds:
- env:
- id: ksops-darwin-amd64
binary: ksops
env:
- CGO_ENABLED=0
main: ./cmd/ksops/main.go
goos:
- darwin
goarch:
- amd64

- id: ksops-darwin-arm64
binary: ksops
env:
- CGO_ENABLED=0
main: ./cmd/ksops/main.go
goos:
- linux
- darwin
goarch:
- arm64


- id: ksops-linux
binary: ksops
env:
- CGO_ENABLED=0
main: ./cmd/ksops/main.go
goos:
- linux
goarch:
- amd64

archives:
- replacements:
darwin: Darwin
- format: tar.gz
name_template: "{{ .Binary }}-v{{ .Version }}-{{ .ShortCommit }}-{{ .Os }}-{{ .Arch }}"
replacements:
amd64: x64
arm64: ARM64
darwin: macOS
linux: Linux
386: i386
amd64: x86_64
allow_different_binary_count: true

sboms:
- artifacts: binary

checksum:
name_template: 'checksums.txt'
name_template: "{{ .ProjectName }}_checksums.txt"

snapshot:
name_template: "{{ incpatch .Version }}-next"
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
name_template: SNAPSHOT-{{.ShortCommit}}
45 changes: 23 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,13 @@
# KSOPS

*Inspired by: https://github.com/viaduct-ai/kustomize-sops*
A Flexible Kustomize KRM based Plugin for SOPS Encrypted Resources.

A Flexible Kustomize Plugin for SOPS Encrypted Resources.

The main difference in this *fork* is the ability to fail silently to allow this plugin to be used in a CI or places
where you don't want to allow for decryption.
This is a completely new KRM based plugin with no affiliation with the [existing Go-based ksops plugin](https://github.com/viaduct-ai/kustomize-sops).

## Installation
Download the binary and add it to your path.

Build and install binary to the following dir:

`$XDG_CONFIG_HOME/kustomize/plugin/argyle.com/v1/ksops/`

## Usage

Run kustomize with plugins enabled flag:

`kustomize build --enable-alpha-plugins <dir>`


## Manifest example

## Fail silently (in case you want the generator to just skip files that it fails to decrypt)
To allow it to fail silently just add the following to your generator:

```yaml
Expand All @@ -34,10 +20,25 @@ files:
- ./secret.enc.yaml
```
## Generate Dummy Secret
## Dummy Secrets
In order to generate a dummy secrets, we need set `KSOPS_GENERATE_DUMMY_SECRETS` environment variable to `true`.
e.g `KSOPS_GENERATE_DUMMY_SECRETS=TRUE kustomize build --enable-alpha-plugins <dir>`_

There is a case where our machine does not have an access to the decryptor key (i.e. our CICD), but we still want ksops to keep producing a secret with a placeholder 'secret' value in it.

With `fail-silently` set to `true`, ksops will outputing an `failed decrypting file` error message with 0 (zero) exit code.
## Example usage:
If you want to test ksops without having to do a bunch of setup, you can use the example files and pgp key provided with the repository:

Install gpg and sops and kustomize using brew (or figure it out if you're on Linux)
```shell
brew install sops gnugpg kustomize
```

then:

```shell
gpg --import example/sops_functional_tests_key.asc
kustomize build --enable-alpha-plugins --enable-exec example/
```

In order to generate a dummy secret without error message above, we need set `KSOPS_GENERATE_DUMMY_SECRETS` environment variable to `TRUE`. e.g `KSOPS_GENERATE_DUMMY_SECRETS=TRUE kustomize build --enable-alpha-plugins <dir>`
This last step will decrypt example.yaml using the test private key.
102 changes: 102 additions & 0 deletions cmd/ksops/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package main

import (
"fmt"
"github.com/argyle-engineering/ksops/pkg/dummy"
"github.com/argyle-engineering/ksops/pkg/schema"
"go.mozilla.org/sops/v3/cmd/sops/formats"
"go.mozilla.org/sops/v3/decrypt"
"os"
"sigs.k8s.io/kustomize/kyaml/fn/framework"
"sigs.k8s.io/kustomize/kyaml/fn/framework/command"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/yaml"
"strconv"
)

func main() {

ke := os.Getenv("KSOPS_GENERATE_DUMMY_SECRETS")
if len(ke) == 0 { // env not set
ke = "false"
}

ksopsGenerateDummySecrets, err := strconv.ParseBool(ke)
if err != nil {
_, _ = fmt.Fprintf(os.Stderr, "error converting string to boolean, please use either false or true : %q\n", err)
os.Exit(1)
}

fn := func(items []*yaml.RNode) ([]*yaml.RNode, error) {
var filteredItems []*yaml.RNode
for i := range items {
item := items[i]
if item.GetKind() == "KSOPSGenerator" && item.GetApiVersion() == "argyle.com/v1" {

// Get the spec RNode
rawSpec := item.Field("spec")
if rawSpec == nil {
return nil, fmt.Errorf("no spec found in KSOPSGenerator")
}

// Get the spec yaml & unmarshal it
var spec schema.Spec
err = yaml.Unmarshal([]byte(rawSpec.Value.MustString()), &spec)
if err != nil {
return nil, fmt.Errorf("unable to parse KSOPSGenerator spec: %w", err)
}

// Generate secrets here
for _, file := range spec.Files {

var b, secret []byte
//var b []byte

b, err = os.ReadFile(file)

if err != nil {
return nil, fmt.Errorf("error reading %s: %w", file, err)
}

if ksopsGenerateDummySecrets {
secret, err = dummy.GenerateDummySecret(b)
if err != nil {
return nil, fmt.Errorf("failed generating dummy file %s: %w", file, err)
}
} else {
format := formats.FormatForPath(file)
secret, err = decrypt.DataWithFormat(b, format)
if err != nil && !spec.FailSilently {
return nil, fmt.Errorf("failed decrypting file %s: %w -- %s", file, err, string(secret))
}
}

var node *yaml.RNode
node, err = yaml.Parse(string(secret))
if err != nil {
return nil, fmt.Errorf("failed parse secret into yaml file %s: %w", file, err)
}

filteredItems = append(filteredItems, node)
}
} else {
// All other resources get passed along unmodified
filteredItems = append(filteredItems, item)
}
}
return filteredItems, nil
}

api := make(framework.GVKFilterMap)
api["KSOPSGenerator"] = make(map[string]kio.Filter)
api["KSOPSGenerator"]["argyle.com/v1"] = kio.FilterFunc(fn)

p := framework.VersionedAPIProcessor{FilterProvider: api}
cmd := command.Build(&p, command.StandaloneDisabled, false)
command.AddGenerateDockerfile(cmd)
if err = cmd.Execute(); err != nil {
fmt.Printf("\nerror: %s\n", err)
os.Exit(1)
}

}
6 changes: 6 additions & 0 deletions example/.sops.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
creation_rules:
- path_regex: \.yaml$
encrypted_regex: ^(data|stringData)$
pgp: >-
FBC7B9E2A4F9289AC0C1D4843D16CEE4A27381B4,
D7229043384BCC60326C6FB9D8720D957C3D3074
13 changes: 9 additions & 4 deletions example/secret-generator.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
apiVersion: argyle.com/v1
kind: ksops
kind: KSOPSGenerator
metadata:
name: secret-generator
fail-silently: true
files:
- ./secret.enc.yaml
annotations:
config.kubernetes.io/function: |
exec:
path: ksops
fail-silently: false
spec:
files:
- ./secret.enc.yaml
46 changes: 46 additions & 0 deletions example/secret.enc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: ENC[AES256_GCM,data:9JIt/XXkWrg=,iv:VqOTxU7m3GB28ga1/jCD1GfTW2mYcoi+u9iUwPIunto=,tag:sOaJw5HbWXF5w/6JtiQfGw==,type:str]
password: ENC[AES256_GCM,data:I6q+2IV9bR7diY2KWyhTPA==,iv:sLZoqLnn+zTwYXM6eA3wnsfPgSw+isUgLCrEtQy4qtI=,tag:wcYfChpSJqXMtja98ZOvvw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2023-01-13T17:28:19Z"
mac: ENC[AES256_GCM,data:q6S3fR1ngyASuFpjnnf1Pc1rnCo39oUqbgf2iB9ojuIhKPQK6wytiqpxIgWpIDrxHEHkIbKvPuwq5opfXjgSQ1Ib3N8jq6pasaGWawYIVPfUXjXjUVZCEiH4ZSp5HB9qIAfv+PbPlQZmXkEWl8MkEt7kyLr872WDHlM8FOZ9k08=,iv:zIksN0ZbhHFYj/79oqxH1AN5Z82ePBPz4MJjQ35mfHQ=,tag:Y+UFTI7kx/UESV6CUmVq0Q==,type:str]
pgp:
- created_at: "2023-01-13T17:28:17Z"
enc: |
-----BEGIN PGP MESSAGE-----
hQEMAyUpShfNkFB/AQf/bBVLvXhHKeuMKu/5V+zqVuadmaRVeXi8Fb6JJzCf0V0Q
vQhKM1ljI7ojpt40w6VxDftzw1+7OT4bworkf60/7WCKC7yBltRp2oECPjwZ0E+5
SZ5KFgttKHQldyjIO8VTKUVW8FH116WrsovqPp9+Hxp3GYSyNKkdgX97wNr+W+3w
HksJUdujRLASbh3+CrheHBMSnM/ngWNmPVJqaHAoutd+qDAcS7LDARXufagAIAud
U4PAwzC3HhjmeFpfyBm2YCuOh/dxfIum96LTaO2adt5O2aCCAz23Wta68vg7UtvA
wrNZ0rdrJxckoMTgdJ3uUrj4chyFd20yulLkzd1B/NJeAXo1cyOJ8z9+YtrHn7tr
DQRiVkCKFhNps5nKd9aYyUAw38COAc8XYK5sdtEDi2yKT35NAV29DIiEhZYSBU0B
rZOYFEzktFq02RtL7cNmnbkr+u24M3c/wFbB2QSJMQ==
=Ge09
-----END PGP MESSAGE-----
fp: FBC7B9E2A4F9289AC0C1D4843D16CEE4A27381B4
- created_at: "2023-01-13T17:28:17Z"
enc: |
-----BEGIN PGP MESSAGE-----
hIwDXFUltYFwV4MBBACPQQhce+ckYCXqU9+N9N9tL52JWW8T+yn9S2bkvr5JBkPN
LqUxyLjN9UkeHlNA6A2Qgr3LAGRKjUAdRGHbrFjGc1K/0csr936RWtgJlBwVAp+M
3SVVPAxI2QQluzXGP5bnvuagBQqUu/yuvqjzO1gWIavpAJg4Bxnh6PbmBo0Yb9Je
ASZcmkZtlrxb9ogs27xDutQl76qSqblj4Rs8aFczWbGMO3nipQj2FlMsfdzMgoP0
Treg8kmSomAjta0IwUivK8nMZEV9IPzWVt80/hKim9rbDyEbWyeXsPFyfpim+A==
=k9Ht
-----END PGP MESSAGE-----
fp: D7229043384BCC60326C6FB9D8720D957C3D3074
encrypted_regex: ^(data|stringData)$
version: 3.7.3
Loading

0 comments on commit c928ab0

Please sign in to comment.