Skip to content

Commit

Permalink
Merge pull request #190 from munnerz/automated-cherry-pick-of-#185-up…
Browse files Browse the repository at this point in the history
…stream-release-0.2

Automatic merge from submit-queue.

Automated cherry pick of #185

Cherry pick of #185 on release-0.2.

#185: Add solverFor and wait.go unit tests for acme dns solver

```release-note
NONE
```
  • Loading branch information
jetstack-bot committed Nov 4, 2017
2 parents 1deb5b9 + 08311cb commit 83a6e13
Show file tree
Hide file tree
Showing 3 changed files with 449 additions and 0 deletions.
278 changes: 278 additions & 0 deletions pkg/issuer/acme/dns/dns_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
package dns

import (
"reflect"
"testing"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
kubeinformers "k8s.io/client-go/informers"
kubefake "k8s.io/client-go/kubernetes/fake"

"github.com/jetstack/cert-manager/pkg/apis/certmanager/v1alpha1"
"github.com/jetstack/cert-manager/pkg/issuer/acme/dns/cloudflare"
)

type fixture struct {
// Issuer resource this solver is for
Issuer v1alpha1.GenericIssuer

// Objects here are pre-loaded into the fake client
KubeObjects []runtime.Object

// Secret objects to store in the fake lister
SecretLister []*corev1.Secret

// the resourceNamespace to set on the solver
ResourceNamespace string

// certificate used in the test
Certificate *v1alpha1.Certificate
}

func (f *fixture) solver() *Solver {
kubeClient := kubefake.NewSimpleClientset(f.KubeObjects...)
sharedInformerFactory := kubeinformers.NewSharedInformerFactory(kubeClient, 0)
secretsLister := sharedInformerFactory.Core().V1().Secrets().Lister()
for _, s := range f.SecretLister {
sharedInformerFactory.Core().V1().Secrets().Informer().GetIndexer().Add(s)
}
stopCh := make(chan struct{})
defer close(stopCh)
sharedInformerFactory.Start(stopCh)
return &Solver{
issuer: f.Issuer,
client: kubeClient,
secretLister: secretsLister,
resourceNamespace: f.ResourceNamespace,
}
}

func newIssuer(name, namespace string, configs []v1alpha1.ACMEIssuerDNS01Provider) *v1alpha1.Issuer {
return &v1alpha1.Issuer{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Spec: v1alpha1.IssuerSpec{
IssuerConfig: v1alpha1.IssuerConfig{
ACME: &v1alpha1.ACMEIssuer{
DNS01: &v1alpha1.ACMEIssuerDNS01Config{
Providers: configs,
},
},
},
},
}
}

func newCertificate(name, namespace, cn string, dnsNames []string, configs []v1alpha1.ACMECertificateDomainConfig) *v1alpha1.Certificate {
return &v1alpha1.Certificate{
Spec: v1alpha1.CertificateSpec{
CommonName: cn,
DNSNames: dnsNames,
ACME: &v1alpha1.ACMECertificateConfig{
Config: configs,
},
},
}
}

func newSecret(name, namespace string, data map[string][]byte) *corev1.Secret {
return &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Data: data,
}
}

