confgenerator/resourcedetector/gce_metadata_provider.go (93 lines of code) (raw):

// Copyright 2022 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package resourcedetector import ( "fmt" "strings" gcp_metadata "cloud.google.com/go/compute/metadata" "github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp" ) const notAvailable = "NOT AVAILABLE" // Provide the GCE metadata using the on-VM metadata server // The following metadata are not available on the metadata server: // * Labels // * Subnet URL type GCEMetadataProvider struct { client *gcp_metadata.Client } func NewGCEMetadataProvider() gceDataProvider { c := gcp_metadata.NewClient(nil) return &GCEMetadataProvider{c} } func (gmp *GCEMetadataProvider) getProject() (string, error) { return gmp.client.ProjectID() } func (gmp *GCEMetadataProvider) getZone() (string, error) { return gmp.client.Zone() } // We assume the current running instance has at least one network interface // Otherwise won't be able to connect to func (gmp *GCEMetadataProvider) getNetwork() (string, error) { return gmp.client.Get("instance/network-interfaces/0/network") } // TODO: b/246995894 // The subnetwork url is currently not available from the metadata server func (gmp *GCEMetadataProvider) getSubnetwork() (string, error) { return notAvailable, nil } func (gmp *GCEMetadataProvider) getPublicIP() (string, error) { return gmp.client.ExternalIP() } func (gmp *GCEMetadataProvider) getPrivateIP() (string, error) { return gmp.client.InternalIP() } func (gmp *GCEMetadataProvider) getInstanceID() (string, error) { return gmp.client.InstanceID() } func (gmp *GCEMetadataProvider) getInstanceName() (string, error) { return gmp.client.InstanceName() } func (gmp *GCEMetadataProvider) getTags() (string, error) { tags, err := gmp.client.InstanceTags() if err != nil { return "", err } return strings.Join(tags, ","), nil } func (gmp *GCEMetadataProvider) getMachineType() (string, error) { return gmp.client.Get("instance/machine-type") } func (gmp *GCEMetadataProvider) getDefaultScopes() ([]string, error) { scopes, err := gmp.client.Scopes("default") // If default service account is not defined return empty scopes if _, ok := err.(gcp_metadata.NotDefinedError); ok { return []string{}, nil } return scopes, err } func (gmp *GCEMetadataProvider) getMetadata() (map[string]string, error) { keys, err := gmp.client.Get("instance/attributes") if err != nil { return map[string]string{}, err } metadata := map[string]string{} for _, key := range strings.Fields(keys) { val, err := gmp.client.Get(fmt.Sprintf("instance/attributes/%s", key)) if err != nil { return map[string]string{}, err } metadata[key] = val } return metadata, nil } // TODO: b/246995462 // GCE VM labels are currently not available in the metadata server func (gmp *GCEMetadataProvider) getLabels() (map[string]string, error) { return map[string]string{}, nil } func (gmp *GCEMetadataProvider) getInterfaceIPv4s() (map[string]string, error) { names, err := gmp.client.Get("instance/network-interfaces/") if err != nil { return map[string]string{}, err } interfaces := map[string]string{} for _, name := range strings.Fields(names) { // The metadata server would return interfaces as "0/", needs to trim the "/" name = strings.TrimRight(name, "/") ip, err := gmp.client.Get(fmt.Sprintf("instance/network-interfaces/%s/ip", name)) if err != nil { return map[string]string{}, err } interfaces[name] = ip } return interfaces, err } func (gmp *GCEMetadataProvider) getMIG() (gcp.ManagedInstanceGroup, error) { return gcp.NewDetector().GCEManagedInstanceGroup() }