Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions pkg/cert-generator/v1beta1/consts/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ limitations under the License.
package consts

const (
CAName = "katib-ca"
Service = "katib-controller"
JobName = "katib-cert-generator"
Secret = "katib-webhook-cert"
Webhook = "katib.kubeflow.org"
Katib = "katib"
)
83 changes: 21 additions & 62 deletions pkg/cert-generator/v1beta1/generate/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import (
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"math/big"
"strings"
"time"

"github.com/kubeflow/katib/pkg/cert-generator/v1beta1/consts"
"github.com/spf13/cobra"
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
Expand All @@ -30,10 +34,7 @@ import (
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog"
"math/big"
"sigs.k8s.io/controller-runtime/pkg/client"
"strings"
"time"
)

// generateOptions contains values for all certificates.
Expand Down Expand Up @@ -76,94 +77,54 @@ func (o *generateOptions) run(ctx context.Context, kubeClient client.Client) err

o.fullServiceDomain = strings.Join([]string{o.serviceName, o.namespace, "svc"}, ".")

caKeyPair, err := o.createCACert()
if err != nil {
return err
}
keyPair, err := o.createCert(caKeyPair)
keyPair, err := o.createCert()
if err != nil {
return err
}

if err = o.createWebhookCertSecret(ctx, kubeClient, caKeyPair, keyPair); err != nil {
if err = o.createWebhookCertSecret(ctx, kubeClient, keyPair); err != nil {
return err
}
if err = o.injectCert(ctx, kubeClient, caKeyPair); err != nil {
if err = o.injectCert(ctx, kubeClient, keyPair); err != nil {
return err
}

return nil
}

// createCACert creates the self-signed CA certificate and private key.
func (o *generateOptions) createCACert() (*certificates, error) {
// createCert creates the self-signed certificate and private key.
func (o *generateOptions) createCert() (*certificates, error) {
now := time.Now()
template := &x509.Certificate{
SerialNumber: big.NewInt(0),
Subject: pkix.Name{
CommonName: consts.CAName,
Organization: []string{consts.Katib},
},
DNSNames: []string{
consts.CAName,
},
NotBefore: now,
NotAfter: now.Add(24 * time.Hour * 365 * 10),
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign,
BasicConstraintsValid: true,
IsCA: true,
}

klog.Info("Generating the self-signed CA certificate and private key.")
rawKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, err
}

der, err := x509.CreateCertificate(rand.Reader, template, template, rawKey.Public(), rawKey)
if err != nil {
return nil, err
}

return encode(rawKey, der)
}

// createCert creates public certificate and private key signed with self-signed CA certificate and private key.
func (o *generateOptions) createCert(caKeyPair *certificates) (*certificates, error) {
now := time.Now()
template := &x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
CommonName: o.fullServiceDomain,
},
DNSNames: []string{
o.serviceName,
strings.Join([]string{o.serviceName, o.namespace}, "."),
o.fullServiceDomain,
},
NotBefore: now,
NotAfter: now.Add(24 * time.Hour * 365 * 10),
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: false,
NotBefore: now,
NotAfter: now.Add(24 * time.Hour * 365 * 10),
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
}

klog.Info("Generating public certificate and private key signed with self-singed CA cert and private key.")
klog.Info("Generating self-signed public certificate and private key.")
rawKey, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return nil, err
}

der, err := x509.CreateCertificate(rand.Reader, template, caKeyPair.cert, rawKey.Public(), caKeyPair.key)
der, err := x509.CreateCertificate(rand.Reader, template, template, rawKey.Public(), rawKey)
if err != nil {
return nil, err
}

return encode(rawKey, der)
}

// createWebhookCertSecret creates Secret embedded ca.key, ca.crt, tls.key and tls.crt.
func (o *generateOptions) createWebhookCertSecret(ctx context.Context, kubeClient client.Client, caKeyPair *certificates, keyPair *certificates) error {
// createWebhookCertSecret creates Secret embedded tls.key and tls.crt.
func (o *generateOptions) createWebhookCertSecret(ctx context.Context, kubeClient client.Client, keyPair *certificates) error {

certGeneratorJob := &batchv1.Job{}
if err := kubeClient.Get(ctx, client.ObjectKey{Namespace: o.namespace, Name: o.jobName}, certGeneratorJob); err != nil {
Expand Down Expand Up @@ -194,8 +155,6 @@ func (o *generateOptions) createWebhookCertSecret(ctx context.Context, kubeClien
},
Type: corev1.SecretTypeTLS,
Data: map[string][]byte{
"ca.key": caKeyPair.keyPem,
"ca.crt": caKeyPair.certPem,
"tls.key": keyPair.keyPem,
"tls.crt": keyPair.certPem,
},
Expand All @@ -221,13 +180,13 @@ func (o *generateOptions) createWebhookCertSecret(ctx context.Context, kubeClien
}

// injectCert applies patch to ValidatingWebhookConfiguration and MutatingWebhookConfiguration.
func (o *generateOptions) injectCert(ctx context.Context, kubeClient client.Client, caKeypair *certificates) error {
func (o *generateOptions) injectCert(ctx context.Context, kubeClient client.Client, keyPair *certificates) error {
validatingConf := &admissionregistrationv1.ValidatingWebhookConfiguration{}
if err := kubeClient.Get(ctx, client.ObjectKey{Name: consts.Webhook}, validatingConf); err != nil {
return err
}
newValidatingConf := validatingConf.DeepCopy()
newValidatingConf.Webhooks[0].ClientConfig.CABundle = caKeypair.certPem
newValidatingConf.Webhooks[0].ClientConfig.CABundle = keyPair.certPem

klog.Info("Trying to patch ValidatingWebhookConfiguration adding the caBundle.")
if err := kubeClient.Patch(ctx, newValidatingConf, client.MergeFrom(validatingConf)); err != nil {
Expand All @@ -240,8 +199,8 @@ func (o *generateOptions) injectCert(ctx context.Context, kubeClient client.Clie
return err
}
newMutatingConf := mutatingConf.DeepCopy()
newMutatingConf.Webhooks[0].ClientConfig.CABundle = caKeypair.certPem
newMutatingConf.Webhooks[1].ClientConfig.CABundle = caKeypair.certPem
newMutatingConf.Webhooks[0].ClientConfig.CABundle = keyPair.certPem
newMutatingConf.Webhooks[1].ClientConfig.CABundle = keyPair.certPem

klog.Info("Trying to patch MutatingWebhookConfiguration adding the caBundle.")
if err := kubeClient.Patch(ctx, newMutatingConf, client.MergeFrom(mutatingConf)); err != nil {
Expand Down
7 changes: 4 additions & 3 deletions pkg/cert-generator/v1beta1/generate/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,18 @@ limitations under the License.
package generate

import (
"log"
"strings"
"testing"

"github.com/kubeflow/katib/pkg/cert-generator/v1beta1/consts"
admissionregistration "k8s.io/api/admissionregistration/v1"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/scheme"
"log"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"strings"
"testing"
)

func TestGenerate(t *testing.T) {
Expand Down