Skip to content

Commit

Permalink
Merge pull request #457 from kube-tarian/mtls-preaction
Browse files Browse the repository at this point in the history
Added mtls preaction package
  • Loading branch information
vramk23 authored Apr 13, 2024
2 parents d4e71e3 + c66dbdb commit b9f2caf
Show file tree
Hide file tree
Showing 5 changed files with 349 additions and 152 deletions.
36 changes: 29 additions & 7 deletions capten/deployment-worker/internal/activities/plugin_activity.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/kube-tarian/kad/capten/common-pkg/k8s"
pluginconfigstore "github.com/kube-tarian/kad/capten/common-pkg/pluginconfig-store"
vaultcred "github.com/kube-tarian/kad/capten/common-pkg/vault-cred"
"github.com/kube-tarian/kad/capten/deployment-worker/internal/captensdk"
"github.com/kube-tarian/kad/capten/model"
v1 "k8s.io/api/core/v1"
)
Expand Down Expand Up @@ -266,17 +267,22 @@ func (p *PluginActivities) PluginDeployPreActionMTLSActivity(ctx context.Context
Message: json.RawMessage(fmt.Sprintf("{ \"reason\": \"%s\"}", err.Error())),
}, err
}
// TODO: Call MTLS creation

// Write the mtls in the vault/conigmap
logger.Infof("MTLS activity Not implemented yet")
captenSDKClient, err := captensdk.NewMTLSClient(logger)
if err != nil {
return &model.ResponsePayload{
Status: "FAILED",
Message: json.RawMessage(fmt.Sprintf("{ \"reason\": \"%s\"}", err.Error())),
}, err
}

pluginInitConfigmapName := req.PluginName + pluginConfigmapNameTemplate
err = p.createUpdateConfigmap(ctx, req.DefaultNamespace, pluginInitConfigmapName, map[string]string{})
err = captenSDKClient.CreateCertificates(req.PluginName, req.DefaultNamespace, "capten-issuer", pluginInitConfigmapName, p.k8sClient)
if err != nil {
logger.Errorf("createupdate configmap failed: %v", err)
return &model.ResponsePayload{
Status: "FAILED",
Message: json.RawMessage(fmt.Sprintf("{ \"reason\": \"update configmap failed, %s\"}", pluginInitConfigmapName)),
Message: json.RawMessage(fmt.Sprintf("{ \"reason\": \"%s\"}", err.Error())),
}, err
}

Expand All @@ -287,6 +293,8 @@ func (p *PluginActivities) PluginDeployPreActionMTLSActivity(ctx context.Context
Message: json.RawMessage(fmt.Sprintf("{ \"reason\": \"%s\"}", err.Error())),
}, err
}

logger.Infof("MTLS certificate creation finished")
return &model.ResponsePayload{
Status: "SUCCESS",
}, nil
Expand All @@ -300,9 +308,22 @@ func (p *PluginActivities) PluginUndeployPreActionMTLSActivity(ctx context.Conte
Message: json.RawMessage(fmt.Sprintf("{ \"reason\": \"%s\"}", err.Error())),
}, err
}
// TODO: Call MTLS creation

// Write the mtls in the vault/conigmap
logger.Infof("MTLS activity Not implemented yet")
captenSDKClient, err := captensdk.NewMTLSClient(logger)
if err != nil {
return &model.ResponsePayload{
Status: "FAILED",
Message: json.RawMessage(fmt.Sprintf("{ \"reason\": \"%s\"}", err.Error())),
}, err
}
err = captenSDKClient.DeleteCertificate(req.PluginName, req.DefaultNamespace)
if err != nil {
return &model.ResponsePayload{
Status: "FAILED",
Message: json.RawMessage(fmt.Sprintf("{ \"reason\": \"%s\"}", err.Error())),
}, err
}

err = p.updateStatus(req.PluginName, mtlsUnitializedStatus)
if err != nil {
Expand All @@ -311,6 +332,7 @@ func (p *PluginActivities) PluginUndeployPreActionMTLSActivity(ctx context.Conte
Message: json.RawMessage(fmt.Sprintf("{ \"reason\": \"%s\"}", err.Error())),
}, err
}
logger.Infof("MTLS certificate deletion finished")
return &model.ResponsePayload{
Status: "SUCCESS",
}, nil
Expand Down
123 changes: 123 additions & 0 deletions capten/deployment-worker/internal/captensdk/mtls_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package captensdk

import (
"context"
"fmt"

v1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
cmmeta "github.com/cert-manager/cert-manager/pkg/apis/meta/v1"
cmclient "github.com/cert-manager/cert-manager/pkg/client/clientset/versioned"
"github.com/intelops/go-common/logging"
"github.com/kube-tarian/kad/capten/common-pkg/k8s"
"github.com/kube-tarian/kad/capten/deployment-worker/internal/k8sops"
"github.com/pkg/errors"
k8serror "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/rest"
)

