func()

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
}