Move Kustomize patch tests to Go test suite
Signed-off-by: Hidde Beydals <hello@hidde.co>
This commit is contained in:
parent
efecc8a793
commit
5a8d5026f6
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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)))
|
||||
})
|
||||
})
|
||||
})
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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(),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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)$
|
||||
|
|
Loading…
Reference in New Issue