mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-05-02 14:26:23 -04:00
[node operator] Add GCP client
Signed-off-by: Malte Poll <mp@edgeless.systems>
This commit is contained in:
parent
0618a000a7
commit
717570d00a
23 changed files with 2102 additions and 21 deletions
|
@ -0,0 +1,118 @@
|
|||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
|
||||
)
|
||||
|
||||
// GetScalingGroupImage returns the image URI of the scaling group.
|
||||
func (c *Client) GetScalingGroupImage(ctx context.Context, scalingGroupID string) (string, error) {
|
||||
instanceTemplate, err := c.getScalingGroupTemplate(ctx, scalingGroupID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return instanceTemplateSourceImage(instanceTemplate)
|
||||
}
|
||||
|
||||
// SetScalingGroupImage sets the image URI of the scaling group.
|
||||
func (c *Client) SetScalingGroupImage(ctx context.Context, scalingGroupID, imageURI string) error {
|
||||
project, zone, instanceGroupName, err := splitInstanceGroupID(scalingGroupID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// get current template
|
||||
instanceTemplate, err := c.getScalingGroupTemplate(ctx, scalingGroupID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// check if template already uses the same image
|
||||
oldImageURI, err := instanceTemplateSourceImage(instanceTemplate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if oldImageURI == imageURI {
|
||||
return nil
|
||||
}
|
||||
|
||||
// clone template with desired image
|
||||
if instanceTemplate.Name == nil {
|
||||
return fmt.Errorf("instance template of scaling group %q has no name", scalingGroupID)
|
||||
}
|
||||
instanceTemplate.Properties.Disks[0].InitializeParams.SourceImage = &imageURI
|
||||
newTemplateName, err := generateInstanceTemplateName(*instanceTemplate.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
instanceTemplate.Name = &newTemplateName
|
||||
op, err := c.instanceTemplateAPI.Insert(ctx, &computepb.InsertInstanceTemplateRequest{
|
||||
Project: project,
|
||||
InstanceTemplateResource: instanceTemplate,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("cloning instance template: %w", err)
|
||||
}
|
||||
if err := op.Wait(ctx); err != nil {
|
||||
return fmt.Errorf("waiting for cloned instance template: %w", err)
|
||||
}
|
||||
|
||||
newTemplateURI := joinInstanceTemplateURI(project, newTemplateName)
|
||||
// update instance group manager to use new template
|
||||
op, err = c.instanceGroupManagersAPI.SetInstanceTemplate(ctx, &computepb.SetInstanceTemplateInstanceGroupManagerRequest{
|
||||
InstanceGroupManager: instanceGroupName,
|
||||
Project: project,
|
||||
Zone: zone,
|
||||
InstanceGroupManagersSetInstanceTemplateRequestResource: &computepb.InstanceGroupManagersSetInstanceTemplateRequest{
|
||||
InstanceTemplate: &newTemplateURI,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("setting instance template: %w", err)
|
||||
}
|
||||
if err := op.Wait(ctx); err != nil {
|
||||
return fmt.Errorf("waiting for setting instance template: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Client) getScalingGroupTemplate(ctx context.Context, scalingGroupID string) (*computepb.InstanceTemplate, error) {
|
||||
project, zone, instanceGroupName, err := splitInstanceGroupID(scalingGroupID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
instanceGroupManager, err := c.instanceGroupManagersAPI.Get(ctx, &computepb.GetInstanceGroupManagerRequest{
|
||||
InstanceGroupManager: instanceGroupName,
|
||||
Project: project,
|
||||
Zone: zone,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting instance group manager %q: %w", instanceGroupName, err)
|
||||
}
|
||||
if instanceGroupManager.InstanceTemplate == nil {
|
||||
return nil, fmt.Errorf("instance group manager %q has no instance template", instanceGroupName)
|
||||
}
|
||||
instanceTemplateProject, instanceTemplateName, err := splitInstanceTemplateID(uriNormalize(*instanceGroupManager.InstanceTemplate))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("splitting instance template name: %w", err)
|
||||
}
|
||||
instanceTemplate, err := c.instanceTemplateAPI.Get(ctx, &computepb.GetInstanceTemplateRequest{
|
||||
InstanceTemplate: instanceTemplateName,
|
||||
Project: instanceTemplateProject,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting instance template %q: %w", instanceTemplateName, err)
|
||||
}
|
||||
return instanceTemplate, nil
|
||||
}
|
||||
|
||||
func instanceTemplateSourceImage(instanceTemplate *computepb.InstanceTemplate) (string, error) {
|
||||
if instanceTemplate.Properties == nil ||
|
||||
len(instanceTemplate.Properties.Disks) == 0 ||
|
||||
instanceTemplate.Properties.Disks[0].InitializeParams == nil ||
|
||||
instanceTemplate.Properties.Disks[0].InitializeParams.SourceImage == nil {
|
||||
return "", errors.New("instance template has no source image")
|
||||
}
|
||||
return uriNormalize(*instanceTemplate.Properties.Disks[0].InitializeParams.SourceImage), nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue