Files
kamaji/internal/datastore/datastore.go
2024-07-11 13:20:02 +02:00

129 lines
2.8 KiB
Go

// Copyright 2022 Clastix Labs
// SPDX-License-Identifier: Apache-2.0
package datastore
import (
"context"
"crypto/tls"
"crypto/x509"
"fmt"
"net"
"strconv"
"github.com/pkg/errors"
"sigs.k8s.io/controller-runtime/pkg/client"
kamajiv1alpha1 "github.com/clastix/kamaji/api/v1alpha1"
)
type ConnectionEndpoint struct {
Host string
Port int
}
func (r ConnectionEndpoint) String() string {
return net.JoinHostPort(r.Host, strconv.FormatInt(int64(r.Port), 10))
}
type ConnectionConfig struct {
User string
Password string
Endpoints []ConnectionEndpoint
DBName string
TLSConfig *tls.Config
Parameters map[string][]string
}
func NewConnectionConfig(ctx context.Context, client client.Client, ds kamajiv1alpha1.DataStore) (*ConnectionConfig, error) {
var tlsConfig *tls.Config
if ds.Spec.TLSConfig != nil {
ca, err := ds.Spec.TLSConfig.CertificateAuthority.Certificate.GetContent(ctx, client)
if err != nil {
return nil, err
}
rootCAs := x509.NewCertPool()
if ok := rootCAs.AppendCertsFromPEM(ca); !ok {
return nil, fmt.Errorf("error create root CA for the DB connector")
}
tlsConfig = &tls.Config{
RootCAs: rootCAs,
}
}
if ds.Spec.TLSConfig != nil && ds.Spec.TLSConfig.ClientCertificate != nil {
crt, err := ds.Spec.TLSConfig.ClientCertificate.Certificate.GetContent(ctx, client)
if err != nil {
return nil, err
}
key, err := ds.Spec.TLSConfig.ClientCertificate.PrivateKey.GetContent(ctx, client)
if err != nil {
return nil, err
}
certificate, err := tls.X509KeyPair(crt, key)
if err != nil {
return nil, errors.Wrap(err, "cannot retrieve x.509 key pair from the Kine Secret")
}
tlsConfig.Certificates = []tls.Certificate{certificate}
}
var user, password string
if auth := ds.Spec.BasicAuth; auth != nil {
u, err := auth.Username.GetContent(ctx, client)
if err != nil {
return nil, err
}
user = string(u)
p, err := auth.Password.GetContent(ctx, client)
if err != nil {
return nil, err
}
password = string(p)
}
eps := make([]ConnectionEndpoint, 0, len(ds.Spec.Endpoints))
for _, ep := range ds.Spec.Endpoints {
host, stringPort, err := net.SplitHostPort(ep)
if err != nil {
return nil, errors.Wrap(err, "cannot retrieve host-port pair from DataStore endpoints")
}
port, err := strconv.Atoi(stringPort)
if err != nil {
return nil, errors.Wrap(err, "cannot convert port from string for the given DataStore")
}
eps = append(eps, ConnectionEndpoint{
Host: host,
Port: port,
})
}
return &ConnectionConfig{
User: user,
Password: password,
Endpoints: eps,
TLSConfig: tlsConfig,
}, nil
}
func (config ConnectionConfig) getDataSourceNameUserPassword() string {
if config.User == "" {
return ""
}
if config.Password == "" {
return fmt.Sprintf("%s@", config.User)
}
return fmt.Sprintf("%s:%s@", config.User, config.Password)
}