From 7d6bb372b5727dd7e74456368a981388905d0aad Mon Sep 17 00:00:00 2001 From: Vasil Averyanau Date: Wed, 11 Dec 2024 11:29:47 +0100 Subject: [PATCH] feat: adds gcp metadata provider support to cloudmeta package This adds gcp metadata provider support to cloudmeta package. Fixes: #4128 --- pkg/cloudmeta/gcp.go | 50 +++++++++++++++++++++++++++++++++++++++ pkg/cloudmeta/metadata.go | 11 +++++++-- 2 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 pkg/cloudmeta/gcp.go diff --git a/pkg/cloudmeta/gcp.go b/pkg/cloudmeta/gcp.go new file mode 100644 index 000000000..30e779ac3 --- /dev/null +++ b/pkg/cloudmeta/gcp.go @@ -0,0 +1,50 @@ +// Copyright (C) 2024 ScyllaDB + +package cloudmeta + +import ( + "context" + "strings" + + "cloud.google.com/go/compute/metadata" + "github.com/pkg/errors" +) + +// GCPMetadata is a wrapper around gcp metadata client. +type GCPMetadata struct { + meta *metadata.Client +} + +// NewGCPMetadata returns gcp metadata provider. +func NewGCPMetadata() *GCPMetadata { + return &GCPMetadata{ + meta: metadata.NewClient(nil), + } +} + +// Metadata returns InstanceMetadata from gcp if available. +func (gcp *GCPMetadata) Metadata(ctx context.Context) (InstanceMetadata, error) { + machineType, err := gcp.getMachineType(ctx) + if err != nil { + return InstanceMetadata{}, errors.Wrap(err, "gcp.meta.GetWithContext") + } + return InstanceMetadata{ + CloudProvider: CloudProviderGCP, + InstanceType: machineType, + }, nil +} + +func (gcp *GCPMetadata) getMachineType(ctx context.Context) (string, error) { + // The machine type for this VM. This value has the following format: projects/PROJECT_NUM/machineTypes/MACHINE_TYPE. + machineType, err := gcp.meta.GetWithContext(ctx, "instance/machine-type") + if err != nil { + return "", errors.Wrap(err, "gcp.meta.GetWithContext") + } + + parts := strings.Split(machineType, "/") + if len(parts) < 2 { + return "", errors.Errorf("unexpected machine-type format: %s", machineType) + } + + return parts[len(parts)-1], nil +} diff --git a/pkg/cloudmeta/metadata.go b/pkg/cloudmeta/metadata.go index 4ccf8d911..a23b49ef6 100644 --- a/pkg/cloudmeta/metadata.go +++ b/pkg/cloudmeta/metadata.go @@ -17,8 +17,12 @@ type InstanceMetadata struct { // CloudProvider is enum of supported cloud providers. type CloudProvider string -// CloudProviderAWS represents aws provider. -var CloudProviderAWS CloudProvider = "aws" +var ( + // CloudProviderAWS represents aws provider. + CloudProviderAWS CloudProvider = "aws" + // CloudProviderGCP represents gcp provider. + CloudProviderGCP CloudProvider = "gcp" +) // CloudMetadataProvider interface that each metadata provider should implement. type CloudMetadataProvider interface { @@ -41,9 +45,12 @@ func NewCloudMeta() (*CloudMeta, error) { return nil, err } + gcpMeta := NewGCPMetadata() + return &CloudMeta{ providers: []CloudMetadataProvider{ awsMeta, + gcpMeta, }, providerTimeout: defaultTimeout, }, nil