mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-10-01 01:36:09 -04:00
Deploy KMS server image in Constellation
Add image pull secret for ghcr.io
This commit is contained in:
parent
4dcb3aa062
commit
db5468a886
29
Dockerfile.kms
Normal file
29
Dockerfile.kms
Normal file
@ -0,0 +1,29 @@
|
||||
FROM ubuntu@sha256:7cc0576c7c0ec2384de5cbf245f41567e922aab1b075f3e8ad565f508032df17 as build
|
||||
|
||||
ENV DEBIAN_FRONTEND="noninteractive"
|
||||
RUN apt-get update && apt-get install wget git -y
|
||||
|
||||
# Install Go
|
||||
ARG GO_VER=1.18
|
||||
RUN wget https://go.dev/dl/go${GO_VER}.linux-amd64.tar.gz
|
||||
RUN tar -C /usr/local -xzf go${GO_VER}.linux-amd64.tar.gz && rm go${GO_VER}.linux-amd64.tar.gz
|
||||
ENV PATH ${PATH}:/usr/local/go/bin
|
||||
|
||||
# Download go dependencies
|
||||
WORKDIR /constellation/
|
||||
COPY go.mod ./
|
||||
COPY go.sum ./
|
||||
RUN go mod download all
|
||||
|
||||
# Copy Repo
|
||||
COPY . /constellation
|
||||
RUN rm -rf ./hack/ go.work.sum go.work
|
||||
|
||||
# Build
|
||||
RUN mkdir -p /constellation/build
|
||||
WORKDIR /constellation/kms/server/cmd
|
||||
RUN CGO_ENABLED=0 go build -o /constellation/build/kmsserver
|
||||
|
||||
FROM scratch as release
|
||||
COPY --from=build /constellation/build/kmsserver /kmsserver
|
||||
ENTRYPOINT ["/kmsserver"]
|
@ -1,17 +0,0 @@
|
||||
package cmd
|
||||
|
||||
const (
|
||||
// wireguardAdminMTU is the MTU designated for the admin's WireGuard interface.
|
||||
//
|
||||
// WireGuard doesn't support Path MTU Discovery. Thus, its default MTU can be too high on some networks.
|
||||
wireguardAdminMTU = 1300
|
||||
|
||||
// masterSecretLengthDefault is the default length in bytes for CLI generated master secrets.
|
||||
masterSecretLengthDefault = 32
|
||||
|
||||
// masterSecretLengthMin is the minimal length in bytes for user provided master secrets.
|
||||
masterSecretLengthMin = 16
|
||||
|
||||
// constellationNameLength is the maximum length of a Constellation's name.
|
||||
constellationNameLength = 37
|
||||
)
|
@ -133,10 +133,10 @@ func parseCreateFlags(cmd *cobra.Command, provider cloudprovider.Provider) (crea
|
||||
if err != nil {
|
||||
return createFlags{}, err
|
||||
}
|
||||
if len(name) > constellationNameLength {
|
||||
if len(name) > constants.ConstellationNameLength {
|
||||
return createFlags{}, fmt.Errorf(
|
||||
"name for Constellation cluster too long, maximum length is %d, got %d: %s",
|
||||
constellationNameLength, len(name), name,
|
||||
constants.ConstellationNameLength, len(name), name,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ func TestCreate(t *testing.T) {
|
||||
provider: cloudprovider.GCP,
|
||||
controllerCountFlag: intPtr(1),
|
||||
workerCountFlag: intPtr(1),
|
||||
nameFlag: strings.Repeat("a", constellationNameLength+1),
|
||||
nameFlag: strings.Repeat("a", constants.ConstellationNameLength+1),
|
||||
wantErr: true,
|
||||
},
|
||||
"flag control-plane-count invalid": {
|
||||
|
@ -153,7 +153,7 @@ func initialize(ctx context.Context, cmd *cobra.Command, protCl protoClient, ser
|
||||
return err
|
||||
}
|
||||
|
||||
vpnConfig, err := vpnHandler.Create(result.coordinatorPubKey, result.coordinatorPubIP, string(flags.userPrivKey), result.clientVpnIP, wireguardAdminMTU)
|
||||
vpnConfig, err := vpnHandler.Create(result.coordinatorPubKey, result.coordinatorPubIP, string(flags.userPrivKey), result.clientVpnIP, constants.WireguardAdminMTU)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -374,14 +374,14 @@ func readOrGeneratedMasterSecret(w io.Writer, fileHandler file.Handler, filename
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(decoded) < masterSecretLengthMin {
|
||||
if len(decoded) < constants.MasterSecretLengthMin {
|
||||
return nil, errors.New("provided master secret is smaller than the required minimum of 16 Bytes")
|
||||
}
|
||||
return decoded, nil
|
||||
}
|
||||
|
||||
// No file given, generate a new secret, and save it to disk
|
||||
masterSecret, err := util.GenerateRandomBytes(masterSecretLengthDefault)
|
||||
masterSecret, err := util.GenerateRandomBytes(constants.MasterSecretLengthDefault)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ func (c *Core) GetK8SCertificateKey() (string, error) {
|
||||
}
|
||||
|
||||
// InitCluster initializes the cluster, stores the join args, and returns the kubeconfig.
|
||||
func (c *Core) InitCluster(autoscalingNodeGroups []string, cloudServiceAccountURI string) ([]byte, error) {
|
||||
func (c *Core) InitCluster(autoscalingNodeGroups []string, cloudServiceAccountURI string, masterSecret []byte) ([]byte, error) {
|
||||
var nodeName string
|
||||
var providerID string
|
||||
var instance Instance
|
||||
@ -99,6 +99,7 @@ func (c *Core) InitCluster(autoscalingNodeGroups []string, cloudServiceAccountUR
|
||||
CloudNodeManagerImage: c.cloudNodeManager.Image(),
|
||||
CloudNodeManagerPath: c.cloudNodeManager.Path(),
|
||||
CloudNodeManagerExtraArgs: c.cloudNodeManager.ExtraArgs(),
|
||||
MasterSecret: masterSecret,
|
||||
}); err != nil {
|
||||
c.zaplogger.Error("Initializing cluster failed", zap.Error(err))
|
||||
return nil, err
|
||||
|
@ -23,12 +23,15 @@ import (
|
||||
func TestInitCluster(t *testing.T) {
|
||||
someErr := errors.New("someErr")
|
||||
|
||||
testMS := []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}
|
||||
|
||||
testCases := map[string]struct {
|
||||
cluster clusterStub
|
||||
metadata stubMetadata
|
||||
cloudControllerManager stubCloudControllerManager
|
||||
cloudNodeManager stubCloudNodeManager
|
||||
clusterAutoscaler stubClusterAutoscaler
|
||||
masterSecret []byte
|
||||
autoscalingNodeGroups []string
|
||||
wantErr bool
|
||||
wantInitClusterInput kubernetes.InitClusterInput
|
||||
@ -38,6 +41,7 @@ func TestInitCluster(t *testing.T) {
|
||||
kubeconfig: []byte("kubeconfig"),
|
||||
},
|
||||
autoscalingNodeGroups: []string{"someNodeGroup"},
|
||||
masterSecret: testMS,
|
||||
wantInitClusterInput: kubernetes.InitClusterInput{
|
||||
APIServerAdvertiseIP: "10.118.0.1",
|
||||
NodeIP: "10.118.0.1",
|
||||
@ -45,6 +49,7 @@ func TestInitCluster(t *testing.T) {
|
||||
SupportsCloudControllerManager: false,
|
||||
SupportClusterAutoscaler: false,
|
||||
AutoscalingNodeGroups: []string{"someNodeGroup"},
|
||||
MasterSecret: testMS,
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
@ -52,6 +57,7 @@ func TestInitCluster(t *testing.T) {
|
||||
cluster: clusterStub{
|
||||
kubeconfig: []byte("kubeconfig"),
|
||||
},
|
||||
masterSecret: testMS,
|
||||
metadata: stubMetadata{
|
||||
selfRes: Instance{
|
||||
Name: "some-name",
|
||||
@ -66,6 +72,7 @@ func TestInitCluster(t *testing.T) {
|
||||
ProviderID: "fake://providerid",
|
||||
SupportsCloudControllerManager: false,
|
||||
SupportClusterAutoscaler: false,
|
||||
MasterSecret: testMS,
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
@ -87,6 +94,7 @@ func TestInitCluster(t *testing.T) {
|
||||
nameRes: "some-name",
|
||||
supportedRes: true,
|
||||
},
|
||||
masterSecret: testMS,
|
||||
autoscalingNodeGroups: []string{"someNodeGroup"},
|
||||
wantInitClusterInput: kubernetes.InitClusterInput{
|
||||
APIServerAdvertiseIP: "10.118.0.1",
|
||||
@ -96,6 +104,7 @@ func TestInitCluster(t *testing.T) {
|
||||
SupportClusterAutoscaler: true,
|
||||
AutoscalingCloudprovider: "some-name",
|
||||
AutoscalingNodeGroups: []string{"someNodeGroup"},
|
||||
MasterSecret: testMS,
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
@ -103,6 +112,7 @@ func TestInitCluster(t *testing.T) {
|
||||
cluster: clusterStub{
|
||||
kubeconfig: []byte("kubeconfig"),
|
||||
},
|
||||
masterSecret: testMS,
|
||||
cloudControllerManager: stubCloudControllerManager{
|
||||
supportedRes: true,
|
||||
nameRes: "some-name",
|
||||
@ -118,6 +128,7 @@ func TestInitCluster(t *testing.T) {
|
||||
CloudControllerManagerName: "some-name",
|
||||
CloudControllerManagerImage: "someImage",
|
||||
CloudControllerManagerPath: "/some/path",
|
||||
MasterSecret: testMS,
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
@ -141,6 +152,7 @@ func TestInitCluster(t *testing.T) {
|
||||
cluster: clusterStub{
|
||||
kubeconfig: []byte("kubeconfig"),
|
||||
},
|
||||
masterSecret: testMS,
|
||||
metadata: stubMetadata{
|
||||
signalRoleErr: errors.New("updating role fails"),
|
||||
supportedRes: true,
|
||||
@ -149,6 +161,7 @@ func TestInitCluster(t *testing.T) {
|
||||
wantInitClusterInput: kubernetes.InitClusterInput{
|
||||
APIServerAdvertiseIP: "10.118.0.1",
|
||||
NodeIP: "10.118.0.1",
|
||||
MasterSecret: testMS,
|
||||
},
|
||||
},
|
||||
"getting kubeconfig fail detected": {
|
||||
@ -176,7 +189,7 @@ func TestInitCluster(t *testing.T) {
|
||||
core, err := NewCore(&stubVPN{}, &tc.cluster, &tc.metadata, &tc.cloudControllerManager, &tc.cloudNodeManager, &tc.clusterAutoscaler, nil, zapLogger, simulator.OpenSimulatedTPM, nil, file.NewHandler(fs), user.NewLinuxUserManagerFake(fs))
|
||||
require.NoError(err)
|
||||
|
||||
kubeconfig, err := core.InitCluster(tc.autoscalingNodeGroups, "cloud-service-account-uri")
|
||||
kubeconfig, err := core.InitCluster(tc.autoscalingNodeGroups, "cloud-service-account-uri", tc.masterSecret)
|
||||
|
||||
if tc.wantErr {
|
||||
assert.Error(err)
|
||||
|
@ -32,4 +32,5 @@ type InitClusterInput struct {
|
||||
CloudNodeManagerImage string
|
||||
CloudNodeManagerPath string
|
||||
CloudNodeManagerExtraArgs []string
|
||||
MasterSecret []byte
|
||||
}
|
||||
|
32
coordinator/kubernetes/k8sapi/resources/image_pull_secret.go
Normal file
32
coordinator/kubernetes/k8sapi/resources/image_pull_secret.go
Normal file
@ -0,0 +1,32 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
|
||||
"github.com/edgelesssys/constellation/internal/secrets"
|
||||
k8s "k8s.io/api/core/v1"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// NewImagePullSecret creates a new k8s.Secret from the config for authenticating when pulling images.
|
||||
func NewImagePullSecret() k8s.Secret {
|
||||
base64EncodedSecret := base64.StdEncoding.EncodeToString(
|
||||
[]byte(fmt.Sprintf("%s:%s", secrets.PullSecretUser, secrets.PullSecretToken)),
|
||||
)
|
||||
|
||||
pullSecretDockerCfgJson := fmt.Sprintf(`{"auths":{"ghcr.io":{"auth":"%s"}}}`, base64EncodedSecret)
|
||||
|
||||
return k8s.Secret{
|
||||
TypeMeta: meta.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "Secret",
|
||||
},
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: secrets.PullSecretName,
|
||||
Namespace: "kube-system",
|
||||
},
|
||||
StringData: map[string]string{".dockerconfigjson": pullSecretDockerCfgJson},
|
||||
Type: "kubernetes.io/dockerconfigjson",
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestImagePullSecret(t *testing.T) {
|
||||
imgPullSec := NewImagePullSecret()
|
||||
_, err := imgPullSec.Marshal()
|
||||
assert.NoError(t, err)
|
||||
}
|
162
coordinator/kubernetes/k8sapi/resources/kms.go
Normal file
162
coordinator/kubernetes/k8sapi/resources/kms.go
Normal file
@ -0,0 +1,162 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"github.com/edgelesssys/constellation/internal/constants"
|
||||
"github.com/edgelesssys/constellation/internal/secrets"
|
||||
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"
|
||||
)
|
||||
|
||||
type kmsDeployment struct {
|
||||
ServiceAccount k8s.ServiceAccount
|
||||
ClusterRole rbac.ClusterRole
|
||||
ClusterRoleBinding rbac.ClusterRoleBinding
|
||||
Deployment apps.Deployment
|
||||
MasterSecret k8s.Secret
|
||||
ImagePullSecret k8s.Secret
|
||||
}
|
||||
|
||||
const (
|
||||
kmsImage = "ghcr.io/edgelesssys/constellation/kmsserver:latest"
|
||||
)
|
||||
|
||||
// NewKMSDeployment creates a new *kmsDeployment to use as the key management system inside Constellation.
|
||||
func NewKMSDeployment(masterSecret []byte) *kmsDeployment {
|
||||
return &kmsDeployment{
|
||||
ServiceAccount: k8s.ServiceAccount{
|
||||
TypeMeta: meta.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "ServiceAccount",
|
||||
},
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: "kms",
|
||||
Namespace: "kube-system",
|
||||
},
|
||||
},
|
||||
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",
|
||||
Namespace: "kube-system",
|
||||
},
|
||||
},
|
||||
},
|
||||
Deployment: apps.Deployment{
|
||||
TypeMeta: meta.TypeMeta{
|
||||
APIVersion: "apps/v1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"k8s-app": "kms",
|
||||
},
|
||||
Name: "kms",
|
||||
Namespace: "kube-system",
|
||||
},
|
||||
Spec: apps.DeploymentSpec{
|
||||
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{
|
||||
ImagePullSecrets: []k8s.LocalObjectReference{
|
||||
{
|
||||
Name: secrets.PullSecretName,
|
||||
},
|
||||
},
|
||||
Volumes: []k8s.Volume{
|
||||
{
|
||||
Name: "mastersecret",
|
||||
VolumeSource: k8s.VolumeSource{
|
||||
Secret: &k8s.SecretVolumeSource{
|
||||
SecretName: constants.ConstellationMasterSecretStoreName,
|
||||
Items: []k8s.KeyToPath{
|
||||
{
|
||||
Key: constants.ConstellationMasterSecretKey,
|
||||
Path: "constellation-mastersecret.base64",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ServiceAccountName: "kms",
|
||||
Containers: []k8s.Container{
|
||||
{
|
||||
Name: "kms",
|
||||
Image: kmsImage,
|
||||
VolumeMounts: []k8s.VolumeMount{
|
||||
{
|
||||
Name: "mastersecret",
|
||||
ReadOnly: true,
|
||||
MountPath: "/constellation/",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MasterSecret: k8s.Secret{
|
||||
TypeMeta: meta.TypeMeta{
|
||||
APIVersion: "v1",
|
||||
Kind: "Secret",
|
||||
},
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: constants.ConstellationMasterSecretStoreName,
|
||||
Namespace: "kube-system",
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
constants.ConstellationMasterSecretKey: masterSecret,
|
||||
},
|
||||
Type: "Opaque",
|
||||
},
|
||||
ImagePullSecret: NewImagePullSecret(),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *kmsDeployment) Marshal() ([]byte, error) {
|
||||
return MarshalK8SResources(c)
|
||||
}
|
22
coordinator/kubernetes/k8sapi/resources/kms_test.go
Normal file
22
coordinator/kubernetes/k8sapi/resources/kms_test.go
Normal file
@ -0,0 +1,22 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestKMSMarshalUnmarshal(t *testing.T) {
|
||||
require := require.New(t)
|
||||
assert := assert.New(t)
|
||||
|
||||
testMS := []byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8}
|
||||
kmsDepl := NewKMSDeployment(testMS)
|
||||
data, err := kmsDepl.Marshal()
|
||||
require.NoError(err)
|
||||
|
||||
var recreated kmsDeployment
|
||||
require.NoError(UnmarshalK8SResources(data, &recreated))
|
||||
assert.Equal(kmsDepl, &recreated)
|
||||
}
|
@ -35,6 +35,7 @@ type ClusterUtil interface {
|
||||
SetupAutoscaling(kubectl Client, clusterAutoscalerConfiguration resources.Marshaler, secrets resources.Marshaler) error
|
||||
SetupCloudControllerManager(kubectl Client, cloudControllerManagerConfiguration resources.Marshaler, configMaps resources.Marshaler, secrets resources.Marshaler) error
|
||||
SetupCloudNodeManager(kubectl Client, cloudNodeManagerConfiguration resources.Marshaler) error
|
||||
SetupKMS(kubectl Client, kmsConfiguration resources.Marshaler) error
|
||||
StartKubelet() error
|
||||
RestartKubelet() error
|
||||
GetControlPlaneJoinCertificateKey() (string, error)
|
||||
@ -173,6 +174,14 @@ func (k *KubernetesUtil) JoinCluster(joinConfig []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetupKMS deploys the KMS deployment.
|
||||
func (k *KubernetesUtil) SetupKMS(kubectl Client, kmsConfiguration resources.Marshaler) error {
|
||||
if err := kubectl.Apply(kmsConfiguration, true); err != nil {
|
||||
return fmt.Errorf("applying KMS configuration failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// StartKubelet enables and starts the kubelet systemd unit.
|
||||
func (k *KubernetesUtil) StartKubelet() error {
|
||||
ctx, cancel := context.WithTimeout(context.TODO(), kubeletStartTimeout)
|
||||
|
@ -79,6 +79,11 @@ func (k *KubeWrapper) InitCluster(in InitClusterInput) error {
|
||||
return fmt.Errorf("setup of pod network failed: %w", err)
|
||||
}
|
||||
|
||||
kms := resources.NewKMSDeployment(in.MasterSecret)
|
||||
if err = k.clusterUtil.SetupKMS(k.client, kms); err != nil {
|
||||
return fmt.Errorf("setup of kms failed: %w", err)
|
||||
}
|
||||
|
||||
if in.SupportsCloudControllerManager {
|
||||
cloudControllerManagerConfiguration := resources.NewDefaultCloudControllerManagerDeployment(
|
||||
in.CloudControllerManagerName, in.CloudControllerManagerImage, in.CloudControllerManagerPath, in.CloudControllerManagerExtraArgs,
|
||||
|
@ -27,6 +27,7 @@ type stubClusterUtil struct {
|
||||
setupAutoscalingError error
|
||||
setupCloudControllerManagerError error
|
||||
setupCloudNodeManagerError error
|
||||
setupKMSError error
|
||||
joinClusterErr error
|
||||
startKubeletErr error
|
||||
restartKubeletErr error
|
||||
@ -58,6 +59,10 @@ func (s *stubClusterUtil) SetupCloudControllerManager(kubectl k8sapi.Client, clo
|
||||
return s.setupCloudControllerManagerError
|
||||
}
|
||||
|
||||
func (s *stubClusterUtil) SetupKMS(kubectl k8sapi.Client, kmsDeployment resources.Marshaler) error {
|
||||
return s.setupKMSError
|
||||
}
|
||||
|
||||
func (s *stubClusterUtil) SetupCloudNodeManager(kubectl k8sapi.Client, cloudNodeManagerConfiguration resources.Marshaler) error {
|
||||
return s.setupCloudNodeManagerError
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ func (a *API) ActivateAsCoordinator(in *pubproto.ActivateAsCoordinatorRequest, s
|
||||
}
|
||||
|
||||
logToCLI("Initializing Kubernetes ...")
|
||||
kubeconfig, err := a.core.InitCluster(in.AutoscalingNodeGroups, in.CloudServiceAccountUri)
|
||||
kubeconfig, err := a.core.InitCluster(in.AutoscalingNodeGroups, in.CloudServiceAccountUri, in.MasterSecret)
|
||||
if err != nil {
|
||||
return status.Errorf(codes.Internal, "initializing Kubernetes cluster failed: %v", err)
|
||||
}
|
||||
|
@ -39,6 +39,6 @@ type Core interface {
|
||||
|
||||
CreateSSHUsers([]ssh.UserKey) error
|
||||
|
||||
InitCluster(autoscalingNodeGroups []string, cloudServiceAccountURI string) ([]byte, error)
|
||||
InitCluster(autoscalingNodeGroups []string, cloudServiceAccountURI string, masterSecret []byte) ([]byte, error)
|
||||
JoinCluster(joinToken *kubeadm.BootstrapTokenDiscovery, certificateKey string, role role.Role) error
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ func (c *fakeCore) UpdatePeers(peers []peer.Peer) error {
|
||||
return c.UpdatePeersErr
|
||||
}
|
||||
|
||||
func (c *fakeCore) InitCluster(autoscalingNodeGroups []string, cloudServiceAccountURI string) ([]byte, error) {
|
||||
func (c *fakeCore) InitCluster(autoscalingNodeGroups []string, cloudServiceAccountURI string, masterSecret []byte) ([]byte, error) {
|
||||
c.autoscalingNodeGroups = autoscalingNodeGroups
|
||||
return c.kubeconfig, nil
|
||||
}
|
||||
|
21
go.work.sum
21
go.work.sum
@ -1,5 +1,26 @@
|
||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||
github.com/containerd/containerd v1.4.11/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
|
||||
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
|
||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8=
|
||||
github.com/google/cadvisor v0.43.0/go.mod h1:+RdMSbc3FVr5NYCD2dOEJy/LI0jYJ/0xJXkzWXEyiFQ=
|
||||
github.com/googleapis/gax-go v2.0.2+incompatible h1:silFMLAnr330+NRuag/VjIGF7TLp/LBrV2CJKFLWEww=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
|
||||
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
|
||||
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.1.6-0.20210820212750-d4cc65f0b2ff/go.mod h1:YD9qOF0M9xpSpdWTBbzEl5e/RnCefISl8E5Noe10jFM=
|
||||
gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
|
||||
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
|
||||
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk=
|
||||
k8s.io/kubernetes v1.23.5/go.mod h1:avI3LUTUYZugxwh52KMVM7v9ZjB5gYJ6D3FIoZ1SHUo=
|
||||
k8s.io/system-validators v1.6.0/go.mod h1:bPldcLgkIUK22ALflnsXk8pvkTEndYdNuaHH6gRrl0Q=
|
||||
k8s.io/utils v0.0.0-20220127004650-9b3446523e65/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
|
@ -7,6 +7,17 @@ package constants
|
||||
import "time"
|
||||
|
||||
const (
|
||||
//
|
||||
// Constellation.
|
||||
//
|
||||
|
||||
// ConstellationNameLength is the maximum length of a Constellation's name.
|
||||
ConstellationNameLength = 37
|
||||
// ConstellationMasterSecretStoreName is the name for the Constellation secrets in Kubernetes.
|
||||
ConstellationMasterSecretStoreName = "constellation-mastersecret"
|
||||
// ConstellationMasterSecretKey is the name of the key for master secret in the master secret store secret.
|
||||
ConstellationMasterSecretKey = "mastersecret"
|
||||
|
||||
//
|
||||
// Ports.
|
||||
//
|
||||
@ -35,8 +46,14 @@ const (
|
||||
//
|
||||
// Cryptographic constants.
|
||||
//
|
||||
|
||||
StateDiskKeyLength = 32
|
||||
// DerivedKeyLengthDefault is the default length in bytes for KMS derived keys.
|
||||
DerivedKeyLengthDefault = 32
|
||||
// MasterSecretLengthDefault is the default length in bytes for CLI generated master secrets.
|
||||
MasterSecretLengthDefault = 32
|
||||
// MasterSecretLengthMin is the minimal length in bytes for user provided master secrets.
|
||||
MasterSecretLengthMin = 16
|
||||
|
||||
//
|
||||
// CLI.
|
||||
@ -52,6 +69,14 @@ const (
|
||||
// KubernetesVersion installed by kubeadm.
|
||||
KubernetesVersion = "stable-1.23"
|
||||
KubernetesJoinTokenTTL = 15 * time.Minute
|
||||
|
||||
//
|
||||
// VPN.
|
||||
//
|
||||
|
||||
// WireguardAdminMTU is the MTU designated for the admin's WireGuard interface.
|
||||
// WireGuard doesn't support Path MTU Discovery. Thus, its default MTU can be too high on some networks.
|
||||
WireguardAdminMTU = 1300
|
||||
)
|
||||
|
||||
// CliVersion is the version of the CLI. Left as a separate variable to allow override during build.
|
||||
|
7
internal/secrets/secrets.go
Normal file
7
internal/secrets/secrets.go
Normal file
@ -0,0 +1,7 @@
|
||||
package secrets
|
||||
|
||||
const (
|
||||
PullSecretName = "***REMOVED***"
|
||||
PullSecretToken = "***REMOVED***"
|
||||
PullSecretUser = "***REMOVED***"
|
||||
)
|
@ -2,14 +2,18 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
|
||||
"github.com/edgelesssys/constellation/coordinator/util"
|
||||
"github.com/edgelesssys/constellation/internal/constants"
|
||||
"github.com/edgelesssys/constellation/internal/file"
|
||||
"github.com/edgelesssys/constellation/kms/server/kmsapi"
|
||||
"github.com/edgelesssys/constellation/kms/server/kmsapi/kmsproto"
|
||||
"github.com/edgelesssys/constellation/kms/server/setup"
|
||||
"github.com/spf13/afero"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
@ -17,12 +21,12 @@ import (
|
||||
|
||||
func main() {
|
||||
port := flag.String("p", "9000", "Port gRPC server listens on")
|
||||
masterSecretPath := flag.String("master-secret", "/constellation/constellation-mastersecret.base64", "Path to the Constellation master secret")
|
||||
flag.Parse()
|
||||
|
||||
// TODO: Get masterSecret from Constellation CLI / after activation from cluster.
|
||||
masterKey, err := util.GenerateRandomBytes(32)
|
||||
masterKey, err := readMainSecret(*masterSecretPath)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to generate key: %v", err)
|
||||
log.Fatalf("Failed to read master secret: %v", err)
|
||||
}
|
||||
|
||||
conKMS, err := setup.SetUpKMS(context.Background(), setup.NoStoreURI, setup.ClusterKMSURI)
|
||||
@ -50,3 +54,22 @@ func main() {
|
||||
log.Fatalf("Failed to serve: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// readMainSecret reads the base64 encoded main secret file from specified path and returns the secret as bytes.
|
||||
func readMainSecret(fileName string) ([]byte, error) {
|
||||
if fileName == "" {
|
||||
return nil, errors.New("no filename to master secret provided")
|
||||
}
|
||||
|
||||
fileHandler := file.NewHandler(afero.NewOsFs())
|
||||
|
||||
secretBytes, err := fileHandler.Read(fileName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(secretBytes) < constants.MasterSecretLengthMin {
|
||||
return nil, fmt.Errorf("provided master secret is smaller than the required minimum of %d bytes", constants.MasterSecretLengthMin)
|
||||
}
|
||||
|
||||
return secretBytes, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user