dataRT/config/rabbit.go

302 lines
5.6 KiB
Go

package config
import (
"crypto/tls"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"os"
"github.com/youmark/pkcs8"
)
type tlsConfig struct {
CAPath string `json:"capath" yaml:"capath"`
KeyPath string `json:"keypath" yaml:"keypath"`
CertPath string `json:"certpath" yaml:"certpath"`
Password string `json:"password" yaml:"password"`
SkipVerify bool `json:"skipverify" yaml:"skipverify"`
ServerName string `json:"servername" yaml:"servername"`
}
type rabbitConfig struct {
Broker string `json:"broker" yaml:"broker"`
Username string `json:"username" yaml:"username"`
Password string `json:"password" yaml:"password"`
TLS *tlsConfig `json:"tls" yaml:"tls"`
}
func NewRabbitConfig() *rabbitConfig {
return new(rabbitConfig)
}
func (conf *rabbitConfig) GenAddress(tls bool) string {
if conf == nil {
panic("rabbit config is nil")
}
address := "amqp://"
if tls {
address = "amqps://"
}
if conf.GetUsername() != "" && conf.GetPassword() != "" {
address += conf.GetUsername() + ":" + conf.GetPassword() + "@"
}
address += conf.GetBroker() + "/"
return address
}
func (conf *rabbitConfig) GetBroker() string {
if conf == nil {
panic("rabbit config is nil")
}
return conf.Broker
}
func (conf *rabbitConfig) SetBroker(broker string) *rabbitConfig {
if conf == nil {
panic("rabbit config is nil")
}
conf.Broker = broker
return conf
}
func (conf *rabbitConfig) GetUsername() string {
if conf == nil {
panic("rabbit config is nil")
}
return conf.Username
}
func (conf *rabbitConfig) SetUsername(username string) *rabbitConfig {
if conf == nil {
panic("rabbit config is nil")
}
conf.Username = username
return conf
}
func (conf *rabbitConfig) GetPassword() string {
if conf == nil {
panic("rabbit config is nil")
}
return conf.Password
}
func (conf *rabbitConfig) SetPassword(password string) *rabbitConfig {
if conf == nil {
panic("rabbit config is nil")
}
conf.Password = password
return conf
}
func (conf *rabbitConfig) InitTLS() *rabbitConfig {
if conf == nil {
panic("rabbit config is nil")
}
conf.TLS = new(tlsConfig)
return conf
}
func (conf *rabbitConfig) GetTLS() *tlsConfig {
if conf == nil {
panic("rabbit config is nil")
}
return conf.TLS
}
func (conf *tlsConfig) GetCAPath() string {
if conf == nil {
panic("rabbit tls is nil")
}
return conf.CAPath
}
func (conf *tlsConfig) SetCAPath(caPath string) *tlsConfig {
if conf == nil {
panic("rabbit tls is nil")
}
conf.CAPath = caPath
return conf
}
func (conf *tlsConfig) GetKeyPath() string {
if conf == nil {
panic("rabbit tls is nil")
}
return conf.KeyPath
}
func (conf *tlsConfig) SetKeyPath(keyPath string) *tlsConfig {
if conf == nil {
panic("rabbit tls is nil")
}
conf.KeyPath = keyPath
return conf
}
func (conf *tlsConfig) GetCertPath() string {
if conf == nil {
panic("rabbit tls is nil")
}
return conf.CertPath
}
func (conf *tlsConfig) SetCertPath(certPath string) *tlsConfig {
if conf == nil {
panic("rabbit tls is nil")
}
conf.CertPath = certPath
return conf
}
func (conf *tlsConfig) GetPassword() string {
if conf == nil {
panic("rabbit tls is nil")
}
return conf.Password
}
func (conf *tlsConfig) SetPassword(password string) *tlsConfig {
if conf == nil {
panic("rabbit tls is nil")
}
conf.Password = password
return conf
}
func (conf *tlsConfig) GetSkipVerify() bool {
if conf == nil {
panic("rabbit tls is nil")
}
return conf.SkipVerify
}
func (conf *tlsConfig) SetSkipVerify(skipVerify bool) *tlsConfig {
if conf == nil {
panic("rabbit tls is nil")
}
conf.SkipVerify = skipVerify
return conf
}
func (conf *tlsConfig) GetServerName() string {
if conf == nil {
panic("rabbit tls is nil")
}
return conf.ServerName
}
func (conf *tlsConfig) SetServerName(serverName string) *tlsConfig {
if conf == nil {
panic("rabbit tls is nil")
}
conf.ServerName = serverName
return conf
}
func (conf *tlsConfig) GenTLSConfig(tag string) (*tls.Config, error) {
if conf == nil {
return nil, nil
}
if conf.GetCAPath() == "" || conf.GetCertPath() == "" ||
conf.GetKeyPath() == "" {
return nil, errors.New("rabbit tls not valid")
}
caPem, err := os.ReadFile(conf.GetCAPath())
if err != nil {
return nil, err
}
certPool := x509.NewCertPool()
certPool.AppendCertsFromPEM(caPem)
keyPem, err := os.ReadFile(conf.GetKeyPath())
if err != nil {
return nil, err
}
certPem, err := os.ReadFile(conf.GetCertPath())
if err != nil {
return nil, err
}
pemBlock, err := parsePrivateKey(keyPem, []byte(conf.GetPassword()))
if err != nil {
return nil, err
}
cliCert, err := tls.X509KeyPair(certPem, pem.EncodeToMemory(pemBlock))
if err != nil {
return nil, err
}
return &tls.Config{
Certificates: []tls.Certificate{cliCert},
RootCAs: certPool,
ServerName: conf.GetServerName(),
InsecureSkipVerify: conf.GetSkipVerify(),
}, nil
}
func parsePrivateKey(key, password []byte) (*pem.Block, error) {
block, _ := pem.Decode(key)
if block == nil {
return nil, errors.New("no valid pem")
}
var privateKey any
var err error
switch block.Type {
case "RSA PRIVATE KEY":
privateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
case "PRIVATE KEY":
privateKey, err = x509.ParsePKCS8PrivateKey(block.Bytes)
case "ENCRYPTED PRIVATE KEY":
privateKey, err = pkcs8.ParsePKCS8PrivateKey(block.Bytes, password)
default:
return nil, fmt.Errorf("unsupported key type: %s", block.Type)
}
if err != nil {
return nil, err
}
pemBytes, err := x509.MarshalPKCS8PrivateKey(privateKey)
if err != nil {
return nil, err
}
return &pem.Block{
Type: "PRIVATE KEY",
Bytes: pemBytes,
}, nil
}
func rabbitConfigName() string {
return "rabbit.json"
}