[additionalOutputFormats] Update comments and add more tests

Signed-off-by: Thierry Sallé <seuf76@gmail.com>
This commit is contained in:
Thierry Sallé 2022-01-12 15:39:29 +01:00
parent 81f308221b
commit 7f8641dd94
11 changed files with 336 additions and 55 deletions

View File

@ -68,16 +68,16 @@ spec:
- secretName
properties:
additionalOutputFormats:
description: AdditionalOutputFormats allows for requests for additional formats in which the private key should be written to the secret
description: AdditionalOutputFormats allows for requests of additional output formats of the private key and the certificate to be written to the secret. This is an Alpha Feature and should be enabled with --feature-gates option.
type: array
items:
description: AdditionalOutputFormat wraps an additional key output format type
description: AdditionalOutputFormat wraps an additional output format type
type: object
required:
- type
properties:
type:
description: OutputFormatType specifies which additional key formats should be added to Kubernetes secrets. Allowed values are `DER` or `CombinedPEM`. When Type is set to `DER` an additional entry `key.der` will be created in the secret containing the binary format of the key. When Type is set to `CombinedPEM` an additional entry `tls-combined.pem` will be created in the secret containing the PEM formatted certificate chain and key (tls.key + tls.crt concatenated)
description: OutputFormatType specifies which additional output formats should be added to Kubernetes secrets. Allowed values are `DER` or `CombinedPEM`. When Type is set to `DER` an additional entry `key.der` will be created in the secret containing the binary format of the key. When Type is set to `CombinedPEM` an additional entry `tls-combined.pem` will be created in the secret containing the PEM formatted certificate chain and key (tls.key + tls.crt concatenated)
type: string
enum:
- DER

View File

