Merge pull request #2573 from meyskens/venafi-custom-fields

Add venafi.cert-manager.io/custom-fields annnotation
This commit is contained in:
jetstack-bot 2020-02-17 12:24:24 +00:00 committed by GitHub
commit 672f7654a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 295 additions and 21 deletions

4
go.mod
View File

@ -12,7 +12,7 @@ require (
github.com/Azure/go-autorest/autorest/adal v0.5.0
github.com/Azure/go-autorest/autorest/to v0.3.0
github.com/Azure/go-autorest/autorest/validation v0.2.0 // indirect
github.com/Venafi/vcert v0.0.0-20190613103158-62139eb19b25
github.com/Venafi/vcert v0.0.0-20200207035730-5a915d73be5d
github.com/aws/aws-sdk-go v1.24.1
github.com/cloudflare/cloudflare-go v0.8.5
github.com/cpu/goacmedns v0.0.0-20180701200144-565ecf2a84df
@ -39,7 +39,7 @@ require (
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
google.golang.org/api v0.4.0
gopkg.in/ini.v1 v1.42.0 // indirect
gopkg.in/ini.v1 v1.52.0 // indirect
k8s.io/api v0.17.0
k8s.io/apiextensions-apiserver v0.17.0
k8s.io/apimachinery v0.17.0

8
go.sum
View File

@ -36,8 +36,8 @@ github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbt
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Venafi/vcert v0.0.0-20190613103158-62139eb19b25 h1:Vy4WHFF6SULSubt7vuyJRJ5AqwjJXzJQWdF37VcsyGo=
github.com/Venafi/vcert v0.0.0-20190613103158-62139eb19b25/go.mod h1:3sXw16DKVded/kLVDma2veqEUQC7O37h98ims7cIvN4=
github.com/Venafi/vcert v0.0.0-20200207035730-5a915d73be5d h1:oFQa1HzZX7Kcnjnosx9wEdVi8ADTDvs+2Tz96HIXrEU=
github.com/Venafi/vcert v0.0.0-20200207035730-5a915d73be5d/go.mod h1:5T4bFPhcgGXbdz8nVVRuE2gXSRDlZVL+9T5CwZZ3Yk4=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
@ -645,8 +645,8 @@ gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.38.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.42.0 h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=
gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.52.0 h1:j+Lt/M1oPPejkniCg1TkWE2J3Eh1oZTsHSXzMTzUXn4=
gopkg.in/ini.v1 v1.52.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=

View File

@ -1647,8 +1647,8 @@ def go_repositories():
build_file_generation = "on",
build_file_proto_mode = "disable",
importpath = "github.com/Venafi/vcert",
sum = "h1:Vy4WHFF6SULSubt7vuyJRJ5AqwjJXzJQWdF37VcsyGo=",
version = "v0.0.0-20190613103158-62139eb19b25",
sum = "h1:oFQa1HzZX7Kcnjnosx9wEdVi8ADTDvs+2Tz96HIXrEU=",
version = "v0.0.0-20200207035730-5a915d73be5d",
)
go_repository(
name = "com_github_xiang90_probing",
@ -1719,8 +1719,8 @@ def go_repositories():
build_file_generation = "on",
build_file_proto_mode = "disable",
importpath = "gopkg.in/ini.v1",
sum = "h1:7N3gPTt50s8GuLortA00n8AqRTk75qOP98+mTPpgzRk=",
version = "v1.42.0",
sum = "h1:j+Lt/M1oPPejkniCg1TkWE2J3Eh1oZTsHSXzMTzUXn4=",
version = "v1.52.0",
)
go_repository(
name = "in_gopkg_mgo_v2",

View File

@ -98,6 +98,15 @@ const (
AllowsInjectionFromSecretAnnotation = "cert-manager.io/allow-direct-injection"
)
// Issuer specific Annotations
const (
// VenafiCustomFieldsAnnotationKey is the annotation that passes on JSON encoded custom fields to the Venafi issuer
// This will only work with Venafi TPP v19.3 and higher
// The value is an array with objetcs containing the name and value keys
// for example: `[{"name": "custom-field", "value": "custom-value"}]`
VenafiCustomFieldsAnnotationKey = "venafi.cert-manager.io/custom-fields"
)
// KeyUsage specifies valid usage contexts for keys.
// See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3
// https://tools.ietf.org/html/rfc5280#section-4.2.1.12

View File

@ -98,6 +98,15 @@ const (
AllowsInjectionFromSecretAnnotation = "cert-manager.io/allow-direct-injection"
)
// Issuer specific Annotations
const (
// VenafiCustomFieldsAnnotationKey is the annotation that passes on JSON encoded custom fields to the Venafi issuer
// This will only work with Venafi TPP v19.3 and higher
// The value is an array with objetcs containing the name and value keys
// for example: `[{"name": "custom-field", "value": "custom-value"}]`
VenafiCustomFieldsAnnotationKey = "venafi.cert-manager.io/custom-fields"
)
// KeyUsage specifies valid usage contexts for keys.
// See: https://tools.ietf.org/html/rfc5280#section-4.2.1.3
// https://tools.ietf.org/html/rfc5280#section-4.2.1.12

View File

@ -12,6 +12,7 @@ go_library(
"//pkg/controller/certificaterequests:go_default_library",
"//pkg/controller/certificaterequests/util:go_default_library",
"//pkg/internal/venafi:go_default_library",
"//pkg/internal/venafi/api:go_default_library",
"//pkg/issuer:go_default_library",
"//pkg/logs:go_default_library",
"@com_github_venafi_vcert//pkg/endpoint:go_default_library",
@ -46,6 +47,7 @@ go_test(
"//pkg/controller/certificaterequests:go_default_library",
"//pkg/controller/test:go_default_library",
"//pkg/internal/venafi:go_default_library",
"//pkg/internal/venafi/api:go_default_library",
"//pkg/internal/venafi/fake:go_default_library",
"//pkg/util/pki:go_default_library",
"//test/unit/gen:go_default_library",

View File

@ -18,6 +18,8 @@ package venafi
import (
"context"
"encoding/json"
"fmt"
"github.com/Venafi/vcert/pkg/endpoint"
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
@ -29,6 +31,7 @@ import (
"github.com/jetstack/cert-manager/pkg/controller/certificaterequests"
crutil "github.com/jetstack/cert-manager/pkg/controller/certificaterequests/util"
venafiinternal "github.com/jetstack/cert-manager/pkg/internal/venafi"
internalvanafiapi "github.com/jetstack/cert-manager/pkg/internal/venafi/api"
issuerpkg "github.com/jetstack/cert-manager/pkg/issuer"
logf "github.com/jetstack/cert-manager/pkg/logs"
)
@ -88,12 +91,31 @@ func (v *Venafi) Sign(ctx context.Context, cr *cmapi.CertificateRequest, issuerO
duration := apiutil.DefaultCertDuration(cr.Spec.Duration)
certPem, err := client.Sign(cr.Spec.CSRPEM, duration)
var customFields []internalvanafiapi.CustomField
if annotation, exists := cr.GetAnnotations()[cmapi.VenafiCustomFieldsAnnotationKey]; exists && annotation != "" {
err := json.Unmarshal([]byte(annotation), &customFields)
if err != nil {
message := fmt.Sprintf("Failed to parse %q annotation", cmapi.VenafiCustomFieldsAnnotationKey)
v.reporter.Failed(cr, err, "CustomFieldsError", message)
log.Error(err, message)
return nil, nil
}
}
certPem, err := client.Sign(cr.Spec.CSRPEM, duration, customFields)
// Check some known error types
if err != nil {
switch err.(type) {
case venafiinternal.ErrCustomFieldsType:
v.reporter.Failed(cr, err, "CustomFieldsError", err.Error())
log.Error(err, err.Error())
return nil, nil
case endpoint.ErrCertificatePending:
message := "Venafi certificate still in a pending state, the request will be retried"

View File

@ -43,6 +43,7 @@ import (
controllertest "github.com/jetstack/cert-manager/pkg/controller/test"
testpkg "github.com/jetstack/cert-manager/pkg/controller/test"
internalvenafi "github.com/jetstack/cert-manager/pkg/internal/venafi"
internalvanafiapi "github.com/jetstack/cert-manager/pkg/internal/venafi/api"
internalvenafifake "github.com/jetstack/cert-manager/pkg/internal/venafi/fake"
"github.com/jetstack/cert-manager/pkg/util/pki"
"github.com/jetstack/cert-manager/test/unit/gen"
@ -146,6 +147,12 @@ func TestSign(t *testing.T) {
}),
)
tppCRWithCustomFields := gen.CertificateRequestFrom(tppCR, gen.SetCertificateRequestAnnotations(map[string]string{"venafi.cert-manager.io/custom-fields": `[{"name": "cert-manager-test", "value": "test ok"}]`}))
tppCRWithInvalidCustomFields := gen.CertificateRequestFrom(tppCR, gen.SetCertificateRequestAnnotations(map[string]string{"venafi.cert-manager.io/custom-fields": `[{"name": cert-manager-test}]`}))
tppCRWithInvalidCustomFieldType := gen.CertificateRequestFrom(tppCR, gen.SetCertificateRequestAnnotations(map[string]string{"venafi.cert-manager.io/custom-fields": `[{"name": "cert-manager-test", "value": "test ok", "type": "Bool"}]`}))
cloudCR := gen.CertificateRequestFrom(baseCR,
gen.SetCertificateRequestIssuer(cmmeta.ObjectReference{
Group: certmanager.GroupName,
@ -177,7 +184,7 @@ func TestSign(t *testing.T) {
}
clientReturnsPending := &internalvenafifake.Venafi{
SignFn: func([]byte, time.Duration) ([]byte, error) {
SignFn: func([]byte, time.Duration, []internalvanafiapi.CustomField) ([]byte, error) {
return nil, endpoint.ErrCertificatePending{
CertificateID: "test-cert-id",
Status: "test-status-pending",
@ -185,23 +192,38 @@ func TestSign(t *testing.T) {
},
}
clientReturnsTimeout := &internalvenafifake.Venafi{
SignFn: func([]byte, time.Duration) ([]byte, error) {
SignFn: func([]byte, time.Duration, []internalvanafiapi.CustomField) ([]byte, error) {
return nil, endpoint.ErrRetrieveCertificateTimeout{
CertificateID: "test-cert-id",
}
},
}
clientReturnsGenericError := &internalvenafifake.Venafi{
SignFn: func([]byte, time.Duration) ([]byte, error) {
SignFn: func([]byte, time.Duration, []internalvanafiapi.CustomField) ([]byte, error) {
return nil, errors.New("this is an error")
},
}
clientReturnsCert := &internalvenafifake.Venafi{
SignFn: func([]byte, time.Duration) ([]byte, error) {
SignFn: func([]byte, time.Duration, []internalvanafiapi.CustomField) ([]byte, error) {
return certPEM, nil
},
}
clientReturnsCertIfCustomField := &internalvenafifake.Venafi{
SignFn: func(csr []byte, t time.Duration, fields []internalvanafiapi.CustomField) ([]byte, error) {
if len(fields) > 0 && fields[0].Name == "cert-manager-test" && fields[0].Value == "test ok" {
return certPEM, nil
}
return nil, errors.New("Custom field not set")
},
}
clientReturnsInvalidCustomFieldType := &internalvenafifake.Venafi{
SignFn: func(csr []byte, t time.Duration, fields []internalvanafiapi.CustomField) ([]byte, error) {
return nil, internalvenafi.ErrCustomFieldsType{Type: fields[0].Type}
},
}
metaFixedClockStart := metav1.NewTime(fixedClockStart)
tests := map[string]testT{
"tpp: if fail to build client based on missing secret then return nil and hard fail": {
@ -573,6 +595,96 @@ func TestSign(t *testing.T) {
fakeSecretLister: failGetSecretLister,
fakeClient: clientReturnsCert,
},
"annotations: Custom Fields": {
certificateRequest: tppCRWithCustomFields.DeepCopy(),
issuer: tppIssuer,
builder: &controllertest.Builder{
CertManagerObjects: []runtime.Object{tppCRWithCustomFields.DeepCopy(), tppIssuer.DeepCopy()},
ExpectedEvents: []string{
`Normal CertificateIssued Certificate fetched from issuer successfully`,
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewUpdateSubresourceAction(
cmapi.SchemeGroupVersion.WithResource("certificaterequests"),
"status",
gen.DefaultTestNamespace,
gen.CertificateRequestFrom(tppCRWithCustomFields,
gen.SetCertificateRequestStatusCondition(cmapi.CertificateRequestCondition{
Type: cmapi.CertificateRequestConditionReady,
Status: cmmeta.ConditionTrue,
Reason: cmapi.CertificateRequestReasonIssued,
Message: "Certificate fetched from issuer successfully",
LastTransitionTime: &metaFixedClockStart,
}),
gen.SetCertificateRequestCertificate(certPEM),
),
)),
},
},
fakeSecretLister: failGetSecretLister,
fakeClient: clientReturnsCertIfCustomField,
expectedErr: false,
},
"annotations: Error on invalid JSON in custom fields": {
certificateRequest: tppCRWithInvalidCustomFields.DeepCopy(),
issuer: tppIssuer,
builder: &controllertest.Builder{
CertManagerObjects: []runtime.Object{tppCRWithInvalidCustomFields.DeepCopy(), tppIssuer.DeepCopy()},
ExpectedEvents: []string{
`Warning CustomFieldsError Failed to parse "venafi.cert-manager.io/custom-fields" annotation: invalid character 'c' looking for beginning of value`,
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewUpdateSubresourceAction(
cmapi.SchemeGroupVersion.WithResource("certificaterequests"),
"status",
gen.DefaultTestNamespace,
gen.CertificateRequestFrom(tppCRWithInvalidCustomFields,
gen.SetCertificateRequestStatusCondition(cmapi.CertificateRequestCondition{
Type: cmapi.CertificateRequestConditionReady,
Status: cmmeta.ConditionFalse,
Reason: cmapi.CertificateRequestReasonFailed,
Message: "Failed to parse \"venafi.cert-manager.io/custom-fields\" annotation: invalid character 'c' looking for beginning of value",
LastTransitionTime: &metaFixedClockStart,
}),
gen.SetCertificateRequestFailureTime(metaFixedClockStart),
),
)),
},
},
fakeSecretLister: failGetSecretLister,
fakeClient: clientReturnsPending,
expectedErr: false,
},
"annotations: Error on invalid type in custom fields": {
certificateRequest: tppCRWithInvalidCustomFieldType.DeepCopy(),
issuer: tppIssuer,
builder: &controllertest.Builder{
CertManagerObjects: []runtime.Object{tppCRWithInvalidCustomFieldType.DeepCopy(), tppIssuer.DeepCopy()},
ExpectedEvents: []string{
`Warning CustomFieldsError certificate request contains an invalid Venafi custom fields type: "Bool": certificate request contains an invalid Venafi custom fields type: "Bool"`,
},
ExpectedActions: []testpkg.Action{
testpkg.NewAction(coretesting.NewUpdateSubresourceAction(
cmapi.SchemeGroupVersion.WithResource("certificaterequests"),
"status",
gen.DefaultTestNamespace,
gen.CertificateRequestFrom(tppCRWithInvalidCustomFieldType,
gen.SetCertificateRequestStatusCondition(cmapi.CertificateRequestCondition{
Type: cmapi.CertificateRequestConditionReady,
Status: cmmeta.ConditionFalse,
Reason: cmapi.CertificateRequestReasonFailed,
Message: "certificate request contains an invalid Venafi custom fields type: \"Bool\": certificate request contains an invalid Venafi custom fields type: \"Bool\"",
LastTransitionTime: &metaFixedClockStart,
}),
gen.SetCertificateRequestFailureTime(metaFixedClockStart),
),
)),
},
},
fakeSecretLister: failGetSecretLister,
fakeClient: clientReturnsInvalidCustomFieldType,
expectedErr: false,
},
}
for name, test := range tests {

View File

@ -10,6 +10,7 @@ go_library(
visibility = ["//pkg:__subpackages__"],
deps = [
"//pkg/apis/certmanager/v1alpha2:go_default_library",
"//pkg/internal/venafi/api:go_default_library",
"//pkg/util/pki:go_default_library",
"@com_github_venafi_vcert//:go_default_library",
"@com_github_venafi_vcert//pkg/certificate:go_default_library",
@ -29,6 +30,7 @@ filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//pkg/internal/venafi/api:all-srcs",
"//pkg/internal/venafi/fake:all-srcs",
],
tags = ["automanaged"],
@ -45,6 +47,7 @@ go_test(
deps = [
"//pkg/apis/certmanager/v1alpha2:go_default_library",
"//pkg/apis/meta/v1:go_default_library",
"//pkg/internal/venafi/api:go_default_library",
"//pkg/internal/venafi/fake:go_default_library",
"//pkg/util:go_default_library",
"//pkg/util/pki:go_default_library",

View File

@ -0,0 +1,22 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
go_library(
name = "go_default_library",
srcs = ["api.go"],
importpath = "github.com/jetstack/cert-manager/pkg/internal/venafi/api",
visibility = ["//pkg:__subpackages__"],
)

View File

@ -0,0 +1,30 @@
/*
Copyright 2020 The Jetstack cert-manager contributors.
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 api
type CustomFieldType string
const (
CustomFieldTypePlain CustomFieldType = "Plain"
)
// CustomField defines a custom field to be passed to Venafi
type CustomField struct {
Type CustomFieldType `json:"type,omitempty"`
Name string `json:"name"`
Value string `json:"value"`
}

View File

@ -9,6 +9,7 @@ go_library(
importpath = "github.com/jetstack/cert-manager/pkg/internal/venafi/fake",
visibility = ["//pkg:__subpackages__"],
deps = [
"//pkg/internal/venafi/api:go_default_library",
"@com_github_venafi_vcert//pkg/certificate:go_default_library",
"@com_github_venafi_vcert//pkg/endpoint:go_default_library",
"@com_github_venafi_vcert//pkg/venafi/fake:go_default_library",

View File

@ -20,11 +20,13 @@ import (
"time"
"github.com/Venafi/vcert/pkg/endpoint"
internalvanafiapi "github.com/jetstack/cert-manager/pkg/internal/venafi/api"
)
type Venafi struct {
PingFn func() error
SignFn func([]byte, time.Duration) ([]byte, error)
SignFn func([]byte, time.Duration, []internalvanafiapi.CustomField) ([]byte, error)
ReadZoneConfigurationFn func() (*endpoint.ZoneConfiguration, error)
}
@ -32,8 +34,8 @@ func (v *Venafi) Ping() error {
return v.PingFn()
}
func (v *Venafi) Sign(b []byte, t time.Duration) ([]byte, error) {
return v.SignFn(b, t)
func (v *Venafi) Sign(b []byte, t time.Duration, f []internalvanafiapi.CustomField) ([]byte, error) {
return v.SignFn(b, t, f)
}
func (v *Venafi) ReadZoneConfiguration() (*endpoint.ZoneConfiguration, error) {

View File

@ -19,18 +19,29 @@ package venafi
import (
"crypto/x509"
"errors"
"fmt"
"strings"
"time"
"github.com/Venafi/vcert/pkg/certificate"
internalvanafiapi "github.com/jetstack/cert-manager/pkg/internal/venafi/api"
"github.com/jetstack/cert-manager/pkg/util/pki"
)
// ErrCustomFieldsType provides a common error structure for a fivalid custom field types
type ErrCustomFieldsType struct {
Type internalvanafiapi.CustomFieldType
}
func (err ErrCustomFieldsType) Error() string {
return fmt.Sprintf("certificate request contains an invalid Venafi custom fields type: %q", err.Type)
}
// This function sends a request to Venafi to for a signed certificate.
// The CSR will be decoded to be validated against the zone configuration policy.
// Upon the template being successfully defaulted and validated, the CSR will be sent, as is.
func (v *Venafi) Sign(csrPEM []byte, duration time.Duration) (cert []byte, err error) {
func (v *Venafi) Sign(csrPEM []byte, duration time.Duration, customFields []internalvanafiapi.CustomField) (cert []byte, err error) {
// Retrieve a copy of the Venafi zone.
// This contains default values and policy control info that we can apply
// and check against locally.
@ -47,6 +58,30 @@ func (v *Venafi) Sign(csrPEM []byte, duration time.Duration) (cert []byte, err e
// Create a vcert Request structure
vreq := newVRequest(tmpl)
// Convert over custom fields from our struct type to venafi's
if len(customFields) > 0 {
vreq.CustomFields = []certificate.CustomField{}
for _, field := range customFields {
var fieldType certificate.CustomFieldType
switch field.Type {
case internalvanafiapi.CustomFieldTypePlain:
fieldType = certificate.CustomFieldPlain
break
case "":
fieldType = certificate.CustomFieldPlain
break
default:
return nil, ErrCustomFieldsType{Type: field.Type}
}
vreq.CustomFields = append(vreq.CustomFields, certificate.CustomField{
Type: fieldType,
Name: field.Name,
Value: field.Value,
})
}
}
// Apply default values from the Venafi zone
zoneCfg.UpdateCertificateRequest(vreq)

View File

@ -30,6 +30,7 @@ import (
"github.com/Venafi/vcert/pkg/endpoint"
"github.com/Venafi/vcert/pkg/venafi/fake"
internalvanafiapi "github.com/jetstack/cert-manager/pkg/internal/venafi/api"
internalfake "github.com/jetstack/cert-manager/pkg/internal/venafi/fake"
"github.com/jetstack/cert-manager/pkg/util"
"github.com/jetstack/cert-manager/pkg/util/pki"
@ -173,6 +174,29 @@ func TestSign(t *testing.T) {
checkFn: checkCertificateIssued,
expectedErr: false,
},
"obtain a certificate with custom fields specified": {
csrPEM: csrPEM,
customFields: []internalvanafiapi.CustomField{{Name: "test", Value: "ok"}},
client: internalfake.Connector{
RetrieveCertificateFunc: func(r *certificate.Request) (*certificate.PEMCollection, error) {
if len(r.CustomFields) == 0 {
return nil, errors.New("custom fields not set")
}
if r.CustomFields[0].Name != "test" || r.CustomFields[0].Value != "ok" {
return nil, errors.New("custom fields content not correct")
}
return internalfake.Connector{}.Default().RetrieveCertificate(r) // hack to return to normal
},
}.Default(),
checkFn: checkCertificateIssued,
expectedErr: false,
},
"If invalid custom field type found the error": {
csrPEM: csrPEM,
customFields: []internalvanafiapi.CustomField{{Name: "test", Value: "ok", Type: "Bool"}},
checkFn: checkNoCetificateIssued,
expectedErr: true,
},
}
for name, test := range tests {
@ -188,6 +212,8 @@ type testSignT struct {
expectedErr bool
customFields []internalvanafiapi.CustomField
checkFn func(*testing.T, []byte, []byte)
}
@ -201,7 +227,7 @@ func (s *testSignT) runTest(t *testing.T) {
client: client,
}
resp, err := v.Sign(s.csrPEM, time.Minute)
resp, err := v.Sign(s.csrPEM, time.Minute, s.customFields)
if err != nil && !s.expectedErr {
t.Errorf("expected to not get an error, but got: %v", err)
}

View File

@ -26,6 +26,7 @@ import (
corelisters "k8s.io/client-go/listers/core/v1"
cmapi "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1alpha2"
internalvanafiapi "github.com/jetstack/cert-manager/pkg/internal/venafi/api"
)
const (
@ -39,7 +40,7 @@ type VenafiClientBuilder func(namespace string, secretsLister corelisters.Secret
issuer cmapi.GenericIssuer) (Interface, error)
type Interface interface {
Sign(csrPEM []byte, duration time.Duration) (cert []byte, err error)
Sign(csrPEM []byte, duration time.Duration, customFields []internalvanafiapi.CustomField) (cert []byte, err error)
Ping() error
ReadZoneConfiguration() (*endpoint.ZoneConfiguration, error)
SetClient(endpoint.Connector)