type MTLSClient struct {
log logging.Logger
}

func NewMTLSClient(log logging.Logger) (*MTLSClient, error) {
return &MTLSClient{log: log}, nil
}

func (m *MTLSClient) CreateCertificates(certName, namespace, issuerRefName, cmName string, k8sClient *k8s.K8SClient) error {
config, err := rest.InClusterConfig()
if err != nil {
return errors.WithMessage(err, "error while building kubeconfig")
}
cmClient, err := cmclient.NewForConfig(config)
if err != nil {
return err
}

// Create cert-manager certificate for client and server
for _, isClient := range []bool{true, false} {
err = m.generateCertificate(cmClient, namespace, certName, issuerRefName, isClient)
if err != nil {
return err
}
}

data := map[string]string{}
data["client-certificate"] = certName + "-client-mtls-capten-sdk"
data["server-certificate"] = certName + "-server-mtls-capten-sdk"
k8sops.CreateUpdateConfigmap(context.TODO(), m.log, namespace, cmName, data, k8sClient)
return nil
}

func (m *MTLSClient) generateCertificate(cmClient *cmclient.Clientset, namespace string, certName string, issuerRefName string, isClient bool) error {
var usages []v1.KeyUsage
if isClient {
usages = []v1.KeyUsage{v1.UsageDigitalSignature, v1.UsageKeyEncipherment, v1.UsageClientAuth}
certName = certName + "-client-mtls-capten-sdk"
} else {
usages = []v1.KeyUsage{v1.UsageDigitalSignature, v1.UsageKeyEncipherment, v1.UsageServerAuth}
certName = certName + "-server-mtls-capten-sdk"
}

_, err := cmClient.CertmanagerV1().Certificates(namespace).Create(
context.TODO(),
&v1.Certificate{
ObjectMeta: metav1.ObjectMeta{
Name: certName,
},
Spec: v1.CertificateSpec{
IssuerRef: cmmeta.ObjectReference{
Name: issuerRefName, // "capten-ca-issuer"
Kind: v1.ClusterIssuerKind,
},
SecretName: certName,
CommonName: certName,
Usages: usages,
PrivateKey: &v1.CertificatePrivateKey{
Algorithm: v1.RSAKeyAlgorithm,
Size: 2048,
Encoding: v1.PKCS1,
},
},
},
metav1.CreateOptions{},
)
if k8serror.IsAlreadyExists(err) {
m.log.Infof("%v Certificate already exists", certName)
return nil
}
if err != nil {
m.log.Infof("%v Certificate generation failed, reason: %v", certName, err)
} else {
m.log.Infof("%v Certificate generation successful", certName)
}

return err
}

func (m *MTLSClient) DeleteCertificate(name, namespace string) error {
config, err := rest.InClusterConfig()
if err != nil {
return errors.WithMessage(err, "error while building kubeconfig")
}
cmClient, err := cmclient.NewForConfig(config)
if err != nil {
return err
}

// Create cert-manager certificate request
err = cmClient.CertmanagerV1().Certificates(namespace).Delete(context.TODO(), name, metav1.DeleteOptions{})
if k8serror.IsNotFound(err) {
m.log.Infof("%v Certificate not found", name)
return nil
}
return err
}

func (c *MTLSClient) PrepareFilePath(dir, path string) string {
return fmt.Sprintf("%s%s%s", "c.CurrentDirPath", dir, path)
}

func (c *MTLSClient) PrepareDirPath(dir string) string {
return fmt.Sprintf("%s%s", "c.CurrentDirPath", dir)
}
37 changes: 37 additions & 0 deletions capten/deployment-worker/internal/k8sops/k8s_ops.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package k8sops

import (
"context"
"fmt"

"github.com/intelops/go-common/logging"
"github.com/kube-tarian/kad/capten/common-pkg/k8s"
)

func CreateUpdateConfigmap(ctx context.Context, log logging.Logger, namespace, cmName string, data map[string]string, k8sClient *k8s.K8SClient) error {
err := k8sClient.CreateNamespace(ctx, namespace)
if err != nil {
log.Errorf("Creation of namespace failed: %v", err)
return fmt.Errorf("creation of namespace faield")
}
cm, err := k8sClient.GetConfigmap(ctx, namespace, cmName)
if err != nil {
log.Infof("plugin configmap %s not found", cmName)
err = k8sClient.CreateConfigmap(ctx, namespace, cmName, data, map[string]string{})
if err != nil {
return fmt.Errorf("failed to create configmap %v", cmName)
}
}
// configmap found but data is empty/nil
if cm == nil {
cm = map[string]string{}
}
for k, v := range data {
cm[k] = v
}
err = k8sClient.UpdateConfigmap(ctx, namespace, cmName, cm)
if err != nil {
return fmt.Errorf("plugin configmap %s not found", cmName)
}
return nil
}
Loading

0 comments on commit b9f2caf

Please sign in to comment.