1
0
mirror of synced 2026-03-01 19:26:55 +00:00

Compare commits

..

9 Commits

Author SHA1 Message Date
Stefan Prodan
a0520de7aa Merge pull request #2397 from fluxcd/ssa-v0.13.0
Fix bootstrap CRD wait race condition
2022-02-07 14:59:05 +02:00
Stefan Prodan
4602b72778 Fix bootstrap CRD wait race condition
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2022-02-07 14:28:56 +02:00
Stefan Prodan
e69a6ed91a Merge pull request #2398 from fluxcd/update-components
Update toolkit components
2022-02-07 14:28:20 +02:00
Stefan Prodan
9d6a037935 Update dependencies
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
2022-02-07 14:09:23 +02:00
fluxcdbot
41df03f600 Update toolkit components
- kustomize-controller to v0.20.1
  https://github.com/fluxcd/kustomize-controller/blob/v0.20.1/CHANGELOG.md
- source-controller to v0.21.2
  https://github.com/fluxcd/source-controller/blob/v0.21.2/CHANGELOG.md

Signed-off-by: GitHub <noreply@github.com>
2022-02-07 11:45:14 +00:00
Stefan Prodan
ca92464ef6 Merge pull request #2392 from souleb/issue-2387
Mask dockerconfigjson secret types and support StringData secrets
2022-02-07 11:18:11 +02:00
Soule BA
2e9fd33ce5 Mask dockerconfigjson secret types and support StringData secrets
If implemented, flux diff kustomization will managed correctly sops
managed dockerconfigjson secrets.
Sops encrypted secret with stringData maps are supported too.

Signed-off-by: Soule BA <soule@weave.works>
2022-02-07 09:45:38 +01:00
Stefan Prodan
cf3f729f98 Merge pull request #2389 from souleb/fix-deleted-mess-diff
Fix wrong deletion message on flux diff
2022-02-07 10:09:51 +02:00
Soule BA
8b444283e6 Fix wrong deletion message on flux diff
If implemented, when an error happens when dry-running an object, we
return early. This match pkg ssa implementation

Signed-off-by: Soule BA <soule@weave.works>
2022-02-07 00:06:33 +01:00
27 changed files with 310 additions and 54 deletions

View File

