mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-24 23:19:39 -05:00
cli: add support for multiple coordinators
Signed-off-by: Benedict Schlueter <bs@edgeless.systems>
This commit is contained in:
parent
ff8830e718
commit
49def1e97f
@ -122,6 +122,7 @@ func initialize(ctx context.Context, cmd *cobra.Command, protCl protoClient, ser
|
|||||||
pubKey: flags.userPubKey,
|
pubKey: flags.userPubKey,
|
||||||
masterSecret: flags.masterSecret,
|
masterSecret: flags.masterSecret,
|
||||||
nodePrivIPs: nodes.PrivateIPs(),
|
nodePrivIPs: nodes.PrivateIPs(),
|
||||||
|
coordinatorPrivIPs: coordinators.PrivateIPs()[1:],
|
||||||
autoscalingNodeGroups: autoscalingNodeGroups,
|
autoscalingNodeGroups: autoscalingNodeGroups,
|
||||||
cloudServiceAccountURI: serviceAccount,
|
cloudServiceAccountURI: serviceAccount,
|
||||||
}
|
}
|
||||||
@ -161,7 +162,7 @@ func activate(ctx context.Context, cmd *cobra.Command, client protoClient, input
|
|||||||
return activationResult{}, err
|
return activationResult{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
respCl, err := client.Activate(ctx, input.pubKey, input.masterSecret, input.nodePrivIPs, input.autoscalingNodeGroups, input.cloudServiceAccountURI)
|
respCl, err := client.Activate(ctx, input.pubKey, input.masterSecret, input.nodePrivIPs, input.coordinatorPrivIPs, input.autoscalingNodeGroups, input.cloudServiceAccountURI)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return activationResult{}, err
|
return activationResult{}, err
|
||||||
}
|
}
|
||||||
@ -208,6 +209,7 @@ type activationInput struct {
|
|||||||
pubKey []byte
|
pubKey []byte
|
||||||
masterSecret []byte
|
masterSecret []byte
|
||||||
nodePrivIPs []string
|
nodePrivIPs []string
|
||||||
|
coordinatorPrivIPs []string
|
||||||
autoscalingNodeGroups []string
|
autoscalingNodeGroups []string
|
||||||
cloudServiceAccountURI string
|
cloudServiceAccountURI string
|
||||||
}
|
}
|
||||||
@ -386,12 +388,20 @@ func getScalingGroupsFromConfig(stat state.ConstellationState, config *config.Co
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getAWSInstances(stat state.ConstellationState) (coordinators, nodes ScalingGroup, err error) {
|
func getAWSInstances(stat state.ConstellationState) (coordinators, nodes ScalingGroup, err error) {
|
||||||
coordinatorID, coordinator, err := stat.EC2Instances.GetOne()
|
coordinatorID, _, err := stat.EC2Instances.GetOne()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
coordinatorMap := stat.EC2Instances
|
||||||
|
var coordinatorInstances Instances
|
||||||
|
for _, node := range coordinatorMap {
|
||||||
|
coordinatorInstances = append(coordinatorInstances, Instance(node))
|
||||||
|
}
|
||||||
// GroupID of coordinators is empty, since they currently do not scale.
|
// GroupID of coordinators is empty, since they currently do not scale.
|
||||||
coordinators = ScalingGroup{Instances: Instances{Instance(coordinator)}, GroupID: ""}
|
coordinators = ScalingGroup{
|
||||||
|
Instances: coordinatorInstances,
|
||||||
|
GroupID: "",
|
||||||
|
}
|
||||||
|
|
||||||
nodeMap := stat.EC2Instances.GetOthers(coordinatorID)
|
nodeMap := stat.EC2Instances.GetOthers(coordinatorID)
|
||||||
if len(nodeMap) == 0 {
|
if len(nodeMap) == 0 {
|
||||||
@ -411,12 +421,19 @@ func getAWSInstances(stat state.ConstellationState) (coordinators, nodes Scaling
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getGCPInstances(stat state.ConstellationState, config *config.Config) (coordinators, nodes ScalingGroup, err error) {
|
func getGCPInstances(stat state.ConstellationState, config *config.Config) (coordinators, nodes ScalingGroup, err error) {
|
||||||
_, coordinator, err := stat.GCPCoordinators.GetOne()
|
coordinatorMap := stat.GCPCoordinators
|
||||||
if err != nil {
|
if len(coordinatorMap) == 0 {
|
||||||
return
|
return ScalingGroup{}, ScalingGroup{}, errors.New("no coordinators available, can't create Constellation without any instance")
|
||||||
|
}
|
||||||
|
var coordinatorInstances Instances
|
||||||
|
for _, node := range coordinatorMap {
|
||||||
|
coordinatorInstances = append(coordinatorInstances, Instance(node))
|
||||||
}
|
}
|
||||||
// GroupID of coordinators is empty, since they currently do not scale.
|
// GroupID of coordinators is empty, since they currently do not scale.
|
||||||
coordinators = ScalingGroup{Instances: Instances{Instance(coordinator)}, GroupID: ""}
|
coordinators = ScalingGroup{
|
||||||
|
Instances: coordinatorInstances,
|
||||||
|
GroupID: "",
|
||||||
|
}
|
||||||
|
|
||||||
nodeMap := stat.GCPNodes
|
nodeMap := stat.GCPNodes
|
||||||
if len(nodeMap) == 0 {
|
if len(nodeMap) == 0 {
|
||||||
@ -438,13 +455,19 @@ func getGCPInstances(stat state.ConstellationState, config *config.Config) (coor
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getAzureInstances(stat state.ConstellationState, config *config.Config) (coordinators, nodes ScalingGroup, err error) {
|
func getAzureInstances(stat state.ConstellationState, config *config.Config) (coordinators, nodes ScalingGroup, err error) {
|
||||||
_, coordinator, err := stat.AzureCoordinators.GetOne()
|
coordinatorMap := stat.AzureCoordinators
|
||||||
if err != nil {
|
if len(coordinatorMap) == 0 {
|
||||||
return
|
return ScalingGroup{}, ScalingGroup{}, errors.New("no coordinators available, can't create Constellation without any instance")
|
||||||
|
}
|
||||||
|
var coordinatorInstances Instances
|
||||||
|
for _, node := range coordinatorMap {
|
||||||
|
coordinatorInstances = append(coordinatorInstances, Instance(node))
|
||||||
}
|
}
|
||||||
// GroupID of coordinators is empty, since they currently do not scale.
|
// GroupID of coordinators is empty, since they currently do not scale.
|
||||||
coordinators = ScalingGroup{Instances: Instances{Instance(coordinator)}, GroupID: ""}
|
coordinators = ScalingGroup{
|
||||||
|
Instances: coordinatorInstances,
|
||||||
|
GroupID: "",
|
||||||
|
}
|
||||||
nodeMap := stat.AzureNodes
|
nodeMap := stat.AzureNodes
|
||||||
if len(nodeMap) == 0 {
|
if len(nodeMap) == 0 {
|
||||||
return ScalingGroup{}, ScalingGroup{}, errors.New("no nodes available, can't create Constellation with one instance")
|
return ScalingGroup{}, ScalingGroup{}, errors.New("no nodes available, can't create Constellation with one instance")
|
||||||
|
@ -10,5 +10,5 @@ import (
|
|||||||
type protoClient interface {
|
type protoClient interface {
|
||||||
Connect(ip, port string, validators []atls.Validator) error
|
Connect(ip, port string, validators []atls.Validator) error
|
||||||
Close() error
|
Close() error
|
||||||
Activate(ctx context.Context, userPublicKey, masterSecret []byte, endpoints, autoscalingNodeGroups []string, cloudServiceAccountURI string) (proto.ActivationResponseClient, error)
|
Activate(ctx context.Context, userPublicKey, masterSecret []byte, nodeIPs, coordinatorIPs, autoscalingNodeGroups []string, cloudServiceAccountURI string) (proto.ActivationResponseClient, error)
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,8 @@ type stubProtoClient struct {
|
|||||||
|
|
||||||
activateUserPublicKey []byte
|
activateUserPublicKey []byte
|
||||||
activateMasterSecret []byte
|
activateMasterSecret []byte
|
||||||
activateEndpoints []string
|
activateNodeIPs []string
|
||||||
|
activateCoordinatorIPs []string
|
||||||
activateAutoscalingNodeGroups []string
|
activateAutoscalingNodeGroups []string
|
||||||
cloudServiceAccountURI string
|
cloudServiceAccountURI string
|
||||||
}
|
}
|
||||||
@ -34,16 +35,21 @@ func (c *stubProtoClient) Close() error {
|
|||||||
return c.closeErr
|
return c.closeErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *stubProtoClient) Activate(ctx context.Context, userPublicKey, masterSecret []byte, endpoints []string, autoscalingNodeGroups []string, cloudServiceAccountURI string) (proto.ActivationResponseClient, error) {
|
func (c *stubProtoClient) Activate(ctx context.Context, userPublicKey, masterSecret []byte, nodeIPs, coordinatorIPs []string, autoscalingNodeGroups []string, cloudServiceAccountURI string) (proto.ActivationResponseClient, error) {
|
||||||
c.activateUserPublicKey = userPublicKey
|
c.activateUserPublicKey = userPublicKey
|
||||||
c.activateMasterSecret = masterSecret
|
c.activateMasterSecret = masterSecret
|
||||||
c.activateEndpoints = endpoints
|
c.activateNodeIPs = nodeIPs
|
||||||
|
c.activateCoordinatorIPs = coordinatorIPs
|
||||||
c.activateAutoscalingNodeGroups = autoscalingNodeGroups
|
c.activateAutoscalingNodeGroups = autoscalingNodeGroups
|
||||||
c.cloudServiceAccountURI = cloudServiceAccountURI
|
c.cloudServiceAccountURI = cloudServiceAccountURI
|
||||||
|
|
||||||
return c.respClient, c.activateErr
|
return c.respClient, c.activateErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *stubProtoClient) ActivateAdditionalCoordinators(ctx context.Context, ips []string) error {
|
||||||
|
return c.activateErr
|
||||||
|
}
|
||||||
|
|
||||||
type stubActivationRespClient struct {
|
type stubActivationRespClient struct {
|
||||||
nextLogErr *error
|
nextLogErr *error
|
||||||
getKubeconfigErr error
|
getKubeconfigErr error
|
||||||
@ -106,13 +112,20 @@ func (c *fakeProtoClient) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeProtoClient) Activate(ctx context.Context, userPublicKey, masterSecret []byte, endpoints []string, autoscalingNodeGroups []string, cloudServiceAccountURI string) (proto.ActivationResponseClient, error) {
|
func (c *fakeProtoClient) Activate(ctx context.Context, userPublicKey, masterSecret []byte, nodeIPs, coordinatorIPs []string, autoscalingNodeGroups []string, cloudServiceAccountURI string) (proto.ActivationResponseClient, error) {
|
||||||
if !c.conn {
|
if !c.conn {
|
||||||
return nil, errors.New("client is not connected")
|
return nil, errors.New("client is not connected")
|
||||||
}
|
}
|
||||||
return c.respClient, nil
|
return c.respClient, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *fakeProtoClient) ActivateAdditionalCoordinators(ctx context.Context, ips []string) error {
|
||||||
|
if !c.conn {
|
||||||
|
return errors.New("client is not connected")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type fakeActivationRespClient struct {
|
type fakeActivationRespClient struct {
|
||||||
responses []fakeActivationRespMessage
|
responses []fakeActivationRespMessage
|
||||||
kubeconfig string
|
kubeconfig string
|
||||||
|
@ -64,14 +64,14 @@ func (c *Client) Close() error {
|
|||||||
// Activate activates the Constellation coordinator via a grpc call.
|
// Activate activates the Constellation coordinator via a grpc call.
|
||||||
// The handed IP addresses must be the private IP addresses of running AWS or GCP instances,
|
// The handed IP addresses must be the private IP addresses of running AWS or GCP instances,
|
||||||
// and the userPublicKey is the VPN key of the users WireGuard interface.
|
// and the userPublicKey is the VPN key of the users WireGuard interface.
|
||||||
func (c *Client) Activate(ctx context.Context, userPublicKey, masterSecret []byte, ips, autoscalingNodeGroups []string, cloudServiceAccountURI string) (ActivationResponseClient, error) {
|
func (c *Client) Activate(ctx context.Context, userPublicKey, masterSecret []byte, nodeIPs, coordinatorIPs, autoscalingNodeGroups []string, cloudServiceAccountURI string) (ActivationResponseClient, error) {
|
||||||
if c.avpn == nil {
|
if c.avpn == nil {
|
||||||
return nil, errors.New("client is not connected")
|
return nil, errors.New("client is not connected")
|
||||||
}
|
}
|
||||||
if len(userPublicKey) == 0 {
|
if len(userPublicKey) == 0 {
|
||||||
return nil, errors.New("parameter userPublicKey is empty")
|
return nil, errors.New("parameter userPublicKey is empty")
|
||||||
}
|
}
|
||||||
if len(ips) == 0 {
|
if len(nodeIPs) == 0 {
|
||||||
return nil, errors.New("parameter ips is empty")
|
return nil, errors.New("parameter ips is empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,8 @@ func (c *Client) Activate(ctx context.Context, userPublicKey, masterSecret []byt
|
|||||||
|
|
||||||
avpnRequest := &pubproto.ActivateAsCoordinatorRequest{
|
avpnRequest := &pubproto.ActivateAsCoordinatorRequest{
|
||||||
AdminVpnPubKey: pubKey[:],
|
AdminVpnPubKey: pubKey[:],
|
||||||
NodePublicIps: ips,
|
NodePublicIps: nodeIPs,
|
||||||
|
CoordinatorPublicIps: coordinatorIPs,
|
||||||
AutoscalingNodeGroups: autoscalingNodeGroups,
|
AutoscalingNodeGroups: autoscalingNodeGroups,
|
||||||
MasterSecret: masterSecret,
|
MasterSecret: masterSecret,
|
||||||
KmsUri: kms.ClusterKMSURI,
|
KmsUri: kms.ClusterKMSURI,
|
||||||
|
@ -120,7 +120,7 @@ func TestActivate(t *testing.T) {
|
|||||||
if tc.avpn != nil {
|
if tc.avpn != nil {
|
||||||
client.avpn = tc.avpn
|
client.avpn = tc.avpn
|
||||||
}
|
}
|
||||||
_, err := client.Activate(context.Background(), []byte(tc.userPublicKey), []byte("Constellation"), tc.ips, nil, "serviceaccount://test")
|
_, err := client.Activate(context.Background(), []byte(tc.userPublicKey), []byte("Constellation"), tc.ips, nil, nil, "serviceaccount://test")
|
||||||
if tc.errExpected {
|
if tc.errExpected {
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user