Move Kustomize patch tests to Go test suite

Signed-off-by: Hidde Beydals <hello@hidde.co>
This commit is contained in:
Hidde Beydals 2021-04-06 11:15:58 +02:00
parent efecc8a793
commit 5a8d5026f6
10 changed files with 378 additions and 316 deletions

View File

@ -79,26 +79,6 @@ jobs:
kubectl -n impersonation wait kustomizations/podinfo --for=condition=ready --timeout=4m
kubectl -n impersonation delete kustomizations/podinfo
until kubectl -n impersonation get deploy/podinfo 2>&1 | grep NotFound ; do sleep 2; done
- name: Run images override tests
run: |
kubectl -n images-test apply -f ./config/testdata/overrides/images.yaml
kubectl -n images-test wait kustomizations/podinfo --for=condition=ready --timeout=1m
ACTUAL_TAG=$(kubectl -n images-test get deployments podinfo -o jsonpath='{.spec.template.spec.containers[0].image}' | cut -f2 -d ":")
if [[ $ACTUAL_TAG != "5.0.0" ]]; then echo "Image tag was not overwritten" && exit 1; fi
- name: Run patches override tests
run: |
kubectl -n patches-test apply -f ./config/testdata/overrides/patches.yaml
kubectl -n patches-test wait kustomizations/podinfo --for=condition=ready --timeout=1m
WANT="xxxx"
RESULT=$(kubectl -n patches-test get deployment podinfo -o jsonpath='{.metadata.labels.yyyy}')
if [ "$RESULT" != "$WANT" ]; then
echo -e "$RESULT\n\ndoes not equal\n\n$WANT" && exit 1
fi
WANT="yyyy"
RESULT=$(kubectl -n patches-test get deployment podinfo -o jsonpath='{.metadata.labels.xxxx}')
if [ "$RESULT" != "$WANT" ]; then
echo -e "$RESULT\n\ndoes not equal\n\$WANT" && exit 1
fi
- name: Logs
run: |
kubectl -n kustomize-system logs deploy/source-controller

View File

@ -1,34 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: images-test
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: podinfo
namespace: images-test
spec:
interval: 5m
url: https://github.com/stefanprodan/podinfo
ref:
branch: master
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
kind: Kustomization
metadata:
name: podinfo
namespace: images-test
spec:
targetNamespace: images-test
interval: 5m
path: "./kustomize"
prune: true
sourceRef:
kind: GitRepository
name: podinfo
validation: client
images:
- name: ghcr.io/stefanprodan/podinfo
newName: ghcr.io/stefanprodan/podinfo
newTag: 5.0.0

View File

@ -1,47 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: patches-test
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: podinfo
namespace: patches-test
spec:
interval: 5m
url: https://github.com/stefanprodan/podinfo
ref:
branch: master
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta1
kind: Kustomization
metadata:
name: podinfo
namespace: patches-test
spec:
targetNamespace: patches-test
interval: 5m
path: "./kustomize"
prune: true
sourceRef:
kind: GitRepository
name: podinfo
validation: client
patchesStrategicMerge:
- kind: Deployment
apiVersion: apps/v1
metadata:
name: podinfo
labels:
xxxx: yyyy
patchesJson6902:
- target:
group: apps
version: v1
kind: Deployment
name: podinfo
patch:
- op: add
path: /metadata/labels/yyyy
value: xxxx

View File

