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) } }