2026-05-11 22:40:22 -07:00
|
|
|
// Copyright IBM Corp. 2024, 2026
|
2024-04-02 15:47:49 -04:00
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
|
2024-09-16 14:28:54 -04:00
|
|
|
package host
|
2024-04-02 15:47:49 -04:00
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"errors"
|
2024-10-28 12:50:14 -04:00
|
|
|
"strconv"
|
2024-04-02 15:47:49 -04:00
|
|
|
|
|
|
|
|
computepb "cloud.google.com/go/compute/apiv1/computepb"
|
2026-10-12 10:28:05 -07:00
|
|
|
pb "repo.anhonesthost.net/CyberCoveLLC/threshold/sdk/pbs/plugin"
|
2024-04-02 15:47:49 -04:00
|
|
|
"google.golang.org/api/iterator"
|
|
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
|
"google.golang.org/grpc/status"
|
|
|
|
|
)
|
|
|
|
|
|
2024-10-28 12:50:14 -04:00
|
|
|
func getInstances(ctx context.Context, instancesClient InstancesAPI, request *computepb.ListInstancesRequest) ([]*computepb.Instance, error) {
|
2024-04-02 15:47:49 -04:00
|
|
|
hosts := []*computepb.Instance{}
|
2024-10-28 12:50:14 -04:00
|
|
|
it := instancesClient.List(ctx, request)
|
2024-04-02 15:47:49 -04:00
|
|
|
for {
|
|
|
|
|
resp, err := it.Next()
|
|
|
|
|
if err == iterator.Done {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
2024-10-28 12:50:14 -04:00
|
|
|
return nil, status.Errorf(codes.Unknown, "error listing instances: %s", err)
|
2024-04-02 15:47:49 -04:00
|
|
|
}
|
|
|
|
|
hosts = append(hosts, resp)
|
|
|
|
|
}
|
|
|
|
|
return hosts, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func instanceToHost(instance *computepb.Instance) (*pb.ListHostsResponseHost, error) {
|
2024-10-28 12:50:14 -04:00
|
|
|
if instance.GetId() == 0 {
|
|
|
|
|
return nil, errors.New("response integrity error: missing instance id")
|
2024-04-02 15:47:49 -04:00
|
|
|
}
|
|
|
|
|
|
2024-08-06 11:51:00 -04:00
|
|
|
if instance.GetName() == "" {
|
|
|
|
|
return nil, errors.New("response integrity error: missing instance name")
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-02 15:47:49 -04:00
|
|
|
result := new(pb.ListHostsResponseHost)
|
|
|
|
|
|
2024-10-28 12:50:14 -04:00
|
|
|
result.ExternalId = strconv.FormatUint(instance.GetId(), 10)
|
2024-04-02 15:47:49 -04:00
|
|
|
result.ExternalName = instance.GetName()
|
|
|
|
|
|
2024-10-28 12:50:14 -04:00
|
|
|
// Internal DNS name is the hostname of the instance.
|
|
|
|
|
// https://cloud.google.com/compute/docs/networking/using-internal-dns
|
|
|
|
|
dnsName := instance.GetHostname()
|
|
|
|
|
result.DnsNames = appendDistinct(result.DnsNames, &dnsName)
|
|
|
|
|
|
2024-04-02 15:47:49 -04:00
|
|
|
// Now go through all of the interfaces and log the IP address of
|
|
|
|
|
// every interface.
|
|
|
|
|
for _, iface := range instance.GetNetworkInterfaces() {
|
2024-10-28 12:50:14 -04:00
|
|
|
// Populate default IP addresses name similar to how we do
|
2024-04-02 15:47:49 -04:00
|
|
|
// for the entire instance.
|
|
|
|
|
result.IpAddresses = appendDistinct(result.IpAddresses, iface.NetworkIP)
|
|
|
|
|
|
|
|
|
|
for _, external := range iface.AccessConfigs {
|
|
|
|
|
result.IpAddresses = appendDistinct(result.IpAddresses, external.NatIP)
|
2024-10-28 12:50:14 -04:00
|
|
|
result.IpAddresses = appendDistinct(result.IpAddresses, external.ExternalIpv6)
|
2024-04-02 15:47:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add the IPv6 addresses.
|
|
|
|
|
result.IpAddresses = appendDistinct(result.IpAddresses, iface.Ipv6Address)
|
2024-10-28 12:50:14 -04:00
|
|
|
if iface.Ipv6AccessConfigs != nil {
|
|
|
|
|
for _, external := range iface.Ipv6AccessConfigs {
|
|
|
|
|
result.IpAddresses = appendDistinct(result.IpAddresses, external.ExternalIpv6)
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-02 15:47:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Done
|
|
|
|
|
return result, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// appendDistinct will append the elements to the slice
|
|
|
|
|
// if an element is not nil, empty, and does not exist in slice.
|
|
|
|
|
func appendDistinct(slice []string, elems ...*string) []string {
|
|
|
|
|
for _, e := range elems {
|
|
|
|
|
if e == nil || *e == "" || stringInSlice(slice, *e) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
slice = append(slice, *e)
|
|
|
|
|
}
|
|
|
|
|
return slice
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func stringInSlice(s []string, x string) bool {
|
|
|
|
|
for _, y := range s {
|
|
|
|
|
if x == y {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|