@ -0,0 +1,195 @@
/*
Copyright 2021 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package controllers
import (
"context"
"fmt"
"os"
"time"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/fluxcd/pkg/apis/kustomize"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/testserver"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
)
const timeout = 10 * time.Second
var _ = Describe("KustomizationReconciler", func() {
var (
artifactServer *testserver.ArtifactServer
)
BeforeEach(func() {
var err error
artifactServer, err = testserver.NewTempArtifactServer()
Expect(err).ToNot(HaveOccurred())
artifactServer.Start()
})
AfterEach(func() {
artifactServer.Stop()
os.RemoveAll(artifactServer.Root())
})
Context("Kustomize patches", func() {
var (
namespace *corev1.Namespace
kubeconfig *kustomizev1.KubeConfig
artifactFile string
artifactChecksum string
artifactURL string
kustomization *kustomizev1.Kustomization
)
BeforeEach(func() {
namespace = &corev1.Namespace{}
namespace.Name = "patch-" + randStringRunes(5)
Expect(k8sClient.Create(context.Background(), namespace)).To(Succeed())
kubecfgSecret, err := kubeConfigSecret()
Expect(err).ToNot(HaveOccurred())
kubecfgSecret.Namespace = namespace.Name
Expect(k8sClient.Create(context.Background(), kubecfgSecret)).To(Succeed())
kubeconfig = &kustomizev1.KubeConfig{
SecretRef: meta.LocalObjectReference{
Name: kubecfgSecret.Name,
},
}
artifactFile = "patch-" + randStringRunes(5)
artifactChecksum, err = initArtifact(artifactServer, "testdata/patch", artifactFile)
Expect(err).ToNot(HaveOccurred())
artifactURL, err = artifactServer.URLForFile(artifactFile)
Expect(err).ToNot(HaveOccurred())
gitRepoKey := client.ObjectKey{
Name: fmt.Sprintf("patch-%s", randStringRunes(5)),
Namespace: namespace.Name,
}
gitRepo := readyGitRepository(gitRepoKey, artifactURL, "main/"+artifactChecksum, artifactChecksum)
Expect(k8sClient.Create(context.Background(), gitRepo)).To(Succeed())
Expect(k8sClient.Status().Update(context.Background(), gitRepo)).To(Succeed())
kustomizationKey := types.NamespacedName{
Name: "patch-" + randStringRunes(5),
Namespace: namespace.Name,
}
kustomization = &kustomizev1.Kustomization{
ObjectMeta: metav1.ObjectMeta{
Name: kustomizationKey.Name,
Namespace: kustomizationKey.Namespace,
},
Spec: kustomizev1.KustomizationSpec{
Path: "./",
KubeConfig: kubeconfig,
SourceRef: kustomizev1.CrossNamespaceSourceReference{
Name: gitRepoKey.Name,
Namespace: gitRepoKey.Namespace,
Kind: sourcev1.GitRepositoryKind,
},
TargetNamespace: namespace.Name,
},
}
})
AfterEach(func() {
Expect(k8sClient.Delete(context.Background(), namespace)).To(Succeed())
})
It("patches images", func() {
kustomization.Spec.Images = []kustomize.Image{
{
Name: "podinfo",
NewName: "ghcr.io/stefanprodan/podinfo",
NewTag: "5.2.0",
},
}
Expect(k8sClient.Create(context.TODO(), kustomization)).To(Succeed())
Eventually(func() bool {
var obj kustomizev1.Kustomization
_ = k8sClient.Get(context.Background(), ObjectKey(kustomization), &obj)
return obj.Status.LastAppliedRevision == "main/"+artifactChecksum
}, timeout, time.Second).Should(BeTrue())
var deployment appsv1.Deployment
Expect(k8sClient.Get(context.TODO(), client.ObjectKey{Name: "podinfo", Namespace: namespace.Name}, &deployment)).To(Succeed())
Expect(deployment.Spec.Template.Spec.Containers[0].Image).To(Equal("ghcr.io/stefanprodan/podinfo:5.2.0"))
})
It("strategic merge patches", func() {
kustomization.Spec.PatchesStrategicMerge = []apiextensionsv1.JSON{
{
Raw: []byte(`{"kind":"Deployment","apiVersion":"apps/v1","metadata":{"name":"podinfo","labels":{"xxxx":"yyyy"}}}`),
},
}
Expect(k8sClient.Create(context.TODO(), kustomization)).To(Succeed())
Eventually(func() bool {
var obj kustomizev1.Kustomization
_ = k8sClient.Get(context.Background(), ObjectKey(kustomization), &obj)
return obj.Status.LastAppliedRevision == "main/"+artifactChecksum
}, timeout, time.Second).Should(BeTrue())
var deployment appsv1.Deployment
Expect(k8sClient.Get(context.TODO(), client.ObjectKey{Name: "podinfo", Namespace: namespace.Name}, &deployment)).To(Succeed())
Expect(deployment.ObjectMeta.Labels["xxxx"]).To(Equal("yyyy"))
})
It("JSON6902 patches", func() {
kustomization.Spec.PatchesJSON6902 = []kustomize.JSON6902Patch{
{
Patch: []kustomize.JSON6902{
{Op: "add", Path: "/metadata/labels/yyyy", Value: &apiextensionsv1.JSON{Raw: []byte(`"xxxx"`)}},
{Op: "replace", Path: "/spec/replicas", Value: &apiextensionsv1.JSON{Raw: []byte("2")}},
},
Target: kustomize.Selector{
Group: "apps",
Version: "v1",
Kind: "Deployment",
Name: "podinfo",
},
},
}
Expect(k8sClient.Create(context.TODO(), kustomization)).To(Succeed())
Eventually(func() bool {
var obj kustomizev1.Kustomization
_ = k8sClient.Get(context.Background(), ObjectKey(kustomization), &obj)
return obj.Status.LastAppliedRevision == "main/"+artifactChecksum
}, timeout, time.Second).Should(BeTrue())
var deployment appsv1.Deployment
Expect(k8sClient.Get(context.TODO(), client.ObjectKey{Name: "podinfo", Namespace: namespace.Name}, &deployment)).To(Succeed())
Expect(deployment.ObjectMeta.Labels["yyyy"]).To(Equal("xxxx"))
Expect(*deployment.Spec.Replicas).To(Equal(int32(2)))
})
})
})

View File

@ -1,5 +1,5 @@
/*
Copyright 2021it com The Flux authors
Copyright 2021 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -17,16 +17,10 @@ limitations under the License.
package controllers
import (
"archive/tar"
"compress/gzip"
"context"
"crypto/sha1"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"time"
"github.com/fluxcd/pkg/apis/meta"
@ -37,12 +31,11 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
)
const timeout = 10 * time.Second
var _ = Describe("KustomizationReconciler", func() {
var (
artifactServer *testserver.ArtifactServer
@ -89,37 +82,11 @@ var _ = Describe("KustomizationReconciler", func() {
artifactURL, err = artifactServer.URLForFile(artifactFile)
Expect(err).ToNot(HaveOccurred())
gitRepoKey := types.NamespacedName{
Name: fmt.Sprintf("%s", randStringRunes(5)),
gitRepoKey := client.ObjectKey{
Name: fmt.Sprintf("sops-%s", randStringRunes(5)),
Namespace: namespace.Name,
}
gitRepo := &sourcev1.GitRepository{
ObjectMeta: metav1.ObjectMeta{
Name: gitRepoKey.Name,
Namespace: gitRepoKey.Namespace,
},
Spec: sourcev1.GitRepositorySpec{
URL: "https://github.com/test/repository",
Interval: metav1.Duration{Duration: time.Minute},
},
Status: sourcev1.GitRepositoryStatus{
Conditions: []metav1.Condition{
{
Type: meta.ReadyCondition,
Status: metav1.ConditionTrue,
LastTransitionTime: metav1.Now(),
Reason: sourcev1.GitOperationSucceedReason,
},
},
Artifact: &sourcev1.Artifact{
Path: artifactURL,
URL: artifactURL,
Revision: "main/" + artifactChecksum,
Checksum: artifactChecksum,
LastUpdateTime: metav1.Now(),
},
},
}
gitRepo := readyGitRepository(gitRepoKey, artifactURL, "main/"+artifactChecksum, artifactChecksum)
Expect(k8sClient.Create(context.Background(), gitRepo)).To(Succeed())
Expect(k8sClient.Status().Update(context.Background(), gitRepo)).To(Succeed())
@ -166,11 +133,7 @@ var _ = Describe("KustomizationReconciler", func() {
Name: sopsSecretKey.Name,
},
},
PostBuild: &kustomizev1.PostBuild{
Substitute: map[string]string{
"FIXTURE_NS": namespace.Name,
},
},
TargetNamespace: namespace.Name,
},
}
Expect(k8sClient.Create(context.Background(), kustomization)).To(Succeed())
@ -197,92 +160,3 @@ var _ = Describe("KustomizationReconciler", func() {
})
})
})
func initArtifact(artifactServer *testserver.ArtifactServer, fixture, path string) (string, error) {
if f, err := os.Stat(fixture); os.IsNotExist(err) || !f.IsDir() {
return "", fmt.Errorf("invalid fixture path: %s", fixture)
}
f, err := os.Create(filepath.Join(artifactServer.Root(), path))
if err != nil {
return "", err
}
defer func() {
if err != nil {
os.Remove(f.Name())
}
}()
h := sha1.New()
mw := io.MultiWriter(h, f)
gw := gzip.NewWriter(mw)
tw := tar.NewWriter(gw)
if err = filepath.Walk(fixture, func(p string, fi os.FileInfo, err error) error {
if err != nil {
return err
}
// Ignore anything that is not a file (directories, symlinks)
if !fi.Mode().IsRegular() {
return nil
}
// Ignore dotfiles
if strings.HasPrefix(fi.Name(), ".") {
return nil
}
header, err := tar.FileInfoHeader(fi, p)
if err != nil {
return err
}
// The name needs to be modified to maintain directory structure
// as tar.FileInfoHeader only has access to the base name of the file.
// Ref: https://golang.org/src/archive/tar/common.go?#L626
relFilePath := p
if filepath.IsAbs(fixture) {
relFilePath, err = filepath.Rel(fixture, p)
if err != nil {
return err
}
}
header.Name = relFilePath
if err := tw.WriteHeader(header); err != nil {
return err
}
f, err := os.Open(p)
if err != nil {
f.Close()
return err
}
if _, err := io.Copy(tw, f); err != nil {
f.Close()
return err
}
return f.Close()
}); err != nil {
return "", err
}
if err := tw.Close(); err != nil {
gw.Close()
f.Close()
return "", err
}
if err := gw.Close(); err != nil {
f.Close()
return "", err
}
if err := f.Close(); err != nil {
return "", err
}
if err := os.Chmod(f.Name(), 0644); err != nil {
return "", err
}
return fmt.Sprintf("%x", h.Sum(nil)), nil
}

View File

@ -17,8 +17,15 @@ limitations under the License.
package controllers
import (
"archive/tar"
"compress/gzip"
"context"
"crypto/sha1"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"time"
. "github.com/onsi/ginkgo"
@ -31,11 +38,13 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"sigs.k8s.io/controller-runtime/pkg/client"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
"github.com/fluxcd/pkg/apis/meta"
"github.com/fluxcd/pkg/testserver"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
)
var _ = Describe("KustomizationReconciler", func() {
@ -98,33 +107,7 @@ var _ = Describe("KustomizationReconciler", func() {
Name: fmt.Sprintf("%s", randStringRunes(5)),
Namespace: namespace.Name,
}
repository := &sourcev1.GitRepository{
ObjectMeta: metav1.ObjectMeta{
Name: repositoryName.Name,
Namespace: repositoryName.Namespace,
},
Spec: sourcev1.GitRepositorySpec{
URL: "https://github.com/test/repository",
Interval: metav1.Duration{Duration: reconciliationInterval},
},
Status: sourcev1.GitRepositoryStatus{
Conditions: []metav1.Condition{
{
Type: meta.ReadyCondition,
Status: metav1.ConditionTrue,
LastTransitionTime: metav1.Now(),
Reason: sourcev1.GitOperationSucceedReason,
},
},
URL: url,
Artifact: &sourcev1.Artifact{
Path: url,
URL: url,
Revision: t.expectRevision,
LastUpdateTime: metav1.Now(),
},
},
}
repository := readyGitRepository(repositoryName, url, t.expectRevision, "")
Expect(k8sClient.Create(context.Background(), repository)).Should(Succeed())
Expect(k8sClient.Status().Update(context.Background(), repository)).Should(Succeed())
defer k8sClient.Delete(context.Background(), repository)
@ -303,33 +286,7 @@ spec:
Name: fmt.Sprintf("%s", randStringRunes(5)),
Namespace: namespace.Name,
}
repository := &sourcev1.GitRepository{
ObjectMeta: metav1.ObjectMeta{
Name: repositoryName.Name,
Namespace: repositoryName.Namespace,
},
Spec: sourcev1.GitRepositorySpec{
URL: "https://github.com/test/repository",
Interval: metav1.Duration{Duration: reconciliationInterval},
},
Status: sourcev1.GitRepositoryStatus{
Conditions: []metav1.Condition{
{
Type: meta.ReadyCondition,
Status: metav1.ConditionTrue,
LastTransitionTime: metav1.Now(),
Reason: sourcev1.GitOperationSucceedReason,
},
},
URL: url,
Artifact: &sourcev1.Artifact{
Path: url,
URL: url,
Revision: "v1",
LastUpdateTime: metav1.Now(),
},
},
}
repository := readyGitRepository(repositoryName, url, "v1", "")
Expect(k8sClient.Create(context.Background(), repository)).To(Succeed())
Expect(k8sClient.Status().Update(context.Background(), repository)).To(Succeed())
defer k8sClient.Delete(context.Background(), repository)
@ -435,3 +392,122 @@ func kubeConfigSecret() (*corev1.Secret, error) {
},
}, nil
}
func initArtifact(artifactServer *testserver.ArtifactServer, fixture, path string) (string, error) {
if f, err := os.Stat(fixture); os.IsNotExist(err) || !f.IsDir() {
return "", fmt.Errorf("invalid fixture path: %s", fixture)
}
f, err := os.Create(filepath.Join(artifactServer.Root(), path))
if err != nil {
return "", err
}
defer func() {
if err != nil {
os.Remove(f.Name())
}
}()
h := sha1.New()
mw := io.MultiWriter(h, f)
gw := gzip.NewWriter(mw)
tw := tar.NewWriter(gw)
if err = filepath.Walk(fixture, func(p string, fi os.FileInfo, err error) error {
if err != nil {
return err
}
// Ignore anything that is not a file (directories, symlinks)
if !fi.Mode().IsRegular() {
return nil
}
// Ignore dotfiles
if strings.HasPrefix(fi.Name(), ".") {
return nil
}
header, err := tar.FileInfoHeader(fi, p)
if err != nil {
return err
}
// The name needs to be modified to maintain directory structure
// as tar.FileInfoHeader only has access to the base name of the file.
// Ref: https://golang.org/src/archive/tar/common.go?#L626
relFilePath := p
if filepath.IsAbs(fixture) {
relFilePath, err = filepath.Rel(fixture, p)
if err != nil {
return err
}
}
header.Name = relFilePath
if err := tw.WriteHeader(header); err != nil {
return err
}
f, err := os.Open(p)
if err != nil {
f.Close()
return err
}
if _, err := io.Copy(tw, f); err != nil {
f.Close()
return err
}
return f.Close()
}); err != nil {
return "", err
}
if err := tw.Close(); err != nil {
gw.Close()
f.Close()
return "", err
}
if err := gw.Close(); err != nil {
f.Close()
return "", err
}
if err := f.Close(); err != nil {
return "", err
}
if err := os.Chmod(f.Name(), 0644); err != nil {
return "", err
}
return fmt.Sprintf("%x", h.Sum(nil)), nil
}
func readyGitRepository(objKey client.ObjectKey, artifactURL, artifactRevision, artifactChecksum string) *sourcev1.GitRepository {
return &sourcev1.GitRepository{
ObjectMeta: metav1.ObjectMeta{
Name: objKey.Name,
Namespace: objKey.Namespace,
},
Spec: sourcev1.GitRepositorySpec{
URL: "https://github.com/test/repository",
Interval: metav1.Duration{Duration: time.Minute},
},
Status: sourcev1.GitRepositoryStatus{
Conditions: []metav1.Condition{
{
Type: meta.ReadyCondition,
Status: metav1.ConditionTrue,
LastTransitionTime: metav1.Now(),
Reason: sourcev1.GitOperationSucceedReason,
},
},
Artifact: &sourcev1.Artifact{
Path: artifactURL,
URL: artifactURL,
Revision: artifactRevision,
Checksum: artifactChecksum,
LastUpdateTime: metav1.Now(),
},
},
}
}

View File

@ -0,0 +1,19 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: podinfo
labels:
app: podinfo
spec:
replicas: 1
selector:
matchLabels:
app: podinfo
template:
metadata:
labels:
app: podinfo
spec:
containers:
- name: podinfo
image: podinfo

View File

@ -2,9 +2,8 @@ apiVersion: v1
kind: Secret
metadata:
name: sops-age
namespace: ${FIXTURE_NS}
stringData:
secret: ENC[AES256_GCM,data:7fIpFCqSZxBl82Y/ePD3QJ0m,iv:yMrwMbWwDZ18RjWye82dWn/CXZKeNIufLiqNWQTbxok=,tag:JEcC7MKwxfGBFuk0gdRWNA==,type:str]
secret: ENC[AES256_GCM,data:RwzrBF8wy16SpfbQoeADeKyz,iv:DuJce2Ebx1Y49DaLCOJ74OOkgiv21roxhz/sZqKCSSs=,tag:Gg9XHapZI5q+rvtgeY6nrg==,type:str]
sops:
kms: []
gcp_kms: []
@ -14,14 +13,14 @@ sops:
- recipient: age1l44xcng8dqj32nlv6d930qvvrny05hglzcv9qpc7kxjc6902ma4qufys29
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2Q3llZGdyVEtNWFE4SUxq
OVhjelNuTTh0WWR0TGo4dmp4VU1SdkVSblQwCmJkUVlLUllvaWl3S01nTEJQRllw
YTVNcWZpSDJOOTNNaUFYckZhQTJ5cVkKLS0tIFZRREM2NWZrRjZiN3pVdnFoeTdo
cm16SUxUY2dEclV4My9mUFVsWlplRGMKf5d+VZr7Q5cvddhvEPW4pOBjWVhL8UQX
Pch6nsGp2RMC7V/BaknpLmx8iFCXslajzjI13P3KhT1B6QR4ZtkfUA==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNeGduOFZjRWw2WTFQdWdu
OS83OEZaN1E1aU1zSThhMlNEZzd0aEYvdURFCnE3bmJ5c3J2cDNEbXhselFPVC9v
NFhMRjZjOHZOdEpoYjdiS0ZPd2pvN1kKLS0tIDZUVEFoblpDNWhnaWxYRTBjaktk
bHRXV0o1K2ZDNm5Mem5SdzNBMTNuNFUKylE2cRLqydjj6e4+4Giwn4y8mIPej+CM
Bab3UWiK1da2rFNTOEnoHl6QDAVxNrWdrrIa5k22SzApT88VtJ4xuQ==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2021-04-01T10:19:56Z"
mac: ENC[AES256_GCM,data:GEQbue4aXmnytMlM3QbOJxWBn/u3KfWB1q66yy4UGvAUz4E8yV1PUDqx7LDEwYusxu+30Zu/zCtJrrYkrWVGiZwQBguhhXNZu1WLBsvTjt5f6mz9/EvBP2r3j4npp/5QarKGpnL5g6bWxh1bVMTOau8hf4Qn1VcpBcHmmAMzCyA=,iv:FIqAJKZIi8gKUSDwinG4znNsfz2vdLkJLBIxevYDGio=,tag:aZ+rpcn3U9ypr4bU/jMEZQ==,type:str]
lastmodified: "2021-04-06T09:07:05Z"
mac: ENC[AES256_GCM,data:oaM8qFtEP8dOCd/Tr5yb08uetsnDtZO8o1rCayN53ncQ1HUAdhRBrFdmbYx1YTh1mwQVVN6sGYqFZU1LBMVv5pTqvpwd41biJZEg8NznXQWx0GA2Z6HOrblGhFZKrqky3P5xN+6j63zkJizXWgBMKzRvBnsVKxjZGr/lk1vVVv4=,iv:p4y9Fo3SArkEMuoK2d9sQYgNdc0iw/StFhg/5LnhcXM=,tag:61JGbnEw35tv6WnGj46JOw==,type:str]
pgp: []
encrypted_regex: ^(data|stringData)$
version: 3.7.0

View File

@ -2,36 +2,35 @@ apiVersion: v1
kind: Secret
metadata:
name: sops-pgp
namespace: ${FIXTURE_NS}
stringData:
secret: ENC[AES256_GCM,data:9+6Vzroi515jTjARa+eqHV6D,iv:DtwcBC0x4KXaAesRstWBVaFCQO2cxDKKFidfykUnNRs=,tag:7RBPloFTMTVggwEjb0ZB9Q==,type:str]
secret: ENC[AES256_GCM,data:rZEmadbj49GoQLlK85hKKAsc,iv:FX4Dfbd173bZQdUgEVRo4q29m/Gz9ob07QHFuiCAufA=,tag:VM6tzAVdGjsythy2Mr5tvw==,type:str]
sops:
kms: []
gcp_kms: []
azure_kv: []
hc_vault: []
age: []
lastmodified: "2021-04-01T10:20:06Z"
mac: ENC[AES256_GCM,data:vxSUzUF1gaYx941Av1KCGkhLrEPNY2GBd8cgke34g/75yaAUZCDF50txTh4t1VlgLvyj0TL459if0J/7cLHOF8a7zoCtYWg3fSTIg8y+1K+94myDpuzRMiXWbsdZdXNtBIJXICUdD5oIg9tBEcYqctwm08wgVQdlTCAjrY00/oo=,iv:cf5SpdXfLD05uQ0bwMBYK5TWXgwLubPbhe9HMBL+Uss=,tag:mY7cdDXmctw5I9FGPj+QKA==,type:str]
lastmodified: "2021-04-06T09:07:19Z"
mac: ENC[AES256_GCM,data:iBg8FY39VSykcWZ/asv86P3VNZkscQdINNOy3UtI5m4OWDpUkyDuq66w7ELiiEXJ3D+b7JKJrsSrYtT7Tn7t+NZGxJcLQFEczozvWgKd2hCikxnMEepCJ3tRcoz7JaItommi1HvA08syGfLA5f6eOxsHQWzmjVdYaVpQ4VGRibk=,iv:VI+Fb7dXV4442IMKZSHOb0GJ/2nNgK9AUTblOZ49Oco=,tag:gJjFguJeE7irKZW7yZi0jw==,type:str]
pgp:
- created_at: "2021-04-01T10:20:06Z"
- created_at: "2021-04-06T09:07:19Z"
enc: |
-----BEGIN PGP MESSAGE-----
hQIMA90SOJihaAjLAQ//WJRMyMrS810ZxeltKQVbxhkAy/0VeHZlj1lqGJGJVAqL
9PtRnClWNbdU3s3Rkkxh4NTwYk7t/CN9Md7WJ+Kr+e5EzbR045BUAZoJ8EvznykU
f6vDejxlb7ltEr4X1WjN2RDK2q/KrVN9GFB0hg8Wq+g6LS0qgq+Eyu98EJo3wczJ
zYnJ19wf/fyIi1dhEgSq76mUkoxUTSoxEvpg8XkPoMuMpI5PpszhfCK64GUZCOji
TYqbSeD0gSnPvpINbKgQo+SuSMKh63uqgqZ7BEhzx8TK6pE7qzW/B6ttri9WcyU8
s/2rxwzJRYXgTp2rJ0qyRDvlBSsTV1YzNnFaM+kfO9Vn30JxY4/IXJFCOGefwqrD
V1Q0CG8n3yWTktiN2eydfXaXNlKJB0x4fu8P6BIe7y3nVyGXIb9i63Mj1+ebsA+8
7zYl9tEn+96CmtaaoSejTJ8a4vkt2JVcURKFbDufTh3oRN70iGmu8ik0EU0IKuz0
ANrq14JVH11MTnm2uhpqrC8nr3dein2dYG3bVkbxqccB7/3u07D8760dC6yFdqmU
OeztFtcbz/GuUOxckX/I4EFgnX/8l21YLvVF9yE/CAFzIfLunp63dRhRIbfn7Qkl
V0pb1DdUjCdczuy1xreYsMf3Vv44cVjNdpkqANg+pBaPbzqh3WYskLA6bvSrlhjS
XAHNfqolTH6NJXPXLHz82rd5erZXHFWUG5roD2YrKloKfV93dDQ+4UqqohHS1l3C
5db1+wVCmE6yrA5A5jrgIqKk8kkNAmz6yBL/yRO3IR2cAC0SXjDdKxCN9MYj
=Qt5P
hQIMA90SOJihaAjLAQ/+LnZo9UHmJ2Llcpq6m5gjo5hbCx6aYTbrvJOFCWeu2oyC
71XsuTUzBp7TK8SkGrxlJmUodezACQ3rCsKY/r2GI4t9HkVRSuhnc/YQMunm3iG1
bsgfdV/KBm0Go7dFXy2R1Pt3PuVnuM9MZ59U4SdqYGZDI7vzy2gfH127qa3oIOoF
2OFfwhUy8nZIVCJ47ExIdrc7Qdk94tbLfwmBAKHFN4Ab0YXasKCpH9O+9/vQ+JJU
7xy61Nv4dqtEDYU9QTh2ZuT6ZaWikTqCcIv/W7lW1RsT8n7YiRZv9POobKDh5KbP
PyfqvJsLcJB8LHN2kZfwr6Iemuce19kRi+7JL9zMGRJSsq0thJ0ly3JBi48pU27w
jbFnmxlIwfb0EsLBp9lsxw7GoUbooSC/rfI5NVeQ+4lFA4gQn2oz7i4zTYesnwil
lrgMxz49SSluAYsGjrJHc+ABmlDz83K42KtWlNjwaIbDgHMl4EbYUe4pxcynEZ6D
0csDIsIA15MP0THfTL1F1vkhvdPHNuUlVjFqgWaJAP2CC5KH8IeTCUN72FySEYAB
BJH+VQoRnS942M8VQAfUQyBsfZKtQhyCkU7KEimUjQzy75JWgy8YMX1mviXk52qB
kVHQIjNEuBta58pmNyhxc+6+bz+ABGp+mR9QemUQjmXghH3VjOwnZVj6KMMX4J3S
XgEubPmw6u4nYqb9bLDVyE2uXXA4TVgFDuZxJrbZOn9zF2aQOOGfZX2Gx5xgK+pV
srM1wyJqdP+QL/fWO9ZI38+tyr1T5zOBPpJ/JTrkSJoVeRWpwuI6BUCZhH66nfU=
=+1cf
-----END PGP MESSAGE-----
fp: 35C1A64CD7FC0AB6EB66756B2445463C3234ECE1
encrypted_regex: ^(data|stringData)$

1
go.mod
View File

@ -30,6 +30,7 @@ require (
google.golang.org/grpc v1.27.1
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
k8s.io/api v0.20.2
k8s.io/apiextensions-apiserver v0.20.2
k8s.io/apimachinery v0.20.2
k8s.io/cli-runtime v0.20.2 // indirect
k8s.io/client-go v0.20.2