package files import ( "os" "path/filepath" "strings" ) type Source struct { rootDirectory string environ map[string]string warner Warner cached struct { wireguardLoaded bool wireguardConf WireguardConfig } } func New(warner Warner) (source *Source) { osEnviron := os.Environ() environ := make(map[string]string, len(osEnviron)) for _, pair := range osEnviron { const maxSplit = 2 split := strings.SplitN(pair, "=", maxSplit) environ[split[0]] = split[1] } return &Source{ rootDirectory: "/gluetun", environ: environ, warner: warner, } } func (s *Source) String() string { return "files" } func (s *Source) Get(key string) (value string, isSet bool) { if key == "" { return "", false } // TODO v4 custom environment variable to set the files parent directory // and not to set each file to a specific path envKey := strings.ToUpper(key) envKey = strings.ReplaceAll(envKey, "-", "_") envKey += "_FILE" path := s.environ[envKey] if path == "" { path = filepath.Join(s.rootDirectory, key) } // Special file handling switch key { // TODO timezone from /etc/localtime case "client.crt", "client.key": value, isSet, err := ReadPEMFile(path) if err != nil { s.warner.Warnf("skipping %s: parsing PEM: %s", path, err) } return value, isSet case "wireguard_private_key": return strPtrToStringIsSet(s.lazyLoadWireguardConf().PrivateKey) case "wireguard_preshared_key": return strPtrToStringIsSet(s.lazyLoadWireguardConf().PreSharedKey) case "wireguard_addresses": return strPtrToStringIsSet(s.lazyLoadWireguardConf().Addresses) case "wireguard_public_key": return strPtrToStringIsSet(s.lazyLoadWireguardConf().PublicKey) case "vpn_endpoint_ip": return strPtrToStringIsSet(s.lazyLoadWireguardConf().EndpointIP) case "vpn_endpoint_port": return strPtrToStringIsSet(s.lazyLoadWireguardConf().EndpointPort) } value, isSet, err := ReadFromFile(path) if err != nil { s.warner.Warnf("skipping %s: reading file: %s", path, err) } return value, isSet } func (s *Source) KeyTransform(key string) string { switch key { // TODO v4 remove these irregular cases case "OPENVPN_KEY": return "client.key" case "OPENVPN_CERT": return "client.crt" default: key = strings.ToLower(key) // HTTPROXY_USER -> httpproxy_user return key } } func strPtrToStringIsSet(ptr *string) (s string, isSet bool) { if ptr == nil { return "", false } return *ptr, true }