func TestSolverFor(t *testing.T) {
type testT struct {
f *fixture
domain string
expectErr bool
expectedSolverType reflect.Type
}
tests := map[string]testT{
"loads secret for cloudflare provider": {
f: &fixture{
Issuer: newIssuer("test", "default", []v1alpha1.ACMEIssuerDNS01Provider{
{
Name: "fake-cloudflare",
Cloudflare: &v1alpha1.ACMEIssuerDNS01ProviderCloudflare{
Email: "test",
APIKey: v1alpha1.SecretKeySelector{
LocalObjectReference: v1alpha1.LocalObjectReference{
Name: "cloudflare-key",
},
Key: "api-key",
},
},
},
}),
SecretLister: []*corev1.Secret{newSecret("cloudflare-key", "default", map[string][]byte{
"api-key": []byte("a-cloudflare-api-key"),
})},
ResourceNamespace: "default",
Certificate: newCertificate("test", "default", "example.com", nil, []v1alpha1.ACMECertificateDomainConfig{
{
Domains: []string{"example.com"},
DNS01: &v1alpha1.ACMECertificateDNS01Config{
Provider: "fake-cloudflare",
},
},
}),
},
domain: "example.com",
expectedSolverType: reflect.TypeOf(&cloudflare.DNSProvider{}),
},
"fails to load a cloudflare provider with a missing secret": {
f: &fixture{
Issuer: newIssuer("test", "default", []v1alpha1.ACMEIssuerDNS01Provider{
{
Name: "fake-cloudflare",
Cloudflare: &v1alpha1.ACMEIssuerDNS01ProviderCloudflare{
Email: "test",
APIKey: v1alpha1.SecretKeySelector{
LocalObjectReference: v1alpha1.LocalObjectReference{
Name: "cloudflare-key",
},
Key: "api-key",
},
},
},
}),
// don't include any secrets in the lister
SecretLister: []*corev1.Secret{},
ResourceNamespace: "default",
Certificate: newCertificate("test", "default", "example.com", nil, []v1alpha1.ACMECertificateDomainConfig{
{
Domains: []string{"example.com"},
DNS01: &v1alpha1.ACMECertificateDNS01Config{
Provider: "fake-cloudflare",
},
},
}),
},
domain: "example.com",
expectErr: true,
},
"fails to load a cloudflare provider with an invalid secret": {
f: &fixture{
Issuer: newIssuer("test", "default", []v1alpha1.ACMEIssuerDNS01Provider{
{
Name: "fake-cloudflare",
Cloudflare: &v1alpha1.ACMEIssuerDNS01ProviderCloudflare{
Email: "test",
APIKey: v1alpha1.SecretKeySelector{
LocalObjectReference: v1alpha1.LocalObjectReference{
Name: "cloudflare-key",
},
Key: "api-key",
},
},
},
}),
SecretLister: []*corev1.Secret{newSecret("cloudflare-key", "default", map[string][]byte{
"api-key-oops": []byte("a-cloudflare-api-key"),
})},
ResourceNamespace: "default",
Certificate: newCertificate("test", "default", "example.com", nil, []v1alpha1.ACMECertificateDomainConfig{
{
Domains: []string{"example.com"},
DNS01: &v1alpha1.ACMECertificateDNS01Config{
Provider: "fake-cloudflare",
},
},
}),
},
domain: "example.com",
expectErr: true,
},
"fails to load a provider with no config set for the domain": {
f: &fixture{
Issuer: newIssuer("test", "default", []v1alpha1.ACMEIssuerDNS01Provider{
{
Name: "fake-cloudflare",
Cloudflare: &v1alpha1.ACMEIssuerDNS01ProviderCloudflare{
Email: "test",
APIKey: v1alpha1.SecretKeySelector{
LocalObjectReference: v1alpha1.LocalObjectReference{
Name: "cloudflare-key",
},
Key: "api-key",
},
},
},
}),
SecretLister: []*corev1.Secret{newSecret("cloudflare-key", "default", map[string][]byte{
"api-key": []byte("a-cloudflare-api-key"),
})},
ResourceNamespace: "default",
Certificate: newCertificate("test", "default", "example.com", nil, []v1alpha1.ACMECertificateDomainConfig{
{
Domains: []string{"example-oops.com"},
DNS01: &v1alpha1.ACMECertificateDNS01Config{
Provider: "fake-cloudflare",
},
},
}),
},
domain: "example.com",
expectErr: true,
},
"fails to load a provider with a non-existent provider set for the domain": {
f: &fixture{
Issuer: newIssuer("test", "default", []v1alpha1.ACMEIssuerDNS01Provider{
{
Name: "fake-cloudflare",
Cloudflare: &v1alpha1.ACMEIssuerDNS01ProviderCloudflare{
Email: "test",
APIKey: v1alpha1.SecretKeySelector{
LocalObjectReference: v1alpha1.LocalObjectReference{
Name: "cloudflare-key",
},
Key: "api-key",
},
},
},
}),
SecretLister: []*corev1.Secret{newSecret("cloudflare-key", "default", map[string][]byte{
"api-key": []byte("a-cloudflare-api-key"),
})},
ResourceNamespace: "default",
Certificate: newCertificate("test", "default", "example.com", nil, []v1alpha1.ACMECertificateDomainConfig{
{
Domains: []string{"example.com"},
DNS01: &v1alpha1.ACMECertificateDNS01Config{
Provider: "fake-cloudflare-oops",
},
},
}),
},
domain: "example.com",
expectErr: true,
},
}
testFn := func(test testT) func(*testing.T) {
return func(t *testing.T) {
s := test.f.solver()
dnsSolver, err := s.solverFor(test.f.Certificate, test.domain)
if err != nil && !test.expectErr {
t.Errorf("expected solverFor to not error, but got: %s", err.Error())
return
}
typeOfSolver := reflect.TypeOf(dnsSolver)
if typeOfSolver != test.expectedSolverType {
t.Errorf("expected solver of type %q but got one of type %q", test.expectedSolverType, typeOfSolver)
return
}
}
}
for name, test := range tests {
t.Run(name, testFn(test))
}
}
5 changes: 5 additions & 0 deletions pkg/issuer/acme/dns/util/testdata/resolv.conf.1
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
domain company.com
nameserver 10.200.3.249
nameserver 10.200.3.250:5353
nameserver 2001:4860:4860::8844
nameserver [10.0.0.1]:5353

0 comments on commit 83a6e13

Please sign in to comment.