mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-24 23:19:39 -05:00
init: create kubeconfig file with unique user/cluster name (#1133)
* Generate kubeconfig with unique name * Move create name flag to config * Add name validation to config * Move name flag in e2e tests to config generation * Remove name flag from create * Update ascii cinema flow --------- Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
parent
fd860ddb91
commit
c29107f5be
@ -73,6 +73,8 @@ runs:
|
||||
run: |
|
||||
constellation config generate ${{ inputs.cloudProvider }}
|
||||
|
||||
yq eval -i "(.name) = \"e2e-test\"" constellation-conf.yaml
|
||||
|
||||
yq eval -i \
|
||||
"(.provider | select(. | has(\"azure\")).azure.subscription) = \"${{ inputs.azureSubscription }}\" |
|
||||
(.provider | select(. | has(\"azure\")).azure.tenant) = \"${{ inputs.azureTenant }}\" |
|
||||
@ -158,7 +160,7 @@ runs:
|
||||
echo "Creating cluster using config:"
|
||||
cat constellation-conf.yaml
|
||||
sudo sh -c 'echo "127.0.0.1 license.confidential.cloud" >> /etc/hosts' || true
|
||||
constellation create -c ${{ inputs.controlNodesCount }} -w ${{ inputs.workerNodesCount }} --name e2e-test -y --force
|
||||
constellation create -c ${{ inputs.controlNodesCount }} -w ${{ inputs.workerNodesCount }} -y --force
|
||||
|
||||
- name: Cdbg deploy
|
||||
if: inputs.isDebugImage == 'true'
|
||||
|
@ -21,7 +21,7 @@ type clusterFake struct{}
|
||||
|
||||
// InitCluster fakes bootstrapping a new cluster with the current node being the master, returning the arguments required to join the cluster.
|
||||
func (c *clusterFake) InitCluster(
|
||||
context.Context, string, string, []byte, []uint32, bool, bool,
|
||||
context.Context, string, string, string, []byte, []uint32, bool, bool,
|
||||
[]byte, bool, components.Components, *logger.Logger,
|
||||
) ([]byte, error) {
|
||||
return []byte{}, nil
|
||||
|
@ -41,6 +41,7 @@ type InitRequest struct {
|
||||
ConformanceMode bool `protobuf:"varint,14,opt,name=conformance_mode,json=conformanceMode,proto3" json:"conformance_mode,omitempty"`
|
||||
KubernetesComponents []*KubernetesComponent `protobuf:"bytes,15,rep,name=kubernetes_components,json=kubernetesComponents,proto3" json:"kubernetes_components,omitempty"`
|
||||
InitSecret []byte `protobuf:"bytes,16,opt,name=init_secret,json=initSecret,proto3" json:"init_secret,omitempty"`
|
||||
ClusterName string `protobuf:"bytes,17,opt,name=cluster_name,json=clusterName,proto3" json:"cluster_name,omitempty"`
|
||||
}
|
||||
|
||||
func (x *InitRequest) Reset() {
|
||||
@ -173,6 +174,13 @@ func (x *InitRequest) GetInitSecret() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *InitRequest) GetClusterName() string {
|
||||
if x != nil {
|
||||
return x.ClusterName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type InitResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@ -311,7 +319,7 @@ var File_init_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_init_proto_rawDesc = []byte{
|
||||
0x0a, 0x0a, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x69, 0x6e,
|
||||
0x69, 0x74, 0x22, 0xe4, 0x04, 0x0a, 0x0b, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x69, 0x74, 0x22, 0x87, 0x05, 0x0a, 0x0b, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x65, 0x63,
|
||||
0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6d, 0x61, 0x73, 0x74, 0x65,
|
||||
0x72, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x6b, 0x6d, 0x73, 0x5f, 0x75,
|
||||
@ -349,29 +357,31 @@ var file_init_proto_rawDesc = []byte{
|
||||
0x6e, 0x74, 0x52, 0x14, 0x6b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65, 0x73, 0x43, 0x6f,
|
||||
0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x69, 0x74,
|
||||
0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x69,
|
||||
0x6e, 0x69, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x68, 0x0a, 0x0c, 0x49, 0x6e, 0x69,
|
||||
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x6b, 0x75, 0x62,
|
||||
0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x6b,
|
||||
0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x77, 0x6e,
|
||||
0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x77, 0x6e,
|
||||
0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65,
|
||||
0x72, 0x49, 0x64, 0x22, 0x78, 0x0a, 0x13, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x65,
|
||||
0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72,
|
||||
0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04,
|
||||
0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68,
|
||||
0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x70, 0x61, 0x74, 0x68,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x50,
|
||||
0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x04,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x32, 0x34, 0x0a,
|
||||
0x03, 0x41, 0x50, 0x49, 0x12, 0x2d, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74, 0x12, 0x11, 0x2e, 0x69,
|
||||
0x6e, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x12, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
|
||||
0x6d, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x79, 0x73, 0x2f, 0x63, 0x6f,
|
||||
0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x32, 0x2f, 0x62,
|
||||
0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x69, 0x74,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x6e, 0x69, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6c, 0x75,
|
||||
0x73, 0x74, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x68, 0x0a, 0x0c,
|
||||
0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a,
|
||||
0x6b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
|
||||
0x52, 0x0a, 0x6b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, 0x0a, 0x08,
|
||||
0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07,
|
||||
0x6f, 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x6c, 0x75, 0x73, 0x74,
|
||||
0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x63, 0x6c, 0x75,
|
||||
0x73, 0x74, 0x65, 0x72, 0x49, 0x64, 0x22, 0x78, 0x0a, 0x13, 0x4b, 0x75, 0x62, 0x65, 0x72, 0x6e,
|
||||
0x65, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 0x65, 0x6e, 0x74, 0x12, 0x10, 0x0a,
|
||||
0x03, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12,
|
||||
0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68,
|
||||
0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x5f, 0x70,
|
||||
0x61, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61,
|
||||
0x6c, 0x6c, 0x50, 0x61, 0x74, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63,
|
||||
0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74,
|
||||
0x32, 0x34, 0x0a, 0x03, 0x41, 0x50, 0x49, 0x12, 0x2d, 0x0a, 0x04, 0x49, 0x6e, 0x69, 0x74, 0x12,
|
||||
0x11, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x12, 0x2e, 0x69, 0x6e, 0x69, 0x74, 0x2e, 0x49, 0x6e, 0x69, 0x74, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x64, 0x67, 0x65, 0x6c, 0x65, 0x73, 0x73, 0x73, 0x79, 0x73,
|
||||
0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x65, 0x6c, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76,
|
||||
0x32, 0x2f, 0x62, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x2f, 0x69,
|
||||
0x6e, 0x69, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -25,6 +25,7 @@ message InitRequest {
|
||||
bool conformance_mode = 14;
|
||||
repeated KubernetesComponent kubernetes_components = 15;
|
||||
bytes init_secret = 16;
|
||||
string cluster_name = 17;
|
||||
}
|
||||
|
||||
message InitResponse {
|
||||
|
@ -161,9 +161,15 @@ func (s *Server) Init(ctx context.Context, req *initproto.InitRequest) (*initpro
|
||||
// Check if we are running on a CVM
|
||||
_, isCVM := s.issuer.(*snp.Issuer)
|
||||
|
||||
clusterName := req.ClusterName
|
||||
if clusterName == "" {
|
||||
clusterName = "constellation"
|
||||
}
|
||||
|
||||
kubeconfig, err := s.initializer.InitCluster(ctx,
|
||||
req.CloudServiceAccountUri,
|
||||
req.KubernetesVersion,
|
||||
clusterName,
|
||||
measurementSalt,
|
||||
req.EnforcedPcrs,
|
||||
req.EnforceIdkeydigest,
|
||||
@ -237,6 +243,7 @@ type ClusterInitializer interface {
|
||||
ctx context.Context,
|
||||
cloudServiceAccountURI string,
|
||||
k8sVersion string,
|
||||
clusterName string,
|
||||
measurementSalt []byte,
|
||||
enforcedPcrs []uint32,
|
||||
enforceIDKeyDigest bool,
|
||||
|
@ -314,7 +314,7 @@ type stubClusterInitializer struct {
|
||||
}
|
||||
|
||||
func (i *stubClusterInitializer) InitCluster(
|
||||
context.Context, string, string, []byte, []uint32, bool, bool,
|
||||
context.Context, string, string, string, []byte, []uint32, bool, bool,
|
||||
[]byte, bool, components.Components, *logger.Logger,
|
||||
) ([]byte, error) {
|
||||
return i.initClusterKubeconfig, i.initClusterErr
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
"github.com/edgelesssys/constellation/v2/internal/role"
|
||||
"github.com/edgelesssys/constellation/v2/internal/versions/components"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
kubeconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/crypto"
|
||||
@ -87,25 +88,26 @@ func (k *KubernetesUtil) InstallComponents(ctx context.Context, kubernetesCompon
|
||||
}
|
||||
|
||||
// InitCluster instruments kubeadm to initialize the K8s cluster.
|
||||
// On success an admin kubeconfig file is returned.
|
||||
func (k *KubernetesUtil) InitCluster(
|
||||
ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, controlPlaneEndpoint string, conformanceMode bool, log *logger.Logger,
|
||||
) error {
|
||||
ctx context.Context, initConfig []byte, nodeName, clusterName string, ips []net.IP, controlPlaneEndpoint string, conformanceMode bool, log *logger.Logger,
|
||||
) ([]byte, error) {
|
||||
// TODO: audit policy should be user input
|
||||
auditPolicy, err := resources.NewDefaultAuditPolicy().Marshal()
|
||||
if err != nil {
|
||||
return fmt.Errorf("generating default audit policy: %w", err)
|
||||
return nil, fmt.Errorf("generating default audit policy: %w", err)
|
||||
}
|
||||
if err := os.WriteFile(auditPolicyPath, auditPolicy, 0o644); err != nil {
|
||||
return fmt.Errorf("writing default audit policy: %w", err)
|
||||
return nil, fmt.Errorf("writing default audit policy: %w", err)
|
||||
}
|
||||
|
||||
initConfigFile, err := os.CreateTemp("", "kubeadm-init.*.yaml")
|
||||
if err != nil {
|
||||
return fmt.Errorf("creating init config file %v: %w", initConfigFile.Name(), err)
|
||||
return nil, fmt.Errorf("creating init config file %v: %w", initConfigFile.Name(), err)
|
||||
}
|
||||
|
||||
if _, err := initConfigFile.Write(initConfig); err != nil {
|
||||
return fmt.Errorf("writing kubeadm init yaml config %v: %w", initConfigFile.Name(), err)
|
||||
return nil, fmt.Errorf("writing kubeadm init yaml config %v: %w", initConfigFile.Name(), err)
|
||||
}
|
||||
|
||||
// preflight
|
||||
@ -115,9 +117,9 @@ func (k *KubernetesUtil) InitCluster(
|
||||
if err != nil {
|
||||
var exitErr *exec.ExitError
|
||||
if errors.As(err, &exitErr) {
|
||||
return fmt.Errorf("kubeadm init phase preflight failed (code %v) with: %s", exitErr.ExitCode(), out)
|
||||
return nil, fmt.Errorf("kubeadm init phase preflight failed (code %v) with: %s", exitErr.ExitCode(), out)
|
||||
}
|
||||
return fmt.Errorf("kubeadm init: %w", err)
|
||||
return nil, fmt.Errorf("kubeadm init: %w", err)
|
||||
}
|
||||
|
||||
// create CA certs
|
||||
@ -127,20 +129,20 @@ func (k *KubernetesUtil) InitCluster(
|
||||
if err != nil {
|
||||
var exitErr *exec.ExitError
|
||||
if errors.As(err, &exitErr) {
|
||||
return fmt.Errorf("kubeadm init phase certs all failed (code %v) with: %s", exitErr.ExitCode(), out)
|
||||
return nil, fmt.Errorf("kubeadm init phase certs all failed (code %v) with: %s", exitErr.ExitCode(), out)
|
||||
}
|
||||
return fmt.Errorf("kubeadm init: %w", err)
|
||||
return nil, fmt.Errorf("kubeadm init: %w", err)
|
||||
}
|
||||
|
||||
// create kubelet key and CA signed certificate for the node
|
||||
log.Infof("Creating signed kubelet certificate")
|
||||
if err := k.createSignedKubeletCert(nodeName, ips); err != nil {
|
||||
return err
|
||||
return nil, fmt.Errorf("creating signed kubelete certificate: %w", err)
|
||||
}
|
||||
|
||||
log.Infof("Preparing node for Konnectivity")
|
||||
if err := k.prepareControlPlaneForKonnectivity(ctx, controlPlaneEndpoint); err != nil {
|
||||
return fmt.Errorf("setup konnectivity: %w", err)
|
||||
return nil, fmt.Errorf("setup konnectivity: %w", err)
|
||||
}
|
||||
|
||||
// initialize the cluster
|
||||
@ -155,12 +157,29 @@ func (k *KubernetesUtil) InitCluster(
|
||||
if err != nil {
|
||||
var exitErr *exec.ExitError
|
||||
if errors.As(err, &exitErr) {
|
||||
return fmt.Errorf("kubeadm init failed (code %v) with: %s", exitErr.ExitCode(), out)
|
||||
return nil, fmt.Errorf("kubeadm init failed (code %v) with: %s", exitErr.ExitCode(), out)
|
||||
}
|
||||
return fmt.Errorf("kubeadm init: %w", err)
|
||||
return nil, fmt.Errorf("kubeadm init: %w", err)
|
||||
}
|
||||
log.With(zap.String("output", string(out))).Infof("kubeadm init succeeded")
|
||||
return nil
|
||||
|
||||
userName := clusterName + "-admin"
|
||||
|
||||
log.With(zap.String("userName", userName)).Infof("Creating admin kubeconfig file")
|
||||
cmd = exec.CommandContext(
|
||||
ctx, constants.KubeadmPath, "kubeconfig", "user",
|
||||
"--client-name", userName, "--config", initConfigFile.Name(), "--org", user.SystemPrivilegedGroup,
|
||||
)
|
||||
out, err = cmd.Output()
|
||||
if err != nil {
|
||||
var exitErr *exec.ExitError
|
||||
if errors.As(err, &exitErr) {
|
||||
return nil, fmt.Errorf("kubeadm kubeconfig user failed (code %v) with: %s", exitErr.ExitCode(), out)
|
||||
}
|
||||
return nil, fmt.Errorf("kubeadm kubeconfig user: %w", err)
|
||||
}
|
||||
log.Infof("kubeadm kubeconfig user succeeded")
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (k *KubernetesUtil) prepareControlPlaneForKonnectivity(ctx context.Context, loadBalancerEndpoint string) error {
|
||||
|
@ -271,6 +271,12 @@ func (k *KubeadmInitYAML) SetNodeName(nodeName string) {
|
||||
k.InitConfiguration.NodeRegistration.Name = nodeName
|
||||
}
|
||||
|
||||
// SetClusterName sets the name of the Kubernetes cluster.
|
||||
// This name is reflected in the kubeconfig file and in the name of the default admin user.
|
||||
func (k *KubeadmInitYAML) SetClusterName(clusterName string) {
|
||||
k.ClusterConfiguration.ClusterName = clusterName
|
||||
}
|
||||
|
||||
// SetCertSANs sets the SANs for the certificate.
|
||||
func (k *KubeadmInitYAML) SetCertSANs(certSANs []string) {
|
||||
for _, certSAN := range certSANs {
|
||||
|
@ -19,7 +19,7 @@ import (
|
||||
|
||||
type clusterUtil interface {
|
||||
InstallComponents(ctx context.Context, kubernetesComponents components.Components) error
|
||||
InitCluster(ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, controlPlaneEndpoint string, conformanceMode bool, log *logger.Logger) error
|
||||
InitCluster(ctx context.Context, initConfig []byte, nodeName, clusterName string, ips []net.IP, controlPlaneEndpoint string, conformanceMode bool, log *logger.Logger) ([]byte, error)
|
||||
JoinCluster(ctx context.Context, joinConfig []byte, peerRole role.Role, controlPlaneEndpoint string, log *logger.Logger) error
|
||||
FixCilium(log *logger.Logger)
|
||||
StartKubelet() error
|
||||
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package kubernetes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
const kubeconfigPath = "/etc/kubernetes/admin.conf"
|
||||
|
||||
// KubeconfigReader implements ConfigReader.
|
||||
type KubeconfigReader struct {
|
||||
fs afero.Afero
|
||||
}
|
||||
|
||||
// ReadKubeconfig reads the Kubeconfig from disk.
|
||||
func (r KubeconfigReader) ReadKubeconfig() ([]byte, error) {
|
||||
kubeconfig, err := r.fs.ReadFile(kubeconfigPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading kubernetes config: %w", err)
|
||||
}
|
||||
return kubeconfig, nil
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package kubernetes
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestReadKubeconfig(t *testing.T) {
|
||||
require := require.New(t)
|
||||
assert := assert.New(t)
|
||||
fs := afero.Afero{
|
||||
Fs: afero.NewMemMapFs(),
|
||||
}
|
||||
require.NoError(fs.WriteFile(kubeconfigPath, []byte("someConfig"), 0o644))
|
||||
reader := KubeconfigReader{fs}
|
||||
config, err := reader.ReadKubeconfig()
|
||||
|
||||
require.NoError(err)
|
||||
assert.Equal([]byte("someConfig"), config)
|
||||
}
|
||||
|
||||
func TestReadKubeconfigFails(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
fs := afero.Afero{
|
||||
Fs: afero.NewMemMapFs(),
|
||||
}
|
||||
reader := KubeconfigReader{fs}
|
||||
_, err := reader.ReadKubeconfig()
|
||||
|
||||
assert.Error(err)
|
||||
}
|
@ -30,7 +30,6 @@ import (
|
||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||
"github.com/edgelesssys/constellation/v2/internal/role"
|
||||
"github.com/edgelesssys/constellation/v2/internal/versions/components"
|
||||
"github.com/spf13/afero"
|
||||
"go.uber.org/zap"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@ -39,11 +38,6 @@ import (
|
||||
|
||||
var validHostnameRegex = regexp.MustCompile(`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`)
|
||||
|
||||
// configReader provides kubeconfig as []byte.
|
||||
type configReader interface {
|
||||
ReadKubeconfig() ([]byte, error)
|
||||
}
|
||||
|
||||
// configurationProvider provides kubeadm init and join configuration.
|
||||
type configurationProvider interface {
|
||||
InitConfiguration(externalCloudProvider bool, k8sVersion string) k8sapi.KubeadmInitYAML
|
||||
@ -62,7 +56,6 @@ type KubeWrapper struct {
|
||||
kubeAPIWaiter kubeAPIWaiter
|
||||
configProvider configurationProvider
|
||||
client k8sapi.Client
|
||||
kubeconfigReader configReader
|
||||
providerMetadata ProviderMetadata
|
||||
initialMeasurements measurements.M
|
||||
getIPAddr func() (string, error)
|
||||
@ -79,7 +72,6 @@ func New(cloudProvider string, clusterUtil clusterUtil, configProvider configura
|
||||
kubeAPIWaiter: kubeAPIWaiter,
|
||||
configProvider: configProvider,
|
||||
client: client,
|
||||
kubeconfigReader: &KubeconfigReader{fs: afero.Afero{Fs: afero.NewOsFs()}},
|
||||
providerMetadata: providerMetadata,
|
||||
initialMeasurements: measurements,
|
||||
getIPAddr: getIPAddr,
|
||||
@ -88,8 +80,8 @@ func New(cloudProvider string, clusterUtil clusterUtil, configProvider configura
|
||||
|
||||
// InitCluster initializes a new Kubernetes cluster and applies pod network provider.
|
||||
func (k *KubeWrapper) InitCluster(
|
||||
ctx context.Context, cloudServiceAccountURI, versionString string, measurementSalt []byte, enforcedPCRs []uint32,
|
||||
enforceIDKeyDigest bool, azureCVM bool,
|
||||
ctx context.Context, cloudServiceAccountURI, versionString, clusterName string,
|
||||
measurementSalt []byte, enforcedPCRs []uint32, enforceIDKeyDigest bool, azureCVM bool,
|
||||
helmReleasesRaw []byte, conformanceMode bool, kubernetesComponents components.Components, log *logger.Logger,
|
||||
) ([]byte, error) {
|
||||
log.With(zap.String("version", versionString)).Infof("Installing Kubernetes components")
|
||||
@ -139,6 +131,7 @@ func (k *KubeWrapper) InitCluster(
|
||||
cloudprovider.FromString(k.cloudProvider) == cloudprovider.GCP
|
||||
initConfig := k.configProvider.InitConfiguration(ccmSupported, versionString)
|
||||
initConfig.SetNodeIP(nodeIP)
|
||||
initConfig.SetClusterName(clusterName)
|
||||
initConfig.SetCertSANs([]string{nodeIP})
|
||||
initConfig.SetNodeName(nodeName)
|
||||
initConfig.SetProviderID(instance.ProviderID)
|
||||
@ -148,13 +141,11 @@ func (k *KubeWrapper) InitCluster(
|
||||
return nil, fmt.Errorf("encoding kubeadm init configuration as YAML: %w", err)
|
||||
}
|
||||
log.Infof("Initializing Kubernetes cluster")
|
||||
if err := k.clusterUtil.InitCluster(ctx, initConfigYAML, nodeName, validIPs, controlPlaneEndpoint, conformanceMode, log); err != nil {
|
||||
kubeConfig, err := k.clusterUtil.InitCluster(ctx, initConfigYAML, nodeName, clusterName, validIPs, controlPlaneEndpoint, conformanceMode, log)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("kubeadm init: %w", err)
|
||||
}
|
||||
kubeConfig, err := k.GetKubeconfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("reading kubeconfig after cluster initialization: %w", err)
|
||||
}
|
||||
|
||||
err = k.client.Initialize(kubeConfig)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("initializing kubectl client: %w", err)
|
||||
@ -250,7 +241,7 @@ func (k *KubeWrapper) InitCluster(
|
||||
|
||||
k.clusterUtil.FixCilium(log)
|
||||
|
||||
return k.GetKubeconfig()
|
||||
return kubeConfig, nil
|
||||
}
|
||||
|
||||
// JoinCluster joins existing Kubernetes cluster.
|
||||
@ -311,11 +302,6 @@ func (k *KubeWrapper) JoinCluster(ctx context.Context, args *kubeadm.BootstrapTo
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetKubeconfig returns the current nodes kubeconfig of stored on disk.
|
||||
func (k *KubeWrapper) GetKubeconfig() ([]byte, error) {
|
||||
return k.kubeconfigReader.ReadKubeconfig()
|
||||
}
|
||||
|
||||
// setupK8sComponentsConfigMap applies a ConfigMap (cf. server-side apply) to store the installed k8s components.
|
||||
// It returns the name of the ConfigMap.
|
||||
func (k *KubeWrapper) setupK8sComponentsConfigMap(ctx context.Context, components components.Components, clusterVersion string) (string, error) {
|
||||
|
@ -50,16 +50,12 @@ func TestInitCluster(t *testing.T) {
|
||||
kubectl stubKubectl
|
||||
kubeAPIWaiter stubKubeAPIWaiter
|
||||
providerMetadata ProviderMetadata
|
||||
kubeconfigReader configReader
|
||||
wantConfig k8sapi.KubeadmInitYAML
|
||||
wantErr bool
|
||||
k8sVersion versions.ValidK8sVersion
|
||||
}{
|
||||
"kubeadm init works with metadata and loadbalancer": {
|
||||
clusterUtil: stubClusterUtil{},
|
||||
kubeconfigReader: &stubKubeconfigReader{
|
||||
kubeconfig: []byte("someKubeconfig"),
|
||||
},
|
||||
clusterUtil: stubClusterUtil{kubeconfig: []byte("someKubeconfig")},
|
||||
kubeAPIWaiter: stubKubeAPIWaiter{},
|
||||
providerMetadata: &stubProviderMetadata{
|
||||
selfResp: metadata.InstanceMetadata{
|
||||
@ -81,6 +77,7 @@ func TestInitCluster(t *testing.T) {
|
||||
},
|
||||
},
|
||||
ClusterConfiguration: kubeadm.ClusterConfiguration{
|
||||
ClusterName: "kubernetes",
|
||||
ControlPlaneEndpoint: loadbalancerIP,
|
||||
APIServer: kubeadm.APIServer{
|
||||
CertSANs: []string{privateIP},
|
||||
@ -91,10 +88,7 @@ func TestInitCluster(t *testing.T) {
|
||||
k8sVersion: versions.Default,
|
||||
},
|
||||
"kubeadm init fails when annotating itself": {
|
||||
clusterUtil: stubClusterUtil{},
|
||||
kubeconfigReader: &stubKubeconfigReader{
|
||||
kubeconfig: []byte("someKubeconfig"),
|
||||
},
|
||||
clusterUtil: stubClusterUtil{kubeconfig: []byte("someKubeconfig")},
|
||||
kubeAPIWaiter: stubKubeAPIWaiter{},
|
||||
providerMetadata: &stubProviderMetadata{
|
||||
selfResp: metadata.InstanceMetadata{
|
||||
@ -110,10 +104,7 @@ func TestInitCluster(t *testing.T) {
|
||||
k8sVersion: versions.Default,
|
||||
},
|
||||
"kubeadm init fails when retrieving metadata self": {
|
||||
clusterUtil: stubClusterUtil{},
|
||||
kubeconfigReader: &stubKubeconfigReader{
|
||||
kubeconfig: []byte("someKubeconfig"),
|
||||
},
|
||||
clusterUtil: stubClusterUtil{kubeconfig: []byte("someKubeconfig")},
|
||||
kubeAPIWaiter: stubKubeAPIWaiter{},
|
||||
providerMetadata: &stubProviderMetadata{
|
||||
selfErr: someErr,
|
||||
@ -122,10 +113,7 @@ func TestInitCluster(t *testing.T) {
|
||||
k8sVersion: versions.Default,
|
||||
},
|
||||
"kubeadm init fails when retrieving metadata loadbalancer ip": {
|
||||
clusterUtil: stubClusterUtil{},
|
||||
kubeconfigReader: &stubKubeconfigReader{
|
||||
kubeconfig: []byte("someKubeconfig"),
|
||||
},
|
||||
clusterUtil: stubClusterUtil{kubeconfig: []byte("someKubeconfig")},
|
||||
providerMetadata: &stubProviderMetadata{
|
||||
getLoadBalancerEndpointErr: someErr,
|
||||
},
|
||||
@ -133,9 +121,9 @@ func TestInitCluster(t *testing.T) {
|
||||
k8sVersion: versions.Default,
|
||||
},
|
||||
"kubeadm init fails when applying the init config": {
|
||||
clusterUtil: stubClusterUtil{initClusterErr: someErr},
|
||||
kubeconfigReader: &stubKubeconfigReader{
|
||||
kubeconfig: []byte("someKubeconfig"),
|
||||
clusterUtil: stubClusterUtil{
|
||||
initClusterErr: someErr,
|
||||
kubeconfig: []byte("someKubeconfig"),
|
||||
},
|
||||
kubeAPIWaiter: stubKubeAPIWaiter{},
|
||||
providerMetadata: &stubProviderMetadata{},
|
||||
@ -143,95 +131,67 @@ func TestInitCluster(t *testing.T) {
|
||||
k8sVersion: versions.Default,
|
||||
},
|
||||
"kubeadm init fails when deploying cilium": {
|
||||
clusterUtil: stubClusterUtil{},
|
||||
helmClient: stubHelmClient{ciliumError: someErr},
|
||||
kubeconfigReader: &stubKubeconfigReader{
|
||||
kubeconfig: []byte("someKubeconfig"),
|
||||
},
|
||||
clusterUtil: stubClusterUtil{kubeconfig: []byte("someKubeconfig")},
|
||||
helmClient: stubHelmClient{ciliumError: someErr},
|
||||
providerMetadata: &stubProviderMetadata{},
|
||||
wantErr: true,
|
||||
k8sVersion: versions.Default,
|
||||
},
|
||||
"kubeadm init fails when setting up constellation-services chart": {
|
||||
clusterUtil: stubClusterUtil{},
|
||||
helmClient: stubHelmClient{servicesError: someErr},
|
||||
kubeconfigReader: &stubKubeconfigReader{
|
||||
kubeconfig: []byte("someKubeconfig"),
|
||||
},
|
||||
clusterUtil: stubClusterUtil{kubeconfig: []byte("someKubeconfig")},
|
||||
helmClient: stubHelmClient{servicesError: someErr},
|
||||
kubeAPIWaiter: stubKubeAPIWaiter{},
|
||||
providerMetadata: &stubProviderMetadata{},
|
||||
wantErr: true,
|
||||
k8sVersion: versions.Default,
|
||||
},
|
||||
"kubeadm init fails when setting the cloud node manager": {
|
||||
clusterUtil: stubClusterUtil{},
|
||||
helmClient: stubHelmClient{servicesError: someErr},
|
||||
kubeconfigReader: &stubKubeconfigReader{
|
||||
kubeconfig: []byte("someKubeconfig"),
|
||||
},
|
||||
clusterUtil: stubClusterUtil{kubeconfig: []byte("someKubeconfig")},
|
||||
helmClient: stubHelmClient{servicesError: someErr},
|
||||
kubeAPIWaiter: stubKubeAPIWaiter{},
|
||||
providerMetadata: &stubProviderMetadata{},
|
||||
wantErr: true,
|
||||
k8sVersion: versions.Default,
|
||||
},
|
||||
"kubeadm init fails when setting the cluster autoscaler": {
|
||||
clusterUtil: stubClusterUtil{},
|
||||
helmClient: stubHelmClient{servicesError: someErr},
|
||||
kubeconfigReader: &stubKubeconfigReader{
|
||||
kubeconfig: []byte("someKubeconfig"),
|
||||
},
|
||||
clusterUtil: stubClusterUtil{kubeconfig: []byte("someKubeconfig")},
|
||||
helmClient: stubHelmClient{servicesError: someErr},
|
||||
kubeAPIWaiter: stubKubeAPIWaiter{},
|
||||
providerMetadata: &stubProviderMetadata{},
|
||||
wantErr: true,
|
||||
k8sVersion: versions.Default,
|
||||
},
|
||||
"kubeadm init fails when reading kubeconfig": {
|
||||
clusterUtil: stubClusterUtil{},
|
||||
kubeconfigReader: &stubKubeconfigReader{
|
||||
readErr: someErr,
|
||||
},
|
||||
clusterUtil: stubClusterUtil{kubeconfig: []byte("someKubeconfig")},
|
||||
kubeAPIWaiter: stubKubeAPIWaiter{},
|
||||
providerMetadata: &stubProviderMetadata{},
|
||||
wantErr: true,
|
||||
k8sVersion: versions.Default,
|
||||
},
|
||||
"kubeadm init fails when setting up konnectivity": {
|
||||
clusterUtil: stubClusterUtil{},
|
||||
helmClient: stubHelmClient{servicesError: someErr},
|
||||
kubeconfigReader: &stubKubeconfigReader{
|
||||
kubeconfig: []byte("someKubeconfig"),
|
||||
},
|
||||
clusterUtil: stubClusterUtil{kubeconfig: []byte("someKubeconfig")},
|
||||
helmClient: stubHelmClient{servicesError: someErr},
|
||||
kubeAPIWaiter: stubKubeAPIWaiter{},
|
||||
providerMetadata: &stubProviderMetadata{},
|
||||
wantErr: true,
|
||||
k8sVersion: versions.Default,
|
||||
},
|
||||
"kubeadm init fails when setting up verification service": {
|
||||
clusterUtil: stubClusterUtil{},
|
||||
helmClient: stubHelmClient{servicesError: someErr},
|
||||
kubeconfigReader: &stubKubeconfigReader{
|
||||
kubeconfig: []byte("someKubeconfig"),
|
||||
},
|
||||
clusterUtil: stubClusterUtil{kubeconfig: []byte("someKubeconfig")},
|
||||
kubeAPIWaiter: stubKubeAPIWaiter{},
|
||||
providerMetadata: &stubProviderMetadata{},
|
||||
wantErr: true,
|
||||
k8sVersion: versions.Default,
|
||||
},
|
||||
"kubeadm init fails when waiting for kubeAPI server": {
|
||||
clusterUtil: stubClusterUtil{},
|
||||
kubeconfigReader: &stubKubeconfigReader{
|
||||
kubeconfig: []byte("someKubeconfig"),
|
||||
},
|
||||
clusterUtil: stubClusterUtil{kubeconfig: []byte("someKubeconfig")},
|
||||
kubeAPIWaiter: stubKubeAPIWaiter{waitErr: someErr},
|
||||
providerMetadata: &stubProviderMetadata{},
|
||||
k8sVersion: versions.Default,
|
||||
wantErr: true,
|
||||
},
|
||||
"unsupported k8sVersion fails cluster creation": {
|
||||
clusterUtil: stubClusterUtil{},
|
||||
kubeconfigReader: &stubKubeconfigReader{
|
||||
kubeconfig: []byte("someKubeconfig"),
|
||||
},
|
||||
clusterUtil: stubClusterUtil{kubeconfig: []byte("someKubeconfig")},
|
||||
kubeAPIWaiter: stubKubeAPIWaiter{},
|
||||
providerMetadata: &stubProviderMetadata{},
|
||||
k8sVersion: "1.19",
|
||||
@ -251,12 +211,11 @@ func TestInitCluster(t *testing.T) {
|
||||
kubeAPIWaiter: &tc.kubeAPIWaiter,
|
||||
configProvider: &stubConfigProvider{initConfig: k8sapi.KubeadmInitYAML{}},
|
||||
client: &tc.kubectl,
|
||||
kubeconfigReader: tc.kubeconfigReader,
|
||||
getIPAddr: func() (string, error) { return privateIP, nil },
|
||||
}
|
||||
|
||||
_, err := kube.InitCluster(
|
||||
context.Background(), serviceAccountURI, string(tc.k8sVersion),
|
||||
context.Background(), serviceAccountURI, string(tc.k8sVersion), "kubernetes",
|
||||
nil, nil, false, true, []byte("{}"), false, nil, logger.NewTest(t),
|
||||
)
|
||||
|
||||
@ -503,6 +462,8 @@ type stubClusterUtil struct {
|
||||
joinClusterErr error
|
||||
startKubeletErr error
|
||||
|
||||
kubeconfig []byte
|
||||
|
||||
initConfigs [][]byte
|
||||
joinConfigs [][]byte
|
||||
}
|
||||
@ -515,9 +476,9 @@ func (s *stubClusterUtil) InstallComponents(ctx context.Context, kubernetesCompo
|
||||
return s.installComponentsErr
|
||||
}
|
||||
|
||||
func (s *stubClusterUtil) InitCluster(ctx context.Context, initConfig []byte, nodeName string, ips []net.IP, controlPlaneEndpoint string, conformanceMode bool, log *logger.Logger) error {
|
||||
func (s *stubClusterUtil) InitCluster(ctx context.Context, initConfig []byte, nodeName, clusterName string, ips []net.IP, controlPlaneEndpoint string, conformanceMode bool, log *logger.Logger) ([]byte, error) {
|
||||
s.initConfigs = append(s.initConfigs, initConfig)
|
||||
return s.initClusterErr
|
||||
return s.kubeconfig, s.initClusterErr
|
||||
}
|
||||
|
||||
func (s *stubClusterUtil) SetupAutoscaling(kubectl k8sapi.Client, clusterAutoscalerConfiguration kubernetes.Marshaler, secrets kubernetes.Marshaler) error {
|
||||
@ -611,15 +572,6 @@ func (s *stubKubectl) ListAllNamespaces(ctx context.Context) (*corev1.NamespaceL
|
||||
return s.listAllNamespacesResp, s.listAllNamespacesErr
|
||||
}
|
||||
|
||||
type stubKubeconfigReader struct {
|
||||
kubeconfig []byte
|
||||
readErr error
|
||||
}
|
||||
|
||||
func (s *stubKubeconfigReader) ReadKubeconfig() ([]byte, error) {
|
||||
return s.kubeconfig, s.readErr
|
||||
}
|
||||
|
||||
type stubHelmClient struct {
|
||||
ciliumError error
|
||||
certManagerError error
|
||||
|
@ -53,7 +53,7 @@ func NewCreator(out io.Writer) *Creator {
|
||||
}
|
||||
|
||||
// Create creates the handed amount of instances and all the needed resources.
|
||||
func (c *Creator) Create(ctx context.Context, provider cloudprovider.Provider, config *config.Config, name, insType string, controlPlaneCount, workerCount int,
|
||||
func (c *Creator) Create(ctx context.Context, provider cloudprovider.Provider, config *config.Config, insType string, controlPlaneCount, workerCount int,
|
||||
) (clusterid.File, error) {
|
||||
image, err := c.image.FetchReference(ctx, config)
|
||||
if err != nil {
|
||||
@ -67,21 +67,21 @@ func (c *Creator) Create(ctx context.Context, provider cloudprovider.Provider, c
|
||||
return clusterid.File{}, err
|
||||
}
|
||||
defer cl.RemoveInstaller()
|
||||
return c.createAWS(ctx, cl, config, name, insType, controlPlaneCount, workerCount, image)
|
||||
return c.createAWS(ctx, cl, config, insType, controlPlaneCount, workerCount, image)
|
||||
case cloudprovider.GCP:
|
||||
cl, err := c.newTerraformClient(ctx)
|
||||
if err != nil {
|
||||
return clusterid.File{}, err
|
||||
}
|
||||
defer cl.RemoveInstaller()
|
||||
return c.createGCP(ctx, cl, config, name, insType, controlPlaneCount, workerCount, image)
|
||||
return c.createGCP(ctx, cl, config, insType, controlPlaneCount, workerCount, image)
|
||||
case cloudprovider.Azure:
|
||||
cl, err := c.newTerraformClient(ctx)
|
||||
if err != nil {
|
||||
return clusterid.File{}, err
|
||||
}
|
||||
defer cl.RemoveInstaller()
|
||||
return c.createAzure(ctx, cl, config, name, insType, controlPlaneCount, workerCount, image)
|
||||
return c.createAzure(ctx, cl, config, insType, controlPlaneCount, workerCount, image)
|
||||
case cloudprovider.QEMU:
|
||||
if runtime.GOARCH != "amd64" || runtime.GOOS != "linux" {
|
||||
return clusterid.File{}, fmt.Errorf("creation of a QEMU based Constellation is not supported for %s/%s", runtime.GOOS, runtime.GOARCH)
|
||||
@ -92,18 +92,18 @@ func (c *Creator) Create(ctx context.Context, provider cloudprovider.Provider, c
|
||||
}
|
||||
defer cl.RemoveInstaller()
|
||||
lv := c.newLibvirtRunner()
|
||||
return c.createQEMU(ctx, cl, lv, name, config, controlPlaneCount, workerCount, image)
|
||||
return c.createQEMU(ctx, cl, lv, config, controlPlaneCount, workerCount, image)
|
||||
default:
|
||||
return clusterid.File{}, fmt.Errorf("unsupported cloud provider: %s", provider)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Creator) createAWS(ctx context.Context, cl terraformClient, config *config.Config,
|
||||
name, insType string, controlPlaneCount, workerCount int, image string,
|
||||
insType string, controlPlaneCount, workerCount int, image string,
|
||||
) (idFile clusterid.File, retErr error) {
|
||||
vars := terraform.AWSClusterVariables{
|
||||
CommonVariables: terraform.CommonVariables{
|
||||
Name: name,
|
||||
Name: config.Name,
|
||||
CountControlPlanes: controlPlaneCount,
|
||||
CountWorkers: workerCount,
|
||||
StateDiskSizeGB: config.StateDiskSizeGB,
|
||||
@ -137,11 +137,11 @@ func (c *Creator) createAWS(ctx context.Context, cl terraformClient, config *con
|
||||
}
|
||||
|
||||
func (c *Creator) createGCP(ctx context.Context, cl terraformClient, config *config.Config,
|
||||
name, insType string, controlPlaneCount, workerCount int, image string,
|
||||
insType string, controlPlaneCount, workerCount int, image string,
|
||||
) (idFile clusterid.File, retErr error) {
|
||||
vars := terraform.GCPClusterVariables{
|
||||
CommonVariables: terraform.CommonVariables{
|
||||
Name: name,
|
||||
Name: config.Name,
|
||||
CountControlPlanes: controlPlaneCount,
|
||||
CountWorkers: workerCount,
|
||||
StateDiskSizeGB: config.StateDiskSizeGB,
|
||||
@ -175,11 +175,11 @@ func (c *Creator) createGCP(ctx context.Context, cl terraformClient, config *con
|
||||
}
|
||||
|
||||
func (c *Creator) createAzure(ctx context.Context, cl terraformClient, config *config.Config,
|
||||
name, insType string, controlPlaneCount, workerCount int, image string,
|
||||
insType string, controlPlaneCount, workerCount int, image string,
|
||||
) (idFile clusterid.File, retErr error) {
|
||||
vars := terraform.AzureClusterVariables{
|
||||
CommonVariables: terraform.CommonVariables{
|
||||
Name: name,
|
||||
Name: config.Name,
|
||||
CountControlPlanes: controlPlaneCount,
|
||||
CountWorkers: workerCount,
|
||||
StateDiskSizeGB: config.StateDiskSizeGB,
|
||||
@ -241,7 +241,7 @@ func normalizeAzureURIs(vars terraform.AzureClusterVariables) terraform.AzureClu
|
||||
return vars
|
||||
}
|
||||
|
||||
func (c *Creator) createQEMU(ctx context.Context, cl terraformClient, lv libvirtRunner, name string, config *config.Config,
|
||||
func (c *Creator) createQEMU(ctx context.Context, cl terraformClient, lv libvirtRunner, config *config.Config,
|
||||
controlPlaneCount, workerCount int, source string,
|
||||
) (idFile clusterid.File, retErr error) {
|
||||
qemuRollbacker := &rollbackerQEMU{client: cl, libvirt: lv, createdWorkspace: false}
|
||||
@ -260,7 +260,7 @@ func (c *Creator) createQEMU(ctx context.Context, cl terraformClient, lv libvirt
|
||||
switch {
|
||||
// if no libvirt URI is specified, start a libvirt container
|
||||
case libvirtURI == "":
|
||||
if err := lv.Start(ctx, name, config.Provider.QEMU.LibvirtContainerImage); err != nil {
|
||||
if err := lv.Start(ctx, config.Name, config.Provider.QEMU.LibvirtContainerImage); err != nil {
|
||||
return clusterid.File{}, err
|
||||
}
|
||||
libvirtURI = libvirt.LibvirtTCPConnectURI
|
||||
@ -292,7 +292,7 @@ func (c *Creator) createQEMU(ctx context.Context, cl terraformClient, lv libvirt
|
||||
|
||||
vars := terraform.QEMUVariables{
|
||||
CommonVariables: terraform.CommonVariables{
|
||||
Name: name,
|
||||
Name: config.Name,
|
||||
CountControlPlanes: controlPlaneCount,
|
||||
CountWorkers: workerCount,
|
||||
StateDiskSizeGB: config.StateDiskSizeGB,
|
||||
|
@ -114,7 +114,7 @@ func TestCreator(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
idFile, err := creator.Create(context.Background(), tc.provider, tc.config, "name", "type", 2, 3)
|
||||
idFile, err := creator.Create(context.Background(), tc.provider, tc.config, "type", 2, 3)
|
||||
|
||||
if tc.wantErr {
|
||||
assert.Error(err)
|
||||
|
@ -21,7 +21,7 @@ type cloudCreator interface {
|
||||
ctx context.Context,
|
||||
provider cloudprovider.Provider,
|
||||
config *config.Config,
|
||||
name, insType string,
|
||||
insType string,
|
||||
coordCount, nodeCount int,
|
||||
) (clusterid.File, error)
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ func (c *stubCloudCreator) Create(
|
||||
ctx context.Context,
|
||||
provider cloudprovider.Provider,
|
||||
config *config.Config,
|
||||
name, insType string,
|
||||
insType string,
|
||||
coordCount, nodeCount int,
|
||||
) (clusterid.File, error) {
|
||||
c.createCalled = true
|
||||
|
@ -41,12 +41,12 @@ func TestConfigGenerateDefaultGCPSpecific(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
wantConf := config.Default()
|
||||
wantConf.RemoveProviderExcept(cloudprovider.GCP)
|
||||
|
||||
fileHandler := file.NewHandler(afero.NewMemMapFs())
|
||||
cmd := newConfigGenerateCmd()
|
||||
|
||||
wantConf := config.Default()
|
||||
wantConf.RemoveProviderExcept(cloudprovider.GCP)
|
||||
|
||||
cg := &configGenerateCmd{log: logger.NewTest(t)}
|
||||
require.NoError(cg.configGenerate(cmd, fileHandler, cloudprovider.GCP))
|
||||
|
||||
|
@ -30,7 +30,6 @@ func NewCreateCmd() *cobra.Command {
|
||||
Args: cobra.ExactArgs(0),
|
||||
RunE: runCreate,
|
||||
}
|
||||
cmd.Flags().String("name", "constell", "create the cluster with the specified name")
|
||||
cmd.Flags().BoolP("yes", "y", false, "create the cluster without further confirmation")
|
||||
cmd.Flags().IntP("control-plane-nodes", "c", 0, "number of control-plane nodes (required)")
|
||||
must(cobra.MarkFlagRequired(cmd.Flags(), "control-plane-nodes"))
|
||||
@ -110,9 +109,6 @@ func (c *createCmd) create(cmd *cobra.Command, creator cloudCreator, fileHandler
|
||||
case cloudprovider.AWS:
|
||||
c.log.Debugf("Configuring instance type for AWS")
|
||||
instanceType = conf.Provider.AWS.InstanceType
|
||||
if len(flags.name) > 10 {
|
||||
return fmt.Errorf("cluster name on AWS must not be longer than 10 characters")
|
||||
}
|
||||
case cloudprovider.Azure:
|
||||
c.log.Debugf("Configuring instance type for Azure")
|
||||
instanceType = conf.Provider.Azure.InstanceType
|
||||
@ -142,7 +138,7 @@ func (c *createCmd) create(cmd *cobra.Command, creator cloudCreator, fileHandler
|
||||
}
|
||||
|
||||
spinner.Start("Creating", false)
|
||||
idFile, err := creator.Create(cmd.Context(), provider, conf, flags.name, instanceType, flags.controllerCount, flags.workerCount)
|
||||
idFile, err := creator.Create(cmd.Context(), provider, conf, instanceType, flags.controllerCount, flags.workerCount)
|
||||
c.log.Debugf("Successfully created the cloud resources for the cluster")
|
||||
spinner.Stop()
|
||||
if err != nil {
|
||||
@ -177,18 +173,6 @@ func (c *createCmd) parseCreateFlags(cmd *cobra.Command) (createFlags, error) {
|
||||
return createFlags{}, fmt.Errorf("number of worker nodes must be at least %d", constants.MinWorkerCount)
|
||||
}
|
||||
|
||||
name, err := cmd.Flags().GetString("name")
|
||||
if err != nil {
|
||||
return createFlags{}, fmt.Errorf("parsing name argument: %w", err)
|
||||
}
|
||||
c.log.Debugf("Name flag is %q", name)
|
||||
if len(name) > constants.ConstellationNameLength {
|
||||
return createFlags{}, fmt.Errorf(
|
||||
"name for Constellation cluster too long, maximum length is %d, got %d: %s",
|
||||
constants.ConstellationNameLength, len(name), name,
|
||||
)
|
||||
}
|
||||
|
||||
yes, err := cmd.Flags().GetBool("yes")
|
||||
if err != nil {
|
||||
return createFlags{}, fmt.Errorf("%w; Set '-yes' without a value to automatically confirm", err)
|
||||
@ -210,7 +194,6 @@ func (c *createCmd) parseCreateFlags(cmd *cobra.Command) (createFlags, error) {
|
||||
return createFlags{
|
||||
controllerCount: controllerCount,
|
||||
workerCount: workerCount,
|
||||
name: name,
|
||||
configPath: configPath,
|
||||
force: force,
|
||||
yes: yes,
|
||||
@ -221,7 +204,6 @@ func (c *createCmd) parseCreateFlags(cmd *cobra.Command) (createFlags, error) {
|
||||
type createFlags struct {
|
||||
controllerCount int
|
||||
workerCount int
|
||||
name string
|
||||
configPath string
|
||||
force bool
|
||||
yes bool
|
||||
|
@ -10,7 +10,6 @@ import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/cli/internal/clusterid"
|
||||
@ -42,7 +41,6 @@ func TestCreate(t *testing.T) {
|
||||
controllerCountFlag *int
|
||||
workerCountFlag *int
|
||||
configFlag string
|
||||
nameFlag string
|
||||
stdin string
|
||||
wantErr bool
|
||||
wantAbort bool
|
||||
@ -81,15 +79,6 @@ func TestCreate(t *testing.T) {
|
||||
stdin: "foo\nfoo\nfoo\n",
|
||||
wantErr: true,
|
||||
},
|
||||
"flag name to long": {
|
||||
setupFs: fsWithDefaultConfig,
|
||||
creator: &stubCloudCreator{},
|
||||
provider: cloudprovider.GCP,
|
||||
controllerCountFlag: intPtr(1),
|
||||
workerCountFlag: intPtr(1),
|
||||
nameFlag: strings.Repeat("a", constants.ConstellationNameLength+1),
|
||||
wantErr: true,
|
||||
},
|
||||
"flag control-plane-count invalid": {
|
||||
setupFs: fsWithDefaultConfig,
|
||||
creator: &stubCloudCreator{},
|
||||
@ -200,9 +189,6 @@ func TestCreate(t *testing.T) {
|
||||
if tc.yesFlag {
|
||||
require.NoError(cmd.Flags().Set("yes", "true"))
|
||||
}
|
||||
if tc.nameFlag != "" {
|
||||
require.NoError(cmd.Flags().Set("name", tc.nameFlag))
|
||||
}
|
||||
if tc.configFlag != "" {
|
||||
require.NoError(cmd.Flags().Set("config", tc.configFlag))
|
||||
}
|
||||
|
@ -226,6 +226,7 @@ func TestIAMCreateAWS(t *testing.T) {
|
||||
cmd.Flags().String("config", constants.ConfigFilename, "") // register persistent flag manually
|
||||
cmd.Flags().Bool("generate-config", false, "") // register persistent flag manually
|
||||
cmd.Flags().Bool("yes", false, "") // register persistent flag manually
|
||||
cmd.Flags().String("name", "constell", "") // register persistent flag manually
|
||||
|
||||
if tc.zoneFlag != "" {
|
||||
require.NoError(cmd.Flags().Set("zone", tc.zoneFlag))
|
||||
@ -446,7 +447,8 @@ func TestIAMCreateAzure(t *testing.T) {
|
||||
|
||||
cmd.Flags().String("config", constants.ConfigFilename, "") // register persistent flag manually
|
||||
cmd.Flags().Bool("generate-config", false, "") // register persistent flag manually
|
||||
cmd.Flags().Bool("yes", false, "") // register persistent flag
|
||||
cmd.Flags().Bool("yes", false, "") // register persistent flag manually
|
||||
cmd.Flags().String("name", "constell", "") // register persistent flag manually
|
||||
|
||||
if tc.regionFlag != "" {
|
||||
require.NoError(cmd.Flags().Set("region", tc.regionFlag))
|
||||
@ -694,7 +696,8 @@ func TestIAMCreateGCP(t *testing.T) {
|
||||
|
||||
cmd.Flags().String("config", constants.ConfigFilename, "") // register persistent flag manually
|
||||
cmd.Flags().Bool("generate-config", false, "") // register persistent flag manually
|
||||
cmd.Flags().Bool("yes", false, "") // register persistent flag
|
||||
cmd.Flags().Bool("yes", false, "") // register persistent flag manually
|
||||
cmd.Flags().String("name", "constell", "") // register persistent flag manually
|
||||
|
||||
if tc.zoneFlag != "" {
|
||||
require.NoError(cmd.Flags().Set("zone", tc.zoneFlag))
|
||||
|
@ -137,11 +137,14 @@ func (i *initCmd) initialize(cmd *cobra.Command, newDialer func(validator *cloud
|
||||
helmLoader := helm.NewLoader(provider, k8sVersion)
|
||||
i.log.Debugf("Created new Helm loader")
|
||||
helmDeployments, err := helmLoader.Load(conf, flags.conformance, masterSecret.Key, masterSecret.Salt)
|
||||
i.log.Debugf("Loaded Helm heployments")
|
||||
i.log.Debugf("Loaded Helm deployments")
|
||||
if err != nil {
|
||||
return fmt.Errorf("loading Helm charts: %w", err)
|
||||
}
|
||||
|
||||
clusterName := conf.Name + "-" + idFile.UID
|
||||
i.log.Debugf("Setting cluster name to %s", clusterName)
|
||||
|
||||
spinner.Start("Initializing cluster ", false)
|
||||
req := &initproto.InitRequest{
|
||||
MasterSecret: masterSecret.Key,
|
||||
@ -158,6 +161,7 @@ func (i *initCmd) initialize(cmd *cobra.Command, newDialer func(validator *cloud
|
||||
EnforceIdkeydigest: conf.EnforcesIDKeyDigest(),
|
||||
ConformanceMode: flags.conformance,
|
||||
InitSecret: idFile.InitSecret,
|
||||
ClusterName: clusterName,
|
||||
}
|
||||
i.log.Debugf("Sending initialization request")
|
||||
resp, err := i.initCall(cmd.Context(), newDialer(validator), idFile.IP, req)
|
||||
|
@ -479,6 +479,7 @@ func defaultConfigWithExpectedMeasurements(t *testing.T, conf *config.Config, cs
|
||||
t.Helper()
|
||||
|
||||
conf.Image = constants.VersionInfo
|
||||
conf.Name = "kubernetes"
|
||||
|
||||
switch csp {
|
||||
case cloudprovider.Azure:
|
||||
|
@ -213,6 +213,7 @@ func (m *miniUpCmd) prepareConfig(cmd *cobra.Command, fileHandler file.Handler)
|
||||
}
|
||||
|
||||
config := config.Default()
|
||||
config.Name = constants.MiniConstellationUID
|
||||
config.RemoveProviderExcept(cloudprovider.QEMU)
|
||||
config.StateDiskSizeGB = 8
|
||||
m.log.Debugf("Prepared configuration")
|
||||
@ -223,7 +224,7 @@ func (m *miniUpCmd) prepareConfig(cmd *cobra.Command, fileHandler file.Handler)
|
||||
// createMiniCluster creates a new cluster using the given config.
|
||||
func (m *miniUpCmd) createMiniCluster(ctx context.Context, fileHandler file.Handler, creator cloudCreator, config *config.Config) error {
|
||||
m.log.Debugf("Creating mini cluster")
|
||||
idFile, err := creator.Create(ctx, cloudprovider.QEMU, config, "mini", "", 1, 1)
|
||||
idFile, err := creator.Create(ctx, cloudprovider.QEMU, config, "", 1, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
274
docs/static/img/shell-windowframe.svg
vendored
274
docs/static/img/shell-windowframe.svg
vendored
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 76 KiB |
@ -58,9 +58,12 @@ type Config struct {
|
||||
// Schema version of this configuration file.
|
||||
Version string `yaml:"version" validate:"eq=v2"`
|
||||
// description: |
|
||||
// Machine image used to create Constellation nodes.
|
||||
// Machine image version used to create Constellation nodes.
|
||||
Image string `yaml:"image" validate:"required,version_compatibility"`
|
||||
// description: |
|
||||
// Name of the cluster.
|
||||
Name string `yaml:"name" validate:"required,valid_name"`
|
||||
// description: |
|
||||
// Size (in GB) of a node's disk to store the non-volatile state.
|
||||
StateDiskSizeGB int `yaml:"stateDiskSizeGB" validate:"min=0"`
|
||||
// description: |
|
||||
@ -252,6 +255,7 @@ func Default() *Config {
|
||||
return &Config{
|
||||
Version: Version2,
|
||||
Image: defaultImage,
|
||||
Name: "constell",
|
||||
MicroserviceVersion: compatibility.EnsurePrefixV(constants.VersionInfo),
|
||||
KubernetesVersion: string(versions.Default),
|
||||
StateDiskSizeGB: 30,
|
||||
@ -505,6 +509,13 @@ func (c *Config) Validate(force bool) error {
|
||||
if err := validate.RegisterTranslation("version_compatibility", trans, registerVersionCompatibilityError, translateVersionCompatibilityError); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := validate.RegisterTranslation("valid_name", trans, registerValidateNameError, c.translateValidateNameError); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validate.RegisterValidation("valid_name", c.validateName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validate.RegisterValidation("no_placeholders", validateNoPlaceholder); err != nil {
|
||||
return err
|
||||
|
@ -24,7 +24,7 @@ func init() {
|
||||
ConfigDoc.Type = "Config"
|
||||
ConfigDoc.Comments[encoder.LineComment] = "Config defines configuration used by CLI."
|
||||
ConfigDoc.Description = "Config defines configuration used by CLI."
|
||||
ConfigDoc.Fields = make([]encoder.Doc, 8)
|
||||
ConfigDoc.Fields = make([]encoder.Doc, 9)
|
||||
ConfigDoc.Fields[0].Name = "version"
|
||||
ConfigDoc.Fields[0].Type = "string"
|
||||
ConfigDoc.Fields[0].Note = ""
|
||||
@ -33,40 +33,45 @@ func init() {
|
||||
ConfigDoc.Fields[1].Name = "image"
|
||||
ConfigDoc.Fields[1].Type = "string"
|
||||
ConfigDoc.Fields[1].Note = ""
|
||||
ConfigDoc.Fields[1].Description = "Machine image used to create Constellation nodes."
|
||||
ConfigDoc.Fields[1].Comments[encoder.LineComment] = "Machine image used to create Constellation nodes."
|
||||
ConfigDoc.Fields[2].Name = "stateDiskSizeGB"
|
||||
ConfigDoc.Fields[2].Type = "int"
|
||||
ConfigDoc.Fields[1].Description = "Machine image version used to create Constellation nodes."
|
||||
ConfigDoc.Fields[1].Comments[encoder.LineComment] = "Machine image version used to create Constellation nodes."
|
||||
ConfigDoc.Fields[2].Name = "name"
|
||||
ConfigDoc.Fields[2].Type = "string"
|
||||
ConfigDoc.Fields[2].Note = ""
|
||||
ConfigDoc.Fields[2].Description = "Size (in GB) of a node's disk to store the non-volatile state."
|
||||
ConfigDoc.Fields[2].Comments[encoder.LineComment] = "Size (in GB) of a node's disk to store the non-volatile state."
|
||||
ConfigDoc.Fields[3].Name = "kubernetesVersion"
|
||||
ConfigDoc.Fields[3].Type = "string"
|
||||
ConfigDoc.Fields[2].Description = "Name of the cluster."
|
||||
ConfigDoc.Fields[2].Comments[encoder.LineComment] = "Name of the cluster."
|
||||
ConfigDoc.Fields[3].Name = "stateDiskSizeGB"
|
||||
ConfigDoc.Fields[3].Type = "int"
|
||||
ConfigDoc.Fields[3].Note = ""
|
||||
ConfigDoc.Fields[3].Description = "Kubernetes version to be installed into the cluster."
|
||||
ConfigDoc.Fields[3].Comments[encoder.LineComment] = "Kubernetes version to be installed into the cluster."
|
||||
ConfigDoc.Fields[4].Name = "microserviceVersion"
|
||||
ConfigDoc.Fields[3].Description = "Size (in GB) of a node's disk to store the non-volatile state."
|
||||
ConfigDoc.Fields[3].Comments[encoder.LineComment] = "Size (in GB) of a node's disk to store the non-volatile state."
|
||||
ConfigDoc.Fields[4].Name = "kubernetesVersion"
|
||||
ConfigDoc.Fields[4].Type = "string"
|
||||
ConfigDoc.Fields[4].Note = ""
|
||||
ConfigDoc.Fields[4].Description = "Microservice version to be installed into the cluster. Setting this value is optional until v2.7. Defaults to the version of the CLI."
|
||||
ConfigDoc.Fields[4].Comments[encoder.LineComment] = "Microservice version to be installed into the cluster. Setting this value is optional until v2.7. Defaults to the version of the CLI."
|
||||
ConfigDoc.Fields[5].Name = "debugCluster"
|
||||
ConfigDoc.Fields[5].Type = "bool"
|
||||
ConfigDoc.Fields[4].Description = "Kubernetes version to be installed into the cluster."
|
||||
ConfigDoc.Fields[4].Comments[encoder.LineComment] = "Kubernetes version to be installed into the cluster."
|
||||
ConfigDoc.Fields[5].Name = "microserviceVersion"
|
||||
ConfigDoc.Fields[5].Type = "string"
|
||||
ConfigDoc.Fields[5].Note = ""
|
||||
ConfigDoc.Fields[5].Description = "DON'T USE IN PRODUCTION: enable debug mode and use debug images. For usage, see: https://github.com/edgelesssys/constellation/blob/main/debugd/README.md"
|
||||
ConfigDoc.Fields[5].Comments[encoder.LineComment] = "DON'T USE IN PRODUCTION: enable debug mode and use debug images. For usage, see: https://github.com/edgelesssys/constellation/blob/main/debugd/README.md"
|
||||
ConfigDoc.Fields[6].Name = "provider"
|
||||
ConfigDoc.Fields[6].Type = "ProviderConfig"
|
||||
ConfigDoc.Fields[5].Description = "Microservice version to be installed into the cluster. Setting this value is optional until v2.7. Defaults to the version of the CLI."
|
||||
ConfigDoc.Fields[5].Comments[encoder.LineComment] = "Microservice version to be installed into the cluster. Setting this value is optional until v2.7. Defaults to the version of the CLI."
|
||||
ConfigDoc.Fields[6].Name = "debugCluster"
|
||||
ConfigDoc.Fields[6].Type = "bool"
|
||||
ConfigDoc.Fields[6].Note = ""
|
||||
ConfigDoc.Fields[6].Description = "Supported cloud providers and their specific configurations."
|
||||
ConfigDoc.Fields[6].Comments[encoder.LineComment] = "Supported cloud providers and their specific configurations."
|
||||
ConfigDoc.Fields[7].Name = "upgrade"
|
||||
ConfigDoc.Fields[7].Type = "UpgradeConfig"
|
||||
ConfigDoc.Fields[6].Description = "DON'T USE IN PRODUCTION: enable debug mode and use debug images. For usage, see: https://github.com/edgelesssys/constellation/blob/main/debugd/README.md"
|
||||
ConfigDoc.Fields[6].Comments[encoder.LineComment] = "DON'T USE IN PRODUCTION: enable debug mode and use debug images. For usage, see: https://github.com/edgelesssys/constellation/blob/main/debugd/README.md"
|
||||
ConfigDoc.Fields[7].Name = "provider"
|
||||
ConfigDoc.Fields[7].Type = "ProviderConfig"
|
||||
ConfigDoc.Fields[7].Note = ""
|
||||
ConfigDoc.Fields[7].Description = "Configuration to apply during constellation upgrade."
|
||||
ConfigDoc.Fields[7].Comments[encoder.LineComment] = "Configuration to apply during constellation upgrade."
|
||||
ConfigDoc.Fields[7].Description = "Supported cloud providers and their specific configurations."
|
||||
ConfigDoc.Fields[7].Comments[encoder.LineComment] = "Supported cloud providers and their specific configurations."
|
||||
ConfigDoc.Fields[8].Name = "upgrade"
|
||||
ConfigDoc.Fields[8].Type = "UpgradeConfig"
|
||||
ConfigDoc.Fields[8].Note = ""
|
||||
ConfigDoc.Fields[8].Description = "Configuration to apply during constellation upgrade."
|
||||
ConfigDoc.Fields[8].Comments[encoder.LineComment] = "Configuration to apply during constellation upgrade."
|
||||
|
||||
ConfigDoc.Fields[7].AddExample("", UpgradeConfig{Image: "", Measurements: Measurements{}})
|
||||
ConfigDoc.Fields[8].AddExample("", UpgradeConfig{Image: "", Measurements: Measurements{}})
|
||||
|
||||
UpgradeConfigDoc.Type = "UpgradeConfig"
|
||||
UpgradeConfigDoc.Comments[encoder.LineComment] = "UpgradeConfig defines configuration used during constellation upgrade."
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/attestation/measurements"
|
||||
@ -366,3 +367,28 @@ func returnsTrue(fl validator.FieldLevel) bool {
|
||||
func validateUpgradeConfig(sl validator.StructLevel) {
|
||||
fmt.Printf("WARNING: the config key `upgrade` will be deprecated in an upcoming version. Please check the documentation for more information.\n")
|
||||
}
|
||||
|
||||
func registerValidateNameError(ut ut.Translator) error {
|
||||
return ut.Add("validate_name", "{0} must be no more than {1} characters long", true)
|
||||
}
|
||||
|
||||
func (c *Config) translateValidateNameError(ut ut.Translator, fe validator.FieldError) string {
|
||||
var t string
|
||||
if c.Provider.AWS != nil {
|
||||
t, _ = ut.T("validate_name", fe.Field(), strconv.Itoa(constants.AWSConstellationNameLength))
|
||||
} else {
|
||||
t, _ = ut.T("validate_name", fe.Field(), strconv.Itoa(constants.ConstellationNameLength))
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
// validateName makes sure the name of the constellation is not too long.
|
||||
// Since this value may differ between providers, we can't simply use built-in validation.
|
||||
// This also allows us to eventually add more validation rules for constellation names if necessary.
|
||||
func (c *Config) validateName(fl validator.FieldLevel) bool {
|
||||
if c.Provider.AWS != nil {
|
||||
return len(fl.Field().String()) <= constants.AWSConstellationNameLength
|
||||
}
|
||||
return len(fl.Field().String()) <= constants.ConstellationNameLength
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ const (
|
||||
|
||||
// ConstellationNameLength is the maximum length of a Constellation's name.
|
||||
ConstellationNameLength = 37
|
||||
// AWSConstellationNameLength is the maximum length of a Constellation's name on AWS.
|
||||
AWSConstellationNameLength = 10
|
||||
// ConstellationMasterSecretStoreName is the name for the Constellation secrets in Kubernetes.
|
||||
ConstellationMasterSecretStoreName = "constellation-mastersecret"
|
||||
// ConstellationMasterSecretKey is the name of the key for the master secret in the master secret kubernetes secret.
|
||||
|
Loading…
Reference in New Issue
Block a user