-
Notifications
You must be signed in to change notification settings - Fork 786
/
cert-manager.go
149 lines (135 loc) · 5.77 KB
/
cert-manager.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package pki
import (
"github.com/jenkins-x/jx/pkg/kube"
"github.com/jenkins-x/jx/pkg/log"
"github.com/jenkins-x/jx/pkg/util"
certmng "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1alpha1"
certclient "github.com/jetstack/cert-manager/pkg/client/clientset/versioned"
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
// CertManagerNamespace indicates the namespace where is cert-manager deployed
CertManagerNamespace = "cert-manager"
// CertManagerDeployment indicates the name of the cert-manager deployment
CertManagerDeployment = "cert-manager"
// CertManagerReleaseName indicates the release name for cert-manager chart
CertManagerReleaseName = "cert-manager"
// CertManagerChart name of the cert-manager chart
CertManagerChart = "stable/cert-manager"
// CertManagerCRDsFile files which contains the cert-manager CRDs
CertManagerCRDsFile = "https://raw.githubusercontent.com/jetstack/cert-manager/release-0.6/deploy/manifests/00-crds.yaml"
// CertManagerIssuerProd name of the production issuer
CertManagerIssuerProd = "letsencrypt-prod"
certManagerIssuerProdServer = "https://acme-v02.api.letsencrypt.org/directory"
// CertManagerIssuerStaging name of the staging issuer
CertManagerIssuerStaging = "letsencrypt-staging"
certManagerIssuerStagingServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
)
// CleanCertManagerResources removed the cert-manager resoruces from the given namespaces
func CleanCertManagerResources(certclient certclient.Interface, ns string, ic kube.IngressConfig) error {
if ic.Issuer == CertManagerIssuerProd {
_, err := certclient.Certmanager().Issuers(ns).Get(CertManagerIssuerProd, metav1.GetOptions{})
if err == nil {
err := certclient.Certmanager().Issuers(ns).Delete(CertManagerIssuerProd, &metav1.DeleteOptions{})
if err != nil {
return errors.Wrapf(err, "deleting cert-manager issuer %q", CertManagerIssuerProd)
}
}
_ = certclient.Certmanager().Certificates(ns).Delete(CertManagerIssuerProd, &metav1.DeleteOptions{})
} else {
_, err := certclient.Certmanager().Issuers(ns).Get(CertManagerIssuerStaging, metav1.GetOptions{})
if err == nil {
err := certclient.Certmanager().Issuers(ns).Delete(CertManagerIssuerStaging, &metav1.DeleteOptions{})
if err != nil {
return errors.Wrapf(err, "deleting cert-manager issuer %q", CertManagerIssuerStaging)
}
}
_ = certclient.Certmanager().Certificates(ns).Delete(CertManagerIssuerStaging, &metav1.DeleteOptions{})
}
return nil
}
// CreateIssuer creates a cert-manager issuer according with the ingress configuration
func CreateIssuer(certclient certclient.Interface, ns string, ic kube.IngressConfig) error {
if ic.Issuer == CertManagerIssuerProd {
_, err := certclient.Certmanager().Issuers(ns).Get(CertManagerIssuerProd, metav1.GetOptions{})
if err != nil {
_, err := certclient.Certmanager().Issuers(ns).Create(
issuer(CertManagerIssuerProd, certManagerIssuerProdServer, ic.Email))
if err != nil {
return errors.Wrapf(err, "creating cert-manager issuer %q", CertManagerIssuerProd)
}
}
} else {
_, err := certclient.Certmanager().Issuers(ns).Get(CertManagerIssuerStaging, metav1.GetOptions{})
if err != nil {
_, err := certclient.Certmanager().Issuers(ns).Create(
issuer(CertManagerIssuerStaging, certManagerIssuerStagingServer, ic.Email))
if err != nil {
return errors.Wrapf(err, "creating cert-manager issuer %q", CertManagerIssuerStaging)
}
}
}
return nil
}
func issuer(name string, server string, email string) *certmng.Issuer {
return &certmng.Issuer{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: certmng.IssuerSpec{
IssuerConfig: certmng.IssuerConfig{
ACME: &certmng.ACMEIssuer{
Email: email,
Server: server,
SkipTLSVerify: false,
PrivateKey: certmng.SecretKeySelector{
LocalObjectReference: certmng.LocalObjectReference{
Name: name,
},
},
HTTP01: &certmng.ACMEIssuerHTTP01Config{},
},
},
},
}
}
// CreateCertManagerResources creates the cert-manager resources such as issuer in the target namespace
func CreateCertManagerResources(certclient certclient.Interface, targetNamespace string, ic kube.IngressConfig) error {
if !ic.TLS {
return nil
}
// do not recreate the issuer if it is already there and correctly configured
if alreadyConfigured(certclient, targetNamespace, ic) {
return nil
}
err := CleanCertManagerResources(certclient, targetNamespace, ic)
if err != nil {
return errors.Wrapf(err, "cleaning the cert-manager resources from namespace %q", targetNamespace)
}
err = CreateIssuer(certclient, targetNamespace, ic)
if err != nil {
return errors.Wrapf(err, "creating the cert-manager issuer %s/%s", targetNamespace, ic.Issuer)
}
return nil
}
// alreadyConfigured checks if cert-manager resources are already configured and match with the ingress configuration
func alreadyConfigured(certClient certclient.Interface, targetNamespace string, ingressConfig kube.IngressConfig) bool {
issuer, err := certClient.CertmanagerV1alpha1().Issuers(targetNamespace).Get(ingressConfig.Issuer, metav1.GetOptions{})
if err != nil {
log.Infof("Certificate issuer %s does not exist. Creating...\n", util.ColorInfo(ingressConfig.Issuer))
return false
}
// ingress and issuer email must match
if issuer.Spec.ACME.Email != ingressConfig.Email {
issuer.Spec.ACME.Email = ingressConfig.Email
_, err := certClient.CertmanagerV1alpha1().Issuers(targetNamespace).Update(issuer)
if err != nil {
// can not update the issuer, let's assume it needs recreation
log.Infof("Certificate issuer %s can not be updated. Recreating...\n", util.ColorInfo(ingressConfig.Issuer))
return false
}
}
log.Infof("Certificate issuer %s already configured.\n", util.ColorInfo(ingressConfig.Issuer))
return true
}