mirror of
https://github.com/edgelesssys/constellation.git
synced 2024-12-24 23:19:39 -05:00
join: join over lb if available (#2348)
* join: join over lb if available
This commit is contained in:
parent
df77696620
commit
2776e40df7
@ -99,5 +99,4 @@ type clusterInitJoiner interface {
|
|||||||
type metadataAPI interface {
|
type metadataAPI interface {
|
||||||
joinclient.MetadataAPI
|
joinclient.MetadataAPI
|
||||||
initserver.MetadataAPI
|
initserver.MetadataAPI
|
||||||
GetLoadBalancerEndpoint(ctx context.Context) (host, port string, err error)
|
|
||||||
}
|
}
|
||||||
|
@ -186,17 +186,29 @@ func (c *JoinClient) Stop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *JoinClient) tryJoinWithAvailableServices() error {
|
func (c *JoinClient) tryJoinWithAvailableServices() error {
|
||||||
ips, err := c.getControlPlaneIPs()
|
ctx, cancel := c.timeoutCtx()
|
||||||
if err != nil {
|
defer cancel()
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(ips) == 0 {
|
var endpoints []string
|
||||||
|
|
||||||
|
ip, _, err := c.metadataAPI.GetLoadBalancerEndpoint(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get load balancer endpoint: %w", err)
|
||||||
|
}
|
||||||
|
endpoints = append(endpoints, net.JoinHostPort(ip, strconv.Itoa(constants.JoinServiceNodePort)))
|
||||||
|
|
||||||
|
ips, err := c.getControlPlaneIPs(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get control plane IPs: %w", err)
|
||||||
|
}
|
||||||
|
endpoints = append(endpoints, ips...)
|
||||||
|
|
||||||
|
if len(endpoints) == 0 {
|
||||||
return errors.New("no control plane IPs found")
|
return errors.New("no control plane IPs found")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ip := range ips {
|
for _, endpoint := range endpoints {
|
||||||
err = c.join(net.JoinHostPort(ip, strconv.Itoa(constants.JoinServiceNodePort)))
|
err = c.join(net.JoinHostPort(endpoint, strconv.Itoa(constants.JoinServiceNodePort)))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -357,10 +369,7 @@ func (c *JoinClient) getDiskUUID() (string, error) {
|
|||||||
return c.disk.UUID()
|
return c.disk.UUID()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *JoinClient) getControlPlaneIPs() ([]string, error) {
|
func (c *JoinClient) getControlPlaneIPs(ctx context.Context) ([]string, error) {
|
||||||
ctx, cancel := c.timeoutCtx()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
instances, err := c.metadataAPI.List(ctx)
|
instances, err := c.metadataAPI.List(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.log.With(zap.Error(err)).Errorf("Failed to list instances from metadata API")
|
c.log.With(zap.Error(err)).Errorf("Failed to list instances from metadata API")
|
||||||
@ -425,6 +434,8 @@ type MetadataAPI interface {
|
|||||||
List(ctx context.Context) ([]metadata.InstanceMetadata, error)
|
List(ctx context.Context) ([]metadata.InstanceMetadata, error)
|
||||||
// Self retrieves the current instance.
|
// Self retrieves the current instance.
|
||||||
Self(ctx context.Context) (metadata.InstanceMetadata, error)
|
Self(ctx context.Context) (metadata.InstanceMetadata, error)
|
||||||
|
// GetLoadBalancerEndpoint retrieves the load balancer endpoint.
|
||||||
|
GetLoadBalancerEndpoint(ctx context.Context) (host, port string, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type encryptedDisk interface {
|
type encryptedDisk interface {
|
||||||
|
@ -330,6 +330,10 @@ func (s *stubRepeaterMetadataAPI) List(_ context.Context) ([]metadata.InstanceMe
|
|||||||
return s.listInstances, s.listErr
|
return s.listInstances, s.listErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *stubRepeaterMetadataAPI) GetLoadBalancerEndpoint(_ context.Context) (string, string, error) {
|
||||||
|
return "", "", nil
|
||||||
|
}
|
||||||
|
|
||||||
type stubMetadataAPI struct {
|
type stubMetadataAPI struct {
|
||||||
selfAnswerC chan selfAnswer
|
selfAnswerC chan selfAnswer
|
||||||
listAnswerC chan listAnswer
|
listAnswerC chan listAnswer
|
||||||
@ -352,6 +356,10 @@ func (s *stubMetadataAPI) List(_ context.Context) ([]metadata.InstanceMetadata,
|
|||||||
return answer.instances, answer.err
|
return answer.instances, answer.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *stubMetadataAPI) GetLoadBalancerEndpoint(_ context.Context) (string, string, error) {
|
||||||
|
return "", "", nil
|
||||||
|
}
|
||||||
|
|
||||||
type selfAnswer struct {
|
type selfAnswer struct {
|
||||||
instance metadata.InstanceMetadata
|
instance metadata.InstanceMetadata
|
||||||
err error
|
err error
|
||||||
|
@ -27,6 +27,7 @@ locals {
|
|||||||
ports_verify = "30081"
|
ports_verify = "30081"
|
||||||
ports_recovery = "9999"
|
ports_recovery = "9999"
|
||||||
ports_debugd = "4000"
|
ports_debugd = "4000"
|
||||||
|
ports_join = "30090"
|
||||||
target_group_arns = {
|
target_group_arns = {
|
||||||
control-plane : flatten([
|
control-plane : flatten([
|
||||||
module.load_balancer_target_bootstrapper.target_group_arn,
|
module.load_balancer_target_bootstrapper.target_group_arn,
|
||||||
@ -34,6 +35,7 @@ locals {
|
|||||||
module.load_balancer_target_verify.target_group_arn,
|
module.load_balancer_target_verify.target_group_arn,
|
||||||
module.load_balancer_target_recovery.target_group_arn,
|
module.load_balancer_target_recovery.target_group_arn,
|
||||||
module.load_balancer_target_konnectivity.target_group_arn,
|
module.load_balancer_target_konnectivity.target_group_arn,
|
||||||
|
module.load_balancer_target_join.target_group_arn,
|
||||||
var.debug ? [module.load_balancer_target_debugd[0].target_group_arn] : [],
|
var.debug ? [module.load_balancer_target_debugd[0].target_group_arn] : [],
|
||||||
])
|
])
|
||||||
worker : []
|
worker : []
|
||||||
@ -96,6 +98,7 @@ resource "aws_lb" "front_end" {
|
|||||||
internal = false
|
internal = false
|
||||||
load_balancer_type = "network"
|
load_balancer_type = "network"
|
||||||
tags = local.tags
|
tags = local.tags
|
||||||
|
security_groups = [aws_security_group.security_group.id]
|
||||||
|
|
||||||
dynamic "subnet_mapping" {
|
dynamic "subnet_mapping" {
|
||||||
# TODO(malt3): use for_each = toset(module.public_private_subnet.all_zones)
|
# TODO(malt3): use for_each = toset(module.public_private_subnet.all_zones)
|
||||||
@ -111,6 +114,10 @@ resource "aws_lb" "front_end" {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
enable_cross_zone_load_balancing = true
|
enable_cross_zone_load_balancing = true
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
ignore_changes = [security_groups]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_security_group" "security_group" {
|
resource "aws_security_group" "security_group" {
|
||||||
@ -255,6 +262,16 @@ module "load_balancer_target_konnectivity" {
|
|||||||
healthcheck_protocol = "TCP"
|
healthcheck_protocol = "TCP"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module "load_balancer_target_join" {
|
||||||
|
source = "./modules/load_balancer_target"
|
||||||
|
name = "${local.name}-join"
|
||||||
|
vpc_id = aws_vpc.vpc.id
|
||||||
|
lb_arn = aws_lb.front_end.arn
|
||||||
|
port = local.ports_join
|
||||||
|
tags = local.tags
|
||||||
|
healthcheck_protocol = "TCP"
|
||||||
|
}
|
||||||
|
|
||||||
module "instance_group" {
|
module "instance_group" {
|
||||||
source = "./modules/instance_group"
|
source = "./modules/instance_group"
|
||||||
for_each = var.node_groups
|
for_each = var.node_groups
|
||||||
|
@ -32,6 +32,7 @@ locals {
|
|||||||
ports_konnectivity = "8132"
|
ports_konnectivity = "8132"
|
||||||
ports_verify = "30081"
|
ports_verify = "30081"
|
||||||
ports_recovery = "9999"
|
ports_recovery = "9999"
|
||||||
|
ports_join = "30090"
|
||||||
ports_debugd = "4000"
|
ports_debugd = "4000"
|
||||||
cidr_vpc_subnet_nodes = "192.168.178.0/24"
|
cidr_vpc_subnet_nodes = "192.168.178.0/24"
|
||||||
cidr_vpc_subnet_pods = "10.10.0.0/16"
|
cidr_vpc_subnet_pods = "10.10.0.0/16"
|
||||||
@ -182,6 +183,12 @@ module "loadbalancer_backend_control_plane" {
|
|||||||
protocol = "Tcp",
|
protocol = "Tcp",
|
||||||
path = null
|
path = null
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name = "join",
|
||||||
|
port = local.ports_join,
|
||||||
|
protocol = "Tcp",
|
||||||
|
path = null
|
||||||
|
},
|
||||||
var.debug ? [{
|
var.debug ? [{
|
||||||
name = "debugd",
|
name = "debugd",
|
||||||
port = local.ports_debugd,
|
port = local.ports_debugd,
|
||||||
@ -231,8 +238,9 @@ resource "azurerm_network_security_group" "security_group" {
|
|||||||
{ name = "kubernetes", priority = 101, dest_port_range = local.ports_kubernetes },
|
{ name = "kubernetes", priority = 101, dest_port_range = local.ports_kubernetes },
|
||||||
{ name = "bootstrapper", priority = 102, dest_port_range = local.ports_bootstrapper },
|
{ name = "bootstrapper", priority = 102, dest_port_range = local.ports_bootstrapper },
|
||||||
{ name = "konnectivity", priority = 103, dest_port_range = local.ports_konnectivity },
|
{ name = "konnectivity", priority = 103, dest_port_range = local.ports_konnectivity },
|
||||||
{ name = "recovery", priority = 104, dest_port_range = local.ports_recovery },
|
{ name = "join", priority = 104, dest_port_range = local.ports_recovery },
|
||||||
var.debug ? [{ name = "debugd", priority = 105, dest_port_range = local.ports_debugd }] : [],
|
{ name = "recovery", priority = 105, dest_port_range = local.ports_join },
|
||||||
|
var.debug ? [{ name = "debugd", priority = 106, dest_port_range = local.ports_debugd }] : [],
|
||||||
])
|
])
|
||||||
content {
|
content {
|
||||||
name = security_rule.value.name
|
name = security_rule.value.name
|
||||||
|
@ -42,6 +42,7 @@ locals {
|
|||||||
ports_konnectivity = "8132"
|
ports_konnectivity = "8132"
|
||||||
ports_verify = "30081"
|
ports_verify = "30081"
|
||||||
ports_recovery = "9999"
|
ports_recovery = "9999"
|
||||||
|
ports_join = "30090"
|
||||||
ports_debugd = "4000"
|
ports_debugd = "4000"
|
||||||
cidr_vpc_subnet_nodes = "192.168.178.0/24"
|
cidr_vpc_subnet_nodes = "192.168.178.0/24"
|
||||||
cidr_vpc_subnet_pods = "10.10.0.0/16"
|
cidr_vpc_subnet_pods = "10.10.0.0/16"
|
||||||
@ -52,6 +53,7 @@ locals {
|
|||||||
{ name = "verify", port = local.ports_verify },
|
{ name = "verify", port = local.ports_verify },
|
||||||
{ name = "konnectivity", port = local.ports_konnectivity },
|
{ name = "konnectivity", port = local.ports_konnectivity },
|
||||||
{ name = "recovery", port = local.ports_recovery },
|
{ name = "recovery", port = local.ports_recovery },
|
||||||
|
{ name = "join", port = local.ports_join },
|
||||||
var.debug ? [{ name = "debugd", port = local.ports_debugd }] : [],
|
var.debug ? [{ name = "debugd", port = local.ports_debugd }] : [],
|
||||||
])
|
])
|
||||||
node_groups_by_role = {
|
node_groups_by_role = {
|
||||||
@ -120,6 +122,7 @@ resource "google_compute_firewall" "firewall_external" {
|
|||||||
local.ports_kubernetes,
|
local.ports_kubernetes,
|
||||||
local.ports_konnectivity,
|
local.ports_konnectivity,
|
||||||
local.ports_recovery,
|
local.ports_recovery,
|
||||||
|
local.ports_join,
|
||||||
var.debug ? [local.ports_debugd] : [],
|
var.debug ? [local.ports_debugd] : [],
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
@ -234,6 +237,17 @@ module "loadbalancer_recovery" {
|
|||||||
frontend_labels = merge(local.labels, { constellation-use = "recovery" })
|
frontend_labels = merge(local.labels, { constellation-use = "recovery" })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module "loadbalancer_join" {
|
||||||
|
source = "./modules/loadbalancer"
|
||||||
|
name = local.name
|
||||||
|
health_check = "TCP"
|
||||||
|
backend_port_name = "join"
|
||||||
|
backend_instance_groups = local.control_plane_instance_groups
|
||||||
|
ip_address = google_compute_global_address.loadbalancer_ip.self_link
|
||||||
|
port = local.ports_join
|
||||||
|
frontend_labels = merge(local.labels, { constellation-use = "join" })
|
||||||
|
}
|
||||||
|
|
||||||
module "loadbalancer_debugd" {
|
module "loadbalancer_debugd" {
|
||||||
count = var.debug ? 1 : 0 // only deploy debugd in debug mode
|
count = var.debug ? 1 : 0 // only deploy debugd in debug mode
|
||||||
source = "./modules/loadbalancer"
|
source = "./modules/loadbalancer"
|
||||||
|
@ -8,6 +8,7 @@ go_library(
|
|||||||
visibility = ["//disk-mapper:__subpackages__"],
|
visibility = ["//disk-mapper:__subpackages__"],
|
||||||
deps = [
|
deps = [
|
||||||
"//internal/cloud/metadata",
|
"//internal/cloud/metadata",
|
||||||
|
"//internal/constants",
|
||||||
"//internal/logger",
|
"//internal/logger",
|
||||||
"//internal/role",
|
"//internal/role",
|
||||||
"//joinservice/joinproto",
|
"//joinservice/joinproto",
|
||||||
|
@ -14,10 +14,13 @@ package rejoinclient
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/cloud/metadata"
|
"github.com/edgelesssys/constellation/v2/internal/cloud/metadata"
|
||||||
|
"github.com/edgelesssys/constellation/v2/internal/constants"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/logger"
|
"github.com/edgelesssys/constellation/v2/internal/logger"
|
||||||
"github.com/edgelesssys/constellation/v2/internal/role"
|
"github.com/edgelesssys/constellation/v2/internal/role"
|
||||||
"github.com/edgelesssys/constellation/v2/joinservice/joinproto"
|
"github.com/edgelesssys/constellation/v2/joinservice/joinproto"
|
||||||
@ -75,7 +78,7 @@ func (c *RejoinClient) Start(ctx context.Context, diskUUID string) (diskKey, mea
|
|||||||
defer c.log.Infof("RejoinClient stopped")
|
defer c.log.Infof("RejoinClient stopped")
|
||||||
|
|
||||||
for {
|
for {
|
||||||
endpoints, err := c.getControlPlaneEndpoints()
|
endpoints, err := c.getJoinEndpoints()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.log.With(zap.Error(err)).Errorf("Failed to get control-plane endpoints")
|
c.log.With(zap.Error(err)).Errorf("Failed to get control-plane endpoints")
|
||||||
} else {
|
} else {
|
||||||
@ -130,19 +133,39 @@ func (c *RejoinClient) requestRejoinTicket(endpoint string) (*joinproto.IssueRej
|
|||||||
return joinproto.NewAPIClient(conn).IssueRejoinTicket(ctx, &joinproto.IssueRejoinTicketRequest{DiskUuid: c.diskUUID})
|
return joinproto.NewAPIClient(conn).IssueRejoinTicket(ctx, &joinproto.IssueRejoinTicketRequest{DiskUuid: c.diskUUID})
|
||||||
}
|
}
|
||||||
|
|
||||||
// getControlPlaneEndpoints requests the available control-plane endpoints from the metadata API.
|
// getJoinEndpoints requests the available control-plane endpoints from the metadata API.
|
||||||
// The list is filtered to remove *this* node if it is a restarting control-plane node.
|
// The list is filtered to remove *this* node if it is a restarting control-plane node.
|
||||||
func (c *RejoinClient) getControlPlaneEndpoints() ([]string, error) {
|
// Furthermore, the load balancer's endpoint is added.
|
||||||
|
func (c *RejoinClient) getJoinEndpoints() ([]string, error) {
|
||||||
ctx, cancel := c.timeoutCtx()
|
ctx, cancel := c.timeoutCtx()
|
||||||
defer cancel()
|
defer cancel()
|
||||||
endpoints, err := metadata.JoinServiceEndpoints(ctx, c.metadataAPI)
|
|
||||||
|
joinEndpoints := []string{}
|
||||||
|
|
||||||
|
lbEndpoint, _, err := c.metadataAPI.GetLoadBalancerEndpoint(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("retrieving load balancer endpoint from cloud provider: %w", err)
|
||||||
}
|
}
|
||||||
|
joinEndpoints = append(joinEndpoints, net.JoinHostPort(lbEndpoint, strconv.Itoa(constants.JoinServiceNodePort)))
|
||||||
|
|
||||||
|
instances, err := c.metadataAPI.List(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("retrieving instances list from cloud provider: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, instance := range instances {
|
||||||
|
if instance.Role == role.ControlPlane {
|
||||||
|
if instance.VPCIP != "" {
|
||||||
|
joinEndpoints = append(joinEndpoints, net.JoinHostPort(instance.VPCIP, strconv.Itoa(constants.JoinServiceNodePort)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if c.nodeInfo.Role == role.ControlPlane {
|
if c.nodeInfo.Role == role.ControlPlane {
|
||||||
return removeSelfFromEndpoints(c.nodeInfo.VPCIP, endpoints), nil
|
return removeSelfFromEndpoints(c.nodeInfo.VPCIP, joinEndpoints), nil
|
||||||
}
|
}
|
||||||
return endpoints, nil
|
|
||||||
|
return joinEndpoints, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// removeSelfFromEndpoints removes *this* node from the list of endpoints.
|
// removeSelfFromEndpoints removes *this* node from the list of endpoints.
|
||||||
@ -169,4 +192,6 @@ type grpcDialer interface {
|
|||||||
type metadataAPI interface {
|
type metadataAPI interface {
|
||||||
// List retrieves all instances belonging to the current constellation.
|
// List retrieves all instances belonging to the current constellation.
|
||||||
List(ctx context.Context) ([]metadata.InstanceMetadata, error)
|
List(ctx context.Context) ([]metadata.InstanceMetadata, error)
|
||||||
|
// GetLoadBalancerEndpoint retrieves the load balancer endpoint.
|
||||||
|
GetLoadBalancerEndpoint(ctx context.Context) (host, port string, err error)
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ func TestRemoveSelfFromEndpoints(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetControlPlaneEndpoints(t *testing.T) {
|
func TestGetJoinEndpoints(t *testing.T) {
|
||||||
testInstances := []metadata.InstanceMetadata{
|
testInstances := []metadata.InstanceMetadata{
|
||||||
{
|
{
|
||||||
Role: role.ControlPlane,
|
Role: role.ControlPlane,
|
||||||
@ -154,7 +154,7 @@ func TestGetControlPlaneEndpoints(t *testing.T) {
|
|||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
nodeInfo metadata.InstanceMetadata
|
nodeInfo metadata.InstanceMetadata
|
||||||
meta stubMetadataAPI
|
meta stubMetadataAPI
|
||||||
wantInstances int
|
wantEndpoints int
|
||||||
wantErr bool
|
wantErr bool
|
||||||
}{
|
}{
|
||||||
"worker node": {
|
"worker node": {
|
||||||
@ -164,8 +164,9 @@ func TestGetControlPlaneEndpoints(t *testing.T) {
|
|||||||
},
|
},
|
||||||
meta: stubMetadataAPI{
|
meta: stubMetadataAPI{
|
||||||
instances: testInstances,
|
instances: testInstances,
|
||||||
|
lbEndpoint: "192.0.2.100",
|
||||||
},
|
},
|
||||||
wantInstances: 3,
|
wantEndpoints: 4,
|
||||||
},
|
},
|
||||||
"control-plane node not in list": {
|
"control-plane node not in list": {
|
||||||
nodeInfo: metadata.InstanceMetadata{
|
nodeInfo: metadata.InstanceMetadata{
|
||||||
@ -174,8 +175,9 @@ func TestGetControlPlaneEndpoints(t *testing.T) {
|
|||||||
},
|
},
|
||||||
meta: stubMetadataAPI{
|
meta: stubMetadataAPI{
|
||||||
instances: testInstances,
|
instances: testInstances,
|
||||||
|
lbEndpoint: "192.0.2.100",
|
||||||
},
|
},
|
||||||
wantInstances: 3,
|
wantEndpoints: 4,
|
||||||
},
|
},
|
||||||
"control-plane node in list": {
|
"control-plane node in list": {
|
||||||
nodeInfo: metadata.InstanceMetadata{
|
nodeInfo: metadata.InstanceMetadata{
|
||||||
@ -184,16 +186,27 @@ func TestGetControlPlaneEndpoints(t *testing.T) {
|
|||||||
},
|
},
|
||||||
meta: stubMetadataAPI{
|
meta: stubMetadataAPI{
|
||||||
instances: testInstances,
|
instances: testInstances,
|
||||||
|
lbEndpoint: "192.0.2.100",
|
||||||
},
|
},
|
||||||
wantInstances: 2,
|
wantEndpoints: 3,
|
||||||
},
|
},
|
||||||
"metadata error": {
|
"metadata list error": {
|
||||||
nodeInfo: metadata.InstanceMetadata{
|
nodeInfo: metadata.InstanceMetadata{
|
||||||
Role: role.ControlPlane,
|
Role: role.ControlPlane,
|
||||||
VPCIP: "192.0.2.1",
|
VPCIP: "192.0.2.1",
|
||||||
},
|
},
|
||||||
meta: stubMetadataAPI{
|
meta: stubMetadataAPI{
|
||||||
err: errors.New("error"),
|
listErr: assert.AnError,
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
"metadata load balancer error": {
|
||||||
|
nodeInfo: metadata.InstanceMetadata{
|
||||||
|
Role: role.ControlPlane,
|
||||||
|
VPCIP: "192.0.2.1",
|
||||||
|
},
|
||||||
|
meta: stubMetadataAPI{
|
||||||
|
getLoadBalancerEndpointErr: assert.AnError,
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
@ -205,13 +218,14 @@ func TestGetControlPlaneEndpoints(t *testing.T) {
|
|||||||
|
|
||||||
client := New(nil, tc.nodeInfo, tc.meta, logger.NewTest(t))
|
client := New(nil, tc.nodeInfo, tc.meta, logger.NewTest(t))
|
||||||
|
|
||||||
endpoints, err := client.getControlPlaneEndpoints()
|
endpoints, err := client.getJoinEndpoints()
|
||||||
if tc.wantErr {
|
if tc.wantErr {
|
||||||
assert.Error(err)
|
assert.Error(err)
|
||||||
} else {
|
} else {
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.NotContains(endpoints, tc.nodeInfo.VPCIP)
|
assert.NotContains(endpoints, tc.nodeInfo.VPCIP)
|
||||||
assert.Len(endpoints, tc.wantInstances)
|
// +1 for the load balancer endpoint
|
||||||
|
assert.Len(endpoints, tc.wantEndpoints)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -289,11 +303,17 @@ func TestStart(t *testing.T) {
|
|||||||
|
|
||||||
type stubMetadataAPI struct {
|
type stubMetadataAPI struct {
|
||||||
instances []metadata.InstanceMetadata
|
instances []metadata.InstanceMetadata
|
||||||
err error
|
lbEndpoint string
|
||||||
|
getLoadBalancerEndpointErr error
|
||||||
|
listErr error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s stubMetadataAPI) List(context.Context) ([]metadata.InstanceMetadata, error) {
|
func (s stubMetadataAPI) List(context.Context) ([]metadata.InstanceMetadata, error) {
|
||||||
return s.instances, s.err
|
return s.instances, s.listErr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s stubMetadataAPI) GetLoadBalancerEndpoint(_ context.Context) (string, string, error) {
|
||||||
|
return s.lbEndpoint, "", s.getLoadBalancerEndpointErr
|
||||||
}
|
}
|
||||||
|
|
||||||
type stubRejoinServiceAPI struct {
|
type stubRejoinServiceAPI struct {
|
||||||
|
@ -7,6 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
package setup
|
package setup
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
@ -37,6 +38,7 @@ type ConfigurationGenerator interface {
|
|||||||
type MetadataAPI interface {
|
type MetadataAPI interface {
|
||||||
metadata.InstanceSelfer
|
metadata.InstanceSelfer
|
||||||
metadata.InstanceLister
|
metadata.InstanceLister
|
||||||
|
GetLoadBalancerEndpoint(ctx context.Context) (host, port string, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RecoveryDoer is an interface to perform key recovery operations.
|
// RecoveryDoer is an interface to perform key recovery operations.
|
||||||
|
@ -5,8 +5,5 @@ go_library(
|
|||||||
srcs = ["metadata.go"],
|
srcs = ["metadata.go"],
|
||||||
importpath = "github.com/edgelesssys/constellation/v2/internal/cloud/metadata",
|
importpath = "github.com/edgelesssys/constellation/v2/internal/cloud/metadata",
|
||||||
visibility = ["//:__subpackages__"],
|
visibility = ["//:__subpackages__"],
|
||||||
deps = [
|
deps = ["//internal/role"],
|
||||||
"//internal/constants",
|
|
||||||
"//internal/role",
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
|
@ -8,11 +8,7 @@ package metadata
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"net"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/constants"
|
|
||||||
"github.com/edgelesssys/constellation/v2/internal/role"
|
"github.com/edgelesssys/constellation/v2/internal/role"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -43,21 +39,3 @@ type InstanceLister interface {
|
|||||||
// List retrieves all instances belonging to the current constellation.
|
// List retrieves all instances belonging to the current constellation.
|
||||||
List(ctx context.Context) ([]InstanceMetadata, error)
|
List(ctx context.Context) ([]InstanceMetadata, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// JoinServiceEndpoints returns the list of endpoints for the join service, which are running on the control plane nodes.
|
|
||||||
func JoinServiceEndpoints(ctx context.Context, lister InstanceLister) ([]string, error) {
|
|
||||||
instances, err := lister.List(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("retrieving instances list from cloud provider: %w", err)
|
|
||||||
}
|
|
||||||
joinEndpoints := []string{}
|
|
||||||
for _, instance := range instances {
|
|
||||||
if instance.Role == role.ControlPlane {
|
|
||||||
if instance.VPCIP != "" {
|
|
||||||
joinEndpoints = append(joinEndpoints, net.JoinHostPort(instance.VPCIP, strconv.Itoa(constants.JoinServiceNodePort)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return joinEndpoints, nil
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user