Use tags for UID and role parsing (#242)

* Apply tags to all applicable GCP resources

* Move GCP UID and role from VM metadata to labels

* Adjust Azure tags to be in line with GCP and AWS

* Dont rely on resource name to find resources

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
Daniel Weiße 2022-10-24 16:58:21 +02:00 committed by GitHub
parent c2814aeddb
commit b35b74b772
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 344 additions and 360 deletions

View file

@ -10,7 +10,6 @@ import (
"context"
"fmt"
"regexp"
"strings"
)
var instanceGroupIDRegex = regexp.MustCompile(`^projects/([^/]+)/zones/([^/]+)/instanceGroupManagers/([^/]+)$`)
@ -36,16 +35,6 @@ func splitInstanceGroupID(instanceGroupID string) (project, zone, instanceGroup
return matches[1], matches[2], matches[3], nil
}
// isControlPlaneInstanceGroup returns true if the instance group is a control plane instance group.
func isControlPlaneInstanceGroup(instanceGroupName string) bool {
return strings.Contains(instanceGroupName, "control-plane")
}
// isWorkerInstanceGroup returns true if the instance group is a worker instance group.
func isWorkerInstanceGroup(instanceGroupName string) bool {
return strings.Contains(instanceGroupName, "worker")
}
// generateInstanceName generates a random instance name.
func generateInstanceName(baseInstanceName string, random prng) string {
letters := []byte("abcdefghijklmnopqrstuvwxyz0123456789")

View file

@ -10,10 +10,10 @@ import (
"context"
"errors"
"fmt"
"strings"
"google.golang.org/api/iterator"
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
"google.golang.org/protobuf/proto"
)
// GetScalingGroupImage returns the image URI of the scaling group.
@ -108,7 +108,6 @@ func (c *Client) GetAutoscalingGroupName(scalingGroupID string) (string, error)
// ListScalingGroups retrieves a list of scaling groups for the cluster.
func (c *Client) ListScalingGroups(ctx context.Context, uid string) (controlPlaneGroupIDs []string, workerGroupIDs []string, err error) {
iter := c.instanceGroupManagersAPI.AggregatedList(ctx, &computepb.AggregatedListInstanceGroupManagersRequest{
Filter: proto.String(fmt.Sprintf("name eq \".+-%s-.+\"", uid)), // filter by constellation UID
Project: c.projectID,
})
for instanceGroupManagerScopedListPair, err := iter.Next(); ; instanceGroupManagerScopedListPair, err = iter.Next() {
@ -121,18 +120,38 @@ func (c *Client) ListScalingGroups(ctx context.Context, uid string) (controlPlan
if instanceGroupManagerScopedListPair.Value == nil {
continue
}
for _, instanceGroupManager := range instanceGroupManagerScopedListPair.Value.InstanceGroupManagers {
if instanceGroupManager == nil || instanceGroupManager.Name == nil || instanceGroupManager.SelfLink == nil {
for _, grpManager := range instanceGroupManagerScopedListPair.Value.InstanceGroupManagers {
if grpManager == nil || grpManager.Name == nil || grpManager.SelfLink == nil || grpManager.InstanceTemplate == nil {
continue
}
groupID, err := c.canonicalInstanceGroupID(ctx, *instanceGroupManager.SelfLink)
templateURI := strings.Split(*grpManager.InstanceTemplate, "/")
if len(templateURI) < 1 {
continue // invalid template URI
}
template, err := c.instanceTemplateAPI.Get(ctx, &computepb.GetInstanceTemplateRequest{
Project: c.projectID,
InstanceTemplate: templateURI[len(templateURI)-1],
})
if err != nil {
return nil, nil, fmt.Errorf("getting instance template: %w", err)
}
if template.Properties == nil || template.Properties.Labels == nil {
continue
}
if template.Properties.Labels["constellation-uid"] != uid {
continue
}
groupID, err := c.canonicalInstanceGroupID(ctx, *grpManager.SelfLink)
if err != nil {
return nil, nil, fmt.Errorf("normalizing instance group ID: %w", err)
}
if isControlPlaneInstanceGroup(*instanceGroupManager.Name) {
switch strings.ToLower(template.Properties.Labels["constellation-role"]) {
case "control-plane", "controlplane":
controlPlaneGroupIDs = append(controlPlaneGroupIDs, groupID)
} else if isWorkerInstanceGroup(*instanceGroupManager.Name) {
case "worker":
workerGroupIDs = append(workerGroupIDs, groupID)
}
}

View file

@ -326,7 +326,10 @@ func TestListScalingGroups(t *testing.T) {
testCases := map[string]struct {
name *string
groupID *string
templateRef *string
templateLabels map[string]string
listInstanceGroupManagersErr error
templateGetErr error
wantControlPlanes []string
wantWorkers []string
wantErr bool
@ -335,23 +338,56 @@ func TestListScalingGroups(t *testing.T) {
listInstanceGroupManagersErr: errors.New("list instance group managers error"),
wantErr: true,
},
"get instance template fails": {
name: proto.String("test-control-plane-uid"),
groupID: proto.String("projects/project/zones/zone/instanceGroupManagers/test-control-plane-uid"),
templateRef: proto.String("projects/project/global/instanceTemplates/test-control-plane-uid"),
templateGetErr: errors.New("get instance template error"),
wantErr: true,
},
"list instance group managers for control plane": {
name: proto.String("test-control-plane-uid"),
groupID: proto.String("projects/project/zones/zone/instanceGroupManagers/test-control-plane-uid"),
name: proto.String("test-control-plane-uid"),
groupID: proto.String("projects/project/zones/zone/instanceGroupManagers/test-control-plane-uid"),
templateRef: proto.String("projects/project/global/instanceTemplates/test-control-plane-uid"),
templateLabels: map[string]string{
"constellation-uid": "uid",
"constellation-role": "control-plane",
},
wantControlPlanes: []string{
"projects/project/zones/zone/instanceGroupManagers/test-control-plane-uid",
},
},
"list instance group managers for worker": {
name: proto.String("test-worker-uid"),
groupID: proto.String("projects/project/zones/zone/instanceGroupManagers/test-worker-uid"),
name: proto.String("test-worker-uid"),
groupID: proto.String("projects/project/zones/zone/instanceGroupManagers/test-worker-uid"),
templateRef: proto.String("projects/project/global/instanceTemplates/test-control-plane-uid"),
templateLabels: map[string]string{
"constellation-uid": "uid",
"constellation-role": "worker",
},
wantWorkers: []string{
"projects/project/zones/zone/instanceGroupManagers/test-worker-uid",
},
},
"listing instance group managers is not dependant on resource name": {
name: proto.String("some-instance-group-manager"),
groupID: proto.String("projects/project/zones/zone/instanceGroupManagers/some-instance-group-manager"),
templateRef: proto.String("projects/project/global/instanceTemplates/some-instance-group-template"),
templateLabels: map[string]string{
"constellation-uid": "uid",
"constellation-role": "control-plane",
},
wantControlPlanes: []string{
"projects/project/zones/zone/instanceGroupManagers/some-instance-group-manager",
},
},
"unrelated instance group manager": {
name: proto.String("test-unrelated-uid"),
groupID: proto.String("projects/project/zones/zone/instanceGroupManagers/test-unrelated-uid"),
name: proto.String("test-control-plane-uid"),
groupID: proto.String("projects/project/zones/zone/instanceGroupManagers/test-unrelated-uid"),
templateRef: proto.String("projects/project/global/instanceTemplates/test-control-plane-uid"),
templateLabels: map[string]string{
"label": "value",
},
},
"invalid instance group manager": {},
}
@ -365,10 +401,19 @@ func TestListScalingGroups(t *testing.T) {
instanceGroupManagersAPI: &stubInstanceGroupManagersAPI{
aggregatedListErr: tc.listInstanceGroupManagersErr,
instanceGroupManager: &computepb.InstanceGroupManager{
Name: tc.name,
SelfLink: tc.groupID,
Name: tc.name,
SelfLink: tc.groupID,
InstanceTemplate: tc.templateRef,
},
},
instanceTemplateAPI: &stubInstanceTemplateAPI{
template: &computepb.InstanceTemplate{
Properties: &computepb.InstanceProperties{
Labels: tc.templateLabels,
},
},
getErr: tc.templateGetErr,
},
}
gotControlPlanes, gotWorkers, err := client.ListScalingGroups(context.Background(), "uid")
if tc.wantErr {