@@ -79,6 +79,18 @@ func TestDiffKustomization(t *testing.T) {
objectFile: "./testdata/diff-kustomization/value-sops-secret.yaml",
assert: assertGoldenFile("./testdata/diff-kustomization/diff-with-drifted-value-sops-secret.golden"),
},
{
name: "diff with a sops dockerconfigjson secret object",
args: "diff kustomization podinfo --path ./testdata/build-kustomization/podinfo",
objectFile: "./testdata/diff-kustomization/dockerconfigjson-sops-secret.yaml",
assert: assertGoldenFile("./testdata/diff-kustomization/diff-with-dockerconfigjson-sops-secret.golden"),
},
{
name: "diff with a sops stringdata secret object",
args: "diff kustomization podinfo --path ./testdata/build-kustomization/podinfo",
objectFile: "./testdata/diff-kustomization/stringdata-sops-secret.yaml",
assert: assertGoldenFile("./testdata/diff-kustomization/diff-with-stringdata-sops-secret.golden"),
},
}
tmpl := map[string]string{

View File

@@ -153,12 +153,18 @@ func NewRootFlags() rootFlags {
func main() {
log.SetFlags(0)
if err := rootCmd.Execute(); err != nil {
logger.Failuref("%v", err)
if err, ok := err.(*RequestError); ok {
if err.StatusCode == 1 {
logger.Warningf("%v", err)
} else {
logger.Failuref("%v", err)
}
os.Exit(err.StatusCode)
}
logger.Failuref("%v", err)
os.Exit(1)
}
}

View File

@@ -123,6 +123,31 @@ spec:
type: ClusterIP
---
apiVersion: v1
data:
.dockerconfigjson: eyJtYXNrIjoiKipTT1BTKioifQ==
kind: Secret
metadata:
labels:
kustomize.toolkit.fluxcd.io/name: podinfo
kustomize.toolkit.fluxcd.io/namespace: {{ .fluxns }}
name: docker-secret
namespace: default
type: kubernetes.io/dockerconfigjson
---
apiVersion: v1
kind: Secret
metadata:
labels:
kustomize.toolkit.fluxcd.io/name: podinfo
kustomize.toolkit.fluxcd.io/namespace: {{ .fluxns }}
name: secret-basic-auth-stringdata
namespace: default
stringData:
password: KipTT1BTKio=
username: KipTT1BTKio=
type: kubernetes.io/basic-auth
---
apiVersion: v1
data:
token: KipTT1BTKio=
kind: Secret

View File

@@ -0,0 +1,27 @@
apiVersion: v1
data:
.dockerconfigjson: ENC[AES256_GCM,data:KHCFH3hNnc+PMfWLFEPjebf3W4z4WXbGFAANRZyZC+07z7wlrTALJM6rn8YslW4tMAWCoAYxblC5WRCszTy0h9rw0U/RGOv5H0qCgnNg/FILFUqhwo9pNfrUH+MEP4M9qxxbLKZwObpHUE7DUsKx1JYAxsI=,iv:q48lqUbUQD+0cbYcjNMZMJLRdGHi78ZmDhNAT2th9tg=,tag:QRI2SZZXQrAcdql3R5AH2g==,type:str]
kind: Secret
metadata:
name: docker-secret
type: kubernetes.io/dockerconfigjson
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age10la2ge0wtvx3qr7datqf7rs4yngxszdal927fs9rukamr8u2pshsvtz7ce
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3eU1CTEJhVXZ4eEVYYkVV
OU90TEcrR2pYckttN0pBanJoSUZWSW1RQXlRCkUydFJ3V1NZUTBuVFF0aC9GUEcw
bUdhNjJWTkoyL1FUVi9Dc1dxUDBkM0UKLS0tIE1sQXkwcWdGaEFuY0RHQTVXM0J6
dWpJcThEbW15V3dXYXpPZklBdW1Hd1kKoIAdmGNPrEctV8h1w8KuvQ5S+BGmgqN9
MgpNmUhJjWhgcQpb5BRYpQesBOgU5TBGK7j58A6DMDKlSiYZsdQchQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-02-03T16:03:17Z"
mac: ENC[AES256_GCM,data:AHdYSawajwgAFwlmDN1IPNmT9vWaYKzyVIra2d6sPcjTbZ8/p+VRSRpVm4XZFFsaNnW5AUJaouwXnKYDTmJDXKlr/rQcu9kXqsssQgdzcXaA6l5uJlgsnml8ba7J3OK+iEKMax23mwQEx2EUskCd9ENOwFDkunP02sxqDNOz20k=,iv:8F5OamHt3fAVorf6p+SoIrWoqkcATSGWVoM0EK87S4M=,tag:E1mxXnc7wWkEX5BxhpLtng==,type:str]
pgp: []
encrypted_regex: ^(data|stringData)$
version: 3.7.1

View File

@@ -4,6 +4,8 @@ resources:
- ./deployment.yaml
- ./hpa.yaml
- ./service.yaml
- ./dockerconfigjson-sops-secret.yaml
- ./stringdata-secret.yaml
secretGenerator:
- files:
- token=token.encrypted

View File

@@ -0,0 +1,28 @@
apiVersion: v1
kind: Secret
metadata:
name: secret-basic-auth-stringdata
type: kubernetes.io/basic-auth
stringData:
username: ENC[AES256_GCM,data:uKiQR48=,iv:jh2lgyAVu7igJAgoJsnOGhjxFyvUAa9lvT21u3hhqpU=,tag:zXM2JEpk3ZEH7WfkcWXXkw==,type:str]
password: ENC[AES256_GCM,data:PyhZmNhy929JGQ==,iv:PBqPaJmSw21+kn4gIlg5VdjLNZyf613z5RUTCesBoVw=,tag:Hjc7DsuUrtsz7PYPdNkL3g==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age:
- recipient: age10la2ge0wtvx3qr7datqf7rs4yngxszdal927fs9rukamr8u2pshsvtz7ce
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBJd0xxbDZhYjVoZzY4YWhK
d2NvMVgrSGRVUGhHRGg3R1FpVURnbmh1TDBzCjcwby85M3JaK09QVk0yZFNMb2NL
c2NQZW5hS1FhYlBHU0VoUzBVYzZYUUUKLS0tIEdaNEw2Y0VjVHpZc3pyYUtLVmJk
NmN3K2VLU0NiZ1d0VHBYbGlCM1lrNmMKeWz3yfFbMNE+ly21oLfc1XnDSPRmnlPP
wIs8lk/qrzVZ45C9GdWnnPeGZZiia46Yop9TxseUS8gCjJ6KCxJCAg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2022-02-06T12:51:07Z"
mac: ENC[AES256_GCM,data:jtdzwj19uxdxvnmXg1HkAkDA6XlKMJOYFy7uLI5t/t11LwGop5Yeo7a4nQEEELehRx9J7B6U6NiySxAxBxWx5uW5vI5c8+069VV6dkiCIefnYSzuoIhQafjlFl1/KvH7VEjIWfHYuXF09v9PEKXkxEHUYDpS3QqQ3ymHRRI08pU=, iv:xX3E7F+AM29Pm8G5oqxRfYu9E7tEBGIaHeCJYgrtFmc=,tag:MJPGusNvu05z939jg8PAwQ==,type:str]
pgp: []
encrypted_regex: ^(data|stringData)$
version: 3.7.1

View File

@@ -1,4 +1,6 @@
► HorizontalPodAutoscaler/default/podinfo created
► Service/default/podinfo created
► Secret/default/docker-secret created
► Secret/default/secret-basic-auth-stringdata created
► Secret/default/podinfo-token-77t89m9b67 created
► Secret/default/db-user-pass-bkbd782d2c created

View File

@@ -0,0 +1,6 @@
► Deployment/default/podinfo created
► HorizontalPodAutoscaler/default/podinfo created
► Service/default/podinfo created
► Secret/default/secret-basic-auth-stringdata created
► Secret/default/podinfo-token-77t89m9b67 created
► Secret/default/db-user-pass-bkbd782d2c created

View File

@@ -1,6 +1,8 @@
► Deployment/default/podinfo created
► HorizontalPodAutoscaler/default/podinfo created
► Service/default/podinfo created
► Secret/default/docker-secret created
► Secret/default/secret-basic-auth-stringdata created
► Secret/default/podinfo-token-77t89m9b67 drifted
data

View File

@@ -1,6 +1,8 @@
► Deployment/default/podinfo created
► HorizontalPodAutoscaler/default/podinfo created
► Service/default/podinfo created
► Secret/default/docker-secret created
► Secret/default/secret-basic-auth-stringdata created
► Secret/default/podinfo-token-77t89m9b67 created
► Secret/default/db-user-pass-bkbd782d2c drifted

View File

@@ -7,5 +7,7 @@ spec.ports.http.port
- 9899
+ 9898
► Secret/default/docker-secret created
► Secret/default/secret-basic-auth-stringdata created
► Secret/default/podinfo-token-77t89m9b67 created
► Secret/default/db-user-pass-bkbd782d2c created

View File

@@ -1,4 +1,6 @@
► Deployment/default/podinfo created
► HorizontalPodAutoscaler/default/podinfo created
► Service/default/podinfo created
► Secret/default/docker-secret created
► Secret/default/secret-basic-auth-stringdata created
► Secret/default/db-user-pass-bkbd782d2c created

View File

@@ -0,0 +1,6 @@
► Deployment/default/podinfo created
► HorizontalPodAutoscaler/default/podinfo created
► Service/default/podinfo created
► Secret/default/docker-secret created
► Secret/default/podinfo-token-77t89m9b67 created
► Secret/default/db-user-pass-bkbd782d2c created

View File

@@ -0,0 +1,11 @@
apiVersion: v1
data:
.dockerconfigjson: eyJtYXNrIjoiKipTT1BTKioifQ==
kind: Secret
metadata:
labels:
kustomize.toolkit.fluxcd.io/name: podinfo
kustomize.toolkit.fluxcd.io/namespace: {{ .fluxns }}
name: docker-secret
namespace: default
type: kubernetes.io/dockerconfigjson

View File

@@ -1,5 +1,7 @@
► Deployment/default/podinfo created
► HorizontalPodAutoscaler/default/podinfo created
► Service/default/podinfo created
► Secret/default/docker-secret created
► Secret/default/secret-basic-auth-stringdata created
► Secret/default/podinfo-token-77t89m9b67 created
► Secret/default/db-user-pass-bkbd782d2c created

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Secret
metadata:
labels:
kustomize.toolkit.fluxcd.io/name: podinfo
kustomize.toolkit.fluxcd.io/namespace: {{ .fluxns }}
name: secret-basic-auth-stringdata
namespace: default
stringData:
password: KipTT1BTKio=
username: KipTT1BTKio=
type: kubernetes.io/basic-auth

View File

@@ -11,6 +11,6 @@ spec:
branch: main
secretRef:
name: flux-system
timeout: 20s
timeout: 1m0s
url: ssh://git@github.com/example/repo

8
go.mod
View File

@@ -10,23 +10,23 @@ require (
github.com/fluxcd/helm-controller/api v0.16.0
github.com/fluxcd/image-automation-controller/api v0.20.0
github.com/fluxcd/image-reflector-controller/api v0.16.0
github.com/fluxcd/kustomize-controller/api v0.20.0
github.com/fluxcd/kustomize-controller/api v0.20.1
github.com/fluxcd/notification-controller/api v0.21.0
github.com/fluxcd/pkg/apis/kustomize v0.3.1 // indirect
github.com/fluxcd/pkg/apis/meta v0.10.2
github.com/fluxcd/pkg/kustomize v0.0.2
github.com/fluxcd/pkg/runtime v0.12.4
github.com/fluxcd/pkg/ssa v0.12.0
github.com/fluxcd/pkg/ssa v0.13.0
github.com/fluxcd/pkg/ssh v0.3.1
github.com/fluxcd/pkg/untar v0.0.5
github.com/fluxcd/pkg/version v0.0.1
github.com/fluxcd/source-controller/api v0.21.1
github.com/fluxcd/source-controller/api v0.21.2
github.com/go-git/go-git/v5 v5.4.2
github.com/gonvenience/bunt v1.3.2
github.com/gonvenience/ytbx v1.4.2
github.com/google/go-cmp v0.5.6
github.com/google/go-containerregistry v0.2.0
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-multierror v1.1.1
github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
github.com/homeport/dyff v1.4.6
github.com/lucasb-eyer/go-colorful v1.2.0

12
go.sum
View File

@@ -230,8 +230,8 @@ github.com/fluxcd/image-automation-controller/api v0.20.0 h1:Z+lxqif0KwccsuNOBZq
github.com/fluxcd/image-automation-controller/api v0.20.0/go.mod h1:XhLYccGUbmJvTTpJ1jAFKZHr2e1GNXy0T85ZBO50mik=
github.com/fluxcd/image-reflector-controller/api v0.16.0 h1:1O1YdoK7LsJgWLyvfZTSbvQcUQCBcgJ573HA0arlQQY=
github.com/fluxcd/image-reflector-controller/api v0.16.0/go.mod h1:OIe3mSXc3OwQiNbiQ9vNXWYtNif31hc7WAbZWlFUUnc=
github.com/fluxcd/kustomize-controller/api v0.20.0 h1:Vw+2qCxeHMv0y1mfiBgVrMfcfFevBMrRfLEdfPTrb40=
github.com/fluxcd/kustomize-controller/api v0.20.0/go.mod h1:5MdpzJVx8+KiDIRv37zLme992BAOCgE0v1n+NOgs1lo=
github.com/fluxcd/kustomize-controller/api v0.20.1 h1:BMOUdKCb6bZ6kepcxU8vz9VcDbl4q6SH9j/mRPl2O1A=
github.com/fluxcd/kustomize-controller/api v0.20.1/go.mod h1:5MdpzJVx8+KiDIRv37zLme992BAOCgE0v1n+NOgs1lo=
github.com/fluxcd/notification-controller/api v0.21.0 h1:D5B3TH5YtSww0SyvW1Ru5xWsh0MgHQanC/a1t3CvXq0=
github.com/fluxcd/notification-controller/api v0.21.0/go.mod h1:gA9/j0kjh7VDuUC2Cubr9twxOdzb/0+ojcE9Lzsc9ug=
github.com/fluxcd/pkg/apis/acl v0.0.3 h1:Lw0ZHdpnO4G7Zy9KjrzwwBmDZQuy4qEjaU/RvA6k1lc=
@@ -245,8 +245,8 @@ github.com/fluxcd/pkg/kustomize v0.0.2/go.mod h1:AFwnf3OqQmpTCuwCARTGpPRMBf0ZFJN
github.com/fluxcd/pkg/runtime v0.12.3/go.mod h1:imJ2xYy/d4PbSinX2IefmZk+iS2c1P5fY0js8mCE4SM=
github.com/fluxcd/pkg/runtime v0.12.4 h1:gA27RG/+adN2/7Qe03PB46Iwmye/MusPCpuS4zQ2fW0=
github.com/fluxcd/pkg/runtime v0.12.4/go.mod h1:gspNvhAqodZgSmK1ZhMtvARBf/NGAlxmaZaIOHkJYsc=
github.com/fluxcd/pkg/ssa v0.12.0 h1:7nF4UigU9Zk/9P/nbzUP3ah8IRC+BpB64O9iu5VnvEo=
github.com/fluxcd/pkg/ssa v0.12.0/go.mod h1:S+qig7BTOxop0c134y8Yv8/iQST4Kt7S2xXiFkP4VMA=
github.com/fluxcd/pkg/ssa v0.13.0 h1:LU4wf7dB9ksYdda0BEWNTBSTd68E5YwWxuPiPLAtw4Y=
github.com/fluxcd/pkg/ssa v0.13.0/go.mod h1:XGVGjUaG152HGN6sSUj+VFK/Th5i5rj2XsXSDdlIMNU=
github.com/fluxcd/pkg/ssh v0.3.1 h1:iQw07bkX2rScactX8WYv+uMDsufFOlg8M3fV2TNs244=
github.com/fluxcd/pkg/ssh v0.3.1/go.mod h1:Sebfv4Um51PvomuYdMvKRncQW5dtKhZ5J5TA+wiHNSQ=
github.com/fluxcd/pkg/untar v0.0.5 h1:UGI3Ch1UIEIaqQvMicmImL1s9npQa64DJ/ozqHKB7gk=
@@ -254,8 +254,8 @@ github.com/fluxcd/pkg/untar v0.0.5/go.mod h1:O6V9+rtl8c1mHBafgqFlJN6zkF1HS5SSYn7
github.com/fluxcd/pkg/version v0.0.1 h1:/8asQoDXSThz3csiwi4Qo8Zb6blAxLXbtxNgeMJ9bCg=
github.com/fluxcd/pkg/version v0.0.1/go.mod h1:WAF4FEEA9xyhngF8TDxg3UPu5fA1qhEYV8Pmi2Il01Q=
github.com/fluxcd/source-controller/api v0.21.0/go.mod h1:Ab2qDmAUz6ZCp8UaHYLYzxyFrC1FQqEqjxiROb/Rdiw=
github.com/fluxcd/source-controller/api v0.21.1 h1:7X39YQHmB1vmIBrHxU+YAqxwtdC9Zh+tdtMKREW3xiQ=
github.com/fluxcd/source-controller/api v0.21.1/go.mod h1:Ab2qDmAUz6ZCp8UaHYLYzxyFrC1FQqEqjxiROb/Rdiw=
github.com/fluxcd/source-controller/api v0.21.2 h1:J0S5NN4V8FPLrkSMXIUoUvj1X/RuTpVJSjIRF414wmc=
github.com/fluxcd/source-controller/api v0.21.2/go.mod h1:Ab2qDmAUz6ZCp8UaHYLYzxyFrC1FQqEqjxiROb/Rdiw=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c=

View File

@@ -20,6 +20,7 @@ import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"sync"
"time"
@@ -40,9 +41,13 @@ import (
)
const (
controllerName = "kustomize-controller"
controllerGroup = "kustomize.toolkit.fluxcd.io"
mask = "**SOPS**"
controllerName = "kustomize-controller"
controllerGroup = "kustomize.toolkit.fluxcd.io"
mask = "**SOPS**"
dockercfgSecretType = "kubernetes.io/dockerconfigjson"
typeField = "type"
dataField = "data"
stringDataField = "stringData"
)
var defaultTimeout = 80 * time.Second
@@ -183,7 +188,7 @@ func (b *Builder) build() (m resmap.ResMap, err error) {
}
// make sure secrets are masked
err = trimSopsData(res)
err = maskSopsData(res)
if err != nil {
return
}
@@ -257,40 +262,131 @@ func (b *Builder) setOwnerLabels(res *resource.Resource) error {
return nil
}
func trimSopsData(res *resource.Resource) error {
func maskSopsData(res *resource.Resource) error {
// sopsMess is the base64 encoded mask
sopsMess := base64.StdEncoding.EncodeToString([]byte(mask))
if res.GetKind() == "Secret" {
// get both data and stringdata maps as a secret can have both
dataMap := res.GetDataMap()
stringDataMap := getStringDataMap(res)
asYaml, err := res.AsYAML()
if err != nil {
return fmt.Errorf("failed to decode secret %s data: %w", res.GetName(), err)
return fmt.Errorf("failed to mask secret %s sops data: %w", res.GetName(), err)
}
//delete any sops data as we don't want to expose it
// delete any sops data as we don't want to expose it
// assume that both data and stringdata are encrypted
if bytes.Contains(asYaml, []byte("sops:")) && bytes.Contains(asYaml, []byte("mac: ENC[")) {
// delete the sops object
res.PipeE(yaml.FieldClearer{Name: "sops"})
for k := range dataMap {
dataMap[k] = sopsMess
secretType, err := res.GetFieldValue(typeField)
if err != nil {
return fmt.Errorf("failed to mask secret %s sops data: %w", res.GetName(), err)
}
} else {
for k, v := range dataMap {
data, err := base64.StdEncoding.DecodeString(v)
if v, ok := secretType.(string); ok && v == dockercfgSecretType {
// if the secret is a json docker config secret, we need to mask the data with a json object
err := maskDockerconfigjsonSopsData(dataMap)
if err != nil {
if _, ok := err.(base64.CorruptInputError); ok {
return fmt.Errorf("failed to decode secret %s data: %w", res.GetName(), err)
}
return fmt.Errorf("failed to mask secret %s sops data: %w", res.GetName(), err)
}
if bytes.Contains(data, []byte("sops")) && bytes.Contains(data, []byte("ENC[")) {
err = maskDockerconfigjsonSopsData(stringDataMap)
if err != nil {
return fmt.Errorf("failed to mask secret %s sops data: %w", res.GetName(), err)
}
} else {
for k := range dataMap {
dataMap[k] = sopsMess
}
for k := range stringDataMap {
stringDataMap[k] = sopsMess
}
}
} else {
err := maskBase64EncryptedSopsData(dataMap, sopsMess)
if err != nil {
return fmt.Errorf("failed to mask secret %s sops data: %w", res.GetName(), err)
}
err = maskSopsDataInStringDataSecret(stringDataMap, sopsMess)
if err != nil {
return fmt.Errorf("failed to mask secret %s sops data: %w", res.GetName(), err)
}
}
// set the data and stringdata maps
res.SetDataMap(dataMap)
if len(stringDataMap) > 0 {
err = res.SetMapField(yaml.NewMapRNode(&stringDataMap), stringDataField)
if err != nil {
return fmt.Errorf("failed to mask secret %s sops data: %w", res.GetName(), err)
}
}
}
return nil
}
func getStringDataMap(rn *resource.Resource) map[string]string {
n, err := rn.Pipe(yaml.Lookup(stringDataField))
if err != nil {
return nil
}
result := map[string]string{}
_ = n.VisitFields(func(node *yaml.MapNode) error {
result[yaml.GetValue(node.Key)] = yaml.GetValue(node.Value)
return nil
})
return result
}
func maskDockerconfigjsonSopsData(dataMap map[string]string) error {
sopsMess := struct {
Mask string `json:"mask"`
}{
Mask: mask,
}
maskJson, err := json.Marshal(sopsMess)
if err != nil {
return err
}
for k := range dataMap {
dataMap[k] = base64.StdEncoding.EncodeToString(maskJson)
}
return nil
}
func maskBase64EncryptedSopsData(dataMap map[string]string, mask string) error {
for k, v := range dataMap {
data, err := base64.StdEncoding.DecodeString(v)
if err != nil {
if _, ok := err.(base64.CorruptInputError); ok {
return err
}
}
if bytes.Contains(data, []byte("sops")) && bytes.Contains(data, []byte("ENC[")) {
dataMap[k] = mask
}
}
return nil
}
func maskSopsDataInStringDataSecret(stringDataMap map[string]string, mask string) error {
for k, v := range stringDataMap {
if bytes.Contains([]byte(v), []byte("sops")) && bytes.Contains([]byte(v), []byte("ENC[")) {
stringDataMap[k] = mask
}
}
return nil

View File

@@ -97,7 +97,7 @@ type: kubernetes.io/basic-auth
name: "secret sops secret",
yamlStr: `apiVersion: v1
data:
.dockercfg: ENC[AES256_GCM,data:KHCFH3hNnc+PMfWLFEPjebf3W4z4WXbGFAANRZyZC+07z7wlrTALJM6rn8YslW4tMAWCoAYxblC5WRCszTy0h9rw0U/RGOv5H0qCgnNg/FILFUqhwo9pNfrUH+MEP4M9qxxbLKZwObpHUE7DUsKx1JYAxsI=,iv:q48lqUbUQD+0cbYcjNMZMJLRdGHi78ZmDhNAT2th9tg=,tag:QRI2SZZXQrAcdql3R5AH2g==,type:str]
.dockerconfigjson: ENC[AES256_GCM,data:KHCFH3hNnc+PMfWLFEPjebf3W4z4WXbGFAANRZyZC+07z7wlrTALJM6rn8YslW4tMAWCoAYxblC5WRCszTy0h9rw0U/RGOv5H0qCgnNg/FILFUqhwo9pNfrUH+MEP4M9qxxbLKZwObpHUE7DUsKx1JYAxsI=,iv:q48lqUbUQD+0cbYcjNMZMJLRdGHi78ZmDhNAT2th9tg=,tag:QRI2SZZXQrAcdql3R5AH2g==,type:str]
kind: Secret
metadata:
name: secret
@@ -125,7 +125,7 @@ sops:
`,
expected: `apiVersion: v1
data:
.dockercfg: KipTT1BTKio=
.dockerconfigjson: eyJtYXNrIjoiKipTT1BTKioifQ==
kind: Secret
metadata:
name: secret
@@ -142,7 +142,7 @@ type: kubernetes.io/dockerconfigjson
}
resource := &resource.Resource{RNode: *r}
err = trimSopsData(resource)
err = maskSopsData(resource)
if err != nil {
t.Fatalf("unable to trim sops data: %v", err)
}

View File

@@ -32,6 +32,7 @@ import (
"github.com/gonvenience/bunt"
"github.com/gonvenience/ytbx"
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/go-multierror"
"github.com/homeport/dyff/pkg/dyff"
"github.com/lucasb-eyer/go-colorful"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -76,6 +77,7 @@ func (b *Builder) Diff() (string, bool, error) {
return "", createdOrDrifted, err
}
var diffErrs error
// create an inventory of objects to be reconciled
newInventory := newInventory()
for _, obj := range objects {
@@ -86,11 +88,8 @@ func (b *Builder) Diff() (string, bool, error) {
}
change, liveObject, mergedObject, err := resourceManager.Diff(ctx, obj, diffOptions)
if err != nil {
if b.kustomization.Spec.Force && ssa.IsImmutableError(err) {
output.WriteString(writeString(fmt.Sprintf("► %s created\n", obj.GetName()), bunt.Green))
} else {
output.WriteString(writeString(fmt.Sprintf("✗ %v\n", err), bunt.Red))
}
// gather errors and continue, as we want to see all the diffs
diffErrs = multierror.Append(diffErrs, err)
continue
}
@@ -124,7 +123,7 @@ func (b *Builder) Diff() (string, bool, error) {
addObjectsToInventory(newInventory, change)
}
if b.kustomization.Spec.Prune {
if b.kustomization.Spec.Prune && diffErrs == nil {
oldStatus := b.kustomization.Status.DeepCopy()
if oldStatus.Inventory != nil {
diffObjects, err := diffInventory(oldStatus.Inventory, newInventory)
@@ -137,7 +136,7 @@ func (b *Builder) Diff() (string, bool, error) {
}
}
return output.String(), createdOrDrifted, nil
return output.String(), createdOrDrifted, diffErrs
}
func writeYamls(liveObject, mergedObject *unstructured.Unstructured) (string, string, string, error) {
@@ -200,17 +199,31 @@ func diff(liveFile, mergedFile string, output io.Writer) error {
}
func diffSopsSecret(obj, liveObject, mergedObject *unstructured.Unstructured, change *ssa.ChangeSetEntry) {
data := obj.Object["data"]
for _, v := range data.(map[string]interface{}) {
// get both data and stringdata maps
data := obj.Object[dataField]
stringData := obj.Object[stringDataField]
if m, ok := data.(map[string]interface{}); ok && m != nil {
applySopsDiff(m, liveObject, mergedObject, change)
}
if m, ok := stringData.(map[string]interface{}); ok && m != nil {
applySopsDiff(m, liveObject, mergedObject, change)
}
}
func applySopsDiff(data map[string]interface{}, liveObject, mergedObject *unstructured.Unstructured, change *ssa.ChangeSetEntry) {
for _, v := range data {
v, err := base64.StdEncoding.DecodeString(v.(string))
if err != nil {
fmt.Println(err)
}
if bytes.Contains(v, []byte(mask)) {
if liveObject != nil && mergedObject != nil {
change.Action = string(ssa.UnchangedAction)
dataLive := liveObject.Object["data"].(map[string]interface{})
dataMerged := mergedObject.Object["data"].(map[string]interface{})
dataLive := liveObject.Object[dataField].(map[string]interface{})
dataMerged := mergedObject.Object[dataField].(map[string]interface{})
if cmp.Diff(keys(dataLive), keys(dataMerged)) != "" {
change.Action = string(ssa.ConfiguredAction)
}

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.20.0/kustomize-controller.crds.yaml
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.20.0/kustomize-controller.deployment.yaml
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.20.1/kustomize-controller.crds.yaml
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.20.1/kustomize-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/source-controller/releases/download/v0.21.1/source-controller.crds.yaml
- https://github.com/fluxcd/source-controller/releases/download/v0.21.1/source-controller.deployment.yaml
- https://github.com/fluxcd/source-controller/releases/download/v0.21.2/source-controller.crds.yaml
- https://github.com/fluxcd/source-controller/releases/download/v0.21.2/source-controller.deployment.yaml
- account.yaml
patchesJson6902:
- target:

View File

@@ -1,8 +1,8 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- https://github.com/fluxcd/source-controller/releases/download/v0.21.1/source-controller.crds.yaml
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.20.0/kustomize-controller.crds.yaml
- https://github.com/fluxcd/source-controller/releases/download/v0.21.2/source-controller.crds.yaml
- https://github.com/fluxcd/kustomize-controller/releases/download/v0.20.1/kustomize-controller.crds.yaml
- https://github.com/fluxcd/helm-controller/releases/download/v0.16.0/helm-controller.crds.yaml
- https://github.com/fluxcd/notification-controller/releases/download/v0.21.0/notification-controller.crds.yaml
- https://github.com/fluxcd/image-reflector-controller/releases/download/v0.16.0/image-reflector-controller.crds.yaml

View File

@@ -7,11 +7,11 @@ require (
github.com/fluxcd/helm-controller/api v0.16.0
github.com/fluxcd/image-automation-controller/api v0.20.0
github.com/fluxcd/image-reflector-controller/api v0.16.0
github.com/fluxcd/kustomize-controller/api v0.20.0
github.com/fluxcd/kustomize-controller/api v0.20.1
github.com/fluxcd/notification-controller/api v0.21.0
github.com/fluxcd/pkg/apis/meta v0.10.2
github.com/fluxcd/pkg/runtime v0.12.4
github.com/fluxcd/source-controller/api v0.21.1
github.com/fluxcd/source-controller/api v0.21.2
github.com/hashicorp/terraform-exec v0.14.0
github.com/libgit2/git2go/v31 v31.6.1
github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5

View File

@@ -204,8 +204,8 @@ github.com/fluxcd/image-automation-controller/api v0.20.0 h1:Z+lxqif0KwccsuNOBZq
github.com/fluxcd/image-automation-controller/api v0.20.0/go.mod h1:XhLYccGUbmJvTTpJ1jAFKZHr2e1GNXy0T85ZBO50mik=
github.com/fluxcd/image-reflector-controller/api v0.16.0 h1:1O1YdoK7LsJgWLyvfZTSbvQcUQCBcgJ573HA0arlQQY=
github.com/fluxcd/image-reflector-controller/api v0.16.0/go.mod h1:OIe3mSXc3OwQiNbiQ9vNXWYtNif31hc7WAbZWlFUUnc=
github.com/fluxcd/kustomize-controller/api v0.20.0 h1:Vw+2qCxeHMv0y1mfiBgVrMfcfFevBMrRfLEdfPTrb40=
github.com/fluxcd/kustomize-controller/api v0.20.0/go.mod h1:5MdpzJVx8+KiDIRv37zLme992BAOCgE0v1n+NOgs1lo=
github.com/fluxcd/kustomize-controller/api v0.20.1 h1:BMOUdKCb6bZ6kepcxU8vz9VcDbl4q6SH9j/mRPl2O1A=
github.com/fluxcd/kustomize-controller/api v0.20.1/go.mod h1:5MdpzJVx8+KiDIRv37zLme992BAOCgE0v1n+NOgs1lo=
github.com/fluxcd/notification-controller/api v0.21.0 h1:D5B3TH5YtSww0SyvW1Ru5xWsh0MgHQanC/a1t3CvXq0=
github.com/fluxcd/notification-controller/api v0.21.0/go.mod h1:gA9/j0kjh7VDuUC2Cubr9twxOdzb/0+ojcE9Lzsc9ug=
github.com/fluxcd/pkg/apis/acl v0.0.3 h1:Lw0ZHdpnO4G7Zy9KjrzwwBmDZQuy4qEjaU/RvA6k1lc=
@@ -218,8 +218,8 @@ github.com/fluxcd/pkg/runtime v0.12.3/go.mod h1:imJ2xYy/d4PbSinX2IefmZk+iS2c1P5f
github.com/fluxcd/pkg/runtime v0.12.4 h1:gA27RG/+adN2/7Qe03PB46Iwmye/MusPCpuS4zQ2fW0=
github.com/fluxcd/pkg/runtime v0.12.4/go.mod h1:gspNvhAqodZgSmK1ZhMtvARBf/NGAlxmaZaIOHkJYsc=
github.com/fluxcd/source-controller/api v0.21.0/go.mod h1:Ab2qDmAUz6ZCp8UaHYLYzxyFrC1FQqEqjxiROb/Rdiw=
github.com/fluxcd/source-controller/api v0.21.1 h1:7X39YQHmB1vmIBrHxU+YAqxwtdC9Zh+tdtMKREW3xiQ=
github.com/fluxcd/source-controller/api v0.21.1/go.mod h1:Ab2qDmAUz6ZCp8UaHYLYzxyFrC1FQqEqjxiROb/Rdiw=
github.com/fluxcd/source-controller/api v0.21.2 h1:J0S5NN4V8FPLrkSMXIUoUvj1X/RuTpVJSjIRF414wmc=
github.com/fluxcd/source-controller/api v0.21.2/go.mod h1:Ab2qDmAUz6ZCp8UaHYLYzxyFrC1FQqEqjxiROb/Rdiw=
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c=