Skip to content

Commit 3bed366

Browse files
authored
Merge pull request #475 from kube-tarian/agent-ca-cert-issuer
Agent rest server intragated with mTLS certificate and certs vault update
2 parents dd53638 + 17389a8 commit 3bed366

File tree

11 files changed

+132
-176
lines changed

11 files changed

+132
-176
lines changed

capten/agent/gin-api-server/server.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ import (
99
"github.com/kube-tarian/kad/capten/agent/internal/config"
1010
)
1111

12-
var log = logging.NewLogger()
13-
14-
func StartRestServer(rpcapi api.ServerInterface, cfg *config.SericeConfig) {
12+
func StartRestServer(rpcapi api.ServerInterface, cfg *config.SericeConfig, log logging.Logger) error {
1513
r := gin.Default()
1614
api.RegisterHandlers(r, rpcapi)
1715

18-
r.Run(fmt.Sprintf("%s:%d", cfg.Host, cfg.RestPort))
16+
return r.RunTLS(fmt.Sprintf("%s:%d", cfg.Host, cfg.RestPort), cfg.CertFileName, cfg.KeyFileName)
1917
}

capten/agent/internal/app/app.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/kube-tarian/kad/capten/agent/internal/job"
1515
captenstore "github.com/kube-tarian/kad/capten/common-pkg/capten-store"
1616
"github.com/kube-tarian/kad/capten/common-pkg/crossplane"
17+
"github.com/kube-tarian/kad/capten/common-pkg/k8s"
1718
"github.com/kube-tarian/kad/capten/common-pkg/pb/agentpb"
1819
"github.com/kube-tarian/kad/capten/common-pkg/pb/captenpluginspb"
1920
"github.com/kube-tarian/kad/capten/common-pkg/pb/clusterpluginspb"
@@ -81,11 +82,17 @@ func Start() {
8182
}
8283
}()
8384

84-
err = setupCACertIssuser(cfg.ClusterCAIssuerName)
85+
err = k8s.SetupCACertIssuser(cfg.ClusterCAIssuerName, log)
8586
if err != nil {
8687
log.Fatalf("Failed to setupt CA Cert Issuer in cert-manager %v", err)
8788
}
88-
go ginapiserver.StartRestServer(rpcapi, cfg)
89+
90+
go func() {
91+
err := ginapiserver.StartRestServer(rpcapi, cfg, log)
92+
if err != nil {
93+
log.Errorf("Failed to start REST server, %v", err)
94+
}
95+
}()
8996

