func fetchMetadata()

in internal/cloudsql/refresh.go [59:169]


func fetchMetadata(
	ctx context.Context, client *sqladmin.Service, inst instance.ConnName,
) (m metadata, err error) {

	var end trace.EndSpanFunc
	ctx, end = trace.StartSpan(ctx, "cloud.google.com/go/cloudsqlconn/internal.FetchMetadata")
	defer func() { end(err) }()

	db, err := retry50x(ctx, func(ctx2 context.Context) (*sqladmin.ConnectSettings, error) {
		return client.Connect.Get(
			inst.Project(), inst.Name(),
		).Context(ctx2).Do()
	}, exponentialBackoff)
	if err != nil {
		return metadata{}, errtype.NewRefreshError("failed to get instance metadata", inst.String(), err)
	}
	// validate the instance is supported for authenticated connections
	if db.Region != inst.Region() {
		msg := fmt.Sprintf(
			"provided region was mismatched - got %s, want %s",
			inst.Region(), db.Region,
		)
		return metadata{}, errtype.NewConfigError(msg, inst.String())
	}
	if db.BackendType != "SECOND_GEN" {
		return metadata{}, errtype.NewConfigError(
			"unsupported instance - only Second Generation instances are supported",
			inst.String(),
		)
	}

	// parse any ip addresses that might be used to connect
	ipAddrs := make(map[string]string)
	for _, ip := range db.IpAddresses {
		switch ip.Type {
		case "PRIMARY":
			ipAddrs[PublicIP] = ip.IpAddress
		case "PRIVATE":
			ipAddrs[PrivateIP] = ip.IpAddress
		}
	}

	// resolve DnsName into IP address for PSC
	// Note that we have to check for PSC enablement first because CAS instances also set the DnsName.
	if db.PscEnabled {
		// Search the dns_names field for the PSC DNS Name.
		pscDNSName := ""
		for _, dnm := range db.DnsNames {
			if dnm.Name != "" &&
				dnm.ConnectionType == "PRIVATE_SERVICE_CONNECT" && dnm.DnsScope == "INSTANCE" {
				pscDNSName = dnm.Name
				break
			}
		}

		// If the psc dns name was not found, use the legacy dns_name field
		if pscDNSName == "" && db.DnsName != "" {
			pscDNSName = db.DnsName
		}

		// If the psc dns name was found, add it to the ipaddrs map.
		if pscDNSName != "" {
			ipAddrs[PSC] = pscDNSName
		}
	}

	if len(ipAddrs) == 0 {
		return metadata{}, errtype.NewConfigError(
			"cannot connect to instance - it has no supported IP addresses",
			inst.String(),
		)
	}

	// parse the server-side CA certificate
	caCerts := []*x509.Certificate{}
	for b, rest := pem.Decode([]byte(db.ServerCaCert.Cert)); b != nil; b, rest = pem.Decode(rest) {
		if b == nil {
			return metadata{}, errtype.NewRefreshError("failed to decode valid PEM cert", inst.String(), nil)
		}
		caCert, err := x509.ParseCertificate(b.Bytes)
		if err != nil {
			return metadata{}, errtype.NewRefreshError(
				fmt.Sprintf("failed to parse as X.509 certificate: %v", err),
				inst.String(),
				nil,
			)
		}
		caCerts = append(caCerts, caCert)
	}

	// Find a DNS name to use to validate the certificate from the dns_names field. Any
	// name in the list may be used to validate the server TLS certificate.
	// Fall back to legacy dns_name field if necessary.
	var serverName string
	if len(db.DnsNames) > 0 {
		serverName = db.DnsNames[0].Name
	}
	if serverName == "" {
		serverName = db.DnsName
	}

	m = metadata{
		ipAddrs:      ipAddrs,
		serverCACert: caCerts,
		version:      db.DatabaseVersion,
		dnsName:      serverName,
		serverCAMode: db.ServerCaMode,
	}

	return m, nil
}