@ -166,7 +166,9 @@ type CertificateSpec struct {
// revisions will not be garbage collected. Default value is `nil`.
RevisionHistoryLimit *int32
// AdditionalOutputFormats allows for requests for additional formats in which the private key should be written to the secret
// AdditionalOutputFormats allows for requests of additional output formats
// of the private key and the certificate to be written to the secret.
// This is an Alpha Feature and should be enabled with --feature-gates option.
AdditionalOutputFormats []AdditionalOutputFormat
}
@ -208,7 +210,7 @@ type CertificatePrivateKey struct {
Size int
}
// OutputFormatType specifies which additional key formats should be added to Kubernetes secrets.
// OutputFormatType specifies which additional output formats should be added to Kubernetes secrets.
// Allowed values are `DER` or `CombinedPEM`.
// When Type is set to `DER` an additional entry `key.der` will be created in the secret
// containing the binary format of the key.
@ -217,16 +219,16 @@ type CertificatePrivateKey struct {
type OutputFormatType string
const (
// AdditionalKeyOutputFormatDER requests that the DER binary format of the key
// AdditionalOutputFormatDER requests that the DER binary format of the key
// is stored in the `key.der` key of a secret
AdditionalKeyOutputFormatDER OutputFormatType = "DER"
AdditionalOutputFormatDER OutputFormatType = "DER"
// AdditionalOutputFormatCombinedPEM requests that an entry containing both the PEM tls.crt and tls.key
// values concatenated is stored in the `tls-combined.pem` key of a secret
AdditionalOutputFormatCombinedPEM OutputFormatType = "CombinedPEM"
)
// AdditionalOutputFormat wraps an additional key output format type
// AdditionalOutputFormat wraps an additional output format type
type AdditionalOutputFormat struct {
Type OutputFormatType
}

View File

@ -209,7 +209,9 @@ type CertificateSpec struct {
// +optional
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` // Validated by the validating webhook.
// AdditionalOutputFormats allows for requests for additional formats in which the private key should be written to the secret
// AdditionalOutputFormats allows for requests of additional output formats
// of the private key and the certificate to be written to the secret.
// This is an Alpha Feature and should be enabled with --feature-gates option.
// +optional
AdditionalOutputFormats []AdditionalOutputFormat `json:"additionalOutputFormats,omitempty"`
}
@ -447,7 +449,7 @@ type CertificateSecretTemplate struct {
Labels map[string]string `json:"labels,omitempty"`
}
// OutputFormatType specifies which additional key formats should be added to Kubernetes secrets.
// OutputFormatType specifies which additional output formats should be added to Kubernetes secrets.
// Allowed values are `DER` or `CombinedPEM`.
// When Type is set to `DER` an additional entry `key.der` will be created in the secret
// containing the binary format of the key.
@ -457,9 +459,9 @@ type CertificateSecretTemplate struct {
type OutputFormatType string
const (
// AdditionalKeyOutputFormatDER requests that the DER binary format of the key
// AdditionalOutputFormatDER requests that the DER binary format of the key
// is stored in the `key.der` key of a secret
AdditionalKeyOutputFormatDER OutputFormatType = "DER"
AdditionalOutputFormatDER OutputFormatType = "DER"
// AdditionalOutputFormatCombinedPEM requests that an entry containing both the PEM tls.crt and tls.key
// values concatenated is stored in the `tls-combined.pem` key of a secret

View File

@ -207,7 +207,9 @@ type CertificateSpec struct {
// +optional
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` // Validated by the validating webhook.
// AdditionalOutputFormats allows for requests for additional formats in which the private key should be written to the secret
// AdditionalOutputFormats allows for requests of additional output formats
// of the private key and the certificate to be written to the secret.
// This is an Alpha Feature and should be enabled with --feature-gates option.
// +optional
AdditionalOutputFormats []AdditionalOutputFormat `json:"additionalOutputFormats,omitempty"`
}
@ -454,7 +456,7 @@ type CertificateSecretTemplate struct {
Labels map[string]string `json:"labels,omitempty"`
}
// OutputFormatType specifies which additional key formats should be added to Kubernetes secrets.
// OutputFormatType specifies which additional output formats should be added to Kubernetes secrets.
// Allowed values are `DER` or `CombinedPEM`.
// When Type is set to `DER` an additional entry `key.der` will be created in the secret
// containing the binary format of the key.
@ -464,9 +466,9 @@ type CertificateSecretTemplate struct {
type OutputFormatType string
const (
// AdditionalKeyOutputFormatDER requests that the DER binary format of the key
// AdditionalOutputFormatDER requests that the DER binary format of the key
// is stored in the `key.der` key of a secret
AdditionalKeyOutputFormatDER OutputFormatType = "DER"
AdditionalOutputFormatDER OutputFormatType = "DER"
// AdditionalOutputFormatCombinedPEM requests that an entry containing both the PEM tls.crt and tls.key
// values concatenated is stored in the `tls-combined.pem` key of a secret

View File

@ -184,7 +184,9 @@ type CertificateSpec struct {
// +optional
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` // Validated by the validating webhook.
// AdditionalOutputFormats allows for requests for additional formats in which the private key should be written to the secret
// AdditionalOutputFormats allows for requests of additional output formats
// of the private key and the certificate to be written to the secret.
// This is an Alpha Feature and should be enabled with --feature-gates option.
// +optional
AdditionalOutputFormats []AdditionalOutputFormat `json:"additionalOutputFormats,omitempty"`
}
@ -452,7 +454,7 @@ type CertificateSecretTemplate struct {
Labels map[string]string `json:"labels,omitempty"`
}
// OutputFormatType specifies which additional key formats should be added to Kubernetes secrets.
// OutputFormatType specifies which additional output formats should be added to Kubernetes secrets.
// Allowed values are `DER` or `CombinedPEM`.
// When Type is set to `DER` an additional entry `key.der` will be created in the secret
// containing the binary format of the key.
@ -462,9 +464,9 @@ type CertificateSecretTemplate struct {
type OutputFormatType string
const (
// AdditionalKeyOutputFormatDER requests that the DER binary format of the key
// AdditionalOutputFormatDER requests that the DER binary format of the key
// is stored in the `key.der` key of a secret
AdditionalKeyOutputFormatDER OutputFormatType = "DER"
AdditionalOutputFormatDER OutputFormatType = "DER"
// AdditionalOutputFormatCombinedPEM requests that an entry containing both the PEM tls.crt and tls.key
// values concatenated is stored in the `tls-combined.pem` key of a secret

View File

@ -188,7 +188,9 @@ type CertificateSpec struct {
// +optional
RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` // Validated by the validating webhook.
// AdditionalOutputFormats allows for requests for additional formats in which the private key should be written to the secret
// AdditionalOutputFormats allows for requests of additional output formats
// of the private key and the certificate to be written to the secret.
// This is an Alpha Feature and should be enabled with --feature-gates option.
// +optional
AdditionalOutputFormats []AdditionalOutputFormat `json:"additionalOutputFormats,omitempty"`
}
@ -253,7 +255,7 @@ var (
RotationPolicyAlways PrivateKeyRotationPolicy = "Always"
)
// OutputFormatType specifies which additional key formats should be added to Kubernetes secrets.
// OutputFormatType specifies which additional output formats should be added to Kubernetes secrets.
// Allowed values are `DER` or `CombinedPEM`.
// When Type is set to `DER` an additional entry `key.der` will be created in the secret
// containing the binary format of the key.
@ -263,24 +265,24 @@ var (
type OutputFormatType string
const (
// AdditionalKeyOutputFormatDER requests that the DER binary format of the key
// is stored in the `key.der` key of a secret
AdditionalKeyOutputFormatDER OutputFormatType = "DER"
// AdditionalOutputFormatDER requests that the DER binary format of the key
// is stored in the `key.der` key of the certificate's secret.
AdditionalOutputFormatDER OutputFormatType = "DER"
// AdditionalKeyOutputFormatDERKey is the name of the data entry in the Secret resource
// used to store the DER formatted private key
AdditionalKeyOutputFormatDERKey string = "key.der"
// AdditionalOutputFormatDERKey is the name of the data entry in the Secret resource
// used to store the DER formatted private key.
AdditionalOutputFormatDERKey string = "key.der"
// AdditionalOutputFormatCombinedPEM requests that an entry containing both the PEM tls.crt and tls.key
// values concatenated is stored in the `tls-combined.pem` key of a secret
// values concatenated is stored in the `tls-combined.pem` key of the certificate's secret.
AdditionalOutputFormatCombinedPEM OutputFormatType = "CombinedPEM"
// AdditionalOutputFormatPEMKey is the name of the data entry in the Secret resource
// used to store the combined PEM certificate + key
// used to store the combined PEM certificate + key.
AdditionalOutputFormatPEMKey string = "tls-combined.pem"
)
// AdditionalOutputFormat wraps an additional key output format type
// AdditionalOutputFormat wraps an additional output format type
type AdditionalOutputFormat struct {
Type OutputFormatType `json:"type"`
}

View File

@ -125,7 +125,7 @@ func (s *SecretsManager) UpdateData(ctx context.Context, crt *cmapi.Certificate,
func updateSecretWithAdditionalOutputFormats(crt *cmapi.Certificate, secret *corev1.Secret, data SecretData) error {
if crt.Spec.AdditionalOutputFormats == nil {
delete(secret.Data, cmapi.AdditionalKeyOutputFormatDERKey)
delete(secret.Data, cmapi.AdditionalOutputFormatDERKey)
delete(secret.Data, cmapi.AdditionalOutputFormatPEMKey)
return nil
}
@ -135,21 +135,21 @@ func updateSecretWithAdditionalOutputFormats(crt *cmapi.Certificate, secret *cor
for _, f := range crt.Spec.AdditionalOutputFormats {
switch f.Type {
case cmapi.AdditionalKeyOutputFormatDER:
case cmapi.AdditionalOutputFormatDER:
additionalOutputFormatDER = true
case cmapi.AdditionalOutputFormatCombinedPEM:
additionalOutputFormatPEM = true
default:
return fmt.Errorf("Unknown additional output format %s", f.Type)
return fmt.Errorf("unknown additional output format %s", f.Type)
}
}
if additionalOutputFormatDER {
// Store binary format of the private key
block, _ := pem.Decode(data.PrivateKey)
secret.Data[cmapi.AdditionalKeyOutputFormatDERKey] = block.Bytes
secret.Data[cmapi.AdditionalOutputFormatDERKey] = block.Bytes
} else {
delete(secret.Data, cmapi.AdditionalKeyOutputFormatDERKey)
delete(secret.Data, cmapi.AdditionalOutputFormatDERKey)
}
if additionalOutputFormatPEM {
@ -248,7 +248,9 @@ func (s *SecretsManager) setValues(crt *cmapi.Certificate, secret *corev1.Secret
// Add additional output formats
if utilfeature.DefaultFeatureGate.Enabled(feature.AdditionalCertificateOutputFormats) {
updateSecretWithAdditionalOutputFormats(crt, secret, data)
if err := updateSecretWithAdditionalOutputFormats(crt, secret, data); err != nil {
return fmt.Errorf("error during additional output format update: %w", err)
}
}
}
secret.Data[corev1.TLSPrivateKeyKey] = data.PrivateKey

View File

@ -77,11 +77,17 @@ func TestSecretsManager(t *testing.T) {
)
// enable feature gate additional private key for this test
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultMutableFeatureGate, feature.AdditionalCertificateOutputFormats, true)()
baseCertWithAdditionalOutputFormatDER := gen.CertificateFrom(baseCertBundle.Certificate,
gen.SetCertificateAdditionalOutputFormats(cmapi.AdditionalOutputFormat{Type: "DER"}),
)
baseCertWithAdditionalOutputFormatCombinedPEM := gen.CertificateFrom(baseCertBundle.Certificate,
gen.SetCertificateAdditionalOutputFormats(cmapi.AdditionalOutputFormat{Type: "CombinedPEM"}),
)
baseCertWithAdditionalOutputFormats := gen.CertificateFrom(baseCertBundle.Certificate,
gen.SetCertificateAdditionalOutputFormats([]cmapi.AdditionalOutputFormat{
{Type: "DER"},
{Type: "CombinedPEM"},
}),
gen.SetCertificateAdditionalOutputFormats(
cmapi.AdditionalOutputFormat{Type: "DER"},
cmapi.AdditionalOutputFormat{Type: "CombinedPEM"},
),
)
block, _ := pem.Decode(baseCertBundle.PrivateKeyBytes)
tlsDerContent := block.Bytes
@ -415,7 +421,87 @@ func TestSecretsManager(t *testing.T) {
expectedErr: false,
},
"if secret does not exist, create new Secret with additional key formats and enabled feature": {
"if secret does not exist, create new Secret with additional output format DER": {
certificate: baseCertWithAdditionalOutputFormatDER,
SecretData: SecretData{Certificate: baseCertBundle.CertBytes, CA: []byte("test-ca"), PrivateKey: baseCertBundle.PrivateKeyBytes},
builder: &testpkg.Builder{
KubeObjects: []runtime.Object{},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewCreateAction(
corev1.SchemeGroupVersion.WithResource("secrets"),
gen.DefaultTestNamespace,
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: gen.DefaultTestNamespace,
Name: "output",
Annotations: map[string]string{
cmapi.CertificateNameKey: "test",
cmapi.IssuerGroupAnnotationKey: "foo.io",
cmapi.IssuerKindAnnotationKey: "Issuer",
cmapi.IssuerNameAnnotationKey: "ca-issuer",
cmapi.CommonNameAnnotationKey: baseCertBundle.Cert.Subject.CommonName,
cmapi.AltNamesAnnotationKey: strings.Join(baseCertBundle.Cert.DNSNames, ","),
cmapi.IPSANAnnotationKey: strings.Join(utilpki.IPAddressesToString(baseCertBundle.Cert.IPAddresses), ","),
cmapi.URISANAnnotationKey: strings.Join(utilpki.URLsToString(baseCertBundle.Cert.URIs), ","),
},
Labels: map[string]string{},
},
Data: map[string][]byte{
corev1.TLSCertKey: baseCertBundle.CertBytes,
corev1.TLSPrivateKeyKey: baseCertBundle.PrivateKeyBytes,
cmmeta.TLSCAKey: []byte("test-ca"),
cmapi.AdditionalOutputFormatDERKey: tlsDerContent,
},
Type: corev1.SecretTypeTLS,
},
)),
},
},
expectedErr: false,
},
"if secret does not exist, create new Secret with additional output format CombinedPEM": {
certificate: baseCertWithAdditionalOutputFormatCombinedPEM,
SecretData: SecretData{Certificate: baseCertBundle.CertBytes, CA: []byte("test-ca"), PrivateKey: baseCertBundle.PrivateKeyBytes},
builder: &testpkg.Builder{
KubeObjects: []runtime.Object{},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewCreateAction(
corev1.SchemeGroupVersion.WithResource("secrets"),
gen.DefaultTestNamespace,
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: gen.DefaultTestNamespace,
Name: "output",
Annotations: map[string]string{
cmapi.CertificateNameKey: "test",
cmapi.IssuerGroupAnnotationKey: "foo.io",
cmapi.IssuerKindAnnotationKey: "Issuer",
cmapi.IssuerNameAnnotationKey: "ca-issuer",
cmapi.CommonNameAnnotationKey: baseCertBundle.Cert.Subject.CommonName,
cmapi.AltNamesAnnotationKey: strings.Join(baseCertBundle.Cert.DNSNames, ","),
cmapi.IPSANAnnotationKey: strings.Join(utilpki.IPAddressesToString(baseCertBundle.Cert.IPAddresses), ","),
cmapi.URISANAnnotationKey: strings.Join(utilpki.URLsToString(baseCertBundle.Cert.URIs), ","),
},
Labels: map[string]string{},
},
Data: map[string][]byte{
corev1.TLSCertKey: baseCertBundle.CertBytes,
corev1.TLSPrivateKeyKey: baseCertBundle.PrivateKeyBytes,
cmmeta.TLSCAKey: []byte("test-ca"),
cmapi.AdditionalOutputFormatPEMKey: []byte(strings.Join([]string{string(baseCertBundle.PrivateKeyBytes), string(baseCertBundle.CertBytes)}, "\n")),
},
Type: corev1.SecretTypeTLS,
},
)),
},
},
expectedErr: false,
},
"if secret does not exist, create new Secret with additional output format DER and CombinedPEM": {
certificate: baseCertWithAdditionalOutputFormats,
SecretData: SecretData{Certificate: baseCertBundle.CertBytes, CA: []byte("test-ca"), PrivateKey: baseCertBundle.PrivateKeyBytes},
builder: &testpkg.Builder{
@ -442,11 +528,199 @@ func TestSecretsManager(t *testing.T) {
Labels: map[string]string{},
},
Data: map[string][]byte{
corev1.TLSCertKey: baseCertBundle.CertBytes,
corev1.TLSPrivateKeyKey: baseCertBundle.PrivateKeyBytes,
cmmeta.TLSCAKey: []byte("test-ca"),
cmapi.AdditionalKeyOutputFormatDERKey: tlsDerContent,
cmapi.AdditionalOutputFormatPEMKey: []byte(strings.Join([]string{string(baseCertBundle.PrivateKeyBytes), string(baseCertBundle.CertBytes)}, "\n")),
corev1.TLSCertKey: baseCertBundle.CertBytes,
corev1.TLSPrivateKeyKey: baseCertBundle.PrivateKeyBytes,
cmmeta.TLSCAKey: []byte("test-ca"),
cmapi.AdditionalOutputFormatDERKey: tlsDerContent,
cmapi.AdditionalOutputFormatPEMKey: []byte(strings.Join([]string{string(baseCertBundle.PrivateKeyBytes), string(baseCertBundle.CertBytes)}, "\n")),
},
Type: corev1.SecretTypeTLS,
},
)),
},
},
expectedErr: false,
},
"if secret exists, with tls-combined.pem and key.der but no additional formats specified": {
certificate: baseCertBundle.Certificate,
certificateOptions: controllerpkg.CertificateOptions{
EnableOwnerRef: false,
},
SecretData: SecretData{Certificate: baseCertBundle.CertBytes, CA: []byte("test-ca"), PrivateKey: []byte("test-key")},
builder: &testpkg.Builder{
KubeObjects: []runtime.Object{
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: gen.DefaultTestNamespace,
Name: "output",
Annotations: map[string]string{
"my-custom": "annotation",
},
},
Data: map[string][]byte{
corev1.TLSCertKey: []byte("foo"),
corev1.TLSPrivateKeyKey: []byte("foo"),
cmmeta.TLSCAKey: []byte("foo"),
cmapi.AdditionalOutputFormatDERKey: []byte("foo"),
cmapi.AdditionalOutputFormatPEMKey: []byte("foo"),
},
Type: corev1.SecretTypeTLS,
},
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewUpdateAction(
corev1.SchemeGroupVersion.WithResource("secrets"),
gen.DefaultTestNamespace,
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: gen.DefaultTestNamespace,
Name: "output",
Annotations: map[string]string{
"my-custom": "annotation",
cmapi.CertificateNameKey: "test",
cmapi.IssuerGroupAnnotationKey: "foo.io",
cmapi.IssuerKindAnnotationKey: "Issuer",
cmapi.IssuerNameAnnotationKey: "ca-issuer",
cmapi.CommonNameAnnotationKey: baseCertBundle.Cert.Subject.CommonName,
cmapi.AltNamesAnnotationKey: strings.Join(baseCertBundle.Cert.DNSNames, ","),
cmapi.IPSANAnnotationKey: strings.Join(utilpki.IPAddressesToString(baseCertBundle.Cert.IPAddresses), ","),
cmapi.URISANAnnotationKey: strings.Join(utilpki.URLsToString(baseCertBundle.Cert.URIs), ","),
},
Labels: map[string]string{},
},
Data: map[string][]byte{
corev1.TLSCertKey: baseCertBundle.CertBytes,
corev1.TLSPrivateKeyKey: []byte("test-key"),
cmmeta.TLSCAKey: []byte("test-ca"),
},
Type: corev1.SecretTypeTLS,
},
)),
},
},
expectedErr: false,
},
"if secret exists, with tls-combined.pem and key.der but only DER Format specified": {
certificate: baseCertWithAdditionalOutputFormatDER,
certificateOptions: controllerpkg.CertificateOptions{
EnableOwnerRef: false,
},
SecretData: SecretData{Certificate: baseCertBundle.CertBytes, CA: []byte("test-ca"), PrivateKey: baseCertBundle.PrivateKeyBytes},
builder: &testpkg.Builder{
KubeObjects: []runtime.Object{
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: gen.DefaultTestNamespace,
Name: "output",
Annotations: map[string]string{
"my-custom": "annotation",
},
},
Data: map[string][]byte{
corev1.TLSCertKey: []byte("foo"),
corev1.TLSPrivateKeyKey: []byte("foo"),
cmmeta.TLSCAKey: []byte("foo"),
cmapi.AdditionalOutputFormatDERKey: []byte("foo"),
cmapi.AdditionalOutputFormatPEMKey: []byte("foo"),
},
Type: corev1.SecretTypeTLS,
},
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewUpdateAction(
corev1.SchemeGroupVersion.WithResource("secrets"),
gen.DefaultTestNamespace,
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: gen.DefaultTestNamespace,
Name: "output",
Annotations: map[string]string{
"my-custom": "annotation",
cmapi.CertificateNameKey: "test",
cmapi.IssuerGroupAnnotationKey: "foo.io",
cmapi.IssuerKindAnnotationKey: "Issuer",
cmapi.IssuerNameAnnotationKey: "ca-issuer",
cmapi.CommonNameAnnotationKey: baseCertBundle.Cert.Subject.CommonName,
cmapi.AltNamesAnnotationKey: strings.Join(baseCertBundle.Cert.DNSNames, ","),
cmapi.IPSANAnnotationKey: strings.Join(utilpki.IPAddressesToString(baseCertBundle.Cert.IPAddresses), ","),
cmapi.URISANAnnotationKey: strings.Join(utilpki.URLsToString(baseCertBundle.Cert.URIs), ","),
},
Labels: map[string]string{},
},
Data: map[string][]byte{
corev1.TLSCertKey: baseCertBundle.CertBytes,
corev1.TLSPrivateKeyKey: baseCertBundle.PrivateKeyBytes,
cmmeta.TLSCAKey: []byte("test-ca"),
cmapi.AdditionalOutputFormatDERKey: tlsDerContent,
},
Type: corev1.SecretTypeTLS,
},
)),
},
},
expectedErr: false,
},
"if secret exists, with tls-combined.pem and key.der but only Combined PEM Format specified": {
certificate: baseCertWithAdditionalOutputFormatCombinedPEM,
certificateOptions: controllerpkg.CertificateOptions{
EnableOwnerRef: false,
},
SecretData: SecretData{Certificate: baseCertBundle.CertBytes, CA: []byte("test-ca"), PrivateKey: baseCertBundle.PrivateKeyBytes},
builder: &testpkg.Builder{
KubeObjects: []runtime.Object{
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: gen.DefaultTestNamespace,
Name: "output",
Annotations: map[string]string{
"my-custom": "annotation",
},
},
Data: map[string][]byte{
corev1.TLSCertKey: []byte("foo"),
corev1.TLSPrivateKeyKey: []byte("foo"),
cmmeta.TLSCAKey: []byte("foo"),
cmapi.AdditionalOutputFormatDERKey: []byte("foo"),
cmapi.AdditionalOutputFormatPEMKey: []byte("foo"),
},
Type: corev1.SecretTypeTLS,
},
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewUpdateAction(
corev1.SchemeGroupVersion.WithResource("secrets"),
gen.DefaultTestNamespace,
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: gen.DefaultTestNamespace,
Name: "output",
Annotations: map[string]string{
"my-custom": "annotation",
cmapi.CertificateNameKey: "test",
cmapi.IssuerGroupAnnotationKey: "foo.io",
cmapi.IssuerKindAnnotationKey: "Issuer",
cmapi.IssuerNameAnnotationKey: "ca-issuer",
cmapi.CommonNameAnnotationKey: baseCertBundle.Cert.Subject.CommonName,
cmapi.AltNamesAnnotationKey: strings.Join(baseCertBundle.Cert.DNSNames, ","),
cmapi.IPSANAnnotationKey: strings.Join(utilpki.IPAddressesToString(baseCertBundle.Cert.IPAddresses), ","),
cmapi.URISANAnnotationKey: strings.Join(utilpki.URLsToString(baseCertBundle.Cert.URIs), ","),
},
Labels: map[string]string{},
},
Data: map[string][]byte{
corev1.TLSCertKey: baseCertBundle.CertBytes,
corev1.TLSPrivateKeyKey: baseCertBundle.PrivateKeyBytes,
cmmeta.TLSCAKey: []byte("test-ca"),
cmapi.AdditionalOutputFormatPEMKey: []byte(strings.Join([]string{string(baseCertBundle.PrivateKeyBytes), string(baseCertBundle.CertBytes)}, "\n")),
},
Type: corev1.SecretTypeTLS,
},

