Rename coordinator to bootstrapper and rename roles

This commit is contained in:
katexochen 2022-06-29 15:26:29 +02:00 committed by Paul Meyer
parent 3280ed200c
commit 916e5d6b55
191 changed files with 1763 additions and 2030 deletions

View file

@ -33,23 +33,23 @@ type Client struct {
iamAPI
projectsAPI
nodes cloudtypes.Instances
coordinators cloudtypes.Instances
workers cloudtypes.Instances
controlPlanes cloudtypes.Instances
nodesInstanceGroup string
coordinatorInstanceGroup string
coordinatorTemplate string
nodeTemplate string
network string
subnetwork string
secondarySubnetworkRange string
firewalls []string
name string
project string
uid string
zone string
region string
serviceAccount string
workerInstanceGroup string
controlPlaneInstanceGroup string
controlPlaneTemplate string
workerTemplate string
network string
subnetwork string
secondarySubnetworkRange string
firewalls []string
name string
project string
uid string
zone string
region string
serviceAccount string
// loadbalancer
healthCheck string
@ -163,8 +163,8 @@ func NewFromDefault(ctx context.Context) (*Client, error) {
instanceGroupManagersAPI: &instanceGroupManagersClient{groupAPI},
iamAPI: &iamClient{iamAPI},
projectsAPI: &projectsClient{projectsAPI},
nodes: make(cloudtypes.Instances),
coordinators: make(cloudtypes.Instances),
workers: make(cloudtypes.Instances),
controlPlanes: make(cloudtypes.Instances),
}, nil
}
@ -218,25 +218,25 @@ func (c *Client) init(project, zone, region, name string) error {
func (c *Client) GetState() (state.ConstellationState, error) {
var stat state.ConstellationState
stat.CloudProvider = cloudprovider.GCP.String()
if len(c.nodes) == 0 {
return state.ConstellationState{}, errors.New("client has no nodes")
if len(c.workers) == 0 {
return state.ConstellationState{}, errors.New("client has no workers")
}
stat.GCPNodes = c.nodes
stat.GCPWorkers = c.workers
if len(c.coordinators) == 0 {
return state.ConstellationState{}, errors.New("client has no coordinators")
if len(c.controlPlanes) == 0 {
return state.ConstellationState{}, errors.New("client has no controlPlanes")
}
stat.GCPCoordinators = c.coordinators
stat.GCPControlPlanes = c.controlPlanes
if c.nodesInstanceGroup == "" {
return state.ConstellationState{}, errors.New("client has no nodeInstanceGroup")
if c.workerInstanceGroup == "" {
return state.ConstellationState{}, errors.New("client has no workerInstanceGroup")
}
stat.GCPNodeInstanceGroup = c.nodesInstanceGroup
stat.GCPWorkerInstanceGroup = c.workerInstanceGroup
if c.coordinatorInstanceGroup == "" {
return state.ConstellationState{}, errors.New("client has no coordinatorInstanceGroup")
if c.controlPlaneInstanceGroup == "" {
return state.ConstellationState{}, errors.New("client has no controlPlaneInstanceGroup")
}
stat.GCPCoordinatorInstanceGroup = c.coordinatorInstanceGroup
stat.GCPControlPlaneInstanceGroup = c.controlPlaneInstanceGroup
if c.project == "" {
return state.ConstellationState{}, errors.New("client has no project")
@ -278,15 +278,15 @@ func (c *Client) GetState() (state.ConstellationState, error) {
}
stat.GCPSubnetwork = c.subnetwork
if c.nodeTemplate == "" {
return state.ConstellationState{}, errors.New("client has no node instance template")
if c.workerTemplate == "" {
return state.ConstellationState{}, errors.New("client has no worker instance template")
}
stat.GCPNodeInstanceTemplate = c.nodeTemplate
stat.GCPWorkerInstanceTemplate = c.workerTemplate
if c.coordinatorTemplate == "" {
return state.ConstellationState{}, errors.New("client has no coordinator instance template")
if c.controlPlaneTemplate == "" {
return state.ConstellationState{}, errors.New("client has no controlPlane instance template")
}
stat.GCPCoordinatorInstanceTemplate = c.coordinatorTemplate
stat.GCPControlPlaneInstanceTemplate = c.controlPlaneTemplate
if c.healthCheck == "" {
return state.ConstellationState{}, errors.New("client has no health check")
@ -314,25 +314,25 @@ func (c *Client) SetState(stat state.ConstellationState) error {
if stat.CloudProvider != cloudprovider.GCP.String() {
return errors.New("state is not gcp state")
}
if len(stat.GCPNodes) == 0 {
return errors.New("state has no nodes")
if len(stat.GCPWorkers) == 0 {
return errors.New("state has no workers")
}
c.nodes = stat.GCPNodes
c.workers = stat.GCPWorkers
if len(stat.GCPCoordinators) == 0 {
return errors.New("state has no coordinator")
if len(stat.GCPControlPlanes) == 0 {
return errors.New("state has no controlPlane")
}
c.coordinators = stat.GCPCoordinators
c.controlPlanes = stat.GCPControlPlanes
if stat.GCPNodeInstanceGroup == "" {
return errors.New("state has no nodeInstanceGroup")
if stat.GCPWorkerInstanceGroup == "" {
return errors.New("state has no workerInstanceGroup")
}
c.nodesInstanceGroup = stat.GCPNodeInstanceGroup
c.workerInstanceGroup = stat.GCPWorkerInstanceGroup
if stat.GCPCoordinatorInstanceGroup == "" {
return errors.New("state has no coordinatorInstanceGroup")
if stat.GCPControlPlaneInstanceGroup == "" {
return errors.New("state has no controlPlaneInstanceGroup")
}
c.coordinatorInstanceGroup = stat.GCPCoordinatorInstanceGroup
c.controlPlaneInstanceGroup = stat.GCPControlPlaneInstanceGroup
if stat.GCPProject == "" {
return errors.New("state has no project")
@ -374,15 +374,15 @@ func (c *Client) SetState(stat state.ConstellationState) error {
}
c.subnetwork = stat.GCPSubnetwork
if stat.GCPNodeInstanceTemplate == "" {
return errors.New("state has no node instance template")
if stat.GCPWorkerInstanceTemplate == "" {
return errors.New("state has no worker instance template")
}
c.nodeTemplate = stat.GCPNodeInstanceTemplate
c.workerTemplate = stat.GCPWorkerInstanceTemplate
if stat.GCPCoordinatorInstanceTemplate == "" {
return errors.New("state has no coordinator instance template")
if stat.GCPControlPlaneInstanceTemplate == "" {
return errors.New("state has no controlPlane instance template")
}
c.coordinatorTemplate = stat.GCPCoordinatorInstanceTemplate
c.controlPlaneTemplate = stat.GCPControlPlaneInstanceTemplate
if stat.GCPHealthCheck == "" {
return errors.New("state has no health check")

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,7 @@ import (
"strings"
"time"
"github.com/edgelesssys/constellation/coordinator/role"
"github.com/edgelesssys/constellation/bootstrapper/role"
"github.com/edgelesssys/constellation/internal/cloud/cloudtypes"
"google.golang.org/api/iterator"
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
@ -16,7 +16,7 @@ import (
// CreateInstances creates instances (virtual machines) on Google Compute Engine.
//
// A separate managed instance group is created for coordinators and nodes, the function
// A separate managed instance group is created for control planes and workers, the function
// waits until the instances are up and stores the public and private IPs of the instances
// in the client. If the client's network must be set before instances can be created.
func (c *Client) CreateInstances(ctx context.Context, input CreateInstancesInput) error {
@ -25,7 +25,7 @@ func (c *Client) CreateInstances(ctx context.Context, input CreateInstancesInput
}
ops := []Operation{}
nodeTemplateInput := insertInstanceTemplateInput{
workerTemplateInput := insertInstanceTemplateInput{
Name: c.name + "-worker-" + c.uid,
Network: c.network,
SecondarySubnetworkRangeName: c.secondarySubnetworkRange,
@ -33,21 +33,21 @@ func (c *Client) CreateInstances(ctx context.Context, input CreateInstancesInput
ImageId: input.ImageId,
InstanceType: input.InstanceType,
StateDiskSizeGB: int64(input.StateDiskSizeGB),
Role: role.Node.String(),
Role: role.Worker.String(),
KubeEnv: input.KubeEnv,
Project: c.project,
Zone: c.zone,
Region: c.region,
UID: c.uid,
}
op, err := c.insertInstanceTemplate(ctx, nodeTemplateInput)
op, err := c.insertInstanceTemplate(ctx, workerTemplateInput)
if err != nil {
return fmt.Errorf("inserting instanceTemplate: %w", err)
}
ops = append(ops, op)
c.nodeTemplate = nodeTemplateInput.Name
c.workerTemplate = workerTemplateInput.Name
coordinatorTemplateInput := insertInstanceTemplateInput{
controlPlaneTemplateInput := insertInstanceTemplateInput{
Name: c.name + "-control-plane-" + c.uid,
Network: c.network,
Subnetwork: c.subnetwork,
@ -55,70 +55,70 @@ func (c *Client) CreateInstances(ctx context.Context, input CreateInstancesInput
ImageId: input.ImageId,
InstanceType: input.InstanceType,
StateDiskSizeGB: int64(input.StateDiskSizeGB),
Role: role.Coordinator.String(),
Role: role.ControlPlane.String(),
KubeEnv: input.KubeEnv,
Project: c.project,
Zone: c.zone,
Region: c.region,
UID: c.uid,
}
op, err = c.insertInstanceTemplate(ctx, coordinatorTemplateInput)
op, err = c.insertInstanceTemplate(ctx, controlPlaneTemplateInput)
if err != nil {
return fmt.Errorf("inserting instanceTemplate: %w", err)
}
ops = append(ops, op)
c.coordinatorTemplate = coordinatorTemplateInput.Name
c.controlPlaneTemplate = controlPlaneTemplateInput.Name
if err := c.waitForOperations(ctx, ops); err != nil {
return err
}
ops = []Operation{}
coordinatorGroupInput := instanceGroupManagerInput{
Count: input.CountCoordinators,
controlPlaneGroupInput := instanceGroupManagerInput{
Count: input.CountControlPlanes,
Name: strings.Join([]string{c.name, "control-plane", c.uid}, "-"),
Template: c.coordinatorTemplate,
Template: c.controlPlaneTemplate,
UID: c.uid,
Project: c.project,
Zone: c.zone,
}
op, err = c.insertInstanceGroupManger(ctx, coordinatorGroupInput)
op, err = c.insertInstanceGroupManger(ctx, controlPlaneGroupInput)
if err != nil {
return fmt.Errorf("inserting instanceGroupManager: %w", err)
}
ops = append(ops, op)
c.coordinatorInstanceGroup = coordinatorGroupInput.Name
c.controlPlaneInstanceGroup = controlPlaneGroupInput.Name
nodeGroupInput := instanceGroupManagerInput{
Count: input.CountNodes,
workerGroupInput := instanceGroupManagerInput{
Count: input.CountWorkers,
Name: strings.Join([]string{c.name, "worker", c.uid}, "-"),
Template: c.nodeTemplate,
Template: c.workerTemplate,
UID: c.uid,
Project: c.project,
Zone: c.zone,
}
op, err = c.insertInstanceGroupManger(ctx, nodeGroupInput)
op, err = c.insertInstanceGroupManger(ctx, workerGroupInput)
if err != nil {
return fmt.Errorf("inserting instanceGroupManager: %w", err)
}
ops = append(ops, op)
c.nodesInstanceGroup = nodeGroupInput.Name
c.workerInstanceGroup = workerGroupInput.Name
if err := c.waitForOperations(ctx, ops); err != nil {
return err
}
if err := c.waitForInstanceGroupScaling(ctx, c.nodesInstanceGroup); err != nil {
if err := c.waitForInstanceGroupScaling(ctx, c.workerInstanceGroup); err != nil {
return fmt.Errorf("waiting for instanceGroupScaling: %w", err)
}
if err := c.waitForInstanceGroupScaling(ctx, c.coordinatorInstanceGroup); err != nil {
if err := c.waitForInstanceGroupScaling(ctx, c.controlPlaneInstanceGroup); err != nil {
return fmt.Errorf("waiting for instanceGroupScaling: %w", err)
}
if err := c.getInstanceIPs(ctx, c.nodesInstanceGroup, c.nodes); err != nil {
if err := c.getInstanceIPs(ctx, c.workerInstanceGroup, c.workers); err != nil {
return fmt.Errorf("getting instanceIPs: %w", err)
}
if err := c.getInstanceIPs(ctx, c.coordinatorInstanceGroup, c.coordinators); err != nil {
if err := c.getInstanceIPs(ctx, c.controlPlaneInstanceGroup, c.controlPlanes); err != nil {
return fmt.Errorf("getting instanceIPs: %w", err)
}
return nil
@ -127,45 +127,45 @@ func (c *Client) CreateInstances(ctx context.Context, input CreateInstancesInput
// TerminateInstances terminates the clients instances.
func (c *Client) TerminateInstances(ctx context.Context) error {
ops := []Operation{}
if c.nodesInstanceGroup != "" {
op, err := c.deleteInstanceGroupManager(ctx, c.nodesInstanceGroup)
if c.workerInstanceGroup != "" {
op, err := c.deleteInstanceGroupManager(ctx, c.workerInstanceGroup)
if err != nil {
return fmt.Errorf("deleting instanceGroupManager '%s': %w", c.nodesInstanceGroup, err)
return fmt.Errorf("deleting instanceGroupManager '%s': %w", c.workerInstanceGroup, err)
}
ops = append(ops, op)
c.nodesInstanceGroup = ""
c.nodes = make(cloudtypes.Instances)
c.workerInstanceGroup = ""
c.workers = make(cloudtypes.Instances)
}
if c.coordinatorInstanceGroup != "" {
op, err := c.deleteInstanceGroupManager(ctx, c.coordinatorInstanceGroup)
if c.controlPlaneInstanceGroup != "" {
op, err := c.deleteInstanceGroupManager(ctx, c.controlPlaneInstanceGroup)
if err != nil {
return fmt.Errorf("deleting instanceGroupManager '%s': %w", c.coordinatorInstanceGroup, err)
return fmt.Errorf("deleting instanceGroupManager '%s': %w", c.controlPlaneInstanceGroup, err)
}
ops = append(ops, op)
c.coordinatorInstanceGroup = ""
c.coordinators = make(cloudtypes.Instances)
c.controlPlaneInstanceGroup = ""
c.controlPlanes = make(cloudtypes.Instances)
}
if err := c.waitForOperations(ctx, ops); err != nil {
return err
}
ops = []Operation{}
if c.nodeTemplate != "" {
op, err := c.deleteInstanceTemplate(ctx, c.nodeTemplate)
if c.workerTemplate != "" {
op, err := c.deleteInstanceTemplate(ctx, c.workerTemplate)
if err != nil {
return fmt.Errorf("deleting instanceTemplate: %w", err)
}
ops = append(ops, op)
c.nodeTemplate = ""
c.workerTemplate = ""
}
if c.coordinatorTemplate != "" {
op, err := c.deleteInstanceTemplate(ctx, c.coordinatorTemplate)
if c.controlPlaneTemplate != "" {
op, err := c.deleteInstanceTemplate(ctx, c.controlPlaneTemplate)
if err != nil {
return fmt.Errorf("deleting instanceTemplate: %w", err)
}
ops = append(ops, op)
c.coordinatorTemplate = ""
c.controlPlaneTemplate = ""
}
return c.waitForOperations(ctx, ops)
}
@ -290,12 +290,12 @@ func (i *instanceGroupManagerInput) InsertInstanceGroupManagerRequest() computep
// CreateInstancesInput is the input for a CreatInstances operation.
type CreateInstancesInput struct {
CountNodes int
CountCoordinators int
ImageId string
InstanceType string
StateDiskSizeGB int
KubeEnv string
CountWorkers int
CountControlPlanes int
ImageId string
InstanceType string
StateDiskSizeGB int
KubeEnv string
}
type insertInstanceTemplateInput struct {

View file

@ -41,11 +41,11 @@ func TestCreateInstances(t *testing.T) {
{CurrentAction: proto.String(computepb.ManagedInstance_NONE.String())},
}
testInput := CreateInstancesInput{
CountCoordinators: 3,
CountNodes: 4,
ImageId: "img",
InstanceType: "n2d-standard-2",
KubeEnv: "kube-env",
CountControlPlanes: 3,
CountWorkers: 4,
ImageId: "img",
InstanceType: "n2d-standard-2",
KubeEnv: "kube-env",
}
someErr := errors.New("failed")
@ -157,22 +157,22 @@ func TestCreateInstances(t *testing.T) {
operationGlobalAPI: tc.operationGlobalAPI,
instanceTemplateAPI: tc.instanceTemplateAPI,
instanceGroupManagersAPI: tc.instanceGroupManagersAPI,
nodes: make(cloudtypes.Instances),
coordinators: make(cloudtypes.Instances),
workers: make(cloudtypes.Instances),
controlPlanes: make(cloudtypes.Instances),
}
if tc.wantErr {
assert.Error(client.CreateInstances(ctx, tc.input))
} else {
assert.NoError(client.CreateInstances(ctx, tc.input))
assert.Equal([]string{"public-ip", "public-ip"}, client.nodes.PublicIPs())
assert.Equal([]string{"private-ip", "private-ip"}, client.nodes.PrivateIPs())
assert.Equal([]string{"public-ip", "public-ip"}, client.coordinators.PublicIPs())
assert.Equal([]string{"private-ip", "private-ip"}, client.coordinators.PrivateIPs())
assert.NotNil(client.nodesInstanceGroup)
assert.NotNil(client.coordinatorInstanceGroup)
assert.NotNil(client.coordinatorTemplate)
assert.NotNil(client.nodeTemplate)
assert.Equal([]string{"public-ip", "public-ip"}, client.workers.PublicIPs())
assert.Equal([]string{"private-ip", "private-ip"}, client.workers.PrivateIPs())
assert.Equal([]string{"public-ip", "public-ip"}, client.controlPlanes.PublicIPs())
assert.Equal([]string{"private-ip", "private-ip"}, client.controlPlanes.PrivateIPs())
assert.NotNil(client.workerInstanceGroup)
assert.NotNil(client.controlPlaneInstanceGroup)
assert.NotNil(client.controlPlaneTemplate)
assert.NotNil(client.workerTemplate)
}
})
}
@ -186,8 +186,8 @@ func TestTerminateInstances(t *testing.T) {
instanceTemplateAPI instanceTemplateAPI
instanceGroupManagersAPI instanceGroupManagersAPI
missingNodeInstanceGroup bool
wantErr bool
missingWorkerInstanceGroup bool
wantErr bool
}{
"successful terminate": {
operationZoneAPI: stubOperationZoneAPI{},
@ -195,12 +195,12 @@ func TestTerminateInstances(t *testing.T) {
instanceTemplateAPI: stubInstanceTemplateAPI{},
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{},
},
"successful terminate with missing node instance group": {
operationZoneAPI: stubOperationZoneAPI{},
operationGlobalAPI: stubOperationGlobalAPI{},
instanceTemplateAPI: stubInstanceTemplateAPI{},
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{},
missingNodeInstanceGroup: true,
"successful terminate with missing worker instance group": {
operationZoneAPI: stubOperationZoneAPI{},
operationGlobalAPI: stubOperationGlobalAPI{},
instanceTemplateAPI: stubInstanceTemplateAPI{},
instanceGroupManagersAPI: stubInstanceGroupManagersAPI{},
missingWorkerInstanceGroup: true,
},
"fail delete instanceGroupManager": {
operationZoneAPI: stubOperationZoneAPI{},
@ -223,40 +223,40 @@ func TestTerminateInstances(t *testing.T) {
ctx := context.Background()
client := Client{
project: "project",
zone: "zone",
name: "name",
uid: "uid",
operationZoneAPI: tc.operationZoneAPI,
operationGlobalAPI: tc.operationGlobalAPI,
instanceTemplateAPI: tc.instanceTemplateAPI,
instanceGroupManagersAPI: tc.instanceGroupManagersAPI,
nodes: cloudtypes.Instances{"node-id-1": cloudtypes.Instance{}, "node-id-2": cloudtypes.Instance{}},
coordinators: cloudtypes.Instances{"coordinator-id-1": cloudtypes.Instance{}},
firewalls: []string{"firewall-1", "firewall-2"},
network: "network-id-1",
nodesInstanceGroup: "nodeInstanceGroup-id-1",
coordinatorInstanceGroup: "coordinatorInstanceGroup-id-1",
nodeTemplate: "template-id-1",
coordinatorTemplate: "template-id-1",
project: "project",
zone: "zone",
name: "name",
uid: "uid",
operationZoneAPI: tc.operationZoneAPI,
operationGlobalAPI: tc.operationGlobalAPI,
instanceTemplateAPI: tc.instanceTemplateAPI,
instanceGroupManagersAPI: tc.instanceGroupManagersAPI,
workers: cloudtypes.Instances{"worker-id-1": cloudtypes.Instance{}, "worker-id-2": cloudtypes.Instance{}},
controlPlanes: cloudtypes.Instances{"controlplane-id-1": cloudtypes.Instance{}},
firewalls: []string{"firewall-1", "firewall-2"},
network: "network-id-1",
workerInstanceGroup: "workerInstanceGroup-id-1",
controlPlaneInstanceGroup: "controlplaneInstanceGroup-id-1",
workerTemplate: "template-id-1",
controlPlaneTemplate: "template-id-1",
}
if tc.missingNodeInstanceGroup {
client.nodesInstanceGroup = ""
client.nodes = cloudtypes.Instances{}
if tc.missingWorkerInstanceGroup {
client.workerInstanceGroup = ""
client.workers = cloudtypes.Instances{}
}
if tc.wantErr {
assert.Error(client.TerminateInstances(ctx))
} else {
assert.NoError(client.TerminateInstances(ctx))
assert.Nil(client.nodes.PublicIPs())
assert.Nil(client.nodes.PrivateIPs())
assert.Nil(client.coordinators.PublicIPs())
assert.Nil(client.coordinators.PrivateIPs())
assert.Empty(client.nodesInstanceGroup)
assert.Empty(client.coordinatorInstanceGroup)
assert.Empty(client.coordinatorTemplate)
assert.Empty(client.nodeTemplate)
assert.Nil(client.workers.PublicIPs())
assert.Nil(client.workers.PrivateIPs())
assert.Nil(client.controlPlanes.PublicIPs())
assert.Nil(client.controlPlanes.PrivateIPs())
assert.Empty(client.workerInstanceGroup)
assert.Empty(client.controlPlaneInstanceGroup)
assert.Empty(client.controlPlaneTemplate)
assert.Empty(client.workerTemplate)
}
})
}

View file

@ -236,7 +236,7 @@ func (c *Client) CreateLoadBalancer(ctx context.Context) error {
Backends: []*computepb.Backend{
{
BalancingMode: proto.String(computepb.Backend_BalancingMode_name[int32(compute.Backend_CONNECTION)]),
Group: proto.String("https://www.googleapis.com/compute/v1/projects/" + c.project + "/zones/" + c.zone + "/instanceGroups/" + c.coordinatorInstanceGroup),
Group: proto.String("https://www.googleapis.com/compute/v1/projects/" + c.project + "/zones/" + c.zone + "/instanceGroups/" + c.controlPlaneInstanceGroup),
},
},
},

View file

@ -71,8 +71,8 @@ func TestCreateVPCs(t *testing.T) {
operationRegionAPI: tc.operationRegionAPI,
networksAPI: tc.networksAPI,
subnetworksAPI: tc.subnetworksAPI,
nodes: make(cloudtypes.Instances),
coordinators: make(cloudtypes.Instances),
workers: make(cloudtypes.Instances),
controlPlanes: make(cloudtypes.Instances),
}
if tc.wantErr {