Skip to content

Commit fc80244

Browse files
Merge pull request #703 from erikgb/refactor-additional-formats-2
Move additional formats handling from source to target
2 parents d378c1f + 58f04e8 commit fc80244

File tree

5 files changed

+118
-220
lines changed

5 files changed

+118
-220
lines changed

pkg/bundle/bundle.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func (b *bundle) reconcileBundle(ctx context.Context, req ctrl.Request) (statusP
115115
statusPatch = &trustapi.BundleStatus{
116116
DefaultCAPackageVersion: bundle.Status.DefaultCAPackageVersion,
117117
}
118-
resolvedBundle, err := b.bundleBuilder.BuildBundle(ctx, bundle.Spec.Sources, bundle.Spec.Target.AdditionalFormats)
118+
resolvedBundle, err := b.bundleBuilder.BuildBundle(ctx, bundle.Spec.Sources)
119119

120120
if err != nil {
121121
var reason, message string

pkg/bundle/internal/source/source.go

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import (
2828

2929
trustapi "github.com/cert-manager/trust-manager/pkg/apis/trust/v1alpha1"
3030
"github.com/cert-manager/trust-manager/pkg/bundle/controller"
31-
"github.com/cert-manager/trust-manager/pkg/bundle/internal/truststore"
3231
"github.com/cert-manager/trust-manager/pkg/fspkg"
3332
"github.com/cert-manager/trust-manager/pkg/util"
3433
)
@@ -43,38 +42,11 @@ type InvalidSecretError struct{ error }
4342
// certificate data from concatenating all the sources together, binary data for any additional formats and
4443
// any metadata from the sources which needs to be exposed on the Bundle resource's status field.
4544
type BundleData struct {
46-
Data string
47-
48-
BinaryData map[string][]byte
45+
CertPool *util.CertPool
4946

5047
DefaultCAPackageStringID string
5148
}
5249

53-
func (b *BundleData) populate(pool *util.CertPool, formats *trustapi.AdditionalFormats) error {
54-
b.Data = pool.PEM()
55-
56-
if formats != nil {
57-
b.BinaryData = make(map[string][]byte)
58-
59-
if formats.JKS != nil {
60-
encoded, err := truststore.NewJKSEncoder(*formats.JKS.Password).Encode(pool)
61-
if err != nil {
62-
return fmt.Errorf("failed to encode JKS: %w", err)
63-
}
64-
b.BinaryData[formats.JKS.Key] = encoded
65-
}
66-
67-
if formats.PKCS12 != nil {
68-
encoded, err := truststore.NewPKCS12Encoder(*formats.PKCS12.Password, formats.PKCS12.Profile).Encode(pool)
69-
if err != nil {
70-
return fmt.Errorf("failed to encode PKCS12: %w", err)
71-
}
72-
b.BinaryData[formats.PKCS12.Key] = encoded
73-
}
74-
}
75-
return nil
76-
}
77-
7850
type BundleBuilder struct {
7951
client.Reader
8052

@@ -87,9 +59,9 @@ type BundleBuilder struct {
8759

8860
// BuildBundle retrieves and concatenates all source bundle data for this Bundle object.
8961
// Each source data is validated and pruned to ensure that all certificates within are valid.
90-
func (b *BundleBuilder) BuildBundle(ctx context.Context, sources []trustapi.BundleSource, formats *trustapi.AdditionalFormats) (BundleData, error) {
62+
func (b *BundleBuilder) BuildBundle(ctx context.Context, sources []trustapi.BundleSource) (BundleData, error) {
9163
var resolvedBundle BundleData
92-
certPool := util.NewCertPool(
64+
resolvedBundle.CertPool = util.NewCertPool(
9365
util.WithFilteredExpiredCerts(b.FilterExpiredCerts),
9466
util.WithLogger(logf.FromContext(ctx).WithName("cert-pool")),
9567
)
@@ -120,20 +92,16 @@ func (b *BundleBuilder) BuildBundle(ctx context.Context, sources []trustapi.Bund
12092
panic(fmt.Sprintf("don't know how to process source: %+v", source))
12193
}
12294

123-
if err := certSource.addToCertPool(ctx, certPool); err != nil {
95+
if err := certSource.addToCertPool(ctx, resolvedBundle.CertPool); err != nil {
12496
return BundleData{}, err
12597
}
12698
}
12799

128100
// NB: empty bundles are not valid, so check and return an error if one somehow snuck through.
129-
if certPool.Size() == 0 {
101+
if resolvedBundle.CertPool.Size() == 0 {
130102
return BundleData{}, NotFoundError{fmt.Errorf("couldn't find any valid certificates in bundle")}
131103
}
132104

133-
if err := resolvedBundle.populate(certPool, formats); err != nil {
134-
return BundleData{}, err
135-
}
136-
137105
return resolvedBundle, nil
138106
}
139107

pkg/bundle/internal/source/source_test.go

Lines changed: 4 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,16 @@ limitations under the License.
1717
package source
1818

1919
import (
20-
"bytes"
21-
"encoding/pem"
2220
"errors"
2321
"strings"
2422
"testing"
2523

26-
jks "github.com/pavlo-v-chernykh/keystore-go/v4"
2724
"github.com/stretchr/testify/assert"
2825
corev1 "k8s.io/api/core/v1"
2926
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3027
"k8s.io/apimachinery/pkg/runtime"
3128
"k8s.io/utils/ptr"
3229
"sigs.k8s.io/controller-runtime/pkg/client/fake"
33-
"software.sslmate.com/src/go-pkcs12"
3430

3531
trustapi "github.com/cert-manager/trust-manager/pkg/apis/trust/v1alpha1"
3632
"github.com/cert-manager/trust-manager/pkg/bundle/controller"
@@ -40,26 +36,15 @@ import (
4036
"github.com/cert-manager/trust-manager/test/dummy"
4137
)
4238

43-
const (
44-
jksKey = "trust.jks"
45-
pkcs12Key = "trust.p12"
46-
data = dummy.TestCertificate1
47-
)
48-
4939
func Test_BuildBundle(t *testing.T) {
5040
tests := map[string]struct {
5141
sources []trustapi.BundleSource
5242
filterExpired bool
53-
formats *trustapi.AdditionalFormats
5443
objects []runtime.Object
5544
expData string
5645
expError bool
5746
expNotFoundError bool
5847
expInvalidSecretSourceError bool
59-
bool
60-
expJKS bool
61-
expPKCS12 bool
62-
expPassword *string
6348
}{
6449
"if no sources defined, should return NotFoundError": {
6550
expError: true,
@@ -333,85 +318,6 @@ func Test_BuildBundle(t *testing.T) {
333318
expError: false,
334319
expNotFoundError: false,
335320
},
336-
337-
"if has JKS target, return binaryData with encoded JKS": {
338-
sources: []trustapi.BundleSource{
339-
{ConfigMap: &trustapi.SourceObjectKeySelector{Name: "configmap", Key: "key"}},
340-
},
341-
formats: &trustapi.AdditionalFormats{
342-
JKS: &trustapi.JKS{
343-
KeySelector: trustapi.KeySelector{
344-
Key: jksKey,
345-
},
346-
Password: ptr.To(trustapi.DefaultJKSPassword),
347-
},
348-
},
349-
objects: []runtime.Object{&corev1.ConfigMap{
350-
ObjectMeta: metav1.ObjectMeta{Name: "configmap"},
351-
Data: map[string]string{"key": dummy.TestCertificate1},
352-
}},
353-
expData: dummy.JoinCerts(dummy.TestCertificate1),
354-
expJKS: true,
355-
},
356-
"if has JKS target with arbitrary password, return binaryData with encoded JKS": {
357-
sources: []trustapi.BundleSource{
358-
{ConfigMap: &trustapi.SourceObjectKeySelector{Name: "configmap", Key: "key"}},
359-
},
360-
formats: &trustapi.AdditionalFormats{
361-
JKS: &trustapi.JKS{
362-
KeySelector: trustapi.KeySelector{
363-
Key: jksKey,
364-
},
365-
Password: ptr.To("testPasswd123"),
366-
},
367-
},
368-
objects: []runtime.Object{&corev1.ConfigMap{
369-
ObjectMeta: metav1.ObjectMeta{Name: "configmap"},
370-
Data: map[string]string{"key": dummy.TestCertificate1},
371-
}},
372-
expData: dummy.JoinCerts(dummy.TestCertificate1),
373-
expJKS: true,
374-
expPassword: ptr.To("testPasswd123"),
375-
},
376-
"if has PKCS12 target, return binaryData with encoded PKCS12": {
377-
sources: []trustapi.BundleSource{
378-
{ConfigMap: &trustapi.SourceObjectKeySelector{Name: "configmap", Key: "key"}},
379-
},
380-
formats: &trustapi.AdditionalFormats{
381-
PKCS12: &trustapi.PKCS12{
382-
KeySelector: trustapi.KeySelector{
383-
Key: pkcs12Key,
384-
},
385-
Password: ptr.To(trustapi.DefaultPKCS12Password),
386-
},
387-
},
388-
objects: []runtime.Object{&corev1.ConfigMap{
389-
ObjectMeta: metav1.ObjectMeta{Name: "configmap"},
390-
Data: map[string]string{"key": dummy.TestCertificate1},
391-
}},
392-
expData: dummy.JoinCerts(dummy.TestCertificate1),
393-
expPKCS12: true,
394-
},
395-
"if has PKCS12 target with arbitrary password, return binaryData with encoded PKCS12": {
396-
sources: []trustapi.BundleSource{
397-
{ConfigMap: &trustapi.SourceObjectKeySelector{Name: "configmap", Key: "key"}},
398-
},
399-
formats: &trustapi.AdditionalFormats{
400-
PKCS12: &trustapi.PKCS12{
401-
KeySelector: trustapi.KeySelector{
402-
Key: pkcs12Key,
403-
},
404-
Password: ptr.To("testPasswd123"),
405-
},
406-
},
407-
objects: []runtime.Object{&corev1.ConfigMap{
408-
ObjectMeta: metav1.ObjectMeta{Name: "configmap"},
409-
Data: map[string]string{"key": dummy.TestCertificate1},
410-
}},
411-
expData: dummy.JoinCerts(dummy.TestCertificate1),
412-
expPKCS12: true,
413-
expPassword: ptr.To("testPasswd123"),
414-
},
415321
}
416322

417323
for name, tt := range tests {
@@ -433,24 +339,7 @@ func Test_BuildBundle(t *testing.T) {
433339
Options: controller.Options{FilterExpiredCerts: tt.filterExpired},
434340
}
435341

436-
// for corresponding store if arbitrary password is expected then set it instead of default one
437-
var password string
438-
if tt.expJKS {
439-
if tt.expPassword != nil {
440-
password = *tt.expPassword
441-
} else {
442-
password = trustapi.DefaultJKSPassword
443-
}
444-
}
445-
if tt.expPKCS12 {
446-
if tt.expPassword != nil {
447-
password = *tt.expPassword
448-
} else {
449-
password = trustapi.DefaultPKCS12Password
450-
}
451-
}
452-
453-
resolvedBundle, err := b.BuildBundle(t.Context(), tt.sources, tt.formats)
342+
resolvedBundle, err := b.BuildBundle(t.Context(), tt.sources)
454343

455344
if (err != nil) != tt.expError {
456345
t.Errorf("unexpected error, exp=%t got=%v", tt.expError, err)
@@ -462,45 +351,9 @@ func Test_BuildBundle(t *testing.T) {
462351
t.Errorf("unexpected InvalidSecretError, exp=%t got=%v", tt.expInvalidSecretSourceError, err)
463352
}
464353

465-
if resolvedBundle.Data != tt.expData {
466-
t.Errorf("unexpected data, exp=%q got=%q", tt.expData, resolvedBundle.Data)
467-
}
468-
469-
binData, jksExists := resolvedBundle.BinaryData[jksKey]
470-
assert.Equal(t, tt.expJKS, jksExists)
471-
472-
if tt.expJKS {
473-
reader := bytes.NewReader(binData)
474-
475-
ks := jks.New()
476-
477-
err := ks.Load(reader, []byte(password))
478-
assert.Nil(t, err)
479-
480-
entryNames := ks.Aliases()
481-
482-
assert.Len(t, entryNames, 1)
483-
assert.True(t, ks.IsTrustedCertificateEntry(entryNames[0]))
484-
485-
// Safe to ignore errors here, we've tested that it's present and a TrustedCertificateEntry
486-
cert, _ := ks.GetTrustedCertificateEntry(entryNames[0])
487-
488-
// Only one certificate block for this test, so we can safely ignore the `remaining` byte array
489-
p, _ := pem.Decode([]byte(data))
490-
assert.Equal(t, p.Bytes, cert.Certificate.Content)
491-
}
492-
493-
binData, pkcs12Exists := resolvedBundle.BinaryData[pkcs12Key]
494-
assert.Equal(t, tt.expPKCS12, pkcs12Exists)
495-
496-
if tt.expPKCS12 {
497-
cas, err := pkcs12.DecodeTrustStore(binData, password)
498-
assert.Nil(t, err)
499-
assert.Len(t, cas, 1)
500-
501-
// Only one certificate block for this test, so we can safely ignore the `remaining` byte array
502-
p, _ := pem.Decode([]byte(data))
503-
assert.Equal(t, p.Bytes, cas[0].Raw)
354+
data := resolvedBundle.CertPool.PEM()
355+
if data != tt.expData {
356+
t.Errorf("unexpected data, exp=%q got=%q", tt.expData, data)
504357
}
505358
})
506359
}

0 commit comments

Comments
 (0)