mirror of
https://github.com/outbackdingo/kamaji.git
synced 2026-01-27 10:19:29 +00:00
129 lines
2.8 KiB
Go
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)
|
|
}
|