2022-09-05 03:06:08 -04:00
|
|
|
/*
|
|
|
|
Copyright (c) Edgeless Systems GmbH
|
|
|
|
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
2022-04-12 10:07:17 -04:00
|
|
|
package resources
|
|
|
|
|
|
|
|
import (
|
2022-06-15 10:00:48 -04:00
|
|
|
"fmt"
|
|
|
|
|
2022-09-21 07:47:57 -04:00
|
|
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
|
|
|
"github.com/edgelesssys/constellation/v2/internal/kubernetes"
|
|
|
|
"github.com/edgelesssys/constellation/v2/internal/versions"
|
2022-04-12 10:07:17 -04:00
|
|
|
apps "k8s.io/api/apps/v1"
|
|
|
|
k8s "k8s.io/api/core/v1"
|
|
|
|
rbac "k8s.io/api/rbac/v1"
|
|
|
|
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
2022-06-15 10:00:48 -04:00
|
|
|
"k8s.io/apimachinery/pkg/util/intstr"
|
2022-04-12 10:07:17 -04:00
|
|
|
)
|
|
|
|
|
2022-08-04 10:15:52 -04:00
|
|
|
const kmsNamespace = "kube-system"
|
|
|
|
|
2022-10-05 09:02:46 -04:00
|
|
|
type KMSDeployment struct {
|
2022-04-12 10:07:17 -04:00
|
|
|
ServiceAccount k8s.ServiceAccount
|
2022-07-26 04:58:39 -04:00
|
|
|
Service k8s.Service
|
2022-04-12 10:07:17 -04:00
|
|
|
ClusterRole rbac.ClusterRole
|
|
|
|
ClusterRoleBinding rbac.ClusterRoleBinding
|
2022-09-05 04:22:40 -04:00
|
|
|
Deployment apps.DaemonSet
|
2022-04-12 10:07:17 -04:00
|
|
|
MasterSecret k8s.Secret
|
|
|
|
}
|
|
|
|
|
2022-07-29 03:52:47 -04:00
|
|
|
// KMSConfig is the configuration needed to set up Constellation's key management service.
|
|
|
|
type KMSConfig struct {
|
|
|
|
MasterSecret []byte
|
|
|
|
Salt []byte
|
|
|
|
KMSURI string
|
|
|
|
StorageURI string
|
|
|
|
KeyEncryptionKeyID string
|
|
|
|
UseExistingKEK bool
|
|
|
|
}
|
|
|
|
|
2022-04-12 10:07:17 -04:00
|
|
|
// NewKMSDeployment creates a new *kmsDeployment to use as the key management system inside Constellation.
|
2022-10-05 09:02:46 -04:00
|
|
|
func NewKMSDeployment(csp string, config KMSConfig) *KMSDeployment {
|
|
|
|
return &KMSDeployment{
|
2022-04-12 10:07:17 -04:00
|
|
|
ServiceAccount: k8s.ServiceAccount{
|
|
|
|
TypeMeta: meta.TypeMeta{
|
|
|
|
APIVersion: "v1",
|
|
|
|
Kind: "ServiceAccount",
|
|
|
|
},
|
|
|
|
ObjectMeta: meta.ObjectMeta{
|
|
|
|
Name: "kms",
|
2022-08-04 10:15:52 -04:00
|
|
|
Namespace: kmsNamespace,
|
2022-04-12 10:07:17 -04:00
|
|
|
},
|
|
|
|
},
|
2022-07-26 04:58:39 -04:00
|
|
|
Service: k8s.Service{
|
2022-06-15 10:00:48 -04:00
|
|
|
TypeMeta: meta.TypeMeta{
|
|
|
|
APIVersion: "v1",
|
|
|
|
Kind: "Service",
|
|
|
|
},
|
|
|
|
ObjectMeta: meta.ObjectMeta{
|
|
|
|
Name: "kms",
|
2022-08-04 10:15:52 -04:00
|
|
|
Namespace: kmsNamespace,
|
2022-06-15 10:00:48 -04:00
|
|
|
},
|
|
|
|
Spec: k8s.ServiceSpec{
|
|
|
|
Type: k8s.ServiceTypeClusterIP,
|
|
|
|
Ports: []k8s.ServicePort{
|
|
|
|
{
|
|
|
|
Name: "grpc",
|
|
|
|
Protocol: k8s.ProtocolTCP,
|
|
|
|
Port: constants.KMSPort,
|
|
|
|
TargetPort: intstr.FromInt(constants.KMSPort),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Selector: map[string]string{
|
|
|
|
"k8s-app": "kms",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2022-04-12 10:07:17 -04:00
|
|
|
ClusterRole: rbac.ClusterRole{
|
|
|
|
TypeMeta: meta.TypeMeta{
|
|
|
|
APIVersion: "rbac.authorization.k8s.io/v1",
|
|
|
|
Kind: "ClusterRole",
|
|
|
|
},
|
|
|
|
ObjectMeta: meta.ObjectMeta{
|
|
|
|
Name: "kms",
|
|
|
|
Labels: map[string]string{
|
|
|
|
"k8s-app": "kms",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Rules: []rbac.PolicyRule{
|
|
|
|
{
|
|
|
|
APIGroups: []string{""},
|
|
|
|
Resources: []string{"secrets"},
|
|
|
|
Verbs: []string{"get"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
ClusterRoleBinding: rbac.ClusterRoleBinding{
|
|
|
|
TypeMeta: meta.TypeMeta{
|
|
|
|
APIVersion: "rbac.authorization.k8s.io/v1",
|
|
|
|
Kind: "ClusterRoleBinding",
|
|
|
|
},
|
|
|
|
ObjectMeta: meta.ObjectMeta{
|
|
|
|
Name: "kms",
|
|
|
|
},
|
|
|
|
RoleRef: rbac.RoleRef{
|
|
|
|
APIGroup: "rbac.authorization.k8s.io",
|
|
|
|
Kind: "ClusterRole",
|
|
|
|
Name: "kms",
|
|
|
|
},
|
|
|
|
Subjects: []rbac.Subject{
|
|
|
|
{
|
|
|
|
Kind: "ServiceAccount",
|
|
|
|
Name: "kms",
|
2022-08-04 10:15:52 -04:00
|
|
|
Namespace: kmsNamespace,
|
2022-04-12 10:07:17 -04:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2022-09-05 04:22:40 -04:00
|
|
|
Deployment: apps.DaemonSet{
|
2022-04-12 10:07:17 -04:00
|
|
|
TypeMeta: meta.TypeMeta{
|
|
|
|
APIVersion: "apps/v1",
|
2022-09-05 04:22:40 -04:00
|
|
|
Kind: "DaemonSet",
|
2022-04-12 10:07:17 -04:00
|
|
|
},
|
|
|
|
ObjectMeta: meta.ObjectMeta{
|
|
|
|
Labels: map[string]string{
|
2022-09-05 04:22:40 -04:00
|
|
|
"k8s-app": "kms",
|
|
|
|
"component": "kms",
|
|
|
|
"kubernetes.io/cluster-service": "true",
|
2022-04-12 10:07:17 -04:00
|
|
|
},
|
|
|
|
Name: "kms",
|
2022-08-04 10:15:52 -04:00
|
|
|
Namespace: kmsNamespace,
|
2022-04-12 10:07:17 -04:00
|
|
|
},
|
2022-09-05 04:22:40 -04:00
|
|
|
Spec: apps.DaemonSetSpec{
|
2022-04-12 10:07:17 -04:00
|
|
|
Selector: &meta.LabelSelector{
|
|
|
|
MatchLabels: map[string]string{
|
|
|
|
"k8s-app": "kms",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Template: k8s.PodTemplateSpec{
|
|
|
|
ObjectMeta: meta.ObjectMeta{
|
|
|
|
Labels: map[string]string{
|
|
|
|
"k8s-app": "kms",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Spec: k8s.PodSpec{
|
2022-06-15 10:00:48 -04:00
|
|
|
PriorityClassName: "system-cluster-critical",
|
|
|
|
Tolerations: []k8s.Toleration{
|
|
|
|
{
|
|
|
|
Key: "CriticalAddonsOnly",
|
|
|
|
Operator: k8s.TolerationOpExists,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Key: "node-role.kubernetes.io/master",
|
|
|
|
Operator: k8s.TolerationOpEqual,
|
|
|
|
Value: "true",
|
|
|
|
Effect: k8s.TaintEffectNoSchedule,
|
|
|
|
},
|
2022-06-28 11:03:28 -04:00
|
|
|
{
|
|
|
|
Key: "node-role.kubernetes.io/control-plane",
|
|
|
|
Operator: k8s.TolerationOpExists,
|
|
|
|
Effect: k8s.TaintEffectNoSchedule,
|
|
|
|
},
|
2022-06-15 10:00:48 -04:00
|
|
|
{
|
|
|
|
Operator: k8s.TolerationOpExists,
|
|
|
|
Effect: k8s.TaintEffectNoExecute,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Operator: k8s.TolerationOpExists,
|
|
|
|
Effect: k8s.TaintEffectNoSchedule,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
// Only run on control plane nodes
|
|
|
|
NodeSelector: map[string]string{
|
2022-07-26 11:08:57 -04:00
|
|
|
"node-role.kubernetes.io/control-plane": "",
|
2022-06-15 10:00:48 -04:00
|
|
|
},
|
2022-04-12 10:07:17 -04:00
|
|
|
Volumes: []k8s.Volume{
|
|
|
|
{
|
2022-06-29 10:13:01 -04:00
|
|
|
Name: "config",
|
2022-04-12 10:07:17 -04:00
|
|
|
VolumeSource: k8s.VolumeSource{
|
2022-06-29 10:13:01 -04:00
|
|
|
Projected: &k8s.ProjectedVolumeSource{
|
|
|
|
Sources: []k8s.VolumeProjection{
|
|
|
|
{
|
|
|
|
ConfigMap: &k8s.ConfigMapProjection{
|
|
|
|
LocalObjectReference: k8s.LocalObjectReference{
|
2022-07-05 08:13:19 -04:00
|
|
|
Name: "join-config",
|
2022-06-29 10:13:01 -04:00
|
|
|
},
|
|
|
|
Items: []k8s.KeyToPath{
|
|
|
|
{
|
|
|
|
Key: constants.MeasurementsFilename,
|
|
|
|
Path: constants.MeasurementsFilename,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2022-04-12 10:07:17 -04:00
|
|
|
{
|
2022-06-29 10:13:01 -04:00
|
|
|
Secret: &k8s.SecretProjection{
|
|
|
|
LocalObjectReference: k8s.LocalObjectReference{
|
|
|
|
Name: constants.ConstellationMasterSecretStoreName,
|
|
|
|
},
|
|
|
|
Items: []k8s.KeyToPath{
|
|
|
|
{
|
|
|
|
Key: constants.ConstellationMasterSecretKey,
|
2022-07-29 03:52:47 -04:00
|
|
|
Path: constants.ConstellationMasterSecretKey,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
Key: constants.ConstellationMasterSecretSalt,
|
|
|
|
Path: constants.ConstellationMasterSecretSalt,
|
2022-06-29 10:13:01 -04:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2022-04-12 10:07:17 -04:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
ServiceAccountName: "kms",
|
|
|
|
Containers: []k8s.Container{
|
|
|
|
{
|
|
|
|
Name: "kms",
|
2022-07-18 06:28:02 -04:00
|
|
|
Image: versions.KmsImage,
|
2022-06-15 10:00:48 -04:00
|
|
|
Args: []string{
|
|
|
|
fmt.Sprintf("--port=%d", constants.KMSPort),
|
|
|
|
},
|
2022-04-12 10:07:17 -04:00
|
|
|
VolumeMounts: []k8s.VolumeMount{
|
|
|
|
{
|
2022-06-29 10:13:01 -04:00
|
|
|
Name: "config",
|
2022-04-12 10:07:17 -04:00
|
|
|
ReadOnly: true,
|
2022-06-29 10:13:01 -04:00
|
|
|
MountPath: constants.ServiceBasePath,
|
2022-04-12 10:07:17 -04:00
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
MasterSecret: k8s.Secret{
|
|
|
|
TypeMeta: meta.TypeMeta{
|
|
|
|
APIVersion: "v1",
|
|
|
|
Kind: "Secret",
|
|
|
|
},
|
|
|
|
ObjectMeta: meta.ObjectMeta{
|
|
|
|
Name: constants.ConstellationMasterSecretStoreName,
|
2022-08-04 10:15:52 -04:00
|
|
|
Namespace: kmsNamespace,
|
2022-04-12 10:07:17 -04:00
|
|
|
},
|
|
|
|
Data: map[string][]byte{
|
2022-07-29 03:52:47 -04:00
|
|
|
constants.ConstellationMasterSecretKey: config.MasterSecret,
|
|
|
|
constants.ConstellationMasterSecretSalt: config.Salt,
|
2022-04-12 10:07:17 -04:00
|
|
|
},
|
|
|
|
Type: "Opaque",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-05 09:02:46 -04:00
|
|
|
func (c *KMSDeployment) Marshal() ([]byte, error) {
|
2022-08-29 08:30:20 -04:00
|
|
|
return kubernetes.MarshalK8SResources(c)
|
2022-04-12 10:07:17 -04:00
|
|
|
}
|