View File

@ -39,20 +39,15 @@ type ValidationFunc func(certificate *cmapi.Certificate, secret *corev1.Secret)
// ExpectValidKeysInSecret checks that the secret contains valid keys
func ExpectValidKeysInSecret(_ *cmapi.Certificate, secret *corev1.Secret) error {
validKeys := [5]string{corev1.TLSPrivateKeyKey, corev1.TLSCertKey, cmmeta.TLSCAKey, cmapi.AdditionalKeyOutputFormatDERKey, cmapi.AdditionalOutputFormatPEMKey}
validKeys := [5]string{corev1.TLSPrivateKeyKey, corev1.TLSCertKey, cmmeta.TLSCAKey, cmapi.AdditionalOutputFormatDERKey, cmapi.AdditionalOutputFormatPEMKey}
nbValidKeys := 0
for k := range secret.Data {
found := false
for _, k2 := range validKeys {
if k == k2 {
found = true
nbValidKeys++
break
}
}
if !found {
return fmt.Errorf("Expected secret key %s to be a valid key (%v)", k, validKeys)
}
}
if nbValidKeys < 2 {
return fmt.Errorf("Expected at least 2 valid keys in certificate secret, but there was %d", nbValidKeys)

View File

@ -125,7 +125,7 @@ var _ = framework.CertManagerDescribe("CA Certificate", func() {
Expect(err).NotTo(HaveOccurred())
})
It("should be able to create a certificate with additional private key formats", func() {
It("should be able to create a certificate with additional output formats", func() {
certClient := f.CertManagerClientSet.CertmanagerV1().Certificates(f.Namespace.Name)
cert := util.NewCertManagerBasicCertificate(certificateName, certificateSecretName, issuerName, v1.IssuerKind, nil, nil)

View File

@ -262,7 +262,7 @@ func SetCertificateRevisionHistoryLimit(limit int32) CertificateModifier {
}
}
func SetCertificateAdditionalOutputFormats(additionalOutputFormats []v1.AdditionalOutputFormat) CertificateModifier {
func SetCertificateAdditionalOutputFormats(additionalOutputFormats ...v1.AdditionalOutputFormat) CertificateModifier {
return func(crt *v1.Certificate) {
crt.Spec.AdditionalOutputFormats = additionalOutputFormats
}