sshpoke/internal/config/model.go

153 lines
4.0 KiB
Go

package config
import (
"crypto/sha1"
"encoding/gob"
"encoding/hex"
"net/http"
"path/filepath"
"github.com/Neur0toxine/sshpoke/pkg/smarttypes"
"github.com/docker/docker/client"
"github.com/docker/go-connections/tlsconfig"
)
var (
Default Config
configHash string
)
type Config struct {
Debug bool `mapstructure:"debug" json:"debug"`
API API `mapstructure:"api" json:"api"`
Docker DockerConfig `mapstructure:"docker" json:"docker"`
DefaultServer string `mapstructure:"default_server" json:"default_server"`
Services []Service `mapstructure:"services" json:"services,omitempty"`
Servers []Server `mapstructure:"servers" json:"servers"`
}
func HasBeenUpdated() bool {
return generateConfigHash() != configHash
}
func Rehash() {
configHash = generateConfigHash()
}
func generateConfigHash() string {
h := sha1.New()
_ = gob.NewEncoder(h).Encode(Default)
return hex.EncodeToString(h.Sum(nil))
}
type Service struct {
Name smarttypes.MatchableString `mapstructure:"name" json:"name"`
Params ServiceLabels `mapstructure:"params" json:"params"`
}
type ServiceLabels struct {
Enable smarttypes.BoolStr `mapstructure:"enable" json:"enable"`
Network string `mapstructure:"network" json:"network,omitempty"`
Server string `mapstructure:"server" json:"server,omitempty"`
Port string `mapstructure:"port" json:"port,omitempty"`
RemoteHost string `mapstructure:"remote_host" json:"remote_host,omitempty"`
}
type API struct {
Rest WebAPI `mapstructure:"rest" json:"rest"`
Plugin PluginAPI `mapstructure:"plugin" json:"plugin"`
}
type WebAPI struct {
Port int `mapstructure:"port" json:"port" validate:"gte=0,lte=65535"`
Token string `mapstructure:"token" json:"token"`
}
type PluginAPI struct {
Port int `mapstructure:"port" json:"port" validate:"gte=0,lte=65535"`
}
type DockerConfig struct {
FromEnv *bool `mapstructure:"from_env,omitempty" json:"from_env"`
CertPath string `mapstructure:"cert_path" json:"cert_path,omitempty"`
TLSVerify *bool `mapstructure:"tls_verify,omitempty" json:"tls_verify,omitempty"`
Host string `mapstructure:"host" json:"host,omitempty"`
Version string `mapstructure:"version" json:"version,omitempty"`
}
type DriverParams map[string]interface{}
type DriverType string
const (
DriverSSH DriverType = "ssh"
DriverPlugin DriverType = "plugin"
DriverNil DriverType = "nil"
)
type Server struct {
Name string `mapstructure:"name" json:"name" validate:"required"`
Driver DriverType `mapstructure:"driver" json:"driver"`
Params DriverParams `mapstructure:"params" json:"params,omitempty"`
}
func (d DockerConfig) Opts(c *client.Client) error {
if d.FromEnv == nil || *d.FromEnv {
return client.FromEnv(c)
}
ops := []client.Opt{
d.withTLSClientConfig(),
d.withHost(),
d.withVersion(),
}
for _, op := range ops {
if err := op(c); err != nil {
return err
}
}
return nil
}
func (d DockerConfig) withTLSClientConfig() client.Opt {
return func(c *client.Client) error {
dockerCertPath := d.CertPath
if dockerCertPath == "" {
return nil
}
skipTLSVerify := false
if d.TLSVerify != nil && !(*d.TLSVerify) {
skipTLSVerify = true
}
options := tlsconfig.Options{
CAFile: filepath.Join(dockerCertPath, "ca.pem"),
CertFile: filepath.Join(dockerCertPath, "cert.pem"),
KeyFile: filepath.Join(dockerCertPath, "key.pem"),
InsecureSkipVerify: skipTLSVerify,
}
tlsConfig, err := tlsconfig.Client(options)
if err != nil {
return err
}
return client.WithHTTPClient(&http.Client{
Transport: &http.Transport{TLSClientConfig: tlsConfig},
CheckRedirect: client.CheckRedirect,
})(c)
}
}
func (d DockerConfig) withHost() client.Opt {
return func(c *client.Client) error {
if host := d.Host; host != "" {
return client.WithHost(host)(c)
}
return nil
}
}
func (d DockerConfig) withVersion() client.Opt {
return func(c *client.Client) error {
return client.WithVersion(d.Version)(c)
}
}