gitrepo: add tests for verifying tag signatures
Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com>
This commit is contained in:
parent
59898cd86b
commit
035d514af3
|
|
@ -65,15 +65,20 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
encodedCommitFixture = `tree f0c522d8cc4c90b73e2bc719305a896e7e3c108a
|
encodedCommitFixture = `tree 35f0b28987e60d4b8dec1f707fd07fef5ad84abc
|
||||||
parent eb167bc68d0a11530923b1f24b4978535d10b879
|
parent 8b52742dbc848eb0975e62ae00fbfa4f8108e835
|
||||||
author Stefan Prodan <stefan.prodan@gmail.com> 1633681364 +0300
|
author Sanskar Jaiswal <jaiswalsanskar078@gmail.com> 1691045123 +0530
|
||||||
committer Stefan Prodan <stefan.prodan@gmail.com> 1633681364 +0300
|
committer Sanskar Jaiswal <jaiswalsanskar078@gmail.com> 1691068951 +0530
|
||||||
|
|
||||||
Update containerd and runc to fix CVEs
|
git/e2e: disable CGO while running e2e tests
|
||||||
|
|
||||||
Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
|
Disable CGO for Git e2e tests as it was originially required because of
|
||||||
|
our libgit2 client. Since we no longer maintain a libgit2 client, there
|
||||||
|
is no need to run the tests with CGO enabled.
|
||||||
|
|
||||||
|
Signed-off-by: Sanskar Jaiswal <jaiswalsanskar078@gmail.com>
|
||||||
`
|
`
|
||||||
|
|
||||||
malformedEncodedCommitFixture = `parent eb167bc68d0a11530923b1f24b4978535d10b879
|
malformedEncodedCommitFixture = `parent eb167bc68d0a11530923b1f24b4978535d10b879
|
||||||
author Stefan Prodan <stefan.prodan@gmail.com> 1633681364 +0300
|
author Stefan Prodan <stefan.prodan@gmail.com> 1633681364 +0300
|
||||||
committer Stefan Prodan <stefan.prodan@gmail.com> 1633681364 +0300
|
committer Stefan Prodan <stefan.prodan@gmail.com> 1633681364 +0300
|
||||||
|
|
@ -84,62 +89,81 @@ Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
|
||||||
`
|
`
|
||||||
signatureCommitFixture = `-----BEGIN PGP SIGNATURE-----
|
signatureCommitFixture = `-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
iHUEABEIAB0WIQQHgExUr4FrLdKzpNYyma6w5AhbrwUCYV//1AAKCRAyma6w5Ahb
|
iQIzBAABCAAdFiEEOxEY0f3iSZ5rKQ+vWYLQJ5wif/0FAmTLqnEACgkQWYLQJ5wi
|
||||||
r7nJAQCQU4zEJu04/Q0ac/UaL6htjhq/wTDNMeUM+aWG/LcBogEAqFUea1oR2BJQ
|
f/1mYw/+LRttvfPrfYl7ASUBGYSQuDzjeold8OO1LpmwjrKPpX4ivZbXHh+lJF0F
|
||||||
JCJmEtERFh39zNWSazQmxPAFhEE0kbc=
|
fqudKuJfJzeQCHsMZjnfgvXHd2VvxPh1jX6h3JLuNu7d4g1DtNQsKJtsLx7JW99X
|
||||||
=+Wlj
|
J9Bb1xj0Ghh2PkrWEB9vpw+uZz4IhFrB+DNNLRNBkon3etrS1q57q8dhQFIhLI1y
|
||||||
|
ij3rq3kFHjrNNdokIv2ujyVJtWgy2fK2ELW5v2dznpykOo7hQEKgtOIHPBzGBFT0
|
||||||
|
dUFjB99Qy4Qgjh3vWaY4fZ3u/vhp3swmw91OlDkFeyndWjDSZhzYnb7wY+U6z35C
|
||||||
|
aU4Gzc71CquSd/nTdOEkpuolBVWV5cBkM+Nxi8jtVGBeDDFE49j27a3lQ3+qtT7/
|
||||||
|
q4FCe5Jw3GSOJvaLBLGmYVn9fc49t/28b5tkGtCHs3ATpsJohzELEIiDP90Me7hQ
|
||||||
|
Joks3ML38T4J/zZ4/ObbVMkrCEATYe3r1Ep7+e6VmOG9iTg0JIexexddjHX26Tgu
|
||||||
|
iuVP2GD/8PceqgNW/LPX84Ub32WTKPZJg+NyliDjH5QOvmguK1dRtSb/9eyYcoSF
|
||||||
|
Fkf0HcgG5jOk0OZJv0QcqXd9PhB4oXeuXgGszo9M+fhr3nWvEooAJtIyLtVtt/u2
|
||||||
|
rNNB7xkZ1uWx+52w9RG2gmZh+LaESwd1rNXgUFLNBebNN3jNzsA=
|
||||||
|
=73xf
|
||||||
-----END PGP SIGNATURE-----`
|
-----END PGP SIGNATURE-----`
|
||||||
|
|
||||||
|
encodedTagFixture = `object 11525516bd55152ce68848bb14680aad43f18479
|
||||||
|
type commit
|
||||||
|
tag v0.1.0
|
||||||
|
tagger Sanskar Jaiswal <jaiswalsanskar078@gmail.com> 1691132850 +0530
|
||||||
|
|
||||||
|
v0.1.0
|
||||||
|
`
|
||||||
|
|
||||||
|
malformedEncodedTagFixture = `object 11525516bd55152ce68848bb14680aad43f18479
|
||||||
|
tagger Sanskar Jaiswal <jaiswalsanskar078@gmail.com> 1691132850 +0530
|
||||||
|
|
||||||
|
v0.1.0
|
||||||
|
`
|
||||||
|
|
||||||
|
signatureTagFixture = `-----BEGIN PGP SIGNATURE-----
|
||||||
|
|
||||||
|
iQIzBAABCAAdFiEEOxEY0f3iSZ5rKQ+vWYLQJ5wif/0FAmTMo7IACgkQWYLQJ5wi
|
||||||
|
f/1uUQ/9F70u8LZZQ3+U2vuYQ8fyVp/AV5h5zwxK5UlkR1crB0gSpdaiIxMMQRc8
|
||||||
|
4QQIqCXloSHherUu9SPbDe9Qmr0JL8a57XqThjUSa52IYMDVos9sYwViJit+xGyz
|
||||||
|
HDot2nQ8MAqkDaiuwAnTqOyTPA89U36lGV/X/25mYxAuED+8xFx1OfvjGkX2eMEr
|
||||||
|
peWJ8VEfdFr2OmWwFceh6iF/izIaZGttwCyNy4BIh2W0GvUtQAxzqF4IzUvwfJU/
|
||||||
|
bgARaHKQhWqFhDNImttsqJBweWavEDDmUgNg80c3cUZKqBtAjElToP9gis/SnPH5
|
||||||
|
zaCAH66OzyKIhn6lde7KpOzyqbOyzddTa8SKkAAHyO7onukOktV8W9toeAxlF20q
|
||||||
|
Bw0MZGzAGisF8EK1HVv8UzrW9vAwdJN/yDIHWkjaeHr2FHmeV3a2QxH9PdwbE3tI
|
||||||
|
B21TCVULJuM8oR0ZG62xzg5ba5HiZMiilNMJdrBfjk5xYGk3LQU1gB4FVYa7yTsN
|
||||||
|
YfAokYtUIG187Qb8vPr1P95TzZxKdb7r/PAKEbGPro5D2Rri8OnxO/OaXG/giWS5
|
||||||
|
5gRGmsQjvMsbzE/2PVc9+jshtZM49xL9H3DMjAWtO6MFbOqGqdi4MBa0T4qj6sZz
|
||||||
|
AbSLuRIBpXDES86faDXLRmufc95+iA/fh7W23G6vmd+SjXnCcHc=
|
||||||
|
=o4nf
|
||||||
|
-----END PGP SIGNATURE-----
|
||||||
|
`
|
||||||
|
|
||||||
armoredKeyRingFixture = `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
armoredKeyRingFixture = `-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
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
|
=Tdjz
|
||||||
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-----
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
@ -1523,10 +1547,42 @@ func TestGitRepositoryReconciler_verifySignature(t *testing.T) {
|
||||||
beforeFunc func(obj *sourcev1.GitRepository)
|
beforeFunc func(obj *sourcev1.GitRepository)
|
||||||
want sreconcile.Result
|
want sreconcile.Result
|
||||||
wantErr bool
|
wantErr bool
|
||||||
|
err error
|
||||||
|
wantSourceVerificationMode *sourcev1.GitVerificationMode
|
||||||
assertConditions []metav1.Condition
|
assertConditions []metav1.Condition
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "Valid commit makes SourceVerifiedCondition=True",
|
name: "Valid commit with mode=HEAD 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: sourcev1.ModeGitHEAD,
|
||||||
|
SecretRef: meta.LocalObjectReference{
|
||||||
|
Name: "existing",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
want: sreconcile.ResultSuccess,
|
||||||
|
wantSourceVerificationMode: ptrToVerificationMode(sourcev1.ModeGitHEAD),
|
||||||
|
assertConditions: []metav1.Condition{
|
||||||
|
*conditions.TrueCondition(sourcev1.SourceVerifiedCondition, meta.SucceededReason, "verified signature of\n\t- commit 'shasum' with key '5982D0279C227FFD'"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Valid commit with mode=head makes SourceVerifiedCondition=True",
|
||||||
secret: &corev1.Secret{
|
secret: &corev1.Secret{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "existing",
|
Name: "existing",
|
||||||
|
|
@ -1550,12 +1606,199 @@ func TestGitRepositoryReconciler_verifySignature(t *testing.T) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
want: sreconcile.ResultSuccess,
|
want: sreconcile.ResultSuccess,
|
||||||
|
wantSourceVerificationMode: ptrToVerificationMode(sourcev1.ModeGitHEAD),
|
||||||
assertConditions: []metav1.Condition{
|
assertConditions: []metav1.Condition{
|
||||||
*conditions.TrueCondition(sourcev1.SourceVerifiedCondition, meta.SucceededReason, "verified signature of\n\t- commit 'shasum' with key '3299AEB0E4085BAF'"),
|
*conditions.TrueCondition(sourcev1.SourceVerifiedCondition, meta.SucceededReason, "verified signature of\n\t- commit 'shasum' with key '5982D0279C227FFD'"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Invalid commit sets no SourceVerifiedCondition and returns error",
|
name: "Valid tag with mode=tag makes SourceVerifiedCondition=True",
|
||||||
|
secret: &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "existing",
|
||||||
|
},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
"foo": []byte(armoredKeyRingFixture),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
commit: git.Commit{
|
||||||
|
ReferencingTag: &git.Tag{
|
||||||
|
Name: "v0.1.0",
|
||||||
|
Hash: []byte("shasum"),
|
||||||
|
Encoded: []byte(encodedTagFixture),
|
||||||
|
Signature: signatureTagFixture,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||||
|
obj.Spec.Reference = &sourcev1.GitRepositoryRef{
|
||||||
|
Tag: "v0.1.0",
|
||||||
|
}
|
||||||
|
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||||
|
obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
||||||
|
Mode: sourcev1.ModeGitTag,
|
||||||
|
SecretRef: meta.LocalObjectReference{
|
||||||
|
Name: "existing",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
want: sreconcile.ResultSuccess,
|
||||||
|
wantSourceVerificationMode: ptrToVerificationMode(sourcev1.ModeGitTag),
|
||||||
|
assertConditions: []metav1.Condition{
|
||||||
|
*conditions.TrueCondition(sourcev1.SourceVerifiedCondition, meta.SucceededReason, "verified signature of\n\t- tag 'v0.1.0@shasum' with key '5982D0279C227FFD'"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Valid tag and commit with mode=TagAndHEAD 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,
|
||||||
|
ReferencingTag: &git.Tag{
|
||||||
|
Name: "v0.1.0",
|
||||||
|
Hash: []byte("shasum"),
|
||||||
|
Encoded: []byte(encodedTagFixture),
|
||||||
|
Signature: signatureTagFixture,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||||
|
obj.Spec.Reference = &sourcev1.GitRepositoryRef{
|
||||||
|
Tag: "v0.1.0",
|
||||||
|
}
|
||||||
|
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||||
|
obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
||||||
|
Mode: sourcev1.ModeGitTagAndHEAD,
|
||||||
|
SecretRef: meta.LocalObjectReference{
|
||||||
|
Name: "existing",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
want: sreconcile.ResultSuccess,
|
||||||
|
wantSourceVerificationMode: ptrToVerificationMode(sourcev1.ModeGitTagAndHEAD),
|
||||||
|
assertConditions: []metav1.Condition{
|
||||||
|
*conditions.TrueCondition(sourcev1.SourceVerifiedCondition, meta.SucceededReason, "verified signature of\n\t- tag 'v0.1.0@shasum' with key '5982D0279C227FFD'\n\t- commit 'shasum' with key '5982D0279C227FFD'"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Source verification mode in status is unset if there's no verification in spec",
|
||||||
|
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||||
|
obj.Status.SourceVerificationMode = ptrToVerificationMode(sourcev1.ModeGitHEAD)
|
||||||
|
obj.Spec.Verification = nil
|
||||||
|
},
|
||||||
|
want: sreconcile.ResultSuccess,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Verification of tag with no tag ref SourceVerifiedCondition=False and returns a stalling error",
|
||||||
|
secret: &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "existing",
|
||||||
|
},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
"foo": []byte(armoredKeyRingFixture),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||||
|
obj.Spec.Reference = &sourcev1.GitRepositoryRef{
|
||||||
|
Branch: "main",
|
||||||
|
}
|
||||||
|
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||||
|
obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
||||||
|
Mode: sourcev1.ModeGitTag,
|
||||||
|
SecretRef: meta.LocalObjectReference{
|
||||||
|
Name: "existing",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
err: serror.NewStalling(
|
||||||
|
errors.New("cannot verify tag object's signature if a tag reference is not specified"),
|
||||||
|
"InvalidVerificationMode",
|
||||||
|
),
|
||||||
|
assertConditions: []metav1.Condition{
|
||||||
|
*conditions.FalseCondition(sourcev1.SourceVerifiedCondition, "InvalidVerificationMode", "cannot verify tag object's signature if a tag reference is not specified"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Unsigned tag with mode=tag makes SourceVerifiedCondition=False",
|
||||||
|
secret: &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "existing",
|
||||||
|
},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
"foo": []byte(armoredKeyRingFixture),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
commit: git.Commit{
|
||||||
|
ReferencingTag: &git.Tag{
|
||||||
|
Name: "v0.1.0",
|
||||||
|
Hash: []byte("shasum"),
|
||||||
|
Encoded: []byte(encodedTagFixture),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||||
|
obj.Spec.Reference = &sourcev1.GitRepositoryRef{
|
||||||
|
Tag: "v0.1.0",
|
||||||
|
}
|
||||||
|
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||||
|
obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
||||||
|
Mode: sourcev1.ModeGitTag,
|
||||||
|
SecretRef: meta.LocalObjectReference{
|
||||||
|
Name: "existing",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
assertConditions: []metav1.Condition{
|
||||||
|
*conditions.FalseCondition(sourcev1.SourceVerifiedCondition, "InvalidGitObject", "cannot verify signature of tag 'v0.1.0@shasum' since it is not signed"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Partially successful verification makes SourceVerifiedCondition=False",
|
||||||
|
secret: &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "existing",
|
||||||
|
},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
"foo": []byte(armoredKeyRingFixture),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
commit: git.Commit{
|
||||||
|
Hash: []byte("shasum"),
|
||||||
|
Encoded: []byte(malformedEncodedCommitFixture),
|
||||||
|
Signature: signatureCommitFixture,
|
||||||
|
ReferencingTag: &git.Tag{
|
||||||
|
Name: "v0.1.0",
|
||||||
|
Hash: []byte("shasum"),
|
||||||
|
Encoded: []byte(encodedTagFixture),
|
||||||
|
Signature: signatureTagFixture,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||||
|
obj.Spec.Reference = &sourcev1.GitRepositoryRef{
|
||||||
|
Tag: "v0.1.0",
|
||||||
|
}
|
||||||
|
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||||
|
obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
||||||
|
Mode: sourcev1.ModeGitTagAndHEAD,
|
||||||
|
SecretRef: meta.LocalObjectReference{
|
||||||
|
Name: "existing",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
assertConditions: []metav1.Condition{
|
||||||
|
*conditions.FalseCondition(sourcev1.SourceVerifiedCondition, "InvalidCommitSignature", "signature verification of commit 'shasum' failed: unable to verify Git commit: unable to verify payload with any of the given key rings"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Invalid commit makes SourceVerifiedCondition=False and returns error",
|
||||||
secret: &corev1.Secret{
|
secret: &corev1.Secret{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Name: "existing",
|
Name: "existing",
|
||||||
|
|
@ -1569,7 +1812,7 @@ func TestGitRepositoryReconciler_verifySignature(t *testing.T) {
|
||||||
beforeFunc: func(obj *sourcev1.GitRepository) {
|
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||||
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||||
obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
||||||
Mode: "head",
|
Mode: sourcev1.ModeGitHEAD,
|
||||||
SecretRef: meta.LocalObjectReference{
|
SecretRef: meta.LocalObjectReference{
|
||||||
Name: "existing",
|
Name: "existing",
|
||||||
},
|
},
|
||||||
|
|
@ -1581,11 +1824,40 @@ func TestGitRepositoryReconciler_verifySignature(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Secret get failure sets no SourceVerifiedCondition and returns error",
|
name: "Invalid PGP key makes SourceVerifiedCondition=False and returns error",
|
||||||
|
secret: &corev1.Secret{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "invalid",
|
||||||
|
},
|
||||||
|
Data: map[string][]byte{
|
||||||
|
"foo": []byte("invalid PGP public key"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
commit: git.Commit{
|
||||||
|
Hash: []byte("shasum"),
|
||||||
|
Encoded: []byte(malformedEncodedCommitFixture),
|
||||||
|
Signature: signatureCommitFixture,
|
||||||
|
},
|
||||||
beforeFunc: func(obj *sourcev1.GitRepository) {
|
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||||
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||||
obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
||||||
Mode: "head",
|
Mode: sourcev1.ModeGitHEAD,
|
||||||
|
SecretRef: meta.LocalObjectReference{
|
||||||
|
Name: "invalid",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
assertConditions: []metav1.Condition{
|
||||||
|
*conditions.FalseCondition(sourcev1.SourceVerifiedCondition, "InvalidCommitSignature", "signature verification of commit 'shasum' failed: unable to verify Git commit: unable to read armored key ring: openpgp: invalid argument: no armored data found"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Secret get failure makes SourceVerifiedCondition=False and returns error",
|
||||||
|
beforeFunc: func(obj *sourcev1.GitRepository) {
|
||||||
|
obj.Spec.Interval = metav1.Duration{Duration: interval}
|
||||||
|
obj.Spec.Verification = &sourcev1.GitRepositoryVerification{
|
||||||
|
Mode: sourcev1.ModeGitHEAD,
|
||||||
SecretRef: meta.LocalObjectReference{
|
SecretRef: meta.LocalObjectReference{
|
||||||
Name: "none-existing",
|
Name: "none-existing",
|
||||||
},
|
},
|
||||||
|
|
@ -1651,7 +1923,15 @@ func TestGitRepositoryReconciler_verifySignature(t *testing.T) {
|
||||||
got, err := r.verifySignature(context.TODO(), obj, tt.commit)
|
got, err := r.verifySignature(context.TODO(), obj, tt.commit)
|
||||||
g.Expect(obj.Status.Conditions).To(conditions.MatchConditions(tt.assertConditions))
|
g.Expect(obj.Status.Conditions).To(conditions.MatchConditions(tt.assertConditions))
|
||||||
g.Expect(err != nil).To(Equal(tt.wantErr))
|
g.Expect(err != nil).To(Equal(tt.wantErr))
|
||||||
|
if tt.err != nil {
|
||||||
|
g.Expect(err).To(Equal(tt.err))
|
||||||
|
}
|
||||||
g.Expect(got).To(Equal(tt.want))
|
g.Expect(got).To(Equal(tt.want))
|
||||||
|
if tt.wantSourceVerificationMode != nil {
|
||||||
|
g.Expect(*obj.Status.SourceVerificationMode).To(Equal(*tt.wantSourceVerificationMode))
|
||||||
|
} else {
|
||||||
|
g.Expect(obj.Status.SourceVerificationMode).To(BeNil())
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2800,3 +3080,124 @@ func TestGitContentConfigChanged(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_requiresVerification(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
obj *sourcev1.GitRepository
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "GitRepository without verification does not require verification",
|
||||||
|
obj: &sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{},
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GitRepository with verification and no observed verification mode in status requires verification",
|
||||||
|
obj: &sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Verification: &sourcev1.GitRepositoryVerification{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GitRepository with HEAD verification and a verified tag requires verification",
|
||||||
|
obj: &sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Verification: &sourcev1.GitRepositoryVerification{
|
||||||
|
Mode: sourcev1.ModeGitHEAD,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{
|
||||||
|
SourceVerificationMode: ptrToVerificationMode(sourcev1.ModeGitTag),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GitRepository with tag and HEAD verification and a verified tag requires verification",
|
||||||
|
obj: &sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Verification: &sourcev1.GitRepositoryVerification{
|
||||||
|
Mode: sourcev1.ModeGitTagAndHEAD,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{
|
||||||
|
SourceVerificationMode: ptrToVerificationMode(sourcev1.ModeGitTag),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GitRepository with tag verification and a verified HEAD requires verification",
|
||||||
|
obj: &sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Verification: &sourcev1.GitRepositoryVerification{
|
||||||
|
Mode: sourcev1.ModeGitTag,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{
|
||||||
|
SourceVerificationMode: ptrToVerificationMode(sourcev1.ModeGitHEAD),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GitRepository with tag and HEAD verification and a verified HEAD requires verification",
|
||||||
|
obj: &sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Verification: &sourcev1.GitRepositoryVerification{
|
||||||
|
Mode: sourcev1.ModeGitTagAndHEAD,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{
|
||||||
|
SourceVerificationMode: ptrToVerificationMode(sourcev1.ModeGitHEAD),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GitRepository with tag verification and a verified HEAD and tag does not require verification",
|
||||||
|
obj: &sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Verification: &sourcev1.GitRepositoryVerification{
|
||||||
|
Mode: sourcev1.ModeGitTag,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{
|
||||||
|
SourceVerificationMode: ptrToVerificationMode(sourcev1.ModeGitTagAndHEAD),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "GitRepository with head verification and a verified HEAD and tag does not require verification",
|
||||||
|
obj: &sourcev1.GitRepository{
|
||||||
|
Spec: sourcev1.GitRepositorySpec{
|
||||||
|
Verification: &sourcev1.GitRepositoryVerification{
|
||||||
|
Mode: sourcev1.ModeGitHEAD,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: sourcev1.GitRepositoryStatus{
|
||||||
|
SourceVerificationMode: ptrToVerificationMode(sourcev1.ModeGitTagAndHEAD),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
g := NewWithT(t)
|
||||||
|
verificationRequired := requiresVerification(tt.obj)
|
||||||
|
g.Expect(verificationRequired).To(Equal(tt.want))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ptrToVerificationMode(mode sourcev1.GitVerificationMode) *sourcev1.GitVerificationMode {
|
||||||
|
return &mode
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue