internal/alloydb/static.go (100 lines of code) (raw):

// Copyright 2024 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 // // https://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 alloydb import ( "context" "crypto/x509" "encoding/json" "io" "cloud.google.com/go/alloydbconn/debug" "cloud.google.com/go/alloydbconn/errtype" ) type staticPSCConfig struct { PSCDNSName string `json:"pscDnsName"` } // staticConnectionInfo is an amalgamation of the generate ephemeral // certificate and instance metadata endpoints. Its structure concatenates the // IP address information with certificate information. As such it provides all // the necessary properties needed for the Dialer to connect to an instance's // Auth Proxy server. type staticConnectionInfo struct { IPAddress string `json:"ipAddress"` PublicIPAddress string `json:"publicIPAddress"` PSCInstanceConfig staticPSCConfig `json:"pscInstanceConfig"` PEMCertificateChain []string `json:"pemCertificateChain"` CACert string `json:"caCert"` } // staticInstanceInfo correlates instance URIs with static connection info. type staticInstanceInfo map[string]staticConnectionInfo // staticData represent a collection of static connection info. type staticData struct { PublicKey string PrivateKey string InstanceInfo staticInstanceInfo } func (s *staticData) UnmarshalJSON(data []byte) error { inner := map[string]json.RawMessage{} if err := json.Unmarshal(data, &inner); err != nil { return err } if err := json.Unmarshal(inner["privateKey"], &s.PrivateKey); err != nil { return err } delete(inner, "privateKey") if err := json.Unmarshal(inner["publicKey"], &s.PublicKey); err != nil { return err } delete(inner, "publicKey") s.InstanceInfo = staticInstanceInfo{} for k, v := range inner { var sci staticConnectionInfo if err := json.Unmarshal(v, &sci); err != nil { return err } s.InstanceInfo[k] = sci } return nil } // StaticConnectionInfoCache provides connection info that is never refreshed. type StaticConnectionInfoCache struct { logger debug.ContextLogger info ConnectionInfo } // NewStaticConnectionInfoCache creates a connection info cache that will // always return the predefined connection info within the provided io.Reader func NewStaticConnectionInfoCache( inst InstanceURI, l debug.ContextLogger, r io.Reader, ) (*StaticConnectionInfoCache, error) { data, err := io.ReadAll(r) if err != nil { return nil, err } var d staticData if err := json.Unmarshal(data, &d); err != nil { return nil, err } static, ok := d.InstanceInfo[inst.URI()] if !ok { return nil, errtype.NewConfigError("unknown instance", inst.String()) } cc, err := newClientCertificate( inst, []byte(d.PrivateKey), static.PEMCertificateChain, static.CACert, ) if err != nil { return nil, err } pool := x509.NewCertPool() pool.AddCert(cc.caCert) info := ConnectionInfo{ Instance: inst, IPAddrs: map[string]string{ PublicIP: static.PublicIPAddress, PrivateIP: static.IPAddress, PSC: static.PSCInstanceConfig.PSCDNSName, }, ClientCert: cc.certChain, RootCAs: pool, Expiration: cc.expiry, } return &StaticConnectionInfoCache{ logger: l, info: info, }, nil } // ConnectionInfo returns the connection info for the specified instance URI as // loaded from the provided io.Reader. func (c *StaticConnectionInfoCache) ConnectionInfo( _ context.Context, ) (ConnectionInfo, error) { return c.info, nil } // ForceRefresh is a no-op as the cache holds only static connection // information and does no refresh. func (*StaticConnectionInfoCache) ForceRefresh() {} // Close is a no-op. func (*StaticConnectionInfoCache) Close() error { return nil }