in internal/system/clouddiscovery/cloud_discovery.go [223:330]
func (d *CloudDiscovery) discoverResource(ctx context.Context, host toDiscover, project string) (*spb.SapDiscovery_Resource, []toDiscover, error) {
log.CtxLogger(ctx).Debugw("discoverResource", "name", host.name, "parent", host.parent.GetResourceUri())
if d.resourceCache == nil {
d.resourceCache = make(map[string]cacheEntry)
}
now := time.Now()
// Check cache for this hostname
if c, ok := d.resourceCache[host.name]; ok {
if now.Sub(c.res.UpdateTime.AsTime()) < (10 * time.Minute) {
log.CtxLogger(ctx).Debugw("discoverResource cache hit", "name", host.name, "now", now, "res", c.res, "related", c.related)
return c.res, c.related, nil
}
}
// h may be a resource URI, a hostname, or an IP address
uri := host.name
var addr string
addrs, _ := d.HostResolver(host.name)
log.CtxLogger(ctx).Debugw("discoverResource addresses", "addrs", addrs)
if len(addrs) > 0 {
uri = ""
addr = addrs[0]
// Check cache for this address
if c, ok := d.resourceCache[addr]; ok {
// Cache did not hit for the hostname, add it
d.resourceCache[host.name] = c
if now.Sub(c.res.UpdateTime.AsTime()) < (10 * time.Minute) {
log.CtxLogger(ctx).Debugw("discoverResource cache hit", "name", host.name, "now", now, "res", c.res, "related", c.related)
return c.res, c.related, nil
}
}
if host.parent != nil {
project = ExtractFromURI(host.parent.ResourceUri, projectsURIPart)
}
var err error
if host.network != "" {
log.CtxLogger(ctx).Debugw("discoverResource host network", "network", host.network)
ip := net.ParseIP(addr)
// Find the right subnetwork that the address might belong to
cloudNet := d.networks[host.network]
if cloudNet == nil {
log.CtxLogger(ctx).Debugw("discoverResource host network not found, discovering", "network", host.network)
d.discoverNetwork(ctx, host.network)
cloudNet = d.networks[host.network]
}
log.CtxLogger(ctx).Debugw("discoverResource host network subnets", "subnets", cloudNet.subnets)
for _, s := range cloudNet.subnets {
log.CtxLogger(ctx).Debugw("discoverResource host network subnets ipRange", "ipRange", s.ipRange)
if s.ipRange.Contains(ip) {
log.CtxLogger(ctx).Debugw("discoverResource host network subnets ipRange contains", "ipRange", s.ipRange, "ip", addr, "subnet", s.name)
uri, err = d.GceService.GetURIForIP(project, addr, host.region, s.name)
if err != nil {
log.CtxLogger(ctx).Infow("discoverResource URI in network error", "err", err, "addr", addr, "host", host.name)
}
break
}
}
}
if uri == "" {
uri, err = d.GceService.GetURIForIP(project, addr, host.region, "")
}
if err != nil {
log.CtxLogger(ctx).Infow("discoverResource URI error", "err", err, "addr", addr, "host", host.name)
return nil, nil, err
}
log.CtxLogger(ctx).Debugw("discoverResource uri for ip", "uri", uri)
// Check cache for this URI
if c, ok := d.resourceCache[uri]; ok {
// Cache did not hit for the hostname or address, add it
d.resourceCache[host.name] = c
d.resourceCache[addr] = c
if now.Sub(c.res.UpdateTime.AsTime()) < (10 * time.Minute) {
return c.res, c.related, nil
}
}
}
log.CtxLogger(ctx).Debugw("discoverResource host did not resolve", "uri", uri)
res, toAdd, err := d.discoverResourceForURI(ctx, uri)
if res == nil || err != nil {
return nil, nil, err
}
if uri != host.name && res.ResourceKind == spb.SapDiscovery_Resource_RESOURCE_KIND_INSTANCE {
res.InstanceProperties.VirtualHostname = host.name
}
if host.parent != nil {
if !slices.Contains(host.parent.RelatedResources, res.ResourceUri) {
host.parent.RelatedResources = append(host.parent.RelatedResources, res.ResourceUri)
}
if !slices.Contains(res.RelatedResources, host.parent.ResourceUri) {
res.RelatedResources = append(res.RelatedResources, host.parent.ResourceUri)
}
}
c := cacheEntry{res, toAdd}
d.resourceCache[host.name] = c
d.resourceCache[res.ResourceUri] = c
if host.name != uri {
d.resourceCache[uri] = c
}
if addr != "" && addr != host.name {
d.resourceCache[addr] = c
}
return res, toAdd, err
}