9097
err = registerK8SWatcher(as)
9198
if err != nil {

capten/agent/internal/app/ca_cert_issuer.go

Lines changed: 0 additions & 148 deletions
This file was deleted.

capten/agent/internal/config/config.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
type SericeConfig struct {
88
Host string `envconfig:"HOST" default:"0.0.0.0"`
99
Port int `envconfig:"PORT" default:"9091"`
10-
RestPort int `envconfig:"REST_PORT" default:"9092"`
10+
RestPort int `envconfig:"REST_PORT" default:"8443"`
1111
Mode string `envconfig:"MODE" default:"production"`
1212
AuthEnabled bool `envconfig:"AUTH_ENABLED" default:"false"`
1313
CrossplaneSyncJobEnabled bool `envconfig:"CROSSPLANE_SYNC_JOB_ENABLED" default:"true"`
@@ -16,6 +16,8 @@ type SericeConfig struct {
1616
TektonSyncJobInterval string `envconfig:"TEKTON_SYNC_JOB_INTERVAL" default:"@every 1h"`
1717
DomainName string `envconfig:"DOMAIN_NAME" default:"example.com"`
1818
ClusterCAIssuerName string `envconfig:"AGENT_CLUSTER_CA_ISSUER_NAME" default:"agent-ca-issuer"`
19+
CertFileName string `envconfig:"CERT_FILE_NAME" default:"/tmp/certs/tls.crt"`
20+
KeyFileName string `envconfig:"KEY_FILE_NAME" default:"/tmp/certs/tls.key"`
1921
}
2022

2123
func GetServiceConfig() (*SericeConfig, error) {

capten/common-pkg/cert/generate_certs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func GenerateRootCerts() (*CertificatesData, error) {
5151
}, nil
5252
}
5353

54-
func generateCACert() (*Key, *Cert, error) { //(rootKey *rsa.PrivateKey, rootCertTemplate *x509.Certificate, err error) {
54+
func generateCACert() (*Key, *Cert, error) {
5555
rootKey, err := rsa.GenerateKey(rand.Reader, caBitSize)
5656
if err != nil {
5757
err = errors.WithMessage(err, "failed to generate RSA key for root certificate")

capten/common-pkg/k8s/cert_issuer.go

Lines changed: 80 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package k8s
22

33
import (
44
"context"
5+
"fmt"
56

67
"github.com/intelops/go-common/logging"
78
"github.com/kube-tarian/kad/capten/common-pkg/cert"
9+
"github.com/kube-tarian/kad/capten/common-pkg/credential"
810
"github.com/pkg/errors"
911

1012
certmanagerv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
@@ -17,15 +19,52 @@ import (
1719

1820
var log = logging.NewLogger()
1921

20-
func CreateOrUpdateClusterIssuer(clusterCAIssuer string) error {
22+
func SetupCACertIssuser(clusterIssuerName string, log logging.Logger) error {
23+
k8sclient, err := NewK8SClient(log)
24+
if err != nil {
25+
log.Errorf("failed to initalize k8s client, %v", err)
26+
return err
27+
}
28+
29+
err = setupCertificateIssuer(k8sclient, clusterIssuerName, log)
30+
if err != nil {
31+
log.Errorf("Setup Certificates Issuer failed, %v", err)
32+
return err
33+
}
34+
return nil
35+
}
36+
37+
// Setup agent certificate issuer
38+
func setupCertificateIssuer(k8sClient *K8SClient, clusterIssuerName string, log logging.Logger) error {
39+
// Create Agent Cluster Issuer
40+
certsData, err := CreateOrUpdateClusterIssuer(clusterIssuerName, k8sClient, false)
41+
if err != nil {
42+
return fmt.Errorf("failed to create/update CA Issuer %s in cert-manager: %v", clusterIssuerName, err)
43+
}
44+
45+
// Update Vault
46+
err = credential.PutClusterCerts(context.TODO(), "kad-agent", "kad-agent", string(certsData.CaChainCertData), string(certsData.RootKey.KeyData), string(certsData.RootCert.CertData))
47+
if err != nil {
48+
log.Errorf("Failed to write to vault, %v", err)
49+
log.Infof("Continued to start the agent as these certs from vault are not used...")
50+
}
51+
return nil
52+
}
53+
54+
func CreateOrUpdateClusterIssuer(clusterCAIssuer string, k8sclient *K8SClient, forceUpdate bool) (*cert.CertificatesData, error) {
2155
config, err := rest.InClusterConfig()
2256
if err != nil {
23-
return errors.WithMessage(err, "error while building kubeconfig")
57+
return nil, errors.WithMessage(err, "error while building kubeconfig")
2458
}
2559

2660
cmClient, err := cmclient.NewForConfig(config)
2761
if err != nil {
28-
return err
62+
return nil, err
63+
}
64+
65+
certsData, err := cert.GenerateRootCerts()
66+
if err != nil {
67+
return nil, err
2968
}
3069

3170
issuer := &certmanagerv1.ClusterIssuer{
@@ -42,23 +81,48 @@ func CreateOrUpdateClusterIssuer(clusterCAIssuer string) error {
4281
}
4382

4483
serverIssuer, err := cmClient.CertmanagerV1().ClusterIssuers().Get(context.Background(), issuer.Name, metav1.GetOptions{})
45-
if err != nil && k8serrors.IsNotFound(err) {
46-
result, err := cmClient.CertmanagerV1().ClusterIssuers().Create(context.Background(), issuer, metav1.CreateOptions{})
47-
if err != nil {
48-
return errors.WithMessage(err, "error in creating cert issuer")
84+
if err != nil {
85+
if k8serrors.IsNotFound(err) {
86+
err = CreateOrUpdateClusterCAIssuerSecret(k8sclient, certsData.RootCert.CertData, certsData.RootKey.KeyData, certsData.CaChainCertData)
87+
if err != nil {
88+
return nil, fmt.Errorf("failed to create/update CA Issuer Secret: %v", err)
89+
}
90+
91+
result, err := cmClient.CertmanagerV1().ClusterIssuers().Create(context.Background(), issuer, metav1.CreateOptions{})
92+
if err != nil {
93+
return nil, errors.WithMessage(err, "error in creating cert issuer")
94+
}
95+
log.Debugf("ClusterIssuer %s created successfully", result.Name)
96+
return certsData, nil
97+
} else if k8serrors.IsAlreadyExists(err) {
98+
secret, err := k8sclient.GetSecretObject(cert.CertManagerNamespace, cert.ClusterCACertSecretName)
99+
if err != nil {
100+
log.Errorf("Failed to read secert %s, %v", cert.ClusterCACertSecretName, err)
101+
return nil, err
102+
}
103+
certsData.CaChainCertData = secret.Data["ca.crt"]
104+
certsData.RootCert.CertData = secret.Data[corev1.TLSCertKey]
105+
certsData.RootKey.KeyData = secret.Data[corev1.TLSPrivateKeyKey]
106+
return certsData, nil
49107
}
50-
log.Debugf("ClusterIssuer %s created successfully", result.Name)
51-
return nil
108+
return nil, err
52109
}
53110

54-
serverIssuer.Spec.IssuerConfig.CA.SecretName = cert.ClusterCACertSecretName
55-
issuerClient := cmClient.CertmanagerV1().ClusterIssuers()
56-
result, err := issuerClient.Update(context.TODO(), serverIssuer, metav1.UpdateOptions{})
57-
if err != nil {
58-
return errors.WithMessage(err, "error while updating cluster issuer")
111+
if forceUpdate {
112+
err = CreateOrUpdateClusterCAIssuerSecret(k8sclient, certsData.RootCert.CertData, certsData.RootKey.KeyData, certsData.CaChainCertData)
113+
if err != nil {
114+
return nil, fmt.Errorf("failed to create/update CA Issuer Secret: %v", err)
115+
}
116+
117+
serverIssuer.Spec.IssuerConfig.CA.SecretName = cert.ClusterCACertSecretName
118+
issuerClient := cmClient.CertmanagerV1().ClusterIssuers()
119+
_, err := issuerClient.Update(context.TODO(), serverIssuer, metav1.UpdateOptions{})
120+
if err != nil {
121+
return nil, errors.WithMessage(err, "error while updating cluster issuer")
122+
}
59123
}
60-
log.Debugf("ClusterIssuer %s updated successfully", result.Name)
61-
return nil
124+
log.Debugf("ClusterIssuer %s updated successfully", issuer.Name)
125+
return certsData, nil
62126
}
63127

64128
func CreateOrUpdateClusterCAIssuerSecret(k8sClient *K8SClient, caCertData, caKeyData, caCertChainData []byte) error {

capten/common-pkg/k8s/client.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,10 @@ func (k *K8SClient) GetSecretData(namespace, secretName string) (*SecretData, er
172172
}, nil
173173
}
174174

175+
func (k *K8SClient) GetSecretObject(namespace, secretName string) (*v1.Secret, error) {
176+
return k.Clientset.CoreV1().Secrets(namespace).Get(context.TODO(), secretName, metav1.GetOptions{})
177+
}
178+
175179
func (k *K8SClient) CreateOrUpdateSecret(
176180
ctx context.Context,
177181
namespace, secretName string,

charts/kad/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ type: application
1515
# This is the chart version. This version number should be incremented each time you make changes
1616
# to the chart and its templates, including the app version.
1717
# Versions are expected to follow Semantic Versioning (https://semver.org/)
18-
version: 1.0.4
18+
version: 1.0.5
1919

2020
# This is the version number of the application being deployed. This version number should be
2121
# incremented each time you make changes to the application. Versions are not expected to
2222
# follow Semantic Versioning. They should reflect the version the application is using.
2323
# It is recommended to use it with quotes.
24-
appVersion: "2.0.2"
24+
appVersion: "2.0.3"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: cert-manager.io/v1
2+
kind: Certificate
3+
metadata:
4+
name: {{ include "kad.fullname" . }}-agent-server-mtls
5+
spec:
6+
commonName: {{ include "kad.fullname" . }}-agent-server-mtls
7+
issuerRef:
8+
kind: ClusterIssuer
9+
name: {{ .Values.agent.clusterIssuerReference }}
10+
privateKey:
11+
algorithm: RSA
12+
encoding: PKCS1
13+
size: 2048
14+
secretName: {{ include "kad.fullname" . }}-agent-server-mtls
15+
usages:
16+
- digital signature
17+
- key encipherment
18+
- server auth

0 commit comments

Comments
 (0)