Fixes to gitrepo reconciler tests
NOTE: This should be amended with the previous commit which has commented out tests. Update reconcileSource() to work with the test case where no secret is set. A minimal auth options is created and used for git checkout. Update TestGitRepositoryReconciler_verifyCommitSignature() to use the new git.Commit type. Update TestGitRepositoryReconciler_reconcileSource_checkoutStrategy to add skipForImplementation for branch commit test case. Signed-off-by: Sunny <darkowlzz@protonmail.com>
This commit is contained in:
parent
31d2e6d65c
commit
b814070bc2
|
@ -284,7 +284,8 @@ func (r *GitRepositoryReconciler) reconcileStorage(ctx context.Context, obj *sou
|
|||
func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context,
|
||||
obj *sourcev1.GitRepository, artifact *sourcev1.Artifact, dir string) (ctrl.Result, error) {
|
||||
// Configure authentication strategy to access the source
|
||||
authOpts := &git.AuthOptions{}
|
||||
var authOpts *git.AuthOptions
|
||||
var err error
|
||||
if obj.Spec.SecretRef != nil {
|
||||
// Attempt to retrieve secret
|
||||
name := types.NamespacedName{
|
||||
|
@ -302,16 +303,18 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context,
|
|||
}
|
||||
|
||||
// Configure strategy with secret
|
||||
var err error
|
||||
authOpts, err = git.AuthOptionsFromSecret(obj.Spec.URL, &secret)
|
||||
if err != nil {
|
||||
conditions.MarkTrue(obj, sourcev1.CheckoutFailedCondition, sourcev1.AuthenticationFailedReason,
|
||||
"Failed to configure auth strategy for Git implementation %q: %s", obj.Spec.GitImplementation, err)
|
||||
r.Eventf(obj, events.EventSeverityError, sourcev1.AuthenticationFailedReason,
|
||||
"Failed to configure auth strategy for Git implementation %q: %s", obj.Spec.GitImplementation, err)
|
||||
// Return error as the contents of the secret may change
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
} else {
|
||||
// Set the minimal auth options for valid transport.
|
||||
authOpts, err = git.AuthOptionsWithoutSecret(obj.Spec.URL)
|
||||
}
|
||||
if err != nil {
|
||||
conditions.MarkTrue(obj, sourcev1.CheckoutFailedCondition, sourcev1.AuthenticationFailedReason,
|
||||
"Failed to configure auth strategy for Git implementation %q: %s", obj.Spec.GitImplementation, err)
|
||||
r.Eventf(obj, events.EventSeverityError, sourcev1.AuthenticationFailedReason,
|
||||
"Failed to configure auth strategy for Git implementation %q: %s", obj.Spec.GitImplementation, err)
|
||||
// Return error as the contents of the secret may change
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
// Configure checkout strategy
|
||||
|
|
|
@ -56,6 +56,86 @@ import (
|
|||
"github.com/fluxcd/source-controller/pkg/git"
|
||||
)
|
||||
|
||||
const (
|
||||
encodedCommitFixture = `tree f0c522d8cc4c90b73e2bc719305a896e7e3c108a
|
||||
parent eb167bc68d0a11530923b1f24b4978535d10b879
|
||||
author Stefan Prodan <stefan.prodan@gmail.com> 1633681364 +0300
|
||||
committer Stefan Prodan <stefan.prodan@gmail.com> 1633681364 +0300
|
||||
|
||||
Update containerd and runc to fix CVEs
|
||||
|
||||
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
|
||||
`
|
||||
malformedEncodedCommitFixture = `parent eb167bc68d0a11530923b1f24b4978535d10b879
|
||||
author Stefan Prodan <stefan.prodan@gmail.com> 1633681364 +0300
|
||||
committer Stefan Prodan <stefan.prodan@gmail.com> 1633681364 +0300
|
||||
|
||||
Update containerd and runc to fix CVEs
|
||||
|
||||
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
|
||||
`
|
||||
signatureCommitFixture = `-----BEGIN PGP SIGNATURE-----
|
||||
|
||||
iHUEABEIAB0WIQQHgExUr4FrLdKzpNYyma6w5AhbrwUCYV//1AAKCRAyma6w5Ahb
|
||||
r7nJAQCQU4zEJu04/Q0ac/UaL6htjhq/wTDNMeUM+aWG/LcBogEAqFUea1oR2BJQ
|
||||
JCJmEtERFh39zNWSazQmxPAFhEE0kbc=
|
||||
=+Wlj
|
||||
-----END PGP SIGNATURE-----`
|
||||
armoredKeyRingFixture = `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mQSuBF9+HgMRDADKT8UBcSzpTi4JXt/ohhVW3x81AGFPrQvs6MYrcnNJfIkPTJD8
|
||||
mY5T7j1fkaN5wcf1wnxM9qTcW8BodkWNGEoEYOtVuigLSxPFqIncxK0PHvdU8ths
|
||||
TEInBrgZv9t6xIVa4QngOEUd2D/aYni7M+75z7ntgj6eU1xLZ60upRFn05862OvJ
|
||||
rZFUvzjsZXMAO3enCu2VhG/2axCY/5uI8PgWjyiKV2TH4LBJgzlb0v6SyI+fYf5K
|
||||
Bg2WzDuLKvQBi9tFSwnUbQoFFlOeiGW8G/bdkoJDWeS1oYgSD3nkmvXvrVESCrbT
|
||||
C05OtQOiDXjSpkLim81vNVPtI2XEug+9fEA+jeJakyGwwB+K8xqV3QILKCoWHKGx
|
||||
yWcMHSR6cP9tdXCk2JHZBm1PLSJ8hIgMH/YwBJLYg90u8lLAs9WtpVBKkLplzzgm
|
||||
B4Z4VxCC+xI1kt+3ZgYvYC+oUXJXrjyAzy+J1f+aWl2+S/79glWgl/xz2VibWMz6
|
||||
nZUE+wLMxOQqyOsBALsoE6z81y/7gfn4R/BziBASi1jq/r/wdboFYowmqd39DACX
|
||||
+i+V0OplP2TN/F5JajzRgkrlq5cwZHinnw+IFwj9RTfOkdGb3YwhBt/h2PP38969
|
||||
ZG+y8muNtaIqih1pXj1fz9HRtsiCABN0j+JYpvV2D2xuLL7P1O0dt5BpJ3KqNCRw
|
||||
mGgO2GLxbwvlulsLidCPxdK/M8g9Eeb/xwA5LVwvjVchHkzHuUT7durn7AT0RWiK
|
||||
BT8iDfeBB9RKienAbWyybEqRaR6/Tv+mghFIalsDiBPbfm4rsNzsq3ohfByqECiy
|
||||
yUvs2O3NDwkoaBDkA3GFyKv8/SVpcuL5OkVxAHNCIMhNzSgotQ3KLcQc0IREfFCa
|
||||
3CsBAC7CsE2bJZ9IA9sbBa3jimVhWUQVudRWiLFeYHUF/hjhqS8IHyFwprjEOLaV
|
||||
EG0kBO6ELypD/bOsmN9XZLPYyI3y9DM6Vo0KMomE+yK/By/ZMxVfex8/TZreUdhP
|
||||
VdCLL95Rc4w9io8qFb2qGtYBij2wm0RWLcM0IhXWAtjI3B17IN+6hmv+JpiZccsM
|
||||
AMNR5/RVdXIl0hzr8LROD0Xe4sTyZ+fm3mvpczoDPQNRrWpmI/9OT58itnVmZ5jM
|
||||
7djV5y/NjBk63mlqYYfkfWto97wkhg0MnTnOhzdtzSiZQRzj+vf+ilLfIlLnuRr1
|
||||
JRV9Skv6xQltcFArx4JyfZCo7JB1ZXcbdFAvIXXS11RTErO0XVrXNm2RenpW/yZA
|
||||
9f+ESQ/uUB6XNuyqVUnJDAFJFLdzx8sO3DXo7dhIlgpFqgQobUl+APpbU5LT95sm
|
||||
89UrV0Lt9vh7k6zQtKOjEUhm+dErmuBnJo8MvchAuXLagHjvb58vYBCUxVxzt1KG
|
||||
2IePwJ/oXIfawNEGad9Lmdo1FYG1u53AKWZmpYOTouu92O50FG2+7dBh0V2vO253
|
||||
aIGFRT1r14B1pkCIun7z7B/JELqOkmwmlRrUnxlADZEcQT3z/S8/4+2P7P6kXO7X
|
||||
/TAX5xBhSqUbKe3DhJSOvf05/RVL5ULc2U2JFGLAtmBOFmnD/u0qoo5UvWliI+v/
|
||||
47QnU3RlZmFuIFByb2RhbiA8c3RlZmFuLnByb2RhbkBnbWFpbC5jb20+iJAEExEI
|
||||
ADgWIQQHgExUr4FrLdKzpNYyma6w5AhbrwUCX34eAwIbAwULCQgHAgYVCgkICwIE
|
||||
FgIDAQIeAQIXgAAKCRAyma6w5Ahbrzu/AP9l2YpRaWZr6wSQuEn0gMN8DRzsWJPx
|
||||
pn0akdY7SRP3ngD9GoKgu41FAItnHAJ2KiHv/fHFyHMndNP3kPGPNW4BF+65Aw0E
|
||||
X34eAxAMAMdYFCHmVA8TZxSTMBDpKYave8RiDCMMMjk26Gl0EPN9f2Y+s5++DhiQ
|
||||
hojNH9VmJkFwZX1xppxe1y1aLa/U6fBAqMP/IdNH8270iv+A9YIxdsWLmpm99BDO
|
||||
3suRfsHcOe9T0x/CwRfDNdGM/enGMhYGTgF4VD58DRDE6WntaBhl4JJa300NG6X0
|
||||
GM4Gh59DKWDnez/Shulj8demlWmakP5imCVoY+omOEc2k3nH02U+foqaGG5WxZZ+
|
||||
GwEPswm2sBxvn8nwjy9gbQwEtzNI7lWYiz36wCj2VS56Udqt+0eNg8WzocUT0XyI
|
||||
moe1qm8YJQ6fxIzaC431DYi/mCDzgx4EV9ww33SXX3Yp2NL6PsdWJWw2QnoqSMpM
|
||||
z5otw2KlMgUHkkXEKs0apmK4Hu2b6KD7/ydoQRFUqR38Gb0IZL1tOL6PnbCRUcig
|
||||
Aypy016W/WMCjBfQ8qxIGTaj5agX2t28hbiURbxZkCkz+Z3OWkO0Rq3Y2hNAYM5s
|
||||
eTn94JIGGwADBgv/dbSZ9LrBvdMwg8pAtdlLtQdjPiT1i9w5NZuQd7OuKhOxYTEB
|
||||
NRDTgy4/DgeNThCeOkMB/UQQPtJ3Et45S2YRtnnuvfxgnlz7xlUn765/grtnRk4t
|
||||
ONjMmb6tZos1FjIJecB/6h4RsvUd2egvtlpD/Z3YKr6MpNjWg4ji7m27e9pcJfP6
|
||||
YpTDrq9GamiHy9FS2F2pZlQxriPpVhjCLVn9tFGBIsXNxxn7SP4so6rJBmyHEAlq
|
||||
iym9wl933e0FIgAw5C1vvprYu2amk+jmVBsJjjCmInW5q/kWAFnFaHBvk+v+/7tX
|
||||
hywWUI7BqseikgUlkgJ6eU7E9z1DEyuS08x/cViDoNh2ntVUhpnluDu48pdqBvvY
|
||||
a4uL/D+KI84THUAJ/vZy+q6G3BEb4hI9pFjgrdJpUKubxyZolmkCFZHjV34uOcTc
|
||||
LQr28P8xW8vQbg5DpIsivxYLqDGXt3OyiItxvLMtw/ypt6PkoeP9A4KDST4StITE
|
||||
1hrOrPtJ/VRmS2o0iHgEGBEIACAWIQQHgExUr4FrLdKzpNYyma6w5AhbrwUCX34e
|
||||
AwIbDAAKCRAyma6w5Ahbr6QWAP9/pl2R6r1nuCnXzewSbnH1OLsXf32hFQAjaQ5o
|
||||
Oomb3gD/TRf/nAdVED+k81GdLzciYdUGtI71/qI47G0nMBluLRE=
|
||||
=/4e+
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
`
|
||||
)
|
||||
|
||||
var (
|
||||
testGitImplementations = []string{sourcev1.GoGitImplementation, sourcev1.LibGit2Implementation}
|
||||
)
|
||||
|
@ -243,7 +323,7 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) {
|
|||
},
|
||||
wantErr: true,
|
||||
assertConditions: []metav1.Condition{
|
||||
*conditions.TrueCondition(sourcev1.CheckoutFailedCondition, sourcev1.GitOperationFailedReason, "Failed to checkout and determine revision: unable to clone '<url>', error: Certificate"),
|
||||
*conditions.TrueCondition(sourcev1.CheckoutFailedCondition, sourcev1.GitOperationFailedReason, "Failed to checkout and determine revision: unable to clone: Certificate"),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -378,8 +458,9 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) {
|
|||
}
|
||||
|
||||
r := &GitRepositoryReconciler{
|
||||
Client: builder.Build(),
|
||||
Storage: testStorage,
|
||||
Client: builder.Build(),
|
||||
EventRecorder: record.NewFakeRecorder(32),
|
||||
Storage: testStorage,
|
||||
}
|
||||
|
||||
for _, i := range testGitImplementations {
|
||||
|
@ -425,11 +506,12 @@ func TestGitRepositoryReconciler_reconcileSource_checkoutStrategy(t *testing.T)
|
|||
tags := []string{"non-semver-tag", "v0.1.0", "0.2.0", "v0.2.1", "v1.0.0-alpha", "v1.1.0", "v2.0.0"}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
reference *sourcev1.GitRepositoryRef
|
||||
want ctrl.Result
|
||||
wantErr bool
|
||||
wantRevision string
|
||||
name string
|
||||
skipForImplementation string
|
||||
reference *sourcev1.GitRepositoryRef
|
||||
want ctrl.Result
|
||||
wantErr bool
|
||||
wantRevision string
|
||||
}{
|
||||
{
|
||||
name: "Nil reference (default branch)",
|
||||
|
@ -453,7 +535,8 @@ func TestGitRepositoryReconciler_reconcileSource_checkoutStrategy(t *testing.T)
|
|||
wantRevision: "v0.1.0/<commit>",
|
||||
},
|
||||
{
|
||||
name: "Branch commit",
|
||||
name: "Branch commit",
|
||||
skipForImplementation: sourcev1.LibGit2Implementation,
|
||||
reference: &sourcev1.GitRepositoryRef{
|
||||
Branch: "staging",
|
||||
Commit: "<commit>",
|
||||
|
@ -461,6 +544,16 @@ func TestGitRepositoryReconciler_reconcileSource_checkoutStrategy(t *testing.T)
|
|||
want: ctrl.Result{RequeueAfter: interval},
|
||||
wantRevision: "staging/<commit>",
|
||||
},
|
||||
{
|
||||
name: "Branch commit",
|
||||
skipForImplementation: sourcev1.GoGitImplementation,
|
||||
reference: &sourcev1.GitRepositoryRef{
|
||||
Branch: "staging",
|
||||
Commit: "<commit>",
|
||||
},
|
||||
want: ctrl.Result{RequeueAfter: interval},
|
||||
wantRevision: "HEAD/<commit>",
|
||||
},
|
||||
{
|
||||
name: "SemVer",
|
||||
reference: &sourcev1.GitRepositoryRef{
|
||||
|
@ -508,8 +601,9 @@ func TestGitRepositoryReconciler_reconcileSource_checkoutStrategy(t *testing.T)
|
|||
}
|
||||
|
||||
r := &GitRepositoryReconciler{
|
||||
Client: fakeclient.NewClientBuilder().WithScheme(runtime.NewScheme()).Build(),
|
||||
Storage: testStorage,
|
||||
Client: fakeclient.NewClientBuilder().WithScheme(runtime.NewScheme()).Build(),
|
||||
EventRecorder: record.NewFakeRecorder(32),
|
||||
Storage: testStorage,
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
@ -534,6 +628,10 @@ func TestGitRepositoryReconciler_reconcileSource_checkoutStrategy(t *testing.T)
|
|||
t.Run(i, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
if tt.skipForImplementation == i {
|
||||
t.Skipf("Skipped for Git implementation %q", i)
|
||||
}
|
||||
|
||||
tmpDir, err := os.MkdirTemp("", "checkout-strategy-")
|
||||
g.Expect(err).NotTo(HaveOccurred())
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
@ -577,7 +675,7 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
|
|||
},
|
||||
afterFunc: func(t *WithT, obj *sourcev1.GitRepository, artifact sourcev1.Artifact) {
|
||||
t.Expect(obj.GetArtifact()).ToNot(BeNil())
|
||||
t.Expect(obj.GetArtifact().Checksum).To(Equal("f9955588f6aeed7be9b1ef15cd2ddac47bb53291"))
|
||||
t.Expect(obj.GetArtifact().Checksum).To(Equal("ef9c34eab0584035ac8b8a4070876954ea46f270250d60648672feef3e943426"))
|
||||
},
|
||||
want: ctrl.Result{RequeueAfter: interval},
|
||||
assertConditions: []metav1.Condition{
|
||||
|
@ -593,7 +691,7 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
|
|||
},
|
||||
afterFunc: func(t *WithT, obj *sourcev1.GitRepository, artifact sourcev1.Artifact) {
|
||||
t.Expect(obj.GetArtifact()).ToNot(BeNil())
|
||||
t.Expect(obj.GetArtifact().Checksum).To(Equal("542a8ad0171118a3249e8c531c598b898defd742"))
|
||||
t.Expect(obj.GetArtifact().Checksum).To(Equal("dc95ae14c19d335b693bbba58ae2a562242b0cf33893baffd1b7605ba578e0d6"))
|
||||
},
|
||||
want: ctrl.Result{RequeueAfter: interval},
|
||||
assertConditions: []metav1.Condition{
|
||||
|
@ -607,7 +705,8 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
|
|||
g := NewWithT(t)
|
||||
|
||||
r := &GitRepositoryReconciler{
|
||||
Storage: testStorage,
|
||||
EventRecorder: record.NewFakeRecorder(32),
|
||||
Storage: testStorage,
|
||||
}
|
||||
|
||||
obj := &sourcev1.GitRepository{
|
||||
|
@ -846,7 +945,8 @@ func TestGitRepositoryReconciler_reconcileDelete(t *testing.T) {
|
|||
g := NewWithT(t)
|
||||
|
||||
r := &GitRepositoryReconciler{
|
||||
Storage: testStorage,
|
||||
EventRecorder: record.NewFakeRecorder(32),
|
||||
Storage: testStorage,
|
||||
}
|
||||
|
||||
obj := &sourcev1.GitRepository{
|
||||
|
@ -870,129 +970,143 @@ func TestGitRepositoryReconciler_reconcileDelete(t *testing.T) {
|
|||
g.Expect(obj.Status.Artifact).To(BeNil())
|
||||
}
|
||||
|
||||
// func TestGitRepositoryReconciler_verifyCommitSignature(t *testing.T) {
|
||||
// tests := []struct {
|
||||
// name string
|
||||
// secret *corev1.Secret
|
||||
// commit git.Commit
|
||||
// beforeFunc func(obj *sourcev1.GitRepository)
|
||||
// want ctrl.Result
|
||||
// wantErr bool
|
||||
// assertConditions []metav1.Condition
|
||||
// }{
|
||||
// {
|
||||
// name: "Valid commit makes SourceVerifiedCondition=True",
|
||||
// secret: &corev1.Secret{
|
||||
// ObjectMeta: metav1.ObjectMeta{
|
||||
// Name: "existing",
|
||||
// },
|
||||
// },
|
||||
// commit: fake.NewCommit(true, "shasum"),
|
||||
// beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||
// obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||
// obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
||||
// Mode: "head",
|
||||
// SecretRef: meta.LocalObjectReference{
|
||||
// Name: "existing",
|
||||
// },
|
||||
// }
|
||||
// },
|
||||
// want: ctrl.Result{RequeueAfter: interval},
|
||||
// assertConditions: []metav1.Condition{
|
||||
// *conditions.TrueCondition(sourcev1.SourceVerifiedCondition, meta.SucceededReason, "Verified signature of commit \"shasum\""),
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "Invalid commit makes SourceVerifiedCondition=False and returns error",
|
||||
// secret: &corev1.Secret{
|
||||
// ObjectMeta: metav1.ObjectMeta{
|
||||
// Name: "existing",
|
||||
// },
|
||||
// },
|
||||
// commit: fake.NewCommit(false, "shasum"),
|
||||
// beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||
// obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||
// obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
||||
// Mode: "head",
|
||||
// SecretRef: meta.LocalObjectReference{
|
||||
// Name: "existing",
|
||||
// },
|
||||
// }
|
||||
// },
|
||||
// wantErr: true,
|
||||
// assertConditions: []metav1.Condition{
|
||||
// *conditions.FalseCondition(sourcev1.SourceVerifiedCondition, meta.FailedReason, "Signature verification of commit \"shasum\" failed: invalid signature"),
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "Secret get failure makes SourceVerified=False and returns error",
|
||||
// beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||
// obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||
// obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
||||
// Mode: "head",
|
||||
// SecretRef: meta.LocalObjectReference{
|
||||
// Name: "none-existing",
|
||||
// },
|
||||
// }
|
||||
// },
|
||||
// wantErr: true,
|
||||
// assertConditions: []metav1.Condition{
|
||||
// *conditions.FalseCondition(sourcev1.SourceVerifiedCondition, meta.FailedReason, "PGP public keys secret error: secrets \"none-existing\" not found"),
|
||||
// },
|
||||
// },
|
||||
// {
|
||||
// name: "Nil verification in spec deletes SourceVerified condition",
|
||||
// beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||
// obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||
// conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, "Foo", "")
|
||||
// },
|
||||
// want: ctrl.Result{RequeueAfter: interval},
|
||||
// assertConditions: []metav1.Condition{},
|
||||
// },
|
||||
// {
|
||||
// name: "Empty verification mode in spec deletes SourceVerified condition",
|
||||
// beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||
// obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||
// obj.Spec.Verification = &sourcev1.GitRepositoryVerification{}
|
||||
// conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, "Foo", "")
|
||||
// },
|
||||
// want: ctrl.Result{RequeueAfter: interval},
|
||||
// assertConditions: []metav1.Condition{},
|
||||
// },
|
||||
// }
|
||||
func TestGitRepositoryReconciler_verifyCommitSignature(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
secret *corev1.Secret
|
||||
commit git.Commit
|
||||
beforeFunc func(obj *sourcev1.GitRepository)
|
||||
want ctrl.Result
|
||||
wantErr bool
|
||||
assertConditions []metav1.Condition
|
||||
}{
|
||||
{
|
||||
name: "Valid commit makes SourceVerifiedCondition=True",
|
||||
secret: &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "existing",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
"foo": []byte(armoredKeyRingFixture),
|
||||
},
|
||||
},
|
||||
commit: git.Commit{
|
||||
Hash: []byte("shasum"),
|
||||
Encoded: []byte(encodedCommitFixture),
|
||||
Signature: signatureCommitFixture,
|
||||
},
|
||||
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||
obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
||||
Mode: "head",
|
||||
SecretRef: meta.LocalObjectReference{
|
||||
Name: "existing",
|
||||
},
|
||||
}
|
||||
},
|
||||
want: ctrl.Result{RequeueAfter: interval},
|
||||
assertConditions: []metav1.Condition{
|
||||
*conditions.TrueCondition(sourcev1.SourceVerifiedCondition, meta.SucceededReason, "Verified signature of commit \"shasum\""),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Invalid commit makes SourceVerifiedCondition=False and returns error",
|
||||
secret: &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "existing",
|
||||
},
|
||||
},
|
||||
commit: git.Commit{
|
||||
Hash: []byte("shasum"),
|
||||
Encoded: []byte(malformedEncodedCommitFixture),
|
||||
Signature: signatureCommitFixture,
|
||||
},
|
||||
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||
obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
||||
Mode: "head",
|
||||
SecretRef: meta.LocalObjectReference{
|
||||
Name: "existing",
|
||||
},
|
||||
}
|
||||
},
|
||||
wantErr: true,
|
||||
assertConditions: []metav1.Condition{
|
||||
*conditions.FalseCondition(sourcev1.SourceVerifiedCondition, meta.FailedReason, "Signature verification of commit \"shasum\" failed: failed to verify commit with any of the given key rings"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Secret get failure makes SourceVerified=False and returns error",
|
||||
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||
obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
||||
Mode: "head",
|
||||
SecretRef: meta.LocalObjectReference{
|
||||
Name: "none-existing",
|
||||
},
|
||||
}
|
||||
},
|
||||
wantErr: true,
|
||||
assertConditions: []metav1.Condition{
|
||||
*conditions.FalseCondition(sourcev1.SourceVerifiedCondition, meta.FailedReason, "PGP public keys secret error: secrets \"none-existing\" not found"),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Nil verification in spec deletes SourceVerified condition",
|
||||
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||
conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, "Foo", "")
|
||||
},
|
||||
want: ctrl.Result{RequeueAfter: interval},
|
||||
assertConditions: []metav1.Condition{},
|
||||
},
|
||||
{
|
||||
name: "Empty verification mode in spec deletes SourceVerified condition",
|
||||
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||
obj.Spec.Verification = &sourcev1.GitRepositoryVerification{}
|
||||
conditions.MarkTrue(obj, sourcev1.SourceVerifiedCondition, "Foo", "")
|
||||
},
|
||||
want: ctrl.Result{RequeueAfter: interval},
|
||||
assertConditions: []metav1.Condition{},
|
||||
},
|
||||
}
|
||||
|
||||
// for _, tt := range tests {
|
||||
// t.Run(tt.name, func(t *testing.T) {
|
||||
// g := NewWithT(t)
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
g := NewWithT(t)
|
||||
|
||||
// builder := fakeclient.NewClientBuilder().WithScheme(testEnv.GetScheme())
|
||||
// if tt.secret != nil {
|
||||
// builder.WithObjects(tt.secret)
|
||||
// }
|
||||
builder := fakeclient.NewClientBuilder().WithScheme(testEnv.GetScheme())
|
||||
if tt.secret != nil {
|
||||
builder.WithObjects(tt.secret)
|
||||
}
|
||||
|
||||
// r := &GitRepositoryReconciler{
|
||||
// Client: builder.Build(),
|
||||
// }
|
||||
r := &GitRepositoryReconciler{
|
||||
EventRecorder: record.NewFakeRecorder(32),
|
||||
Client: builder.Build(),
|
||||
}
|
||||
|
||||
// obj := &sourcev1.GitRepository{
|
||||
// ObjectMeta: metav1.ObjectMeta{
|
||||
// GenerateName: "verify-commit-",
|
||||
// Generation: 1,
|
||||
// },
|
||||
// Status: sourcev1.GitRepositoryStatus{},
|
||||
// }
|
||||
obj := &sourcev1.GitRepository{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: "verify-commit-",
|
||||
Generation: 1,
|
||||
},
|
||||
Status: sourcev1.GitRepositoryStatus{},
|
||||
}
|
||||
|
||||
// if tt.beforeFunc != nil {
|
||||
// tt.beforeFunc(obj)
|
||||
// }
|
||||
if tt.beforeFunc != nil {
|
||||
tt.beforeFunc(obj)
|
||||
}
|
||||
|
||||
// got, err := r.verifyCommitSignature(logr.NewContext(ctx, log.NullLogger{}), obj, tt.commit)
|
||||
// g.Expect(obj.Status.Conditions).To(conditions.MatchConditions(tt.assertConditions))
|
||||
// g.Expect(err != nil).To(Equal(tt.wantErr))
|
||||
// g.Expect(got).To(Equal(tt.want))
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
dlog := log.NewDelegatingLogSink(log.NullLogSink{})
|
||||
nullLogger := logr.New(dlog)
|
||||
got, err := r.verifyCommitSignature(logr.NewContext(ctx, nullLogger), obj, tt.commit)
|
||||
g.Expect(obj.Status.Conditions).To(conditions.MatchConditions(tt.assertConditions))
|
||||
g.Expect(err != nil).To(Equal(tt.wantErr))
|
||||
g.Expect(got).To(Equal(tt.want))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// helpers
|
||||
|
||||
|
|
|
@ -129,3 +129,24 @@ func AuthOptionsFromSecret(URL string, secret *v1.Secret) (*AuthOptions, error)
|
|||
|
||||
return opts, nil
|
||||
}
|
||||
|
||||
// AuthOptionsWithoutSecret constructs a minimal AuthOptions object from the
|
||||
// given URL and then validates the result. It returns the AuthOptions, or an
|
||||
// error.
|
||||
func AuthOptionsWithoutSecret(URL string) (*AuthOptions, error) {
|
||||
u, err := url.Parse(URL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse URL to determine auth strategy: %w", err)
|
||||
}
|
||||
|
||||
opts := &AuthOptions{
|
||||
Transport: TransportType(u.Scheme),
|
||||
Host: u.Host,
|
||||
}
|
||||
|
||||
if err = opts.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return opts, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue